From 2d3530a7c11557a40807ad7c0b9e302ce6ce3a9f Mon Sep 17 00:00:00 2001
From: hsy <1029150275@qq.com>
Date: 星期五, 28 八月 2026 10:16:32 +0800
Subject: [PATCH] feat: 综合业务模块页面重构与交互完善

---
 src/views/salesManagement/salesLedger/index.vue |  439 ++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 372 insertions(+), 67 deletions(-)

diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index d2e82b5..ccef759 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -188,6 +188,7 @@
           </template>
         </el-table-column>
         <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+
         <el-table-column
           label="閿�鍞悎鍚屽彿"
           prop="salesContractNo"
@@ -216,7 +217,14 @@
           label="浠樻鏂瑰紡"
           prop="paymentMethod"
           show-overflow-tooltip
-        />
+        >
+          <template #default="scope">
+            <dict-tag
+              :options="checkout_payment"
+              :value="scope.row.paymentMethod"
+            />
+          </template>
+        </el-table-column>
         <el-table-column
           label="鍚堝悓閲戦(鍏�)"
           prop="contractAmount"
@@ -322,6 +330,76 @@
             </el-button>
           </el-col>
         </el-row>
+
+        <el-divider content-position="left">鍏宠仈椤圭洰</el-divider>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="瀹㈡埛鍚嶇О锛�" prop="customerId">
+              <el-select
+                v-model="form.customerId"
+                placeholder="璇烽�夋嫨"
+                clearable
+                :disabled="operationType === 'view'"
+                filterable
+              >
+                <el-option
+                  v-for="item in customerOption"
+                  :key="item.id"
+                  :label="item.customerName"
+                  :value="item.id"
+                >
+                  {{
+                    item.customerName + "鈥斺��" + item.taxpayerIdentificationNumber
+                  }}
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectId">
+              <el-select
+                v-model="form.projectId"
+                placeholder="璇烽�夋嫨椤圭洰"
+                clearable
+                filterable
+                :disabled="operationType === 'view'"
+                @focus="previousProjectId = form.projectId"
+                @change="handleProjectChange"
+              >
+                <el-option
+                  v-for="item in projectOptions"
+                  :key="item.id"
+                  :label="item.no + ' - ' + item.title"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="鍏宠仈鍚堝悓锛�" prop="associatedContractIds">
+              <el-select
+                v-model="form.associatedContractIds"
+                multiple
+                placeholder="璇烽�夋嫨鍏宠仈鍚堝悓"
+                clearable
+                filterable
+                :disabled="operationType === 'view'"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="item in contractOptions"
+                  :key="item.id"
+                  :label="item.contractNo"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-divider content-position="left">鍙拌处淇℃伅</el-divider>
         <el-row :gutter="30">
           <el-col :span="12">
             <el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesContractNo">
@@ -372,44 +450,11 @@
         </el-row>
         <el-row :gutter="30">
           <el-col :span="12">
-            <el-form-item label="瀹㈡埛鍚嶇О锛�" prop="customerId">
-              <el-select
-                v-model="form.customerId"
-                placeholder="璇烽�夋嫨"
-                clearable
-                :disabled="operationType === 'view'"
-                filterable
-              >
-                <el-option
-                  v-for="item in customerOption"
-                  :key="item.id"
-                  :label="item.customerName"
-                  :value="item.id"
-                >
-                  {{
-                    item.customerName + "鈥斺��" + item.taxpayerIdentificationNumber
-                  }}
-                </el-option>
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <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-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
             <el-form-item label="绛捐鏃ユ湡锛�" prop="executionDate">
               <el-date-picker
                 style="width: 100%"
                 v-model="form.executionDate"
+                @change="(val) => { if(val) form.year = parseInt(val.substring(0, 4)) }"
                 value-format="YYYY-MM-DD"
                 format="YYYY-MM-DD"
                 type="date"
@@ -421,12 +466,19 @@
           </el-col>
           <el-col :span="12">
             <el-form-item label="浠樻鏂瑰紡">
-              <el-input
+              <el-select
                 v-model="form.paymentMethod"
-                placeholder="璇疯緭鍏�"
+                placeholder="璇烽�夋嫨浠樻鏂瑰紡"
                 clearable
                 :disabled="operationType === 'view'"
-              />
+              >
+                <el-option
+                  v-for="item in checkout_payment"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                />
+              </el-select>
             </el-form-item>
           </el-col>
         </el-row>
@@ -483,13 +535,160 @@
             </el-form-item>
           </el-col>
         </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="绛惧崟鍗曚綅锛�" prop="signingUnitId">
+              <el-tree-select
+                v-model="form.signingUnitId"
+                :data="deptOptions"
+                :props="{ value: 'id', label: 'label', children: 'children' }"
+                value-key="id"
+                placeholder="璇烽�夋嫨绛惧崟鍗曚綅"
+                check-strictly
+                clearable
+                :disabled="operationType === 'view'"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍔炰簨澶勶細" prop="officeId">
+              <el-tree-select
+                v-model="form.officeId"
+                :data="deptOptions"
+                :props="{ value: 'id', label: 'label', children: 'children' }"
+                value-key="id"
+                placeholder="璇烽�夋嫨鍔炰簨澶�"
+                check-strictly
+                clearable
+                :disabled="operationType === 'view'"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="缁勮礋璐d汉锛�" prop="groupLeaderId">
+              <el-select
+                v-model="form.groupLeaderId"
+                filterable
+                placeholder="璇烽�夋嫨缁勮礋璐d汉"
+                clearable
+                :disabled="operationType === 'view'"
+              >
+                <el-option
+                  v-for="item in userList"
+                  :key="item.userId"
+                  :label="item.nickName"
+                  :value="item.userId"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="骞翠唤锛�">
+              <el-input
+                v-model="form.year"
+                placeholder="鑷姩鍙栫璁㈡棩鏈�"
+                disabled
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鏄惁寮�鍙戠エ锛�">
+              <el-switch
+                v-model="form.isInvoice"
+                :active-value="1"
+                :inactive-value="0"
+                :disabled="operationType === 'view'"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鏄惁涓爣锛�">
+              <el-switch
+                v-model="form.isBid"
+                :active-value="1"
+                :inactive-value="0"
+                :disabled="operationType === 'view'"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12" v-if="form.isBid === 1">
+            <el-form-item label="涓爣浠凤細">
+              <el-input-number
+                v-model="form.bidPrice"
+                :precision="2"
+                :step="1000"
+                :min="0"
+                style="width: 100%"
+                :disabled="operationType === 'view'"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="form.isBid !== 1">
+            <el-form-item label="鏈腑鏍囧師鍥狅細">
+              <el-input
+                v-model="form.unbidReason"
+                placeholder="璇疯緭鍏ユ湭涓爣鍘熷洜"
+                clearable
+                :disabled="operationType === 'view'"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鍚堝悓鍘熶欢绾﹀畾鍥炰紶鏃ユ湡锛�">
+              <el-date-picker
+                style="width: 100%"
+                v-model="form.contractOriginalReturnDate"
+                value-format="YYYY-MM-DD"
+                format="YYYY-MM-DD"
+                type="date"
+                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="remarks">
+              <el-input
+                v-model="form.remarks"
+                placeholder="璇疯緭鍏�"
+                clearable
+                type="textarea"
+                :rows="2"
+                :disabled="operationType === 'view'"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row v-if="operationType !== 'view'" :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="闄勪欢鏉愭枡锛�" prop="salesLedgerFiles">
+              <FileUpload
+                v-model:file-list="fileList"
+                :disabled="operationType === 'view'"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-divider content-position="left">浜у搧淇℃伅</el-divider>
         <el-row>
-          <el-form-item label="浜у搧淇℃伅锛�" prop="entryDate">
+          <el-form-item label="" prop="entryDate">
             <el-button
               v-if="operationType !== 'view'"
               type="primary"
               @click="openProductForm('add')"
-              >娣诲姞
+              >娣诲姞鏄庣粏
             </el-button>
             <el-button
               v-if="operationType !== 'view'"
@@ -566,30 +765,6 @@
             </template>
           </el-table-column>
         </el-table>
-        <el-row :gutter="30">
-          <el-col :span="24">
-            <el-form-item label="澶囨敞锛�" prop="remarks">
-              <el-input
-                v-model="form.remarks"
-                placeholder="璇疯緭鍏�"
-                clearable
-                type="textarea"
-                :rows="2"
-                :disabled="operationType === 'view'"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row v-if="operationType !== 'view'" :gutter="30">
-          <el-col :span="24">
-            <el-form-item label="闄勪欢鏉愭枡锛�" prop="salesLedgerFiles">
-              <FileUpload
-                v-model:file-list="fileList"
-                :disabled="operationType === 'view'"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
       </el-form>
     </FormDialog>
     <!-- 浠庢姤浠峰崟瀵煎叆锛堜粎瀹℃壒閫氳繃锛� -->
@@ -1105,6 +1280,56 @@
         </el-row>
         <el-row :gutter="30">
           <el-col :span="24">
+            <el-form-item label="鍙戣揣鍗曟嵁锛�" prop="shippingDocument">
+              <el-input
+                v-model="deliveryForm.shippingDocument"
+                placeholder="璇疯緭鍏ュ彂璐у崟鎹�"
+                clearable
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="8">
+            <el-form-item label="鏄惁瀵硅处锛�" prop="isReconciled">
+              <el-switch v-model="deliveryForm.isReconciled" :active-value="1" :inactive-value="0" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鏄惁缁撶畻锛�" prop="isSettled">
+              <el-switch v-model="deliveryForm.isSettled" :active-value="1" :inactive-value="0" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鏄惁宸插紑绁細" prop="isInvoiced">
+              <el-switch v-model="deliveryForm.isInvoiced" :active-value="1" :inactive-value="0" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12" v-if="deliveryForm.isReconciled === 1">
+            <el-form-item label="瀵硅处鍗曞綊妗f儏鍐碉細" prop="statementArchivingStatus">
+              <el-input
+                type="textarea"
+                v-model="deliveryForm.statementArchivingStatus"
+                placeholder="璇疯緭鍏ュ璐﹀崟褰掓。鎯呭喌"
+                clearable
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="deliveryForm.isSettled === 1">
+            <el-form-item label="缁撶畻鍗曞綊妗f儏鍐碉細" prop="settlementArchivingStatus">
+              <el-input
+                type="textarea"
+                v-model="deliveryForm.settlementArchivingStatus"
+                placeholder="璇疯緭鍏ョ粨绠楀崟褰掓。鎯呭喌"
+                clearable
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
             <el-form-item label="搴撳瓨锛�" prop="batchNo">
               <el-table
                 :data="deliveryForm.batchNoList"
@@ -1176,9 +1401,11 @@
 import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
 import { ElMessageBox, ElMessage } from "element-plus";
 import useUserStore from "@/store/modules/user";
-import { userListNoPage } from "@/api/system/user.js";
+import { userListNoPage, deptTreeSelect } from "@/api/system/user.js";
+import { listProject, getProject } from "@/api/projectManagement/project.js";
 import FormDialog from "@/components/Dialog/FormDialog.vue";
 import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
+import { contractListNoPage } from "@/api/salesManagement/contractManagement.js";
 import {
   ledgerListPage,
   productList,
@@ -1208,12 +1435,15 @@
 const route = useRoute();
 const userStore = useUserStore();
 const { proxy } = getCurrentInstance();
-const { tax_rate } = proxy.useDict("tax_rate");
+const { tax_rate, checkout_payment } = proxy.useDict("tax_rate", "checkout_payment");
 const tableData = ref([]);
 const productData = ref([]);
 const selectedRows = ref([]);
 const productSelectedRows = ref([]);
 const userList = ref([]);
+const deptOptions = ref([]);
+const projectOptions = ref([]);
+const contractOptions = ref([]);
 const customerOption = ref([]);
 const productOptions = ref([]);
 const modelOptions = ref([]);
@@ -1248,6 +1478,18 @@
     maintenanceTime: "",
     productData: [],
     executionDate: "",
+    projectId: undefined,
+    associatedContractIds: [],
+
+    year: "",
+    signingUnitId: undefined,
+    officeId: undefined,
+    groupLeaderId: undefined,
+    isInvoice: 0,
+    bidPrice: undefined,
+    isBid: 0,
+    unbidReason: "",
+    contractOriginalReturnDate: "",
     hasProductionRecord: false,
     createTime: "",
   },
@@ -1323,6 +1565,51 @@
   total: 0,
 });
 const selectedQuotation = ref(null);
+
+const previousProjectId = ref(null);
+const handleProjectChange = (val) => {
+  if (productData.value && productData.value.length > 0) {
+    ElMessageBox.confirm("褰撳墠宸插綍鍏ヤ骇鍝佹槑缁嗭紝鍒囨崲椤圭洰灏嗚瑕嗙洊锛屾槸鍚︾户缁紵", "鎻愮ず", {
+      type: "warning",
+    })
+      .then(() => {
+        previousProjectId.value = val;
+        fetchAndPopulateProject(val);
+      })
+      .catch(() => {
+        form.value.projectId = previousProjectId.value;
+      });
+  } else {
+    previousProjectId.value = val;
+    fetchAndPopulateProject(val);
+  }
+};
+
+const fetchAndPopulateProject = (val) => {
+  let proj = projectOptions.value.find((p) => p.id === val);
+  form.value.projectName = proj ? proj.title : "";
+
+  if (!val) {
+    productData.value = [];
+    return;
+  }
+
+  getProject(val).then((res) => {
+    const projectInfo = res.data;
+    if (projectInfo.info && projectInfo.info.clientId) {
+      form.value.customerId = projectInfo.info.clientId;
+    }
+    if (projectInfo.salesLedgerProductList) {
+      productData.value = projectInfo.salesLedgerProductList.map((item) => ({
+        ...item,
+        id: undefined,
+        salesLedgerId: undefined
+      }));
+    } else {
+      productData.value = [];
+    }
+  });
+};
 
 // 鍙戣揣鐩稿叧
 const deliveryFormVisible = ref(false);
@@ -1423,6 +1710,12 @@
     expressCompany: "",
     expressNumber: "",
     type: "璐ц溅", // 璐ц溅, 蹇��
+    shippingDocument: "",
+    isReconciled: 0,
+    statementArchivingStatus: "",
+    isSettled: 0,
+    settlementArchivingStatus: "",
+    isInvoiced: 0,
   },
   deliveryRules: {
     shippingCarNumber: [
@@ -1750,6 +2043,9 @@
   form.value = {};
   productData.value = [];
   selectedQuotation.value = null;
+  deptTreeSelect().then(res => deptOptions.value = res.data);
+  listProject({}).then(res => projectOptions.value = res.rows || res.data.records || res.data);
+  contractListNoPage({}).then(res => contractOptions.value = res.data);
   let userLists = await userListNoPage();
   userList.value = userLists.data;
   listCustomer({ current: -1, size: -1, type: 0 }).then((res) => {
@@ -2993,13 +3289,22 @@
   let res = await userStore.getInfo();
   currentFactoryName.value = res.user.currentFactoryName;
 };
-onMounted(() => {
+onMounted(async () => {
   searchForm.salesContractNo = route.query.salesContractNo;
   getList();
   userListNoPage().then((res) => {
     userList.value = res.data;
   });
   getCurrentFactoryName();
+
+  if (route.query.action === "add") {
+    await openForm("add");
+    if (route.query.projectId) {
+      const pId = Number(route.query.projectId);
+      form.value.projectId = pId;
+      fetchAndPopulateProject(pId);
+    }
+  }
 });
 </script>
 

--
Gitblit v1.9.3