Browse Source

feat: 新增三个台账页面及相关接口,调整用户编辑页布局

1. 新增资质汇总表、合同到期台账、月度免考核人员页面
2. 新增对应业务的API接口文件
3. 临时注释掉用户编辑页的是否参加考核字段
huoyi 1 month ago
parent
commit
f5f8d70a60

+ 53 - 0
src/api/ledgerManage/contractExpirationLedger.js

@@ -0,0 +1,53 @@
1
+import request from '@/utils/request'
2
+
3
+// 查询合同到期台账列表
4
+export function listContractExpirationLedger(query) {
5
+  return request({
6
+    url: '/ledger/contract-expiration/list',
7
+    method: 'get',
8
+    params: query
9
+  })
10
+}
11
+
12
+// 查询合同到期台账详情(合同明细)
13
+export function getContractExpirationLedger(id) {
14
+  return request({
15
+    url: `/ledger/contract-expiration/${id}`,
16
+    method: 'get'
17
+  })
18
+}
19
+
20
+// 新增合同到期台账
21
+export function addContractExpirationLedger(data) {
22
+  return request({
23
+    url: '/ledger/contract-expiration',
24
+    method: 'post',
25
+    data: data
26
+  })
27
+}
28
+
29
+// 修改合同到期台账
30
+export function updateContractExpirationLedger(data) {
31
+  return request({
32
+    url: '/ledger/contract-expiration',
33
+    method: 'put',
34
+    data: data
35
+  })
36
+}
37
+
38
+// 删除合同到期台账
39
+export function delContractExpirationLedger(ids) {
40
+  return request({
41
+    url: `/ledger/contract-expiration/${ids}`,
42
+    method: 'delete'
43
+  })
44
+}
45
+
46
+// 导出合同到期台账列表
47
+export function exportContractExpirationLedger(query) {
48
+  return request({
49
+    url: '/ledger/contract-expiration/export',
50
+    method: 'get',
51
+    params: query
52
+  })
53
+}

+ 53 - 0
src/api/ledgerManage/qualificationSummary.js

@@ -0,0 +1,53 @@
1
+import request from '@/utils/request'
2
+
3
+// 查询资质汇总列表
4
+export function listQualificationSummary(query) {
5
+  return request({
6
+    url: '/ledger/qualification-summary/list',
7
+    method: 'get',
8
+    params: query
9
+  })
10
+}
11
+
12
+// 查询资质汇总详情
13
+export function getQualificationSummary(id) {
14
+  return request({
15
+    url: `/ledger/qualification-summary/${id}`,
16
+    method: 'get'
17
+  })
18
+}
19
+
20
+// 新增资质汇总
21
+export function addQualificationSummary(data) {
22
+  return request({
23
+    url: '/ledger/qualification-summary',
24
+    method: 'post',
25
+    data: data
26
+  })
27
+}
28
+
29
+// 修改资质汇总
30
+export function updateQualificationSummary(data) {
31
+  return request({
32
+    url: '/ledger/qualification-summary',
33
+    method: 'put',
34
+    data: data
35
+  })
36
+}
37
+
38
+// 删除资质汇总
39
+export function delQualificationSummary(ids) {
40
+  return request({
41
+    url: `/ledger/qualification-summary/${ids}`,
42
+    method: 'delete'
43
+  })
44
+}
45
+
46
+// 导出资质汇总列表
47
+export function exportQualificationSummary(query) {
48
+  return request({
49
+    url: '/ledger/qualification-summary/export',
50
+    method: 'get',
51
+    params: query
52
+  })
53
+}

+ 45 - 0
src/api/performance/exemptEvaluation.js

@@ -0,0 +1,45 @@
1
+import request from '@/utils/request'
2
+
3
+// 查询免考核人员列表
4
+export function listExemptEvaluation(query) {
5
+  return request({
6
+    url: '/performance/exempt-evaluation/list',
7
+    method: 'get',
8
+    params: query
9
+  })
10
+}
11
+
12
+// 新增免考核人员
13
+export function addExemptEvaluation(data) {
14
+  return request({
15
+    url: '/performance/exempt-evaluation',
16
+    method: 'post',
17
+    data: data
18
+  })
19
+}
20
+
21
+// 修改免考核人员
22
+export function updateExemptEvaluation(data) {
23
+  return request({
24
+    url: '/performance/exempt-evaluation',
25
+    method: 'put',
26
+    data: data
27
+  })
28
+}
29
+
30
+// 删除免考核人员
31
+export function delExemptEvaluation(ids) {
32
+  return request({
33
+    url: `/performance/exempt-evaluation/${ids}`,
34
+    method: 'delete'
35
+  })
36
+}
37
+
38
+// 导入免考核人员
39
+export function importExemptEvaluation(data) {
40
+  return request({
41
+    url: '/performance/exempt-evaluation/import',
42
+    method: 'post',
43
+    data: data
44
+  })
45
+}

+ 274 - 0
src/views/ledgerManage/contractExpirationLedger/index.vue

@@ -0,0 +1,274 @@
1
+<template>
2
+  <div class="app-container">
3
+    <div class="filter-container">
4
+      <el-form :model="queryParams" ref="queryFormRef" :inline="true" class="search-form">
5
+        <el-form-item label="姓名" prop="userName">
6
+          <UserSelect v-model="queryParams.userId" placeholder="请输入姓名搜索" style="width: 200px" />
7
+        </el-form-item>
8
+
9
+        <el-form-item label="用工形式" prop="employmentType">
10
+          <el-select v-model="queryParams.employmentType" placeholder="请选择用工形式" clearable style="width: 200px">
11
+            <el-option v-for="dict in employment_type" :key="dict.value" :label="dict.label" :value="dict.value" />
12
+          </el-select>
13
+        </el-form-item>
14
+
15
+        <el-form-item label="部门" prop="deptName">
16
+          <el-input v-model="queryParams.deptName" placeholder="请输入部门" clearable style="width: 200px" />
17
+        </el-form-item>
18
+
19
+        <el-form-item label="最近合同开始时间" prop="recentContractStartTime">
20
+          <el-date-picker v-model="queryParams.recentContractStartTime" type="date" value-format="YYYY-MM-DD"
21
+            placeholder="选择日期" style="width: 200px" />
22
+        </el-form-item>
23
+
24
+        <el-form-item label="最近合同结束时间" prop="recentContractEndTime">
25
+          <el-date-picker v-model="queryParams.recentContractEndTime" type="date" value-format="YYYY-MM-DD"
26
+            placeholder="选择日期" style="width: 200px" />
27
+        </el-form-item>
28
+
29
+        <el-form-item label="合同名称" prop="contractName">
30
+          <el-input v-model="queryParams.contractName" placeholder="请输入合同名称" clearable style="width: 200px" />
31
+        </el-form-item>
32
+
33
+        <el-form-item label="开始时间" prop="contractStartTime">
34
+          <el-date-picker v-model="queryParams.contractStartTime" type="date" value-format="YYYY-MM-DD"
35
+            placeholder="选择日期" style="width: 200px" />
36
+        </el-form-item>
37
+
38
+        <el-form-item label="结束时间" prop="contractEndTime">
39
+          <el-date-picker v-model="queryParams.contractEndTime" type="date" value-format="YYYY-MM-DD"
40
+            placeholder="选择日期" style="width: 200px" />
41
+        </el-form-item>
42
+
43
+        <el-form-item>
44
+          <el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
45
+          <el-button icon="Refresh" @click="resetQuery">重置</el-button>
46
+        </el-form-item>
47
+      </el-form>
48
+    </div>
49
+
50
+    <div class="operation-container">
51
+      <el-button type="info" plain icon="Upload" @click="handleImport">导入</el-button>
52
+      <el-button type="warning" plain icon="Download" @click="handleExport">导出</el-button>
53
+    </div>
54
+
55
+    <el-table v-loading="loading" :data="list" border fit highlight-current-row style="width: 100%; margin-top: 20px;"
56
+      @expand-change="handleExpandChange">
57
+      <el-table-column type="expand">
58
+        <template #default="scope">
59
+          <div class="detail-container">
60
+            <div class="detail-title">合同明细</div>
61
+            <el-table :data="scope.row.contractDetailList || []" border fit size="small"
62
+              style="width: 100%; margin-top: 10px;">
63
+              <el-table-column label="序号" type="index" width="60" align="center" />
64
+              <el-table-column label="合同名称" prop="contractName" align="center" min-width="200"
65
+                show-overflow-tooltip />
66
+              <el-table-column label="开始时间" prop="startTime" align="center" min-width="130" />
67
+              <el-table-column label="结束时间" prop="endTime" align="center" min-width="130" />
68
+            </el-table>
69
+          </div>
70
+        </template>
71
+      </el-table-column>
72
+      <el-table-column label="序号" type="index" width="60" align="center">
73
+        <template #default="scope">
74
+          {{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}
75
+        </template>
76
+      </el-table-column>
77
+      <el-table-column label="姓名" prop="userName" align="center" min-width="100" />
78
+      <el-table-column label="用工形式" prop="employmentType" align="center" min-width="100">
79
+        <template #default="scope">
80
+          <dict-tag :options="employment_type" :value="scope.row.employmentType" />
81
+        </template>
82
+      </el-table-column>
83
+      <el-table-column label="部门" prop="deptName" align="center" min-width="150" show-overflow-tooltip />
84
+      <el-table-column label="最近合同开始时间" prop="recentContractStartTime" align="center" min-width="150" />
85
+      <el-table-column label="最近合同结束时间" prop="recentContractEndTime" align="center" min-width="150" />
86
+    </el-table>
87
+
88
+    <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
89
+      @pagination="getList" />
90
+
91
+    <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
92
+      <el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url"
93
+        :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess"
94
+        :auto-upload="false" drag>
95
+        <el-icon class="el-icon--upload">
96
+          <upload-filled />
97
+        </el-icon>
98
+        <div class="el-upload__text">
99
+          将文件拖到此处,或<em>点击上传</em>
100
+        </div>
101
+        <template #tip>
102
+          <div class="el-upload__tip text-center">
103
+            <span>仅允许导入xls、xlsx格式文件。</span>
104
+            <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline"
105
+              @click="importTemplate">下载模板</el-link>
106
+          </div>
107
+        </template>
108
+      </el-upload>
109
+      <template #footer>
110
+        <div class="dialog-footer">
111
+          <el-button type="primary" @click="submitFileForm">确 定</el-button>
112
+          <el-button @click="upload.open = false">取 消</el-button>
113
+        </div>
114
+      </template>
115
+    </el-dialog>
116
+  </div>
117
+</template>
118
+
119
+<script setup name="ContractExpirationLedger">
120
+import { ref, reactive, getCurrentInstance, onMounted } from 'vue'
121
+import { UploadFilled } from '@element-plus/icons-vue'
122
+import UserSelect from '@/components/UserSelect/index.vue'
123
+import {
124
+  listContractExpirationLedger,
125
+  exportContractExpirationLedger,
126
+  getContractExpirationLedger
127
+} from '@/api/ledgerManage/contractExpirationLedger'
128
+import { getToken } from '@/utils/auth'
129
+
130
+const { proxy } = getCurrentInstance()
131
+
132
+const { employment_type } = proxy.useDict('employment_type')
133
+
134
+const loading = ref(false)
135
+const total = ref(0)
136
+const list = ref([])
137
+const queryFormRef = ref(null)
138
+
139
+const queryParams = reactive({
140
+  pageNum: 1,
141
+  pageSize: 10,
142
+  userId: '',
143
+  employmentType: '',
144
+  deptName: '',
145
+  recentContractStartTime: '',
146
+  recentContractEndTime: '',
147
+  contractName: '',
148
+  contractStartTime: '',
149
+  contractEndTime: ''
150
+})
151
+
152
+const upload = reactive({
153
+  open: false,
154
+  title: '',
155
+  isUploading: false,
156
+  url: '',
157
+  headers: {
158
+    Authorization: 'Bearer ' + getToken()
159
+  }
160
+})
161
+
162
+const getList = async () => {
163
+  loading.value = true
164
+  try {
165
+    const res = await listContractExpirationLedger(queryParams)
166
+    list.value = res.rows || []
167
+    total.value = res.total || 0
168
+  } finally {
169
+    loading.value = false
170
+  }
171
+}
172
+
173
+const handleQuery = () => {
174
+  queryParams.pageNum = 1
175
+  getList()
176
+}
177
+
178
+const resetQuery = () => {
179
+  queryFormRef.value.resetFields()
180
+  queryParams.userId = ''
181
+  queryParams.employmentType = ''
182
+  queryParams.deptName = ''
183
+  queryParams.recentContractStartTime = ''
184
+  queryParams.recentContractEndTime = ''
185
+  queryParams.contractName = ''
186
+  queryParams.contractStartTime = ''
187
+  queryParams.contractEndTime = ''
188
+  handleQuery()
189
+}
190
+
191
+const handleExpandChange = async (row, expandedRows) => {
192
+  if (expandedRows.includes(row) && (!row.contractDetailList || row.contractDetailList.length === 0)) {
193
+    try {
194
+      const res = await getContractExpirationLedger(row.id)
195
+      row.contractDetailList = res.data?.contractDetailList || res.data || []
196
+    } catch (error) {
197
+      row.contractDetailList = []
198
+    }
199
+  }
200
+}
201
+
202
+const handleExport = () => {
203
+  proxy.download(
204
+    'ledger/contract-expiration/export',
205
+    queryParams,
206
+    `contract_expiration_ledger_${new Date().getTime()}.xlsx`
207
+  )
208
+}
209
+
210
+const handleImport = () => {
211
+  upload.title = '合同到期台账导入'
212
+  upload.url = import.meta.env.VITE_APP_BASE_API + '/ledger/contract-expiration/import'
213
+  upload.open = true
214
+}
215
+
216
+const importTemplate = () => {
217
+  proxy.download(
218
+    'ledger/contract-expiration/importTemplate',
219
+    {},
220
+    `contract_expiration_template_${new Date().getTime()}.xlsx`
221
+  )
222
+}
223
+
224
+const handleFileUploadProgress = () => {
225
+  upload.isUploading = true
226
+}
227
+
228
+const handleFileSuccess = (response, file) => {
229
+  upload.open = false
230
+  upload.isUploading = false
231
+  proxy.$refs.uploadRef.handleRemove(file)
232
+  proxy.$alert(
233
+    "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
234
+      response.msg +
235
+      '</div>',
236
+    '导入结果',
237
+    { dangerouslyUseHTMLString: true }
238
+  )
239
+  getList()
240
+}
241
+
242
+const submitFileForm = () => {
243
+  proxy.$refs.uploadRef.submit()
244
+}
245
+
246
+onMounted(() => {
247
+  getList()
248
+})
249
+</script>
250
+
251
+<style scoped lang="less">
252
+.app-container {
253
+  padding: 20px;
254
+}
255
+
256
+.filter-container {
257
+  margin-bottom: 10px;
258
+}
259
+
260
+.operation-container {
261
+  margin-top: 10px;
262
+}
263
+
264
+.detail-container {
265
+  padding: 10px 30px;
266
+}
267
+
268
+.detail-title {
269
+  font-size: 14px;
270
+  font-weight: bold;
271
+  color: #303133;
272
+  margin-bottom: 5px;
273
+}
274
+</style>

+ 0 - 0
src/views/ledgerManage/contractExpirationLedger/合同到期台账


+ 244 - 0
src/views/ledgerManage/qualificationSummary/index.vue

@@ -0,0 +1,244 @@
1
+<template>
2
+  <div class="app-container">
3
+    <div class="filter-container">
4
+      <el-form :model="queryParams" ref="queryFormRef" :inline="true" class="search-form">
5
+        <el-form-item label="姓名" prop="userName">
6
+          <UserSelect v-model="queryParams.userId" placeholder="请输入姓名搜索" style="width: 200px" />
7
+        </el-form-item>
8
+
9
+        <el-form-item label="证书等级" prop="certificateLevel">
10
+          <el-select v-model="queryParams.certificateLevel" placeholder="请选择证书等级" clearable style="width: 200px">
11
+            <el-option v-for="dict in certificate_level" :key="dict.value" :label="dict.label" :value="dict.value" />
12
+          </el-select>
13
+        </el-form-item>
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="结束日期" />
18
+        </el-form-item>
19
+
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="结束日期" />
23
+        </el-form-item>
24
+
25
+        <el-form-item label="状态" prop="status">
26
+          <el-select v-model="queryParams.status" placeholder="请选择状态" clearable style="width: 200px">
27
+            <el-option v-for="dict in certificate_status" :key="dict.value" :label="dict.label" :value="dict.value" />
28
+          </el-select>
29
+        </el-form-item>
30
+
31
+        <el-form-item>
32
+          <el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
33
+          <el-button icon="Refresh" @click="resetQuery">重置</el-button>
34
+        </el-form-item>
35
+      </el-form>
36
+    </div>
37
+
38
+    <div class="operation-container">
39
+      <el-button type="info" plain icon="Upload" @click="handleImport">导入</el-button>
40
+      <el-button type="warning" plain icon="Download" @click="handleExport">导出</el-button>
41
+    </div>
42
+
43
+    <el-table v-loading="loading" :data="list" border fit highlight-current-row style="width: 100%; margin-top: 20px;">
44
+      <el-table-column label="序号" type="index" width="60" align="center">
45
+        <template #default="scope">
46
+          {{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}
47
+        </template>
48
+      </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">
51
+        <template #default="scope">
52
+          <dict-tag :options="certificate_level" :value="scope.row.certificateLevel" />
53
+        </template>
54
+      </el-table-column>
55
+      <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 />
57
+      <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" />
61
+      <el-table-column label="到期日期" prop="expiryDate" align="center" min-width="120" />
62
+      <el-table-column label="状态" prop="status" align="center" min-width="90">
63
+        <template #default="scope">
64
+          <dict-tag :options="certificate_status" :value="scope.row.status" />
65
+        </template>
66
+      </el-table-column>
67
+      <el-table-column label="到期天数" prop="expiryDays" align="center" min-width="100">
68
+        <template #default="scope">
69
+          <span :style="{ color: scope.row.expiryDays <= 30 ? '#f56c6c' : scope.row.expiryDays <= 90 ? '#e6a23c' : '#67c23a' }">
70
+            {{ scope.row.expiryDays }}天
71
+          </span>
72
+        </template>
73
+      </el-table-column>
74
+    </el-table>
75
+
76
+    <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
77
+      @pagination="getList" />
78
+
79
+    <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
80
+      <el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url"
81
+        :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess"
82
+        :auto-upload="false" drag>
83
+        <el-icon class="el-icon--upload">
84
+          <upload-filled />
85
+        </el-icon>
86
+        <div class="el-upload__text">
87
+          将文件拖到此处,或<em>点击上传</em>
88
+        </div>
89
+        <template #tip>
90
+          <div class="el-upload__tip text-center">
91
+            <span>仅允许导入xls、xlsx格式文件。</span>
92
+            <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline"
93
+              @click="importTemplate">下载模板</el-link>
94
+          </div>
95
+        </template>
96
+      </el-upload>
97
+      <template #footer>
98
+        <div class="dialog-footer">
99
+          <el-button type="primary" @click="submitFileForm">确 定</el-button>
100
+          <el-button @click="upload.open = false">取 消</el-button>
101
+        </div>
102
+      </template>
103
+    </el-dialog>
104
+  </div>
105
+</template>
106
+
107
+<script setup name="QualificationSummary">
108
+import { ref, reactive, getCurrentInstance, onMounted } from 'vue'
109
+import { UploadFilled } from '@element-plus/icons-vue'
110
+import UserSelect from '@/components/UserSelect/index.vue'
111
+import { listQualificationSummary, exportQualificationSummary } from '@/api/ledgerManage/qualificationSummary'
112
+import { getToken } from '@/utils/auth'
113
+
114
+const { proxy } = getCurrentInstance()
115
+
116
+const { certificate_level, certificate_status } = proxy.useDict('certificate_level', 'certificate_status')
117
+
118
+const loading = ref(false)
119
+const total = ref(0)
120
+const list = ref([])
121
+const queryFormRef = ref(null)
122
+const issueDateRange = ref([])
123
+const expiryDateRange = ref([])
124
+
125
+const queryParams = reactive({
126
+  pageNum: 1,
127
+  pageSize: 10,
128
+  userId: '',
129
+  certificateLevel: '',
130
+  status: ''
131
+})
132
+
133
+const upload = reactive({
134
+  open: false,
135
+  title: '',
136
+  isUploading: false,
137
+  url: '',
138
+  headers: {
139
+    Authorization: 'Bearer ' + getToken()
140
+  }
141
+})
142
+
143
+const getList = async () => {
144
+  loading.value = true
145
+  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)
154
+    list.value = res.rows || []
155
+    total.value = res.total || 0
156
+  } finally {
157
+    loading.value = false
158
+  }
159
+}
160
+
161
+const handleQuery = () => {
162
+  queryParams.pageNum = 1
163
+  getList()
164
+}
165
+
166
+const resetQuery = () => {
167
+  queryFormRef.value.resetFields()
168
+  queryParams.userId = ''
169
+  queryParams.certificateLevel = ''
170
+  queryParams.status = ''
171
+  issueDateRange.value = []
172
+  expiryDateRange.value = []
173
+  handleQuery()
174
+}
175
+
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
183
+  }
184
+  proxy.download(
185
+    'ledger/qualification-summary/export',
186
+    params,
187
+    `qualification_summary_${new Date().getTime()}.xlsx`
188
+  )
189
+}
190
+
191
+const handleImport = () => {
192
+  upload.title = '资质汇总导入'
193
+  upload.url = import.meta.env.VITE_APP_BASE_API + '/ledger/qualification-summary/import'
194
+  upload.open = true
195
+}
196
+
197
+const importTemplate = () => {
198
+  proxy.download(
199
+    'ledger/qualification-summary/importTemplate',
200
+    {},
201
+    `qualification_summary_template_${new Date().getTime()}.xlsx`
202
+  )
203
+}
204
+
205
+const handleFileUploadProgress = () => {
206
+  upload.isUploading = true
207
+}
208
+
209
+const handleFileSuccess = (response, file) => {
210
+  upload.open = false
211
+  upload.isUploading = false
212
+  proxy.$refs.uploadRef.handleRemove(file)
213
+  proxy.$alert(
214
+    "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
215
+      response.msg +
216
+      '</div>',
217
+    '导入结果',
218
+    { dangerouslyUseHTMLString: true }
219
+  )
220
+  getList()
221
+}
222
+
223
+const submitFileForm = () => {
224
+  proxy.$refs.uploadRef.submit()
225
+}
226
+
227
+onMounted(() => {
228
+  getList()
229
+})
230
+</script>
231
+
232
+<style scoped lang="less">
233
+.app-container {
234
+  padding: 20px;
235
+}
236
+
237
+.filter-container {
238
+  margin-bottom: 10px;
239
+}
240
+
241
+.operation-container {
242
+  margin-top: 10px;
243
+}
244
+</style>

+ 0 - 0
src/views/ledgerManage/qualificationSummary/资质汇总表


+ 175 - 0
src/views/performanceManage/exemptEvaluation/index.vue

@@ -0,0 +1,175 @@
1
+<template>
2
+  <div class="app-container">
3
+    <div class="filter-container">
4
+      <el-form :model="queryParams" ref="queryFormRef" :inline="true" class="search-form">
5
+        <el-form-item label="考核月份" prop="assessmentMonth">
6
+          <el-date-picker v-model="queryParams.assessmentMonth" type="month" placeholder="请选择考核月份"
7
+            value-format="YYYY-MM" style="width: 200px" />
8
+        </el-form-item>
9
+
10
+        <el-form-item label="姓名" prop="userId">
11
+          <UserSelect v-model="queryParams.userId" placeholder="请输入姓名搜索" style="width: 200px" />
12
+        </el-form-item>
13
+
14
+        <el-form-item label="不参加考核原因" prop="exemptionReason">
15
+          <el-input v-model="queryParams.exemptionReason" placeholder="请输入原因" clearable style="width: 200px" />
16
+        </el-form-item>
17
+
18
+        <el-form-item>
19
+          <el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
20
+          <el-button icon="Refresh" @click="resetQuery">重置</el-button>
21
+        </el-form-item>
22
+      </el-form>
23
+    </div>
24
+
25
+    <div class="operation-container">
26
+      <el-button type="success" plain icon="Upload" @click="handleImport">导入</el-button>
27
+    </div>
28
+
29
+    <el-table v-loading="loading" :data="list" border fit highlight-current-row style="width: 100%; margin-top: 20px;">
30
+      <el-table-column label="考核月份" prop="assessmentMonth" align="center" min-width="150" />
31
+      <el-table-column label="姓名" prop="userName" align="center" min-width="120" />
32
+      <el-table-column label="不参加考核原因" prop="exemptionReason" align="center" min-width="200" show-overflow-tooltip />
33
+    </el-table>
34
+
35
+    <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
36
+      @pagination="getList" />
37
+
38
+    <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
39
+      <el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url"
40
+        :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess"
41
+        :auto-upload="false" drag>
42
+        <el-icon class="el-icon--upload">
43
+          <upload-filled />
44
+        </el-icon>
45
+        <div class="el-upload__text">
46
+          将文件拖到此处,或<em>点击上传</em>
47
+        </div>
48
+        <template #tip>
49
+          <div class="el-upload__tip text-center">
50
+            <span>仅允许导入xls、xlsx格式文件。</span>
51
+            <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline"
52
+              @click="importTemplate">下载模板</el-link>
53
+          </div>
54
+        </template>
55
+      </el-upload>
56
+      <template #footer>
57
+        <div class="dialog-footer">
58
+          <el-button type="primary" @click="submitFileForm">确 定</el-button>
59
+          <el-button @click="upload.open = false">取 消</el-button>
60
+        </div>
61
+      </template>
62
+    </el-dialog>
63
+  </div>
64
+</template>
65
+
66
+<script setup name="ExemptEvaluation">
67
+import { ref, reactive, getCurrentInstance, onMounted } from 'vue'
68
+import { UploadFilled } from '@element-plus/icons-vue'
69
+import UserSelect from '@/components/UserSelect/index.vue'
70
+import { listExemptEvaluation, delExemptEvaluation } from '@/api/performance/exemptEvaluation'
71
+import { getToken } from '@/utils/auth'
72
+
73
+const { proxy } = getCurrentInstance()
74
+
75
+const loading = ref(false)
76
+const total = ref(0)
77
+const list = ref([])
78
+const queryFormRef = ref(null)
79
+
80
+const queryParams = reactive({
81
+  pageNum: 1,
82
+  pageSize: 10,
83
+  assessmentMonth: '',
84
+  userId: '',
85
+  exemptionReason: ''
86
+})
87
+
88
+const upload = reactive({
89
+  open: false,
90
+  title: '',
91
+  isUploading: false,
92
+  url: '',
93
+  headers: {
94
+    Authorization: 'Bearer ' + getToken()
95
+  }
96
+})
97
+
98
+const getList = async () => {
99
+  loading.value = true
100
+  try {
101
+    const res = await listExemptEvaluation(queryParams)
102
+    list.value = res.rows || []
103
+    total.value = res.total || 0
104
+  } finally {
105
+    loading.value = false
106
+  }
107
+}
108
+
109
+const handleQuery = () => {
110
+  queryParams.pageNum = 1
111
+  getList()
112
+}
113
+
114
+const resetQuery = () => {
115
+  queryFormRef.value.resetFields()
116
+  queryParams.assessmentMonth = ''
117
+  queryParams.userId = ''
118
+  queryParams.exemptionReason = ''
119
+  handleQuery()
120
+}
121
+
122
+const handleImport = () => {
123
+  upload.title = '免考核人员导入'
124
+  upload.url = import.meta.env.VITE_APP_BASE_API + '/performance/exempt-evaluation/import'
125
+  upload.open = true
126
+}
127
+
128
+const importTemplate = () => {
129
+  proxy.download(
130
+    'performance/exempt-evaluation/importTemplate',
131
+    {},
132
+    `exempt_evaluation_template_${new Date().getTime()}.xlsx`
133
+  )
134
+}
135
+
136
+const handleFileUploadProgress = () => {
137
+  upload.isUploading = true
138
+}
139
+
140
+const handleFileSuccess = (response, file) => {
141
+  upload.open = false
142
+  upload.isUploading = false
143
+  proxy.$refs.uploadRef.handleRemove(file)
144
+  proxy.$alert(
145
+    "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
146
+      response.msg +
147
+      '</div>',
148
+    '导入结果',
149
+    { dangerouslyUseHTMLString: true }
150
+  )
151
+  getList()
152
+}
153
+
154
+const submitFileForm = () => {
155
+  proxy.$refs.uploadRef.submit()
156
+}
157
+
158
+onMounted(() => {
159
+  getList()
160
+})
161
+</script>
162
+
163
+<style scoped lang="less">
164
+.app-container {
165
+  padding: 20px;
166
+}
167
+
168
+.filter-container {
169
+  margin-bottom: 10px;
170
+}
171
+
172
+.operation-container {
173
+  margin-top: 10px;
174
+}
175
+</style>

+ 0 - 0
src/views/performanceManage/exemptEvaluation/月度免考核人员


+ 2 - 2
src/views/system/user/components/UserInfoEdit.vue

@@ -100,7 +100,7 @@
100 100
               </el-select>
101 101
             </el-form-item>
102 102
           </el-col>
103
-          <el-col :span="12">
103
+          <!-- <el-col :span="12">
104 104
             <el-form-item label="是否参加考核" prop="takeAssessment">
105 105
               <el-radio-group v-model="form.takeAssessment">
106 106
                 <el-radio :value="'Y'">是</el-radio>
@@ -128,7 +128,7 @@
128 128
                 </el-form-item>
129 129
               </el-col>
130 130
             </el-row>
131
-          </el-col>
131
+          </el-col> -->
132 132
           <el-col :span="12">
133 133
             <el-form-item label="岗位" prop="post">
134 134
               <el-select v-model="form.post" placeholder="请选择岗位">