From 4b96a3812c141f06c767467a7f9e41940b4e8d03 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期三, 24 六月 2026 18:42:13 +0800
Subject: [PATCH] 1.客户,销售,供应商,采购增加总合同号 2.采购的产品增加库存状态回显 3.出厂改成创建时间倒序 4.开发总合同号管理页面

---
 src/views/basicData/supplierManage/components/HomeTab.vue |  531 ++++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 386 insertions(+), 145 deletions(-)

diff --git a/src/views/basicData/supplierManage/components/HomeTab.vue b/src/views/basicData/supplierManage/components/HomeTab.vue
index da62ca4..eea719d 100644
--- a/src/views/basicData/supplierManage/components/HomeTab.vue
+++ b/src/views/basicData/supplierManage/components/HomeTab.vue
@@ -23,7 +23,7 @@
         <el-button type="info" plain icon="Upload" @click="handleImport"
         >瀵煎叆</el-button
         >
-        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+        <el-button type="danger" plain @click="handleDelete" v-hasPermi="['basicData:supplierManage:remove']">鍒犻櫎</el-button>
       </div>
     </div>
     <div class="table_list">
@@ -44,155 +44,259 @@
         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="supplierName">
-              <el-input
-                  v-model="form.supplierName"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item
-                label="绾崇◣浜鸿瘑鍒彿锛�"
-                prop="taxpayerIdentificationNum"
-            >
-              <el-input
-                  v-model="form.taxpayerIdentificationNum"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鍏徃鍦板潃锛�" prop="companyAddress">
-              <el-input
-                  v-model="form.companyAddress"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鍏徃鐢佃瘽锛�" prop="companyPhone">
-              <el-input
-                  v-model="form.companyPhone"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="寮�鎴疯锛�" prop="bankAccountName">
-              <el-input
-                  v-model="form.bankAccountName"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="璐﹀彿锛�" prop="bankAccountNum">
-              <el-input
-                  v-model="form.bankAccountNum"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="鑱旂郴浜猴細" prop="contactUserName">
-              <el-input
-                  v-model="form.contactUserName"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鑱旂郴鐢佃瘽锛�" prop="contactUserPhone">
-              <el-input
-                  v-model="form.contactUserPhone"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="缁存姢浜猴細" prop="maintainUserId">
-              <el-select
-                  v-model="form.maintainUserId"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-                  disabled
-              >
-                <el-option
-                    v-for="item in userList"
-                    :key="item.nickName"
-                    :label="item.nickName"
-                    :value="item.userId"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="缁存姢鏃堕棿锛�" prop="maintainTime">
-              <el-date-picker
-                  style="width: 100%"
-                  v-model="form.maintainTime"
-                  value-format="YYYY-MM-DD"
-                  format="YYYY-MM-DD"
-                  type="date"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="渚涘簲鍟嗙被鍨嬶細" prop="supplierType">
-              <el-select v-model="form.supplierType" placeholder="璇烽�夋嫨" clearable>
-                <el-option label="鐢�" value="鐢�" />
-                <el-option label="涔�" value="涔�" />
-                <el-option label="涓�" value="涓�" />
-                <el-option label="涓�" value="涓�" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鏄惁鐧藉悕鍗曪細" prop="isWhite">
-              <el-select v-model="form.isWhite" placeholder="璇烽�夋嫨" clearable>
-                <el-option label="鏄�" :value="0" />
-                <el-option label="鍚�" :value="1" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
-      </el-form>
+      <el-tabs v-model="supplierActiveTab">
+        <!-- 鍩烘湰淇℃伅 Tab -->
+        <el-tab-pane label="鍩烘湰淇℃伅" name="basic">
+          <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="supplierName">
+                  <el-input
+                      v-model="form.supplierName"
+                      placeholder="璇疯緭鍏�"
+                      clearable
+                  />
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item
+                    label="绾崇◣浜鸿瘑鍒彿锛�"
+                    prop="taxpayerIdentificationNum"
+                >
+                  <el-input
+                      v-model="form.taxpayerIdentificationNum"
+                      placeholder="璇疯緭鍏�"
+                      clearable
+                  />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="30">
+              <el-col :span="12">
+                <el-form-item label="鍏徃鍦板潃锛�" prop="companyAddress">
+                  <el-input
+                      v-model="form.companyAddress"
+                      placeholder="璇疯緭鍏�"
+                      clearable
+                  />
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="鍏徃鐢佃瘽锛�" prop="companyPhone">
+                  <el-input
+                      v-model="form.companyPhone"
+                      placeholder="璇疯緭鍏�"
+                      clearable
+                  />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="30">
+              <el-col :span="12">
+                <el-form-item label="寮�鎴疯锛�" prop="bankAccountName">
+                  <el-input
+                      v-model="form.bankAccountName"
+                      placeholder="璇疯緭鍏�"
+                      clearable
+                  />
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="璐﹀彿锛�" prop="bankAccountNum">
+                  <el-input
+                      v-model="form.bankAccountNum"
+                      placeholder="璇疯緭鍏�"
+                      clearable
+                  />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="30">
+              <el-col :span="12">
+                <el-form-item label="鑱旂郴浜猴細" prop="contactUserName">
+                  <el-input
+                      v-model="form.contactUserName"
+                      placeholder="璇疯緭鍏�"
+                      clearable
+                  />
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="鑱旂郴鐢佃瘽锛�" prop="contactUserPhone">
+                  <el-input
+                      v-model="form.contactUserPhone"
+                      placeholder="璇疯緭鍏�"
+                      clearable
+                  />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="30">
+              <el-col :span="12">
+                <el-form-item label="缁存姢浜猴細" prop="maintainUserId">
+                  <el-select
+                      v-model="form.maintainUserId"
+                      placeholder="璇烽�夋嫨"
+                      clearable
+                      disabled
+                  >
+                    <el-option
+                        v-for="item in userList"
+                        :key="item.nickName"
+                        :label="item.nickName"
+                        :value="item.userId"
+                    />
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="缁存姢鏃堕棿锛�" prop="maintainTime">
+                  <el-date-picker
+                      style="width: 100%"
+                      v-model="form.maintainTime"
+                      value-format="YYYY-MM-DD"
+                      format="YYYY-MM-DD"
+                      type="date"
+                      placeholder="璇烽�夋嫨"
+                      clearable
+                  />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="30">
+              <el-col :span="12">
+                <el-form-item label="渚涘簲鍟嗙被鍨嬶細" prop="supplierType">
+                  <el-select v-model="form.supplierType" placeholder="璇烽�夋嫨" clearable>
+                    <el-option label="鐢�" value="鐢�" />
+                    <el-option label="涔�" value="涔�" />
+                    <el-option label="涓�" value="涓�" />
+                    <el-option label="涓�" value="涓�" />
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="鏄惁鐧藉悕鍗曪細" prop="isWhite">
+                  <el-select v-model="form.isWhite" placeholder="璇烽�夋嫨" clearable>
+                    <el-option label="鏄�" :value="0" />
+                    <el-option label="鍚�" :value="1" />
+                  </el-select>
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </el-form>
+        </el-tab-pane>
+
+        <!-- 鍚堝悓璁板綍 Tab -->
+        <el-tab-pane label="鍚堝悓璁板綍" name="contract" :disabled="operationType === 'add' || !currentSupplierId">
+          <div style="margin-bottom: 15px;">
+            <el-button type="primary" size="small" @click="handleAddContract">鏂板鍚堝悓璁板綍</el-button>
+          </div>
+          <el-table :data="contractRecordList" border style="width: 100%">
+            <el-table-column prop="masterContractNo" label="鎬诲悎鍚屽彿" show-overflow-tooltip />
+            <el-table-column prop="entryDate" label="褰曞叆鏃ユ湡" width="180" />
+            <el-table-column prop="entryPerson" label="褰曞叆浜�" width="120" />
+            <el-table-column prop="remark" label="澶囨敞" show-overflow-tooltip />
+            <el-table-column label="闄勪欢" width="100">
+              <template #default="{ row }">
+                <el-link type="primary" v-if="row.fileList && row.fileList.length" @click="handleViewContractFiles(row)">
+                  鏌ョ湅({{ row.fileList.length }})
+                </el-link>
+                <span v-else>-</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="鎿嶄綔" width="150">
+              <template #default="{ row }">
+                <el-button link type="primary" @click="handleEditContract(row)">缂栬緫</el-button>
+                <el-button link type="danger" @click="handleDeleteContract(row)">鍒犻櫎</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-tab-pane>
+      </el-tabs>
       <template #footer>
         <div class="dialog-footer">
           <el-button type="primary" @click="submitForm">纭</el-button>
           <el-button @click="closeDia">鍙栨秷</el-button>
         </div>
       </template>
+    </el-dialog>
+
+    <!-- 鍚堝悓璁板綍寮圭獥 -->
+    <el-dialog
+        v-model="contractDialogVisible"
+        :title="contractDialogTitle"
+        width="600px"
+        :close-on-click-modal="false"
+    >
+      <el-form
+          :model="contractForm"
+          :rules="contractRules"
+          ref="contractFormRef"
+          label-width="100px"
+      >
+        <el-form-item label="鎬诲悎鍚屽彿" prop="masterContractNo">
+          <el-input v-model="contractForm.masterContractNo" placeholder="璇疯緭鍏ユ�诲悎鍚屽彿" clearable />
+        </el-form-item>
+        <el-form-item label="褰曞叆鏃ユ湡" prop="entryDate">
+          <el-date-picker
+              v-model="contractForm.entryDate"
+              type="datetime"
+              placeholder="閫夋嫨鏃ユ湡鏃堕棿"
+              value-format="YYYY-MM-DD HH:mm:ss"
+              style="width: 100%"
+              clearable
+          />
+        </el-form-item>
+        <el-form-item label="褰曞叆浜�" prop="entryPerson">
+          <el-input v-model="contractForm.entryPerson" placeholder="璇疯緭鍏ュ綍鍏ヤ汉" clearable />
+        </el-form-item>
+        <el-form-item label="闄勪欢">
+          <FileUpload
+              v-model="contractForm.storageBlobDTOs"
+              :record-type="'supplier_contract_record'"
+              :record-id="contractForm.id"
+          />
+        </el-form-item>
+        <el-form-item label="澶囨敞">
+          <el-input v-model="contractForm.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitContractForm">纭</el-button>
+          <el-button @click="contractDialogVisible = false">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <!-- 鍚堝悓闄勪欢鏌ョ湅寮圭獥 -->
+    <el-dialog
+        v-model="contractFileDialogVisible"
+        title="鍚堝悓闄勪欢"
+        width="700px"
+        :close-on-click-modal="false"
+    >
+      <el-table :data="contractFileList" border v-if="contractFileList.length">
+        <el-table-column prop="name" label="鏂囦欢鍚嶇О" show-overflow-tooltip />
+        <el-table-column prop="byteSize" label="鏂囦欢澶у皬" width="120">
+          <template #default="{ row }">
+            {{ formatFileSize(row.byteSize) }}
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" width="150">
+          <template #default="{ row }">
+            <el-link type="primary" :href="row.previewURL" target="_blank">棰勮</el-link>
+            <el-link type="primary" :href="row.downloadURL" style="margin-left: 10px">涓嬭浇</el-link>
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-empty v-else description="鏆傛棤闄勪欢" />
     </el-dialog>
 
     <!-- 渚涘簲鍟嗗鍏ュ璇濇 -->
@@ -256,8 +360,16 @@
   listSupplier,
   updateSupplier,
 } from "@/api/basicData/supplierManageFile.js";
+import {
+  getSupplierContractList,
+  getSupplierContractById,
+  addSupplierContract,
+  updateSupplierContract,
+  delSupplierContract,
+} from "@/api/basicData/supplierContract.js";
 import useUserStore from "@/store/modules/user";
 import { getToken } from "@/utils/auth.js";
+import FileUpload from "@/components/AttachmentUpload/file/index.vue";
 const FileList = defineAsyncComponent(() =>
     import("@/components/Dialog/FileList.vue")
 );
@@ -355,6 +467,34 @@
   size: 100,
   total: 0,
 });
+
+// 渚涘簲鍟嗚鎯匱ab鐩稿叧
+const supplierActiveTab = ref('basic');
+const currentSupplierId = ref(null);
+const contractRecordList = ref([]);
+
+// 鍚堝悓璁板綍寮圭獥鐩稿叧
+const contractDialogVisible = ref(false);
+const contractDialogTitle = ref('');
+const contractFormRef = ref();
+const contractForm = reactive({
+  id: null,
+  supplierId: null,
+  masterContractNo: '',
+  entryDate: '',
+  entryPerson: '',
+  entryPersonId: null,
+  remark: '',
+  storageBlobDTOs: []
+});
+const contractRules = {
+  masterContractNo: [{ required: true, message: '璇疯緭鍏ユ�诲悎鍚屽彿', trigger: 'blur' }],
+  entryDate: [{ required: true, message: '璇烽�夋嫨褰曞叆鏃ユ湡', trigger: 'change' }]
+};
+
+// 鍚堝悓闄勪欢寮圭獥鐩稿叧
+const contractFileDialogVisible = ref(false);
+const contractFileList = ref([]);
 // 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
 const operationType = ref("");
 const dialogFormVisible = ref(false);
@@ -472,21 +612,122 @@
   selectedRows.value = selection;
 };
 // 鎵撳紑寮规
-const openForm = (type, row) => {
+const openForm = async (type, row) => {
   operationType.value = type;
   form.value = {};
   form.value.maintainUserId = userStore.id;
   form.value.maintainTime = getCurrentDate();
+  supplierActiveTab.value = 'basic';
+  currentSupplierId.value = null;
+  contractRecordList.value = [];
+
   userListNoPage().then((res) => {
     userList.value = res.data;
   });
+
   if (type === "edit") {
+    currentSupplierId.value = row.id;
     getSupplier(row.id).then((res) => {
       form.value = { ...res.data };
     });
+    // 鍔犺浇鍚堝悓璁板綍鍒楄〃
+    loadContractList(row.id);
   }
   dialogFormVisible.value = true;
 };
+
+// 鍔犺浇鍚堝悓璁板綍鍒楄〃
+const loadContractList = async (supplierId) => {
+  try {
+    const res = await getSupplierContractList(supplierId);
+    if (res.code === 200) {
+      contractRecordList.value = res.data || [];
+    }
+  } catch (error) {
+    console.error('鑾峰彇鍚堝悓璁板綍鍒楄〃澶辫触:', error);
+  }
+};
+
+// 鏂板鍚堝悓璁板綍
+const handleAddContract = () => {
+  contractDialogTitle.value = '鏂板鍚堝悓璁板綍';
+  Object.assign(contractForm, {
+    id: null,
+    supplierId: currentSupplierId.value,
+    masterContractNo: '',
+    entryDate: '',
+    entryPerson: userStore.nickName,
+    entryPersonId: userStore.id,
+    remark: '',
+    storageBlobDTOs: []
+  });
+  contractDialogVisible.value = true;
+};
+
+// 缂栬緫鍚堝悓璁板綍
+const handleEditContract = async (row) => {
+  contractDialogTitle.value = '缂栬緫鍚堝悓璁板綍';
+  try {
+    const res = await getSupplierContractById(row.id);
+    if (res.code === 200) {
+      Object.assign(contractForm, {
+        ...res.data,
+        storageBlobDTOs: res.data.fileList ? res.data.fileList.map(f => ({ id: f.id })) : []
+      });
+      contractDialogVisible.value = true;
+    }
+  } catch (error) {
+    console.error('鑾峰彇鍚堝悓璁板綍璇︽儏澶辫触:', error);
+  }
+};
+
+// 鍒犻櫎鍚堝悓璁板綍
+const handleDeleteContract = async (row) => {
+  try {
+    await ElMessageBox.confirm('纭畾鍒犻櫎璇ュ悎鍚岃褰曞悧锛�', '鎻愮ず', { type: 'warning' });
+    const res = await delSupplierContract(row.id);
+    if (res.code === 200) {
+      proxy.$modal.msgSuccess('鍒犻櫎鎴愬姛');
+      loadContractList(currentSupplierId.value);
+    }
+  } catch (error) {
+    if (error !== 'cancel') {
+      console.error('鍒犻櫎鍚堝悓璁板綍澶辫触:', error);
+    }
+  }
+};
+
+// 鎻愪氦鍚堝悓璁板綍琛ㄥ崟
+const submitContractForm = async () => {
+  try {
+    await contractFormRef.value.validate();
+    const api = contractForm.id ? updateSupplierContract : addSupplierContract;
+    const res = await api(contractForm);
+    if (res.code === 200) {
+      proxy.$modal.msgSuccess('鎿嶄綔鎴愬姛');
+      contractDialogVisible.value = false;
+      loadContractList(currentSupplierId.value);
+    }
+  } catch (error) {
+    console.error('鎻愪氦鍚堝悓璁板綍澶辫触:', error);
+  }
+};
+
+// 鏌ョ湅鍚堝悓闄勪欢
+const handleViewContractFiles = (row) => {
+  contractFileList.value = row.fileList || [];
+  contractFileDialogVisible.value = true;
+};
+
+// 鏍煎紡鍖栨枃浠跺ぇ灏�
+const formatFileSize = (bytes) => {
+  if (!bytes) return '0 B';
+  const k = 1024;
+  const sizes = ['B', 'KB', 'MB', 'GB'];
+  const i = Math.floor(Math.log(bytes) / Math.log(k));
+  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
+};
+
 // 鎻愪氦琛ㄥ崟
 const submitForm = () => {
   proxy.$refs["formRef"].validate((valid) => {

--
Gitblit v1.9.3