Forráskód Böngészése

组件优化:用户选择组件支持单选和多选模式,优化选中状态管理

刘博博 1 hete
szülő
commit
e8d47de2d9

+ 90 - 34
src/components/UserSelect/index.vue

@@ -15,7 +15,7 @@
             <div class="user-panel">
                 <div class="selected-users" v-if="selectedUsers && selectedUsers.length > 0">
                     <div class="selected-header">
-                        <span>已选中人员 ({{ selectedUsers.length }})</span>
+                        <span>{{ selectMode === 'single' ? '已选中' : '已选中人员' }} ({{ selectedUsers.length }})</span>
                     </div>
                     <div class="selected-list">
                         <el-tag v-for="(user, index) in selectedUsers" :key="user.userId" closable
@@ -25,7 +25,7 @@
                     </div>
                 </div>
 
-                <!-- 暂时注释掉搜索功能 -->
+                <!-- 搜索功能 -->
                 <!-- <div class="search-form">
                     <el-form :model="queryParams" ref="queryForm" size="small" :inline="true">
                         <el-form-item label="用户名称" prop="userName">
@@ -40,7 +40,7 @@
                     </el-form>
                 </div> -->
 
-                <!-- 暂时注释掉搜索结果展示 -->
+                <!-- 搜索结果展示 -->
                 <!-- <div class="search-results" v-if="searchText && filteredUsers.length > 0">
                     <div class="result-header">
                         <span>搜索结果 ({{ filteredUsers.length }})</span>
@@ -72,7 +72,17 @@
                 <div class="user-table" v-if="currentDepartment">
                     <el-table v-loading="userLoading" @row-click="clickRow" ref="table" :data="userList"
                         @selection-change="handleSelectionChange" style="flex: 1">
-                        <el-table-column type="selection" width="55"></el-table-column>
+                        <!-- 根据选择模式显示不同的选择列 -->
+                        <el-table-column v-if="selectMode === 'multiple'" type="selection" width="55"></el-table-column>
+                        <el-table-column v-else type="index" width="55" label="选择">
+                            <template slot-scope="scope">
+                                <el-radio 
+                                    v-model="selectedUserId" 
+                                    :label="scope.row.userId"
+                                    @change="() => handleSingleSelect(scope.row)"
+                                >&nbsp;</el-radio>
+                            </template>
+                        </el-table-column>
                         <el-table-column label="用户名称" prop="userName" :show-overflow-tooltip="true" />
                         <el-table-column label="用户昵称" prop="nickName" :show-overflow-tooltip="true" />
                         <el-table-column label="邮箱" prop="email" :show-overflow-tooltip="true" />
@@ -136,6 +146,12 @@ export default {
         extraParams: {
             type: Object,
             default: () => ({})
+        },
+        // 选择模式:single-单选,multiple-多选
+        selectMode: {
+            type: String,
+            default: 'multiple',
+            validator: (value) => ['single', 'multiple'].includes(value)
         }
     },
     data() {
@@ -161,10 +177,13 @@ export default {
             userLoading: false,
             // 内部部门数据存储
             internalDepartments: [],
-            // 搜索关键词(暂时不用)
+            // 搜索关键词
             // searchText: '',
-            // 搜索结果总数(暂时不用)
-            // searchTotal: 0
+            // 搜索结果总数
+            // searchTotal: 0,
+            // 单选模式下的选中用户ID
+            selectedUserId: null,
+            isDialogClosing: false
         };
     },
     computed: {
@@ -172,7 +191,7 @@ export default {
         departmentData() {
             return this.departments.length > 0 ? this.departments : this.internalDepartments;
         },
-        // 以下计算属性暂时注释(搜索相关
+        // 以下计算属性搜索相关
         // filteredUsers() {
         //     if (!this.searchText) return [];
 
@@ -201,6 +220,7 @@ export default {
         visible(val) {
             this.dialogVisible = val;
             if (val) {
+                this.isDialogClosing = false;
                 if (this.departmentData.length === 0) {
                     // 首次打开时加载部门数据
                     this.loadDepartmentData();
@@ -211,7 +231,7 @@ export default {
         dialogVisible(val) {
             this.$emit('update:visible', val);
         },
-        // 暂时注释掉搜索相关的监听
+        // 搜索相关的监听
         // searchText(val) {
         //     this.$nextTick(() => {
         //         if (this.$refs.tree) {
@@ -230,7 +250,7 @@ export default {
         // }
     },
     methods: {
-        // 使用真实API加载部门数据
+        // 加载部门数据
         async loadDepartmentData() {
             this.deptLoading = true;
             try {
@@ -249,45 +269,62 @@ export default {
         },
         // 只有点击叶子节点时才加载用户
         handleNodeClick(data) {
+            // 保存当前选中的用户
+            const currentSelectedUsers = [...this.selectedUsers];
+            const currentSelectedUserIds = [...this.selectedUserIds];
+            
             this.currentDepartment = data;
             this.queryParams.deptId = data.id;
             this.queryParams.pageNum = 1;
             this.queryParams.userName = undefined;
-            this.getUsers();
-
-            // 加载用户后恢复选中状态
-            this.$nextTick(() => {
-                this.restoreSelection();
+            this.getUsers().then(() => {
+                // 数据加载完成后恢复选中的用户
+                this.selectedUsers = currentSelectedUsers;
+                this.selectedUserIds = currentSelectedUserIds;
+             
+                this.$nextTick(() => {
+                    this.restoreSelection();
+                });
             });
         },
-        // 处理行点击事件,切换选中状态
+        // 处理单选模式的选择
+        handleSingleSelect(row) {
+            this.selectedUserId = row.userId;
+            this.selectedUsers = [row];
+            this.selectedUserIds = [row.userId];
+        },
+        // 切换选中状态
         clickRow(row) {
-            // 获取当前表格选中状态
+            // 单选模式处理
+            if (this.selectMode === 'single') {
+                this.handleSingleSelect(row);
+                return;
+            }
+
+            // 多选模式处理获取当前表格选中状态
             const selection = this.$refs.table.selection || [];
             const isSelected = selection.some(item => item.userId === row.userId);
 
-            // 切换选中状态
+            // 切换表格中的选中状态
             if (isSelected) {
-                // 如果已选中,从选择中移除
                 this.$refs.table.toggleRowSelection(row, false);
-                const newSelection = selection.filter(item => item.userId !== row.userId);
-                this.handleSelectionChange(newSelection);
             } else {
-                // 如果未选中,添加到选择中
                 this.$refs.table.toggleRowSelection(row, true);
-                const newSelection = [...selection, row];
-                this.handleSelectionChange(newSelection);
             }
         },
 
         handleSelectionChange(selection) {
-            // 获取当前表格中选中的用户ID
+            // 单选模式下
+            if (this.selectMode === 'single') {
+                return;
+            }
+
             const currentTableSelectedIds = selection.map(item => item.userId);
 
-            // 获取当前表格中所有用户的ID
+            // 多选模式处理
             const currentTableUserIds = this.userList.map(user => user.userId);
 
-            // 保留不在当前表格中的已选用户(来自其他部门的选择)
+            // 保留不在当前表格中的已选用户
             const otherSelectedUsers = this.selectedUsers.filter(user =>
                 !currentTableUserIds.includes(user.userId)
             );
@@ -299,9 +336,9 @@ export default {
             this.selectedUsers = [...otherSelectedUsers, ...selection];
             this.selectedUserIds = [...otherSelectedUserIds, ...currentTableSelectedIds];
         },
-        // 使用真实API获取部门用户数据:/system/user/list?pageNum=1&pageSize=10&deptId=xxx
+
         async getUsers() {
-            if (!this.queryParams.deptId) return;
+            if (!this.queryParams.deptId) return Promise.resolve();
 
             this.userLoading = true;
             try {
@@ -327,8 +364,10 @@ export default {
             } finally {
                 this.userLoading = false;
             }
+            
+            return Promise.resolve();
         },
-        // 暂时注释掉搜索相关的方法
+        // 搜索相关的方法
         // async getList() {
         //     if (!this.queryParams.deptId) return;
 
@@ -440,20 +479,32 @@ export default {
                 ...this.extraParams
             });
 
+            this.isDialogClosing = true;
             this.dialogVisible = false;
         },
         handleCancel() {
+            this.isDialogClosing = true;
             this.dialogVisible = false;
         },
         /* 恢复表格中的选中状态 */
         restoreSelection() {
             if (!this.$refs.table || !this.userList || !this.selectedUsers) return;
 
+            // 单选模式
+            if (this.selectMode === 'single') {
+                const selectedUser = this.selectedUsers.find(user => 
+                    this.userList.some(row => row.userId === user.userId)
+                );
+                if (selectedUser) {
+                    this.selectedUserId = selectedUser.userId;
+                }
+                return;
+            }
 
+            // 多选模式
             this.$refs.table.clearSelection();
             const originalSelectedUserIds = [...this.selectedUserIds];
 
-
             this.userList.forEach(row => {
                 if (originalSelectedUserIds.includes(row.userId)) {
                     this.$refs.table.toggleRowSelection(row, true);
@@ -464,7 +515,8 @@ export default {
         removeSelectedUser(user, index) {
             this.selectedUsers.splice(index, 1);
             this.selectedUserIds.splice(this.selectedUserIds.indexOf(user.userId), 1);
-            // 同步取消表格中的选中状态,需要找到表格中对应的行对象
+            
+            // 同步取消表格中的选中状态
             if (this.$refs.table) {
                 const tableRow = this.userList.find(row => row.userId === user.userId);
                 if (tableRow) {
@@ -475,8 +527,12 @@ export default {
         handleClose() {
             this.currentDepartment = null;
             this.userList = [];
-            this.selectedUsers = [];
-            this.selectedUserIds = [];
+            // 清空选中状态
+            if (this.isDialogClosing) {
+                this.selectedUsers = [];
+                this.selectedUserIds = [];
+                this.selectedUserId = null;
+            }
             // this.searchText = '';
             this.queryParams.pageNum = 1;
         }

+ 1 - 0
src/views/system/auditConfig/index.vue

@@ -121,6 +121,7 @@
     <user-select
       :visible.sync="showUserSelectDialog"
       title="选择审核人"
+      select-mode="multiple"
       @confirm="handleUserSelectConfirm"
     />
 

+ 1 - 0
src/views/system/role/authUser.vue

@@ -99,6 +99,7 @@
       ref="userSelect"
       :visible.sync="selectUserVisible"
       :extra-params="{ roleId: queryParams.roleId }"
+      select-mode="single"
       @confirm="handleConfirm"
     />
   </div>