<template>
|
<el-dialog
|
v-model="visible"
|
:title="
|
isReturnMode ? '设备归还' : isEdit ? '编辑设备领用' : '新增设备领用'
|
"
|
width="600px"
|
@close="handleClose"
|
>
|
<el-form :model="form" :rules="rules" ref="formRef" label-width="150px">
|
<el-form-item label="领用人" prop="userId">
|
<el-select
|
v-model="form.userId"
|
placeholder="请选择"
|
:disabled="isViewMode || isReturnMode"
|
@change="getEquipment"
|
>
|
<el-option
|
v-for="item in userList"
|
:key="item.userId"
|
:label="item.nickName"
|
:value="item.userId"
|
/>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="设备名称" prop="equipmentId">
|
<el-select
|
v-model="form.equipmentId"
|
placeholder="请选择"
|
:disabled="isViewMode || isReturnMode"
|
>
|
<el-option
|
v-for="item in equipmentList"
|
:key="item.id"
|
:label="item.equipmentName"
|
:value="item.id"
|
/>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="是否为消耗品" prop="isConsumables">
|
<el-select
|
:model-value="currentConsumables"
|
placeholder="请选择是否为耗材类型"
|
:disabled="true"
|
>
|
<el-option label="是" :value="true" />
|
<el-option label="否" :value="false" />
|
</el-select>
|
</el-form-item>
|
<el-form-item
|
label="设备库存"
|
prop="equipmentStock"
|
v-if="!isReturnMode && formData.status !== 2"
|
>
|
<el-input
|
:value="
|
equipmentList.find((item) => item.id == form.equipmentId)
|
?.quantity || 0
|
"
|
disabled
|
style="width: 100%"
|
/>
|
</el-form-item>
|
<el-form-item label="已使用数量" prop="usedQuantity" v-if="isReturnMode">
|
<el-input
|
:value="formData.usageQuantity"
|
disabled
|
style="width: 100%"
|
/>
|
</el-form-item>
|
<el-form-item
|
label="已归还数量"
|
prop="returnedQuantity"
|
v-if="isReturnMode"
|
>
|
<el-input
|
:value="formData.totalReturnNo || 0"
|
disabled
|
style="width: 100%"
|
/>
|
</el-form-item>
|
<el-form-item
|
label="领用数量"
|
prop="usageQuantity"
|
v-if="!isReturnMode && formData.status !== 2"
|
>
|
<el-input-number
|
v-model="form.usageQuantity"
|
:min="1"
|
:max="maxQuantity || 999"
|
style="width: 100%"
|
:disabled="isViewMode"
|
/>
|
<span
|
v-if="maxQuantity !== null"
|
style="color: #999; font-size: 12px; margin-left: 8px"
|
>(最多{{ maxQuantity }}台)</span
|
>
|
</el-form-item>
|
<el-form-item
|
label="本次归还数量"
|
prop="returnQuantity"
|
v-if="isReturnMode"
|
>
|
<el-input-number
|
v-model="form.returnQuantity"
|
:min="1"
|
:max="Math.max(1, remainingReturnQuantity)"
|
style="width: 100%"
|
:disabled="remainingReturnQuantity <= 0"
|
/>
|
<span
|
style="color: #999; font-size: 12px; margin-left: 8px"
|
v-if="remainingReturnQuantity > 0"
|
>(最多{{ remainingReturnQuantity }}台)</span
|
>
|
<span style="color: #67c23a; font-size: 12px; margin-left: 8px" v-else
|
>(已全部归还)</span
|
>
|
<!-- 归还完成提示 -->
|
<div
|
v-if="
|
remainingReturnQuantity > 0 &&
|
form.returnQuantity === remainingReturnQuantity
|
"
|
style="color: #67c23a; font-size: 12px; margin-top: 4px"
|
>
|
💡 提示:本次归还后将完成全部归还
|
</div>
|
</el-form-item>
|
<!-- 使用开始时间 - 只在非归还模式显示 -->
|
<el-form-item
|
label="使用开始时间"
|
prop="usageStartTime"
|
v-if="!isReturnMode"
|
>
|
<el-date-picker
|
v-model="form.usageStartTime"
|
type="datetime"
|
placeholder="选择开始时间"
|
style="width: 100%"
|
value-format="YYYY-MM-DD"
|
format="YYYY-MM-DD"
|
:disabled="isViewMode"
|
/>
|
</el-form-item>
|
|
<!-- 归还结束时间 - 只在归还模式显示 -->
|
<el-form-item label="归还时间" prop="returnTime" v-if="isReturnMode">
|
<el-date-picker
|
v-model="form.returnTime"
|
type="datetime"
|
placeholder="选择归还时间"
|
style="width: 100%"
|
value-format="YYYY-MM-DD"
|
format="YYYY-MM-DD"
|
/>
|
</el-form-item>
|
<el-form-item label="备注" prop="remarks">
|
<el-input
|
v-model="form.remarks"
|
type="textarea"
|
placeholder="请输入备注"
|
:disabled="isViewMode"
|
/>
|
</el-form-item>
|
</el-form>
|
<template #footer>
|
<el-button @click="handleClose">取消</el-button>
|
<el-button type="primary" @click="debouncedSubmit" v-if="!isViewMode"
|
>确定</el-button
|
>
|
</template>
|
</el-dialog>
|
</template>
|
|
<script setup>
|
import { ref, watch, computed, onMounted } from "vue";
|
import { ElMessage, ElMessageBox } from "element-plus";
|
import { getEquipmentList } from "@/api/publicApi/index.js";
|
import { addOrEditUsageRecord } from "@/api/equipment/requisition/index.js";
|
|
import useUserStore from "@/store/modules/user";
|
|
const userStore = useUserStore();
|
let userList = ref([]);
|
userStore.getUserList().then((res) => {
|
userList.value = res;
|
});
|
// 获取设备列表
|
const equipmentList = ref([]);
|
// 获取最新数据
|
const getEquipment = async () => {
|
try {
|
await getEquipmentList().then((res) => {
|
equipmentList.value = res.data;
|
});
|
} catch (error) {
|
ElMessage.error("获取设备列表失败");
|
}
|
};
|
const props = defineProps({
|
modelValue: Boolean,
|
formData: {
|
type: Object,
|
default: () => ({}),
|
},
|
addOrEdit: {
|
type: String,
|
default: "add",
|
},
|
});
|
|
// 默认表单初始值
|
const defaultForm = {
|
userId: "",
|
equipmentId: "",
|
usageQuantity: 1,
|
usageStartTime: "",
|
returnQuantity: 1,
|
returnTime: "",
|
remarks: "",
|
};
|
const form = ref({ ...defaultForm });
|
|
const currentConsumables = computed(() => {
|
const eq = equipmentList.value.find(item => item.id == form.value.equipmentId);
|
return eq ? !!eq.isConsumables : false;
|
});
|
const maxQuantity = computed(() => {
|
if (!form.value.equipmentId) return 0;
|
const eq = equipmentList.value.find(
|
(item) => item.id == form.value.equipmentId
|
);
|
// 防止为0或负数,最小为1
|
return eq && eq.quantity > 0 ? eq.quantity : 999;
|
});
|
const emit = defineEmits(["update:modelValue", "submit"]);
|
|
const visible = computed({
|
get: () => props.modelValue,
|
set: (v) => emit("update:modelValue", v),
|
});
|
|
// 监听设备选择变化
|
watch(
|
() => form.value.equipmentId,
|
(newId) => {
|
if (newId) {
|
const eq = equipmentList.value.find(item => item.id == newId);
|
}
|
}
|
);
|
const isViewMode = computed(
|
() => props.addOrEdit === "view" || props.addOrEdit === "viewRow"
|
);
|
|
// 判断是否为归还模式
|
const isReturnMode = computed(() => props.addOrEdit === "return");
|
|
// 计算剩余可归还数量
|
const remainingReturnQuantity = computed(() => {
|
if (!isReturnMode.value || !props.formData.usageQuantity) return 0;
|
|
const totalUsageQuantity = props.formData.usageQuantity || 0; // 总使用数量
|
const alreadyReturnedQuantity = props.formData.totalReturnNo || 0; // 已归还数量
|
const remaining = totalUsageQuantity - alreadyReturnedQuantity; // 剩余可归还数量
|
|
return Math.max(0, remaining); // 确保不为负数
|
});
|
|
const isEdit = computed(() => !!props.formData?.id);
|
const formRef = ref();
|
|
// 获取当前日期(YYYY-MM-DD格式)
|
const getCurrentDate = () => {
|
const now = new Date();
|
const year = now.getFullYear();
|
const month = String(now.getMonth() + 1).padStart(2, "0");
|
const day = String(now.getDate()).padStart(2, "0");
|
return `${year}-${month}-${day}`;
|
};
|
|
// 确保初始化时获取设备列表
|
onMounted(() => {
|
getEquipment();
|
});
|
|
watch(
|
() => props.formData,
|
(val) => {
|
if (val && Object.keys(val).length > 0) {
|
form.value = { ...val };
|
|
// 归还模式初始化
|
if (isReturnMode.value) {
|
form.value.returnTime = getCurrentDate();
|
const maxReturnQuantity = remainingReturnQuantity.value;
|
form.value.returnQuantity =
|
maxReturnQuantity > 0 ? Math.min(1, maxReturnQuantity) : 0;
|
}
|
} else {
|
form.value = { ...defaultForm };
|
}
|
},
|
{ immediate: true }
|
);
|
|
const rules = computed(() => {
|
const baseRules = {
|
userId: [{ required: true, message: "请输入领用人", trigger: "blur" }],
|
equipmentId: [{ required: true, message: "请输入设备ID", trigger: "blur" }],
|
};
|
|
if (isReturnMode.value) {
|
// 归还模式的验证规则
|
return {
|
...baseRules,
|
returnQuantity: [
|
{ required: true, message: "请输入归还数量", trigger: "blur" },
|
{ type: "number", min: 1, message: "至少归还1台", trigger: "blur" },
|
{
|
validator: (rule, value, callback) => {
|
const remaining = remainingReturnQuantity.value;
|
if (remaining <= 0) {
|
callback(new Error("已全部归还,无法继续归还"));
|
} else if (value > remaining) {
|
callback(
|
new Error(`归还数量不能大于剩余可归还数量(${remaining}台)`)
|
);
|
} else {
|
callback();
|
}
|
},
|
trigger: "blur",
|
},
|
],
|
returnTime: [
|
{ required: true, message: "请选择归还时间", trigger: "change" },
|
],
|
};
|
} else {
|
// 新增/编辑模式的验证规则
|
return {
|
...baseRules,
|
usageQuantity: [
|
{ required: true, message: "请输入领用数量", trigger: "blur" },
|
{ type: "number", min: 1, message: "至少领用1台", trigger: "blur" },
|
{
|
validator: (rule, value, callback) => {
|
if (maxQuantity.value !== null && value > maxQuantity.value) {
|
callback(new Error("领用数量不能大于设备数量"));
|
} else {
|
callback();
|
}
|
},
|
trigger: "blur",
|
},
|
],
|
usageStartTime: [
|
{ required: true, message: "请选择开始时间", trigger: "change" },
|
],
|
};
|
}
|
});
|
|
function handleClose() {
|
emit("update:modelValue", false);
|
}
|
|
// 通用防抖函数
|
function debounce(fn, delay = 800) {
|
let timer = null;
|
return function (...args) {
|
if (timer) clearTimeout(timer);
|
timer = setTimeout(() => {
|
fn.apply(this, args);
|
timer = null;
|
}, delay);
|
};
|
}
|
|
// 防抖后的提交方法
|
const debouncedSubmit = debounce(handleSubmit, 800);
|
|
function handleSubmit() {
|
formRef.value.validate(async (valid) => {
|
if (!valid) return;
|
|
let submitData = { ...form.value };
|
|
// 归还模式处理
|
if (isReturnMode.value) {
|
const currentReturnQuantity = form.value.returnQuantity;
|
const totalUsageQuantity = props.formData.usageQuantity;
|
const alreadyReturnedQuantity = props.formData.totalReturnNo || 0;
|
const newTotalReturnedQuantity =
|
alreadyReturnedQuantity + currentReturnQuantity;
|
|
// 判断是否全部归还完成
|
let equipmentStatus = 2; // 默认为部分归还
|
let isFullyReturned = newTotalReturnedQuantity >= totalUsageQuantity;
|
|
if (isFullyReturned) {
|
equipmentStatus = 3; // 全部归还完成
|
|
// 全部归还时的确认提示
|
try {
|
await ElMessageBox.confirm(
|
`确认将设备"${
|
props.formData.equipmentName || "未知设备"
|
}"全部归还吗?归还后设备状态将变为"已归还"。`,
|
"确认全部归还",
|
{
|
confirmButtonText: "确认归还",
|
cancelButtonText: "取消",
|
type: "success",
|
}
|
);
|
} catch (error) {
|
if (error === "cancel") {
|
ElMessage.info("已取消归还操作");
|
return;
|
}
|
}
|
|
console.log("设备归还完成:", {
|
设备名称: props.formData.equipmentName,
|
总使用数量: totalUsageQuantity,
|
新的归还总数: newTotalReturnedQuantity,
|
状态: "已全部归还",
|
});
|
} else {
|
console.log("设备部分归还:", {
|
设备名称: props.formData.equipmentName,
|
总使用数量: totalUsageQuantity,
|
已归还数量: newTotalReturnedQuantity,
|
剩余未归还: totalUsageQuantity - newTotalReturnedQuantity,
|
状态: "部分归还",
|
});
|
}
|
|
submitData = {
|
...props.formData,
|
totalReturnNo: newTotalReturnedQuantity,
|
returnQuantity: currentReturnQuantity,
|
returnTime: form.value.returnTime,
|
equipmentStatus: equipmentStatus,
|
remarks: form.value.remarks,
|
usageQuantity: totalUsageQuantity,
|
};
|
}
|
|
try {
|
let { code, data } = await addOrEditUsageRecord(submitData);
|
if (code !== 200) {
|
ElMessage.error(data.msg || "操作失败");
|
return;
|
}
|
if (code == 200 && data == 1) {
|
emit("submit", submitData);
|
}
|
handleClose();
|
} catch (error) {
|
console.error("提交失败:", error);
|
ElMessage.error("操作失败,请稍后再试");
|
}
|
});
|
}
|
</script>
|