Browse Source

refactor(ledgerManage): 重构资质汇总模块为证书信息管理模块

1. 更新所有接口路径与注释,将资质汇总相关接口改为证书信息接口
2. 调整搜索表单布局与字段,替换为证书相关查询参数
3. 重构表格列字段,适配证书信息数据结构
4. 新增增删改查完整业务逻辑与弹窗表单
5. 完善导入导出功能,新增导入模板下载接口调用
huoyi 1 month ago
parent
commit
14d7cc9902

+ 35 - 15
src/api/ledgerManage/qualificationSummary.js

@@ -1,53 +1,73 @@
1 1
 import request from '@/utils/request'
2 2
 
3
-// 查询资质汇总列表
3
+// 查询证书信息列表
4 4
 export function listQualificationSummary(query) {
5 5
   return request({
6
-    url: '/ledger/qualification-summary/list',
6
+    url: '/ledger/certificate/list',
7 7
     method: 'get',
8 8
     params: query
9 9
   })
10 10
 }
11 11
 
12
-// 查询资质汇总详情
12
+// 查询证书信息详情
13 13
 export function getQualificationSummary(id) {
14 14
   return request({
15
-    url: `/ledger/qualification-summary/${id}`,
15
+    url: `/ledger/certificate/${id}`,
16 16
     method: 'get'
17 17
   })
18 18
 }
19 19
 
20
-// 新增资质汇总
20
+// 新增证书信息
21 21
 export function addQualificationSummary(data) {
22 22
   return request({
23
-    url: '/ledger/qualification-summary',
23
+    url: '/ledger/certificate',
24 24
     method: 'post',
25 25
     data: data
26 26
   })
27 27
 }
28 28
 
29
-// 修改资质汇总
29
+// 修改证书信息
30 30
 export function updateQualificationSummary(data) {
31 31
   return request({
32
-    url: '/ledger/qualification-summary',
32
+    url: '/ledger/certificate',
33 33
     method: 'put',
34 34
     data: data
35 35
   })
36 36
 }
37 37
 
38
-// 删除资质汇总
38
+// 删除证书信息
39 39
 export function delQualificationSummary(ids) {
40 40
   return request({
41
-    url: `/ledger/qualification-summary/${ids}`,
41
+    url: `/ledger/certificate/${ids}`,
42 42
     method: 'delete'
43 43
   })
44 44
 }
45 45
 
46
-// 导出资质汇总列表
47
-export function exportQualificationSummary(query) {
46
+// 导出证书信息列表
47
+export function exportQualificationSummary(data) {
48 48
   return request({
49
-    url: '/ledger/qualification-summary/export',
50
-    method: 'get',
51
-    params: query
49
+    url: '/ledger/certificate/export',
50
+    method: 'post',
51
+    data: data
52
+  })
53
+}
54
+
55
+// 导入证书数据(支持动态复审时间列)
56
+export function importData(data) {
57
+  return request({
58
+    url: '/ledger/certificate/importData',
59
+    method: 'post',
60
+    data: data,
61
+    headers: {
62
+      'Content-Type': 'multipart/form-data'
63
+    }
64
+  })
65
+}
66
+
67
+// 下载导入模板
68
+export function importTemplate() {
69
+  return request({
70
+    url: '/ledger/certificate/importTemplate',
71
+    method: 'post'
52 72
   })
53 73
 }

+ 222 - 48
src/views/ledgerManage/qualificationSummary/index.vue

@@ -12,14 +12,12 @@
12 12
           </el-select>
13 13
         </el-form-item>
14 14
 
15
-        <el-form-item label="发证时间" prop="issueDate" style="width: 308px">
16
-          <el-date-picker v-model="issueDateRange" value-format="YYYY-MM-DD" type="daterange" range-separator="-"
17
-            start-placeholder="开始日期" end-placeholder="结束日期" />
15
+        <el-form-item label="发证时间" prop="issueDate" style="width: 200px">
16
+          <el-date-picker v-model="queryParams.issueDate" value-format="YYYY-MM-DD" type="date" placeholder="请选择发证时间" clearable />
18 17
         </el-form-item>
19 18
 
20
-        <el-form-item label="到期日期" prop="expiryDate" style="width: 308px">
21
-          <el-date-picker v-model="expiryDateRange" value-format="YYYY-MM-DD" type="daterange" range-separator="-"
22
-            start-placeholder="开始日期" end-placeholder="结束日期" />
19
+        <el-form-item label="到期日期" prop="expiryDate" style="width: 200px">
20
+          <el-date-picker v-model="queryParams.expiryDate" value-format="YYYY-MM-DD" type="date" placeholder="请选择到期日期" clearable />
23 21
         </el-form-item>
24 22
 
25 23
         <el-form-item label="状态" prop="status">
@@ -36,38 +34,44 @@
36 34
     </div>
37 35
 
38 36
     <div class="operation-container">
37
+      <el-button type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
38
+      <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate">修改</el-button>
39
+      <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete">删除</el-button>
39 40
       <el-button type="info" plain icon="Upload" @click="handleImport">导入</el-button>
40 41
       <el-button type="warning" plain icon="Download" @click="handleExport">导出</el-button>
41 42
     </div>
42 43
 
43
-    <el-table v-loading="loading" :data="list" border fit highlight-current-row style="width: 100%; margin-top: 20px;">
44
+    <el-table v-loading="loading" :data="list" border fit highlight-current-row style="width: 100%; margin-top: 20px;"
45
+      @selection-change="handleSelectionChange">
46
+      <el-table-column type="selection" width="55" align="center" />
44 47
       <el-table-column label="序号" type="index" width="60" align="center">
45 48
         <template #default="scope">
46 49
           {{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}
47 50
         </template>
48 51
       </el-table-column>
49
-      <el-table-column label="姓名" prop="userName" align="center" min-width="100" />
50
-      <el-table-column label="证书等级" prop="certificateLevel" align="center" min-width="100">
52
+      <el-table-column label="姓名" prop="personName" align="center" min-width="100" />
53
+      <el-table-column label="单位" prop="unitName" align="center" min-width="120" />
54
+      <el-table-column label="证书等级" prop="certLevel" align="center" min-width="100">
51 55
         <template #default="scope">
52
-          <dict-tag :options="certificate_level" :value="scope.row.certificateLevel" />
56
+          <dict-tag :options="certificate_level" :value="scope.row.certLevel" />
53 57
         </template>
54 58
       </el-table-column>
55 59
       <el-table-column label="发证时间" prop="issueDate" align="center" min-width="120" />
56
-      <el-table-column label="证书编号" prop="certificateNo" align="center" min-width="150" show-overflow-tooltip />
60
+      <el-table-column label="证书编号" prop="certNo" align="center" min-width="150" show-overflow-tooltip />
57 61
       <el-table-column label="理论考核成绩" prop="theoryScore" align="center" min-width="120" />
58
-      <el-table-column label="实操考核成绩" prop="practicalScore" align="center" min-width="120" />
59
-      <el-table-column label="评定成绩" prop="assessmentScore" align="center" min-width="100" />
60
-      <el-table-column label="服务期(月)" prop="servicePeriodMonths" align="center" min-width="110" />
62
+      <el-table-column label="实操考核成绩" prop="practiceScore" align="center" min-width="120" />
63
+      <el-table-column label="评定成绩" prop="evalScore" align="center" min-width="100" />
64
+      <el-table-column label="服务期(月)" prop="serviceMonths" align="center" min-width="110" />
61 65
       <el-table-column label="到期日期" prop="expiryDate" align="center" min-width="120" />
62 66
       <el-table-column label="状态" prop="status" align="center" min-width="90">
63 67
         <template #default="scope">
64 68
           <dict-tag :options="certificate_status" :value="scope.row.status" />
65 69
         </template>
66 70
       </el-table-column>
67
-      <el-table-column label="到期天数" prop="expiryDays" align="center" min-width="100">
71
+      <el-table-column label="到期天数" prop="expireDays" align="center" min-width="100">
68 72
         <template #default="scope">
69
-          <span :style="{ color: scope.row.expiryDays <= 30 ? '#f56c6c' : scope.row.expiryDays <= 90 ? '#e6a23c' : '#67c23a' }">
70
-            {{ scope.row.expiryDays }}天
73
+          <span :style="{ color: scope.row.expireDays <= 30 ? '#f56c6c' : scope.row.expireDays <= 90 ? '#e6a23c' : '#67c23a' }">
74
+            {{ scope.row.expireDays }}天
71 75
           </span>
72 76
         </template>
73 77
       </el-table-column>
@@ -76,6 +80,73 @@
76 80
     <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
77 81
       @pagination="getList" />
78 82
 
83
+    <!-- 添加或修改证书信息对话框 -->
84
+    <el-dialog :title="title" v-model="open" width="600px" append-to-body destroy-on-close>
85
+      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
86
+        <el-form-item label="姓名" prop="userId">
87
+          <UserSelect v-model="form.userId" placeholder="请选择姓名" style="width: 100%" />
88
+        </el-form-item>
89
+        <el-form-item label="单位" prop="unitName">
90
+          <el-input v-model="form.unitName" placeholder="请输入单位" />
91
+        </el-form-item>
92
+        <el-form-item label="性别" prop="gender">
93
+          <el-select v-model="form.gender" placeholder="请选择性别" clearable style="width: 100%">
94
+            <el-option label="男" value="0" />
95
+            <el-option label="女" value="1" />
96
+          </el-select>
97
+        </el-form-item>
98
+        <el-form-item label="出生日期" prop="birthDate">
99
+          <el-date-picker v-model="form.birthDate" value-format="YYYY-MM-DD" type="date" placeholder="请选择出生日期" style="width: 100%" />
100
+        </el-form-item>
101
+        <el-form-item label="身份证号" prop="idCard">
102
+          <el-input v-model="form.idCard" placeholder="请输入身份证号" />
103
+        </el-form-item>
104
+        <el-form-item label="证书等级" prop="certLevel">
105
+          <el-select v-model="form.certLevel" placeholder="请选择证书等级" clearable style="width: 100%">
106
+            <el-option v-for="dict in certificate_level" :key="dict.value" :label="dict.label" :value="dict.value" />
107
+          </el-select>
108
+        </el-form-item>
109
+        <el-form-item label="发证时间" prop="issueDate">
110
+          <el-date-picker v-model="form.issueDate" value-format="YYYY-MM-DD" type="date" placeholder="请选择发证时间" style="width: 100%" />
111
+        </el-form-item>
112
+        <el-form-item label="证书编号" prop="certNo">
113
+          <el-input v-model="form.certNo" placeholder="请输入证书编号" />
114
+        </el-form-item>
115
+        <el-form-item label="理论考核成绩" prop="theoryScore">
116
+          <el-input v-model="form.theoryScore" placeholder="请输入理论考核成绩" />
117
+        </el-form-item>
118
+        <el-form-item label="实操考核成绩" prop="practiceScore">
119
+          <el-input v-model="form.practiceScore" placeholder="请输入实操考核成绩" />
120
+        </el-form-item>
121
+        <el-form-item label="评定成绩" prop="evalScore">
122
+          <el-input v-model="form.evalScore" placeholder="请输入评定成绩" />
123
+        </el-form-item>
124
+        <el-form-item label="用工形式" prop="employmentType">
125
+          <el-input v-model="form.employmentType" placeholder="请输入用工形式" />
126
+        </el-form-item>
127
+        <el-form-item label="服务期(月)" prop="serviceMonths">
128
+          <el-input-number v-model="form.serviceMonths" :min="0" placeholder="请输入服务期(月)" style="width: 100%" />
129
+        </el-form-item>
130
+        <el-form-item label="到期日期" prop="expiryDate">
131
+          <el-date-picker v-model="form.expiryDate" value-format="YYYY-MM-DD" type="date" placeholder="请选择到期日期" style="width: 100%" />
132
+        </el-form-item>
133
+        <el-form-item label="状态" prop="status">
134
+          <el-select v-model="form.status" placeholder="请选择状态" clearable style="width: 100%">
135
+            <el-option v-for="dict in certificate_status" :key="dict.value" :label="dict.label" :value="dict.value" />
136
+          </el-select>
137
+        </el-form-item>
138
+        <el-form-item label="备注" prop="remark">
139
+          <el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
140
+        </el-form-item>
141
+      </el-form>
142
+      <template #footer>
143
+        <div class="dialog-footer">
144
+          <el-button type="primary" @click="submitForm">确 定</el-button>
145
+          <el-button @click="cancel">取 消</el-button>
146
+        </div>
147
+      </template>
148
+    </el-dialog>
149
+
79 150
     <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
80 151
       <el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url"
81 152
         :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess"
@@ -90,7 +161,7 @@
90 161
           <div class="el-upload__tip text-center">
91 162
             <span>仅允许导入xls、xlsx格式文件。</span>
92 163
             <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline"
93
-              @click="importTemplate">下载模板</el-link>
164
+              @click="downloadTemplate">下载模板</el-link>
94 165
           </div>
95 166
         </template>
96 167
       </el-upload>
@@ -108,7 +179,7 @@
108 179
 import { ref, reactive, getCurrentInstance, onMounted } from 'vue'
109 180
 import { UploadFilled } from '@element-plus/icons-vue'
110 181
 import UserSelect from '@/components/UserSelect/index.vue'
111
-import { listQualificationSummary, exportQualificationSummary } from '@/api/ledgerManage/qualificationSummary'
182
+import { listQualificationSummary, getQualificationSummary, addQualificationSummary, updateQualificationSummary, delQualificationSummary, exportQualificationSummary } from '@/api/ledgerManage/qualificationSummary'
112 183
 import { getToken } from '@/utils/auth'
113 184
 
114 185
 const { proxy } = getCurrentInstance()
@@ -119,14 +190,18 @@ const loading = ref(false)
119 190
 const total = ref(0)
120 191
 const list = ref([])
121 192
 const queryFormRef = ref(null)
122
-const issueDateRange = ref([])
123
-const expiryDateRange = ref([])
193
+const formRef = ref(null)
194
+const ids = ref([])
195
+const single = ref(true)
196
+const multiple = ref(true)
124 197
 
125 198
 const queryParams = reactive({
126 199
   pageNum: 1,
127 200
   pageSize: 10,
128 201
   userId: '',
129
-  certificateLevel: '',
202
+  certLevel: '',
203
+  issueDate: '',
204
+  expiryDate: '',
130 205
   status: ''
131 206
 })
132 207
 
@@ -140,17 +215,42 @@ const upload = reactive({
140 215
   }
141 216
 })
142 217
 
218
+const title = ref('')
219
+const open = ref(false)
220
+
221
+const form = ref({
222
+  id: undefined,
223
+  userId: '',
224
+  unitName: '',
225
+  gender: '',
226
+  birthDate: '',
227
+  idCard: '',
228
+  certLevel: '',
229
+  issueDate: '',
230
+  certNo: '',
231
+  theoryScore: '',
232
+  practiceScore: '',
233
+  evalScore: '',
234
+  employmentType: '',
235
+  serviceMonths: undefined,
236
+  expiryDate: '',
237
+  status: '',
238
+  remark: ''
239
+})
240
+
241
+const rules = reactive({
242
+  userId: [{ required: true, message: '请选择姓名', trigger: 'change' }],
243
+  certLevel: [{ required: true, message: '请选择证书等级', trigger: 'change' }],
244
+  certNo: [{ required: true, message: '请输入证书编号', trigger: 'blur' }],
245
+  issueDate: [{ required: true, message: '请选择发证时间', trigger: 'change' }],
246
+  expiryDate: [{ required: true, message: '请选择到期日期', trigger: 'change' }],
247
+  status: [{ required: true, message: '请选择状态', trigger: 'change' }]
248
+})
249
+
143 250
 const getList = async () => {
144 251
   loading.value = true
145 252
   try {
146
-    const params = {
147
-      ...queryParams,
148
-      issueStartTime: issueDateRange.value && issueDateRange.value.length > 0 ? issueDateRange.value[0] : undefined,
149
-      issueEndTime: issueDateRange.value && issueDateRange.value.length > 0 ? issueDateRange.value[1] : undefined,
150
-      expiryStartTime: expiryDateRange.value && expiryDateRange.value.length > 0 ? expiryDateRange.value[0] : undefined,
151
-      expiryEndTime: expiryDateRange.value && expiryDateRange.value.length > 0 ? expiryDateRange.value[1] : undefined
152
-    }
153
-    const res = await listQualificationSummary(params)
253
+    const res = await listQualificationSummary(queryParams)
154 254
     list.value = res.rows || []
155 255
     total.value = res.total || 0
156 256
   } finally {
@@ -166,39 +266,113 @@ const handleQuery = () => {
166 266
 const resetQuery = () => {
167 267
   queryFormRef.value.resetFields()
168 268
   queryParams.userId = ''
169
-  queryParams.certificateLevel = ''
269
+  queryParams.certLevel = ''
270
+  queryParams.issueDate = ''
271
+  queryParams.expiryDate = ''
170 272
   queryParams.status = ''
171
-  issueDateRange.value = []
172
-  expiryDateRange.value = []
173 273
   handleQuery()
174 274
 }
175 275
 
176
-const handleExport = () => {
177
-  const params = {
178
-    ...queryParams,
179
-    issueStartTime: issueDateRange.value && issueDateRange.value.length > 0 ? issueDateRange.value[0] : undefined,
180
-    issueEndTime: issueDateRange.value && issueDateRange.value.length > 0 ? issueDateRange.value[1] : undefined,
181
-    expiryStartTime: expiryDateRange.value && expiryDateRange.value.length > 0 ? expiryDateRange.value[0] : undefined,
182
-    expiryEndTime: expiryDateRange.value && expiryDateRange.value.length > 0 ? expiryDateRange.value[1] : undefined
276
+const handleSelectionChange = (selection) => {
277
+  ids.value = selection.map(item => item.id)
278
+  single.value = selection.length !== 1
279
+  multiple.value = !selection.length
280
+}
281
+
282
+const handleAdd = () => {
283
+  reset()
284
+  open.value = true
285
+  title.value = '添加证书信息'
286
+}
287
+
288
+const handleUpdate = async (row) => {
289
+  reset()
290
+  const id = row.id || ids.value[0]
291
+  const res = await getQualificationSummary(id)
292
+  form.value = res.data || {}
293
+  open.value = true
294
+  title.value = '修改证书信息'
295
+}
296
+
297
+const handleDelete = (row) => {
298
+  const deleteIds = row.id || ids.value
299
+  proxy.$modal.confirm('是否确认删除证书信息编号为"' + deleteIds + '"的数据项?').then(() => {
300
+    return delQualificationSummary(deleteIds)
301
+  }).then(() => {
302
+    getList()
303
+    proxy.$modal.msgSuccess('删除成功')
304
+  }).catch(() => { })
305
+}
306
+
307
+const submitForm = async () => {
308
+  const valid = await formRef.value.validate().catch(() => false)
309
+  if (!valid) return
310
+
311
+  loading.value = true
312
+  try {
313
+    if (form.value.id) {
314
+      await updateQualificationSummary(form.value)
315
+      proxy.$modal.msgSuccess('修改成功')
316
+    } else {
317
+      await addQualificationSummary(form.value)
318
+      proxy.$modal.msgSuccess('新增成功')
319
+    }
320
+    open.value = false
321
+    getList()
322
+  } finally {
323
+    loading.value = false
324
+  }
325
+}
326
+
327
+const cancel = () => {
328
+  open.value = false
329
+  reset()
330
+}
331
+
332
+const reset = () => {
333
+  form.value = {
334
+    id: undefined,
335
+    userId: '',
336
+    unitName: '',
337
+    gender: '',
338
+    birthDate: '',
339
+    idCard: '',
340
+    certLevel: '',
341
+    issueDate: '',
342
+    certNo: '',
343
+    theoryScore: '',
344
+    practiceScore: '',
345
+    evalScore: '',
346
+    employmentType: '',
347
+    serviceMonths: undefined,
348
+    expiryDate: '',
349
+    status: '',
350
+    remark: ''
183 351
   }
352
+  formRef.value && formRef.value.resetFields()
353
+}
354
+
355
+const handleExport = () => {
184 356
   proxy.download(
185
-    'ledger/qualification-summary/export',
186
-    params,
187
-    `qualification_summary_${new Date().getTime()}.xlsx`
357
+    'ledger/certificate/export',
358
+    queryParams,
359
+    `qualification_summary_${new Date().getTime()}.xlsx`,
360
+    'post'
188 361
   )
189 362
 }
190 363
 
191 364
 const handleImport = () => {
192
-  upload.title = '资质汇总导入'
193
-  upload.url = import.meta.env.VITE_APP_BASE_API + '/ledger/qualification-summary/import'
365
+  upload.title = '证书信息导入'
366
+  upload.url = import.meta.env.VITE_APP_BASE_API + '/ledger/certificate/importData'
194 367
   upload.open = true
195 368
 }
196 369
 
197
-const importTemplate = () => {
370
+const downloadTemplate = () => {
198 371
   proxy.download(
199
-    'ledger/qualification-summary/importTemplate',
372
+    'ledger/certificate/importTemplate',
200 373
     {},
201
-    `qualification_summary_template_${new Date().getTime()}.xlsx`
374
+    `qualification_summary_template_${new Date().getTime()}.xlsx`,
375
+    'post'
202 376
   )
203 377
 }
204 378