From 33a6362a6e50684b3652d6ac8bd7a61a9978f11b Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期六, 13 六月 2026 14:40:48 +0800
Subject: [PATCH] 君歌 1.对于新增订单需流转协同办公进行审批,审批完成流转生产管控-生产订单 2.客户分类修改为:核心、重要、普通、一般。 3.可对报价多次修改,修改后流转至协同办公-协同审批-报价审批,并对每次报价进行记录。 4.不合格管理字段按照单据进行修改。 5.谁登记的客户只能看见自己的,负责人(维护人)可以转移,操作加一个‘客户交接’按钮选择要交接给的负责人

---
 src/components/PIMTable/PIMTable.vue                                                           |    1 
 src/views/basicData/customerFileOpenSea/index.vue                                              |   34 ++
 src/views/salesManagement/salesLedger/index.vue                                                |   18 +
 src/api/basicData/customer.js                                                                  |    9 
 src/views/officeProcessAutomation/ApproveManage/approve-list/components/ApproveDetailPanel.vue |   51 ++++
 src/api/qualityManagement/qualityUnqualifiedOrder.js                                           |   45 +++
 src/views/officeProcessAutomation/ApproveManage/approve-list/useApproveList.js                 |   35 ++
 src/views/qualityManagement/nonconformingManagement/components/formDia.vue                     |   10 
 src/views/basicData/customerFile/index.vue                                                     |  146 +++++++++++
 src/views/qualityManagement/nonconformingManagement/components/orderFormDia.vue                |  296 ++++++++++++++++++++++++
 src/views/productionPlan/productionPlan/index.vue                                              |   24 ++
 src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js           |    1 
 src/views/qualityManagement/nonconformingManagement/components/inspectionFormDia.vue           |   12 
 src/views/qualityManagement/nonconformingManagement/index.vue                                  |   13 +
 14 files changed, 672 insertions(+), 23 deletions(-)

diff --git a/src/api/basicData/customer.js b/src/api/basicData/customer.js
index 0934193..405162a 100644
--- a/src/api/basicData/customer.js
+++ b/src/api/basicData/customer.js
@@ -26,6 +26,15 @@
     })
 }
 
+// 浜ゆ帴瀹㈡埛
+export function handoverCustomer(data) {
+    return request({
+        url: '/basic/customer/handover',
+        method: 'post',
+        data
+    })
+}
+
 // 娴佸叆鍏捣
 export function backCustomer(id) {
     return request({
diff --git a/src/api/qualityManagement/qualityUnqualifiedOrder.js b/src/api/qualityManagement/qualityUnqualifiedOrder.js
new file mode 100644
index 0000000..a6bc577
--- /dev/null
+++ b/src/api/qualityManagement/qualityUnqualifiedOrder.js
@@ -0,0 +1,45 @@
+import request from "@/utils/request";
+
+// 鍒嗛〉鏌ヨ涓嶅悎鏍煎搧澶勭悊鍗�
+export function listPage(query) {
+  return request({
+    url: "/qualityUnqualifiedOrder/listPage",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鏌ョ湅璇︽儏
+export function getDetail(id) {
+  return request({
+    url: `/qualityUnqualifiedOrder/${id}`,
+    method: "get",
+  });
+}
+
+// 鏂板澶勭悊鍗�
+export function save(data) {
+  return request({
+    url: "/qualityUnqualifiedOrder/save",
+    method: "post",
+    data,
+  });
+}
+
+// 淇敼澶勭悊鍗�
+export function update(data) {
+  return request({
+    url: "/qualityUnqualifiedOrder/update",
+    method: "put",
+    data,
+  });
+}
+
+// 鍒犻櫎澶勭悊鍗�
+export function remove(ids) {
+  return request({
+    url: "/qualityUnqualifiedOrder/delete",
+    method: "delete",
+    data: ids,
+  });
+}
diff --git a/src/components/PIMTable/PIMTable.vue b/src/components/PIMTable/PIMTable.vue
index 74615af..10c8cd2 100644
--- a/src/components/PIMTable/PIMTable.vue
+++ b/src/components/PIMTable/PIMTable.vue
@@ -28,6 +28,7 @@
     <el-table-column align="center"
                      label="搴忓彿"
                      type="index"
+										 fixed="left"
                      width="60" />
     <el-table-column v-for="(item, index) in column"
                      :key="index"
diff --git a/src/views/basicData/customerFile/index.vue b/src/views/basicData/customerFile/index.vue
index 7091a02..4cadf16 100644
--- a/src/views/basicData/customerFile/index.vue
+++ b/src/views/basicData/customerFile/index.vue
@@ -15,10 +15,14 @@
                    style="width: 240px"
                    clearable
                    @change="handleQuery">
-          <el-option label="闆跺敭瀹㈡埛"
-                     value="闆跺敭瀹㈡埛" />
-          <el-option label="杩涢攢鍟嗗鎴�"
-                     value="杩涢攢鍟嗗鎴�" />
+          <el-option label="鏍稿績"
+                     value="鏍稿績" />
+          <el-option label="閲嶈"
+                     value="閲嶈" />
+          <el-option label="鏅��"
+                     value="鏅��" />
+          <el-option label="涓�鑸�"
+                     value="涓�鑸�" />
         </el-select>
         <el-button type="primary"
                    @click="handleQuery"
@@ -31,6 +35,7 @@
                    plain
                    @click="back">娴佸叆鍏捣</el-button>
         <el-button @click="handleOut">瀵煎嚭</el-button>
+				<el-button type="primary" @click="handleOutFollowUpList">瀵煎嚭璺熻繘璁板綍</el-button>
         <el-button type="info"
                    plain
                    icon="Upload"
@@ -128,10 +133,14 @@
               <el-select v-model="form.customerType"
                          placeholder="璇烽�夋嫨"
                          clearable>
-                <el-option label="闆跺敭瀹㈡埛"
-                           value="闆跺敭瀹㈡埛" />
-                <el-option label="杩涢攢鍟嗗鎴�"
-                           value="杩涢攢鍟嗗鎴�" />
+                <el-option label="鏍稿績"
+                           value="鏍稿績" />
+                <el-option label="閲嶈"
+                           value="閲嶈" />
+                <el-option label="鏅��"
+                           value="鏅��" />
+                <el-option label="涓�鑸�"
+                           value="涓�鑸�" />
               </el-select>
             </el-form-item>
           </el-col>
@@ -609,6 +618,39 @@
         </div>
       </template>
     </el-dialog>
+    <!-- 浜ゆ帴瀵硅瘽妗� -->
+    <el-dialog v-model="handoverDialogVisible"
+               title="瀹㈡埛浜ゆ帴"
+               width="400px"
+               @close="closeHandoverDialog">
+      <el-form :model="handoverForm"
+               :rules="handoverRules"
+               ref="handoverFormRef"
+               label-width="100px">
+        <el-form-item label="褰撳墠缁存姢浜�">
+          <span>{{ handoverForm.oldMaintainer }}</span>
+        </el-form-item>
+        <el-form-item label="鏂扮淮鎶や汉"
+                      prop="maintainer">
+          <el-select v-model="handoverForm.maintainerId"
+                     placeholder="璇烽�夋嫨鏂扮淮鎶や汉"
+                     style="width: 100%"
+                     filterable
+                     @change="handleHandoverUserChange">
+            <el-option v-for="item in userList"
+                       :key="item.userId || item.nickName"
+                       :label="item.nickName"
+                       :value="item.userId" />
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitHandoverForm">纭</el-button>
+          <el-button @click="closeHandoverDialog">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
@@ -622,7 +664,7 @@
     addReturnVisit,
     getReturnVisit,
   } from "@/api/basicData/customerFile.js";
-  import {listCustomer, getCustomer, addCustomer, updateCustomer, delCustomer, backCustomer} from "@/api/basicData/customer.js";
+  import {listCustomer, getCustomer, addCustomer, updateCustomer, delCustomer, backCustomer, handoverCustomer} from "@/api/basicData/customer.js";
   import { ElMessageBox } from "element-plus";
   import { userListNoPage } from "@/api/system/user.js";
   import useUserStore from "@/store/modules/user";
@@ -712,11 +754,23 @@
     {
       label: "瀹㈡埛鍒嗙被",
       prop: "customerType",
+			fixed: "left",
+      dataType: "tag",
       width: 120,
+      formatType: value => {
+        switch (value) {
+          case "鏍稿績": return "danger";
+          case "閲嶈": return "warning";
+          case "鏅��": return "primary";
+          case "涓�鑸�": return "info";
+          default: return "info";
+        }
+      },
     },
     {
       label: "瀹㈡埛鍚嶇О",
       prop: "customerName",
+			fixed: "left",
       width: 220,
     },
     {
@@ -795,13 +849,20 @@
       label: "鎿嶄綔",
       align: "center",
       fixed: "right",
-      width: 290,
+      width: 340,
       operation: [
         {
           name: "缂栬緫",
           type: "text",
           clickFun: row => {
             openForm("edit", row);
+          },
+        },
+        {
+          name: "浜ゆ帴",
+          type: "text",
+          clickFun: row => {
+            openHandoverDialog(row);
           },
         },
 				{
@@ -842,6 +903,19 @@
   // 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
   const operationType = ref("");
   const dialogFormVisible = ref(false);
+
+  // 浜ゆ帴瀵硅瘽妗�
+  const handoverDialogVisible = ref(false);
+  const handoverFormRef = ref();
+  const handoverForm = reactive({
+    id: undefined,
+    oldMaintainer: "",
+    maintainer: "",
+    maintainerId: undefined,
+  });
+  const handoverRules = {
+    maintainer: [{ required: true, message: "璇烽�夋嫨鏂扮淮鎶や汉", trigger: "change" }],
+  };
   const formYYs = ref({
     // 鍏朵粬瀛楁...
     contactList: [
@@ -1078,6 +1152,44 @@
     proxy.resetForm("formRef");
     dialogFormVisible.value = false;
   };
+  // 浜ゆ帴
+  const handleHandoverUserChange = userId => {
+    const user = userList.value.find(item => (item.userId || item.nickName) === userId);
+    handoverForm.maintainer = user ? user.nickName : "";
+  };
+  const openHandoverDialog = row => {
+    handoverForm.id = row.id;
+    handoverForm.oldMaintainer = row.maintainer;
+    handoverForm.maintainer = "";
+    handoverForm.maintainerId = undefined;
+    userListNoPage().then(res => {
+      userList.value = res.data;
+      handoverDialogVisible.value = true;
+    });
+  };
+  const closeHandoverDialog = () => {
+    proxy.resetForm("handoverFormRef");
+    handoverForm.id = undefined;
+    handoverForm.oldMaintainer = "";
+    handoverForm.maintainer = "";
+    handoverForm.maintainerId = undefined;
+    handoverDialogVisible.value = false;
+  };
+  const submitHandoverForm = () => {
+    proxy.$refs.handoverFormRef.validate(valid => {
+      if (valid) {
+        handoverCustomer({
+          id: handoverForm.id,
+          maintainer: handoverForm.maintainer,
+          maintainerId: handoverForm.maintainerId,
+        }).then(() => {
+          proxy.$modal.msgSuccess("浜ゆ帴鎴愬姛");
+          closeHandoverDialog();
+          getList();
+        });
+      }
+    });
+  };
   // 瀵煎嚭
   const handleOut = () => {
     ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
@@ -1092,6 +1204,20 @@
         proxy.$modal.msg("宸插彇娑�");
       });
   };
+	// 瀵煎嚭璺熻繘璁板綍
+	const handleOutFollowUpList = () => {
+		ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+			confirmButtonText: "纭",
+			cancelButtonText: "鍙栨秷",
+			type: "warning",
+		})
+			.then(() => {
+				proxy.download("basic/customer-follow/export", {}, "瀹㈡埛璺熻繘璁板綍.xlsx");
+			})
+			.catch(() => {
+				proxy.$modal.msg("宸插彇娑�");
+			});
+	};
   // 鍒犻櫎
   const handleDelete = () => {
     let ids = [];
diff --git a/src/views/basicData/customerFileOpenSea/index.vue b/src/views/basicData/customerFileOpenSea/index.vue
index bad28e1..943339e 100644
--- a/src/views/basicData/customerFileOpenSea/index.vue
+++ b/src/views/basicData/customerFileOpenSea/index.vue
@@ -15,10 +15,14 @@
                    style="width: 240px"
                    clearable
                    @change="handleQuery">
-          <el-option label="闆跺敭瀹㈡埛"
-                     value="闆跺敭瀹㈡埛" />
-          <el-option label="杩涢攢鍟嗗鎴�"
-                     value="杩涢攢鍟嗗鎴�" />
+          <el-option label="鏍稿績"
+                     value="鏍稿績" />
+          <el-option label="閲嶈"
+                     value="閲嶈" />
+          <el-option label="鏅��"
+                     value="鏅��" />
+          <el-option label="涓�鑸�"
+                     value="涓�鑸�" />
         </el-select>
         <el-button type="primary"
                    @click="handleQuery"
@@ -125,10 +129,14 @@
               <el-select v-model="form.customerType"
                          placeholder="璇烽�夋嫨"
                          clearable>
-                <el-option label="闆跺敭瀹㈡埛"
-                           value="闆跺敭瀹㈡埛" />
-                <el-option label="杩涢攢鍟嗗鎴�"
-                           value="杩涢攢鍟嗗鎴�" />
+                <el-option label="鏍稿績"
+                           value="鏍稿績" />
+                <el-option label="閲嶈"
+                           value="閲嶈" />
+                <el-option label="鏅��"
+                           value="鏅��" />
+                <el-option label="涓�鑸�"
+                           value="涓�鑸�" />
               </el-select>
             </el-form-item>
           </el-col>
@@ -808,7 +816,17 @@
     {
       label: "瀹㈡埛鍒嗙被",
       prop: "customerType",
+      dataType: "tag",
       width: 120,
+      formatType: value => {
+        switch (value) {
+          case "鏍稿績": return "danger";
+          case "閲嶈": return "warning";
+          case "鏅��": return "primary";
+          case "涓�鑸�": return "info";
+          default: return "info";
+        }
+      },
     },
     {
       label: "瀹㈡埛鍚嶇О",
diff --git a/src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js b/src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js
index e2f1e45..21af0d1 100644
--- a/src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js
+++ b/src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js
@@ -19,6 +19,7 @@
   { value: "quotation", label: "鎶ヤ环瀹℃壒", cellBg: "#f4ecfc", cellColor: "#9b59b6" },
   { value: "shipment", label: "鍙戣揣瀹℃壒", cellBg: "#e8faf6", cellColor: "#1abc9c" },
   { value: "enterprise_news", label: "浼佷笟鏂伴椈", cellBg: "#ecf5ff", cellColor: "#409eff" },
+  { value: "sales", label: "閿�鍞鎵�", cellBg: "#e8faf0", cellColor: "#1a9c5d" },
 ];
 
 /** 鍒楄〃鏌ヨ锛氬鎵圭姸鎬侊紙涓庡悗绔� status 鏋氫妇涓�鑷达級 */
diff --git a/src/views/officeProcessAutomation/ApproveManage/approve-list/components/ApproveDetailPanel.vue b/src/views/officeProcessAutomation/ApproveManage/approve-list/components/ApproveDetailPanel.vue
index 58b612b..dc25beb 100644
--- a/src/views/officeProcessAutomation/ApproveManage/approve-list/components/ApproveDetailPanel.vue
+++ b/src/views/officeProcessAutomation/ApproveManage/approve-list/components/ApproveDetailPanel.vue
@@ -145,6 +145,45 @@
           </div>
         </div>
       </template>
+
+      <!-- 閿�鍞鎵硅鎯� -->
+      <template v-else-if="row.businessType === 19">
+        <div v-if="detailData" class="sales-detail">
+          <el-divider content-position="left">閿�鍞鎯�</el-divider>
+          <el-descriptions :column="2" border>
+            <el-descriptions-item label="閿�鍞悎鍚屽彿">{{ detailData.salesContractNo || "--" }}</el-descriptions-item>
+            <el-descriptions-item label="瀹㈡埛鍚嶇О">{{ detailData.customerName || "--" }}</el-descriptions-item>
+            <el-descriptions-item label="涓氬姟鍛�">{{ detailData.salesman || "--" }}</el-descriptions-item>
+            <el-descriptions-item label="椤圭洰鍚嶇О">{{ detailData.projectName || "--" }}</el-descriptions-item>
+            <el-descriptions-item label="绛捐鏃ユ湡">{{ detailData.executionDate || "--" }}</el-descriptions-item>
+            <el-descriptions-item label="浠樻鏂瑰紡">{{ detailData.paymentMethod || "--" }}</el-descriptions-item>
+            <el-descriptions-item label="褰曞叆浜�">{{ detailData.entryPersonName || detailData.entryPerson || "--" }}</el-descriptions-item>
+            <el-descriptions-item label="褰曞叆鏃ユ湡">{{ detailData.entryDate || "--" }}</el-descriptions-item>
+            <el-descriptions-item label="鍚堝悓閲戦" :span="2">
+              <span style="font-size: 18px; color: #e6a23c; font-weight: bold;">
+                楼{{ salesTotalAmount }}
+              </span>
+            </el-descriptions-item>
+          </el-descriptions>
+          <div v-if="detailData.productData && detailData.productData.length" style="margin-top: 20px;">
+            <h4>浜у搧鏄庣粏</h4>
+            <el-table :data="detailData.productData"
+                      border
+                      style="width: 100%">
+              <el-table-column prop="productCategory" label="浜у搧鍚嶇О" />
+              <el-table-column prop="specificationModel" label="瑙勬牸鍨嬪彿" />
+              <el-table-column prop="unit" label="鍗曚綅" />
+              <el-table-column prop="quantity" label="鏁伴噺" />
+              <el-table-column prop="taxInclusiveUnitPrice" label="鍚◣鍗曚环">
+                <template #default="scope">楼{{ Number(scope.row.taxInclusiveUnitPrice ?? 0).toFixed(2) }}</template>
+              </el-table-column>
+              <el-table-column prop="taxInclusiveTotalPrice" label="鍚◣鎬讳环">
+                <template #default="scope">楼{{ Number(scope.row.taxInclusiveTotalPrice ?? 0).toFixed(2) }}</template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </div>
+      </template>
     </div>
     <div v-if="attachmentList.length"
          class="detail-block">
@@ -199,9 +238,9 @@
   const formResolved = computed(() => resolveInstanceFormFields(props.row));
 
 
-  // 鏄惁涓虹壒娈婂鎵圭被鍨嬶紙閲囪喘銆佸彂璐с�佹姤浠凤級
+  // 鏄惁涓虹壒娈婂鎵圭被鍨嬶紙閲囪喘銆佸彂璐с�佹姤浠枫�侀攢鍞級
   const isSpecialApprovalType = computed(() => {
-    return [5, 7, 6].includes(props.row.businessType);
+    return [5, 7, 6, 19].includes(props.row.businessType);
   });
 
   // 璇︽儏鏁版嵁锛堢洿鎺ヤ娇鐢ㄤ紶鍏ョ殑 detail-data 鍙傛暟锛�
@@ -209,6 +248,14 @@
     return props.detailData || {};
   });
 
+  // 閿�鍞鎵癸細鍚堝悓閲戦 = 浜у搧鏄庣粏鍚◣鎬讳环涔嬪拰
+  const salesTotalAmount = computed(() => {
+    const products = detailData.value?.productData;
+    if (!Array.isArray(products) || !products.length) return "0.00";
+    const total = products.reduce((sum, p) => sum + Number(p.taxInclusiveTotalPrice ?? 0), 0);
+    return total.toFixed(2);
+  });
+
   const attachmentList = computed(() => {
     const list = props.row.storageBlobVOList || props.row.storageBlobDTOs || [];
     return Array.isArray(list) ? list : [];
diff --git a/src/views/officeProcessAutomation/ApproveManage/approve-list/useApproveList.js b/src/views/officeProcessAutomation/ApproveManage/approve-list/useApproveList.js
index 9442a5a..31a34f8 100644
--- a/src/views/officeProcessAutomation/ApproveManage/approve-list/useApproveList.js
+++ b/src/views/officeProcessAutomation/ApproveManage/approve-list/useApproveList.js
@@ -13,6 +13,7 @@
 import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
 import { getPurchaseByCode } from "@/api/procurementManagement/procurementLedger.js";
 import { getDeliveryDetailByShippingNo } from "@/api/salesManagement/deliveryLedger.js";
+import { ledgerListPage, getSalesLedgerWithProducts } from "@/api/salesManagement/salesLedger.js";
 import useUserStore from "@/store/modules/user";
 import { Search } from "@element-plus/icons-vue";
 import { ElMessage, ElMessageBox } from "element-plus";
@@ -226,7 +227,7 @@
         fetchBusinessTypeOptions(),
         listApprovalTemplate(TEMPLATE_TYPE_CUSTOM),
       ]);
-      submitBusinessTypeOptions.value = typeOptions.filter((x) => ![5, 6, 7].includes(x.value));
+      submitBusinessTypeOptions.value = typeOptions.filter((x) => ![5, 6, 7, 19].includes(x.value));
       allSubmitTemplates.value = unwrapTemplateList(customRes)
         .filter((row) => mapEnabledFromApi(row.enabled))
         .map(mapSubmitTemplateCard);
@@ -324,6 +325,22 @@
       }
     }
     
+    // 閿�鍞鎵癸細鐢� quotationNo锛堥攢鍞悎鍚屽彿锛夊幓鏌ラ攢鍞彴璐﹁鎯�
+    else if (row.businessType === 19) {
+      const salesContractNo = row?.quotationNo;
+      if (salesContractNo) {
+        const listRes = await ledgerListPage({ salesContractNo });
+        const records = listRes?.records || listRes?.data || [];
+        const ledger = Array.isArray(records) ? records[0] : null;
+        if (ledger?.id) {
+          const detail = await getSalesLedgerWithProducts({ id: ledger.id, type: 1 });
+          detailData.value = detail || ledger;
+        } else {
+          detailData.value = ledger || {};
+        }
+      }
+    }
+
     // 鍏朵粬瀹℃壒绫诲瀷
     else {
       detailData.value = {};
@@ -369,6 +386,22 @@
       }
     }
 
+    // 閿�鍞鎵癸細鐢� quotationNo锛堥攢鍞悎鍚屽彿锛夊幓鏌ラ攢鍞彴璐﹁鎯�
+    else if (row.businessType === 19) {
+      const salesContractNo = row?.quotationNo;
+      if (salesContractNo) {
+        const listRes = await ledgerListPage({ salesContractNo });
+        const records = listRes?.records || listRes?.data || [];
+        const ledger = Array.isArray(records) ? records[0] : null;
+        if (ledger?.id) {
+          const detail = await getSalesLedgerWithProducts({ id: ledger.id, type: 1 });
+          detailData.value = detail || ledger;
+        } else {
+          detailData.value = ledger || {};
+        }
+      }
+    }
+
     // 鍏朵粬瀹℃壒绫诲瀷
     else {
       detailData.value = {};
diff --git a/src/views/productionPlan/productionPlan/index.vue b/src/views/productionPlan/productionPlan/index.vue
index fd6c1a3..416ecfb 100644
--- a/src/views/productionPlan/productionPlan/index.vue
+++ b/src/views/productionPlan/productionPlan/index.vue
@@ -377,6 +377,30 @@
       },
     },
     {
+      label: "瀹℃壒鐘舵��",
+      prop: "approvalStatus",
+      width: "100px",
+      dataType: "tag",
+      formatType: params => {
+        const typeMap = {
+          0: "info",
+          1: "warning",
+          2: "success",
+          3: "danger",
+        };
+        return typeMap[params] || "info";
+      },
+      formatData: cell => {
+        const statusMap = {
+          0: "寰呭鎵�",
+          1: "瀹℃壒涓�",
+          2: "宸查�氳繃",
+          3: "宸查┏鍥�",
+        };
+        return statusMap[cell] || "-";
+      },
+    },
+    {
       label: "宸蹭笅鍙戞暟閲�",
       prop: "quantityIssued",
       width: "120px",
diff --git a/src/views/qualityManagement/nonconformingManagement/components/formDia.vue b/src/views/qualityManagement/nonconformingManagement/components/formDia.vue
index e747d04..2239f47 100644
--- a/src/views/qualityManagement/nonconformingManagement/components/formDia.vue
+++ b/src/views/qualityManagement/nonconformingManagement/components/formDia.vue
@@ -112,6 +112,13 @@
             </el-form-item>
           </el-col>
         </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="闄勪欢锛�">
+              <FileUpload v-model:file-list="form.storageBlobDTOs" :file-list="form.storageBlobVOs" />
+            </el-form-item>
+          </el-col>
+        </el-row>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
@@ -132,6 +139,7 @@
   qualityUnqualifiedUpdate
 } from "@/api/qualityManagement/nonconformingManagement.js";
 import {userListNoPage} from "@/api/system/user.js";
+import FileUpload from "@/components/AttachmentUpload/file/index.vue";
 import useUserStore from "@/store/modules/user";
 const { proxy } = getCurrentInstance()
 const userStore = useUserStore()
@@ -158,6 +166,8 @@
     dealName: '',
     dealTime: '',
     productModelId: undefined,
+    storageBlobDTOs: [],
+    storageBlobVOs: [],
   },
   rules: {
     checkTime: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" },],
diff --git a/src/views/qualityManagement/nonconformingManagement/components/inspectionFormDia.vue b/src/views/qualityManagement/nonconformingManagement/components/inspectionFormDia.vue
index 8f4492a..e53fc49 100644
--- a/src/views/qualityManagement/nonconformingManagement/components/inspectionFormDia.vue
+++ b/src/views/qualityManagement/nonconformingManagement/components/inspectionFormDia.vue
@@ -109,6 +109,13 @@
             </el-form-item>
           </el-col>
         </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="闄勪欢锛�">
+              <FileUpload v-model:file-list="form.storageBlobDTOs" :file-list="form.storageBlobVOs" />
+            </el-form-item>
+          </el-col>
+        </el-row>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
@@ -128,6 +135,7 @@
   qualityUnqualifiedDeal
 } from "@/api/qualityManagement/nonconformingManagement.js";
 import {userListNoPage} from "@/api/system/user.js";
+import FileUpload from "@/components/AttachmentUpload/file/index.vue";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 
@@ -151,7 +159,9 @@
     dealResult: '',
     dealName: '',
     dealTime: '',
-    method: undefined
+    method: undefined,
+    storageBlobDTOs: [],
+    storageBlobVOs: [],
   },
   rules: {
     checkTime: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" },],
diff --git a/src/views/qualityManagement/nonconformingManagement/components/orderFormDia.vue b/src/views/qualityManagement/nonconformingManagement/components/orderFormDia.vue
new file mode 100644
index 0000000..0cba8c3
--- /dev/null
+++ b/src/views/qualityManagement/nonconformingManagement/components/orderFormDia.vue
@@ -0,0 +1,296 @@
+<template>
+  <div>
+    <el-dialog
+      v-model="dialogFormVisible"
+      :title="operationType === 'add' ? '鏂板涓嶅悎鏍煎搧澶勭悊鍗�' : '缂栬緫涓嶅悎鏍煎搧澶勭悊鍗�'"
+      width="70%"
+      @close="closeDia"
+    >
+      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="椤圭洰鍚嶇О" prop="projectName">
+              <el-input v-model="form.projectName" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="椤圭洰缂栧彿" prop="projectNo">
+              <el-input v-model="form.projectNo" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="璁惧鍚嶇О" prop="equipmentName">
+              <el-input v-model="form.equipmentName" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="璁惧鍥惧彿" prop="equipmentDrawingNo">
+              <el-input v-model="form.equipmentDrawingNo" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鐗╂枡/閮ㄤ欢鍚嶇О" prop="materialName">
+              <el-input v-model="form.materialName" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鐗╂枡鍥惧彿" prop="materialDrawingNo">
+              <el-input v-model="form.materialDrawingNo" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鍨嬪彿瑙勬牸" prop="specificationModel">
+              <el-input v-model="form.specificationModel" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鏉愯川" prop="materialQuality">
+              <el-input v-model="form.materialQuality" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鎬绘暟閲�" prop="quantity">
+              <el-input-number v-model="form.quantity" :min="0" style="width: 100%" :disabled="operationType === 'view'" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="涓嶅悎鏍兼暟閲�" prop="unqualifiedQuantity">
+              <el-input-number v-model="form.unqualifiedQuantity" :min="0" style="width: 100%" :disabled="operationType === 'view'" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="涓嶅悎鏍煎伐搴�" prop="unqualifiedProcess">
+              <el-select v-model="form.unqualifiedProcess" placeholder="璇烽�夋嫨" clearable :disabled="operationType === 'view'" style="width: 100%">
+                <el-option label="鏉ユ枡" :value="1" />
+                <el-option label="鍒剁▼" :value="2" />
+                <el-option label="鎴愬搧" :value="3" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="渚涘簲鍟嗗悕绉�" prop="supplierName">
+              <el-input v-model="form.supplierName" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="妫�楠屽憳" prop="inspectorName">
+              <el-input v-model="form.inspectorName" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="妫�楠屾棩鏈�" prop="inspectDate">
+              <el-date-picker v-model="form.inspectDate" type="date" value-format="YYYY-MM-DD" format="YYYY-MM-DD" placeholder="璇烽�夋嫨" clearable style="width: 100%" :disabled="operationType === 'view'" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="璐d换浜�" prop="responsiblePerson">
+              <el-input v-model="form.responsiblePerson" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="璐d换閮ㄩ棬" prop="responsibleDept">
+              <el-input v-model="form.responsibleDept" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="闂鎻忚堪" prop="problemDescription">
+              <el-input type="textarea" v-model="form.problemDescription" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" :rows="3" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="鍘熷洜鍒嗘瀽鍙婂缓璁�" prop="reasonAnalysis">
+              <el-input type="textarea" v-model="form.reasonAnalysis" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" :rows="3" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="绾犳鎺柦" prop="correctionAction">
+              <el-input type="textarea" v-model="form.correctionAction" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" :rows="3" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="澶勭疆鏂瑰紡" prop="disposalMethod">
+              <el-select v-model="form.disposalMethod" placeholder="璇烽�夋嫨" clearable :disabled="operationType === 'view'" style="width: 100%">
+                <el-option label="璁╂鎺ユ敹" :value="1" />
+                <el-option label="鍘傚唴缁翠慨" :value="2" />
+                <el-option label="杩斿巶缁翠慨" :value="3" />
+                <el-option label="鎹㈣揣" :value="4" />
+                <el-option label="閫�璐�" :value="5" />
+                <el-option label="鎶ュ簾" :value="6" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="缁翠慨璇勪及" prop="repairEvaluation">
+              <el-input type="textarea" v-model="form.repairEvaluation" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" :rows="3" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="棰勯槻鎺柦" prop="preventiveAction">
+              <el-input type="textarea" v-model="form.preventiveAction" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" :rows="3" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="澶囨敞" prop="remark">
+              <el-input type="textarea" v-model="form.remark" placeholder="璇疯緭鍏�" clearable :disabled="operationType === 'view'" :rows="2" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="闄勪欢">
+              <FileUpload v-model:file-list="form.storageBlobDTOs" :file-list="form.storageBlobVOs" :disabled="operationType === 'view'" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm" v-if="operationType !== 'view'">纭</el-button>
+          <el-button @click="closeDia">鍏抽棴</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, toRefs, getCurrentInstance } from "vue";
+import { save, update, getDetail } from "@/api/qualityManagement/qualityUnqualifiedOrder.js";
+import FileUpload from "@/components/AttachmentUpload/file/index.vue";
+
+const { proxy } = getCurrentInstance();
+const emit = defineEmits(["close"]);
+
+const dialogFormVisible = ref(false);
+const operationType = ref("");
+
+const data = reactive({
+  form: {
+    projectName: "",
+    projectNo: "",
+    equipmentName: "",
+    equipmentDrawingNo: "",
+    materialName: "",
+    materialDrawingNo: "",
+    specificationModel: "",
+    materialQuality: "",
+    quantity: undefined,
+    unqualifiedQuantity: undefined,
+    unqualifiedProcess: undefined,
+    supplierName: "",
+    inspectorName: "",
+    inspectDate: "",
+    responsiblePerson: "",
+    responsibleDept: "",
+    problemDescription: "",
+    reasonAnalysis: "",
+    correctionAction: "",
+    disposalMethod: undefined,
+    repairEvaluation: "",
+    preventiveAction: "",
+    remark: "",
+    storageBlobDTOs: [],
+    storageBlobVOs: [],
+  },
+  rules: {
+    projectName: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
+  },
+});
+const { form, rules } = toRefs(data);
+
+const openDialog = async (type, row) => {
+  operationType.value = type;
+  dialogFormVisible.value = true;
+  if (type === "add") {
+    form.value = {
+      projectName: "",
+      projectNo: "",
+      equipmentName: "",
+      equipmentDrawingNo: "",
+      materialName: "",
+      materialDrawingNo: "",
+      specificationModel: "",
+      materialQuality: "",
+      quantity: undefined,
+      unqualifiedQuantity: undefined,
+      unqualifiedProcess: undefined,
+      supplierName: "",
+      inspectorName: "",
+      inspectDate: "",
+      responsiblePerson: "",
+      responsibleDept: "",
+      problemDescription: "",
+      reasonAnalysis: "",
+      correctionAction: "",
+      disposalMethod: undefined,
+      repairEvaluation: "",
+      preventiveAction: "",
+      remark: "",
+      storageBlobDTOs: [],
+      storageBlobVOs: [],
+    };
+  } else {
+    form.value = {};
+    if (row?.id) {
+      getDetail(row.id).then((res) => {
+        form.value = res.data || res || {};
+      });
+    }
+  }
+};
+
+const submitForm = () => {
+  proxy.$refs.formRef.validate((valid) => {
+    if (valid) {
+      const { status, ...payload } = form.value || {};
+      if (operationType.value === "add") {
+        save(payload).then(() => {
+          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+          closeDia();
+        });
+      } else {
+        update(payload).then(() => {
+          proxy.$modal.msgSuccess("淇敼鎴愬姛");
+          closeDia();
+        });
+      }
+    }
+  });
+};
+
+const closeDia = () => {
+  proxy.resetForm("formRef");
+  dialogFormVisible.value = false;
+  emit("close");
+};
+
+defineExpose({ openDialog });
+</script>
+
+<style scoped></style>
diff --git a/src/views/qualityManagement/nonconformingManagement/index.vue b/src/views/qualityManagement/nonconformingManagement/index.vue
index fc9d5d2..3afcf9c 100644
--- a/src/views/qualityManagement/nonconformingManagement/index.vue
+++ b/src/views/qualityManagement/nonconformingManagement/index.vue
@@ -36,7 +36,8 @@
       </el-form>
     </div>
     <div class="mb20" style="text-align: right;">
-        <el-button type="primary" @click="openForm('add')">鏂板</el-button>
+<!--        <el-button type="primary" @click="openForm('add')">鏂板</el-button>-->
+        <el-button type="primary" @click="openOrderForm">澶勭悊鍗�</el-button>
         <el-button @click="handleOut">瀵煎嚭</el-button>
         <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
       </div>
@@ -55,6 +56,7 @@
     </div>
     <FormDia ref="formDia" @close="handleQuery"></FormDia>
     <InspectionFormDia ref="inspectionFormDia" @close="handleQuery"></InspectionFormDia>
+    <OrderFormDia ref="orderFormDia" @close="handleQuery"></OrderFormDia>
   </div>
 </template>
 
@@ -65,6 +67,7 @@
 import {ElMessageBox} from "element-plus";
 import {qualityUnqualifiedDel, qualityUnqualifiedListPage} from "@/api/qualityManagement/nonconformingManagement.js";
 import InspectionFormDia from "@/views/qualityManagement/nonconformingManagement/components/inspectionFormDia.vue";
+import OrderFormDia from "@/views/qualityManagement/nonconformingManagement/components/orderFormDia.vue";
 import dayjs from "dayjs";
 
 const data = reactive({
@@ -200,6 +203,7 @@
 });
 const formDia = ref()
 const inspectionFormDia = ref()
+const orderFormDia = ref()
 const { proxy } = getCurrentInstance()
 
 const changeDaterange = (value) => {
@@ -260,6 +264,13 @@
   })
 };
 
+// 鎵撳紑澶勭悊鍗曞脊妗�
+const openOrderForm = () => {
+  nextTick(() => {
+    orderFormDia.value?.openDialog("add", null);
+  });
+};
+
 // 鍒犻櫎
 const handleDelete = () => {
   let ids = [];
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index 5c643d7..1f86d63 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -241,6 +241,14 @@
           width="120"
           show-overflow-tooltip
         />
+        <el-table-column label="瀹℃壒鐘舵��" prop="approvalStatus" width="100" align="center">
+          <template #default="scope">
+            <el-tag v-if="scope.row.approvalStatus === 0" type="info">寰呭鎵�</el-tag>
+            <el-tag v-else-if="scope.row.approvalStatus === 1" type="warning">瀹℃壒涓�</el-tag>
+            <el-tag v-else-if="scope.row.approvalStatus === 2" type="success">宸查�氳繃</el-tag>
+            <el-tag v-else-if="scope.row.approvalStatus === 3" type="danger">宸查┏鍥�</el-tag>
+          </template>
+        </el-table-column>
         <el-table-column
           label="浜や粯鏃ユ湡"
           prop="deliveryDate"
@@ -582,6 +590,16 @@
             </el-form-item>
           </el-col>
         </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="瀹℃壒鐘舵�侊細">
+              <el-tag v-if="form.approvalStatus === 0" type="info">寰呭鎵�</el-tag>
+              <el-tag v-else-if="form.approvalStatus === 1" type="warning">瀹℃壒涓�</el-tag>
+              <el-tag v-else-if="form.approvalStatus === 2" type="success">宸查�氳繃</el-tag>
+              <el-tag v-else-if="form.approvalStatus === 3" type="danger">宸查┏鍥�</el-tag>
+            </el-form-item>
+          </el-col>
+        </el-row>
       </el-form>
     </FormDialog>
     <!-- 浠庢姤浠峰崟瀵煎叆锛堜粎瀹℃壒閫氳繃锛� -->

--
Gitblit v1.9.3