Browse Source

Merge remote-tracking branch 'origin/master'

luoyb 1 month ago
parent
commit
edd68d3495
2 changed files with 151 additions and 19 deletions
  1. 14 1
      src/api/payment/account/index.ts
  2. 137 18
      src/views/payment/account/facePhoto.vue

+ 14 - 1
src/api/payment/account/index.ts

@@ -169,6 +169,18 @@ export const closeAccount = (userId: string | number | Array<string | number>) =
169 169
     method: 'put'
170 170
   });
171 171
 };
172
+
173
+export const photoBatchUpload = (data) => {
174
+  return request({
175
+    url: '/backstage/payment/ptUserAccount/photoBatchUpload',
176
+    method: 'post',
177
+    data: data,
178
+    headers: {
179
+      'Content-Type': 'multipart/form-data'
180
+    }
181
+  });
182
+};
183
+
172 184
 export default {
173 185
   listPtUserAccount,
174 186
   listPtUserAccount4Select,
@@ -184,5 +196,6 @@ export default {
184 196
   resetCardType,
185 197
   resetConsumePwd,
186 198
   openAccount,
187
-  closeAccount
199
+  closeAccount,
200
+  photoBatchUpload
188 201
 };

+ 137 - 18
src/views/payment/account/facePhoto.vue

@@ -57,9 +57,11 @@
57 57
                 :before-upload="beforeAvatarUpload"
58 58
                 :on-success="handleAvatarSuccess"
59 59
                 :headers="headers"
60
+                accept=".jpg,.jpeg,.png"
61
+                :limit="1"
60 62
               >
61
-                <el-image v-if="user.photo" :src="baseUrl + '/backstage/upload/' + user.photo" />
62
-                <el-icon v-else><Plus /></el-icon>
63
+                <el-image v-if="user.photo" :src="baseUrl + '/backstage/upload/' + user.photo" fit="fill" class="imageClass" />
64
+                <el-icon v-else class="avatar-uploader-icon-2"><Plus /></el-icon>
63 65
               </el-upload>
64 66
             </div>
65 67
           </div>
@@ -69,21 +71,29 @@
69 71
     </el-row>
70 72
 
71 73
     <!--批量上传照片弹窗-->
72
-    <el-dialog v-model="dialogVisible" title="批量上传人员照片" width="500">
74
+    <el-dialog v-model="dialogVisible" title="批量上传人员照片" width="30%" @close="handleClickClose">
73 75
       <el-upload
76
+        ref="upload"
74 77
         :headers="headers"
75
-        :action="`${baseUrl}/backstage/payment/ptUserAccount/photoBatchUpload`"
76 78
         :show-file-list="true"
77
-        :before-upload="beforeAvatarUpload"
78
-        :on-success="handleAvatarSuccess"
79
+        :auto-upload="false"
80
+        accept=".jpg,.png,.jpeg"
79 81
         multiple
80 82
         :limit="20"
83
+        :on-change="onChange"
84
+        :before-remove="beforeRemove"
85
+        :file-list="fileList"
86
+        action="#"
87
+        class="flex w-full h-full items-center justify-center overflow-auto"
81 88
       >
82
-        选择照片
89
+        <el-icon class="avatar-uploader-icon">
90
+          <Plus />
91
+        </el-icon>
83 92
       </el-upload>
84
-      <template #footer>
85
-        <span style="color: crimson">*照片名称必须是身份证号</span>
86
-      </template>
93
+      <div class="flex justify-between mt-5">
94
+        <div class="mt-3 mb-3 font-20" style="color: crimson">*照片名称必须是身份证号</div>
95
+        <el-button type="primary" @click="uploadBatch">确定</el-button>
96
+      </div>
87 97
     </el-dialog>
88 98
   </div>
89 99
 </template>
@@ -107,10 +117,13 @@ const total = ref(0);
107 117
 const dateRange = ref<[DateModelType, DateModelType]>(['', '']);
108 118
 const deptName = ref('');
109 119
 const deptOptions = ref<DeptVO[]>([]);
120
+const fileList = ref<UploadFile[]>([]);
110 121
 
111 122
 const deptTreeRef = ref<ElTreeInstance>();
112 123
 const queryFormRef = ref<ElFormInstance>();
113 124
 
125
+const upload = ref();
126
+
114 127
 const expandKeys = ref([]);
115 128
 const dialogVisible = ref(false);
116 129
 const initFormData: PtUserAccountForm = {
@@ -205,7 +218,7 @@ onMounted(async () => {
205 218
   expandKeys.value = [first.id as number];
206 219
 });
207 220
 
208
-import type { UploadProps } from 'element-plus';
221
+import type { UploadFiles, UploadProps } from 'element-plus';
209 222
 import { globalHeaders } from '@/utils/request';
210 223
 
211 224
 const baseUrl = import.meta.env.VITE_APP_BASE_API;
@@ -222,14 +235,87 @@ const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
222 235
   return true;
223 236
 };
224 237
 
238
+const ACCEPTED_EXTENSIONS = ['png', 'jpg', 'jpeg'];
239
+
240
+/**
241
+ * 请求前判断文件是否符合要求
242
+ * 如果符合则添加到上传队列
243
+ */
244
+function beforeUpload(file) {
245
+  console.log('beforeUpload', file);
246
+  const extension = file.name.split('.').pop().toLowerCase();
247
+  if (!ACCEPTED_EXTENSIONS.includes(extension)) {
248
+    ElMessage({
249
+      type: 'error',
250
+      message: '仅支持 png, jpg 和 jpeg 格式的文件'
251
+    });
252
+    return false;
253
+  }
254
+  if (file.size / 1024 / 1024 > 2) {
255
+    ElMessage.error('上传图片大小不能超过 2MB!');
256
+    return false;
257
+  }
258
+  return true;
259
+}
260
+
261
+/**
262
+ * 文件选择改变时触发
263
+ */
264
+function onChange(file, fileListVal) {
265
+  fileList.value = fileListVal;
266
+}
267
+
268
+function beforeRemove(file: UploadFile, fileListVal: UploadFiles) {
269
+  fileList.value = fileListVal;
270
+  return true;
271
+}
272
+
273
+// 清空附件列表
274
+const clearAttachments = () => {
275
+  if (upload.value) {
276
+    upload.value.clearFiles(); // 调用实例方法 `clearFiles` 清空附件列表
277
+    console.log('已清空附件列表');
278
+  }
279
+};
280
+
281
+/**点击close触发 */
282
+const handleClickClose = () => {
283
+  fileList.value = [];
284
+  clearAttachments();
285
+  dialogVisible.value = false;
286
+};
287
+const uploadBatch = async () => {
288
+  if (!fileList.value.length) {
289
+    ElMessage.error('请先选择文件');
290
+    return;
291
+  }
292
+  for (let i = 0; i < fileList.value.length; i++) {
293
+    console.log('fileList.value[i]', fileList.value[i]);
294
+    let rs = beforeUpload(fileList.value[i]);
295
+    if (!rs) {
296
+      return;
297
+    }
298
+  }
299
+  const formData = new FormData();
300
+  console.log('fileList', fileList.value);
301
+  fileList.value.forEach((file) => {
302
+    formData.append('file', file.raw);
303
+  });
304
+  const res = await api.photoBatchUpload(formData);
305
+  ElMessage.success(res.msg);
306
+  dialogVisible.value = false;
307
+  getList();
308
+};
309
+
225 310
 const handleAvatarSuccess: UploadProps['onSuccess'] = (response, uploadFile) => {
311
+  console.log('uploadFile', uploadFile);
226 312
   getList();
227 313
 };
228 314
 </script>
229 315
 
230 316
 <style lang="scss" scoped>
231 317
 .list-image .block {
232
-  padding: 30px 0;
318
+  padding: 15px 0;
233 319
   text-align: center;
234 320
   border-right: solid 1px var(--el-border-color);
235 321
   display: inline-block;
@@ -244,28 +330,61 @@ const handleAvatarSuccess: UploadProps['onSuccess'] = (response, uploadFile) =>
244 330
   display: block;
245 331
   color: var(--el-text-color-secondary);
246 332
   font-size: 14px;
247
-  margin-bottom: 20px;
333
+  margin-bottom: 15px;
248 334
 }
249 335
 
250 336
 .avatar-uploader {
251
-  width: 60%;
252
-  height: 110px;
337
+  width: 160px;
338
+  height: 150px;
253 339
   margin-left: auto;
254 340
   margin-right: auto;
255 341
   display: flex;
256 342
   justify-content: center;
257 343
   align-items: center;
344
+  border: 1px dashed var(--el-border-color);
258 345
 }
259 346
 
260
-.avatar-uploader {
261
-  border: 1px dashed var(--el-border-color);
347
+.avatar-uploader:hover {
348
+  border: 1px dashed blue;
349
+  height: 150px;
350
+  width: 160px;
262 351
   border-radius: 6px;
263 352
   cursor: pointer;
264 353
   position: relative;
265
-  overflow: hidden;
266 354
   transition: var(--el-transition-duration-fast);
267 355
 }
268 356
 
357
+.el-icon.avatar-uploader-icon {
358
+  border: 1px dashed #8c939d;
359
+  font-size: 28px;
360
+  color: #8c939d;
361
+  width: 110px;
362
+  height: 110px;
363
+  text-align: center;
364
+  transition: var(--el-transition-duration-fast);
365
+}
366
+
367
+.el-icon.avatar-uploader-icon-2 {
368
+  padding: 2px;
369
+  font-size: 28px;
370
+  color: #8c939d;
371
+  width: 160px;
372
+  height: 150px;
373
+  text-align: center;
374
+}
375
+.imageClass {
376
+  padding: 2px;
377
+  font-size: 28px;
378
+  color: #8c939d;
379
+  width: 160px;
380
+  height: 150px;
381
+  text-align: center;
382
+}
383
+
384
+.el-icon.avatar-uploader-icon:hover {
385
+  border-color: blue;
386
+}
387
+
269 388
 .el-tree > :nth-child(n + 1) {
270 389
   display: inline-block !important;
271 390
   min-width: 100% !important;