Преглед на файлове

feat(用户管理): 优化用户管理界面和功能

- 添加用户查询条件:昵称和角色筛选
- 修复用户编辑表单中岗位类型和资质等级的联动逻辑
- 调整用户列表和部门树的布局样式
- 修正表单验证规则和字段标签
- 优化用户编辑时的数据初始化逻辑
huoyi преди 1 месец
родител
ревизия
e9ec762ae2
променени са 2 файла, в които са добавени 82 реда и са изтрити 16 реда
  1. 55 7
      src/views/system/user/components/UserInfoEdit.vue
  2. 27 9
      src/views/system/user/index.vue

+ 55 - 7
src/views/system/user/components/UserInfoEdit.vue

@@ -109,7 +109,7 @@
109 109
           <el-col :span="12">
110 110
             <el-form-item label="资质等级" prop="qualificationLevel"
111 111
               :rules="(form.roleIds || []).includes(101) || (form.roleIds || []).includes(102) ? [{ required: true, message: '请选择资质等级', trigger: 'blur' }] : []">
112
-              <el-select v-model="form.qualificationLevel" placeholder="请选择资质等级">
112
+              <el-select v-model="form.qualificationLevel" placeholder="请选择资质等级" @change="handleQualificationLevelChange">
113 113
                 <el-option v-for="item in sys_user_qualification_level" :key="item.value" :label="item.label"
114 114
                   :value="item.value" />
115 115
               </el-select>
@@ -118,7 +118,7 @@
118 118
           <el-col :span="12">
119 119
             <el-form-item label="岗位类型" prop="postIds"
120 120
               :rules="(form.roleIds || []).includes(101) || (form.roleIds || []).includes(102) ? [{ required: true, message: '请选择岗位类型', trigger: 'blur' }] : []">
121
-              <el-cascader v-model="form.postIds" :options="treeData" :props="treeNodeProps" filterable
121
+              <el-cascader v-model="form.postIds" :options="filteredTreeData" :props="treeNodeProps" filterable
122 122
                 style="width: 100%" />
123 123
             </el-form-item>
124 124
           </el-col>
@@ -152,7 +152,7 @@
152 152
             </el-form-item>
153 153
           </el-col>
154 154
           <el-col :span="24">
155
-            <el-form-item label="身体健康情况" prop="physicalHealthStatus">
155
+            <el-form-item label="健康异常情况" prop="physicalHealthStatus">
156 156
               <el-input v-model="form.physicalHealthStatus" type="textarea" placeholder="请输入内容"></el-input>
157 157
             </el-form-item>
158 158
           </el-col>
@@ -162,12 +162,14 @@
162 162
         <el-row :gutter="16">
163 163
           <el-col :span="12">
164 164
             <el-form-item label="开始工作时间" prop="startWorkingDate">
165
-              <el-date-picker v-model="form.startWorkingDate" type="date" placeholder="请选择开始工作时间" value-format="YYYY-MM-DD" style="width: 100%;" />
165
+              <el-date-picker v-model="form.startWorkingDate" type="date" placeholder="请选择开始工作时间"
166
+                value-format="YYYY-MM-DD" style="width: 100%;" />
166 167
             </el-form-item>
167 168
           </el-col>
168 169
           <el-col :span="12">
169 170
             <el-form-item label="开始安检工作时间" prop="securityCheckStartDate" label-width="140px">
170
-              <el-date-picker v-model="form.securityCheckStartDate" type="date" placeholder="请选择开始安检工作时间" value-format="YYYY-MM-DD" style="width: 100%;" />
171
+              <el-date-picker v-model="form.securityCheckStartDate" type="date" placeholder="请选择开始安检工作时间"
172
+                value-format="YYYY-MM-DD" style="width: 100%;" />
171 173
             </el-form-item>
172 174
           </el-col>
173 175
           <el-col :span="12">
@@ -373,7 +375,7 @@
373 375
 </template>
374 376
 
375 377
 <script setup>
376
-import { onMounted, reactive, computed } from 'vue';
378
+import { onMounted, reactive, computed, watch, nextTick, ref } from 'vue';
377 379
 import { useDict } from '@/utils/dict'
378 380
 import { listAllTree } from '@/api/system/post'
379 381
 import UserSelect from '@/components/UserSelect/index.vue'
@@ -427,7 +429,7 @@ const rules = computed(() => ({
427 429
   nickName: [{ required: true, message: "用户昵称不能为空", trigger: "blur" }],
428 430
   password: [{ required: true, message: "用户密码不能为空", trigger: "blur" }, { min: 5, max: 20, message: "用户密码长度必须介于 5 和 20 之间", trigger: "blur" }, { pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }],
429 431
   email: [{ type: "email", message: "请输入正确的邮箱地址", trigger: ["blur", "change"] }],
430
-  phonenumber: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请输入正确的手机号码", trigger: "blur" }],
432
+  phonenumber: [{ required: true, message: "手机号码不能为空", trigger: "blur" }, { pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请输入正确的手机号码", trigger: "blur" }],
431 433
   emergencyContactPhone: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请输入正确的手机号码", trigger: "blur" }],
432 434
   roleIds: [{ required: true, message: '请选择角色', trigger: "blur" }],
433 435
   status: [{ required: true, message: '请选择账号状态', trigger: "blur" }]
@@ -435,6 +437,52 @@ const rules = computed(() => ({
435 437
 
436 438
 const treeNodeProps = { multiple: true, expandTrigger: 'hover', label: 'postName', value: 'postId', emitPath: false, checkOnClickNode: true }
437 439
 const treeData = ref([])
440
+
441
+// 过滤后的岗位类型选项
442
+const filteredTreeData = computed(() => {
443
+  if (!treeData.value || treeData.value.length === 0) {
444
+    return []
445
+  }
446
+
447
+  // 如果资质等级为五级,过滤掉value为9或10的选项
448
+  // 其他级别显示完整的选项列表
449
+  if (form.value.qualificationLevel === 'LEVEL_FIVE') {
450
+    return filterTreeData(JSON.parse(JSON.stringify(treeData.value)))
451
+  }
452
+
453
+  // 其他级别返回完整的选项列表
454
+  return treeData.value
455
+})
456
+
457
+// 递归过滤树形数据
458
+const filterTreeData = (data) => {
459
+  return data.filter(item => {
460
+
461
+    // 过滤掉value为9或10的选项
462
+    if (item.postId == 9 || item.postId == 10) {
463
+
464
+      return false
465
+    }
466
+
467
+    // 如果有子节点,递归过滤
468
+    if (item.children && item.children.length > 0) {
469
+      item.children = filterTreeData(item.children)
470
+    }
471
+
472
+    return true
473
+  })
474
+}
475
+
476
+// 资质等级变化处理函数
477
+const handleQualificationLevelChange = (newVal) => {
478
+  console.log('资质等级变化', newVal)
479
+  form.value.postIds = []
480
+  // 触发验证
481
+  nextTick(() => {
482
+    userRef.value && userRef.value.validateField('postIds')
483
+  })
484
+}
485
+
438 486
 onMounted(() => {
439 487
   listAllTree().then(res => {
440 488
     treeData.value = res.data || []

+ 27 - 9
src/views/system/user/index.vue

@@ -4,12 +4,12 @@
4 4
       <splitpanes :horizontal="appStore.device === 'mobile'" class="default-theme">
5 5
         <!--部门数据-->
6 6
         <pane size="16">
7
-          <el-col>
7
+          <el-col style="height: calc(100vh - 130px); display: flex; flex-direction: column;">
8 8
             <div class="head-container">
9 9
               <el-input v-model="deptName" placeholder="请输入部门名称" clearable prefix-icon="Search"
10 10
                 style="margin-bottom: 20px" />
11 11
             </div>
12
-            <div class="head-container">
12
+            <div class="head-container" style="height: 100%; overflow-y: auto; flex: 1;">
13 13
               <el-tree :data="deptOptions" :props="{ label: 'label', children: 'children' }"
14 14
                 :expand-on-click-node="false" :filter-node-method="filterNode" ref="deptTreeRef" node-key="id"
15 15
                 highlight-current default-expand-all @node-click="handleNodeClick" />
@@ -18,12 +18,21 @@
18 18
         </pane>
19 19
         <!--用户数据-->
20 20
         <pane size="84">
21
-          <el-col>
21
+          <el-col style="height: calc(100vh - 130px); overflow-y: auto;">
22 22
             <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
23 23
               <el-form-item label="用户名称" prop="userName">
24 24
                 <el-input v-model="queryParams.userName" placeholder="请输入用户名称" clearable style="width: 240px"
25 25
                   @keyup.enter="handleQuery" />
26 26
               </el-form-item>
27
+              <el-form-item label="用户昵称" prop="nickName">
28
+                <el-input v-model="queryParams.nickName" placeholder="请输入用户名称" clearable style="width: 240px"
29
+                  @keyup.enter="handleQuery" />
30
+              </el-form-item>
31
+              <el-form-item label="角色" prop="roleName">
32
+                <el-select v-model="queryParams.roleName" placeholder="请选择角色" clearable style="width: 240px">
33
+                  <el-option v-for="role in roleOptions" :key="role.roleName" :label="role.roleName" :value="role.roleName" />
34
+                </el-select>
35
+              </el-form-item>
27 36
               <el-form-item label="手机号码" prop="phonenumber">
28 37
                 <el-input v-model="queryParams.phonenumber" placeholder="请输入手机号码" clearable style="width: 240px"
29 38
                   @keyup.enter="handleQuery" />
@@ -123,7 +132,7 @@
123 132
     </el-row>
124 133
 
125 134
     <!-- 添加或修改用户配置对话框 -->
126
-    <el-dialog :title="title" v-model="open" width="75vw" hei append-to-body destroy-on-close>
135
+    <el-dialog :title="title" v-model="open" width="75vw"  append-to-body destroy-on-close>
127 136
       <UserInfoEdit ref="userRef" v-model:form="form" :sys_user_sex="sys_user_sex"
128 137
         :enabledDeptOptions="enabledDeptOptions"
129 138
         :sys_normal_disable="sys_normal_disable" :postOptions="postOptions" :roleOptions="roleOptions" />
@@ -227,7 +236,9 @@ const data = reactive({
227 236
     userName: undefined,
228 237
     phonenumber: undefined,
229 238
     status: undefined,
230
-    deptId: undefined
239
+    deptId: undefined,
240
+    nickName: undefined,
241
+    roleName: undefined
231 242
   }
232 243
 })
233 244
 
@@ -462,15 +473,18 @@ function handleUpdate (row) {
462 473
     reset()
463 474
     form.value = {
464 475
       ...response.data,
465
-      teamCooperation:response.data.teamCooperation?response.data.teamCooperation.split(",").map(Number) : []
476
+      teamCooperation:response.data.teamCooperation?response.data.teamCooperation.split(",").map(Number) : [],
477
+      postIds: response.postIds || [],
478
+      roleIds: response.roleIds || [],
479
+      password:""
466 480
     }
467 481
     
468 482
     postOptions.value = response.posts
469 483
     roleOptions.value = response.roles
470
-    form.value.postIds = response.postIds || []
471
-    form.value.roleIds = response.roleIds || []
484
+    // form.value.postIds = response.postIds || []
485
+    // form.value.roleIds = response.roleIds || []
472 486
     title.value = "修改用户"
473
-    form.password = ""
487
+    // form.password = ""
474 488
   })
475 489
 }
476 490
 
@@ -521,6 +535,10 @@ function submitForm () {
521 535
 onMounted(() => {
522 536
   getDeptTree()
523 537
   getList()
538
+  // 获取角色选项数据
539
+  getUser().then(response => {
540
+    roleOptions.value = response.roles
541
+  })
524 542
   proxy.getConfigKey("sys.user.initPassword").then(response => {
525 543
     initPassword.value = response.msg
526 544
   })