refactor(系统设置): 系统菜单用户列表批量操作
This commit is contained in:
parent
6743dac777
commit
f562d3eb25
|
@ -1,5 +1,5 @@
|
||||||
package io.metersphere.commons.constants;
|
package io.metersphere.commons.constants;
|
||||||
|
|
||||||
public enum BatchProcessUserInfoType {
|
public enum BatchProcessUserInfoType {
|
||||||
ADD_WORKSPACE,ADD_USER_ROLE
|
ADD_WORKSPACE,ADD_USER_ROLE, ADD_PROJECT, ADD_USER_GROUP
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,11 @@ public class GroupController {
|
||||||
return groupService.getGroupList(request);
|
return groupService.getGroupList(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get/all")
|
||||||
|
public List<Group> getAllGroup() {
|
||||||
|
return groupService.getAllGroup();
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/get")
|
@PostMapping("/get")
|
||||||
@RequiresPermissions(PermissionConstants.SYSTEM_GROUP_READ)
|
@RequiresPermissions(PermissionConstants.SYSTEM_GROUP_READ)
|
||||||
public List<Group> getGroupByType(@RequestBody EditGroupRequest request) {
|
public List<Group> getGroupByType(@RequestBody EditGroupRequest request) {
|
||||||
|
@ -96,4 +101,9 @@ public class GroupController {
|
||||||
public List<Organization> getOrganization(@PathVariable String userId) {
|
public List<Organization> getOrganization(@PathVariable String userId) {
|
||||||
return groupService.getOrganization(userId);
|
return groupService.getOrganization(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{type}/{id}")
|
||||||
|
public List<?> getResource(@PathVariable String type, @PathVariable String id) {
|
||||||
|
return groupService.getResource(type, id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,4 +102,11 @@ public class WorkspaceController {
|
||||||
public void updateOrgMember(@RequestBody WorkspaceMemberDTO memberDTO) {
|
public void updateOrgMember(@RequestBody WorkspaceMemberDTO memberDTO) {
|
||||||
workspaceService.updateWorkspaceMember(memberDTO);
|
workspaceService.updateWorkspaceMember(memberDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/list/{orgId}")
|
||||||
|
public List<Workspace> getWorkspaceByOrgId(@PathVariable String orgId) {
|
||||||
|
WorkspaceRequest request = new WorkspaceRequest();
|
||||||
|
request.setOrganizationId(orgId);
|
||||||
|
return workspaceService.getWorkspaceList(request);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,7 @@ import com.alibaba.fastjson.JSON;
|
||||||
import com.github.pagehelper.Page;
|
import com.github.pagehelper.Page;
|
||||||
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageHelper;
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.mapper.GroupMapper;
|
import io.metersphere.base.mapper.*;
|
||||||
import io.metersphere.base.mapper.OrganizationMapper;
|
|
||||||
import io.metersphere.base.mapper.UserGroupMapper;
|
|
||||||
import io.metersphere.base.mapper.UserGroupPermissionMapper;
|
|
||||||
import io.metersphere.base.mapper.ext.ExtGroupMapper;
|
import io.metersphere.base.mapper.ext.ExtGroupMapper;
|
||||||
import io.metersphere.base.mapper.ext.ExtUserGroupMapper;
|
import io.metersphere.base.mapper.ext.ExtUserGroupMapper;
|
||||||
import io.metersphere.commons.constants.UserGroupConstants;
|
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.ExecutorType;
|
||||||
import org.apache.ibatis.session.SqlSession;
|
import org.apache.ibatis.session.SqlSession;
|
||||||
import org.apache.ibatis.session.SqlSessionFactory;
|
import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
|
import org.apache.poi.ss.formula.functions.T;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@ -54,6 +52,10 @@ public class GroupService {
|
||||||
private OrganizationService organizationService;
|
private OrganizationService organizationService;
|
||||||
@Resource
|
@Resource
|
||||||
private OrganizationMapper organizationMapper;
|
private OrganizationMapper organizationMapper;
|
||||||
|
@Resource
|
||||||
|
private WorkspaceMapper workspaceMapper;
|
||||||
|
@Resource
|
||||||
|
private ProjectMapper projectMapper;
|
||||||
|
|
||||||
private static final Map<String, List<String>> map = new HashMap<String, List<String>>(4){{
|
private static final Map<String, List<String>> map = new HashMap<String, List<String>>(4){{
|
||||||
put(UserGroupType.SYSTEM, Arrays.asList(UserGroupType.SYSTEM, UserGroupType.ORGANIZATION, UserGroupType.WORKSPACE, UserGroupType.PROJECT));
|
put(UserGroupType.SYSTEM, Arrays.asList(UserGroupType.SYSTEM, UserGroupType.ORGANIZATION, UserGroupType.WORKSPACE, UserGroupType.PROJECT));
|
||||||
|
@ -341,4 +343,54 @@ public class GroupService {
|
||||||
public List<Group> getProjectMemberGroups(String projectId, String userId) {
|
public List<Group> getProjectMemberGroups(String projectId, String userId) {
|
||||||
return extUserGroupMapper.getProjectMemberGroups(projectId, userId);
|
return extUserGroupMapper.getProjectMemberGroups(projectId, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Group> getAllGroup() {
|
||||||
|
return groupMapper.selectByExample(new GroupExample());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<? extends Object> getResource(String type, String groupId) {
|
||||||
|
List<T> 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<Workspace> workspaces = workspaceMapper.selectByExample(workspaceExample);
|
||||||
|
List<String> list = workspaces.stream().map(Workspace::getId).collect(Collectors.toList());
|
||||||
|
pc.andWorkspaceIdIn(list);
|
||||||
|
}
|
||||||
|
return projectMapper.selectByExample(projectExample);
|
||||||
|
}
|
||||||
|
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -909,27 +909,104 @@ public class UserService {
|
||||||
* @param request
|
* @param request
|
||||||
*/
|
*/
|
||||||
public void batchProcessUserInfo(UserBatchProcessRequest request) {
|
public void batchProcessUserInfo(UserBatchProcessRequest request) {
|
||||||
List<String> userIdList = this.selectIdByUserRequest(request);
|
|
||||||
String batchType = request.getBatchType();
|
String batchType = request.getBatchType();
|
||||||
for (String userID : userIdList) {
|
if (StringUtils.equals(BatchProcessUserInfoType.ADD_PROJECT.name(), batchType)) {
|
||||||
Map<String, List<String>> roleResourceIdMap = new HashMap<>();
|
batchAddUserToProject(request);
|
||||||
if (StringUtils.equals(BatchProcessUserInfoType.ADD_WORKSPACE.name(), batchType)) {
|
} else {
|
||||||
//添加工作空间时,默认赋予只读用户权限
|
batchAddUserGroup(request);
|
||||||
String userRole = RoleConstants.TEST_VIEWER;
|
}
|
||||||
List<String> workspaceID = request.getBatchProcessValue();
|
}
|
||||||
if (workspaceID != null && !workspaceID.isEmpty()) {
|
|
||||||
roleResourceIdMap.put(userRole, workspaceID);
|
private void batchAddUserGroup(UserBatchProcessRequest request) {
|
||||||
|
List<String> userIds = this.selectIdByUserRequest(request);
|
||||||
|
// groupId+resourceId e.g. admin+none
|
||||||
|
List<String> groupResources = request.getBatchProcessValue();
|
||||||
|
Map<String, List<String>> 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<String> list = new ArrayList<>();
|
||||||
|
list.add(sourceId);
|
||||||
|
sourceMap.put(groupId, list);
|
||||||
|
} else {
|
||||||
|
sourceMap.get(groupId).add(sourceId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String userId : userIds) {
|
||||||
|
Set<String> 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<UserGroup> 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<UserGroup> userGroups = userGroupMapper.selectByExample(userGroupExample);
|
||||||
|
List<String> sourceIds = userGroups.stream().map(UserGroup::getSourceId).collect(Collectors.toList());
|
||||||
|
List<String> 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<UserRole> userRoles = userRoleMapper.selectByExample(userRoleExample);
|
private void batchAddUserToProject(UserBatchProcessRequest request) {
|
||||||
UserRequest user = this.convert2UserRequest(userID, roleResourceIdMap, userRoles);
|
List<String> userIds = this.selectIdByUserRequest(request);
|
||||||
this.addUserWorkspaceAndRole(user, userRoles);
|
String toSetGroup = UserGroupConstants.READ_ONLY;
|
||||||
|
List<String> projectIds = request.getBatchProcessValue();
|
||||||
|
for (String userId : userIds) {
|
||||||
|
UserGroupExample userGroupExample = new UserGroupExample();
|
||||||
|
userGroupExample
|
||||||
|
.createCriteria()
|
||||||
|
.andUserIdEqualTo(userId)
|
||||||
|
.andGroupIdEqualTo(toSetGroup);
|
||||||
|
List<UserGroup> userGroups = userGroupMapper.selectByExample(userGroupExample);
|
||||||
|
List<String> 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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,24 +5,24 @@
|
||||||
<ms-table-header :create-permission="['ORGANIZATION_USER:READ+CREATE']" :condition.sync="condition" @search="initTableData" @create="create"
|
<ms-table-header :create-permission="['ORGANIZATION_USER:READ+CREATE']" :condition.sync="condition" @search="initTableData" @create="create"
|
||||||
:create-tip="$t('member.create')" :title="$t('commons.member')"/>
|
:create-tip="$t('member.create')" :title="$t('commons.member')"/>
|
||||||
</template>
|
</template>
|
||||||
<el-table border class="adjust-table ms-select-all-fixed" :data="tableData" style="width: 100%"
|
<el-table border class="adjust-table" :data="tableData" style="width: 100%"
|
||||||
@select-all="handleSelectAll"
|
@select-all="handleSelectAll"
|
||||||
@select="handleSelect"
|
@select="handleSelect"
|
||||||
:height="screenHeight"
|
:height="screenHeight"
|
||||||
ref="userTable">
|
ref="userTable">
|
||||||
<el-table-column type="selection" width="50"/>
|
<el-table-column type="selection" width="50"/>
|
||||||
<ms-table-header-select-popover v-show="total>0"
|
<!-- <ms-table-header-select-popover v-show="total>0"-->
|
||||||
:page-size="pageSize>total?total:pageSize"
|
<!-- :page-size="pageSize>total?total:pageSize"-->
|
||||||
:total="total"
|
<!-- :total="total"-->
|
||||||
:select-data-counts="selectDataCounts"
|
<!-- :select-data-counts="selectDataCounts"-->
|
||||||
:table-data-count-in-page="tableData.length"
|
<!-- :table-data-count-in-page="tableData.length"-->
|
||||||
@selectPageAll="isSelectDataAll(false)"
|
<!-- @selectPageAll="isSelectDataAll(false)"-->
|
||||||
@selectAll="isSelectDataAll(true)"/>
|
<!-- @selectAll="isSelectDataAll(true)"/>-->
|
||||||
<el-table-column v-if="!referenced" width="30" min-width="30" :resizable="false" align="center">
|
<!-- <el-table-column v-if="!referenced" width="30" min-width="30" :resizable="false" align="center">-->
|
||||||
<template v-slot:default="scope">
|
<!-- <template v-slot:default="scope">-->
|
||||||
<show-more-btn :is-show="scope.row.showMore" :buttons="buttons" :size="selectDataCounts"/>
|
<!-- <show-more-btn :is-show="scope.row.showMore" :buttons="buttons" :size="selectDataCounts"/>-->
|
||||||
</template>
|
<!-- </template>-->
|
||||||
</el-table-column>
|
<!-- </el-table-column>-->
|
||||||
|
|
||||||
<el-table-column prop="id" label="ID"/>
|
<el-table-column prop="id" label="ID"/>
|
||||||
<el-table-column prop="name" :label="$t('commons.username')"/>
|
<el-table-column prop="name" :label="$t('commons.username')"/>
|
||||||
|
|
|
@ -98,7 +98,8 @@
|
||||||
</span>
|
</span>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<user-import ref="userImportDialog" @refreshAll="search"></user-import>
|
<user-import ref="userImportDialog" @refreshAll="search"></user-import>
|
||||||
<user-cascader :lable="batchAddLable" :title="batchAddTitle" @confirm="cascaderConfirm" ref="cascaderDialog"></user-cascader>
|
<project-cascader :title="batchAddTitle" @confirm="cascaderConfirm" ref="cascaderDialog"></project-cascader>
|
||||||
|
<group-cascader :title="'批量添加用户组'" @confirm="cascaderConfirm" ref="groupCascaderDialog"></group-cascader>
|
||||||
<edit-user ref="editUser" @refresh="search"/>
|
<edit-user ref="editUser" @refresh="search"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -112,7 +113,7 @@ import MsDialogFooter from "../../common/components/MsDialogFooter";
|
||||||
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
|
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
|
||||||
import {getCurrentProjectID, listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
import {getCurrentProjectID, listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
||||||
import MsRolesTag from "../../common/components/MsRolesTag";
|
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 {PHONE_REGEX} from "@/common/js/regex";
|
||||||
import UserImport from "@/business/components/settings/system/components/UserImport";
|
import UserImport from "@/business/components/settings/system/components/UserImport";
|
||||||
import MsTableHeaderSelectPopover from "@/business/components/common/components/table/MsTableHeaderSelectPopover";
|
import MsTableHeaderSelectPopover from "@/business/components/common/components/table/MsTableHeaderSelectPopover";
|
||||||
|
@ -126,10 +127,13 @@ import {
|
||||||
import UserCascader from "@/business/components/settings/system/components/UserCascader";
|
import UserCascader from "@/business/components/settings/system/components/UserCascader";
|
||||||
import ShowMoreBtn from "@/business/components/track/case/components/ShowMoreBtn";
|
import ShowMoreBtn from "@/business/components/track/case/components/ShowMoreBtn";
|
||||||
import EditUser from "@/business/components/settings/system/EditUser";
|
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 {
|
export default {
|
||||||
name: "MsUser",
|
name: "MsUser",
|
||||||
components: {
|
components: {
|
||||||
|
GroupCascader,
|
||||||
EditUser,
|
EditUser,
|
||||||
MsCreateBox,
|
MsCreateBox,
|
||||||
MsTablePagination,
|
MsTablePagination,
|
||||||
|
@ -141,6 +145,7 @@ export default {
|
||||||
UserImport,
|
UserImport,
|
||||||
MsTableHeaderSelectPopover,
|
MsTableHeaderSelectPopover,
|
||||||
UserCascader,
|
UserCascader,
|
||||||
|
ProjectCascader,
|
||||||
ShowMoreBtn
|
ShowMoreBtn
|
||||||
},
|
},
|
||||||
inject: [
|
inject: [
|
||||||
|
@ -163,9 +168,8 @@ export default {
|
||||||
createPath: '/user/special/add',
|
createPath: '/user/special/add',
|
||||||
updatePath: '/user/special/update',
|
updatePath: '/user/special/update',
|
||||||
editPasswordPath: '/user/special/password',
|
editPasswordPath: '/user/special/password',
|
||||||
batchAddLable: this.$t('project.please_choose_workspace'),
|
batchAddTitle: "批量选择项目",
|
||||||
batchAddTitle: this.$t('project.batch_choose_workspace'),
|
batchAddProjectOptions:[],
|
||||||
batchAddWorkspaceOptions:[],
|
|
||||||
batchAddUserRoleOptions:[],
|
batchAddUserRoleOptions:[],
|
||||||
result: {},
|
result: {},
|
||||||
currentUserId: '',
|
currentUserId: '',
|
||||||
|
@ -191,12 +195,12 @@ export default {
|
||||||
checkPasswordForm: {},
|
checkPasswordForm: {},
|
||||||
ruleForm: {},
|
ruleForm: {},
|
||||||
buttons: [
|
buttons: [
|
||||||
// {
|
{
|
||||||
// name: this.$t('user.button.add_workspace_batch'), handleClick: this.addWorkspaceBatch
|
name: "批量添加到项目", handleClick: this.addToProjectBatch
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// name: this.$t('user.button.add_user_role_batch'), handleClick: this.addUserRoleBatch
|
name: "批量添加用户组", handleClick: this.addUserGroupBatch
|
||||||
// }
|
}
|
||||||
],
|
],
|
||||||
rule: {
|
rule: {
|
||||||
id: [
|
id: [
|
||||||
|
@ -338,7 +342,7 @@ export default {
|
||||||
},
|
},
|
||||||
search() {
|
search() {
|
||||||
this.selectRows = new Set();
|
this.selectRows = new Set();
|
||||||
// this.condition.selectAll = false;
|
this.condition.selectAll = false;
|
||||||
this.result = this.$post(this.buildPagePath(this.queryPath), this.condition, response => {
|
this.result = this.$post(this.buildPagePath(this.queryPath), this.condition, response => {
|
||||||
let data = response.data;
|
let data = response.data;
|
||||||
this.total = data.itemCount;
|
this.total = data.itemCount;
|
||||||
|
@ -418,41 +422,6 @@ export default {
|
||||||
importUserDialogOpen(){
|
importUserDialogOpen(){
|
||||||
this.$refs.userImportDialog.open();
|
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(selection) {
|
||||||
_handleSelectAll(this, selection, this.tableData, this.selectRows, this.condition);
|
_handleSelectAll(this, selection, this.tableData, this.selectRows, this.condition);
|
||||||
setUnSelectIds(this.tableData, this.condition, this.selectRows);
|
setUnSelectIds(this.tableData, this.condition, this.selectRows);
|
||||||
|
@ -468,25 +437,18 @@ export default {
|
||||||
isSelectDataAll(data) {
|
isSelectDataAll(data) {
|
||||||
this.condition.selectAll = data;
|
this.condition.selectAll = data;
|
||||||
setUnSelectIds(this.tableData, this.condition, this.selectRows);
|
setUnSelectIds(this.tableData, this.condition, this.selectRows);
|
||||||
|
this.condition.unSelectIds = [];
|
||||||
this.selectDataCounts = getSelectDataCounts(this.condition, this.total, this.selectRows);
|
this.selectDataCounts = getSelectDataCounts(this.condition, this.total, this.selectRows);
|
||||||
toggleAllSelection(this.$refs.userTable, this.tableData, this.selectRows);
|
toggleAllSelection(this.$refs.userTable, this.tableData, this.selectRows);
|
||||||
},
|
},
|
||||||
addWorkspaceBatch(){
|
addToProjectBatch(){
|
||||||
if(this.batchAddWorkspaceOptions.length == 0){
|
this.$refs.cascaderDialog.open('ADD_PROJECT',this.batchAddProjectOptions);
|
||||||
this.initWorkspaceBatchProcessDataStruct(true);
|
|
||||||
}else{
|
|
||||||
this.$refs.cascaderDialog.open('ADD_WORKSPACE',this.batchAddWorkspaceOptions);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
addUserRoleBatch(){
|
addUserGroupBatch(){
|
||||||
if(this.batchAddUserRoleOptions.length == 0){
|
this.$refs.groupCascaderDialog.open('ADD_USER_GROUP',this.batchAddUserRoleOptions);
|
||||||
this.initRoleBatchProcessDataStruct(true);
|
|
||||||
}else{
|
|
||||||
this.$refs.cascaderDialog.open('ADD_USER_ROLE',this.batchAddUserRoleOptions);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
cascaderConfirm(batchProcessTypeParam,selectValueArr){
|
cascaderConfirm(batchProcessTypeParam, selectValueArr){
|
||||||
if(selectValueArr.length == 0){
|
if(selectValueArr.length === 0){
|
||||||
this.$success(this.$t('commons.modify_success'));
|
this.$success(this.$t('commons.modify_success'));
|
||||||
}
|
}
|
||||||
let params = {};
|
let params = {};
|
||||||
|
@ -496,7 +458,8 @@ export default {
|
||||||
this.$post('/user/special/batchProcessUserInfo', params, () => {
|
this.$post('/user/special/batchProcessUserInfo', params, () => {
|
||||||
this.$success(this.$t('commons.modify_success'));
|
this.$success(this.$t('commons.modify_success'));
|
||||||
this.search();
|
this.search();
|
||||||
this.$refs.cascaderDialog.close();
|
batchProcessTypeParam === "ADD_PROJECT" ? this.$refs.cascaderDialog.close() :
|
||||||
|
this.$refs.groupCascaderDialog.close();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
buildBatchParam(param) {
|
buildBatchParam(param) {
|
||||||
|
|
|
@ -0,0 +1,174 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog class="user-cascade" :title="title" :visible.sync="dialogVisible"
|
||||||
|
@close="close">
|
||||||
|
<div class="block">
|
||||||
|
<el-form :model="ruleForm" :rules="rules" ref="ruleForm">
|
||||||
|
<el-form-item prop="project" label-width="0px">
|
||||||
|
<el-cascader-panel :props="props"
|
||||||
|
popper-class="ms-cascade"
|
||||||
|
:emitPath="true"
|
||||||
|
ref="cascadeSelector"
|
||||||
|
:key="isResourceShow"
|
||||||
|
clearable>
|
||||||
|
</el-cascader-panel>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<ms-dialog-footer
|
||||||
|
@cancel="close()"
|
||||||
|
@confirm="confirm()"/>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ElUploadList from "element-ui/packages/upload/src/upload-list";
|
||||||
|
import MsTableButton from '../../../../components/common/components/MsTableButton';
|
||||||
|
import {listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
||||||
|
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
|
||||||
|
import {GROUP_SYSTEM} from "@/common/js/constants";
|
||||||
|
import {USER_GROUP_SCOPE} from "@/common/js/table-constants";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "GroupCascader",
|
||||||
|
components: {ElUploadList, MsTableButton, MsDialogFooter},
|
||||||
|
data() {
|
||||||
|
let validateSelect = (rule, value, callback) => {
|
||||||
|
let checkNodes = this.$refs.cascadeSelector.getCheckedNodes(true);
|
||||||
|
if (checkNodes.length === 0) {
|
||||||
|
callback(new Error("请选择项目"));
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
};
|
||||||
|
const self = this
|
||||||
|
return {
|
||||||
|
ruleForm: {
|
||||||
|
project: '',
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
project: [
|
||||||
|
{validator: validateSelect, message: "请选择项目", trigger: 'change'}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
selectedIds: [],
|
||||||
|
isResourceShow: 0,
|
||||||
|
props: {
|
||||||
|
multiple: true,
|
||||||
|
lazy: true,
|
||||||
|
value: 'id',
|
||||||
|
label: 'showLabel',
|
||||||
|
lazyLoad(node, resolve) {
|
||||||
|
const {level} = node;
|
||||||
|
if (level === 0) {
|
||||||
|
self.getGroup(resolve);
|
||||||
|
} else if (level === 1) {
|
||||||
|
self.getResource(node, resolve);
|
||||||
|
} else {
|
||||||
|
resolve([]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dialogVisible: false,
|
||||||
|
isLoading: false,
|
||||||
|
batchProcessType: '',
|
||||||
|
options: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
close() {
|
||||||
|
removeGoBackListener(this.close);
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.selectedIds = [];
|
||||||
|
++this.isResourceShow;
|
||||||
|
this.options = [];
|
||||||
|
this.$refs['ruleForm'].resetFields();
|
||||||
|
},
|
||||||
|
open(batchProcessType, optionsParam) {
|
||||||
|
listenGoBack(this.close);
|
||||||
|
this.dialogVisible = true;
|
||||||
|
this.batchProcessType = batchProcessType;
|
||||||
|
this.options = optionsParam;
|
||||||
|
if (this.batchProcessType === 'ADD_PROJECT') {
|
||||||
|
this.rules.project[0].message = "请选择项目";
|
||||||
|
} else {
|
||||||
|
this.rules.project[0].message = "请选择用户组";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
confirm() {
|
||||||
|
this.$refs.ruleForm.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
let checkNodes = this.$refs.cascadeSelector.getCheckedNodes(true);
|
||||||
|
let selectValueArr = [];
|
||||||
|
for (let node of checkNodes) {
|
||||||
|
let idString = "";
|
||||||
|
if (node.parent) {
|
||||||
|
idString = node.parent.value + "+" + node.value;
|
||||||
|
} else {
|
||||||
|
idString = node.value + "+none";
|
||||||
|
}
|
||||||
|
selectValueArr.push(idString);
|
||||||
|
}
|
||||||
|
this.$emit('confirm', this.batchProcessType, selectValueArr)
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getGroup(resolve) {
|
||||||
|
this.$get("user/group/get/all", res => {
|
||||||
|
let data = res.data ? res.data : [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.forEach(d => {
|
||||||
|
d.leaf = d.type === GROUP_SYSTEM;
|
||||||
|
d.showLabel = "[" + USER_GROUP_SCOPE[d.type] + "] " + d.name;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
resolve(data);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getResource(node, resolve) {
|
||||||
|
let type = node.data.type;
|
||||||
|
let {value} = node;
|
||||||
|
this.$get("user/group/" + type + "/" + value, res => {
|
||||||
|
let data = res.data ? res.data : [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.forEach(d => {
|
||||||
|
d.leaf = true;
|
||||||
|
d.showLabel = d.name;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
resolve(data);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.user-cascade >>> .el-dialog {
|
||||||
|
width: 700px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-cascade >>> .el-dialog__body {
|
||||||
|
padding: 5px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .el-form-item__content {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .el-cascader-menu__wrap {
|
||||||
|
height: 300px;
|
||||||
|
width: 340px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,177 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog class="user-cascade" :title="title" :visible.sync="dialogVisible"
|
||||||
|
@close="close">
|
||||||
|
<div class="block">
|
||||||
|
<el-alert
|
||||||
|
title="默认为成员添加只读用户组(系统)"
|
||||||
|
type="info"
|
||||||
|
show-icon
|
||||||
|
:closable="false"
|
||||||
|
style="margin-bottom: 10px;"
|
||||||
|
>
|
||||||
|
</el-alert>
|
||||||
|
<el-form :model="ruleForm" :rules="rules" ref="ruleForm">
|
||||||
|
<el-form-item prop="project" label-width="0px">
|
||||||
|
<el-cascader-panel :props="props"
|
||||||
|
popper-class="ms-cascade"
|
||||||
|
v-model="selectedIds"
|
||||||
|
ref="cascadeSelector"
|
||||||
|
:key="isResourceShow"
|
||||||
|
clearable>
|
||||||
|
</el-cascader-panel>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<ms-dialog-footer
|
||||||
|
@cancel="close()"
|
||||||
|
@confirm="confirm()"/>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ElUploadList from "element-ui/packages/upload/src/upload-list";
|
||||||
|
import MsTableButton from '../../../../components/common/components/MsTableButton';
|
||||||
|
import {listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
||||||
|
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "User2ProjectCascader",
|
||||||
|
components: {ElUploadList, MsTableButton, MsDialogFooter},
|
||||||
|
data() {
|
||||||
|
let validateSelect = (rule, value, callback) => {
|
||||||
|
let checkNodes = this.$refs.cascadeSelector.getCheckedNodes(true);
|
||||||
|
if (checkNodes.length === 0) {
|
||||||
|
callback(new Error("请选择项目"));
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
};
|
||||||
|
const self = this
|
||||||
|
return {
|
||||||
|
ruleForm: {
|
||||||
|
project: '',
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
project: [
|
||||||
|
{validator: validateSelect, message: "请选择项目", trigger: 'change'}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
selectedIds: [],
|
||||||
|
isResourceShow: 0,
|
||||||
|
props: {
|
||||||
|
multiple: true,
|
||||||
|
lazy: true,
|
||||||
|
value: 'id',
|
||||||
|
label: 'name',
|
||||||
|
lazyLoad(node, resolve) {
|
||||||
|
const {level, value} = node;
|
||||||
|
if (level === 0) {
|
||||||
|
self.getOrganization(resolve);
|
||||||
|
} else if (level === 1) {
|
||||||
|
self.getWorkspace(value, resolve);
|
||||||
|
} else if (level === 2) {
|
||||||
|
self.getProject(value, resolve);
|
||||||
|
} else {
|
||||||
|
resolve([]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dialogVisible: false,
|
||||||
|
isLoading: false,
|
||||||
|
batchProcessType: '',
|
||||||
|
options: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
close() {
|
||||||
|
removeGoBackListener(this.close);
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.selectedIds = [];
|
||||||
|
++this.isResourceShow;
|
||||||
|
this.options = [];
|
||||||
|
this.$refs['ruleForm'].resetFields();
|
||||||
|
},
|
||||||
|
open(batchProcessType, optionsParam) {
|
||||||
|
listenGoBack(this.close);
|
||||||
|
this.dialogVisible = true;
|
||||||
|
this.batchProcessType = batchProcessType;
|
||||||
|
this.options = optionsParam;
|
||||||
|
if (this.batchProcessType === 'ADD_PROJECT') {
|
||||||
|
this.rules.project[0].message = "请选择项目";
|
||||||
|
} else {
|
||||||
|
this.rules.project[0].message = "请选择用户组";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
confirm() {
|
||||||
|
this.$refs.ruleForm.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
let checkNodes = this.$refs.cascadeSelector.getCheckedNodes(true);
|
||||||
|
let selectValueArr = [];
|
||||||
|
for (let i = 0; i < checkNodes.length; i++) {
|
||||||
|
selectValueArr.push(checkNodes[i].value);
|
||||||
|
}
|
||||||
|
this.$emit('confirm', this.batchProcessType, selectValueArr)
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getOrganization(resolve) {
|
||||||
|
this.$get("organization/list", res => {
|
||||||
|
let data = res.data ? res.data : [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.forEach(d => d.leaf = false);
|
||||||
|
}
|
||||||
|
resolve(data);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getWorkspace(condition, resolve) {
|
||||||
|
this.$get("workspace/list/" + condition, res => {
|
||||||
|
let data = res.data ? res.data : [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.forEach(d => d.leaf = false);
|
||||||
|
}
|
||||||
|
resolve(data);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getProject(condition, resolve) {
|
||||||
|
this.$get("project/listAll/" + condition, res => {
|
||||||
|
let data = res.data ? res.data : [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.forEach(d => d.leaf = true);
|
||||||
|
}
|
||||||
|
resolve(data);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.user-cascade >>> .el-dialog {
|
||||||
|
width: 750px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-cascade >>> .el-dialog__body {
|
||||||
|
padding: 5px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .el-form-item__content {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .el-cascader-menu__wrap {
|
||||||
|
height: 300px;
|
||||||
|
width: 250px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -5,25 +5,25 @@
|
||||||
<ms-table-header :create-permission="['WORKSPACE_USER:READ+CREATE']" :condition.sync="condition" @search="initTableData" @create="create"
|
<ms-table-header :create-permission="['WORKSPACE_USER:READ+CREATE']" :condition.sync="condition" @search="initTableData" @create="create"
|
||||||
:create-tip="$t('member.create')" :title="$t('commons.member')"/>
|
:create-tip="$t('member.create')" :title="$t('commons.member')"/>
|
||||||
</template>
|
</template>
|
||||||
<el-table border class="adjust-table ms-select-all-fixed" :data="tableData" style="width: 100%"
|
<el-table border class="adjust-table" :data="tableData" style="width: 100%"
|
||||||
@select-all="handleSelectAll"
|
@select-all="handleSelectAll"
|
||||||
@select="handleSelect"
|
@select="handleSelect"
|
||||||
:height="screenHeight"
|
:height="screenHeight"
|
||||||
ref="userTable">
|
ref="userTable">
|
||||||
|
|
||||||
<el-table-column type="selection" width="50"/>
|
<el-table-column type="selection" width="50"/>
|
||||||
<ms-table-header-select-popover v-show="total>0"
|
<!-- <ms-table-header-select-popover v-show="total>0"-->
|
||||||
:page-size="pageSize>total?total:pageSize"
|
<!-- :page-size="pageSize>total?total:pageSize"-->
|
||||||
:total="total"
|
<!-- :total="total"-->
|
||||||
:select-data-counts="selectDataCounts"
|
<!-- :select-data-counts="selectDataCounts"-->
|
||||||
:table-data-count-in-page="tableData.length"
|
<!-- :table-data-count-in-page="tableData.length"-->
|
||||||
@selectPageAll="isSelectDataAll(false)"
|
<!-- @selectPageAll="isSelectDataAll(false)"-->
|
||||||
@selectAll="isSelectDataAll(true)"/>
|
<!-- @selectAll="isSelectDataAll(true)"/>-->
|
||||||
<el-table-column v-if="!referenced" width="30" min-width="30" :resizable="false" align="center">
|
<!-- <el-table-column v-if="!referenced" width="30" min-width="30" :resizable="false" align="center">-->
|
||||||
<template v-slot:default="scope">
|
<!-- <template v-slot:default="scope">-->
|
||||||
<show-more-btn :is-show="scope.row.showMore" :buttons="buttons" :size="selectDataCounts"/>
|
<!-- <show-more-btn :is-show="scope.row.showMore" :buttons="buttons" :size="selectDataCounts"/>-->
|
||||||
</template>
|
<!-- </template>-->
|
||||||
</el-table-column>
|
<!-- </el-table-column>-->
|
||||||
|
|
||||||
<el-table-column prop="id" label="ID"/>
|
<el-table-column prop="id" label="ID"/>
|
||||||
<el-table-column prop="name" :label="$t('commons.username')"/>
|
<el-table-column prop="name" :label="$t('commons.username')"/>
|
||||||
|
|
Loading…
Reference in New Issue