Explorar el Código

Merge branch 'ljy'

# Conflicts:
#	src/views/supplier/aptitude/index.vue
Lijingyang hace 2 meses
padre
commit
7b63b3c5d2
Se han modificado 1 ficheros con 274 adiciones y 146 borrados
  1. 274 146
      src/views/supplier/aptitude/index.vue

+ 274 - 146
src/views/supplier/aptitude/index.vue

@@ -1,48 +1,59 @@
 <template>
   <div class="app-container">
     <!-- 资质管理列表 -->
+
     <div class="table-header">
       <span class="table-title">资质管理列表</span>
+
       <el-button type="primary" @click="handleAdd">新增</el-button>
     </div>
 
     <!-- 资质信息列表 -->
+
     <el-table v-loading="loading" :data="qualificationList" border style="width: 100%">
       <el-table-column prop="qualificationName" label="资质名称" align="center" width="120" />
+
       <el-table-column prop="qualificationLevel" label="资质级别" align="center" width="100" />
+
       <el-table-column prop="certificateNo" label="证件编号" align="center" width="120" />
+
       <el-table-column prop="issuingAuthority" label="发证机构" align="center" width="120" />
+
       <el-table-column label="资质到期日" align="center" width="150">
         <template #default="scope">
-          <span v-if="scope.row.isLongValid == 1">
-            {{ formatDate(scope.row.endDate) }} 长期有效
-          </span>
+          <span v-if="scope.row.isLongValid == 1"> {{ formatDate(scope.row.endDate) }} 长期有效 </span>
+
           <span v-else>{{ formatDate(scope.row.endDate) }}</span>
         </template>
       </el-table-column>
+
       <el-table-column label="资质文件" align="center" min-width="300">
         <template #default="scope">
           <el-button v-if="scope.row.attachmentUrl" link type="primary" @click="handleDownload(scope.row)">
             {{ scope.row.attachmentName || '下载文件' }}
           </el-button>
+
           <span v-else>-</span>
         </template>
       </el-table-column>
+
       <el-table-column label="操作" align="center" width="200" fixed="right">
         <template #default="scope">
           <el-button link type="primary" @click="handleView(scope.row)">查看</el-button>
+
           <el-button link type="primary" @click="handleEdit(scope.row)">编辑</el-button>
+
           <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button>
         </template>
       </el-table-column>
     </el-table>
 
     <!-- 空状态 -->
-    <div v-if="qualificationList.length === 0 && !loading" class="empty-state">
-      暂无资质信息
-    </div>
+
+    <div v-if="qualificationList.length === 0 && !loading" class="empty-state">暂无资质信息</div>
 
     <!-- 分页 -->
+
     <div v-if="pagination.total > pagination.pageSize" class="pagination-container">
       <el-pagination
         v-model:current-page="pagination.pageNum"
@@ -56,12 +67,8 @@
     </div>
 
     <!-- 新增/编辑对话框 -->
-    <el-dialog
-      v-model="dialogVisible"
-      :title="dialogTitle"
-      width="800px"
-      :close-on-click-modal="false"
-    >
+
+    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="800px" :close-on-click-modal="false">
       <el-form :model="formData" :rules="formRules" ref="formRef" label-width="100px">
         <el-row :gutter="20">
           <el-col :span="24">
@@ -70,7 +77,7 @@
             </el-form-item>
           </el-col>
         </el-row>
-        
+
         <el-row :gutter="20">
           <el-col :span="24">
             <el-form-item label="资质级别" prop="qualificationLevel">
@@ -78,20 +85,21 @@
             </el-form-item>
           </el-col>
         </el-row>
-        
+
         <el-row :gutter="20">
           <el-col :span="12">
             <el-form-item label="证件编号" prop="certificateNo">
               <el-input v-model="formData.certificateNo" placeholder="请输入证件编号" />
             </el-form-item>
           </el-col>
+
           <el-col :span="12">
             <el-form-item label="发证机构" prop="issuingAuthority">
               <el-input v-model="formData.issuingAuthority" placeholder="请输入发证机构" />
             </el-form-item>
           </el-col>
         </el-row>
-        
+
         <el-row :gutter="20">
           <el-col :span="24">
             <el-form-item label="资质到期日">
@@ -101,67 +109,56 @@
                     v-model="startDate"
                     type="date"
                     placeholder="开始日期"
-                    style="width: 200px;"
+                    style="width: 200px"
                     :disabled="isLongValid"
                     @change="handleStartDateChange"
                   />
-                  <span style="margin: 0 10px;">-</span>
+
+                  <span style="margin: 0 10px">-</span>
+
                   <el-date-picker
                     v-model="endDate"
                     type="date"
                     placeholder="结束日期"
-                    style="width: 200px;"
+                    style="width: 200px"
                     :disabled="isLongValid"
                     @change="handleEndDateChange"
                   />
-                  <el-checkbox v-model="isLongValid" @change="handleLongValidChange" style="margin-left: 20px;">
-                    长期有效
-                  </el-checkbox>
+
+                  <el-checkbox v-model="isLongValid" @change="handleLongValidChange" style="margin-left: 20px"> 长期有效 </el-checkbox>
                 </div>
               </div>
             </el-form-item>
           </el-col>
         </el-row>
-        
+
         <el-row :gutter="20">
           <el-col :span="24">
             <el-form-item label="上传附件">
-              <FileUpload 
-                v-model="formData.attachmentUrl"
-                :limit="1"
-                :file-size="10"
-                :file-type="['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx']"
-              />
+              <FileUpload v-model="formData.attachmentUrl" :limit="1" :file-size="10" :file-type="['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx']" />
             </el-form-item>
           </el-col>
         </el-row>
-        
+
         <el-row :gutter="20">
           <el-col :span="24">
             <el-form-item label="备注">
-              <el-input 
-                v-model="formData.remark" 
-                type="textarea" 
-                :rows="4" 
-                placeholder="请输入内容" 
-              />
+              <el-input v-model="formData.remark" type="textarea" :rows="4" placeholder="请输入内容" />
             </el-form-item>
           </el-col>
         </el-row>
       </el-form>
+
       <template #footer>
         <el-button @click="dialogVisible = false">取消</el-button>
+
         <el-button type="primary" :loading="submitLoading" @click="handleSubmit">确认</el-button>
       </template>
     </el-dialog>
 
     <!-- 查看对话框 -->
-    <el-dialog
-      v-model="viewDialogVisible"
-      title="查看资质"
-      width="800px"
-      :close-on-click-modal="false"
-    >
+
+    <el-dialog v-model="viewDialogVisible" title="查看资质" width="800px" :close-on-click-modal="false">
       <el-form :model="viewData" label-width="100px">
         <el-row :gutter="20">
           <el-col :span="24">
@@ -170,7 +167,7 @@
             </el-form-item>
           </el-col>
         </el-row>
-        
+
         <el-row :gutter="20">
           <el-col :span="24">
             <el-form-item label="资质级别">
@@ -178,51 +175,39 @@
             </el-form-item>
           </el-col>
         </el-row>
-        
+
         <el-row :gutter="20">
           <el-col :span="12">
             <el-form-item label="证件编号">
               <el-input v-model="viewData.certificateNo" readonly />
             </el-form-item>
           </el-col>
+
           <el-col :span="12">
             <el-form-item label="发证机构">
               <el-input v-model="viewData.issuingAuthority" readonly />
             </el-form-item>
           </el-col>
         </el-row>
-        
+
         <el-row :gutter="20">
           <el-col :span="24">
             <el-form-item label="资质到期日">
               <div class="date-range-container">
                 <div class="date-inputs">
-                  <el-date-picker
-                    :model-value="viewStartDate"
-                    type="date"
-                    placeholder="开始日期"
-                    style="width: 200px;"
-                    readonly
-                    disabled
-                  />
-                  <span style="margin: 0 10px;">-</span>
-                  <el-date-picker
-                    :model-value="viewEndDate"
-                    type="date"
-                    placeholder="结束日期"
-                    style="width: 200px;"
-                    readonly
-                    disabled
-                  />
-                  <el-checkbox :model-value="viewData.isLongValid == 1" disabled style="margin-left: 20px;">
-                    长期有效
-                  </el-checkbox>
+                  <el-date-picker :model-value="viewStartDate" type="date" placeholder="开始日期" style="width: 200px" readonly disabled />
+
+                  <span style="margin: 0 10px">-</span>
+
+                  <el-date-picker :model-value="viewEndDate" type="date" placeholder="结束日期" style="width: 200px" readonly disabled />
+
+                  <el-checkbox :model-value="viewData.isLongValid == 1" disabled style="margin-left: 20px"> 长期有效 </el-checkbox>
                 </div>
               </div>
             </el-form-item>
           </el-col>
         </el-row>
-        
+
         <el-row :gutter="20">
           <el-col :span="24">
             <el-form-item label="上传附件">
@@ -231,24 +216,21 @@
                   {{ viewData.attachmentName || '下载文件' }}
                 </el-button>
               </div>
+
               <span v-else>暂无文件</span>
             </el-form-item>
           </el-col>
         </el-row>
-        
+
         <el-row :gutter="20">
           <el-col :span="24">
             <el-form-item label="备注">
-              <el-input 
-                v-model="viewData.remark" 
-                type="textarea" 
-                :rows="4" 
-                readonly
-              />
+              <el-input v-model="viewData.remark" type="textarea" :rows="4" readonly />
             </el-form-item>
           </el-col>
         </el-row>
       </el-form>
+
       <template #footer>
         <el-button @click="viewDialogVisible = false">关闭</el-button>
       </template>
@@ -263,7 +245,7 @@ import { ElMessage, ElMessageBox } from 'element-plus';
 import { listQualification, addQualification, updateQualification, delQualification } from '@/api/supplier/qualification';
 import type { QualificationVO, QualificationForm, QualificationQuery } from '@/api/supplier/qualification/types';
 import { listByIds } from '@/api/system/oss';
-import { getInfo, getInfoTemporary, updateInfo } from '@/api/supplier/info';
+import { getInfo, updateInfo } from '@/api/supplier/info';
 import FileUpload from '@/components/FileUpload/index.vue';
 
 defineOptions({
@@ -272,83 +254,112 @@ defineOptions({
 
 const route = useRoute();
 
-const route = useRoute();
-
 const qualificationList = ref<QualificationVO[]>([]);
+
 const loading = ref(false);
 
 // 供应商相关
+
 const supplierId = ref<string | number>('');
+
 const isEditMode = ref(false); // 是否为编辑模式
+
 const supplierInfo = ref<any>({}); // 供应商基础信息
 
 // 分页参数
+
 const pagination = ref({
   pageNum: 1,
+
   pageSize: 10,
+
   total: 0
 });
 
 // 对话框相关
+
 const dialogVisible = ref(false);
+
 const dialogTitle = ref('');
+
 const submitLoading = ref(false);
+
 const formRef = ref();
 
 // 查看对话框相关
+
 const viewDialogVisible = ref(false);
+
 const viewData = ref<QualificationVO>({} as QualificationVO);
+
 const viewStartDate = ref<Date | null>(null);
+
 const viewEndDate = ref<Date | null>(null);
 
 // 表单数据
+
 const formData = ref<QualificationForm>({
   qualificationName: '',
+
   qualificationLevel: '',
+
   certificateNo: '',
+
   issuingAuthority: '',
+
   startDate: '',
+
   endDate: '',
+
   isLongValid: 0,
+
   attachmentUrl: '',
+
   attachmentName: '',
+
   remark: ''
 });
 
 // 长期有效标志和日期
+
 const isLongValid = ref(false);
+
 const startDate = ref<Date | null>(null);
+
 const endDate = ref<Date | null>(null);
 
 // 表单验证规则
+
 const formRules = {
-  qualificationName: [
-    { required: true, message: '请输入资质名称', trigger: 'blur' }
-  ],
-  qualificationLevel: [
-    { required: true, message: '请输入资质级别', trigger: 'blur' }
-  ],
-  certificateNo: [
-    { required: true, message: '请输入证件编号', trigger: 'blur' }
-  ],
-  issuingAuthority: [
-    { required: true, message: '请输入发证机构', trigger: 'blur' }
-  ]
+  qualificationName: [{ required: true, message: '请输入资质名称', trigger: 'blur' }],
+
+  qualificationLevel: [{ required: true, message: '请输入资质级别', trigger: 'blur' }],
+
+  certificateNo: [{ required: true, message: '请输入证件编号', trigger: 'blur' }],
+
+  issuingAuthority: [{ required: true, message: '请输入发证机构', trigger: 'blur' }]
 };
 
 /** 获取资质列表 */
+
 const getQualificationList = async () => {
   try {
     loading.value = true;
+
     const res = await listQualification({
       pageNum: pagination.value.pageNum,
+
       pageSize: pagination.value.pageSize
     });
+
     qualificationList.value = res.rows || [];
+
     pagination.value.total = res.total || 0;
+
     console.log('资质列表:', qualificationList.value);
   } catch (e) {
     console.error('获取资质列表失败:', e);
+
     ElMessage.error('获取资质列表失败');
   } finally {
     loading.value = false;
@@ -356,105 +367,155 @@ const getQualificationList = async () => {
 };
 
 /** 新增 */
+
 const handleAdd = () => {
   resetForm();
+
   dialogTitle.value = '新增资质';
+
   dialogVisible.value = true;
 };
 
 /** 查看 */
+
 const handleView = (row: QualificationVO) => {
   viewData.value = { ...row };
-  
+
   // 设置查看模式的日期
+
   if (row.startDate && row.endDate) {
     const startDateStr = row.startDate.split(' ')[0]; // 去掉时分秒
+
     const endDateStr = row.endDate.split(' ')[0]; // 去掉时分秒
+
     viewStartDate.value = new Date(startDateStr);
+
     viewEndDate.value = new Date(endDateStr);
   } else {
     viewStartDate.value = null;
+
     viewEndDate.value = null;
   }
-  
+
   viewDialogVisible.value = true;
 };
 
 /** 编辑 */
+
 const handleEdit = (row: QualificationVO) => {
   resetForm();
+
   dialogTitle.value = '编辑资质';
-  
+
   // 回显数据
+
   formData.value = { ...row };
+
   isLongValid.value = row.isLongValid == 1;
-  
+
   // 回显日期,去掉时分秒
+
   if (!isLongValid.value && row.startDate && row.endDate) {
     const startDateStr = row.startDate.split(' ')[0]; // 去掉时分秒
+
     const endDateStr = row.endDate.split(' ')[0]; // 去掉时分秒
+
     startDate.value = new Date(startDateStr);
+
     endDate.value = new Date(endDateStr);
   }
-  
+
   dialogVisible.value = true;
 };
 
 /** 删除 */
+
 const handleDelete = (row: QualificationVO) => {
   ElMessageBox.confirm('确定要删除该资质信息吗?', '提示', {
     confirmButtonText: '确定',
+
     cancelButtonText: '取消',
+
     type: 'warning'
-  }).then(async () => {
-    try {
-      await delQualification(row.id);
-      ElMessage.success('删除成功');
-      getQualificationList();
-    } catch (e) {
-      console.error('删除失败:', e);
-      ElMessage.error('删除失败');
-    }
-  }).catch(() => {
-    // 取消删除
-  });
+  })
+    .then(async () => {
+      try {
+        await delQualification(row.id);
+
+        ElMessage.success('删除成功');
+
+        getQualificationList();
+      } catch (e) {
+        console.error('删除失败:', e);
+
+        ElMessage.error('删除失败');
+      }
+    })
+    .catch(() => {
+      // 取消删除
+    });
 };
 
 /** 下载附件 */
+
 const handleDownload = async (row: QualificationVO) => {
   if (!row.attachmentUrl) {
     ElMessage.warning('暂无附件可下载');
+
     return;
   }
-  
+
   try {
-    // 直接使用 attachmentUrl 进行下载
+    // 使用 fetch 获取文件并强制下载
+
+    const response = await fetch(row.attachmentUrl);
+
+    if (!response.ok) throw new Error('下载失败');
+
+    const blob = await response.blob();
+
+    const url = window.URL.createObjectURL(blob);
+
     const link = document.createElement('a');
-    link.href = row.attachmentUrl;
+
+    link.href = url;
+
     link.download = row.attachmentName || '附件';
-    link.target = '_blank';
+
     document.body.appendChild(link);
+
     link.click();
+
     document.body.removeChild(link);
+
+    window.URL.revokeObjectURL(url);
+
     ElMessage.success('开始下载');
   } catch (e) {
     console.error('下载附件失败:', e);
+
     ElMessage.error('下载失败');
   }
 };
 
 /** 长期有效改变 */
+
 const handleLongValidChange = (value: boolean) => {
   if (value) {
     startDate.value = null;
+
     endDate.value = null;
+
     formData.value.startDate = '';
+
     formData.value.endDate = '';
   }
+
   formData.value.isLongValid = value ? 1 : 0;
 };
 
 /** 开始日期改变 */
+
 const handleStartDateChange = (date: Date | null) => {
   if (date) {
     formData.value.startDate = date.toISOString().split('T')[0];
@@ -464,6 +525,7 @@ const handleStartDateChange = (date: Date | null) => {
 };
 
 /** 结束日期改变 */
+
 const handleEndDateChange = (date: Date | null) => {
   if (date) {
     formData.value.endDate = date.toISOString().split('T')[0];
@@ -473,51 +535,65 @@ const handleEndDateChange = (date: Date | null) => {
 };
 
 /** 提交 */
+
 const handleSubmit = async () => {
   try {
     await formRef.value.validate();
-    
+
     submitLoading.value = true;
-    
+
     // 如果有附件,获取文件详情(URL 和文件名)
+
     if (formData.value.attachmentUrl) {
       try {
         const res = await listByIds(formData.value.attachmentUrl);
+
         if (res.data && res.data.length > 0) {
           const file = res.data[0];
+
           formData.value.attachmentUrl = file.url; // 存储实际的 URL
+
           formData.value.attachmentName = file.originalName; // 存储文件名
         }
       } catch (e) {
         console.warn('获取文件信息失败:', e);
+
         // 如果获取文件信息失败,直接使用原始的 attachmentUrl
       }
     }
-    
+
     if (formData.value.id) {
       // 编辑
+
       await updateQualification(formData.value);
+
       ElMessage.success('更新成功');
-      
+
       // 如果是编辑模式,需要同步更新供应商主表信息
+
       if (isEditMode.value && supplierId.value) {
         await syncSupplierInfo();
       }
     } else {
       // 新增
+
       await addQualification(formData.value);
+
       ElMessage.success('新增成功');
-      
+
       // 如果是编辑模式,需要同步更新供应商主表信息
+
       if (isEditMode.value && supplierId.value) {
         await syncSupplierInfo();
       }
     }
-    
+
     dialogVisible.value = false;
+
     getQualificationList();
   } catch (e) {
     console.error('提交失败:', e);
+
     ElMessage.error('提交失败');
   } finally {
     submitLoading.value = false;
@@ -525,119 +601,149 @@ const handleSubmit = async () => {
 };
 
 /** 同步更新供应商主表信息(编辑模式下) */
+
 const syncSupplierInfo = async () => {
   if (!isEditMode.value || !supplierId.value) {
     return;
   }
-  
+
   try {
-    // 先查询临时表
-    const tempRes = await getInfoTemporary(supplierId.value);
-    let submitData: any;
-    
-    if (tempRes.data) {
-      // 临时表已有记录,使用临时表数据作为基础
-      const tempData = tempRes.data;
-      submitData = {
-        ...tempData,  // 临时表中的数据(保留之前的所有修改)
-        ...supplierInfo.value,  // 当前供应商基础信息
-        supplierType: String(supplierInfo.value.supplierType || tempData.supplierType),
-        cooperateLevel: String(supplierInfo.value.cooperateLevel || tempData.cooperateLevel),
-        supplyStatus: "4"
-      };
-    } else {
-      // 临时表没有记录,使用当前数据
-      submitData = {
-        ...supplierInfo.value,
-        supplierType: String(supplierInfo.value.supplierType),
-        cooperateLevel: String(supplierInfo.value.cooperateLevel),
-        supplyStatus: "4"
-      };
-    }
-    
+    // 使用当前供应商信息
+
+    const submitData = {
+      ...supplierInfo.value,
+
+      supplierType: String(supplierInfo.value.supplierType),
+
+      cooperateLevel: String(supplierInfo.value.cooperateLevel),
+
+      supplyStatus: '4'
+    };
+
     // 删除后端返回的展示字段
+
     delete submitData.supplierTypeName;
+
     delete submitData.cooperateLevelName;
+
     delete submitData.membershipSizeName;
+
     delete submitData.industrCategoryName;
+
     delete submitData.productManager;
+
     delete submitData.buyer;
+
     delete submitData.brandName;
+
     delete submitData.province;
+
     delete submitData.city;
-    
+
     // 更新主表信息
+
     await updateInfo(submitData);
+
     console.log('供应商主表信息已同步更新');
   } catch (e) {
     console.error('同步供应商主表信息失败:', e);
+
     // 不抛出错误,避免影响资质保存成功的提示
   }
 };
 
 /** 重置表单 */
+
 const resetForm = () => {
   formData.value = {
     qualificationName: '',
+
     qualificationLevel: '',
+
     certificateNo: '',
+
     issuingAuthority: '',
+
     startDate: '',
+
     endDate: '',
+
     isLongValid: 0,
+
     attachmentUrl: '',
+
     attachmentName: '',
+
     remark: ''
   };
+
   isLongValid.value = false;
+
   startDate.value = null;
+
   endDate.value = null;
+
   formRef.value?.clearValidate();
 };
 
 /** 分页大小改变 */
+
 const handleSizeChange = (size: number) => {
   pagination.value.pageSize = size;
+
   getQualificationList();
 };
 
 /** 当前页改变 */
+
 const handleCurrentChange = (page: number) => {
   pagination.value.pageNum = page;
+
   getQualificationList();
 };
 
 /** 格式化日期 */
+
 const formatDate = (dateStr: string) => {
-  if (!dateStr) return '-';
+  if (!dateStr) return '';
+
   // 去掉时分秒,只保留日期部分
+
   return dateStr.split(' ')[0];
 };
 
 onMounted(() => {
   // 从路由参数获取供应商ID和模式
+
   const id = route.query.id as string;
+
   const mode = route.query.mode as string;
-  
+
   if (id) {
     supplierId.value = id;
+
     // 判断是否为编辑模式
+
     isEditMode.value = mode === 'edit';
-    
+
     // 获取供应商基础信息
+
     getSupplierInfo();
   }
-  
+
   getQualificationList();
 });
 
 /** 获取供应商基础信息 */
+
 const getSupplierInfo = async () => {
   if (!supplierId.value) return;
-  
+
   try {
     const res = await getInfo(supplierId.value);
+
     supplierInfo.value = res.data;
+
     console.log('供应商基础信息:', supplierInfo.value);
   } catch (e) {
     console.error('获取供应商基础信息失败:', e);
@@ -648,23 +754,33 @@ const getSupplierInfo = async () => {
 <style scoped>
 .app-container {
   padding: 20px;
+
   background: #f0f2f5;
+
   min-height: calc(100vh - 84px);
 }
 
 .table-header {
   display: flex;
+
   justify-content: space-between;
+
   align-items: center;
+
   background: #fff;
+
   padding: 16px 20px;
+
   margin-bottom: 0;
+
   border-radius: 4px 4px 0 0;
 }
 
 .table-title {
   font-size: 16px;
+
   font-weight: 500;
+
   color: #333;
 }
 
@@ -674,16 +790,23 @@ const getSupplierInfo = async () => {
 
 .empty-state {
   text-align: center;
+
   padding: 40px;
+
   color: #999;
+
   background: #fff;
 }
 
 .pagination-container {
   display: flex;
+
   justify-content: flex-end;
+
   padding: 20px;
+
   background: #fff;
+
   border-radius: 0 0 4px 4px;
 }
 
@@ -693,14 +816,19 @@ const getSupplierInfo = async () => {
 
 .date-inputs {
   display: flex;
+
   align-items: center;
 }
 
 .file-display {
   padding: 8px 12px;
+
   background: #f5f7fa;
+
   border: 1px solid #dcdfe6;
+
   border-radius: 4px;
+
   display: inline-block;
 }
-</style>
+</style>