diff --git a/frontend/package.json b/frontend/package.json index 0592096178..ff920348c2 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -47,6 +47,7 @@ "dayjs": "^1.11.8", "echarts": "^5.4.2", "hotbox-minder": "1.0.15", + "jsencrypt": "^3.3.2", "jsonpath-picker-vanilla": "^1.2.4", "lodash": "^4.17.21", "lodash-es": "^4.17.21", diff --git a/frontend/src/api/http/checkStatus.ts b/frontend/src/api/http/checkStatus.ts index 4b19b56226..e9be307797 100644 --- a/frontend/src/api/http/checkStatus.ts +++ b/frontend/src/api/http/checkStatus.ts @@ -12,7 +12,11 @@ export default function checkStatus(status: number, msg: string, errorMessageMod errMessage = `${msg}`; break; case 401: { - setSalt(msg); + if (msg.length > 100) { + setSalt(msg); + } else { + errMessage = msg || t('api.errMsg401'); + } if (!isLoginPage()) { // 不是登录页再调用logout logout(); diff --git a/frontend/src/api/modules/setting/organizationAndProject.ts b/frontend/src/api/modules/setting/organizationAndProject.ts index 130d4c97de..715615f8c1 100644 --- a/frontend/src/api/modules/setting/organizationAndProject.ts +++ b/frontend/src/api/modules/setting/organizationAndProject.ts @@ -75,6 +75,11 @@ export function addUserToOrgOrProject(data: AddUserToOrgOrProjectParams) { export function getUserByOrganizationOrProject(sourceId: string) { return MSR.get({ url: `${orgUrl.getUserByOrgOrProjectUrl}${sourceId}` }); } + +// 系统-获取管理员下拉选项 +export function getAdminByOrganizationOrProject() { + return MSR.get({ url: `${orgUrl.getAdminByOrgOrProjectUrl}` }); +} // 删除组织或项目成员 export function deleteUserFromOrgOrProject(sourceId: string, userId: string, isOrg = true) { return MSR.get({ @@ -147,3 +152,13 @@ export function deleteProjectMemberByOrg(projectId: string, userId: string) { export function addProjectMemberByOrg(data: AddUserToOrgOrProjectParams) { return MSR.post({ url: orgUrl.postAddProjectMemberByOrgUrl, data }); } + +// 组织-获取项目下的管理员选项 +export function getAdminByProjectByOrg(organizationId: string) { + return MSR.get({ url: `${orgUrl.getAdminByOrganizationOrProjectUrl}${organizationId}` }); +} + +// 组织-获取成员下的成员选项 +export function getUserByProjectByOrg(organizationId: string, projectId: string) { + return MSR.get({ url: `${orgUrl.getUserByOrganizationOrProjectUrl}${organizationId}/${projectId}` }); +} diff --git a/frontend/src/api/modules/setting/usergroup.ts b/frontend/src/api/modules/setting/usergroup.ts index 4fc047816b..97786342db 100644 --- a/frontend/src/api/modules/setting/usergroup.ts +++ b/frontend/src/api/modules/setting/usergroup.ts @@ -67,6 +67,16 @@ export function saveGlobalUSetting(data: SaveGlobalUSettingData) { return MSR.post({ url: ugUrl.editGlobalUSettingUrl, data }); } +// 系统-获取需要关联的用户选项 +export function getSystemUserGroupOption(id: string) { + return MSR.get({ url: `${ugUrl.getSystemUserGroupOptionUrl}${id}` }); +} + +// 组织-获取需要关联的用户选项 +export function getOrgUserGroupOption(organizationId: string, roleId: string) { + return MSR.get({ url: `${ugUrl.getOrgUserGroupOptionUrl}${organizationId}/${roleId}` }); +} + // 组织-编辑用户组对应的权限配置 export function saveOrgUSetting(data: SaveGlobalUSettingData) { return MSR.post({ url: ugUrl.editOrgUSettingUrl, data }); @@ -86,8 +96,8 @@ export function deleteUserFromUserGroup(id: string) { return MSR.get({ url: `${ugUrl.deleteUserFromUserGroupUrl}${id}` }); } // 组织-删除用户组对应的用户 -export function deleteOrgUserFromUserGroup(id: string) { - return MSR.get({ url: `${ugUrl.deleteOrgUserFromUserGroupUrl}${id}` }); +export function deleteOrgUserFromUserGroup(data: { userRoleId: string; userIds: string[]; organizationId: string }) { + return MSR.post>({ url: ugUrl.deleteOrgUserFromUserGroupUrl, data }); } // 系统-添加用户到用户组 export function addUserToUserGroup(data: { roleId: string; userIds: string[] }) { diff --git a/frontend/src/api/requrls/setting/organizationAndProject.ts b/frontend/src/api/requrls/setting/organizationAndProject.ts index 70377447f3..a8848bd39e 100644 --- a/frontend/src/api/requrls/setting/organizationAndProject.ts +++ b/frontend/src/api/requrls/setting/organizationAndProject.ts @@ -48,7 +48,7 @@ export const getDeleteProjectUrl = '/system/project/delete/'; // 系统-组织及项目,获取用户下拉选项 export const getUserByOrgOrProjectUrl = '/system/organization/get-option/'; // 系统-组织及项目,获取管理员下拉选项 -export const getAdminByOrgOrProjectUrl = '/system/organization/get-admin-option/'; +export const getAdminByOrgOrProjectUrl = '/system/project/user-list'; // 启用项目 export const getEnableProjectUrl = '/system/project/enable/'; // 禁用项目 @@ -82,3 +82,7 @@ export const getEnableProjectByOrgUrl = '/organization/project/enable/'; export const getDisableProjectByOrgUrl = '/organization/project/disable/'; // 删除项目 export const getDeleteProjectByOrgUrl = '/organization/project/delete/'; +// 获取成员下拉选项 +export const getUserByOrganizationOrProjectUrl = '/organization/project/user-member-list/'; +// 获取管理员下拉选项 +export const getAdminByOrganizationOrProjectUrl = '/organization/project/user-admin-list/'; diff --git a/frontend/src/api/requrls/setting/usergroup.ts b/frontend/src/api/requrls/setting/usergroup.ts index 78b408e696..11e50b1499 100644 --- a/frontend/src/api/requrls/setting/usergroup.ts +++ b/frontend/src/api/requrls/setting/usergroup.ts @@ -20,6 +20,8 @@ export const postUserByUserGroupUrl = `/user/role/relation/global/list`; export const addUserToUserGroupUrl = `/user/role/relation/global/add`; /** 删除用户组用户 */ export const deleteUserFromUserGroupUrl = `/user/role/relation/global/delete/`; +/** 获取需要关联的用户选项 */ +export const getSystemUserGroupOptionUrl = `/user/role/relation//global/user/option/`; /** 组织 */ // 组织-修改用户组 @@ -41,4 +43,6 @@ export const postOrgUserByUserGroupUrl = `/user/role/organization/list-member`; /** 组织-用户组添加用户 */ export const addOrgUserToUserGroupUrl = `/user/role/organization/add-member`; /** 组织-删除用户组用户 */ -export const deleteOrgUserFromUserGroupUrl = `/user/role/organization/delete/`; +export const deleteOrgUserFromUserGroupUrl = `/user/role/organization/remove-member`; +/** 组织-给用户组添加用户下拉选项 */ +export const getOrgUserGroupOptionUrl = `/user/role/organization/get-member/option/`; diff --git a/frontend/src/components/business/ms-user-selector/index.vue b/frontend/src/components/business/ms-user-selector/index.vue index 1c6690b703..3fa363a56e 100644 --- a/frontend/src/components/business/ms-user-selector/index.vue +++ b/frontend/src/components/business/ms-user-selector/index.vue @@ -1,100 +1,130 @@ diff --git a/frontend/src/components/business/ms-user-selector/utils.ts b/frontend/src/components/business/ms-user-selector/utils.ts new file mode 100644 index 0000000000..f19b4d37cb --- /dev/null +++ b/frontend/src/components/business/ms-user-selector/utils.ts @@ -0,0 +1,46 @@ +import { + getAdminByOrganizationOrProject, + getAdminByProjectByOrg, + getUserByOrganizationOrProject, + getUserByProjectByOrg, +} from '@/api/modules/setting/organizationAndProject'; +import { getOrgUserGroupOption, getSystemUserGroupOption } from '@/api/modules/setting/usergroup'; + +// eslint-disable-next-line no-shadow +export enum UserRequesetTypeEnum { + SYSTEM_USER_GROUP = 'SYSTEM_USER_GROUP', + SYSTEM_ORGANIZATION = 'SYSTEM_ORGANIZATION', + SYSTEM_ORGANIZATION_ADMIN = 'SYSTEM_ORGANIZATION_ADMIN', + SYSTEM_PROJECT = 'SYSTEM_PROJECT', + SYSTEM_PROJECT_ADMIN = 'SYSTEM_PROJECT_ADMIN', + ORGANIZATION_USER_GROUP = 'ORGANIZATION_USER_GROUP', + ORGANIZATION_USER_GROUP_ADMIN = 'ORGANIZATION_USER_GROUP_ADMIN', + ORGANIZATION_PROJECT = 'ORGANIZATION_PROJECT', + ORGANIZATION_PROJECT_ADMIN = 'ORGANIZATION_PROJECT_ADMIN', +} +export default function initOptionsFunc(type: string, params: Record) { + if (type === UserRequesetTypeEnum.SYSTEM_USER_GROUP) { + // 系统 - 用户组-添加成员-下拉选项 + return getSystemUserGroupOption(params.roleId); + } + if (type === UserRequesetTypeEnum.ORGANIZATION_USER_GROUP) { + // 组织 - 用户组-添加成员-下拉选项 + return getOrgUserGroupOption(params.organizationId, params.roleId); + } + if (type === UserRequesetTypeEnum.SYSTEM_ORGANIZATION_ADMIN || type === UserRequesetTypeEnum.SYSTEM_PROJECT_ADMIN) { + // 系统 - 【组织 或 项目】-添加管理员-下拉选项 + return getAdminByOrganizationOrProject(); + } + if (type === UserRequesetTypeEnum.SYSTEM_ORGANIZATION || type === UserRequesetTypeEnum.SYSTEM_PROJECT) { + // 系统 -【组织 或 项目】-添加成员-下拉选项 + return getUserByOrganizationOrProject(params.sourceId); + } + if (type === UserRequesetTypeEnum.ORGANIZATION_PROJECT) { + // 组织 - 项目-添加成员-下拉选项 + return getUserByProjectByOrg(params.organizationId, params.projectId); + } + if (type === UserRequesetTypeEnum.ORGANIZATION_PROJECT_ADMIN) { + // 组织 - 项目-添加管理员-下拉选项 + return getAdminByProjectByOrg(params.organizationId); + } +} diff --git a/frontend/src/locale/en-US/common.ts b/frontend/src/locale/en-US/common.ts index b26c027b07..8dfcb4bdde 100644 --- a/frontend/src/locale/en-US/common.ts +++ b/frontend/src/locale/en-US/common.ts @@ -14,6 +14,7 @@ export default { 'common.enable': 'Enable', 'common.close': 'Close', 'common.create': 'Create', + 'common.update': 'Update', 'common.confirmEnable': 'Confirm enable', 'common.confirmClose': 'Confirm close', 'common.enableSuccess': 'Enable success', diff --git a/frontend/src/locale/zh-CN/common.ts b/frontend/src/locale/zh-CN/common.ts index 91627b65d0..5b908f87e4 100644 --- a/frontend/src/locale/zh-CN/common.ts +++ b/frontend/src/locale/zh-CN/common.ts @@ -14,6 +14,7 @@ export default { 'common.enable': '启用', 'common.close': '关闭', 'common.create': '创建', + 'common.update': '更新', 'common.confirmEnable': '确认启用', 'common.confirmClose': '确认关闭', 'common.enableSuccess': '启用成功', diff --git a/frontend/src/models/setting/usergroup.ts b/frontend/src/models/setting/usergroup.ts index 34d62d05d2..f554a48426 100644 --- a/frontend/src/models/setting/usergroup.ts +++ b/frontend/src/models/setting/usergroup.ts @@ -120,4 +120,5 @@ export interface UserTableItem { createUser: string; updateUser: string; deleted: boolean; + [key: string]: string | boolean | number; } diff --git a/frontend/src/views/login/components/login-form.vue b/frontend/src/views/login/components/login-form.vue index 8de0cb38b8..e0486fe8c9 100644 --- a/frontend/src/views/login/components/login-form.vue +++ b/frontend/src/views/login/components/login-form.vue @@ -64,6 +64,7 @@ import { GetLoginLogoUrl } from '@/api/requrls/setting/config'; import type { LoginData } from '@/models/user'; import { WorkbenchRouteEnum } from '@/enums/routeEnum'; + import JSEncrypt from 'jsencrypt'; const router = useRouter(); const { t } = useI18n(); @@ -99,6 +100,13 @@ password: 'metersphere', }); + const encrypted = (input: string, publicKey: string) => { + const encrypt = new JSEncrypt({ default_key_size: '1024' }); + debugger; + encrypt.setPublicKey(publicKey); + return encrypt.encrypt(input); + }; + const handleSubmit = async ({ errors, values, @@ -110,12 +118,15 @@ if (!errors) { setLoading(true); try { - await userStore.login(values as LoginData); + const publicKey = userStore.salt; + await userStore.login({ + username: encrypted(values.username, publicKey), + password: encrypted(values.password, publicKey), + authenticate: values.authenticate, + } as LoginData); Message.success(t('login.form.login.success')); const { rememberPassword } = loginConfig.value; const { username, password } = values; - // 实际生产环境需要进行加密存储。 - // The actual production environment requires encrypted storage. loginConfig.value.username = rememberPassword ? username : ''; loginConfig.value.password = rememberPassword ? password : ''; const { redirect, ...othersQuery } = router.currentRoute.value.query; diff --git a/frontend/src/views/setting/organization/project/components/addProjectModal.vue b/frontend/src/views/setting/organization/project/components/addProjectModal.vue index 41fcfb140c..d4f7a63248 100644 --- a/frontend/src/views/setting/organization/project/components/addProjectModal.vue +++ b/frontend/src/views/setting/organization/project/components/addProjectModal.vue @@ -5,7 +5,7 @@ class="ms-modal-form ms-modal-medium" :ok-text="isEdit ? t('common.update') : t('common.create')" unmount-on-close - @cancel="handleCancel" + @cancel="handleCancel(false)" > @@ -67,7 +73,7 @@ import useModal from '@/hooks/useModal'; import { CreateOrUpdateSystemProjectParams } from '@/models/setting/system/orgAndProject'; import AddProjectModal from './addProjectModal.vue'; - import { UserItem } from '@/components/business/ms-user-selector/index.vue'; + import { UserItem } from '@/models/setting/log'; export interface SystemOrganizationProps { keyword: string; @@ -235,16 +241,13 @@ const handleUserDrawerCancel = () => { currentUserDrawer.visible = false; - fetchData(); }; const handleAddUserModalCancel = () => { userVisible.value = false; - fetchData(); }; const handleAddProjectModalCancel = () => { addProjectVisible.value = false; - fetchData(); }; const handleRevokeDelete = async (record: TableData) => { @@ -278,4 +281,3 @@ cursor: pointer; } -@/api/modules/setting/organizationAndProject diff --git a/frontend/src/views/setting/system/organizationAndProject/components/userDrawer.vue b/frontend/src/views/setting/system/organizationAndProject/components/userDrawer.vue index 0927bd1668..bb47cc2b1a 100644 --- a/frontend/src/views/setting/system/organizationAndProject/components/userDrawer.vue +++ b/frontend/src/views/setting/system/organizationAndProject/components/userDrawer.vue @@ -44,6 +44,7 @@ :organization-id="props.organizationId" :visible="userVisible" @cancel="handleHideUserModal" + @submit="fetchData" /> diff --git a/frontend/src/views/setting/system/organizationAndProject/index.vue b/frontend/src/views/setting/system/organizationAndProject/index.vue index a213033a2f..b1c3c64221 100644 --- a/frontend/src/views/setting/system/organizationAndProject/index.vue +++ b/frontend/src/views/setting/system/organizationAndProject/index.vue @@ -29,8 +29,8 @@ - - + +