|
|
@@ -1,259 +1,515 @@
|
|
|
<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-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="pagination.total > pagination.pageSize" class="pagination-container">
|
|
|
+
|
|
|
<el-pagination
|
|
|
+
|
|
|
v-model:current-page="pagination.pageNum"
|
|
|
+
|
|
|
v-model:page-size="pagination.pageSize"
|
|
|
+
|
|
|
:page-sizes="[10, 20, 50, 100]"
|
|
|
+
|
|
|
:total="pagination.total"
|
|
|
+
|
|
|
layout="total, sizes, prev, pager, next, jumper"
|
|
|
+
|
|
|
@size-change="handleSizeChange"
|
|
|
+
|
|
|
@current-change="handleCurrentChange"
|
|
|
+
|
|
|
/>
|
|
|
+
|
|
|
</div>
|
|
|
|
|
|
+
|
|
|
+
|
|
|
<!-- 新增/编辑对话框 -->
|
|
|
+
|
|
|
<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">
|
|
|
+
|
|
|
<el-form-item label="资质名称" prop="qualificationName">
|
|
|
+
|
|
|
<el-input v-model="formData.qualificationName" placeholder="请输入资质名称" />
|
|
|
+
|
|
|
</el-form-item>
|
|
|
+
|
|
|
</el-col>
|
|
|
+
|
|
|
</el-row>
|
|
|
|
|
|
+
|
|
|
+
|
|
|
<el-row :gutter="20">
|
|
|
+
|
|
|
<el-col :span="24">
|
|
|
+
|
|
|
<el-form-item label="资质级别" prop="qualificationLevel">
|
|
|
+
|
|
|
<el-input v-model="formData.qualificationLevel" placeholder="请输入资质级别" />
|
|
|
+
|
|
|
</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="资质到期日">
|
|
|
+
|
|
|
<div class="date-range-container">
|
|
|
+
|
|
|
<div class="date-inputs">
|
|
|
+
|
|
|
<el-date-picker
|
|
|
+
|
|
|
v-model="startDate"
|
|
|
+
|
|
|
type="date"
|
|
|
+
|
|
|
placeholder="开始日期"
|
|
|
+
|
|
|
style="width: 200px;"
|
|
|
+
|
|
|
:disabled="isLongValid"
|
|
|
+
|
|
|
@change="handleStartDateChange"
|
|
|
+
|
|
|
/>
|
|
|
+
|
|
|
<span style="margin: 0 10px;">-</span>
|
|
|
+
|
|
|
<el-date-picker
|
|
|
+
|
|
|
v-model="endDate"
|
|
|
+
|
|
|
type="date"
|
|
|
+
|
|
|
placeholder="结束日期"
|
|
|
+
|
|
|
style="width: 200px;"
|
|
|
+
|
|
|
:disabled="isLongValid"
|
|
|
+
|
|
|
@change="handleEndDateChange"
|
|
|
+
|
|
|
/>
|
|
|
+
|
|
|
<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
|
|
|
+
|
|
|
+ <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-form :model="viewData" label-width="100px">
|
|
|
+
|
|
|
<el-row :gutter="20">
|
|
|
+
|
|
|
<el-col :span="24">
|
|
|
+
|
|
|
<el-form-item label="资质名称">
|
|
|
+
|
|
|
<el-input v-model="viewData.qualificationName" readonly />
|
|
|
+
|
|
|
</el-form-item>
|
|
|
+
|
|
|
</el-col>
|
|
|
+
|
|
|
</el-row>
|
|
|
|
|
|
+
|
|
|
+
|
|
|
<el-row :gutter="20">
|
|
|
+
|
|
|
<el-col :span="24">
|
|
|
+
|
|
|
<el-form-item label="资质级别">
|
|
|
+
|
|
|
<el-input v-model="viewData.qualificationLevel" readonly />
|
|
|
+
|
|
|
</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>
|
|
|
+
|
|
|
</div>
|
|
|
+
|
|
|
</div>
|
|
|
+
|
|
|
</el-form-item>
|
|
|
+
|
|
|
</el-col>
|
|
|
+
|
|
|
</el-row>
|
|
|
|
|
|
+
|
|
|
+
|
|
|
<el-row :gutter="20">
|
|
|
+
|
|
|
<el-col :span="24">
|
|
|
+
|
|
|
<el-form-item label="上传附件">
|
|
|
+
|
|
|
<div v-if="viewData.attachmentUrl" class="file-display">
|
|
|
+
|
|
|
<el-button link type="primary" @click="handleDownload(viewData)">
|
|
|
+
|
|
|
{{ 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"
|
|
|
+
|
|
|
+ <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>
|
|
|
+
|
|
|
</el-dialog>
|
|
|
+
|
|
|
</div>
|
|
|
+
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
@@ -263,7 +519,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({
|
|
|
@@ -273,433 +529,843 @@ defineOptions({
|
|
|
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' }
|
|
|
+
|
|
|
]
|
|
|
+
|
|
|
};
|
|
|
|
|
|
+
|
|
|
+
|
|
|
/** 获取资质列表 */
|
|
|
+
|
|
|
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;
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
};
|
|
|
|
|
|
+
|
|
|
+
|
|
|
/** 新增 */
|
|
|
+
|
|
|
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(() => {
|
|
|
+
|
|
|
// 取消删除
|
|
|
+
|
|
|
});
|
|
|
+
|
|
|
};
|
|
|
|
|
|
+
|
|
|
+
|
|
|
/** 下载附件 */
|
|
|
+
|
|
|
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];
|
|
|
+
|
|
|
} else {
|
|
|
+
|
|
|
formData.value.startDate = '';
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
};
|
|
|
|
|
|
+
|
|
|
+
|
|
|
/** 结束日期改变 */
|
|
|
+
|
|
|
const handleEndDateChange = (date: Date | null) => {
|
|
|
+
|
|
|
if (date) {
|
|
|
+
|
|
|
formData.value.endDate = date.toISOString().split('T')[0];
|
|
|
+
|
|
|
} else {
|
|
|
+
|
|
|
formData.value.endDate = '';
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
};
|
|
|
|
|
|
+
|
|
|
+
|
|
|
/** 提交 */
|
|
|
+
|
|
|
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;
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
};
|
|
|
|
|
|
+
|
|
|
+
|
|
|
/** 同步更新供应商主表信息(编辑模式下) */
|
|
|
+
|
|
|
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);
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
};
|
|
|
+
|
|
|
</script>
|
|
|
|
|
|
+
|
|
|
+
|
|
|
<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;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
.el-table {
|
|
|
+
|
|
|
border-radius: 0 0 4px 4px;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
.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;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
.date-range-container {
|
|
|
+
|
|
|
width: 100%;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
.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>
|