Procházet zdrojové kódy

组件优化:用户选择组件新增用户类型筛选功能,支持按类型过滤用户并动态显示部门面板

刘博博 před 5 dny
rodič
revize
39ade6ed97

+ 162 - 9
src/components/UserSelect/index.vue

@@ -1,8 +1,29 @@
 <template>
     <el-dialog :title="title" :visible.sync="dialogVisible" :width="width" :top="top" append-to-body
         @close="handleClose">
+        <!-- 用户类型选择 -->
+        <div class="user-type-filter">
+            <el-form :inline="true" size="small">
+                <el-form-item label="用户类型">
+                    <el-select 
+                        v-model="selectedUserType" 
+                        placeholder="请选择用户类型" 
+                        clearable
+                        style="width: 240px"
+                        @change="handleUserTypeChange"
+                    >
+                        <el-option
+                            v-for="item in userTypeOptions"
+                            :key="item.value"
+                            :label="item.label"
+                            :value="item.value"
+                        />
+                    </el-select>
+                </el-form-item>
+            </el-form>
+        </div>
         <div class="user-select-container">
-            <div class="department-panel">
+            <div class="department-panel" v-if="showDepartmentPanel">
                 <div class="panel-header">
                     <h4>请选择部门</h4>
                 </div>
@@ -12,7 +33,7 @@
                     class="department-tree"></el-tree>
             </div>
 
-            <div class="user-panel">
+            <div class="user-panel" :class="{ 'full-width': !showDepartmentPanel }">
                 <div class="selected-users" v-if="selectedUsers && selectedUsers.length > 0">
                     <div class="selected-header">
                         <span>{{ selectMode === 'single' ? '已选中' : '已选中人员' }} ({{ selectedUsers.length }})</span>
@@ -69,7 +90,7 @@
                     <p>未找到匹配的用户</p>
                 </div> -->
 
-                <div class="user-table" v-if="currentDepartment">
+                <div class="user-table" v-if="shouldShowUserTable">
                     <el-table v-loading="userLoading" @row-click="clickRow" ref="table" :data="userList"
                         @selection-change="handleSelectionChange" style="flex: 1">
                         <!-- 根据选择模式显示不同的选择列 -->
@@ -99,9 +120,9 @@
                     </div>
                 </div>
 
-                <div class="empty-state" v-if="!currentDepartment">
+                <div class="empty-state" v-if="!shouldShowUserTable">
                     <i class="el-icon-warning"></i>
-                    <p>请先选择一个部门</p>
+                    <p>{{ emptyStateMessage }}</p>
                 </div>
             </div>
         </div>
@@ -170,7 +191,8 @@ export default {
                 pageNum: 1,
                 pageSize: 10,
                 userName: undefined,
-                deptId: undefined
+                deptId: undefined,
+                userType: undefined
             },
             // 加载状态标识
             deptLoading: false,
@@ -183,7 +205,15 @@ export default {
             // searchTotal: 0,
             // 单选模式下的选中用户ID
             selectedUserId: null,
-            isDialogClosing: false
+            isDialogClosing: false,
+            // 用户类型选择
+            selectedUserType: undefined,
+            userTypeOptions: [
+                { value: '1', label: '系统用户' },
+                { value: '2', label: '慧项管第三方用户' },
+                { value: '3', label: '慧监理第三方用户' },
+                { value: '4', label: '建科用户' }
+            ]
         };
     },
     computed: {
@@ -191,6 +221,36 @@ export default {
         departmentData() {
             return this.departments.length > 0 ? this.departments : this.internalDepartments;
         },
+        // 是否显示部门面板(只有建科用户需要选择部门)
+        showDepartmentPanel() {
+            return this.selectedUserType === '4';
+        },
+        // 是否需要选择部门
+        needDepartmentSelection() {
+            return this.selectedUserType === '4';
+        },
+        // 是否应该显示用户表格
+        shouldShowUserTable() {
+            if (!this.selectedUserType) {
+                return false;
+            }
+            // 建科用户需要选择部门后才显示
+            if (this.needDepartmentSelection) {
+                return !!this.currentDepartment;
+            }
+            // 其他类型用户直接显示
+            return true;
+        },
+        // 空状态提示信息
+        emptyStateMessage() {
+            if (!this.selectedUserType) {
+                return '请先选择用户类型';
+            }
+            if (this.needDepartmentSelection && !this.currentDepartment) {
+                return '请先选择一个部门';
+            }
+            return '暂无数据';
+        },
         // 以下计算属性搜索相关
         // filteredUsers() {
         //     if (!this.searchText) return [];
@@ -250,6 +310,58 @@ export default {
         // }
     },
     methods: {
+        // 用户类型变化处理
+        handleUserTypeChange(value) {
+            this.selectedUserType = value;
+            this.queryParams.userType = value;
+            
+            // 清空之前的选择
+            this.currentDepartment = null;
+            this.userList = [];
+            this.total = 0;
+            this.queryParams.deptId = undefined;
+            this.queryParams.pageNum = 1;
+            
+            if (!value) {
+                return;
+            }
+            
+            // 如果不是建科用户(1,2,3),直接加载该类型的所有用户
+            if (value !== '4') {
+                this.getUsersByType();
+            }
+            // 如果是建科用户(4),需要加载部门树供选择
+            else if (this.departmentData.length === 0) {
+                this.loadDepartmentData();
+            }
+        },
+        // 根据用户类型加载用户(不需要部门)
+        async getUsersByType() {
+            this.userLoading = true;
+            try {
+                const response = await listUser({
+                    pageNum: this.queryParams.pageNum,
+                    pageSize: this.queryParams.pageSize,
+                    userType: this.queryParams.userType
+                });
+
+                if (response.code === 200) {
+                    this.userList = response.rows || [];
+                    this.total = response.total || 0;
+                } else {
+                    this.$modal.msgError("获取用户数据失败: " + response.msg);
+                    this.userList = [];
+                    this.total = 0;
+                }
+            } catch (error) {
+                this.$modal.msgError("获取用户数据失败");
+                console.error("获取用户数据失败:", error);
+                this.userList = [];
+                this.total = 0;
+            } finally {
+                this.userLoading = false;
+            }
+        },
         // 加载部门数据
         async loadDepartmentData() {
             this.deptLoading = true;
@@ -338,15 +450,28 @@ export default {
         },
 
         async getUsers() {
+            // 如果不需要部门选择(非建科用户),使用类型筛选
+            if (!this.needDepartmentSelection) {
+                return this.getUsersByType();
+            }
+            
+            // 建科用户需要选择部门
             if (!this.queryParams.deptId) return Promise.resolve();
 
             this.userLoading = true;
             try {
-                const response = await listUser({
+                const params = {
                     pageNum: this.queryParams.pageNum,
                     pageSize: this.queryParams.pageSize,
                     deptId: this.queryParams.deptId
-                });
+                };
+                
+                // 如果有用户类型,添加到参数中
+                if (this.queryParams.userType) {
+                    params.userType = this.queryParams.userType;
+                }
+
+                const response = await listUser(params);
 
                 if (response.code === 200) {
                     this.userList = response.rows || [];
@@ -461,6 +586,11 @@ export default {
         // },
         // 确认选择
         handleConfirm() {
+            if (!this.selectedUserType) {
+                this.$modal.msgError("请先选择用户类型");
+                return;
+            }
+            
             if (this.selectedUserIds.length === 0) {
                 this.$modal.msgError("请选择要分配的用户");
                 return;
@@ -474,6 +604,7 @@ export default {
             this.$emit('confirm', {
                 userIds: this.selectedUserIds,
                 users: actualSelectedUsers,
+                userType: this.selectedUserType,
                 deptId: this.queryParams.deptId,
                 deptName: this.currentDepartment ? this.currentDepartment.label : '',
                 ...this.extraParams
@@ -532,15 +663,33 @@ export default {
                 this.selectedUsers = [];
                 this.selectedUserIds = [];
                 this.selectedUserId = null;
+                this.selectedUserType = undefined;
+                this.queryParams.userType = undefined;
             }
             // this.searchText = '';
             this.queryParams.pageNum = 1;
+            this.queryParams.deptId = undefined;
         }
     }
 };
 </script>
 
 <style scoped>
+.user-type-filter {
+    padding: 15px;
+    background-color: #f5f7fa;
+    border-bottom: 2px solid #e4e7ed;
+    margin-bottom: 0;
+}
+
+.user-type-filter .el-form {
+    margin-bottom: 0;
+}
+
+.user-type-filter .el-form-item {
+    margin-bottom: 0;
+}
+
 .user-select-container {
     display: flex;
     height: 500px;
@@ -565,6 +714,10 @@ export default {
     padding: 10px;
 }
 
+.user-panel.full-width {
+    width: 100%;
+}
+
 .panel-header {
     padding-bottom: 10px;
     border-bottom: 1px solid #e4e7ed;

+ 2 - 2
src/views/system/auditConfig/index.vue

@@ -26,10 +26,10 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item> -->
-      <el-form-item>
+      <!-- <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
-      </el-form-item>
+      </el-form-item> -->
     </el-form>
 
     <el-row :gutter="10" class="mb8">

+ 41 - 26
src/views/system/project/index.vue

@@ -4,7 +4,7 @@
       <el-form-item label="项目来源" prop="sourceFrom">
         <el-select v-model="queryParams.sourceFrom" placeholder="请选择项目来源" clearable filterable @change="handleQuery">
           <el-option
-            v-for="item in projectSourceList"
+            v-for="item in projectTypeList"
             :key="item.dictCode || item.dictValue || item.value"
             :label="item.dictLabel || item.label"
             :value="item.dictValue || item.value"
@@ -35,14 +35,14 @@
     </el-form>
 
     <el-row :gutter="10" class="mb8">
-      <el-col :span="1.5">
+      <!-- <el-col :span="1.5">
         <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
           v-hasPermi="['system:project:add']">新增</el-button>
-      </el-col>
-      <el-col :span="1.5">
+      </el-col> -->
+      <!-- <el-col :span="1.5">
         <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate"
           v-hasPermi="['system:project:edit']">修改</el-button>
-      </el-col>
+      </el-col> -->
       <!-- <el-col :span="1.5">
         <el-button
           type="danger"
@@ -98,8 +98,8 @@
       <el-table-column label="项目创建时间" width="160" align="center" prop="createTime" />
       <el-table-column label="操作" width="180" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
-          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
-            v-hasPermi="['system:project:edit']">修改</el-button>
+          <!-- <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
+            v-hasPermi="['system:project:edit']">修改</el-button> -->
           <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
             v-hasPermi="['system:project:remove']">删除</el-button>
         </template>
@@ -126,7 +126,12 @@
         </el-form-item> -->
         <el-form-item label="应用名称" prop="appId">
           <el-select v-model="form.appId" multiple style="width: 100%;">
-            <el-option v-for="item in appList" :key="item.appId" :label="item.name" :value="item.appId" />
+            <el-option
+              v-for="item in appList"
+              :key="item.appId || item.name"
+              :label="item.name"
+              :value="item.appId"
+            />
           </el-select>
         </el-form-item>
       </el-form>
@@ -176,9 +181,18 @@ export default {
       },
       appList: [],
       projectTypeList: [],
-      projectSourceList: [],
       // 表单参数
-      form: {},
+      form: {
+        projectId: null,
+        projectPid: null,
+        projectName: null,
+        appId: [],
+        createBy: null,
+        createTime: null,
+        updateBy: null,
+        updateTime: null,
+        name: null
+      },
       // 表单校验
       rules: {
         projectName: [
@@ -194,30 +208,25 @@ export default {
     this.getList();
     this.getAppList();
     this.getProjectTypeList();
-    this.getProjectSourceList();
   },
   methods: {
     /** 查询项目列表 */
     getList() {
       this.loading = true;
       listProject(this.queryParams).then(response => {
-        this.projectList = response.rows;
-        this.total = response.total;
+        this.projectList = response.rows || [];
+        this.total = response.total || 0;
+        this.loading = false;
+      }).catch(() => {
         this.loading = false;
       });
     },
 
     getProjectTypeList() {
       getDicts('project_type').then(response => {
-        this.projectTypeList = response.data;
-      });
-    },
-    getProjectSourceList() {
-      // 假设后端提供字典类型 project_source
-      getDicts('project_source').then(response => {
-        this.projectSourceList = response.data || [];
+        this.projectTypeList = response.data || [];
       }).catch(() => {
-        this.projectSourceList = [];
+        this.projectTypeList = [];
       });
     },
     // 取消按钮
@@ -231,6 +240,7 @@ export default {
         projectId: null,
         projectPid: null,
         projectName: null,
+        appId: [],
         createBy: null,
         createTime: null,
         updateBy: null,
@@ -267,7 +277,7 @@ export default {
       this.reset();
       const projectId = row.projectId || this.ids
       getProject(projectId).then(response => {
-        this.form = response.data;
+        this.form = response.data || {};
         this.open = true;
         this.title = "修改项目";
       });
@@ -314,11 +324,16 @@ export default {
       getInfo().then(res => {
         // 获取登录用户信息
         const user = res.user
-        appList(user.userId).then(response => {
-          this.appList = response.data;
-        });
+        if (user && user.userId) {
+          appList(user.userId).then(response => {
+            this.appList = response.data || [];
+          }).catch(() => {
+            this.appList = [];
+          });
+        }
       }).catch(error => {
-        reject(error)
+        console.error('获取用户信息失败:', error);
+        this.appList = [];
       })
     },
     // 根据名称生成稳定的颜色 class

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

@@ -34,7 +34,7 @@
           size="mini"
           @click="openSelectUser"
           v-hasPermi="['system:role:add']"
-        >添加用户</el-button>
+        >分配用户</el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button

+ 46 - 21
src/views/system/staff/index.vue

@@ -1,6 +1,16 @@
 <template>
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="项目来源" prop="sourceFrom">
+        <el-select v-model="queryParams.sourceFrom" placeholder="请选择项目来源" clearable filterable @change="handleQuery">
+          <el-option
+            v-for="item in projectTypeList"
+            :key="item.dictCode || item.dictValue || item.value"
+            :label="item.dictLabel || item.label"
+            :value="item.dictValue || item.value"
+          />
+        </el-select>
+      </el-form-item>
       <el-form-item label="项目" prop="projectPid">
         <el-select v-model="queryParams.projectPid"
                    filterable
@@ -14,10 +24,10 @@
         <div class="approver-selector">
           <div class="approver-input" @click="openQueryUserSelect">
             <span v-if="selectedQueryUsers.length === 0" class="placeholder">请选择成员</span>
-            <el-tag 
-              v-for="(user, index) in selectedQueryUsers" 
-              :key="user.userId" 
-              closable 
+            <el-tag
+              v-for="(user, index) in selectedQueryUsers"
+              :key="user.userId"
+              closable
               @close="removeQueryUser(user, index)"
               style="margin-right: 8px; margin-bottom: 5px"
             >
@@ -48,14 +58,14 @@
     </el-form>
 
     <el-row :gutter="10" class="mb8">
-      <el-col :span="1.5">
+      <!-- <el-col :span="1.5">
         <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
           v-hasPermi="['system:staff:add']">新增</el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate"
           v-hasPermi="['system:staff:edit']">修改</el-button>
-      </el-col>
+      </el-col> -->
       <!-- <el-col :span="1.5">
         <el-button
           type="danger"
@@ -116,8 +126,8 @@
 
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
-          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
-            v-hasPermi="['system:staff:edit']">修改</el-button>
+          <!-- <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
+            v-hasPermi="['system:staff:edit']">修改</el-button> -->
           <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
             v-hasPermi="['system:staff:remove']">删除</el-button>
         </template>
@@ -142,10 +152,10 @@
           <div class="approver-selector">
             <div class="approver-input" @click="openUserSelect">
               <span v-if="selectedUsers.length === 0" class="placeholder">请选择成员</span>
-              <el-tag 
-                v-for="(user, index) in selectedUsers" 
-                :key="user.userId" 
-                closable 
+              <el-tag
+                v-for="(user, index) in selectedUsers"
+                :key="user.userId"
+                closable
                 @close="removeUser(user, index)"
                 style="margin-right: 8px; margin-bottom: 5px"
               >
@@ -208,7 +218,7 @@
       select-mode="single"
       @confirm="handleUserSelectConfirm"
     />
-    
+
     <!-- 查询表单用户选择组件 -->
     <user-select
       :visible.sync="showQueryUserSelectDialog"
@@ -221,6 +231,7 @@
 
 <script>
 import { listStaff, getStaff, delStaff, addStaff, updateStaff, projectList, userList, roleList } from "@/api/system/staff";
+import { getDicts } from "@/api/system/dict/data";
 import UserSelect from "@/components/UserSelect";
 
 export default {
@@ -252,6 +263,7 @@ export default {
       queryParams: {
         pageNum: 1,
         pageSize: 10,
+        sourceFrom: null,
         projectPid: null,
         userId: null,
         roleId: null,
@@ -264,6 +276,7 @@ export default {
         username: null
       },
       projectList: [],
+      projectTypeList: [],
       userList: [],
       roleList: [],
       // 表单参数
@@ -283,7 +296,7 @@ export default {
       // 用户选择相关数据
       showUserSelectDialog: false,
       selectedUsers: [], // 当前选中的用户列表
-      
+
       // 查询表单用户选择相关数据
       showQueryUserSelectDialog: false,
       selectedQueryUsers: [], // 查询表单中选中的用户列表
@@ -292,6 +305,7 @@ export default {
   created() {
     this.getList();
     this.getProjectList();
+    this.getProjectTypeList();
     this.getUserList();
     this.getRoleList();
   },
@@ -464,7 +478,18 @@ export default {
     /**获取项目列表 */
     getProjectList() {
       projectList().then(response => {
-        this.projectList = response.rows;
+        this.projectList = response.rows || [];
+      }).catch(() => {
+        this.projectList = [];
+      });
+    },
+
+    /** 获取项目来源列表 */
+    getProjectTypeList() {
+      getDicts('project_type').then(response => {
+        this.projectTypeList = response.data || [];
+      }).catch(() => {
+        this.projectTypeList = [];
       });
     },
 
@@ -480,12 +505,12 @@ export default {
         this.roleList = response.rows;
       });
     },
-    
+
     // 打开用户选择对话框
     openUserSelect() {
       this.showUserSelectDialog = true;
     },
-    
+
     // 处理用户选择确认
     handleUserSelectConfirm(data) {
       // 单选模式,只取第一个用户
@@ -494,18 +519,18 @@ export default {
         this.form.userId = data.users[0].userId;
       }
     },
-    
+
     // 移除选中的用户
     removeUser(user, index) {
       this.selectedUsers.splice(index, 1);
       this.form.userId = null;
     },
-    
+
     // 打开查询表单用户选择对话框
     openQueryUserSelect() {
       this.showQueryUserSelectDialog = true;
     },
-    
+
     // 处理查询表单用户选择确认
     handleQueryUserSelectConfirm(data) {
       // 单选模式,只取第一个用户
@@ -514,7 +539,7 @@ export default {
         this.queryParams.userId = data.users[0].userId;
       }
     },
-    
+
     // 移除查询表单中选中的用户
     removeQueryUser(user, index) {
       this.selectedQueryUsers.splice(index, 1);

+ 26 - 3
src/views/system/user/index.vue

@@ -62,6 +62,21 @@
               />
             </el-select>
           </el-form-item>
+          <el-form-item label="用户类型" prop="userType">
+            <el-select
+              v-model="queryParams.userType"
+              placeholder="请选择用户类型"
+              clearable
+              style="width: 240px"
+            >
+              <el-option
+                v-for="item in userTypeOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
           <el-form-item label="创建时间">
             <el-date-picker
               v-model="dateRange"
@@ -187,13 +202,13 @@
                 @click="handleResetPwd(scope.row)"
                 v-hasPermi="['system:user:resetPwd']"
               >重置密码</el-button>
-              <el-button
+              <!-- <el-button
                 size="mini"
                 type="text"
                 icon="el-icon-circle-check"
                 @click="handleAuthRole(scope.row)"
                 v-hasPermi="['system:user:edit']"
-              >分配角色</el-button>
+              >分配角色</el-button> -->
             </template>
           </el-table-column>
         </el-table>
@@ -388,6 +403,13 @@ export default {
       postOptions: [],
       // 角色选项
       roleOptions: [],
+      // 用户类型选项
+      userTypeOptions: [
+        { value: '1', label: '系统用户' },
+        { value: '2', label: '慧项管第三方用户' },
+        { value: '3', label: '慧监理第三方用户' },
+        { value: '4', label: '建科用户' }
+      ],
       // 表单参数
       form: {},
       defaultProps: {
@@ -416,7 +438,8 @@ export default {
         userName: undefined,
         phonenumber: undefined,
         status: undefined,
-        deptId: undefined
+        deptId: undefined,
+        userType: undefined
       },
       // 列信息
       columns: [