From f562d3eb25c254440d42113836d33074272c4ec8 Mon Sep 17 00:00:00 2001 From: shiziyuan9527 Date: Fri, 25 Jun 2021 18:57:40 +0800 Subject: [PATCH] =?UTF-8?q?refactor(=E7=B3=BB=E7=BB=9F=E8=AE=BE=E7=BD=AE):?= =?UTF-8?q?=20=E7=B3=BB=E7=BB=9F=E8=8F=9C=E5=8D=95=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E6=89=B9=E9=87=8F=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../constants/BatchProcessUserInfoType.java | 2 +- .../controller/GroupController.java | 10 + .../controller/WorkspaceController.java | 7 + .../io/metersphere/service/GroupService.java | 60 +++++- .../io/metersphere/service/UserService.java | 111 +++++++++-- .../organization/OrganizationMember.vue | 26 +-- .../components/settings/system/User.vue | 87 +++------ .../system/components/GroupCascader.vue | 174 +++++++++++++++++ .../system/components/ProjectCascader.vue | 177 ++++++++++++++++++ .../settings/workspace/WorkspaceMember.vue | 26 +-- 10 files changed, 570 insertions(+), 110 deletions(-) create mode 100644 frontend/src/business/components/settings/system/components/GroupCascader.vue create mode 100644 frontend/src/business/components/settings/system/components/ProjectCascader.vue diff --git a/backend/src/main/java/io/metersphere/commons/constants/BatchProcessUserInfoType.java b/backend/src/main/java/io/metersphere/commons/constants/BatchProcessUserInfoType.java index 11798c100a..cdbad34694 100644 --- a/backend/src/main/java/io/metersphere/commons/constants/BatchProcessUserInfoType.java +++ b/backend/src/main/java/io/metersphere/commons/constants/BatchProcessUserInfoType.java @@ -1,5 +1,5 @@ package io.metersphere.commons.constants; public enum BatchProcessUserInfoType { - ADD_WORKSPACE,ADD_USER_ROLE + ADD_WORKSPACE,ADD_USER_ROLE, ADD_PROJECT, ADD_USER_GROUP } diff --git a/backend/src/main/java/io/metersphere/controller/GroupController.java b/backend/src/main/java/io/metersphere/controller/GroupController.java index 96922cd070..dfc0345dbd 100644 --- a/backend/src/main/java/io/metersphere/controller/GroupController.java +++ b/backend/src/main/java/io/metersphere/controller/GroupController.java @@ -31,6 +31,11 @@ public class GroupController { return groupService.getGroupList(request); } + @GetMapping("/get/all") + public List getAllGroup() { + return groupService.getAllGroup(); + } + @PostMapping("/get") @RequiresPermissions(PermissionConstants.SYSTEM_GROUP_READ) public List getGroupByType(@RequestBody EditGroupRequest request) { @@ -96,4 +101,9 @@ public class GroupController { public List getOrganization(@PathVariable String userId) { return groupService.getOrganization(userId); } + + @GetMapping("/{type}/{id}") + public List getResource(@PathVariable String type, @PathVariable String id) { + return groupService.getResource(type, id); + } } diff --git a/backend/src/main/java/io/metersphere/controller/WorkspaceController.java b/backend/src/main/java/io/metersphere/controller/WorkspaceController.java index e82621fb2d..8963b3a113 100644 --- a/backend/src/main/java/io/metersphere/controller/WorkspaceController.java +++ b/backend/src/main/java/io/metersphere/controller/WorkspaceController.java @@ -102,4 +102,11 @@ public class WorkspaceController { public void updateOrgMember(@RequestBody WorkspaceMemberDTO memberDTO) { workspaceService.updateWorkspaceMember(memberDTO); } + + @GetMapping("/list/{orgId}") + public List getWorkspaceByOrgId(@PathVariable String orgId) { + WorkspaceRequest request = new WorkspaceRequest(); + request.setOrganizationId(orgId); + return workspaceService.getWorkspaceList(request); + } } diff --git a/backend/src/main/java/io/metersphere/service/GroupService.java b/backend/src/main/java/io/metersphere/service/GroupService.java index d19e60e4a7..d50f0507f3 100644 --- a/backend/src/main/java/io/metersphere/service/GroupService.java +++ b/backend/src/main/java/io/metersphere/service/GroupService.java @@ -4,10 +4,7 @@ import com.alibaba.fastjson.JSON; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import io.metersphere.base.domain.*; -import io.metersphere.base.mapper.GroupMapper; -import io.metersphere.base.mapper.OrganizationMapper; -import io.metersphere.base.mapper.UserGroupMapper; -import io.metersphere.base.mapper.UserGroupPermissionMapper; +import io.metersphere.base.mapper.*; import io.metersphere.base.mapper.ext.ExtGroupMapper; import io.metersphere.base.mapper.ext.ExtUserGroupMapper; import io.metersphere.commons.constants.UserGroupConstants; @@ -24,6 +21,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; +import org.apache.poi.ss.formula.functions.T; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -54,6 +52,10 @@ public class GroupService { private OrganizationService organizationService; @Resource private OrganizationMapper organizationMapper; + @Resource + private WorkspaceMapper workspaceMapper; + @Resource + private ProjectMapper projectMapper; private static final Map> map = new HashMap>(4){{ put(UserGroupType.SYSTEM, Arrays.asList(UserGroupType.SYSTEM, UserGroupType.ORGANIZATION, UserGroupType.WORKSPACE, UserGroupType.PROJECT)); @@ -341,4 +343,54 @@ public class GroupService { public List getProjectMemberGroups(String projectId, String userId) { return extUserGroupMapper.getProjectMemberGroups(projectId, userId); } + + public List getAllGroup() { + return groupMapper.selectByExample(new GroupExample()); + } + + public List getResource(String type, String groupId) { + List resource = new ArrayList<>(); + Group group = groupMapper.selectByPrimaryKey(groupId); + String orgId = group.getScopeId(); + if (!StringUtils.equals("global", orgId)) { + Organization organization = organizationMapper.selectByPrimaryKey(orgId); + if (organization == null) { + return resource; + } + } + + if (StringUtils.equals(UserGroupType.ORGANIZATION, type)) { + OrganizationExample organizationExample = new OrganizationExample(); + OrganizationExample.Criteria criteria = organizationExample.createCriteria(); + if (!StringUtils.equals(orgId, "global")) { + criteria.andIdEqualTo(orgId); + } + return organizationMapper.selectByExample(organizationExample); + } + + if (StringUtils.equals(UserGroupType.WORKSPACE, type)) { + WorkspaceExample workspaceExample = new WorkspaceExample(); + WorkspaceExample.Criteria criteria = workspaceExample.createCriteria(); + if (!StringUtils.equals(orgId, "global")) { + criteria.andOrganizationIdEqualTo(orgId); + } + return workspaceMapper.selectByExample(workspaceExample); + } + + if (StringUtils.equals(UserGroupType.PROJECT, type)) { + ProjectExample projectExample = new ProjectExample(); + ProjectExample.Criteria pc = projectExample.createCriteria(); + WorkspaceExample workspaceExample = new WorkspaceExample(); + WorkspaceExample.Criteria criteria = workspaceExample.createCriteria(); + if (!StringUtils.equals(orgId, "global")) { + criteria.andOrganizationIdEqualTo(orgId); + List workspaces = workspaceMapper.selectByExample(workspaceExample); + List list = workspaces.stream().map(Workspace::getId).collect(Collectors.toList()); + pc.andWorkspaceIdIn(list); + } + return projectMapper.selectByExample(projectExample); + } + + return resource; + } } diff --git a/backend/src/main/java/io/metersphere/service/UserService.java b/backend/src/main/java/io/metersphere/service/UserService.java index 8604fdd035..a9ddaed719 100644 --- a/backend/src/main/java/io/metersphere/service/UserService.java +++ b/backend/src/main/java/io/metersphere/service/UserService.java @@ -909,27 +909,104 @@ public class UserService { * @param request */ public void batchProcessUserInfo(UserBatchProcessRequest request) { - List userIdList = this.selectIdByUserRequest(request); String batchType = request.getBatchType(); - for (String userID : userIdList) { - Map> roleResourceIdMap = new HashMap<>(); - if (StringUtils.equals(BatchProcessUserInfoType.ADD_WORKSPACE.name(), batchType)) { - //添加工作空间时,默认赋予只读用户权限 - String userRole = RoleConstants.TEST_VIEWER; - List workspaceID = request.getBatchProcessValue(); - if (workspaceID != null && !workspaceID.isEmpty()) { - roleResourceIdMap.put(userRole, workspaceID); + if (StringUtils.equals(BatchProcessUserInfoType.ADD_PROJECT.name(), batchType)) { + batchAddUserToProject(request); + } else { + batchAddUserGroup(request); + } + } + + private void batchAddUserGroup(UserBatchProcessRequest request) { + List userIds = this.selectIdByUserRequest(request); + // groupId+resourceId e.g. admin+none + List groupResources = request.getBatchProcessValue(); + Map> sourceMap = new HashMap<>(); + for (String groupResource : groupResources) { + String[] split = groupResource.split("\\+"); + String groupId = split[0]; + String sourceId = split[1]; + if (sourceMap.get(groupId) == null) { + List list = new ArrayList<>(); + list.add(sourceId); + sourceMap.put(groupId, list); + } else { + sourceMap.get(groupId).add(sourceId); + } + } + + for (String userId : userIds) { + Set set = sourceMap.keySet(); + for (String group : set) { + Group gp = groupMapper.selectByPrimaryKey(group); + if (gp != null) { + if (StringUtils.equals(UserGroupType.SYSTEM, gp.getType())) { + UserGroupExample userGroupExample = new UserGroupExample(); + userGroupExample.createCriteria().andGroupIdEqualTo(group).andUserIdEqualTo(userId); + List userGroups = userGroupMapper.selectByExample(userGroupExample); + if (CollectionUtils.isEmpty(userGroups)) { + UserGroup userGroup = new UserGroup(); + userGroup.setId(UUID.randomUUID().toString()); + userGroup.setGroupId(group); + userGroup.setSourceId("system"); + userGroup.setUserId(userId); + userGroup.setUpdateTime(System.currentTimeMillis()); + userGroup.setCreateTime(System.currentTimeMillis()); + userGroupMapper.insertSelective(userGroup); + } + } else { + // 组织、工作空间、项目 + UserGroupExample userGroupExample = new UserGroupExample(); + userGroupExample.createCriteria().andGroupIdEqualTo(group).andUserIdEqualTo(userId); + List userGroups = userGroupMapper.selectByExample(userGroupExample); + List sourceIds = userGroups.stream().map(UserGroup::getSourceId).collect(Collectors.toList()); + List list = sourceMap.get(group); + list.removeAll(sourceIds); + SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); + UserGroupMapper mapper = sqlSession.getMapper(UserGroupMapper.class); + for (String sourceId : list) { + UserGroup userGroup = new UserGroup(); + userGroup.setId(UUID.randomUUID().toString()); + userGroup.setUserId(userId); + userGroup.setGroupId(group); + userGroup.setSourceId(sourceId); + userGroup.setCreateTime(System.currentTimeMillis()); + userGroup.setUpdateTime(System.currentTimeMillis()); + mapper.insertSelective(userGroup); + } + sqlSession.flushStatements(); + } } - } else if (StringUtils.equals(BatchProcessUserInfoType.ADD_USER_ROLE.name(), batchType)) { - roleResourceIdMap = this.genRoleResourceMap(request.getBatchProcessValue()); } - if (!roleResourceIdMap.isEmpty()) { - UserRoleExample userRoleExample = new UserRoleExample(); - userRoleExample.createCriteria().andUserIdEqualTo(userID); - List userRoles = userRoleMapper.selectByExample(userRoleExample); - UserRequest user = this.convert2UserRequest(userID, roleResourceIdMap, userRoles); - this.addUserWorkspaceAndRole(user, userRoles); + } + } + + private void batchAddUserToProject(UserBatchProcessRequest request) { + List userIds = this.selectIdByUserRequest(request); + String toSetGroup = UserGroupConstants.READ_ONLY; + List projectIds = request.getBatchProcessValue(); + for (String userId : userIds) { + UserGroupExample userGroupExample = new UserGroupExample(); + userGroupExample + .createCriteria() + .andUserIdEqualTo(userId) + .andGroupIdEqualTo(toSetGroup); + List userGroups = userGroupMapper.selectByExample(userGroupExample); + List exist = userGroups.stream().map(UserGroup::getSourceId).collect(Collectors.toList()); + projectIds.removeAll(exist); + SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); + UserGroupMapper mapper = sqlSession.getMapper(UserGroupMapper.class); + for (String projectId : projectIds) { + UserGroup userGroup = new UserGroup(); + userGroup.setId(UUID.randomUUID().toString()); + userGroup.setUserId(userId); + userGroup.setGroupId(toSetGroup); + userGroup.setSourceId(projectId); + userGroup.setCreateTime(System.currentTimeMillis()); + userGroup.setUpdateTime(System.currentTimeMillis()); + mapper.insertSelective(userGroup); } + sqlSession.flushStatements(); } } diff --git a/frontend/src/business/components/settings/organization/OrganizationMember.vue b/frontend/src/business/components/settings/organization/OrganizationMember.vue index 378df3aa31..db159cf690 100644 --- a/frontend/src/business/components/settings/organization/OrganizationMember.vue +++ b/frontend/src/business/components/settings/organization/OrganizationMember.vue @@ -5,24 +5,24 @@ - - - - - + + + + + + + + + + + + diff --git a/frontend/src/business/components/settings/system/User.vue b/frontend/src/business/components/settings/system/User.vue index f12452ffd2..e720351132 100644 --- a/frontend/src/business/components/settings/system/User.vue +++ b/frontend/src/business/components/settings/system/User.vue @@ -98,7 +98,8 @@ - + + @@ -112,7 +113,7 @@ import MsDialogFooter from "../../common/components/MsDialogFooter"; import MsTableOperatorButton from "../../common/components/MsTableOperatorButton"; import {getCurrentProjectID, listenGoBack, removeGoBackListener} from "@/common/js/utils"; import MsRolesTag from "../../common/components/MsRolesTag"; -import {getCurrentUser} from "../../../../common/js/utils"; +import {getCurrentUser} from "@/common/js/utils"; import {PHONE_REGEX} from "@/common/js/regex"; import UserImport from "@/business/components/settings/system/components/UserImport"; import MsTableHeaderSelectPopover from "@/business/components/common/components/table/MsTableHeaderSelectPopover"; @@ -126,10 +127,13 @@ import { import UserCascader from "@/business/components/settings/system/components/UserCascader"; import ShowMoreBtn from "@/business/components/track/case/components/ShowMoreBtn"; import EditUser from "@/business/components/settings/system/EditUser"; +import ProjectCascader from "@/business/components/settings/system/components/ProjectCascader"; +import GroupCascader from "@/business/components/settings/system/components/GroupCascader"; export default { name: "MsUser", components: { + GroupCascader, EditUser, MsCreateBox, MsTablePagination, @@ -141,6 +145,7 @@ export default { UserImport, MsTableHeaderSelectPopover, UserCascader, + ProjectCascader, ShowMoreBtn }, inject: [ @@ -163,9 +168,8 @@ export default { createPath: '/user/special/add', updatePath: '/user/special/update', editPasswordPath: '/user/special/password', - batchAddLable: this.$t('project.please_choose_workspace'), - batchAddTitle: this.$t('project.batch_choose_workspace'), - batchAddWorkspaceOptions:[], + batchAddTitle: "批量选择项目", + batchAddProjectOptions:[], batchAddUserRoleOptions:[], result: {}, currentUserId: '', @@ -191,12 +195,12 @@ export default { checkPasswordForm: {}, ruleForm: {}, buttons: [ - // { - // name: this.$t('user.button.add_workspace_batch'), handleClick: this.addWorkspaceBatch - // }, - // { - // name: this.$t('user.button.add_user_role_batch'), handleClick: this.addUserRoleBatch - // } + { + name: "批量添加到项目", handleClick: this.addToProjectBatch + }, + { + name: "批量添加用户组", handleClick: this.addUserGroupBatch + } ], rule: { id: [ @@ -338,7 +342,7 @@ export default { }, search() { this.selectRows = new Set(); - // this.condition.selectAll = false; + this.condition.selectAll = false; this.result = this.$post(this.buildPagePath(this.queryPath), this.condition, response => { let data = response.data; this.total = data.itemCount; @@ -418,41 +422,6 @@ export default { importUserDialogOpen(){ this.$refs.userImportDialog.open(); }, - addRole(validForm) { - this.$refs[validForm].validate(valid => { - if (valid) { - let roleInfo = {}; - roleInfo.selects = []; - let ids = this.form.roles.map(r => r.id); - ids.forEach(id => { - roleInfo.selects.push(id); - }) - let roles = this.form.roles; - roles.push(roleInfo); - if (this.form.roles.length > this.userRole.length - 1) { - this.btnAddRole = true; - } - } else { - return false; - } - }) - }, - initWorkspaceBatchProcessDataStruct(isShow){ - this.$get("/user/getWorkspaceDataStruct/All", response => { - this.batchAddWorkspaceOptions = response.data; - if(isShow){ - this.$refs.cascaderDialog.open('ADD_WORKSPACE',this.batchAddWorkspaceOptions); - } - }); - }, - initRoleBatchProcessDataStruct(isShow){ - this.$get("/user/getUserRoleDataStruct/All", response => { - this.batchAddUserRoleOptions = response.data; - if(isShow){ - this.$refs.cascaderDialog.open('ADD_USER_ROLE',this.batchAddUserRoleOptions); - } - }); - }, handleSelectAll(selection) { _handleSelectAll(this, selection, this.tableData, this.selectRows, this.condition); setUnSelectIds(this.tableData, this.condition, this.selectRows); @@ -468,25 +437,18 @@ export default { isSelectDataAll(data) { this.condition.selectAll = data; setUnSelectIds(this.tableData, this.condition, this.selectRows); + this.condition.unSelectIds = []; this.selectDataCounts = getSelectDataCounts(this.condition, this.total, this.selectRows); toggleAllSelection(this.$refs.userTable, this.tableData, this.selectRows); }, - addWorkspaceBatch(){ - if(this.batchAddWorkspaceOptions.length == 0){ - this.initWorkspaceBatchProcessDataStruct(true); - }else{ - this.$refs.cascaderDialog.open('ADD_WORKSPACE',this.batchAddWorkspaceOptions); - } + addToProjectBatch(){ + this.$refs.cascaderDialog.open('ADD_PROJECT',this.batchAddProjectOptions); }, - addUserRoleBatch(){ - if(this.batchAddUserRoleOptions.length == 0){ - this.initRoleBatchProcessDataStruct(true); - }else{ - this.$refs.cascaderDialog.open('ADD_USER_ROLE',this.batchAddUserRoleOptions); - } + addUserGroupBatch(){ + this.$refs.groupCascaderDialog.open('ADD_USER_GROUP',this.batchAddUserRoleOptions); }, - cascaderConfirm(batchProcessTypeParam,selectValueArr){ - if(selectValueArr.length == 0){ + cascaderConfirm(batchProcessTypeParam, selectValueArr){ + if(selectValueArr.length === 0){ this.$success(this.$t('commons.modify_success')); } let params = {}; @@ -496,7 +458,8 @@ export default { this.$post('/user/special/batchProcessUserInfo', params, () => { this.$success(this.$t('commons.modify_success')); this.search(); - this.$refs.cascaderDialog.close(); + batchProcessTypeParam === "ADD_PROJECT" ? this.$refs.cascaderDialog.close() : + this.$refs.groupCascaderDialog.close(); }); }, buildBatchParam(param) { diff --git a/frontend/src/business/components/settings/system/components/GroupCascader.vue b/frontend/src/business/components/settings/system/components/GroupCascader.vue new file mode 100644 index 0000000000..f58f521fa5 --- /dev/null +++ b/frontend/src/business/components/settings/system/components/GroupCascader.vue @@ -0,0 +1,174 @@ + + + + + + + diff --git a/frontend/src/business/components/settings/system/components/ProjectCascader.vue b/frontend/src/business/components/settings/system/components/ProjectCascader.vue new file mode 100644 index 0000000000..642c94dfb3 --- /dev/null +++ b/frontend/src/business/components/settings/system/components/ProjectCascader.vue @@ -0,0 +1,177 @@ + + + + + + + diff --git a/frontend/src/business/components/settings/workspace/WorkspaceMember.vue b/frontend/src/business/components/settings/workspace/WorkspaceMember.vue index 78613dfc64..3aad1aa1d4 100644 --- a/frontend/src/business/components/settings/workspace/WorkspaceMember.vue +++ b/frontend/src/business/components/settings/workspace/WorkspaceMember.vue @@ -5,25 +5,25 @@ - - - - - + + + + + + + + + + + +