From 7619d415522ab3dc3299d6a2a9f5c9964a692d3f Mon Sep 17 00:00:00 2001 From: 张诺 <zhang_12370@163.com> Date: 星期三, 18 六月 2025 17:58:53 +0800 Subject: [PATCH] 添加生产管理接口及优化表格字段 --- src/views/production/components/ProductionDetailsTable.vue | 358 ++++++++++--- src/views/production/components/useDialog.js | 56 ++ src/api/publicApi/index.js | 12 src/api/production/index.js | 19 src/views/production/index.vue | 169 ++---- src/views/archiveManagement/index.vue | 33 - src/views/production/components/useTableData.js | 136 +++++ src/components/Pagination/index.vue | 2 src/components/Table/ETable.vue | 40 + src/utils/production.js | 141 +++++ src/views/production/components/ProductionDialog.vue | 297 +++++------ src/views/procureMent/index.vue | 7 /dev/null | 88 --- src/views/archiveManagement/mould/archiveDialog.vue | 8 src/views/procureMent/components/ProductionDialog.vue | 4 src/components/Table/EtableModify.vue | 2 src/components/FileUpload/index.vue | 9 src/views/production/components/useCoalData.js | 96 +++ 18 files changed, 966 insertions(+), 511 deletions(-) diff --git a/src/api/production/index.js b/src/api/production/index.js index 9cb0823..eb6faaf 100644 --- a/src/api/production/index.js +++ b/src/api/production/index.js @@ -49,3 +49,22 @@ }) } +// /productionMaster/deleteProductionInventory +// 鍒犻櫎涓昏〃 +export function deleteProductionInventory(data) { + return request({ + url: '/productionMaster/deleteProductionInventory', + method: 'delete', + data: data + }) +} + +// /productionMaster/delPM +// 鍒犻櫎涓昏〃 +export function delPM(data) { + return request({ + url: '/productionMaster/delPM', + method: 'delete', + data: data + }) +} \ No newline at end of file diff --git a/src/api/publicApi/index.js b/src/api/publicApi/index.js new file mode 100644 index 0000000..8156ad0 --- /dev/null +++ b/src/api/publicApi/index.js @@ -0,0 +1,12 @@ +// 鏂囨。绠$悊 +import request from '@/utils/request' + + +// /system/user/listAll +// 鏌ヨ鎵�鏈夌敤鎴峰垪琛� +export function userListAll() { + return request({ + url: '/system/user/listAll', + method: 'get' + }) +} \ No newline at end of file diff --git a/src/components/FileUpload/index.vue b/src/components/FileUpload/index.vue index d8aa818..fd5271e 100644 --- a/src/components/FileUpload/index.vue +++ b/src/components/FileUpload/index.vue @@ -131,7 +131,13 @@ number.value = 0; } const editInit = (val) => { - console.log("editInit", val); + fileList.value = []; + val.storageBlobDTO.forEach(element => { + console.log("缂栬緫鍒濆鍖�", element); + fileList.value.push(element); + uploadedSuccessfully(); + }); + // uploadList.value.push }; defineExpose({ init, @@ -179,6 +185,7 @@ }) .then((response) => { if (response.data.code === 200) { + console.log("涓婁紶鎴愬姛", response.data); handleUploadSuccess(response.data, param.file); // 鏇存柊鐖剁粍浠� emit("update:modelValue", fileList.value); diff --git a/src/components/Pagination/index.vue b/src/components/Pagination/index.vue index 56569f7..0348dec 100644 --- a/src/components/Pagination/index.vue +++ b/src/components/Pagination/index.vue @@ -59,7 +59,7 @@ } }) -const emit = defineEmits() +const emit = defineEmits(['update:page', 'update:limit', 'pagination']) const currentPage = computed({ get() { return props.page diff --git a/src/components/Table/ETable.vue b/src/components/Table/ETable.vue index 13d2dda..24fe060 100644 --- a/src/components/Table/ETable.vue +++ b/src/components/Table/ETable.vue @@ -18,9 +18,13 @@ style="width: 100%" > <el-table-column v-if="showSelection" type="selection" width="55" align="center" /> - <el-table-column v-if="showIndex" label="搴忓彿" type="index" width="60" align="center" /> + <el-table-column v-if="showIndex" label="搴忓彿" width="60" align="center" fixed="left"> + <template #default="scope"> + {{ getRowIndex(scope.$index) }} + </template> + </el-table-column> <template v-for="col in columns" :key="col.prop"> - <el-table-column v-bind="col" :show-overflow-tooltip="shouldShowTooltip(col, tableData)" + <el-table-column v-bind="col" :formatter="col.formatter || defaultFormatter" align="center"> <template v-if="col.slot" #default="scope"> <slot :name="col.prop" :row="scope.row" :column="scope.column" :index="scope.$index"></slot> @@ -139,24 +143,22 @@ rowKey: { type: String, default: 'id' - }, - showOverflowTooltip: { + }, showOverflowTooltip: { type: Boolean, default: true + }, + // 褰撳墠椤电爜 + currentPage: { + type: Number, + default: 1 + }, + // 姣忛〉澶у皬 + pageSize: { + type: Number, + default: 10 } }) const tableRef = ref(null) -// 妫�鏌ュ垪鏄惁闇�瑕佹樉绀簍ooltip -const shouldShowTooltip = (col, data) => { - // 濡傛灉鍒楅厤缃腑鏄庣‘璁剧疆浜唖howOverflowTooltip锛屼娇鐢ㄨ璁剧疆 - if (col.hasOwnProperty('showOverflowTooltip')) { - return col.showOverflowTooltip; - } - // 濡傛灉娌℃湁prop锛岀洿鎺ヨ繑鍥瀎alse - if (!col.prop) return false; - // 妫�鏌ヨ鍒楀湪鎵�鏈夋暟鎹腑鏄惁鏈夐潪绌哄�硷紝榛樿鏄剧ずtooltip - return data.some(row => row[col.prop] != null && row[col.prop] !== ''); -}; // 榛樿鐨勬牸寮忓寲鍑芥暟 const defaultFormatter = (row, column, cellValue) => { @@ -188,6 +190,11 @@ const handleExport = (row) => { emit('export', row) } + +// 璁$畻鍒嗛〉搴忓彿 +const getRowIndex = (index) => { + return (props.currentPage - 1) * props.pageSize + index + 1; +}; // 姝g‘鐨� toggleRowSelection 鏂规硶锛氶拡瀵瑰崟琛� const toggleRowSelection = (row, selected) => { @@ -270,6 +277,9 @@ </script> <style scoped> + :deep(.el-tooltip) { + justify-content: center !important; + } .el-table { margin: 20px 0 !important; } diff --git a/src/components/Table/EtableModify.vue b/src/components/Table/EtableModify.vue index cf21bc2..9afb58d 100644 --- a/src/components/Table/EtableModify.vue +++ b/src/components/Table/EtableModify.vue @@ -32,7 +32,7 @@ <template v-for="col in columns" :key="col.prop"> <el-table-column v-bind="col" - :show-overflow-tooltip="shouldShowTooltip(col, tableData)" + :show-overflow-tooltip="false" align="center" > <template #default="scope"> diff --git a/src/utils/production.js b/src/utils/production.js new file mode 100644 index 0000000..ce5fbdc --- /dev/null +++ b/src/utils/production.js @@ -0,0 +1,141 @@ +/** + * 鐢熶骇妯″潡宸ュ叿鍑芥暟 + * 鎻愪緵鏁版嵁澶勭悊銆侀獙璇併�佽浆鎹㈢瓑閫氱敤鏂规硶 + */ + +/** + * 瑙f瀽鐓ょ鏁扮粍瀛楃涓� + * @param {string|array} coalString - 鐓ょ瀛楃涓叉垨鏁扮粍 + * @returns {array} 瑙f瀽鍚庣殑鐓ょ鏁扮粍 + */ +export function parseCoalArray(coalString) { + if (!coalString) return []; + + if (Array.isArray(coalString)) return coalString; + + return String(coalString) + .replace(/^\[|\]$/g, '') + .split(',') + .map(item => item.trim()) + .filter(Boolean); +} + +/** + * 鏍规嵁ID鍖归厤鍒楄〃涓殑椤圭洰 + * @param {array} list - 鏁版嵁鍒楄〃 + * @param {string|number} value - 瑕佸尮閰嶇殑鍊� + * @param {string} keyField - 閿瓧娈靛悕锛岄粯璁や负'id' + * @param {string} valueField - 鍊煎瓧娈靛悕锛岄粯璁や负'fieldName' + * @returns {string} 鍖归厤鍒扮殑鍊兼垨鍘熷�� + */ +export function matchItemById(list, value, keyField = 'id', valueField = 'fieldName') { + if (!Array.isArray(list) || !value) return value; + + const found = list.find(item => item[keyField] == value); + return found ? found[valueField] : value; +} + +/** + * 璁$畻鎬绘垚鏈� + * @param {object} row - 鏁版嵁琛� + * @param {array} fields - 闇�瑕佽绠楃殑瀛楁鏁扮粍 + * @returns {string} 鏍煎紡鍖栧悗鐨勬�绘垚鏈� + */ +export function calculateTotalCost(row, fields = ['laborCost', 'energyConsumptionCost', 'equipmentDepreciation', 'purchasePrice']) { + const total = fields.reduce((sum, field) => { + return sum + (parseFloat(row[field]) || 0); + }, 0); + + return total.toFixed(2); +} + +/** + * 楠岃瘉琛ㄥ崟鏁版嵁 + * @param {array} data - 琛ㄥ崟鏁版嵁鏁扮粍 + * @param {array} requiredFields - 蹇呭~瀛楁 + * @returns {object} 楠岃瘉缁撴灉 { isValid, message } + */ +export function validateFormData(data, requiredFields) { + if (!data || data.length === 0) { + return { isValid: false, message: '璇锋坊鍔犳暟鎹�' }; + } + + for (let i = 0; i < data.length; i++) { + const item = data[i]; + for (const field of requiredFields) { + if (item[field] === '' || item[field] === null || item[field] === undefined) { + return { + isValid: false, + message: `绗�${i + 1}琛岀殑${field}瀛楁涓嶈兘涓虹┖` + }; + } + } + } + + return { isValid: true, message: '楠岃瘉閫氳繃' }; +} + +/** + * 鏁板�奸獙璇� + * @param {any} value - 瑕侀獙璇佺殑鍊� + * @param {number} min - 鏈�灏忓�� + * @param {number} max - 鏈�澶у�� + * @returns {object} 楠岃瘉缁撴灉 { isValid, message, value } + */ +export function validateNumber(value, min = 0, max = Infinity) { + const numValue = Number(value); + + if (isNaN(numValue)) { + return { isValid: false, message: '璇疯緭鍏ユ湁鏁堟暟瀛�', value: 0 }; + } + + if (numValue < min) { + return { isValid: false, message: `鏁板�间笉鑳藉皬浜�${min}`, value: min }; + } + + if (numValue > max) { + return { isValid: false, message: `鏁板�间笉鑳藉ぇ浜�${max}`, value: max }; + } + + return { isValid: true, message: '楠岃瘉閫氳繃', value: numValue }; +} + +/** + * 娣辨嫹璐濆璞� + * @param {any} obj - 瑕佹嫹璐濈殑瀵硅薄 + * @returns {any} 鎷疯礉鍚庣殑瀵硅薄 + */ +export function deepClone(obj) { + if (obj === null || typeof obj !== 'object') return obj; + if (obj instanceof Date) return new Date(obj.getTime()); + if (obj instanceof Array) return obj.map(item => deepClone(item)); + if (typeof obj === 'object') { + const clonedObj = {}; + for (const key in obj) { + if (obj.hasOwnProperty(key)) { + clonedObj[key] = deepClone(obj[key]); + } + } + return clonedObj; + } +} + +/** + * 鐢熸垚榛樿鐨勭敓浜ф槑缁嗚鏁版嵁 + * @param {object} userData - 鐢ㄦ埛鏁版嵁 + * @param {object} extraData - 棰濆鏁版嵁 + * @returns {object} 榛樿琛屾暟鎹� + */ +export function createDefaultProductionRow(userData = {}, extraData = {}) { + return { + coal: "", + productionQuantity: "", + laborCost: "", + energyConsumptionCost: "", + equipmentDepreciation: "", + purchasePrice: "", + totalCost: "0.00", + producer: userData?.user?.nickName || "", + ...extraData + }; +} diff --git a/src/views/archiveManagement/index.vue b/src/views/archiveManagement/index.vue index 486522f..58d41d2 100644 --- a/src/views/archiveManagement/index.vue +++ b/src/views/archiveManagement/index.vue @@ -191,8 +191,6 @@ return data.name?.toLowerCase().includes(value.toLowerCase()); }; const submitForm = async (res) => { - console.log("鎻愪氦琛ㄥ崟鍥炶皟:", res); - if (res && res.code === 200) { ElMessage.success("鎿嶄綔鎴愬姛"); // 鍒锋柊鍒楄〃鏁版嵁 @@ -202,11 +200,9 @@ } } const centerDialogVisible = (val) => { - console.log(val); }; // 澶勭悊鑺傜偣鐐瑰嚮 const handleNodeClick = async (data) => { - console.log("鐐瑰嚮鑺傜偣:", data); // 鍒囨崲鑺傜偣鏃堕噸缃埌绗竴椤� queryParams.current = 1; queryParams.treeId = data.id; @@ -222,7 +218,6 @@ }; // 澶勭悊鍒嗛〉鍙樺寲 const handlePageChange = ({ page }) => { - console.log("鍒嗛〉鍙樺寲:", { page }); queryParams.current = page; // pageSize 鍥哄畾涓�20锛屼笉鍐嶄粠鍙傛暟涓幏鍙� getArchiveListData(); @@ -231,12 +226,6 @@ const getArchiveListData = async () => { try { loading.value = true; - console.log("鑾峰彇褰掓。鍒楄〃鏁版嵁", { - treeId: queryParams.treeId, - current: queryParams.current, - pageSize: queryParams.pageSize, - }); - let res = await getArchiveList({ treeId: queryParams.treeId, current: queryParams.current, @@ -258,14 +247,7 @@ } // pageSize 鍥哄畾涓�20锛屼笉浠庡悗绔幏鍙� - console.log("鏁版嵁鏇存柊瀹屾垚:", { - total: total.value, - current: queryParams.current, - pageSize: queryParams.pageSize, - records: tableData.value.length, - }); } catch (error) { - console.error("鑾峰彇褰掓。鍒楄〃澶辫触:", error); ElMessage.error("鑾峰彇鏁版嵁澶辫触"); tableData.value = []; total.value = 0; @@ -280,7 +262,6 @@ } try { const ids = selectedRows.map((row) => row.id); - console.log(ids) const { code, msg } = await delArchive(ids); if (code !== 200) { ElMessage.warning("鍒犻櫎澶辫触: " + msg); @@ -290,7 +271,6 @@ await getArchiveListData(); } } catch (error) { - console.error("鍒犻櫎褰掓。澶辫触:", error); ElMessage.error("鍒犻櫎褰掓。澶辫触"); } }; @@ -329,11 +309,9 @@ comeTreeData.isEdit = false; const newValue = newName.value.trim(); if (comeTreeData.name === newValue) { - console.log("娌℃湁淇敼鍐呭"); return; } if (newValue === "") { - console.warn("杈撳叆涓嶈兘涓虹┖"); newName.value = comeTreeData.name || "鏂拌妭鐐�"; return; } @@ -349,10 +327,8 @@ parentId: parentId || null, // 濡傛灉娌℃湁鐖惰妭鐐癸紝鍒欎负 null }); } catch (error) { - console.error("瀛樺偍澶辫触", error); comeTreeData.name = comeTreeData.name || "鏂拌妭鐐�"; } - console.log("淇濆瓨鎴愬姛:", newValue); }; onMounted(async () => { @@ -365,12 +341,9 @@ }; const remove = async (node, data) => { - console.log("鍒犻櫎鑺傜偣:", data); if (!data || !data.id) { - console.warn("鏃犳硶鍒犻櫎鏈畾涔夋垨鏃犳晥鐨勮妭鐐�"); return; } - console.log("鍒犻櫎鑺傜偣 ID:", data.id); let { code, msg } = await delTree([data.id]); if (code !== 200) { ElMessage.warning("鍒犻櫎澶辫触, " + msg); @@ -383,7 +356,6 @@ const append = async (data) => { if (data === "") { // 鏂板鏍硅妭鐐� - console.log("鏂板鏍硅妭鐐�"); const newNode = { id: Date.now(), name: "鏂拌妭鐐�", @@ -405,7 +377,6 @@ const node = treeRef.value?.getNode(nodeKey); const isExpanded = node?.expanded; // 濡傛灉鏈夊瓙绾т笖鏈睍寮�锛屽厛灞曞紑鑺傜偣 if (hasChildren && !isExpanded) { - console.log(treeRef.value, "灞曞紑鑺傜偣", nodeKey); if ( treeRef.value && treeRef.value.store && @@ -414,7 +385,6 @@ treeRef.value.store.nodesMap[nodeKey].expanded = true; } } - const newNode = { id: Date.now(), name: "鏂板瓙鑺傜偣", @@ -453,7 +423,6 @@ row.value = rows; dialogVisible.value = true; archiveDialogs.value.editForm(rows); // 璋冪敤缂栬緫鏂规硶 - // console.log("缂栬緫琛屾暟鎹�:", archiveDialogs.value); }; // 绉婚櫎鎳掑姞杞斤紝鐩存帴鑾峰彇鏁版嵁 @@ -463,11 +432,9 @@ if (res.code === 200) { treeData.value = res.data?.records || res.data || []; } else { - console.error("Failed to fetch tree data:", res.message); treeData.value = []; } } catch (error) { - console.error("鑾峰彇鏍戝舰鏁版嵁澶辫触:", error); treeData.value = []; } }; diff --git a/src/views/archiveManagement/mould/archiveDialog.vue b/src/views/archiveManagement/mould/archiveDialog.vue index 844bd1a..5406cc2 100644 --- a/src/views/archiveManagement/mould/archiveDialog.vue +++ b/src/views/archiveManagement/mould/archiveDialog.vue @@ -103,9 +103,7 @@ }; const editForm = (val) => { ruleForm.value = copyForm.value; - // fileUploadRef.value.editInit(ruleForm.value); nextTick(() => { - // console.log("缂栬緫琛ㄥ崟鏁版嵁:", fileUploadRef.value); fileUploadRef.value.editInit(val); }); @@ -144,7 +142,6 @@ type: "error", message: error.msg || "鎿嶄綔澶辫触", }); - console.error("API 璋冪敤澶辫触:", error); return; } // 鍙戦�� emit 浜嬩欢 @@ -152,7 +149,10 @@ // 鍏抽棴瀵硅瘽妗� centerDialogVisible.value = false; } catch (error) { - console.error("琛ㄥ崟楠岃瘉澶辫触鎴朅PI璋冪敤澶辫触:", error); + ElMessage({ + type: "error", + message: error.msg || "鎿嶄綔澶辫触", + }); } }; </script> diff --git a/src/views/procureMent/components/ProductionDialog.vue b/src/views/procureMent/components/ProductionDialog.vue index 3360364..31a6243 100644 --- a/src/views/procureMent/components/ProductionDialog.vue +++ b/src/views/procureMent/components/ProductionDialog.vue @@ -174,9 +174,8 @@ value: item.id, label: item.coal, })); - console.log(supplyList.value, coalList.value); } catch (error) { - console.error("鑾峰彇涓嬫媺鏁版嵁澶辫触:", error); + ElMessage.error("鑾峰彇涓嬫媺鏁版嵁澶辫触锛岃绋嶅悗閲嶈瘯"); } }; @@ -334,7 +333,6 @@ const formRef = ref(null); // 鎻愪氦琛ㄥ崟 const handleSubmit = async () => { - console.log("鎻愪氦琛ㄥ崟", form.value); if (!formRef.value) return; await formRef.value.validate(async (valid) => { if (valid) { diff --git a/src/views/procureMent/index.vue b/src/views/procureMent/index.vue index 0651cd4..ba02734 100644 --- a/src/views/procureMent/index.vue +++ b/src/views/procureMent/index.vue @@ -171,13 +171,6 @@ const handleAddEdit = () => { addOrEdit.value == "add" ? (title.value = "鏂板") : (title.value = "缂栬緫"); title.value = title.value + "閲囪喘淇℃伅"; - - // 姝g‘浣跨敤瀛愮粍浠秗ef - if (productionDialogs.value) { - // 杩欓噷鍙互璋冪敤瀛愮粍浠剁殑鏂规硶 - console.log("瀛愮粍浠跺疄渚�:", productionDialogs.value.getDropdownData()); - } - openDialog(); }; // 鎵撳紑寮圭獥 diff --git a/src/views/production/components/ProductionDetailsTable.vue b/src/views/production/components/ProductionDetailsTable.vue index 678ab65..eb4091b 100644 --- a/src/views/production/components/ProductionDetailsTable.vue +++ b/src/views/production/components/ProductionDetailsTable.vue @@ -1,114 +1,140 @@ <template> - <el-table :data="tableData" :border="border" style="width: 100%"> - <el-table-column label="鐓ょ" min-width="120" > - <template #default="{ row, $index }" > - <el-input - v-model="row.coal" - placeholder="璇疯緭鍏ョ叅绉�" - @input="handleInput('coal', $index, $event)" - /> + <el-table :data="tableData" :border="border" style="width: 100%"> + <el-table-column label="鐓ょ" min-width="120"> + <template #default="{ row, $index }"> + <el-select + clearable + :model-value="getCoalNameById(row.coal) || row.coal" + placeholder="璇烽�夋嫨鐓ょ" + @change="(value) => handleCoalSelectChange(row, value)" + filterable + :key="`coal-select-${$index}-${weekList.length}`" + > + <el-option + v-for="(item, index) of weekList" + :key="`option-${index}-${item.key}`" + :label="item.value" + :value="item.value" + /> + </el-select> </template> </el-table-column> <el-table-column label="鐢熶骇鏁伴噺" min-width="120"> <template #default="{ row, $index }"> - <el-input - v-model="row.productionQuantity" + <el-input + v-model="row.productionQuantity" placeholder="璇疯緭鍏ョ敓浜ф暟閲�" type="number" @input="handleInput('productionQuantity', $index, $event)" /> </template> </el-table-column> - + <el-table-column label="浜哄伐鎴愭湰" min-width="120"> <template #default="{ row, $index }"> - <el-input - v-model="row.laborCost" + <el-input + v-model="row.laborCost" placeholder="璇疯緭鍏ヤ汉宸ユ垚鏈�" type="number" @input="handleInput('laborCost', $index, $event)" > <template #suffix> - <i style="font-style:normal;">鍏�</i> + <i style="font-style: normal">鍏�</i> </template> </el-input> </template> </el-table-column> - + <el-table-column label="鑳借�楁垚鏈�" min-width="120"> <template #default="{ row, $index }"> - <el-input - v-model="row.energyConsumptionCost" + <el-input + v-model="row.energyConsumptionCost" placeholder="璇疯緭鍏ヨ兘鑰楁垚鏈�" type="number" @input="handleInput('energyConsumptionCost', $index, $event)" > <template #suffix> - <i style="font-style:normal;">鍏�</i> + <i style="font-style: normal">鍏�</i> </template> </el-input> </template> </el-table-column> - + <el-table-column label="璁惧鎶樻棫" min-width="120"> <template #default="{ row, $index }"> - <el-input - v-model="row.equipmentDepreciation" + <el-input + v-model="row.equipmentDepreciation" placeholder="璇疯緭鍏ヨ澶囨姌鏃�" type="number" @input="handleInput('equipmentDepreciation', $index, $event)" > <template #suffix> - <i style="font-style:normal;">鍏�</i> + <i style="font-style: normal">鍏�</i> </template> </el-input> </template> </el-table-column> - + <el-table-column label="閲囪喘鍗曚环" min-width="120"> <template #default="{ row, $index }"> - <el-input - v-model="row.purchasePrice" + <el-input + v-model="row.purchasePrice" placeholder="璇疯緭鍏ラ噰璐崟浠�" type="number" @input="handleInput('purchasePrice', $index, $event)" > <template #suffix> - <i style="font-style:normal;">鍏�</i> + <i style="font-style: normal">鍏�</i> </template> </el-input> </template> </el-table-column> - + <el-table-column label="鎬绘垚鏈�" min-width="120"> <template #default="{ row, $index }"> - <el-input - v-model="row.totalCost" + <el-input + disabled + v-model="row.totalCost" placeholder="鎬绘垚鏈�" type="number" :readonly="autoCalculate" @input="handleInput('totalCost', $index, $event)" > <template #suffix> - <i style="font-style:normal;">鍏�</i> + <i style="font-style: normal">鍏�</i> </template> </el-input> </template> </el-table-column> <el-table-column label="鐢熶骇浜�" min-width="120"> <template #default="{ row, $index }"> - <el-input - v-model="row.producer" - placeholder="鐢熶骇浜�" - @input="handleInput('producer', $index, $event)" - /> + <el-select + clearable + :model-value="getUserNameById(row.producer) || row.producer" + placeholder="璇烽�夋嫨鐢熶骇浜�" + @change="(value) => handleUserSelectChange(row, value)" + filterable + :key="`producer-select-${$index}-${userList.length}`" + > + <el-option + v-for="(item, index) of userList" + :key="`option-${index}-${item.key}`" + :label="item.value" + :value="item.value" + /> + </el-select> </template> </el-table-column> - <el-table-column v-if="showOperations" label="鎿嶄綔" width="120" fixed="right"> + <el-table-column + v-if="showOperations" + label="鎿嶄綔" + width="120" + fixed="right" + > <template #default="{ $index }"> - <el-button - type="danger" - size="small" + <el-button + type="danger" + size="small" @click="handleDelete($index)" :icon="Delete" > @@ -120,93 +146,251 @@ </template> <script setup name="ProductionDetailsTable"> -import { ref, computed, watch } from 'vue' -import { Delete } from '@element-plus/icons-vue' - +import { ref, computed, watch, onMounted, nextTick } from "vue"; +import { Delete } from "@element-plus/icons-vue"; +import { getCoalFieldList } from "@/api/basicInformation/coalQualityMaintenance"; +import { userListAll } from "@/api/publicApi"; const props = defineProps({ modelValue: { type: Array, - default: () => [] + default: () => [], }, border: { type: Boolean, - default: false + default: false, }, showOperations: { type: Boolean, - default: true + default: true, }, autoCalculate: { type: Boolean, - default: true - } -}) + default: true, + }, +}); -const emit = defineEmits(['update:modelValue', 'input-change', 'delete-row']) +const emit = defineEmits(["update:modelValue", "input-change", "delete-row"]); // 浣跨敤 v-model 杩涜鍙屽悜缁戝畾 const tableData = computed({ get() { - return props.modelValue + return props.modelValue; }, set(value) { - emit('update:modelValue', value) - } -}) + emit("update:modelValue", value); + }, +}); // 澶勭悊杈撳叆鍙樺寲 const handleInput = (field, index, value) => { - const newData = [...tableData.value] - newData[index][field] = value - + const newData = [...tableData.value]; + newData[index][field] = value; + // 濡傛灉寮�鍚嚜鍔ㄨ绠楁�绘垚鏈� - if (props.autoCalculate && ['laborCost', 'energyCost', 'equipmentDepreciation', 'purchasePrice'].includes(field)) { - calculateTotalCost(newData[index]) + if ( + props.autoCalculate && + [ + "laborCost", + "energyCost", + "equipmentDepreciation", + "purchasePrice", + ].includes(field) + ) { + calculateTotalCost(newData[index]); } - - tableData.value = newData - emit('input-change', { field, index, value, row: newData[index] }) -} + + tableData.value = newData; + emit("input-change", { field, index, value, row: newData[index] }); +}; // 璁$畻鎬绘垚鏈� const calculateTotalCost = (row) => { - const laborCost = parseFloat(row.laborCost) || 0 - const energyCost = parseFloat(row.energyCost) || 0 - const equipmentDepreciation = parseFloat(row.equipmentDepreciation) || 0 - const purchasePrice = parseFloat(row.purchasePrice) || 0 - - row.totalCost = (laborCost + energyCost + equipmentDepreciation + purchasePrice).toFixed(2) -} + const laborCost = parseFloat(row.laborCost) || 0; + const energyCost = parseFloat(row.energyCost) || 0; + const equipmentDepreciation = parseFloat(row.equipmentDepreciation) || 0; + const purchasePrice = parseFloat(row.purchasePrice) || 0; + + row.totalCost = ( + laborCost + + energyCost + + equipmentDepreciation + + purchasePrice + ).toFixed(2); +}; // 鍒犻櫎琛� const handleDelete = (index) => { - const newData = [...tableData.value] - newData.splice(index, 1) - tableData.value = newData - emit('delete-row', index) -} + const newData = [...tableData.value]; + newData.splice(index, 1); + tableData.value = newData; + emit("delete-row", index); +}; +// 澶勭悊鐓ょ閫夋嫨鍙樺寲 + +// 澶勭悊鐓ょ閫夋嫨鍙樺寲锛堟柊鏂规硶锛氬悕绉伴�夋嫨杞琁D锛� +const handleCoalSelectChange = (row, selectedName) => { + // 鏍规嵁閫夋嫨鐨勫悕绉版壘鍒板搴旂殑ID + const coalItem = weekList.value.find(item => item.value === selectedName); + if (coalItem) { + row.coal = coalItem.key; // 璁剧疆涓篒D + } else { + row.coal = ''; // 濡傛灉娌℃壘鍒帮紝娓呯┖ + } +}; + +// 鏍规嵁ID鑾峰彇鐓ょ鍚嶇О锛堢敤浜庢樉绀猴級 +const getCoalNameById = (id) => { + const coal = weekList.value.find(item => item.key == id); + return coal ? coal.value : id; +}; + +const weekList = ref([]); + + +// 鐩戝惉琛ㄦ牸鏁版嵁鍙樺寲锛岀‘淇濇樉绀烘纭� +watch(() => props.modelValue, (newValue) => { + if (newValue && weekList.value.length > 0) { + // 褰撴暟鎹姞杞藉畬鎴愪笖weekList宸茶幏鍙栨椂锛岀‘淇濇樉绀烘纭� + } +}, { deep: true }); + +// 鐩戝惉weekList鍙樺寲锛屽綋涓嬫媺鏁版嵁鍔犺浇瀹屾垚鍚庡鐞嗘樉绀� +watch(weekList, (newList) => { + if (newList.length > 0 && tableData.value.length > 0) { + // 寮哄埗瑙﹀彂琛ㄦ牸閲嶆柊娓叉煋浠ョ‘淇漞l-select姝g‘鏄剧ず + nextTick(() => { + // 瑙﹀彂涓�涓井灏忕殑鏁版嵁鍙樺寲鏉ュ己鍒堕噸鏂版覆鏌� + const tempData = [...tableData.value]; + tableData.value = tempData; + }); + } +}, { deep: true }); + +onMounted(async()=>{ + let res = await getCoalFieldList() + res.data.forEach(item => { + let obj = {}; + obj.value = item.fieldName; + obj.key = item.id; + weekList.value.push(obj); + }); + let ress = await userListAll(); + ress.data.forEach(item => { + let obj = {}; + obj.value = item.nickName; + obj.key = item.userId; + userList.value.push(obj); + }); + // 閫氱煡鐖剁粍浠秝eekList宸插姞杞藉畬鎴� + nextTick(() => { + }); +}) +const dropdownList = ref([]); +// 鑾峰彇涓嬫媺鏁版嵁 +const getDropdownData = async () => { + let res = await getCoalFieldList(); + if (res.code === 200) { + dropdownList.value = res.data.map((item) => ({ + value: item.fieldName, + key: item.id, + })); + } else { + ElMessage.error("鑾峰彇涓嬫媺鏁版嵁澶辫触"); + } +}; +const userList = ref([]); +const getUserList = (async()=>{ + let res = await userListAll(); + if (res.code === 200) { + userList.value = res.data.map((item) => ({ + value: item.nickName, + key: item.userId, + })); + } else { + ElMessage.error("鑾峰彇鐢ㄦ埛鍒楄〃澶辫触"); + } +}) +// 鐩戝惉琛ㄦ牸鏁版嵁鍙樺寲锛岀‘淇濇樉绀烘纭� +watch(() => props.modelValue, (newValue) => { + if (newValue && userList.value.length > 0) { + // 褰撴暟鎹姞杞藉畬鎴愪笖weekList宸茶幏鍙栨椂锛岀‘淇濇樉绀烘纭� + } +}, { deep: true }); + +// 鐩戝惉userList鍙樺寲锛屽綋涓嬫媺鏁版嵁鍔犺浇瀹屾垚鍚庡鐞嗘樉绀� +watch(userList, (newList) => { + if (newList.length > 0 && tableData.value.length > 0) { + // 寮哄埗瑙﹀彂琛ㄦ牸閲嶆柊娓叉煋浠ョ‘淇漞l-select姝g‘鏄剧ず + nextTick(() => { + // 瑙﹀彂涓�涓井灏忕殑鏁版嵁鍙樺寲鏉ュ己鍒堕噸鏂版覆鏌� + const tempData = [...tableData.value]; + tableData.value = tempData; + }); + } +}, { deep: true }); + +const getUserNameById = (id) => { + const producer = userList.value.find(item => item.key == id); + return producer ? producer.value : id; +}; +// 澶勭悊鐢ㄦ埛閫夋嫨鍙樺寲锛堟柊鏂规硶锛氬悕绉伴�夋嫨杞琁D锛� +const handleUserSelectChange = (row, selectedName) => { + // 鏍规嵁閫夋嫨鐨勫悕绉版壘鍒板搴旂殑ID + const userItem = userList.value.find(item => item.value === selectedName); + if (userItem) { + row.producer = userItem.key; // 璁剧疆涓篒D + } else { + row.producer = ''; // 濡傛灉娌℃壘鍒帮紝娓呯┖ + } +}; // 鏆撮湶鏂规硶缁欑埗缁勪欢浣跨敤 defineExpose({ calculateTotalCost, + getDropdownData, + getCoalNameById, // 鏆撮湶鑾峰彇鐓ょ鍚嶇О鐨勬柟娉� + weekList, // 鏆撮湶weekList璁╃埗缁勪欢鍙互璁块棶 addRow: (rowData = {}) => { const defaultRow = { - coal: '', - calorificValue: '', - productionQuantity: '', - laborCost: '', - energyCost: '', - equipmentDepreciation: '', - purchasePrice: '', - totalCost: '', - ...rowData - } - tableData.value = [...tableData.value, defaultRow] + coal: "", + calorificValue: "", + productionQuantity: "", + laborCost: "", + energyCost: "", + equipmentDepreciation: "", + purchasePrice: "", + totalCost: "", + producer: "", + ...rowData, + }; + tableData.value = [...tableData.value, defaultRow]; }, clearData: () => { - tableData.value = [] + tableData.value = []; + }, + // 娣诲姞涓�涓柟娉曟潵绛夊緟weekList鍔犺浇瀹屾垚 + waitForWeekList: () => { + return new Promise((resolve) => { + if (weekList.value.length > 0) { + resolve(); + } else { + const unwatch = watch(weekList, (newList) => { + if (newList.length > 0) { + unwatch(); + resolve(); + } + }); + } + }); + }, + // 寮哄埗鍒锋柊琛ㄦ牸鏄剧ず + forceRefresh: () => { + nextTick(() => { + const tempData = [...tableData.value]; + tableData.value = tempData; + }); } -}) +}); </script> <style scoped> diff --git a/src/views/production/components/ProductionDetailsTableExample.vue b/src/views/production/components/ProductionDetailsTableExample.vue deleted file mode 100644 index eda5955..0000000 --- a/src/views/production/components/ProductionDetailsTableExample.vue +++ /dev/null @@ -1,88 +0,0 @@ -<!-- 浣跨敤绀轰緥 --> -<template> - <div> - <!-- 鍩烘湰浣跨敤 --> - <ProductionDetailsTable v-model="tableData" /> - - <!-- 鑷畾涔夐厤缃� --> - <ProductionDetailsTable - v-model="tableData" - :border="true" - :show-operations="false" - :auto-calculate="false" - @input-change="handleChange" - @delete-row="handleDelete" - /> - - <!-- 鎿嶄綔鎸夐挳 --> - <el-row :gutter="10" style="margin-top: 20px;"> - <el-col :span="4"> - <el-button type="primary" @click="addRow">鏂板琛�</el-button> - </el-col> - <el-col :span="4"> - <el-button type="danger" @click="clearData">娓呯┖鏁版嵁</el-button> - </el-col> - <el-col :span="4"> - <el-button type="success" @click="submitData">鎻愪氦鏁版嵁</el-button> - </el-col> - </el-row> - </div> -</template> - -<script setup> -import { ref } from 'vue' -import ProductionDetailsTable from './ProductionDetailsTable.vue' - -// 琛ㄦ牸鏁版嵁 -const tableData = ref([ - { - coal: '鍔ㄥ姏鐓�', - calorificValue: '5000', - productionQuantity: '100', - laborCost: '1000', - energyCost: '800', - equipmentDepreciation: '500', - purchasePrice: '2000', - totalCost: '4300' - } -]) - -// 鑾峰彇缁勪欢瀹炰緥寮曠敤 -const tableRef = ref(null) - -// 浜嬩欢澶勭悊 -const handleChange = (data) => { - console.log('鏁版嵁鍙樺寲:', data) -} - -const handleDelete = (index) => { - console.log('鍒犻櫎琛�:', index) -} - -// 鎿嶄綔鏂规硶 -const addRow = () => { - if (tableRef.value) { - tableRef.value.addRow({ - coal: '', - calorificValue: '0', - productionQuantity: '0', - laborCost: '0', - energyCost: '0', - equipmentDepreciation: '0', - purchasePrice: '0', - totalCost: '0' - }) - } -} - -const clearData = () => { - if (tableRef.value) { - tableRef.value.clearData() - } -} - -const submitData = () => { - console.log('鎻愪氦鐨勬暟鎹�:', tableData.value) - // 杩欓噷鍙互璋冪敤API鎻愪氦鏁版嵁 -} -</script> diff --git a/src/views/production/components/ProductionDialog.vue b/src/views/production/components/ProductionDialog.vue index d95d9ae..7733da7 100644 --- a/src/views/production/components/ProductionDialog.vue +++ b/src/views/production/components/ProductionDialog.vue @@ -9,9 +9,7 @@ <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"> @@ -57,21 +55,14 @@ 鏂板 </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" @@ -85,12 +76,14 @@ <template #footer> <div class="dialog-footer"> - <el-button @click="handleClose" v-if="dialogType === 'add'" + <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 > @@ -114,6 +107,8 @@ /> </div> <ETable + :showIndex="false" + :showOverflowTooltip="false" @selection-change="handleSelectionChange" :showOperations="false" ref="etableRef" @@ -152,35 +147,45 @@ 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 { + getOfficialAll, + addOrEditPM, + 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 columns = [ { label: "鐓ょ", prop: "coal", minwidth: 120 }, { label: "搴撳瓨鏁伴噺", prop: "inventoryQuantity", minwidth: 100 }, @@ -192,9 +197,16 @@ editType: "number", }, ]; -const etableRef = ref(null); -const selectedIds = ref([]); // 榛樿閫変腑鐨処D鏁扮粍 -// 璋冭瘯鍑芥暟锛氶獙璇両D鍖归厤閫昏緫 + +const formalDatabaseColumns = ref([ + { prop: "supplierName", label: "渚涘簲鍟嗗悕绉�", minwidth: 150 }, + { prop: "coal", label: "鐓ょ绫诲瀷", minwidth: 60 }, + { 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) => @@ -202,32 +214,12 @@ ); } }; -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(); @@ -258,44 +250,32 @@ nextTick(() => { setTimeout(() => { try { - // 鍏堟竻闄ゆ墍鏈夐�変腑 etableRef.value.clearSelection(); - - // 鎵惧埌闇�瑕侀�変腑鐨勮骞惰缃�変腑鐘舵�� - // 娉ㄦ剰锛歩ds涓槸officialId锛岄渶瑕佸尮閰峟ormalDatabaseData涓殑id瀛楁 const rowsToSelect = formalDatabaseData.value.filter((row) => 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); @@ -304,7 +284,6 @@ // 鐩戝惉瀵硅瘽妗嗙姸鎬侊紝鍦ㄦ墦寮�鏃惰缃�変腑鐘舵�� watch(innerVisible, (newVal) => { if (newVal && selectedIds.value.length > 0) { - console.log("瀵硅瘽妗嗘墦寮�锛岃缃�変腑鐘舵��"); setTimeout(() => setTableSelection(selectedIds.value), 200); } // 瀵硅瘽妗嗗叧闂椂娓呯┖閫夋嫨鐘舵�� @@ -344,9 +323,6 @@ .filter((id) => id); selectedIds.value = allOfficialIds; - console.log("鏇存柊鍚庣殑琛ㄦ牸鏁版嵁:", tableData.value); - console.log("鏇存柊鍚庣殑閫変腑ID:", selectedIds.value); - // 鍏抽棴閫夋嫨瀵硅瘽妗� innerVisible.value = false; @@ -367,94 +343,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, [ + "coal", + "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); - - // 楠岃瘉杈撳叆鍊� - if (isNaN(numValue) || numValue < 0) { - ElMessage.warning("浣跨敤鏁伴噺蹇呴』鏄潪璐熸暟锛�"); - row.usedQuantity = 0; + const validation = validateNumber(value, 0, Number(row.inventoryQuantity)); + + 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,7 +444,6 @@ // 鍒犻櫎鍗曚釜宸查�夋暟鎹」 const handleRemoveItem = (row) => { - console.log("鍒犻櫎椤�:", row); const index = tableData.value.findIndex( (item) => item.officialId === row.officialId ); @@ -475,10 +455,6 @@ .map((item) => item.officialId) .filter((id) => id); selectedIds.value = updatedOfficialIds; - - console.log("鍒犻櫎鍚庣殑琛ㄦ牸鏁版嵁:", tableData.value); - console.log("鏇存柊鍚庣殑閫変腑ID:", selectedIds.value); - ElMessage.success("宸插垹闄ら�変腑椤�"); } }; @@ -489,21 +465,26 @@ ElMessage.warning("娌℃湁鍙竻绌虹殑鏁版嵁"); return; } - ElMessageBox.confirm("纭娓呯┖鎵�鏈夊凡閫夋嫨鐨勬暟鎹悧锛�", "璀﹀憡", { confirmButtonText: "纭畾", cancelButtonText: "鍙栨秷", type: "warning", }) - .then(() => { + .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 = []; - console.log("宸叉竻绌烘墍鏈夊凡閫夋暟鎹�"); ElMessage.success("宸叉竻绌烘墍鏈夋暟鎹�"); }) - .catch(() => { - console.log("鍙栨秷娓呯┖鎿嶄綔"); - }); + .catch(() => {}); }; // 璁$畻鎬讳娇鐢ㄩ噺 diff --git a/src/views/production/components/useCoalData.js b/src/views/production/components/useCoalData.js new file mode 100644 index 0000000..61179b4 --- /dev/null +++ b/src/views/production/components/useCoalData.js @@ -0,0 +1,96 @@ +/** + * 鐓ょ鏁版嵁绠$悊缁勫悎寮忓嚱鏁� + * 鎻愪緵鐓ょ鏁版嵁鐨勮幏鍙栥�佺紦瀛樸�佽浆鎹㈢瓑鍔熻兘 + */ +import { ref, computed, watch } from 'vue'; +import { getCoalFieldList } from '@/api/basicInformation/coalQualityMaintenance'; +import { ElMessage } from 'element-plus'; + +// 鍏ㄥ眬鐓ょ鏁版嵁缂撳瓨 +const coalData = ref([]); +const isLoading = ref(false); +const isLoaded = ref(false); + +export function useCoalData() { + + // 鑾峰彇鐓ょ鏁版嵁 + const getCoalData = async (forceRefresh = false) => { + if (isLoaded.value && !forceRefresh) { + return coalData.value; + } + + if (isLoading.value) { + // 濡傛灉姝e湪鍔犺浇锛岀瓑寰呭姞杞藉畬鎴� + return new Promise((resolve) => { + const unwatch = watch(isLoading, (loading) => { + if (!loading) { + unwatch(); + resolve(coalData.value); + } + }); + }); + } + + isLoading.value = true; + try { + const res = await getCoalFieldList(); + if (res.code === 200) { + coalData.value = res.data; + isLoaded.value = true; + return coalData.value; + } else { + ElMessage.error('鑾峰彇鐓ょ鏁版嵁澶辫触'); + return []; + } + } catch (error) { + ElMessage.error('鑾峰彇鐓ょ鏁版嵁澶辫触'); + console.error('鐓ょ鏁版嵁鑾峰彇閿欒:', error); + return []; + } finally { + isLoading.value = false; + } + }; + + // 鏍规嵁ID鑾峰彇鐓ょ鍚嶇О + const getCoalNameById = (id) => { + if (!id || coalData.value.length === 0) return id; + const coal = coalData.value.find(item => item.id == id); + return coal ? coal.fieldName : id; + }; + + // 鏍规嵁鍚嶇О鑾峰彇鐓ょID + const getCoalIdByName = (name) => { + if (!name || coalData.value.length === 0) return ''; + const coal = coalData.value.find(item => item.fieldName === name); + return coal ? coal.id : ''; + }; + + // 鐢熸垚涓嬫媺閫夐」 + const coalOptions = computed(() => { + return coalData.value.map(item => ({ + label: item.fieldName, + value: item.fieldName, + key: item.id + })); + }); + + // 鐢熸垚key-value鏄犲皠 + const coalMap = computed(() => { + const map = {}; + coalData.value.forEach(item => { + map[item.id] = item.fieldName; + }); + return map; + }); + + return { + coalData: computed(() => coalData.value), + coalOptions, + coalMap, + isLoading: computed(() => isLoading.value), + isLoaded: computed(() => isLoaded.value), + getCoalData, + getCoalNameById, + getCoalIdByName + }; +} diff --git a/src/views/production/components/useDialog.js b/src/views/production/components/useDialog.js new file mode 100644 index 0000000..c3694b3 --- /dev/null +++ b/src/views/production/components/useDialog.js @@ -0,0 +1,56 @@ +/** + * 瀵硅瘽妗嗙鐞嗙粍鍚堝紡鍑芥暟 + * 鎻愪緵瀵硅瘽妗嗙殑鎵撳紑銆佸叧闂�佹暟鎹鐞嗙瓑鍔熻兘 + */ +import { ref } from 'vue'; + +export function useDialog() { + const dialogVisible = ref(false); + const dialogType = ref('add'); + const dialogRef = ref(null); + const currentRowData = ref(null); + + // 鎵撳紑瀵硅瘽妗� + const openDialog = (type = 'add', rowData = null) => { + dialogType.value = type; + currentRowData.value = rowData; + dialogVisible.value = true; + + // 璋冪敤瀵硅瘽妗嗙粍浠剁殑鍒濆鍖栨柟娉� + if (dialogRef.value) { + if (type === 'add') { + dialogRef.value.Initialization?.(); + } else if (type === 'edit' && rowData) { + dialogRef.value.editInitialization?.(rowData); + } + } + }; + + // 鍏抽棴瀵硅瘽妗� + const closeDialog = () => { + dialogVisible.value = false; + dialogType.value = 'add'; + currentRowData.value = null; + }; + + // 瀵硅瘽妗嗘垚鍔熷洖璋� + const handleDialogSuccess = (callback) => { + closeDialog(); + if (typeof callback === 'function') { + callback(); + } + }; + + return { + // 鐘舵�� + dialogVisible, + dialogType, + dialogRef, + currentRowData, + + // 鏂规硶 + openDialog, + closeDialog, + handleDialogSuccess + }; +} diff --git a/src/views/production/components/useTableData.js b/src/views/production/components/useTableData.js new file mode 100644 index 0000000..fe2ea50 --- /dev/null +++ b/src/views/production/components/useTableData.js @@ -0,0 +1,136 @@ +/** + * 琛ㄦ牸鏁版嵁绠$悊缁勫悎寮忓嚱鏁� + * 鎻愪緵鍒嗛〉銆佹悳绱€�侀�夋嫨绛夐�氱敤鍔熻兘 + */ +import { ref, reactive } from 'vue'; +import { ElMessage, ElMessageBox } from 'element-plus'; + +export function useTableData(apiFunction, options = {}) { + const { + pageSize = 10, + searchField = 'searchAll' + } = options; + + // 鍝嶅簲寮忔暟鎹� + const tableData = ref([]); + const loading = ref(false); + const total = ref(0); + const selectedRows = ref([]); + + // 鏌ヨ鍙傛暟 + const queryParams = reactive({ + [searchField]: '', + current: 1, + size: pageSize, + }); + + // 鑾峰彇鍒楄〃鏁版嵁 + const getList = async () => { + loading.value = true; + try { + const params = { + [searchField]: queryParams[searchField], + current: queryParams.current, + size: queryParams.size, + page: queryParams.current, + pageSize: queryParams.size, + pageNum: queryParams.current, + limit: queryParams.size, + offset: (queryParams.current - 1) * queryParams.size + }; + + const res = await apiFunction(params); + tableData.value = res.data.records || []; + total.value = res.data.total || 0; + } catch (error) { + ElMessage.error('鑾峰彇鏁版嵁澶辫触'); + console.error('API閿欒:', error); + } finally { + loading.value = false; + } + }; + + // 鎼滅储 + const handleSearch = () => { + queryParams.current = 1; + getList(); + }; + + // 閲嶇疆鎼滅储 + const handleReset = () => { + queryParams[searchField] = ''; + handleSearch(); + }; + + // 鍒嗛〉澶勭悊 + const handlePageChange = ({ page, limit }) => { + if (page && page !== queryParams.current) { + queryParams.current = page; + } + if (limit && limit !== queryParams.size) { + queryParams.size = limit; + queryParams.current = 1; // 鏀瑰彉姣忛〉澶у皬鏃跺洖鍒扮涓�椤� + } + getList(); + }; + + // 琛ㄦ牸閫夋嫨澶勭悊 + const handleSelectionChange = (selection) => { + selectedRows.value = selection; + }; + + // 鎵归噺鍒犻櫎 + const deleteSelected = async (deleteFunction) => { + if (selectedRows.value.length === 0) { + ElMessage.warning('璇烽�夋嫨瑕佸垹闄ょ殑鏁版嵁'); + return; + } + + try { + await ElMessageBox.confirm( + `纭鍒犻櫎閫変腑鐨� ${selectedRows.value.length} 鏉℃暟鎹悧锛焋, + '鍒犻櫎纭', + { + confirmButtonText: '纭畾', + cancelButtonText: '鍙栨秷', + type: 'warning' + } + ); + + const ids = selectedRows.value.map(row => row.id); + await deleteFunction(ids); + + ElMessage.success('鍒犻櫎鎴愬姛'); + selectedRows.value = []; + getList(); + } catch (error) { + if (error !== 'cancel') { + ElMessage.error('鍒犻櫎澶辫触'); + console.error('鍒犻櫎閿欒:', error); + } + } + }; + + // 鍒锋柊鏁版嵁 + const refresh = () => { + getList(); + }; + + return { + // 鏁版嵁 + tableData, + loading, + total, + selectedRows, + queryParams, + + // 鏂规硶 + getList, + handleSearch, + handleReset, + handlePageChange, + handleSelectionChange, + deleteSelected, + refresh + }; +} diff --git a/src/views/production/index.vue b/src/views/production/index.vue index 531640a..4827925 100644 --- a/src/views/production/index.vue +++ b/src/views/production/index.vue @@ -22,59 +22,64 @@ <el-button type="success" :icon="Plus" @click="openDialog('add')"> 鏂板鍔犲伐 </el-button> - <el-button type="danger" :icon="Delete" :disabled="!selectedRows.length"> + <el-button type="danger" :icon="Delete" :disabled="!selectedRows.length" @click="() => deleteSelected(delPM)"> 鍒犻櫎 </el-button> - </div> - - <!-- 鏁版嵁琛ㄦ牸 --> + </div> <!-- 鏁版嵁琛ㄦ牸 --> <ETable + :showOverflowTooltip="false" :loading="loading" :table-data="tableData" :columns="columns" + :current-page="queryParams.current" + :page-size="queryParams.size" @selection-change="handleSelectionChange" @edit="row => openDialog('edit', row)" :show-selection="true" :border="true" :maxHeight="480" - > - <template #coal="{ row }"> + > <template #coal="{ row }"> <div class="coal-tags"> <el-tag v-for="coal in parseCoalArray(row.coal)" :key="coal" size="small"> - {{ coal }} + {{ getCoalNameById(coal) }} </el-tag> <span v-if="!row.coal">--</span> </div> </template> - </ETable> - - <!-- 鍒嗛〉缁勪欢 --> + </ETable> <!-- 鍒嗛〉缁勪欢 --> <Pagination + :layout="'total, prev, pager, next, jumper'" :total="total" - :page="queryParams.current" + v-model:page="queryParams.current" :limit="queryParams.size" @pagination="handlePageChange" /> </el-card> <!-- 鐢熶骇瀵硅瘽妗� --> + <!-- handleProductionAndProcessing --> <ProductionDialog v-model:visible="dialogVisible" ref="dialogRef" :type="dialogType" + @update:productionAndProcessing="handleProductionAndProcessing" @success="handleDialogSuccess" /> </div> </template> <script setup> -import { ref, reactive, onMounted } from "vue"; -import { ElMessage, ElMessageBox } from "element-plus"; +import { onMounted } from "vue"; +import { ElMessage } from "element-plus"; import { Plus, Delete } from "@element-plus/icons-vue"; import ProductionDialog from "./components/ProductionDialog.vue"; import ETable from "@/components/Table/ETable.vue"; import Pagination from "@/components/Pagination/index.vue"; -import { getProductionMasterList } from "@/api/production"; +import { getProductionMasterList, delPM } from "@/api/production"; +import { parseCoalArray } from "@/utils/production"; +import { useTableData } from "./components/useTableData.js"; +import { useDialog } from "./components/useDialog.js"; +import { useCoalData } from "./components/useCoalData.js"; // 琛ㄦ牸鍒楅厤缃� const columns = [ @@ -87,115 +92,53 @@ { prop: "producer", label: "鐢熶骇浜�", minWidth: 150 }, ]; -// 鍝嶅簲寮忔暟鎹� -const tableData = ref([]); -const loading = ref(false); -const total = ref(0); -const selectedRows = ref([]); -const dialogVisible = ref(false); -const dialogType = ref("add"); -const dialogRef = ref(null); +// 浣跨敤琛ㄦ牸鏁版嵁缁勫悎寮忓嚱鏁� +const { + tableData, + loading, + total, + selectedRows, + queryParams, + getList, + handleSearch, + handleReset, + handlePageChange, + handleSelectionChange, + deleteSelected +} = useTableData(getProductionMasterList, { pageSize: 10 }); -// 鏌ヨ鍙傛暟 -const queryParams = reactive({ - searchAll: "", - current: 1, - size: 10, -}); +// 浣跨敤瀵硅瘽妗嗙粍鍚堝紡鍑芥暟 +const { + dialogVisible, + dialogType, + dialogRef, + openDialog, + handleDialogSuccess: onDialogSuccess +} = useDialog(); -// 鑾峰彇琛ㄦ牸鏁版嵁 -// 鑾峰彇琛ㄦ牸鏁版嵁 -const getList = async () => { - loading.value = true; - try { - // 鏋勫缓姝g‘鐨勫垎椤靛弬鏁� - const params = { - searchAll: queryParams.searchAll, - // 灏濊瘯澶氱甯歌鐨勫垎椤靛弬鏁版牸寮� - current: queryParams.current, - size: queryParams.size, - page: queryParams.current, - pageSize: queryParams.size, - pageNum: queryParams.current, - limit: queryParams.size, - offset: (queryParams.current - 1) * queryParams.size - }; - - console.log('鍙戦�佸垎椤靛弬鏁�:', params); - console.log(`绗�${queryParams.current}椤靛簲璇ユ樉绀虹${(queryParams.current - 1) * queryParams.size + 1}-${queryParams.current * queryParams.size}鏉℃暟鎹甡); - - const res = await getProductionMasterList(params); - tableData.value = res.data.records || []; - total.value = res.data.total || 0; - - console.log('鎺ユ敹鍒扮殑鏁版嵁:', { - 褰撳墠椤�: queryParams.current, - 杩斿洖鏉℃暟: tableData.value.length, - 鎬绘潯鏁�: total.value - }); - } catch (error) { - ElMessage.error("鑾峰彇鏁版嵁澶辫触"); - console.error('API閿欒:', error); - } finally { - loading.value = false; - } -}; +// 浣跨敤鐓ょ鏁版嵁缁勫悎寮忓嚱鏁� +const { getCoalNameById, getCoalData } = useCoalData(); -// 鎼滅储鍜岄噸缃� -const handleSearch = () => { - queryParams.current = 1; - getList(); -}; - -const handleReset = () => { - queryParams.searchAll = ""; - handleSearch(); -}; - -// 鍒嗛〉澶勭悊 -const handlePageChange = ({ page }) => { - queryParams.current = page; - getList(); -}; - -// 琛ㄦ牸閫夋嫨澶勭悊 -const handleSelectionChange = (selection) => { - selectedRows.value = selection; -}; - -// 鎵撳紑瀵硅瘽妗� - 缁熶竴澶勭悊鏂板鍜岀紪杈� -const openDialog = (type, row = null) => { - dialogType.value = type; - dialogVisible.value = true; - - if (type === 'add') { - dialogRef.value?.Initialization(); - } else if (type === 'edit' && row) { - dialogRef.value?.editInitialization({ ...row }); +// 澶勭悊鐢熶骇鏁版嵁鏇存柊 +const handleProductionAndProcessing = (row, rows) => { + const index = tableData.value.findIndex(item => item.id === rows.id); + if (index !== -1) { + tableData.value[index] = { ...tableData.value[index], ...row }; } }; // 瀵硅瘽妗嗘垚鍔熷洖璋� const handleDialogSuccess = () => { - getList(); - ElMessage.success("鎿嶄綔鎴愬姛"); + onDialogSuccess(() => { + getList(); + ElMessage.success("鎿嶄綔鎴愬姛"); + }); }; - -// 瑙f瀽鐓ょ鏁扮粍 - 绠�鍖栭�昏緫 -const parseCoalArray = (coalString) => { - if (!coalString) return []; - - if (Array.isArray(coalString)) return coalString; - - return String(coalString) - .replace(/^\[|\]$/g, '') - .split(',') - .map(item => item.trim()) - .filter(Boolean); -}; - // 缁勪欢鎸傝浇鏃跺姞杞芥暟鎹� -onMounted(getList); +onMounted(async () => { + await getCoalData(); // 棰勫姞杞界叅绉嶆暟鎹� + getList(); +}); </script> <style scoped lang="scss"> -- Gitblit v1.9.3