feat(系统设置): 系统项目启用禁用添加成员&菜单图标
This commit is contained in:
parent
8ed90363f9
commit
7fb94f0977
|
@ -19,11 +19,21 @@ export function deleteOrg(id: string) {
|
||||||
return MSR.get({ url: `${orgUrl.getDeleteOrgUrl}${id}` });
|
return MSR.get({ url: `${orgUrl.getDeleteOrgUrl}${id}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 删除项目
|
||||||
|
export function deleteProject(id: string) {
|
||||||
|
return MSR.get({ url: `${orgUrl.getDeleteProjectUrl}${id}` });
|
||||||
|
}
|
||||||
|
|
||||||
// 撤销删除组织
|
// 撤销删除组织
|
||||||
export function revokeDeleteOrg(id: string) {
|
export function revokeDeleteOrg(id: string) {
|
||||||
return MSR.get({ url: `${orgUrl.getRecoverOrgUrl}${id}` });
|
return MSR.get({ url: `${orgUrl.getRecoverOrgUrl}${id}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 撤销删除项目
|
||||||
|
export function revokeDeleteProject(id: string) {
|
||||||
|
return MSR.get({ url: `${orgUrl.getRevokeProjectUrl}${id}` });
|
||||||
|
}
|
||||||
|
|
||||||
// 启用或禁用组织
|
// 启用或禁用组织
|
||||||
export function enableOrDisableOrg(id: string, isEnable = true) {
|
export function enableOrDisableOrg(id: string, isEnable = true) {
|
||||||
return MSR.get({ url: `${isEnable ? orgUrl.getEnableOrgUrl : orgUrl.getDisableOrgUrl}${id}` });
|
return MSR.get({ url: `${isEnable ? orgUrl.getEnableOrgUrl : orgUrl.getDisableOrgUrl}${id}` });
|
||||||
|
@ -60,5 +70,5 @@ export function deleteUserFromOrgOrProject(sourceId: string, userId: string, isO
|
||||||
|
|
||||||
// TODO: 等待后端同学的接口 启用或禁用项目
|
// TODO: 等待后端同学的接口 启用或禁用项目
|
||||||
export function enableOrDisableProject(id: string, isEnable = true) {
|
export function enableOrDisableProject(id: string, isEnable = true) {
|
||||||
return MSR.get({ url: `${isEnable ? orgUrl.getEnableOrgUrl : orgUrl.getDisableOrgUrl}${id}` });
|
return MSR.get({ url: `${isEnable ? orgUrl.getEnableProjectUrl : orgUrl.getDisableProjectUrl}${id}` });
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,3 +46,7 @@ export const getProjectInfoUrl = '/system/project/get/';
|
||||||
export const getDeleteProjectUrl = '/system/project/delete/';
|
export const getDeleteProjectUrl = '/system/project/delete/';
|
||||||
// 系统-组织及项目,获取用户下拉选项
|
// 系统-组织及项目,获取用户下拉选项
|
||||||
export const getUserByOrgOrProjectUrl = '/system/user/get-option/';
|
export const getUserByOrgOrProjectUrl = '/system/user/get-option/';
|
||||||
|
// 启用项目
|
||||||
|
export const getEnableProjectUrl = '/system/project/enable/';
|
||||||
|
// 禁用项目
|
||||||
|
export const getDisableProjectUrl = '/system/project/disable/';
|
||||||
|
|
|
@ -9,7 +9,7 @@ const ApiTest: AppRouteRecordRaw = {
|
||||||
component: DEFAULT_LAYOUT,
|
component: DEFAULT_LAYOUT,
|
||||||
meta: {
|
meta: {
|
||||||
locale: 'menu.apiTest',
|
locale: 'menu.apiTest',
|
||||||
icon: 'icon_api-test-filled',
|
icon: 'icon-icon_api-test-filled',
|
||||||
order: 4,
|
order: 4,
|
||||||
hideChildrenInMenu: true,
|
hideChildrenInMenu: true,
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,7 +9,7 @@ const BugManagement: AppRouteRecordRaw = {
|
||||||
component: DEFAULT_LAYOUT,
|
component: DEFAULT_LAYOUT,
|
||||||
meta: {
|
meta: {
|
||||||
locale: 'menu.bugManagement',
|
locale: 'menu.bugManagement',
|
||||||
icon: 'icon_defect',
|
icon: 'icon-icon_defect',
|
||||||
order: 2,
|
order: 2,
|
||||||
hideChildrenInMenu: true,
|
hideChildrenInMenu: true,
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,7 +9,7 @@ const FeatureTest: AppRouteRecordRaw = {
|
||||||
component: DEFAULT_LAYOUT,
|
component: DEFAULT_LAYOUT,
|
||||||
meta: {
|
meta: {
|
||||||
locale: 'menu.featureTest',
|
locale: 'menu.featureTest',
|
||||||
icon: 'icon_functional_testing',
|
icon: 'icon-icon_functional_testing',
|
||||||
order: 3,
|
order: 3,
|
||||||
hideChildrenInMenu: true,
|
hideChildrenInMenu: true,
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,7 +9,7 @@ const PerformanceTest: AppRouteRecordRaw = {
|
||||||
component: DEFAULT_LAYOUT,
|
component: DEFAULT_LAYOUT,
|
||||||
meta: {
|
meta: {
|
||||||
locale: 'menu.performanceTest',
|
locale: 'menu.performanceTest',
|
||||||
icon: 'icon_performance-test-filled',
|
icon: 'icon-icon_performance-test-filled',
|
||||||
order: 6,
|
order: 6,
|
||||||
hideChildrenInMenu: true,
|
hideChildrenInMenu: true,
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,7 +9,7 @@ const ProjectManagement: AppRouteRecordRaw = {
|
||||||
component: DEFAULT_LAYOUT,
|
component: DEFAULT_LAYOUT,
|
||||||
meta: {
|
meta: {
|
||||||
locale: 'menu.projectManagement',
|
locale: 'menu.projectManagement',
|
||||||
icon: 'icon_project-settings-filled',
|
icon: 'icon-icon_project-settings-filled',
|
||||||
order: 7,
|
order: 7,
|
||||||
hideChildrenInMenu: true,
|
hideChildrenInMenu: true,
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,7 +9,7 @@ const TestPlan: AppRouteRecordRaw = {
|
||||||
component: DEFAULT_LAYOUT,
|
component: DEFAULT_LAYOUT,
|
||||||
meta: {
|
meta: {
|
||||||
locale: 'menu.testPlan',
|
locale: 'menu.testPlan',
|
||||||
icon: 'icon_test-tracking_filled',
|
icon: 'icon-icon_test-tracking_filled',
|
||||||
order: 1,
|
order: 1,
|
||||||
hideChildrenInMenu: true,
|
hideChildrenInMenu: true,
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,7 +9,7 @@ const UiTest: AppRouteRecordRaw = {
|
||||||
component: DEFAULT_LAYOUT,
|
component: DEFAULT_LAYOUT,
|
||||||
meta: {
|
meta: {
|
||||||
locale: 'menu.uiTest',
|
locale: 'menu.uiTest',
|
||||||
icon: 'icon_ui-test-filled',
|
icon: 'icon-icon_ui-test-filled',
|
||||||
order: 5,
|
order: 5,
|
||||||
hideChildrenInMenu: true,
|
hideChildrenInMenu: true,
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,7 +9,7 @@ const WorkPlace: AppRouteRecordRaw = {
|
||||||
component: DEFAULT_LAYOUT,
|
component: DEFAULT_LAYOUT,
|
||||||
meta: {
|
meta: {
|
||||||
locale: 'menu.workplace',
|
locale: 'menu.workplace',
|
||||||
icon: 'icon_pc_filled',
|
icon: 'icon-icon_pc_filled',
|
||||||
order: 0,
|
order: 0,
|
||||||
hideChildrenInMenu: true,
|
hideChildrenInMenu: true,
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,4 +5,6 @@ export interface UserGroupState {
|
||||||
currentId: string;
|
currentId: string;
|
||||||
// 当前用户类型
|
// 当前用户类型
|
||||||
currentType: string;
|
currentType: string;
|
||||||
|
// 菜单开启关闭
|
||||||
|
collapse: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ const useUserGroupStore = defineStore('userGroup', {
|
||||||
currentTitle: '',
|
currentTitle: '',
|
||||||
currentId: '',
|
currentId: '',
|
||||||
currentType: '',
|
currentType: '',
|
||||||
|
collapse: true,
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
userGroupInfo(state: UserGroupState): UserGroupState {
|
userGroupInfo(state: UserGroupState): UserGroupState {
|
||||||
|
@ -18,6 +19,10 @@ const useUserGroupStore = defineStore('userGroup', {
|
||||||
setInfo(partial: Partial<UserGroupState>) {
|
setInfo(partial: Partial<UserGroupState>) {
|
||||||
this.$patch(partial);
|
this.$patch(partial);
|
||||||
},
|
},
|
||||||
|
// 设置用户组菜单开启关闭
|
||||||
|
setCollapse(collapse: boolean) {
|
||||||
|
this.collapse = collapse;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@
|
||||||
const { organizationId, projectId } = props;
|
const { organizationId, projectId } = props;
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await addUserToOrgOrProject({ memberIds: form.name, organizationId, projectId });
|
await addUserToOrgOrProject({ userIds: form.name, organizationId, projectId });
|
||||||
Message.success(t('system.organization.addSuccess'));
|
Message.success(t('system.organization.addSuccess'));
|
||||||
handleCancel();
|
handleCancel();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<MsDrawer
|
<MsDrawer
|
||||||
|
:mask="false"
|
||||||
:width="680"
|
:width="680"
|
||||||
:visible="currentVisible"
|
:visible="currentVisible"
|
||||||
unmount-on-close
|
unmount-on-close
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
</template>
|
</template>
|
||||||
<template #creator="{ record }">
|
<template #creator="{ record }">
|
||||||
<span>{{ record.createUser }}</span>
|
<span>{{ record.createUser }}</span>
|
||||||
<span v-if="record.orgAdmins.length > 0" class="text-[var(--color-text-4)]">{{
|
<span v-if="record.orgCreateUserIsAdmin" class="ml-[8px] text-[var(--color-text-4)]">{{
|
||||||
` (${t('common.admin')})`
|
`(${t('common.admin')})`
|
||||||
}}</span>
|
}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #memberCount="{ record }">
|
<template #memberCount="{ record }">
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
</template>
|
</template>
|
||||||
<template #creator="{ record }">
|
<template #creator="{ record }">
|
||||||
<span>{{ record.createUser }}</span>
|
<span>{{ record.createUser }}</span>
|
||||||
<span v-if="record.creatorAdmin" class="text-[var(--color-text-4)]">{{ ` (${t('common.admin')})` }}</span>
|
<span v-if="record.projectCreateUserIsAdmin" class="ml-[8px] text-[var(--color-text-4)]">{{
|
||||||
|
`(${t('common.admin')})`
|
||||||
|
}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #memberCount="{ record }">
|
<template #memberCount="{ record }">
|
||||||
<span class="primary-color" @click="showUserDrawer(record)">{{ record.memberCount }}</span>
|
<span class="primary-color" @click="showUserDrawer(record)">{{ record.memberCount }}</span>
|
||||||
|
@ -22,25 +24,30 @@
|
||||||
<MsButton @click="handleRevokeDelete(record)">{{ t('common.revokeDelete') }}</MsButton>
|
<MsButton @click="handleRevokeDelete(record)">{{ t('common.revokeDelete') }}</MsButton>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="!record.enable">
|
<template v-else-if="!record.enable">
|
||||||
<MsButton @click="handleEnableOrDisableOrg(record)">{{ t('common.enable') }}</MsButton>
|
<MsButton @click="handleEnableOrDisableProject(record)">{{ t('common.enable') }}</MsButton>
|
||||||
<MsButton @click="handleDelete(record)">{{ t('common.delete') }}</MsButton>
|
<MsButton @click="handleDelete(record)">{{ t('common.delete') }}</MsButton>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<MsButton @click="showOrganizationModal(record)">{{ t('common.edit') }}</MsButton>
|
<MsButton @click="showOrganizationModal(record)">{{ t('common.edit') }}</MsButton>
|
||||||
<MsButton @click="showAddUserModal(record)">{{ t('system.organization.addMember') }}</MsButton>
|
<MsButton @click="showAddUserModal(record)">{{ t('system.organization.addMember') }}</MsButton>
|
||||||
<MsButton @click="handleEnableOrDisableOrg(record, false)">{{ t('common.end') }}</MsButton>
|
<MsButton @click="handleEnableOrDisableProject(record, false)">{{ t('common.end') }}</MsButton>
|
||||||
<MsTableMoreAction :list="tableActions" @select="handleMoreAction($event, record)"></MsTableMoreAction>
|
<MsTableMoreAction :list="tableActions" @select="handleMoreAction($event, record)"></MsTableMoreAction>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</MsBaseTable>
|
</MsBaseTable>
|
||||||
<AddOrganizationModal
|
<AddProjectModal
|
||||||
type="edit"
|
type="edit"
|
||||||
:current-organization="currentUpdateOrganization"
|
:current-organization="currentUpdateOrganization"
|
||||||
:visible="orgVisible"
|
:visible="orgVisible"
|
||||||
@cancel="handleAddOrgModalCancel"
|
@cancel="handleAddOrgModalCancel"
|
||||||
/>
|
/>
|
||||||
<AddUserModal :organization-id="currentOrganizationId" :visible="userVisible" @cancel="handleAddUserModalCancel" />
|
<AddUserModal :project-id="currentProjectId" :visible="userVisible" @cancel="handleAddUserModalCancel" />
|
||||||
<UserDrawer v-bind="currentUserDrawer" @cancel="handleUserDrawerCancel" />
|
<UserDrawer
|
||||||
|
:project-id="currentProjectId"
|
||||||
|
type="project"
|
||||||
|
v-bind="currentUserDrawer"
|
||||||
|
@cancel="handleUserDrawerCancel"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@ -52,20 +59,20 @@
|
||||||
import type { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
import type { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||||
import {
|
import {
|
||||||
postProjectTable,
|
postProjectTable,
|
||||||
deleteOrg,
|
deleteProject,
|
||||||
enableOrDisableProject,
|
enableOrDisableProject,
|
||||||
revokeDeleteOrg,
|
revokeDeleteProject,
|
||||||
} from '@/api/modules/setting/system/organizationAndProject';
|
} from '@/api/modules/setting/system/organizationAndProject';
|
||||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||||
import { MsTableColumn } from '@/components/pure/ms-table/type';
|
import { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||||
import MsTableMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
import MsTableMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
||||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||||
import AddOrganizationModal from './addOrganizationModal.vue';
|
|
||||||
import { Message, TableData } from '@arco-design/web-vue';
|
import { Message, TableData } from '@arco-design/web-vue';
|
||||||
import UserDrawer from './userDrawer.vue';
|
import UserDrawer from './userDrawer.vue';
|
||||||
import AddUserModal from './addUserModal.vue';
|
import AddUserModal from './addUserModal.vue';
|
||||||
import useModal from '@/hooks/useModal';
|
import useModal from '@/hooks/useModal';
|
||||||
import { CreateOrUpdateSystemOrgParams } from '@/models/setting/system/orgAndProject';
|
import { CreateOrUpdateSystemOrgParams } from '@/models/setting/system/orgAndProject';
|
||||||
|
import AddProjectModal from './addProjectModal.vue';
|
||||||
|
|
||||||
export interface SystemOrganizationProps {
|
export interface SystemOrganizationProps {
|
||||||
keyword: string;
|
keyword: string;
|
||||||
|
@ -77,7 +84,7 @@
|
||||||
const tableStore = useTableStore();
|
const tableStore = useTableStore();
|
||||||
const userVisible = ref(false);
|
const userVisible = ref(false);
|
||||||
const orgVisible = ref(false);
|
const orgVisible = ref(false);
|
||||||
const currentOrganizationId = ref('');
|
const currentProjectId = ref('');
|
||||||
const currentUpdateOrganization = ref<CreateOrUpdateSystemOrgParams>();
|
const currentUpdateOrganization = ref<CreateOrUpdateSystemOrgParams>();
|
||||||
const { openDeleteModal, openModal } = useModal();
|
const { openDeleteModal, openModal } = useModal();
|
||||||
|
|
||||||
|
@ -133,7 +140,7 @@
|
||||||
|
|
||||||
tableStore.initColumn(TableKeyEnum.SYSTEM_PROJECT, organizationColumns, 'drawer');
|
tableStore.initColumn(TableKeyEnum.SYSTEM_PROJECT, organizationColumns, 'drawer');
|
||||||
|
|
||||||
const { propsRes, propsEvent, loadList, setKeyword, setLoading } = useTable(postProjectTable, {
|
const { propsRes, propsEvent, loadList, setKeyword } = useTable(postProjectTable, {
|
||||||
tableKey: TableKeyEnum.SYSTEM_PROJECT,
|
tableKey: TableKeyEnum.SYSTEM_PROJECT,
|
||||||
scroll: { y: 'auto', x: '1300px' },
|
scroll: { y: 'auto', x: '1300px' },
|
||||||
selectable: false,
|
selectable: false,
|
||||||
|
@ -167,7 +174,7 @@
|
||||||
content: t('system.organization.deleteTip'),
|
content: t('system.organization.deleteTip'),
|
||||||
onBeforeOk: async () => {
|
onBeforeOk: async () => {
|
||||||
try {
|
try {
|
||||||
await deleteOrg(record.id);
|
await deleteProject(record.id);
|
||||||
Message.success(t('common.deleteSuccess'));
|
Message.success(t('common.deleteSuccess'));
|
||||||
fetchData();
|
fetchData();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -184,9 +191,9 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEnableOrDisableOrg = async (record: any, isEnable = true) => {
|
const handleEnableOrDisableProject = async (record: any, isEnable = true) => {
|
||||||
const title = isEnable ? t('system.organization.enableTitle') : t('system.organization.enableTitle');
|
const title = isEnable ? t('system.project.enableTitle') : t('system.project.endTitle');
|
||||||
const content = isEnable ? t('system.organization.enableContent') : t('system.organization.endContent');
|
const content = isEnable ? t('system.project.enableContent') : t('system.project.endContent');
|
||||||
const okText = isEnable ? t('common.confirmEnable') : t('common.confirmClose');
|
const okText = isEnable ? t('common.confirmEnable') : t('common.confirmClose');
|
||||||
openModal({
|
openModal({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
|
@ -209,7 +216,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
const showOrganizationModal = (record: any) => {
|
const showOrganizationModal = (record: any) => {
|
||||||
currentOrganizationId.value = record.id;
|
currentProjectId.value = record.id;
|
||||||
orgVisible.value = true;
|
orgVisible.value = true;
|
||||||
currentUpdateOrganization.value = {
|
currentUpdateOrganization.value = {
|
||||||
id: record.id,
|
id: record.id,
|
||||||
|
@ -220,7 +227,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
const showAddUserModal = (record: any) => {
|
const showAddUserModal = (record: any) => {
|
||||||
currentOrganizationId.value = record.id;
|
currentProjectId.value = record.id;
|
||||||
userVisible.value = true;
|
userVisible.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -244,17 +251,24 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRevokeDelete = async (record: TableData) => {
|
const handleRevokeDelete = async (record: TableData) => {
|
||||||
try {
|
openModal({
|
||||||
setLoading(true);
|
type: 'error',
|
||||||
await revokeDeleteOrg(record.id);
|
cancelText: t('common.cancel'),
|
||||||
Message.success(t('common.revokeDeleteSuccess'));
|
title: t('system.project.revokeDeleteTitle', { name: record.name }),
|
||||||
fetchData();
|
content: t('system.organization.enableContent'),
|
||||||
} catch (error) {
|
okText: t('common.revokeDelete'),
|
||||||
// eslint-disable-next-line no-console
|
onBeforeOk: async () => {
|
||||||
console.error(error);
|
try {
|
||||||
} finally {
|
await revokeDeleteProject(record.id);
|
||||||
setLoading(false);
|
Message.success(t('common.revokeDeleteSuccess'));
|
||||||
}
|
fetchData();
|
||||||
|
} catch (error) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hideCancel: false,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<MsDrawer
|
<MsDrawer
|
||||||
|
:mask="false"
|
||||||
:width="680"
|
:width="680"
|
||||||
:visible="currentVisible"
|
:visible="currentVisible"
|
||||||
unmount-on-close
|
unmount-on-close
|
||||||
|
@ -37,7 +38,12 @@
|
||||||
</ms-base-table>
|
</ms-base-table>
|
||||||
</div>
|
</div>
|
||||||
</MsDrawer>
|
</MsDrawer>
|
||||||
<AddUserModal :organization-id="props.organizationId" :visible="userVisible" @cancel="handleHideUserModal" />
|
<AddUserModal
|
||||||
|
:project-id="props.projectId"
|
||||||
|
:organization-id="props.organizationId"
|
||||||
|
:visible="userVisible"
|
||||||
|
@cancel="handleHideUserModal"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@ -57,7 +63,8 @@
|
||||||
|
|
||||||
export interface projectDrawerProps {
|
export interface projectDrawerProps {
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
}
|
}
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const props = defineProps<projectDrawerProps>();
|
const props = defineProps<projectDrawerProps>();
|
||||||
|
@ -121,7 +128,12 @@
|
||||||
|
|
||||||
const handleRemove = async (record: TableData) => {
|
const handleRemove = async (record: TableData) => {
|
||||||
try {
|
try {
|
||||||
await deleteUserFromOrgOrProject(props.organizationId, record.id);
|
if (props.organizationId) {
|
||||||
|
await deleteUserFromOrgOrProject(props.organizationId, record.id);
|
||||||
|
}
|
||||||
|
if (props.projectId) {
|
||||||
|
await deleteUserFromOrgOrProject(props.projectId, record.id, true);
|
||||||
|
}
|
||||||
Message.success(t('common.removeSuccess'));
|
Message.success(t('common.removeSuccess'));
|
||||||
fetchData();
|
fetchData();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
@ -54,4 +54,9 @@ export default {
|
||||||
'system.organization.updateOrganizationSuccess': 'Update organization success',
|
'system.organization.updateOrganizationSuccess': 'Update organization success',
|
||||||
'system.organization.createProject': 'Create project',
|
'system.organization.createProject': 'Create project',
|
||||||
'system.organization.subordinateOrg': 'Subordinate organization',
|
'system.organization.subordinateOrg': 'Subordinate organization',
|
||||||
|
'system.project.revokeDeleteTitle': 'Confirm revoke {name} ?',
|
||||||
|
'system.project.enableTitle': 'Start project',
|
||||||
|
'system.project.endTitle': 'Close project',
|
||||||
|
'system.project.enableContent': 'The project after opening is displayed in the organization switching list',
|
||||||
|
'system.project.endContent': 'The project after closing is not displayed in the project switching list',
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,4 +50,9 @@ export default {
|
||||||
'system.organization.updateOrganizationSuccess': '更新组织成功',
|
'system.organization.updateOrganizationSuccess': '更新组织成功',
|
||||||
'system.organization.createProject': '创建项目',
|
'system.organization.createProject': '创建项目',
|
||||||
'system.organization.subordinateOrg': '所属组织',
|
'system.organization.subordinateOrg': '所属组织',
|
||||||
|
'system.project.revokeDeleteTitle': '确认恢复 {name} 这个项目吗?',
|
||||||
|
'system.project.enableTitle': '开启项目',
|
||||||
|
'system.project.endTitle': '关闭项目',
|
||||||
|
'system.project.enableContent': '开启后的项目展示在项目切换列表',
|
||||||
|
'system.project.endContent': '关闭后的项目不展示在项目切换列表',
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<a-modal
|
<a-modal
|
||||||
v-model="currentVisible"
|
v-model:visible="currentVisible"
|
||||||
class="ms-modal-form ms-modal-medium"
|
class="ms-modal-form ms-modal-medium"
|
||||||
width="680px"
|
width="680px"
|
||||||
text-align="start"
|
text-align="start"
|
||||||
:ok-text="t('system.userGroup.add')"
|
:ok-text="t('system.userGroup.add')"
|
||||||
unmount-on-close
|
unmount-on-close
|
||||||
:ok-loading="loading"
|
|
||||||
:on-before-ok="handleBeforeOk"
|
|
||||||
@cancel="handleCancel"
|
@cancel="handleCancel"
|
||||||
>
|
>
|
||||||
<template #title> {{ t('system.userGroup.addUser') }} </template>
|
<template #title> {{ t('system.userGroup.addUser') }} </template>
|
||||||
|
@ -22,6 +20,14 @@
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
</div>
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<a-button type="secondary" :loading="loading" @click="handleCancel">
|
||||||
|
{{ t('common.cancel') }}
|
||||||
|
</a-button>
|
||||||
|
<a-button type="primary" :loading="loading" :disabled="form.name.length === 0" @click="handleBeforeOk">
|
||||||
|
{{ t('common.add') }}
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -40,12 +40,6 @@
|
||||||
</a-table-column>
|
</a-table-column>
|
||||||
</template>
|
</template>
|
||||||
</a-table>
|
</a-table>
|
||||||
<div class="action">
|
|
||||||
<ms-button class="btn" @click="handleReset">{{ t('system.userGroup.reset') }}</ms-button>
|
|
||||||
<a-button class="btn" :disabled="!canSave" type="primary" @click="handleSave">{{
|
|
||||||
t('system.userGroup.save')
|
|
||||||
}}</a-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -56,7 +50,6 @@
|
||||||
import useUserGroupStore from '@/store/modules/setting/usergroup';
|
import useUserGroupStore from '@/store/modules/setting/usergroup';
|
||||||
import { getGlobalUSetting, saveGlobalUSetting } from '@/api/modules/setting/usergroup';
|
import { getGlobalUSetting, saveGlobalUSetting } from '@/api/modules/setting/usergroup';
|
||||||
import { UserGroupAuthSetting, AuthTableItem, type AuthScopeType, SavePermissions } from '@/models/setting/usergroup';
|
import { UserGroupAuthSetting, AuthTableItem, type AuthScopeType, SavePermissions } from '@/models/setting/usergroup';
|
||||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
|
||||||
|
|
||||||
export declare type OperationName = 'selection-checkbox' | 'selection-radio' | 'expand' | 'drag-handle';
|
export declare type OperationName = 'selection-checkbox' | 'selection-radio' | 'expand' | 'drag-handle';
|
||||||
|
|
||||||
|
@ -281,6 +274,11 @@
|
||||||
initData(store.currentId);
|
initData(store.currentId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
defineExpose({
|
||||||
|
handleReset,
|
||||||
|
handleSave,
|
||||||
|
canSave,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
|
|
@ -2,7 +2,11 @@
|
||||||
<a-button type="primary" @click="handleAddUser">{{ t('system.userGroup.quickAddUser') }}</a-button>
|
<a-button type="primary" @click="handleAddUser">{{ t('system.userGroup.quickAddUser') }}</a-button>
|
||||||
<MsBaseTable class="mt-[16px]" v-bind="propsRes" v-on="propsEvent">
|
<MsBaseTable class="mt-[16px]" v-bind="propsRes" v-on="propsEvent">
|
||||||
<template #action="{ record }">
|
<template #action="{ record }">
|
||||||
<ms-button @click="handleRemove(record)">{{ t('system.userGroup.remove') }}</ms-button>
|
<MsRemoveButton
|
||||||
|
:title="t('system.userGroup.removeName', { name: record.name })"
|
||||||
|
:sub-title-tip="t('system.userGroup.removeTip')"
|
||||||
|
@ok="handleRemove(record)"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</MsBaseTable>
|
</MsBaseTable>
|
||||||
<AddUserModal :visible="userVisible" @cancel="handleAddUserModalCancel" />
|
<AddUserModal :visible="userVisible" @cancel="handleAddUserModalCancel" />
|
||||||
|
@ -17,9 +21,9 @@
|
||||||
import { postUserByUserGroup, deleteUserFromUserGroup } from '@/api/modules/setting/usergroup';
|
import { postUserByUserGroup, deleteUserFromUserGroup } from '@/api/modules/setting/usergroup';
|
||||||
import { UserTableItem } from '@/models/setting/usergroup';
|
import { UserTableItem } from '@/models/setting/usergroup';
|
||||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
|
||||||
import { MsTableColumn } from '@/components/pure/ms-table/type';
|
import { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||||
import AddUserModal from './addUserModal.vue';
|
import AddUserModal from './addUserModal.vue';
|
||||||
|
import MsRemoveButton from '@/components/bussiness/ms-remove-button/MsRemoveButton.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const store = useUserGroupStore();
|
const store = useUserGroupStore();
|
||||||
|
@ -33,28 +37,20 @@
|
||||||
{
|
{
|
||||||
title: 'system.userGroup.name',
|
title: 'system.userGroup.name',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
showDrag: false,
|
|
||||||
showInTable: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'system.userGroup.email',
|
title: 'system.userGroup.email',
|
||||||
dataIndex: 'email',
|
dataIndex: 'email',
|
||||||
showDrag: false,
|
|
||||||
showInTable: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'system.userGroup.phone',
|
title: 'system.userGroup.phone',
|
||||||
dataIndex: 'email',
|
dataIndex: 'email',
|
||||||
showDrag: true,
|
|
||||||
showInTable: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'system.userGroup.operation',
|
title: 'system.userGroup.operation',
|
||||||
slotName: 'action',
|
slotName: 'action',
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
width: 200,
|
width: 200,
|
||||||
showDrag: true,
|
|
||||||
showInTable: true,
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
<template>
|
<template>
|
||||||
<MsCard simple>
|
<MsCard simple>
|
||||||
<div class="flex flex-row">
|
<div class="flex flex-row">
|
||||||
<div class="user-group-left">
|
<div class="user-group-left" :style="{ padding: collapse ? '24px 24px 24px 0' : 0 }">
|
||||||
<user-group-left v-if="collapse" />
|
<user-group-left v-if="collapse" />
|
||||||
<div class="usergroup-collapse">
|
<div class="usergroup-collapse" @click="handleCollapse">
|
||||||
<icon-double-left v-if="collapse" class="icon" @click="collapse = false" />
|
<MsIcon v-if="collapse" type="icon-icon_up-left_outlined" class="icon" />
|
||||||
<icon-double-right v-else class="icon" @click="collapse = true" />
|
<MsIcon v-else type="icon-icon_down-right_outlined" class="icon" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-[100%] overflow-x-scroll p-[24px]">
|
<div class="relative w-[100%] overflow-x-scroll p-[24px]">
|
||||||
<div class="flex flex-row items-center justify-between">
|
<div class="flex flex-row items-center justify-between">
|
||||||
<div class="title">{{ store.userGroupInfo.currentName }}</div>
|
<div class="title">{{ store.userGroupInfo.currentName }}</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
|
@ -27,11 +27,21 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-[16px]">
|
<div class="mt-[16px]">
|
||||||
<user-table v-if="currentTable === 'user'" :keyword="currentKeyword" />
|
<user-table v-if="currentTable === 'user'" :keyword="currentKeyword" />
|
||||||
<auth-table v-if="currentTable === 'auth'" />
|
<auth-table v-if="currentTable === 'auth'" ref="authRef" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</MsCard>
|
</MsCard>
|
||||||
|
<div
|
||||||
|
v-if="currentTable === 'auth'"
|
||||||
|
class="fixed bottom-[16px] right-[16px] z-[999] flex justify-between bg-white p-[24px] shadow-[0_-1px_4px_rgba(2,2,2,0.1)]"
|
||||||
|
:style="{ width: `calc(100% - ${menuWidth + 16}px)` }"
|
||||||
|
>
|
||||||
|
<ms-button class="btn" :disabled="!canSave" @click="handleReset">{{ t('system.userGroup.reset') }}</ms-button>
|
||||||
|
<a-button class="btn" :disabled="!canSave" type="primary" @click="handleSave">{{
|
||||||
|
t('system.userGroup.save')
|
||||||
|
}}</a-button>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@ -42,12 +52,20 @@
|
||||||
import UserGroupLeft from './components/index.vue';
|
import UserGroupLeft from './components/index.vue';
|
||||||
import UserTable from './components/userTable.vue';
|
import UserTable from './components/userTable.vue';
|
||||||
import AuthTable from './components/authTable.vue';
|
import AuthTable from './components/authTable.vue';
|
||||||
|
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
|
||||||
|
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||||
|
import { useAppStore } from '@/store';
|
||||||
|
|
||||||
const currentTable = ref('auth');
|
const currentTable = ref('auth');
|
||||||
const collapse = ref(true);
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const currentKeyword = ref('');
|
const currentKeyword = ref('');
|
||||||
|
const authRef = ref<{
|
||||||
|
handleReset: () => void;
|
||||||
|
handleSave: () => void;
|
||||||
|
canSave: boolean;
|
||||||
|
}>();
|
||||||
|
const appStore = useAppStore();
|
||||||
|
|
||||||
const handleSearch = (value: string) => {
|
const handleSearch = (value: string) => {
|
||||||
currentKeyword.value = value;
|
currentKeyword.value = value;
|
||||||
|
@ -58,6 +76,10 @@
|
||||||
|
|
||||||
const store = useUserGroupStore();
|
const store = useUserGroupStore();
|
||||||
const couldShowUser = computed(() => store.userGroupInfo.currentType === 'SYSTEM');
|
const couldShowUser = computed(() => store.userGroupInfo.currentType === 'SYSTEM');
|
||||||
|
const handleCollapse = () => {
|
||||||
|
store.setCollapse(!store.collapse);
|
||||||
|
};
|
||||||
|
const collapse = computed(() => store.collapse);
|
||||||
watch(
|
watch(
|
||||||
() => couldShowUser.value,
|
() => couldShowUser.value,
|
||||||
(val) => {
|
(val) => {
|
||||||
|
@ -66,6 +88,26 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
const menuWidth = computed(() => {
|
||||||
|
const width = appStore.menuCollapse ? 86 : appStore.menuWidth;
|
||||||
|
if (store.collapse) {
|
||||||
|
return width + 300;
|
||||||
|
}
|
||||||
|
return width + 24;
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleReset = () => {
|
||||||
|
authRef.value?.handleReset();
|
||||||
|
};
|
||||||
|
const handleSave = () => {
|
||||||
|
authRef.value?.handleSave();
|
||||||
|
};
|
||||||
|
const canSave = computed(() => {
|
||||||
|
if (currentTable.value === 'auth') {
|
||||||
|
return authRef.value?.canSave;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -77,19 +119,23 @@
|
||||||
}
|
}
|
||||||
.user-group-left {
|
.user-group-left {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 24px;
|
|
||||||
border-right: 1px solid var(--color-border);
|
border-right: 1px solid var(--color-border);
|
||||||
.usergroup-collapse {
|
.usergroup-collapse {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
right: -16px;
|
right: -16px;
|
||||||
|
z-index: 100;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
background-color: var(--color-text-n8);
|
background-color: var(--color-text-n8);
|
||||||
|
opacity: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
.icon {
|
.icon {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: var(--color-text-brand);
|
color: var(--color-text-brand);
|
||||||
|
|
|
@ -54,6 +54,8 @@ export default {
|
||||||
phone: 'Phone',
|
phone: 'Phone',
|
||||||
remove: 'Remove',
|
remove: 'Remove',
|
||||||
quickAddUser: 'Quick add user',
|
quickAddUser: 'Quick add user',
|
||||||
|
removeName: 'Confirm to remove {name} this user',
|
||||||
|
removeTip: 'After removal, the User Group permission will be lost',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
permission: {
|
permission: {
|
||||||
|
|
|
@ -53,6 +53,8 @@ export default {
|
||||||
phone: '手机',
|
phone: '手机',
|
||||||
remove: '移除',
|
remove: '移除',
|
||||||
quickAddUser: '快速添加用户',
|
quickAddUser: '快速添加用户',
|
||||||
|
removeName: '确认移除 {name} 这个用户吗',
|
||||||
|
removeTip: '移除后,将失去用户组权限',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
permission: {
|
permission: {
|
||||||
|
|
Loading…
Reference in New Issue