From 77bb73aaef8f85d961b373731a05361cbe6921de Mon Sep 17 00:00:00 2001 From: 张诺 <2864490065@qq.com> Date: 星期五, 25 七月 2025 14:06:57 +0800 Subject: [PATCH] 提交设备管理优化 以及防抖功能 --- src/views/equipment/management/mould/equipmentRequisitionDialog.vue | 343 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 286 insertions(+), 57 deletions(-) diff --git a/src/views/equipment/management/mould/equipmentRequisitionDialog.vue b/src/views/equipment/management/mould/equipmentRequisitionDialog.vue index 8f58ee2..92768ec 100644 --- a/src/views/equipment/management/mould/equipmentRequisitionDialog.vue +++ b/src/views/equipment/management/mould/equipmentRequisitionDialog.vue @@ -1,13 +1,18 @@ <template> <el-dialog v-model="visible" - :title="isEdit ? '缂栬緫璁惧棰嗙敤' : '鏂板璁惧棰嗙敤'" + :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="璇烽�夋嫨"> + <el-select + v-model="form.userId" + placeholder="璇烽�夋嫨" + :disabled="isViewMode || isReturnMode" + @change="getEquipment" + > <el-option v-for="item in userList" :key="item.userId" @@ -17,7 +22,11 @@ </el-select> </el-form-item> <el-form-item label="璁惧鍚嶇О" prop="equipmentId"> - <el-select v-model="form.equipmentId" placeholder="璇烽�夋嫨"> + <el-select + v-model="form.equipmentId" + placeholder="璇烽�夋嫨" + :disabled="isViewMode || isReturnMode" + > <el-option v-for="item in equipmentList" :key="item.id" @@ -26,7 +35,7 @@ /> </el-select> </el-form-item> - <el-form-item label="璁惧搴撳瓨" prop="equipmentStock"> + <el-form-item label="璁惧搴撳瓨" prop="equipmentStock" v-if="!isReturnMode && formData.status !== 2"> <el-input :value=" equipmentList.find((item) => item.id == form.equipmentId) @@ -36,12 +45,27 @@ style="width: 100%" /> </el-form-item> - <el-form-item label="棰嗙敤鏁伴噺" prop="usageQuantity"> + <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" @@ -49,16 +73,34 @@ >(鏈�澶歿{ maxQuantity }}鍙�)</span > </el-form-item> - <el-form-item label="浣跨敤鐘舵��" prop="equipmentStatus"> - <el-select v-model="form.equipmentStatus" placeholder="璇烽�夋嫨"> - <el-option label="鍚敤" :value="1" /> - <el-option label="绂佺敤" :value="0" /> - <el-option label="缁翠慨涓�" :value="2" /> - <el-option label="鎶ュ簾" :value="3" /> - <el-option label="寰呴鐢�" :value="4" /> - </el-select> + <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"> + <!-- 浣跨敤寮�濮嬫椂闂� - 鍙湪闈炲綊杩樻ā寮忔樉绀� --> + <el-form-item label="浣跨敤寮�濮嬫椂闂�" prop="usageStartTime" v-if="!isReturnMode"> <el-date-picker v-model="form.usageStartTime" type="datetime" @@ -66,40 +108,47 @@ style="width: 100%" value-format="YYYY-MM-DD" format="YYYY-MM-DD" + :disabled="isViewMode" /> </el-form-item> - <!-- <el-form-item label="浣跨敤缁撴潫鏃堕棿" prop="usageEndTime"> + + <!-- 褰掕繕缁撴潫鏃堕棿 - 鍙湪褰掕繕妯″紡鏄剧ず --> + <el-form-item label="褰掕繕鏃堕棿" prop="returnTime" v-if="isReturnMode"> <el-date-picker - v-model="form.usageEndTime" + v-model="form.returnTime" type="datetime" - placeholder="閫夋嫨缁撴潫鏃堕棿" + placeholder="閫夋嫨褰掕繕鏃堕棿" style="width: 100%" + value-format="YYYY-MM-DD" + format="YYYY-MM-DD" /> - </el-form-item> --> + </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="handleSubmit">纭畾</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 } from "element-plus"; +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"; -onMounted(() => {}); const userStore = useUserStore(); let userList = ref([]); userStore.getUserList().then((res) => { @@ -107,14 +156,26 @@ }); // 鑾峰彇璁惧鍒楄〃 const equipmentList = ref([]); -getEquipmentList().then((res) => { - equipmentList.value = res.data; -}); +// 鑾峰彇鏈�鏂版暟鎹� +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 maxQuantity = computed(() => { @@ -131,6 +192,25 @@ get: () => props.modelValue, set: (v) => emit("update:modelValue", v), }); +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(); @@ -140,60 +220,209 @@ userId: "", equipmentId: "", usageQuantity: 1, - equipmentStatus: 1, usageStartTime: "", - remarks: "" + returnQuantity: 1, + returnTime: "", + remarks: "", }; const form = ref({ ...defaultForm }); + +// 鑾峰彇褰撳墠鏃ユ湡锛圷YYY-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 = { ...defaultForm, ...val }; + 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 = { - userId: [{ required: true, message: "璇疯緭鍏ラ鐢ㄤ汉", trigger: "blur" }], - equipmentId: [{ required: true, message: "璇疯緭鍏ヨ澶嘔D", trigger: "blur" }], - 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", - }, - ], - equipmentStatus: [ - { required: true, message: "璇烽�夋嫨浣跨敤鐘舵��", trigger: "change" }, - ], - usageStartTime: [ - { required: true, message: "璇烽�夋嫨寮�濮嬫椂闂�", trigger: "change" }, - ], -}; +const rules = computed(() => { + const baseRules = { + userId: [{ required: true, message: "璇疯緭鍏ラ鐢ㄤ汉", trigger: "blur" }], + equipmentId: [{ required: true, message: "璇疯緭鍏ヨ澶嘔D", 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 handleSubmit() { - formRef.value.validate((valid) => { +// 閫氱敤闃叉姈鍑芥暟 +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 res = addOrEditUsageRecord(form.value); - emit("submit", { ...form.value }); - handleClose(); + + 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){ + // 鏍规嵁褰掕繕鐘舵�佺粰鍑轰笉鍚岀殑鎴愬姛鎻愮ず + if (isReturnMode.value && submitData.equipmentStatus === 3) { + ElMessage.success("璁惧宸插叏閮ㄥ綊杩樺畬鎴愶紒"); + } else if (isReturnMode.value && submitData.equipmentStatus === 2) { + ElMessage.success("璁惧閮ㄥ垎褰掕繕鎴愬姛锛�"); + } else { + ElMessage.success("鎿嶄綔鎴愬姛锛�"); + } + + emit("submit", submitData); + } + handleClose(); + } catch (error) { + console.error('鎻愪氦澶辫触:', error); + ElMessage.error("鎿嶄綔澶辫触锛岃绋嶅悗鍐嶈瘯"); + } }); } </script> -- Gitblit v1.9.3