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/ProductionDialog.vue |  297 +++++++++++++++++++++++++++-------------------------------
 1 files changed, 139 insertions(+), 158 deletions(-)

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(() => {});
 };
 
 // 璁$畻鎬讳娇鐢ㄩ噺

--
Gitblit v1.9.3