From df1406d0f571972d033dffd6a93fb4b94febeb56 Mon Sep 17 00:00:00 2001 From: gaoluyang <2820782392@qq.com> Date: 星期二, 24 六月 2025 16:46:44 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev --- src/views/production/components/ProductionDialog.vue | 468 +++++++++++++++++++++++++++++---------------------------- 1 files changed, 239 insertions(+), 229 deletions(-) diff --git a/src/views/production/components/ProductionDialog.vue b/src/views/production/components/ProductionDialog.vue index d95d9ae..3b96834 100644 --- a/src/views/production/components/ProductionDialog.vue +++ b/src/views/production/components/ProductionDialog.vue @@ -1,27 +1,30 @@ <template> <el-dialog - v-model="dialogVisible" - :title="dialogType === 'add' ? '鏂板鐢熶骇鍔犲伐' : '缂栬緫鐢熶骇鍔犲伐'" - width="1200px" - :close-on-click-modal="false" - @close="handleClose" + v-model="dialogVisible" + :title="dialogType === 'add' ? '鏂板鐢熶骇鍔犲伐' : '缂栬緫鐢熶骇鍔犲伐'" + width="1200px" + :close-on-click-modal="false" + @close="handleClose" > <el-row :gutter="10" style="margin-bottom: 10px"> <el-col :span="3"> <el-button type="primary" @click="handlData" - ><el-icon> - <Plus /> </el-icon - >閫夋嫨鏁版嵁</el-button + > + <el-icon> + <Plus/> + </el-icon> + 閫夋嫨鏁版嵁 + </el-button > </el-col> <el-col :span="4"> <el-button - type="danger" - @click="removeSelectedData" - :disabled="tableData.length === 0" + type="danger" + @click="removeSelectedData" + :disabled="tableData.length === 0" > <el-icon> - <Delete /> + <Delete/> </el-icon> 娓呯┖宸查�� </el-button> @@ -36,15 +39,15 @@ </el-col> </el-row> <ETableModify - :columns="columns" - :showOperations="false" - height="200" - @cell-edit="handleCellEdit" - :tableData="tableData" - :showOverflowTooltip="false" - @row-click="handleRowClick" - :editableColumns="['usedQuantity']" - @delete="handleRemoveItem" + :columns="columns" + :showOperations="false" + height="200" + @cell-edit="handleCellEdit" + :tableData="tableData" + :showOverflowTooltip="false" + @row-click="handleRowClick" + :editableColumns="['usedQuantity']" + @delete="handleRemoveItem" /> <div class="empty-table"> <h1>鐢熶骇鏄庣粏</h1> @@ -52,78 +55,77 @@ <el-col :span="2"> <el-button type="primary" @click="addNewRow"> <el-icon> - <Plus /> + <Plus/> </el-icon> 鏂板 </el-button> </el-col> - <el-col :span="2"> + <!-- <el-col :span="2"> <el-button type="danger" @click="clearAllRows"> <el-icon> <Delete /> </el-icon> 娓呯┖ </el-button> - </el-col> - <!-- <el-col :span="2"> - <el-button type="warning" @click="calculateAllCosts"> - <el-icon> - <Warning /> - </el-icon> 閲嶆柊璁$畻 - </el-button> - </el-col> --> + </el-col> --> </el-row> <ProductionDetailsTable - v-model="detailsTableData" - :border="false" - :show-operations="true" - :auto-calculate="true" - @input-change="handleDetailsChange" - @delete-row="handleDeleteRow" + v-model="detailsTableData" + :border="false" + :show-operations="true" + :auto-calculate="true" + @input-change="handleDetailsChange" + @delete-row="handleDeleteRow" /> </div> <template #footer> <div class="dialog-footer"> - <el-button @click="handleClose" v-if="dialogType === 'add'" - >鍙� 娑�</el-button + <el-button + @click="handleClose" + v-if="dialogType === 'add' || dialogType === 'edit'" + >鍙� 娑� + </el-button > - <el-button @click="handleReset" v-if="dialogType === 'edit'" + <!-- <el-button @click="handleReset" v-if="dialogType === 'edit'" >閲� 缃�</el-button - > + > --> <el-button type="primary" :loading="loading" @click="handleSubmit" - >纭� 瀹�</el-button + >纭� 瀹� + </el-button > </div> </template> </el-dialog> <el-dialog - v-model="innerVisible" - width="1000" - title="閫夋嫨閰嶇疆鏁版嵁" - center - append-to-body + v-model="innerVisible" + width="1000" + title="閫夋嫨閰嶇疆鏁版嵁" + center + append-to-body > <div style="margin-bottom: 10px"> <el-alert - v-if="tableData.length > 0" - :title="`褰撳墠宸查�夋嫨 ${tableData.length} 鏉℃暟鎹甡" - type="info" - :closable="false" - show-icon + v-if="tableData.length > 0" + :title="`褰撳墠宸查�夋嫨 ${tableData.length} 鏉℃暟鎹甡" + type="info" + :closable="false" + show-icon /> </div> <ETable - @selection-change="handleSelectionChange" - :showOperations="false" - ref="etableRef" - :columns="formalDatabaseColumns" - :tableData="formalDatabaseData" - :defaultSelectedIds="selectedIds" - :rowKey="'id'" - height="400" - @cell-edit="handleCellEdit" - :show-selection="true" + :showIndex="false" + :showOverflowTooltip="false" + @selection-change="handleSelectionChange" + :showOperations="false" + ref="etableRef" + :columns="formalDatabaseColumns" + :tableData="formalDatabaseData" + :defaultSelectedIds="selectedIds" + :rowKey="'id'" + height="400" + @cell-edit="handleCellEdit" + :show-selection="true" /> <el-row :gutter="24" style="margin-top: 15px"> <el-col :span="12"> @@ -134,9 +136,9 @@ <el-col :span="12" style="text-align: right"> <el-button @click="innerVisible = false">鍙栨秷</el-button> <el-button - type="primary" - @click="handleSelectData" - :disabled="formalDatabaseSelectedData.length === 0" + type="primary" + @click="handleSelectData" + :disabled="formalDatabaseSelectedData.length === 0" > 纭畾娣诲姞 </el-button> @@ -146,44 +148,61 @@ </template> <script setup> -import { ref, reactive, watch, onMounted, nextTick, computed } from "vue"; +import {ref, reactive, watch, onMounted, nextTick, computed} from "vue"; import ETable from "@/components/Table/ETable.vue"; import ETableModify from "@/components/Table/EtableModify.vue"; import ProductionDetailsTable from "./ProductionDetailsTable.vue"; -import { ElMessage, ElMessageBox, ElAlert, ElText } from "element-plus"; -import { Delete, Warning, Plus } from "@element-plus/icons-vue"; -import { getOfficialAll, addOrEditPM } from "@/api/production/index.js"; -import { getCurrentInstance } from "vue"; +import {ElMessage, ElMessageBox, ElAlert, ElText} from "element-plus"; +import {Delete, Warning, Plus} from "@element-plus/icons-vue"; +import { + getOfficialAll, + addOrEditPM, + getCoalInfoList, + deleteProductionInventory, +} from "@/api/production/index.js"; +import {validateFormData, validateNumber, deepClone, createDefaultProductionRow} from "@/utils/production"; +import {useCoalData} from "./useCoalData"; +import useUserStore from "@/store/modules/user"; +// Props 鍜� Emits const props = defineProps({ - visible: { - type: Boolean, - default: false, - }, - type: { - type: String, - default: "add", // 'add' 鎴� 'edit' - }, - rowData: { - type: Object, - default: () => ({}), - }, + visible: {type: Boolean, default: false}, + type: {type: String, default: "add"}, + rowData: {type: Object, default: () => ({})}, }); -const dialogVisible = defineModel("visible", { - type: Boolean, - default: false, -}); -const emit = defineEmits(["update:visible", "success"]); +const dialogVisible = defineModel("visible", {type: Boolean, default: false}); +const emit = defineEmits(["update:visible", "success", "update:productionAndProcessing"]); + +// 鐢ㄦ埛淇℃伅鍜岀叅绉嶆暟鎹� +const userStore = useUserStore(); +const {getCoalNameById} = useCoalData(); +let userInfo; + +// 瀵硅瘽妗嗙姸鎬� const innerVisible = ref(false); const dialogType = ref("add"); const loading = ref(false); -const formRef = ref(null); +const etableRef = ref(null); + +// 鏁版嵁鐘舵�� const tableData = ref([]); +const detailsTableData = ref([]); +const formalDatabaseData = ref([]); +const formalDatabaseSelectedData = ref([]); +const selectedIds = ref([]); const currentRow = ref(null); +const copyForm = ref(null); +const coalList = ref([]) +const supplierList = ref({}); +// 琛ㄦ牸鍒楅厤缃� const columns = [ - { label: "鐓ょ", prop: "coal", minwidth: 120 }, - { label: "搴撳瓨鏁伴噺", prop: "inventoryQuantity", minwidth: 100 }, + {prop: "coalId", label: "鐓ょ", minwidth: 60,slot:false, + formatter: (row) => { + return coalList.value.find(coal => coal.id === row.coalId)?.coal || "--"; + } + }, + {label: "搴撳瓨鏁伴噺", prop: "inventoryQuantity", minwidth: 100}, { label: "浣跨敤鏁伴噺", prop: "usedQuantity", @@ -192,50 +211,50 @@ editType: "number", }, ]; -const etableRef = ref(null); -const selectedIds = ref([]); // 榛樿閫変腑鐨処D鏁扮粍 -// 璋冭瘯鍑芥暟锛氶獙璇両D鍖归厤閫昏緫 + +const formalDatabaseColumns = ref([ + {prop: "supplierName", label: "渚涘簲鍟嗗悕绉�", minwidth: 150 + // ,formatter: (row) => { + // console.log(row); + // return supplierList.value[row.supplierId] || "--"; + // } + }, + {prop: "coalId", label: "鐓ょ", minwidth: 60, + formatter: (row) => { + // return coalList.value[row.coalId].coal || "--"; + return coalList.value.find(coal => coal.id === row.coalId)?.coal || "--"; + } + }, + {prop: "inventoryQuantity", label: "搴撳瓨鏁伴噺", minwidth: 80}, + {prop: "unit", label: "鍗曚綅", minwidth: 20}, + {prop: "priceExcludingTax", label: "鍗曚环锛堜笉鍚◣锛�", minwidth: 80}, + {prop: "createTime", label: "鐧昏鏃ユ湡", width: 200}, +]); +// 宸ュ叿鍑芥暟 const debugIdMatching = () => { if (formalDatabaseData.value.length > 0 && selectedIds.value.length > 0) { const matchedRows = formalDatabaseData.value.filter((row) => - selectedIds.value.includes(row.id) + selectedIds.value.includes(row.id) ); } }; -const detailsTableData = ref([]); + const handleRowClick = (row) => { currentRow.value = row; }; -const formalDatabaseColumns = ref([ - { prop: "supplierName", label: "渚涘簲鍟嗗悕绉�", minwidth: 150 }, - { prop: "coal", label: "鐓ょ绫诲瀷", minwidth: 60 }, - { prop: "inventoryQuantity", label: "搴撳瓨鏁伴噺", minwidth: 80 }, - { prop: "unit", label: "鍗曚綅", minwidth: 100 }, - { prop: "priceExcludingTax", label: "鍗曚环锛堜笉鍚◣锛�", minwidth: 80 }, - { prop: "createTime", label: "鐧昏鏃ユ湡", minwidth: 400 }, -]); -// 琛ㄥ崟鏁版嵁 -const formData = reactive({ - category: "", - unit: "", - productionVolume: 0, - laborCost: 0, - materialCost: 0, - equipmentCost: 0, - totalCost: 0, - totalPrice: 0, - profit: 0, - reviewer: "", - date: "", -}); + +// 鑾峰彇閰嶇疆鏁版嵁 const handlData = async () => { innerVisible.value = true; - let res = await getOfficialAll(); - if (res.code === 200) { - formalDatabaseData.value = res.data; + let getSupplier = await getOfficialAll(); + let getCoalName = await getCoalInfoList(); + coalList.value = getCoalName.data || []; + supplierList.value = getSupplier.data || []; + if (getSupplier.code === 200) { + formalDatabaseData.value = getSupplier.data; const existingOfficialIds = tableData.value - .map((item) => item.officialId) - .filter((id) => id); + .map((item) => item.officialId) + .filter((id) => id); selectedIds.value = existingOfficialIds; debugIdMatching(); nextTick(() => { @@ -258,53 +277,40 @@ nextTick(() => { setTimeout(() => { try { - // 鍏堟竻闄ゆ墍鏈夐�変腑 etableRef.value.clearSelection(); - - // 鎵惧埌闇�瑕侀�変腑鐨勮骞惰缃�変腑鐘舵�� - // 娉ㄦ剰锛歩ds涓槸officialId锛岄渶瑕佸尮閰峟ormalDatabaseData涓殑id瀛楁 const rowsToSelect = formalDatabaseData.value.filter((row) => - ids.includes(row.id) + ids.includes(row.id) ); if (rowsToSelect.length > 0) { etableRef.value.setRowsSelection(rowsToSelect, true); - console.log("閫変腑鐘舵�佽缃畬鎴�"); - } else { } } catch (error) { - console.error("璁剧疆閫変腑鐘舵�佸け璐�:", error); } }, 150); }); }; -const formalDatabaseData = ref([]); -const formalDatabaseSelectedData = ref([]); -formalDatabaseData.value = []; -// 鍒濆鍖� +// 鍒濆鍖栧拰缂栬緫鍒濆鍖� const Initialization = () => { tableData.value = []; detailsTableData.value = []; copyForm.value = null; dialogType.value = "add"; }; -const copyForm = ref(null); + const editInitialization = (data) => { - copyForm.value = { ...data }; // 娣辨嫹璐濇暟鎹� + copyForm.value = deepClone(data); tableData.value = data.productionInventoryList || []; detailsTableData.value = data.productionList || []; dialogType.value = "edit"; - - // 璁剧疆榛樿閫変腑鐨処D锛屼娇鐢╫fficialId鏉ュ尮閰� const existingOfficialIds = tableData.value - .map((item) => item.officialId) - .filter((id) => id); + .map((item) => item.officialId) + .filter((id) => id); selectedIds.value = existingOfficialIds; }; // 鐩戝惉瀵硅瘽妗嗙姸鎬侊紝鍦ㄦ墦寮�鏃惰缃�変腑鐘舵�� watch(innerVisible, (newVal) => { if (newVal && selectedIds.value.length > 0) { - console.log("瀵硅瘽妗嗘墦寮�锛岃缃�変腑鐘舵��"); setTimeout(() => setTableSelection(selectedIds.value), 200); } // 瀵硅瘽妗嗗叧闂椂娓呯┖閫夋嫨鐘舵�� @@ -340,12 +346,9 @@ // 鏇存柊selectedIds锛岀‘淇濆寘鍚墍鏈夊綋鍓峵ableData涓殑officialId const allOfficialIds = tableData.value - .map((item) => item.officialId) - .filter((id) => id); + .map((item) => item.officialId) + .filter((id) => id); selectedIds.value = allOfficialIds; - - console.log("鏇存柊鍚庣殑琛ㄦ牸鏁版嵁:", tableData.value); - console.log("鏇存柊鍚庣殑閫変腑ID:", selectedIds.value); // 鍏抽棴閫夋嫨瀵硅瘽妗� innerVisible.value = false; @@ -367,94 +370,99 @@ const handleSelectionChange = (selection) => { formalDatabaseSelectedData.value = selection; }; -const handleReset = () => { - console.log(copyForm.value); - tableData.value = - JSON.parse(JSON.stringify(copyForm.value.productionInventoryList)) || []; - detailsTableData.value = - JSON.parse(JSON.stringify(copyForm.value.productionList)) || []; -}; -// 鎻愪氦琛ㄥ崟 +// 鎻愪氦琛ㄥ崟 - 浣跨敤宸ュ叿鍑芥暟楠岃瘉 const handleSubmit = async () => { - let data = { - productionList: detailsTableData.value, - productionInventoryList: tableData.value, - ...copyForm.value, - }; - let res = await addOrEditPM(data); - if (res.code === 200) { - dialogVisible.value = false; - emit("success"); - } else { - ElMessage.error("鎻愪氦澶辫触"); + // 楠岃瘉鐢熶骇鏄庣粏鏁版嵁 + const detailsValidation = validateFormData(detailsTableData.value, [ + "coalId", + "productionQuantity", + "laborCost", + "energyConsumptionCost", + "equipmentDepreciation", + "purchasePrice" + ]); + + if (!detailsValidation.isValid) { + ElMessage.warning(detailsValidation.message); + return; + } + + // 楠岃瘉搴撳瓨浣跨敤鏁版嵁 + if (tableData.value.length === 0) { + ElMessage.warning("璇锋坊鍔犵敓浜у姞宸ユ暟鎹�"); + return; + } + + for (let i = 0; i < tableData.value.length; i++) { + const element = tableData.value[i]; + if (element.usedQuantity == 0 || element.usedQuantity === null) { + ElMessage.warning(`璇峰~鍐欎娇鐢ㄦ暟閲�: ${element.coal}`); + return; + } + } + + try { + const data = { + ...copyForm.value, + productionList: detailsTableData.value, + productionInventoryList: tableData.value, + }; + const res = await addOrEditPM(data); + if (res.code === 200) { + dialogVisible.value = false; + emit("success"); + } else { + ElMessage.error("鎻愪氦澶辫触"); + } + } catch (error) { + ElMessage.error("鎻愪氦澶辫触锛岃閲嶈瘯"); } }; - // 鍏抽棴寮圭獥 const handleClose = () => { dialogVisible.value = false; - formRef.value?.resetFields(); - Object.assign(formData, { - category: "", - unit: "", - productionVolume: 0, - laborCost: 0, - materialCost: 0, - equipmentCost: 0, - totalCost: 0, - totalPrice: 0, - profit: 0, - reviewer: "", - date: "", - }); }; -// 娣诲姞鍗曞厓鏍肩紪杈戝鐞嗗嚱鏁� +// 浣跨敤鏁伴噺楠岃瘉 - 浣跨敤宸ュ叿鍑芥暟 const handleCellEdit = (row, prop, value) => { if (prop === "usedQuantity") { - const numValue = Number(value); - const inventory = Number(row.inventoryQuantity); + const validation = validateNumber(value, 0, Number(row.inventoryQuantity)); - // 楠岃瘉杈撳叆鍊� - if (isNaN(numValue) || numValue < 0) { - ElMessage.warning("浣跨敤鏁伴噺蹇呴』鏄潪璐熸暟锛�"); - row.usedQuantity = 0; + if (!validation.isValid) { + ElMessage.warning(validation.message); + row.usedQuantity = validation.value; return; } - if (numValue > inventory) { - ElMessage.warning(`浣跨敤鏁伴噺涓嶈兘澶т簬搴撳瓨鏁伴噺锛�${inventory}锛夛紒`); - row.usedQuantity = inventory; - return; - } - - // 鏇存柊鍊� - row.usedQuantity = numValue; - console.log(`鏇存柊 ${row.coal} 鐨勪娇鐢ㄦ暟閲忎负: ${numValue}`); + row.usedQuantity = validation.value; } }; -// 澶勭悊鐢熶骇鏄庣粏琛ㄦ牸鐨勬搷浣� +// 澶勭悊鐢熶骇鏄庣粏琛ㄦ牸鐨勬搷浣� - 浣跨敤宸ュ叿鍑芥暟 const addNewRow = () => { - detailsTableData.value.push({ - coal: "", - productionQuantity: "", - laborCost: "", - energyConsumptionCost: "", - equipmentDepreciation: "", - purchasePrice: "", - autoCalculate: "0.00", - producer: "", - }); + const newRow = createDefaultProductionRow(userInfo); + detailsTableData.value.push(newRow); }; -const clearAllRows = () => { - detailsTableData.value = []; - ElMessage.success("宸叉竻绌烘墍鏈夋暟鎹�"); +// 閲嶇疆鏁版嵁 - 浣跨敤娣辨嫹璐� +const handleReset = () => { + if (copyForm.value) { + tableData.value = deepClone(copyForm.value.productionInventoryList) || []; + detailsTableData.value = deepClone(copyForm.value.productionList) || []; + } }; +// 鑾峰彇鐢ㄦ埛淇℃伅 +onMounted(async () => { + try { + userInfo = await userStore.getInfo(); + } catch (error) { + ElMessage.error("鑾峰彇鐢ㄦ埛淇℃伅澶辫触锛岃閲嶈瘯"); + } +}); + +// 绠�鍖栫殑浜嬩欢澶勭悊鍑芥暟 const handleDetailsChange = (data) => { - console.log("鐢熶骇鏄庣粏鏁版嵁鍙樺寲:", data); }; const handleDeleteRow = (index) => { @@ -463,22 +471,17 @@ // 鍒犻櫎鍗曚釜宸查�夋暟鎹」 const handleRemoveItem = (row) => { - console.log("鍒犻櫎椤�:", row); const index = tableData.value.findIndex( - (item) => item.officialId === row.officialId + (item) => item.officialId === row.officialId ); if (index > -1) { tableData.value.splice(index, 1); // 鏇存柊selectedIds const updatedOfficialIds = tableData.value - .map((item) => item.officialId) - .filter((id) => id); + .map((item) => item.officialId) + .filter((id) => id); selectedIds.value = updatedOfficialIds; - - console.log("鍒犻櫎鍚庣殑琛ㄦ牸鏁版嵁:", tableData.value); - console.log("鏇存柊鍚庣殑閫変腑ID:", selectedIds.value); - ElMessage.success("宸插垹闄ら�変腑椤�"); } }; @@ -489,21 +492,27 @@ ElMessage.warning("娌℃湁鍙竻绌虹殑鏁版嵁"); return; } - ElMessageBox.confirm("纭娓呯┖鎵�鏈夊凡閫夋嫨鐨勬暟鎹悧锛�", "璀﹀憡", { confirmButtonText: "纭畾", cancelButtonText: "鍙栨秷", type: "warning", }) - .then(() => { - tableData.value = []; - selectedIds.value = []; - console.log("宸叉竻绌烘墍鏈夊凡閫夋暟鎹�"); - ElMessage.success("宸叉竻绌烘墍鏈夋暟鎹�"); - }) - .catch(() => { - console.log("鍙栨秷娓呯┖鎿嶄綔"); - }); + .then(async () => { + if (dialogType.value === "edit") { + let res = await deleteProductionInventory({ + productionInventoryList: tableData.value, + }); + emit("update:productionAndProcessing", tableData.value, copyForm.value); + } + // [Vue warn]: Component emitted event "update:productionAndProcessing" but it is neither declared in the emits option nor as an "onUpdate:productionAndProcessing" prop. + + formalDatabaseSelectedData.value = []; + tableData.value = []; + selectedIds.value = []; + ElMessage.success("宸叉竻绌烘墍鏈夋暟鎹�"); + }) + .catch(() => { + }); }; // 璁$畻鎬讳娇鐢ㄩ噺 @@ -526,6 +535,7 @@ .el-row > .el-col > h1 { font-weight: bolder; } + .empty-table > .el-row { margin-bottom: 12px; } -- Gitblit v1.9.3