|
@@ -54,27 +54,27 @@
|
54
|
54
|
删除
|
55
|
55
|
</el-button>
|
56
|
56
|
</el-col>
|
57
|
|
- <el-col :span="1.5">
|
58
|
|
- <el-dropdown class="mt-[1px]">
|
59
|
|
- <el-button plain type="info">
|
60
|
|
- 更多
|
61
|
|
- <el-icon class="el-icon--right">
|
62
|
|
- <arrow-down />
|
63
|
|
- </el-icon>
|
64
|
|
- </el-button>
|
65
|
|
- <template #dropdown>
|
66
|
|
- <el-dropdown-menu>
|
67
|
|
- <el-dropdown-item icon="Download" @click="importTemplate">下载模板</el-dropdown-item>
|
68
|
|
- <el-dropdown-item icon="Top" @click="handleImport"> 导入数据</el-dropdown-item>
|
69
|
|
- <el-dropdown-item icon="Download" @click="handleExport"> 导出数据</el-dropdown-item>
|
70
|
|
- </el-dropdown-menu>
|
71
|
|
- </template>
|
72
|
|
- </el-dropdown>
|
73
|
|
- </el-col>
|
|
57
|
+<!-- <el-col :span="1.5">-->
|
|
58
|
+<!-- <el-dropdown class="mt-[1px]">-->
|
|
59
|
+<!-- <el-button plain type="info">-->
|
|
60
|
+<!-- 更多-->
|
|
61
|
+<!-- <el-icon class="el-icon--right">-->
|
|
62
|
+<!-- <arrow-down />-->
|
|
63
|
+<!-- </el-icon>-->
|
|
64
|
+<!-- </el-button>-->
|
|
65
|
+<!-- <template #dropdown>-->
|
|
66
|
+<!-- <el-dropdown-menu>-->
|
|
67
|
+<!-- <el-dropdown-item icon="Download" @click="importTemplate">下载模板</el-dropdown-item>-->
|
|
68
|
+<!-- <el-dropdown-item icon="Top" @click="handleImport"> 导入数据</el-dropdown-item>-->
|
|
69
|
+<!-- <el-dropdown-item icon="Download" @click="handleExport"> 导出数据</el-dropdown-item>-->
|
|
70
|
+<!-- </el-dropdown-menu>-->
|
|
71
|
+<!-- </template>-->
|
|
72
|
+<!-- </el-dropdown>-->
|
|
73
|
+<!-- </el-col>-->
|
74
|
74
|
<right-toolbar v-model:showSearch="showSearch" :columns="columns" :search="true" @query-table="getList"></right-toolbar>
|
75
|
75
|
</el-row>
|
76
|
76
|
</template>
|
77
|
|
- <el-table v-loading="loading" :data="userList" height="calc(100vh - 22rem)" @selection-change="handleSelectionChange" highlight-current-row>
|
|
77
|
+ <el-table v-loading="loading" :data="userList" height="calc(100vh - 22rem)" highlight-current-row @selection-change="handleSelectionChange">
|
78
|
78
|
<el-table-column type="selection" width="50" align="center" />
|
79
|
79
|
<el-table-column
|
80
|
80
|
v-if="columns[0].visible"
|
|
@@ -103,14 +103,7 @@
|
103
|
103
|
width="160"
|
104
|
104
|
:show-overflow-tooltip="true"
|
105
|
105
|
/>
|
106
|
|
- <el-table-column
|
107
|
|
- v-if="columns[3].visible"
|
108
|
|
- key="deptName"
|
109
|
|
- label="部门"
|
110
|
|
- align="center"
|
111
|
|
- prop="deptName"
|
112
|
|
- :show-overflow-tooltip="true"
|
113
|
|
- />
|
|
106
|
+ <el-table-column v-if="columns[3].visible" key="deptName" label="部门" align="center" prop="deptName" :show-overflow-tooltip="true" />
|
114
|
107
|
<el-table-column
|
115
|
108
|
v-if="columns[4].visible"
|
116
|
109
|
key="phone"
|
|
@@ -138,10 +131,16 @@
|
138
|
131
|
<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
|
139
|
132
|
</template>
|
140
|
133
|
</el-table-column>
|
141
|
|
- <el-table-column label="操作" fixed="right" class-name="small-padding fixed-width">
|
|
134
|
+ <el-table-column label="操作" fixed="right" class-name="small-padding fixed-width">
|
142
|
135
|
<template #default="scope">
|
143
|
136
|
<el-tooltip v-if="scope.row.userId !== 1" content="修改" placement="top">
|
144
|
|
- <el-button v-hasPermi="['system:user:edit']" link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button>
|
|
137
|
+ <el-button
|
|
138
|
+ v-hasPermi="['system:user:edit']"
|
|
139
|
+ link
|
|
140
|
+ type="primary"
|
|
141
|
+ icon="Edit"
|
|
142
|
+ @click="handleOpenDetail('edit', scope.row)"
|
|
143
|
+ ></el-button>
|
145
|
144
|
</el-tooltip>
|
146
|
145
|
<el-tooltip v-if="scope.row.userId !== 1" content="删除" placement="top">
|
147
|
146
|
<el-button v-hasPermi="['system:user:remove']" link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button>
|
|
@@ -210,17 +209,16 @@
|
210
|
209
|
|
211
|
210
|
<script setup name="User" lang="ts">
|
212
|
211
|
import api from '@/api/system/right/user';
|
213
|
|
-import { UserForm, UserQuery, UserVO } from '@/api/system/right/user/types';
|
|
212
|
+import { UserQuery, UserVO } from '@/api/system/right/user/types';
|
214
|
213
|
import { DeptVO } from '@/api/system/dept/types';
|
215
|
|
-import { PostVO } from '@/api/system/params/post/types';
|
216
|
|
-import { treeselect } from '@/api/system/dept';
|
217
|
214
|
import { globalHeaders } from '@/utils/request';
|
218
|
215
|
import { to } from 'await-to-js';
|
219
|
216
|
import UserDetailForm from '@/views/system/right/user/UserDetailForm.vue';
|
|
217
|
+import { ArrowDown } from '@element-plus/icons-vue';
|
220
|
218
|
|
221
|
219
|
const router = useRouter();
|
222
|
220
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
223
|
|
-const { sys_normal_disable, sys_user_sex,CATEGORY } = toRefs<any>(proxy?.useDict('sys_normal_disable', 'sys_user_sex','CATEGORY'));
|
|
221
|
+const { CATEGORY } = toRefs<any>(proxy?.useDict('CATEGORY'));
|
224
|
222
|
const userList = ref<UserVO[]>();
|
225
|
223
|
const loading = ref(true);
|
226
|
224
|
const showSearch = ref(true);
|
|
@@ -232,7 +230,6 @@ const dateRange = ref<[DateModelType, DateModelType]>(['', '']);
|
232
|
230
|
const deptName = ref('');
|
233
|
231
|
const deptOptions = ref<DeptVO[]>([]);
|
234
|
232
|
const initPassword = ref<string>('');
|
235
|
|
-const postOptions = ref<PostVO[]>([]);
|
236
|
233
|
|
237
|
234
|
/*** 用户导入参数 */
|
238
|
235
|
const upload = reactive<ImportOption>({
|
|
@@ -259,87 +256,19 @@ const columns = ref<FieldOption[]>([
|
259
|
256
|
{ key: 5, label: `状态`, visible: true, children: [] },
|
260
|
257
|
{ key: 6, label: `创建时间`, visible: true, children: [] }
|
261
|
258
|
]);
|
|
259
|
+const queryParams = reactive<UserQuery>({
|
|
260
|
+ pageNum: 1,
|
|
261
|
+ pageSize: 10,
|
|
262
|
+ userName: '',
|
|
263
|
+ phone: '',
|
|
264
|
+ status: '',
|
|
265
|
+ deptId: '',
|
|
266
|
+ roleId: ''
|
|
267
|
+});
|
262
|
268
|
const deptTreeRef = ref<ElTreeInstance>();
|
263
|
269
|
// 查询客体ref
|
264
|
270
|
const queryFormRef = ref<ElFormInstance>();
|
265
|
|
-const userFormRef = ref<ElFormInstance>();
|
266
|
271
|
const uploadRef = ref<ElUploadInstance>();
|
267
|
|
-const formDialogRef = ref<ElDialogInstance>();
|
268
|
|
-
|
269
|
|
-const dialog = reactive<DialogOption>({
|
270
|
|
- visible: false,
|
271
|
|
- title: ''
|
272
|
|
-});
|
273
|
|
-
|
274
|
|
-const initFormData: UserForm = {
|
275
|
|
- userId: undefined,
|
276
|
|
- deptId: undefined,
|
277
|
|
- userName: '',
|
278
|
|
- nickName: undefined,
|
279
|
|
- password: '',
|
280
|
|
- phonenumber: undefined,
|
281
|
|
- email: undefined,
|
282
|
|
- sex: undefined,
|
283
|
|
- status: '0',
|
284
|
|
- remark: '',
|
285
|
|
- postIds: [],
|
286
|
|
- roleIds: []
|
287
|
|
-};
|
288
|
|
-
|
289
|
|
-const initData: PageData<UserForm, UserQuery> = {
|
290
|
|
- form: { ...initFormData },
|
291
|
|
- queryParams: {
|
292
|
|
- pageNum: 1,
|
293
|
|
- pageSize: 10,
|
294
|
|
- userName: '',
|
295
|
|
- realName: '',
|
296
|
|
- phone: '',
|
297
|
|
- status: '',
|
298
|
|
- deptId: '',
|
299
|
|
- roleId: ''
|
300
|
|
- },
|
301
|
|
- rules: {
|
302
|
|
- userName: [
|
303
|
|
- { required: true, message: '用户名称不能为空', trigger: 'blur' },
|
304
|
|
- {
|
305
|
|
- min: 2,
|
306
|
|
- max: 20,
|
307
|
|
- message: '用户名称长度必须介于 2 和 20 之间',
|
308
|
|
- trigger: 'blur'
|
309
|
|
- }
|
310
|
|
- ],
|
311
|
|
- nickName: [{ required: true, message: '用户昵称不能为空', trigger: 'blur' }],
|
312
|
|
- password: [
|
313
|
|
- { required: true, message: '用户密码不能为空', trigger: 'blur' },
|
314
|
|
- {
|
315
|
|
- min: 5,
|
316
|
|
- max: 20,
|
317
|
|
- message: '用户密码长度必须介于 5 和 20 之间',
|
318
|
|
- trigger: 'blur'
|
319
|
|
- },
|
320
|
|
- { pattern: /^[^<>"'|\\]+$/, message: '不能包含非法字符:< > " \' \\\ |', trigger: 'blur' }
|
321
|
|
- ],
|
322
|
|
- email: [
|
323
|
|
- {
|
324
|
|
- type: 'email',
|
325
|
|
- message: '请输入正确的邮箱地址',
|
326
|
|
- trigger: ['blur', 'change']
|
327
|
|
- }
|
328
|
|
- ],
|
329
|
|
- phonenumber: [
|
330
|
|
- {
|
331
|
|
- pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
|
332
|
|
- message: '请输入正确的手机号码',
|
333
|
|
- trigger: 'blur'
|
334
|
|
- }
|
335
|
|
- ],
|
336
|
|
- roleIds: [{ required: true, message: '用户角色不能为空', trigger: 'blur' }]
|
337
|
|
- }
|
338
|
|
-};
|
339
|
|
-const data = reactive<PageData<UserForm, UserQuery>>(initData);
|
340
|
|
-
|
341
|
|
-const { queryParams, form, rules } = toRefs<PageData<UserForm, UserQuery>>(data);
|
342
|
|
-
|
343
|
272
|
/** 通过条件过滤节点 */
|
344
|
273
|
const filterNode = (value: string, data: any) => {
|
345
|
274
|
if (!value) return true;
|
|
@@ -364,7 +293,7 @@ const getTreeSelect = async () => {
|
364
|
293
|
/** 查询用户列表 */
|
365
|
294
|
const getList = async () => {
|
366
|
295
|
loading.value = true;
|
367
|
|
- const res = await api.listUser(proxy?.addDateRange(queryParams.value, dateRange.value));
|
|
296
|
+ const res = await api.listUser(proxy?.addDateRange(queryParams, dateRange.value));
|
368
|
297
|
loading.value = false;
|
369
|
298
|
userList.value = res.rows;
|
370
|
299
|
total.value = res.total;
|
|
@@ -372,21 +301,21 @@ const getList = async () => {
|
372
|
301
|
|
373
|
302
|
/** 节点单击事件 */
|
374
|
303
|
const handleNodeClick = (data: DeptVO) => {
|
375
|
|
- queryParams.value.deptId = data.id;
|
|
304
|
+ queryParams.deptId = data.id;
|
376
|
305
|
handleQuery();
|
377
|
306
|
};
|
378
|
307
|
|
379
|
308
|
/** 搜索按钮操作 */
|
380
|
309
|
const handleQuery = () => {
|
381
|
|
- queryParams.value.pageNum = 1;
|
|
310
|
+ queryParams.pageNum = 1;
|
382
|
311
|
getList();
|
383
|
312
|
};
|
384
|
313
|
/** 重置按钮操作 */
|
385
|
314
|
const resetQuery = () => {
|
386
|
315
|
dateRange.value = ['', ''];
|
387
|
316
|
queryFormRef.value?.resetFields();
|
388
|
|
- queryParams.value.pageNum = 1;
|
389
|
|
- queryParams.value.deptId = undefined;
|
|
317
|
+ queryParams.pageNum = 1;
|
|
318
|
+ queryParams.deptId = undefined;
|
390
|
319
|
deptTreeRef.value?.setCurrentKey(undefined);
|
391
|
320
|
handleQuery();
|
392
|
321
|
};
|
|
@@ -394,14 +323,11 @@ const resetQuery = () => {
|
394
|
323
|
/** 删除按钮操作 */
|
395
|
324
|
const handleDelete = async (row?: UserVO) => {
|
396
|
325
|
const userIds = row?.userId || ids.value;
|
397
|
|
- const [err] = await to(proxy?.$modal.confirm('是否确认删除用户编号为"' + userIds + '"的数据项?') as any);
|
398
|
|
- if (!err) {
|
399
|
|
- await api.delUser(userIds);
|
400
|
|
- await getList();
|
401
|
|
- proxy?.$modal.msgSuccess('删除成功');
|
402
|
|
- }
|
|
326
|
+ await proxy?.$modal.confirm('是否确认删除用户编号为"' + userIds + '"的数据项?');
|
|
327
|
+ await api.delUser(userIds);
|
|
328
|
+ await getList();
|
|
329
|
+ proxy?.$modal.msgSuccess('删除成功');
|
403
|
330
|
};
|
404
|
|
-
|
405
|
331
|
/** 用户状态修改 */
|
406
|
332
|
const handleStatusChange = async (row: UserVO) => {
|
407
|
333
|
let text = row.status === '0' ? '启用' : '停用';
|
|
@@ -429,7 +355,7 @@ const handleResetPwd = async (row: UserVO) => {
|
429
|
355
|
inputPattern: /^.{5,20}$/,
|
430
|
356
|
inputErrorMessage: '用户密码长度必须介于 5 和 20 之间',
|
431
|
357
|
inputValidator: (value) => {
|
432
|
|
- if (/<|>|"|'|\||\\/.test(value)) {
|
|
358
|
+ if (/[<>"'|\\]/.test(value)) {
|
433
|
359
|
return '不能包含非法字符:< > " \' \\\ |';
|
434
|
360
|
}
|
435
|
361
|
}
|
|
@@ -458,7 +384,7 @@ const handleExport = () => {
|
458
|
384
|
proxy?.download(
|
459
|
385
|
'system/user/export',
|
460
|
386
|
{
|
461
|
|
- ...queryParams.value
|
|
387
|
+ ...queryParams
|
462
|
388
|
},
|
463
|
389
|
`user_${new Date().getTime()}.xlsx`
|
464
|
390
|
);
|
|
@@ -488,26 +414,6 @@ function submitFileForm() {
|
488
|
414
|
uploadRef.value?.submit();
|
489
|
415
|
}
|
490
|
416
|
|
491
|
|
-/** 初始化部门数据 */
|
492
|
|
-const initTreeData = async () => {
|
493
|
|
- // 判断部门的数据是否存在,存在不获取,不存在则获取
|
494
|
|
- if (deptOptions.value === undefined) {
|
495
|
|
- const { data } = await treeselect();
|
496
|
|
- deptOptions.value = data;
|
497
|
|
- }
|
498
|
|
-};
|
499
|
|
-
|
500
|
|
-/** 重置操作表单 */
|
501
|
|
-const reset = () => {
|
502
|
|
- form.value = { ...initFormData };
|
503
|
|
- userFormRef.value?.resetFields();
|
504
|
|
-};
|
505
|
|
-/** 取消按钮 */
|
506
|
|
-const cancel = () => {
|
507
|
|
- dialog.visible = false;
|
508
|
|
- reset();
|
509
|
|
-};
|
510
|
|
-
|
511
|
417
|
/** 增加/修改按钮操作 */
|
512
|
418
|
const userDetailFormRef = ref();
|
513
|
419
|
const handleOpenDetail = async (cmd: string, row?: UserVO) => {
|
|
@@ -517,37 +423,6 @@ const handleOpenDetail = async (cmd: string, row?: UserVO) => {
|
517
|
423
|
}
|
518
|
424
|
userDetailFormRef?.value.open(cmd, userId);
|
519
|
425
|
};
|
520
|
|
-
|
521
|
|
-/** 提交按钮 */
|
522
|
|
-const submitForm = () => {
|
523
|
|
- userFormRef.value?.validate(async (valid: boolean) => {
|
524
|
|
- if (valid) {
|
525
|
|
- form.value.userId ? await api.updateUser(form.value) : await api.addUser(form.value);
|
526
|
|
- proxy?.$modal.msgSuccess('操作成功');
|
527
|
|
- dialog.visible = false;
|
528
|
|
- await getList();
|
529
|
|
- }
|
530
|
|
- });
|
531
|
|
-};
|
532
|
|
-
|
533
|
|
-/**
|
534
|
|
- * 关闭用户弹窗
|
535
|
|
- */
|
536
|
|
-const closeDialog = () => {
|
537
|
|
- dialog.visible = false;
|
538
|
|
- resetForm();
|
539
|
|
-};
|
540
|
|
-
|
541
|
|
-/**
|
542
|
|
- * 重置表单
|
543
|
|
- */
|
544
|
|
-const resetForm = () => {
|
545
|
|
- userFormRef.value?.resetFields();
|
546
|
|
- userFormRef.value?.clearValidate();
|
547
|
|
-
|
548
|
|
- form.value.id = undefined;
|
549
|
|
- form.value.status = '1';
|
550
|
|
-};
|
551
|
426
|
onMounted(() => {
|
552
|
427
|
getTreeSelect(); // 初始化部门数据
|
553
|
428
|
getList(); // 初始化列表数据
|
|
@@ -555,12 +430,6 @@ onMounted(() => {
|
555
|
430
|
initPassword.value = response.data;
|
556
|
431
|
});
|
557
|
432
|
});
|
558
|
|
-
|
559
|
|
-async function handleDeptChange(value: number | string) {
|
560
|
|
- const response = await optionselect(value);
|
561
|
|
- postOptions.value = response.data;
|
562
|
|
- form.value.postIds = [];
|
563
|
|
-}
|
564
|
433
|
</script>
|
565
|
434
|
|
566
|
435
|
<style lang="scss" scoped>
|