feat: 新增权限管理&表格样式调整
This commit is contained in:
parent
7ab276d3b9
commit
802efe9900
|
@ -59,7 +59,9 @@
|
|||
:style="{ width: props.width }"
|
||||
>
|
||||
<ms-button :disabled="!canSave" @click="handleReset">{{ t('system.userGroup.reset') }}</ms-button>
|
||||
<a-button :disabled="!canSave" type="primary" @click="handleSave">{{ t('system.userGroup.save') }}</a-button>
|
||||
<a-button v-permission="props.savePermission || []" :disabled="!canSave" type="primary" @click="handleSave">{{
|
||||
t('system.userGroup.save')
|
||||
}}</a-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -101,6 +103,7 @@
|
|||
const props = withDefaults(
|
||||
defineProps<{
|
||||
current: CurrentUserGroupItem;
|
||||
savePermission?: string[];
|
||||
width?: string;
|
||||
showBottom?: boolean;
|
||||
scroll?: {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
@search="searchData"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="showSystem" class="mt-2">
|
||||
<div v-if="showSystem" v-permission="['SYSTEM_USER_ROLE:READ']" class="mt-2">
|
||||
<CreateUserGroupPopup
|
||||
:list="systemUserGroupList"
|
||||
:visible="systemUserGroupVisible"
|
||||
|
@ -36,7 +36,11 @@
|
|||
{{ t('system.userGroup.systemUserGroup') }}
|
||||
</div>
|
||||
</div>
|
||||
<MsMoreAction :list="createSystemUGActionItem" @select="handleCreateUG(AuthScopeEnum.SYSTEM)">
|
||||
<MsMoreAction
|
||||
v-permission="['SYSTEM_USER_ROLE:READ+ADD']"
|
||||
:list="createSystemUGActionItem"
|
||||
@select="handleCreateUG(AuthScopeEnum.SYSTEM)"
|
||||
>
|
||||
<icon-plus-circle-fill class="cursor-pointer text-[rgb(var(--primary-7))]" size="20" />
|
||||
</MsMoreAction>
|
||||
</div>
|
||||
|
@ -67,6 +71,7 @@
|
|||
<div v-if="element.id === currentId && !element.internal" class="flex flex-row items-center gap-[8px]">
|
||||
<MsMoreAction
|
||||
v-if="element.type === systemType"
|
||||
v-permission="['SYSTEM_USER_ROLE:READ+UPDATE']"
|
||||
:list="addMemberActionItem"
|
||||
@select="handleAddMember"
|
||||
>
|
||||
|
@ -75,7 +80,7 @@
|
|||
</div>
|
||||
</MsMoreAction>
|
||||
<MsMoreAction
|
||||
:list="moreAction"
|
||||
:list="systemMoreAction"
|
||||
@select="(value) => handleMoreAction(value, element.id, AuthScopeEnum.SYSTEM)"
|
||||
>
|
||||
<div class="icon-button">
|
||||
|
@ -90,7 +95,7 @@
|
|||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
<div v-if="showOrg" class="mt-2">
|
||||
<div v-if="showOrg" v-permission="['ORGANIZATION_USER_ROLE:READ']" class="mt-2">
|
||||
<CreateUserGroupPopup
|
||||
:list="orgUserGroupList"
|
||||
:visible="orgUserGroupVisible"
|
||||
|
@ -118,7 +123,11 @@
|
|||
{{ t('system.userGroup.orgUserGroup') }}
|
||||
</div>
|
||||
</div>
|
||||
<MsMoreAction :list="createOrgUGActionItem" @select="orgUserGroupVisible = true">
|
||||
<MsMoreAction
|
||||
v-permission="['ORGANIZATION_USER_ROLE:READ+ADD']"
|
||||
:list="createOrgUGActionItem"
|
||||
@select="orgUserGroupVisible = true"
|
||||
>
|
||||
<icon-plus-circle-fill class="cursor-pointer text-[rgb(var(--primary-7))]" size="20" />
|
||||
</MsMoreAction>
|
||||
</div>
|
||||
|
@ -149,6 +158,7 @@
|
|||
<div v-if="element.id === currentId && !element.internal" class="flex flex-row items-center gap-[8px]">
|
||||
<MsMoreAction
|
||||
v-if="element.type === systemType"
|
||||
v-permission="['ORGANIZATION_USER_ROLE:READ+UPDATE']"
|
||||
:list="addMemberActionItem"
|
||||
@select="handleAddMember"
|
||||
>
|
||||
|
@ -157,7 +167,7 @@
|
|||
</div>
|
||||
</MsMoreAction>
|
||||
<MsMoreAction
|
||||
:list="moreAction"
|
||||
:list="orgMoreAction"
|
||||
@select="(value) => handleMoreAction(value, element.id, AuthScopeEnum.ORGANIZATION)"
|
||||
>
|
||||
<div class="icon-button">
|
||||
|
@ -172,7 +182,7 @@
|
|||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
<div v-if="showProject" class="mt-2">
|
||||
<div v-if="showProject" v-permission="['PROJECT_GROUP:READ']" class="mt-2">
|
||||
<CreateUserGroupPopup
|
||||
:list="projectUserGroupList"
|
||||
:visible="projectUserGroupVisible"
|
||||
|
@ -200,7 +210,11 @@
|
|||
{{ t('system.userGroup.projectUserGroup') }}
|
||||
</div>
|
||||
</div>
|
||||
<MsMoreAction :list="createProjectUGActionItem" @select="projectUserGroupVisible = true">
|
||||
<MsMoreAction
|
||||
v-permission="['PROJECT_GROUP:READ+ADD']"
|
||||
:list="createProjectUGActionItem"
|
||||
@select="projectUserGroupVisible = true"
|
||||
>
|
||||
<icon-plus-circle-fill class="cursor-pointer text-[rgb(var(--primary-7))]" size="20" />
|
||||
</MsMoreAction>
|
||||
</div>
|
||||
|
@ -231,6 +245,7 @@
|
|||
<div v-if="element.id === currentId && !element.internal" class="flex flex-row items-center gap-[8px]">
|
||||
<MsMoreAction
|
||||
v-if="element.type === systemType"
|
||||
v-permission="['PROJECT_GROUP:READ+UPDATE']"
|
||||
:list="addMemberActionItem"
|
||||
@select="handleAddMember"
|
||||
>
|
||||
|
@ -239,7 +254,7 @@
|
|||
</div>
|
||||
</MsMoreAction>
|
||||
<MsMoreAction
|
||||
:list="moreAction"
|
||||
:list="projectMoreAction"
|
||||
@select="(value) => handleMoreAction(value, element.id, AuthScopeEnum.PROJECT)"
|
||||
>
|
||||
<div class="icon-button">
|
||||
|
@ -278,6 +293,7 @@
|
|||
import useModal from '@/hooks/useModal';
|
||||
import { useAppStore } from '@/store';
|
||||
import { characterLimit } from '@/utils';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { CurrentUserGroupItem, PopVisible, PopVisibleItem, UserGroupItem } from '@/models/setting/usergroup';
|
||||
import { AuthScopeEnum } from '@/enums/commonEnum';
|
||||
|
@ -362,6 +378,57 @@
|
|||
eventTag: 'delete',
|
||||
},
|
||||
];
|
||||
const systemMoreAction: ActionsItem[] = [
|
||||
{
|
||||
label: 'system.userGroup.rename',
|
||||
danger: false,
|
||||
eventTag: 'rename',
|
||||
permission: ['SYSTEM_USER_ROLE:READ+UPDATE'],
|
||||
},
|
||||
{
|
||||
isDivider: true,
|
||||
},
|
||||
{
|
||||
label: 'system.userGroup.delete',
|
||||
danger: true,
|
||||
eventTag: 'delete',
|
||||
permission: ['SYSTEM_USER_ROLE:READ+DELETE'],
|
||||
},
|
||||
];
|
||||
const orgMoreAction: ActionsItem[] = [
|
||||
{
|
||||
label: 'system.userGroup.rename',
|
||||
danger: false,
|
||||
eventTag: 'rename',
|
||||
permission: ['ORGANIZATION_USER_ROLE:READ+UPDATE'],
|
||||
},
|
||||
{
|
||||
isDivider: true,
|
||||
},
|
||||
{
|
||||
label: 'system.userGroup.delete',
|
||||
danger: true,
|
||||
eventTag: 'delete',
|
||||
permission: ['ORGANIZATION_USER_ROLE:READ+UPDATE'],
|
||||
},
|
||||
];
|
||||
const projectMoreAction: ActionsItem[] = [
|
||||
{
|
||||
label: 'system.userGroup.rename',
|
||||
danger: false,
|
||||
eventTag: 'rename',
|
||||
permission: ['PROJECT_GROUP:READ+UPDATE'],
|
||||
},
|
||||
{
|
||||
isDivider: true,
|
||||
},
|
||||
{
|
||||
label: 'system.userGroup.delete',
|
||||
danger: true,
|
||||
eventTag: 'delete',
|
||||
permission: ['PROJECT_GROUP:READ+UPDATE'],
|
||||
},
|
||||
];
|
||||
|
||||
// 点击用户组列表
|
||||
const handleListItemClick = (element: UserGroupItem) => {
|
||||
|
@ -375,11 +442,11 @@
|
|||
const initData = async (id?: string, isSelect = true) => {
|
||||
try {
|
||||
let res: UserGroupItem[] = [];
|
||||
if (systemType === AuthScopeEnum.SYSTEM) {
|
||||
if (systemType === AuthScopeEnum.SYSTEM && hasAnyPermission(['SYSTEM_USER_ROLE:READ'])) {
|
||||
res = await getUserGroupList();
|
||||
} else if (systemType === AuthScopeEnum.ORGANIZATION) {
|
||||
} else if (systemType === AuthScopeEnum.ORGANIZATION && hasAnyPermission(['ORGANIZATION_USER_ROLE:READ'])) {
|
||||
res = await getOrgUserGroupList(appStore.currentOrgId);
|
||||
} else if (systemType === AuthScopeEnum.PROJECT) {
|
||||
} else if (systemType === AuthScopeEnum.PROJECT && hasAnyPermission(['PROJECT_GROUP:READ'])) {
|
||||
res = await getProjectUserGroupList(appStore.currentProjectId);
|
||||
}
|
||||
if (res.length > 0) {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<template>
|
||||
<MsBaseTable class="mt-[16px]" v-bind="propsRes" v-on="propsEvent">
|
||||
<template #quickCreate>
|
||||
<!-- <a-button type="primary" @click="handleAddUser">{{ t('system.userGroup.quickAddUser') }}</a-button> -->
|
||||
<template v-if="hasAnyPermission(props.updatePermission || [])" #quickCreate>
|
||||
<MsConfirmUserSelector :ok-loading="okLoading" v-bind="userSelectorProps" @confirm="handleAddMember" />
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
|
@ -33,6 +32,7 @@
|
|||
} from '@/api/modules/setting/usergroup';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { useAppStore } from '@/store';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { CurrentUserGroupItem, UserTableItem } from '@/models/setting/usergroup';
|
||||
import { AuthScopeEnum } from '@/enums/commonEnum';
|
||||
|
@ -48,6 +48,9 @@
|
|||
const props = defineProps<{
|
||||
keyword: string;
|
||||
current: CurrentUserGroupItem;
|
||||
deletePermission?: string[];
|
||||
readPermission?: string[];
|
||||
updatePermission?: string[];
|
||||
}>();
|
||||
|
||||
const userSelectorProps = computed(() => {
|
||||
|
@ -112,11 +115,21 @@
|
|||
heightUsed: 288,
|
||||
});
|
||||
|
||||
const handlePermission = (permission: string[], cb: () => void) => {
|
||||
if (!hasAnyPermission(permission)) {
|
||||
Message.error(t('common.noPermission'));
|
||||
return false;
|
||||
}
|
||||
cb();
|
||||
};
|
||||
const fetchData = async () => {
|
||||
handlePermission(props.readPermission || [], async () => {
|
||||
setKeyword(props.keyword);
|
||||
await loadList();
|
||||
});
|
||||
};
|
||||
const handleRemove = async (record: UserTableItem) => {
|
||||
handlePermission(props.deletePermission || [], async () => {
|
||||
try {
|
||||
if (systemType === AuthScopeEnum.SYSTEM) {
|
||||
await deleteUserFromUserGroup(record.id);
|
||||
|
@ -132,6 +145,7 @@
|
|||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -59,10 +59,22 @@
|
|||
<a-button :disabled="props.okLoading" @click="handleCancel">
|
||||
{{ t(props.cancelText || 'ms.drawer.cancel') }}
|
||||
</a-button>
|
||||
<a-button v-if="showContinue" type="secondary" :loading="props.okLoading" @click="handleContinue">
|
||||
<a-button
|
||||
v-if="showContinue"
|
||||
v-permission="props.okPermission || []"
|
||||
type="secondary"
|
||||
:loading="props.okLoading"
|
||||
@click="handleContinue"
|
||||
>
|
||||
{{ t(props.saveContinueText || 'ms.drawer.saveContinue') }}
|
||||
</a-button>
|
||||
<a-button type="primary" :disabled="okDisabled" :loading="props.okLoading" @click="handleOk">
|
||||
<a-button
|
||||
v-permission="props.okPermission || []"
|
||||
type="primary"
|
||||
:disabled="okDisabled"
|
||||
:loading="props.okLoading"
|
||||
@click="handleOk"
|
||||
>
|
||||
{{ t(props.okText || 'ms.drawer.ok') }}
|
||||
</a-button>
|
||||
</div>
|
||||
|
@ -93,6 +105,7 @@
|
|||
showSkeleton?: boolean; // 是否显示骨架屏
|
||||
okLoading?: boolean;
|
||||
okDisabled?: boolean;
|
||||
okPermission?: string[]; // 确认按钮权限
|
||||
okText?: string;
|
||||
cancelText?: string;
|
||||
saveContinueText?: string;
|
||||
|
@ -110,6 +123,7 @@
|
|||
showContinue: false,
|
||||
popupContainer: 'body',
|
||||
disabledWidthDrag: false,
|
||||
okPermission: () => [], // 确认按钮权限
|
||||
});
|
||||
const emit = defineEmits(['update:visible', 'confirm', 'cancel', 'continue']);
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
<a-doption
|
||||
v-else
|
||||
:key="item.label"
|
||||
v-permission="item.permission || []"
|
||||
:class="item.danger ? 'error-6' : ''"
|
||||
:disabled="item.disabled"
|
||||
:value="item.eventTag"
|
||||
|
|
|
@ -5,6 +5,7 @@ export interface ActionsItem {
|
|||
danger?: boolean; // 是否危险操作,true 的话会显示红色按钮
|
||||
disabled?: boolean; // 是否禁用
|
||||
icon?: string; // 按钮图标
|
||||
permission?: string[]; // 权限标识
|
||||
}
|
||||
|
||||
export type SelectedValue = string | number | Record<string, any> | undefined;
|
||||
|
|
|
@ -75,7 +75,6 @@
|
|||
@show-setting="handleShowSetting"
|
||||
@init-data="handleInitColumn"
|
||||
/>
|
||||
|
||||
<slot v-else-if="item.filterConfig" :name="item.filterConfig.filterSlotName">
|
||||
<DefaultFilter
|
||||
class="ml-[4px]"
|
||||
|
@ -541,9 +540,6 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
:deep(.arco-table-th-title) {
|
||||
width: 100%;
|
||||
}
|
||||
.setting-icon {
|
||||
margin-left: 16px;
|
||||
color: var(--color-text-4);
|
||||
|
|
|
@ -103,6 +103,7 @@ export interface MsTableProps<T> {
|
|||
emptyDataShowLine?: boolean; // 空数据是否显示 "-"
|
||||
showJumpMethod?: boolean; // 是否展示跳转方法
|
||||
isSimpleSetting?: boolean; // 是否是简单的设置
|
||||
filterIconAlignLeft?: boolean; // 筛选图标是否靠左
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ export default function useTableProps<T>(
|
|||
showJumpMethod: false, // 是否显示跳转方法
|
||||
showFooterActionWrap: false, // 是否显示底部操作区域
|
||||
isSimpleSetting: false, // 是否是简易column设置
|
||||
filterIconAlignLeft: true, // 筛选图标是否靠左
|
||||
...props,
|
||||
};
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
:min="0"
|
||||
hide-button
|
||||
size="small"
|
||||
:disabled="props.disabled"
|
||||
@press-enter="handleEnter(false)"
|
||||
@blur="handleEnter(true)"
|
||||
>
|
||||
|
@ -14,6 +15,7 @@
|
|||
v-model:model-value="current.type"
|
||||
size="small"
|
||||
class="max-w-[64px]"
|
||||
:disabled="props.disabled"
|
||||
:options="option"
|
||||
:trigger-props="{ autoFitPopupMinWidth: true }"
|
||||
@change="handleEnter(false)"
|
||||
|
@ -28,7 +30,7 @@
|
|||
|
||||
const { t } = useI18n();
|
||||
|
||||
const props = defineProps<{ modelValue?: string; defaultValue?: string }>();
|
||||
const props = defineProps<{ modelValue?: string; defaultValue?: string; disabled?: boolean }>();
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: string): void;
|
||||
(e: 'change', value: string): void;
|
||||
|
|
|
@ -101,4 +101,5 @@ export default {
|
|||
'common.noProject': 'No project, please contact the administrator',
|
||||
'common.noResource': 'No resource, please contact the administrator',
|
||||
'common.noSelectProject': 'No optional items available',
|
||||
'common.noPermission': 'No permission',
|
||||
};
|
||||
|
|
|
@ -104,4 +104,5 @@ export default {
|
|||
'common.noProject': '暂无项目权限,请联系管理员',
|
||||
'common.noResource': '暂无资源权限,请联系管理员',
|
||||
'common.noSelectProject': '无可选项目',
|
||||
'common.noPermission': '无权限',
|
||||
};
|
||||
|
|
|
@ -44,7 +44,15 @@ const ProjectManagement: AppRouteRecordRaw = {
|
|||
component: () => import('@/views/project-management/projectAndPermission/menuManagement/menuManagement.vue'),
|
||||
meta: {
|
||||
locale: 'project.permission.menuManagement',
|
||||
roles: ['PROJECT_APPLICATION_WORKSTATION:READ'],
|
||||
roles: [
|
||||
'PROJECT_APPLICATION_WORKSTATION:READ',
|
||||
'PROJECT_APPLICATION_TEST_PLAN:READ',
|
||||
'PROJECT_APPLICATION_BUG:READ',
|
||||
'PROJECT_APPLICATION_CASE:READ',
|
||||
'PROJECT_APPLICATION_API:READ',
|
||||
'PROJECT_APPLICATION_UI:READ',
|
||||
'PROJECT_APPLICATION_PERFORMANCE_TEST:READ',
|
||||
],
|
||||
},
|
||||
},
|
||||
// 项目版本
|
||||
|
@ -250,7 +258,7 @@ const ProjectManagement: AppRouteRecordRaw = {
|
|||
import('@/views/project-management/projectAndPermission/menuManagement/components/falseAlermRule.vue'),
|
||||
meta: {
|
||||
locale: 'project.menu.API_ERROR_REPORT_RULE',
|
||||
roles: ['*'],
|
||||
roles: ['PROJECT_APPLICATION_API:READ'],
|
||||
breadcrumbs: [
|
||||
{
|
||||
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_MENU_MANAGEMENT,
|
||||
|
|
|
@ -44,7 +44,7 @@ const Setting: AppRouteRecordRaw = {
|
|||
component: () => import('@/views/setting/system/usergroup/systemUserGroup.vue'),
|
||||
meta: {
|
||||
locale: 'menu.settings.system.usergroup',
|
||||
roles: ['*'],
|
||||
roles: ['SYSTEM_USER_ROLE:READ'],
|
||||
isTopMenu: true,
|
||||
},
|
||||
},
|
||||
|
@ -158,7 +158,7 @@ const Setting: AppRouteRecordRaw = {
|
|||
component: () => import('@/views/setting/organization/usergroup/orgUserGroup.vue'),
|
||||
meta: {
|
||||
locale: 'menu.settings.organization.userGroup',
|
||||
roles: ['*'],
|
||||
roles: ['ORGANIZATION_USER_ROLE:READ'],
|
||||
isTopMenu: true,
|
||||
},
|
||||
},
|
||||
|
@ -168,7 +168,7 @@ const Setting: AppRouteRecordRaw = {
|
|||
component: () => import('@/views/setting/organization/project/orgProject.vue'),
|
||||
meta: {
|
||||
locale: 'menu.settings.organization.project',
|
||||
roles: ['*'],
|
||||
roles: ['ORGANIZATION_PROJECT:READ'],
|
||||
isTopMenu: true,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -24,11 +24,13 @@
|
|||
import MsMenuPanel from '@/components/pure/ms-menu-panel/index.vue';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import usePermission from '@/hooks/usePermission';
|
||||
import useLicenseStore from '@/store/modules/setting/license';
|
||||
|
||||
import { ProjectManagementRouteEnum } from '@/enums/routeEnum';
|
||||
|
||||
const { t } = useI18n();
|
||||
const permission = usePermission();
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
@ -47,7 +49,7 @@
|
|||
}
|
||||
return [];
|
||||
}
|
||||
const menuList = ref([
|
||||
const sourceMenuList = [
|
||||
{
|
||||
key: 'project',
|
||||
title: t('project.permission.project'),
|
||||
|
@ -85,7 +87,18 @@
|
|||
level: 2,
|
||||
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_USER_GROUP,
|
||||
},
|
||||
]);
|
||||
];
|
||||
const menuList = computed(() => {
|
||||
const routerList = router.getRoutes();
|
||||
return sourceMenuList.filter((item) => {
|
||||
if (item.name) {
|
||||
const routerItem = routerList.find((rou) => rou.name === item.name);
|
||||
if (!routerItem) return false;
|
||||
return permission.accessRouter(routerItem);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
});
|
||||
|
||||
const currentKey = ref<string>('');
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
:width="680"
|
||||
:ok-loading="okLoading"
|
||||
:ok-disabled="okDisabled"
|
||||
:ok-permission="['PROJECT_APPLICATION_CASE:READ+UPDATE']"
|
||||
@cancel="handleCancel(false)"
|
||||
@confirm="handleConfirm"
|
||||
>
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="mb-4 flex items-center justify-between">
|
||||
<a-button type="primary" @click="showAddRule(undefined)">{{ t('project.menu.addFalseAlertRules') }}</a-button>
|
||||
<a-button v-permission="['PROJECT_APPLICATION_API:READ+ADD']" type="primary" @click="showAddRule(undefined)">{{
|
||||
t('project.menu.addFalseAlertRules')
|
||||
}}</a-button>
|
||||
<a-input-search
|
||||
v-model="keyword"
|
||||
:placeholder="t('project.menu.nameSearch')"
|
||||
|
@ -24,18 +26,36 @@
|
|||
>
|
||||
<template #operation="{ record }">
|
||||
<template v-if="!record.enable">
|
||||
<MsButton class="!mr-0" @click="handleEnableOrDisableProject(record.id)">{{ t('common.enable') }}</MsButton>
|
||||
<div class="flex flex-row">
|
||||
<span v-permission="['PROJECT_APPLICATION_API:READ+UPDATE']" class="flex flex-row">
|
||||
<MsButton class="!mr-0" @click="handleEnableOrDisableProject(record.id)">{{
|
||||
t('common.enable')
|
||||
}}</MsButton>
|
||||
<a-divider direction="vertical" />
|
||||
<MsButton class="!mr-0" @click="handleDelete(record.id)">{{ t('common.delete') }}</MsButton>
|
||||
</span>
|
||||
<span>
|
||||
<MsButton
|
||||
v-permission="['PROJECT_APPLICATION_API:READ+DELETE']"
|
||||
class="!mr-0"
|
||||
@click="handleDelete(record.id)"
|
||||
>{{ t('common.delete') }}</MsButton
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span v-permission="['PROJECT_APPLICATION_API:READ+UPDATE']" class="flex flex-row">
|
||||
<MsButton class="!mr-0" @click="showAddRule(record)">{{ t('common.edit') }}</MsButton>
|
||||
<a-divider direction="vertical" />
|
||||
</span>
|
||||
<span v-permission="['PROJECT_APPLICATION_API:READ+UPDATE']" class="flex flex-row">
|
||||
<MsButton class="!mr-0" @click="handleEnableOrDisableProject(record.id, false)">{{
|
||||
t('common.disable')
|
||||
}}</MsButton>
|
||||
<a-divider direction="vertical" />
|
||||
</span>
|
||||
<MsTableMoreAction
|
||||
v-permission="['PROJECT_APPLICATION_API:READ+DELETE']"
|
||||
class="!mr-0"
|
||||
:list="tableActions"
|
||||
@select="handleMoreAction($event, record)"
|
||||
|
@ -70,7 +90,7 @@
|
|||
</MsDrawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
<script async lang="ts" setup>
|
||||
import { useRouter } from 'vue-router';
|
||||
import { Message, TableData } from '@arco-design/web-vue';
|
||||
|
||||
|
@ -94,7 +114,7 @@
|
|||
} from '@/api/modules/project-management/menuManagement';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import { useAppStore } from '@/store';
|
||||
import { useAppStore, useTableStore } from '@/store';
|
||||
|
||||
import { FakeTableListItem } from '@/models/projectManagement/menuManagement';
|
||||
import { ProjectManagementRouteEnum } from '@/enums/routeEnum';
|
||||
|
@ -111,6 +131,7 @@
|
|||
const batchFormRef = ref();
|
||||
const ruleFormMode = ref<UserModalMode>('create');
|
||||
const currentList = ref<FakeTableListItem[]>([]);
|
||||
const tableStore = useTableStore();
|
||||
const headerOptions = computed(() => [
|
||||
{ label: 'Response Headers', value: 'headers' },
|
||||
{ label: 'Response Data', value: 'data' },
|
||||
|
@ -131,15 +152,18 @@
|
|||
{
|
||||
label: 'common.enable',
|
||||
eventTag: 'batchEnable',
|
||||
permission: ['PROJECT_APPLICATION_API:READ+UPDATE'],
|
||||
},
|
||||
{
|
||||
label: 'common.disable',
|
||||
eventTag: 'batchDisable',
|
||||
permission: ['PROJECT_APPLICATION_API:READ+UPDATE'],
|
||||
},
|
||||
{
|
||||
label: 'common.delete',
|
||||
eventTag: 'batchDelete',
|
||||
danger: true,
|
||||
permission: ['PROJECT_APPLICATION_API:READ+UPDATE'],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
@ -196,17 +220,16 @@
|
|||
width: 169,
|
||||
},
|
||||
];
|
||||
|
||||
await tableStore.initColumn(TableKeyEnum.PROJECT_MANAGEMENT_MENU_FALSE_ALERT, rulesColumn, 'drawer');
|
||||
const { propsRes, propsEvent, loadList, setKeyword, setLoadListParams, resetSelector } = useTable(
|
||||
postFakeTableList,
|
||||
{
|
||||
scroll: { x: 1200 },
|
||||
columns: rulesColumn,
|
||||
tableKey: TableKeyEnum.PROJECT_MANAGEMENT_MENU_FALSE_ALERT,
|
||||
selectable: true,
|
||||
noDisable: false,
|
||||
size: 'default',
|
||||
debug: true,
|
||||
showSetting: true,
|
||||
},
|
||||
(record: TableData) => {
|
||||
record.typeList = record.type ? record.type.split(',') : [];
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
:width="680"
|
||||
:ok-loading="okLoading"
|
||||
:ok-disabled="okDisabled"
|
||||
:ok-permission="['PROJECT_APPLICATION_CASE:READ+UPDATE']"
|
||||
@cancel="handleCancel(false)"
|
||||
@confirm="handleConfirm"
|
||||
>
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<!-- 测试计划 报告保留时间范围 -->
|
||||
<MsTimeSelectorVue
|
||||
v-model="allValueMap['TEST_PLAN_CLEAN_REPORT']"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_TEST_PLAN:READ+UPDATE'])"
|
||||
@change="(v: string) => handleMenuStatusChange('TEST_PLAN_CLEAN_REPORT',v,MenuEnum.testPlan)"
|
||||
/>
|
||||
</div>
|
||||
|
@ -40,15 +41,19 @@
|
|||
<!-- 测试计划 报告链接有效期 -->
|
||||
<MsTimeSelectorVue
|
||||
v-model="allValueMap['TEST_PLAN_SHARE_REPORT']"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_TEST_PLAN:READ+UPDATE'])"
|
||||
@change="(v: string) => handleMenuStatusChange('TEST_PLAN_SHARE_REPORT',v,MenuEnum.testPlan)"
|
||||
/>
|
||||
</div>
|
||||
<template v-if="record.type === 'BUG_SYNC'">
|
||||
<!-- 同步缺陷 -->
|
||||
<span>{{ t('project.menu.row2') }}</span>
|
||||
<div class="ml-[8px] cursor-pointer text-[rgb(var(--primary-7))]" @click="showDefectDrawer">{{
|
||||
t('project.menu.BUG_SYNC')
|
||||
}}</div>
|
||||
<div
|
||||
v-permission="['PROJECT_APPLICATION_BUG:READ+UPDATE']"
|
||||
class="ml-[8px] cursor-pointer text-[rgb(var(--primary-7))]"
|
||||
@click="showDefectDrawer"
|
||||
>{{ t('project.menu.BUG_SYNC') }}</div
|
||||
>
|
||||
</template>
|
||||
<div v-if="record.type === 'CASE_PUBLIC'">
|
||||
<!-- 用例 公共用例库 -->
|
||||
|
@ -57,9 +62,12 @@
|
|||
<div v-if="record.type === 'CASE_RELATED'" class="flex flex-row">
|
||||
<!-- 用例 关联需求 -->
|
||||
<div>{{ t('project.menu.row4') }}</div>
|
||||
<div class="ml-[8px] cursor-pointer text-[rgb(var(--primary-7))]" @click="showRelatedCaseDrawer">{{
|
||||
t('project.menu.CASE_RELATED')
|
||||
}}</div>
|
||||
<div
|
||||
v-permission="['PROJECT_APPLICATION_CASE:READ+UPDATE']"
|
||||
class="ml-[8px] cursor-pointer text-[rgb(var(--primary-7))]"
|
||||
@click="showRelatedCaseDrawer"
|
||||
>{{ t('project.menu.CASE_RELATED') }}</div
|
||||
>
|
||||
</div>
|
||||
<div v-if="record.type === 'CASE_RE_REVIEW'">
|
||||
<!-- 用例 重新提审 -->
|
||||
|
@ -72,6 +80,7 @@
|
|||
<div v-if="record.type === 'API_CLEAN_REPORT'">
|
||||
<MsTimeSelectorVue
|
||||
v-model="allValueMap['API_CLEAN_REPORT']"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_API:READ+UPDATE'])"
|
||||
@change="(v: string) => handleMenuStatusChange('API_CLEAN_REPORT',v,MenuEnum.apiTest)"
|
||||
/>
|
||||
</div>
|
||||
|
@ -79,6 +88,7 @@
|
|||
<!--接口测试 报告链接有效期 -->
|
||||
<MsTimeSelectorVue
|
||||
v-model="allValueMap['API_SHARE_REPORT']"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_API:READ+UPDATE'])"
|
||||
@change="(v: string) => handleMenuStatusChange('API_SHARE_REPORT',v,MenuEnum.apiTest)"
|
||||
/>
|
||||
</div>
|
||||
|
@ -89,6 +99,7 @@
|
|||
:field-names="{ label: 'name', value: 'id' }"
|
||||
:options="apiPoolOption"
|
||||
class="w-[120px]"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_API:READ+UPDATE'])"
|
||||
@change="(v: SelectValue) => handleMenuStatusChange('API_RESOURCE_POOL_ID',v as string,MenuEnum.apiTest)"
|
||||
/>
|
||||
<a-tooltip
|
||||
|
@ -110,6 +121,7 @@
|
|||
v-model="allValueMap['API_SCRIPT_REVIEWER_ID']"
|
||||
:field-names="{ label: 'name', value: 'id' }"
|
||||
:options="apiAuditorOption"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_API:READ+UPDATE'])"
|
||||
class="w-[120px]"
|
||||
@change="(v: SelectValue) => handleMenuStatusChange('API_SCRIPT_REVIEWER_ID',v as string,MenuEnum.apiTest)"
|
||||
/>
|
||||
|
@ -133,9 +145,12 @@
|
|||
</template>
|
||||
</a-input-number>
|
||||
</div>
|
||||
<div class="ml-[8px] cursor-pointer text-[rgb(var(--primary-7))]" @click="pushFar">{{
|
||||
t('project.menu.API_ERROR_REPORT_RULE')
|
||||
}}</div>
|
||||
<div
|
||||
v-permission="['PROJECT_APPLICATION_API:READ+UPDATE']"
|
||||
class="ml-[8px] cursor-pointer text-[rgb(var(--primary-7))]"
|
||||
@click="pushFar"
|
||||
>{{ t('project.menu.API_ERROR_REPORT_RULE') }}</div
|
||||
>
|
||||
<a-tooltip :content="t('project.menu.API_ERROR_REPORT_RULE_TIP')" position="right">
|
||||
<div>
|
||||
<MsIcon class="ml-[4px] text-[rgb(var(--primary-5))]" type="icon-icon-maybe_outlined" />
|
||||
|
@ -147,6 +162,7 @@
|
|||
<!--UI 报告保留时间范围 -->
|
||||
<MsTimeSelectorVue
|
||||
v-model="allValueMap['UI_CLEAN_REPORT']"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_UI:READ+UPDATE'])"
|
||||
@change="(v: string) => handleMenuStatusChange('UI_CLEAN_REPORT',v,MenuEnum.uiTest)"
|
||||
/>
|
||||
</div>
|
||||
|
@ -154,6 +170,7 @@
|
|||
<!--UI 报告链接有效期 -->
|
||||
<MsTimeSelectorVue
|
||||
v-model="allValueMap['UI_SHARE_REPORT']"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_UI:READ+UPDATE'])"
|
||||
@change="(v: string) => handleMenuStatusChange('UI_SHARE_REPORT',v,MenuEnum.uiTest)"
|
||||
/>
|
||||
</div>
|
||||
|
@ -164,6 +181,7 @@
|
|||
:field-names="{ label: 'name', value: 'id' }"
|
||||
:options="uiPoolOption"
|
||||
class="w-[120px]"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_UI:READ+UPDATE'])"
|
||||
@change="(v: SelectValue) => handleMenuStatusChange('UI_RESOURCE_POOL_ID',v as string,MenuEnum.uiTest)"
|
||||
/>
|
||||
<a-tooltip
|
||||
|
@ -183,6 +201,7 @@
|
|||
<!--性能测试 报告保留时间范围 -->
|
||||
<MsTimeSelectorVue
|
||||
v-model="allValueMap['PERFORMANCE_TEST_CLEAN_REPORT']"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_PERFORMANCE_TEST:READ+UPDATE'])"
|
||||
@change="(v: string) => handleMenuStatusChange('PERFORMANCE_TEST_CLEAN_REPORT',v,MenuEnum.loadTest)"
|
||||
/>
|
||||
</div>
|
||||
|
@ -190,6 +209,7 @@
|
|||
<!--性能测试 报告链接有效期 -->
|
||||
<MsTimeSelectorVue
|
||||
v-model="allValueMap['PERFORMANCE_TEST_SHARE_REPORT']"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_PERFORMANCE_TEST:READ+UPDATE'])"
|
||||
@change="(v: string) => handleMenuStatusChange('PERFORMANCE_TEST_SHARE_REPORT',v,MenuEnum.loadTest)"
|
||||
/>
|
||||
</div>
|
||||
|
@ -200,6 +220,7 @@
|
|||
:field-names="{ label: 'name', value: 'id' }"
|
||||
:options="performanceAuditorOption"
|
||||
class="w-[120px]"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_PERFORMANCE_TEST:READ+UPDATE'])"
|
||||
@change="(v: SelectValue) => handleMenuStatusChange('PERFORMANCE_TEST_SCRIPT_REVIEWER_ID',v as string,MenuEnum.loadTest)"
|
||||
/>
|
||||
<a-tooltip :content="t('project.menu.PERFORMANCE_TEST_SCRIPT_REVIEWER_TIP')" position="right">
|
||||
|
@ -210,8 +231,12 @@
|
|||
</div>
|
||||
</template>
|
||||
<template #operation="{ record }">
|
||||
<!-- 同步缺陷状态 -->
|
||||
<a-tooltip v-if="record.type === 'BUG_SYNC' && !allValueMap['BUG_SYNC_SYNC_ENABLE']" position="tr">
|
||||
<!-- 用例 同步缺陷状态 -->
|
||||
<a-tooltip
|
||||
v-if="record.type === 'BUG_SYNC' && !allValueMap['BUG_SYNC_SYNC_ENABLE']"
|
||||
v-permission="['PROJECT_APPLICATION_BUG:READ+UPDATE']"
|
||||
position="tr"
|
||||
>
|
||||
<template #content>
|
||||
<span>
|
||||
{{ t('project.menu.notConfig') }}
|
||||
|
@ -224,6 +249,7 @@
|
|||
<a-switch
|
||||
checked-value="true"
|
||||
unchecked-value="false"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_BUG:READ+UPDATE'])"
|
||||
:value="allValueMap['BUG_SYNC_SYNC_ENABLE']"
|
||||
size="small"
|
||||
type="line"
|
||||
|
@ -234,12 +260,17 @@
|
|||
v-if="record.type === 'BUG_SYNC' && allValueMap['BUG_SYNC_SYNC_ENABLE']"
|
||||
checked-value="true"
|
||||
unchecked-value="false"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_BUG:READ+UPDATE'])"
|
||||
size="small"
|
||||
type="line"
|
||||
@change="(v: boolean | string| number) => handleMenuStatusChange('BUG_SYNC_SYNC_ENABLE',v as boolean, MenuEnum.bugManagement)"
|
||||
/>
|
||||
<!-- 关联需求状态 -->
|
||||
<a-tooltip v-if="record.type === 'CASE_RELATED' && !allValueMap['CASE_RELATED_CASE_ENABLE']" position="tr">
|
||||
<!-- 功能测试 同步缺陷 -->
|
||||
<a-tooltip
|
||||
v-if="record.type === 'CASE_RELATED' && !allValueMap['CASE_RELATED_CASE_ENABLE']"
|
||||
v-permission="['PROJECT_APPLICATION_BUG:READ+UPDATE']"
|
||||
position="tr"
|
||||
>
|
||||
<template #content>
|
||||
<span>
|
||||
{{ t('project.menu.notConfig') }}
|
||||
|
@ -252,6 +283,7 @@
|
|||
<a-switch
|
||||
checked-value="true"
|
||||
unchecked-value="false"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_CASE:READ+UPDATE'])"
|
||||
:value="allValueMap['CASE_RELATED_CASE_ENABLE']"
|
||||
size="small"
|
||||
type="line"
|
||||
|
@ -260,6 +292,7 @@
|
|||
</a-tooltip>
|
||||
<a-switch
|
||||
v-if="record.type === 'CASE_RELATED' && allValueMap['CASE_RELATED_CASE_ENABLE']"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_BUG:READ+UPDATE'])"
|
||||
checked-value="true"
|
||||
unchecked-value="false"
|
||||
size="small"
|
||||
|
@ -271,6 +304,7 @@
|
|||
<a-switch
|
||||
v-if="record.type === 'WORKSTATION_SYNC_RULE'"
|
||||
v-model="allValueMap['WORKSTATION_SYNC_RULE']"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_API:READ+UPDATE'])"
|
||||
checked-value="true"
|
||||
unchecked-value="false"
|
||||
size="small"
|
||||
|
@ -281,6 +315,7 @@
|
|||
<a-switch
|
||||
v-if="record.type === 'CASE_PUBLIC'"
|
||||
v-model="allValueMap['CASE_PUBLIC']"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_CASE:READ+UPDATE'])"
|
||||
checked-value="true"
|
||||
unchecked-value="false"
|
||||
size="small"
|
||||
|
@ -291,6 +326,7 @@
|
|||
<a-switch
|
||||
v-if="record.type === 'CASE_RE_REVIEW'"
|
||||
v-model="allValueMap['CASE_RE_REVIEW']"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_CASE:READ+UPDATE'])"
|
||||
checked-value="true"
|
||||
unchecked-value="false"
|
||||
size="small"
|
||||
|
@ -301,6 +337,7 @@
|
|||
<a-switch
|
||||
v-if="record.type === 'API_URL_REPEATABLE'"
|
||||
v-model="allValueMap['API_URL_REPEATABLE']"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_API:READ+UPDATE'])"
|
||||
checked-value="true"
|
||||
unchecked-value="false"
|
||||
size="small"
|
||||
|
@ -311,6 +348,7 @@
|
|||
<a-switch
|
||||
v-if="record.type === 'API_SYNC_CASE'"
|
||||
v-model="allValueMap['API_SYNC_CASE']"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_API:READ+UPDATE'])"
|
||||
checked-value="true"
|
||||
unchecked-value="false"
|
||||
size="small"
|
||||
|
@ -321,6 +359,7 @@
|
|||
<a-switch
|
||||
v-if="record.type === 'PERFORMANCE_TEST_SCRIPT_REVIEWER'"
|
||||
v-model="allValueMap['PERFORMANCE_TEST_SCRIPT_REVIEWER_ENABLE']"
|
||||
:disabled="!hasAnyPermission(['PROJECT_APPLICATION_PERFORMANCE_TEST:READ+UPDATE'])"
|
||||
checked-value="true"
|
||||
unchecked-value="false"
|
||||
size="small"
|
||||
|
@ -356,6 +395,7 @@
|
|||
} from '@/api/modules/project-management/menuManagement';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { useAppStore } from '@/store';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { MenuTableConfigItem, PoolOption, SelectValue } from '@/models/projectManagement/menuManagement';
|
||||
import { MenuEnum } from '@/enums/commonEnum';
|
||||
|
@ -562,6 +602,52 @@
|
|||
|
||||
const getMenuConfig = async (type: string) => {
|
||||
try {
|
||||
let hasAuth = false;
|
||||
switch (type) {
|
||||
case MenuEnum.workstation:
|
||||
if (hasAnyPermission(['PROJECT_APPLICATION_WORKSTATION:READ'])) {
|
||||
hasAuth = true;
|
||||
}
|
||||
break;
|
||||
case MenuEnum.apiTest:
|
||||
if (hasAnyPermission(['PROJECT_APPLICATION_API:READ'])) {
|
||||
hasAuth = true;
|
||||
}
|
||||
break;
|
||||
case MenuEnum.bugManagement:
|
||||
if (hasAnyPermission(['PROJECT_APPLICATION_BUG:READ'])) {
|
||||
hasAuth = true;
|
||||
}
|
||||
break;
|
||||
case MenuEnum.caseManagement:
|
||||
if (hasAnyPermission(['PROJECT_APPLICATION_CASE:READ'])) {
|
||||
hasAuth = true;
|
||||
}
|
||||
break;
|
||||
case 'loadTest':
|
||||
if (hasAnyPermission(['PROJECT_APPLICATION_PERFORMANCE_TEST:READ'])) {
|
||||
hasAuth = true;
|
||||
}
|
||||
break;
|
||||
case MenuEnum.testPlan:
|
||||
if (hasAnyPermission(['PROJECT_APPLICATION_TEST_PLAN:READ'])) {
|
||||
hasAuth = true;
|
||||
}
|
||||
break;
|
||||
case MenuEnum.uiTest:
|
||||
if (hasAnyPermission(['PROJECT_APPLICATION_UI:READ'])) {
|
||||
hasAuth = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hasAuth) {
|
||||
Message.error(t('common.noPermission'));
|
||||
return;
|
||||
}
|
||||
|
||||
const resultObj = await getConfigByMenuItem({
|
||||
projectId: currentProjectId.value,
|
||||
type,
|
||||
|
@ -584,14 +670,11 @@
|
|||
getMenuConfig(record.module);
|
||||
if (record.module === MenuEnum.apiTest && !apiPoolOption.value.length) {
|
||||
apiPoolOption.value = await getPoolOptions(currentProjectId.value, record.module);
|
||||
}
|
||||
if (record.module === MenuEnum.uiTest && !uiPoolOption.value.length) {
|
||||
} else if (record.module === MenuEnum.uiTest && !uiPoolOption.value.length) {
|
||||
uiPoolOption.value = await getPoolOptions(currentProjectId.value, record.module);
|
||||
}
|
||||
if (record.module === MenuEnum.apiTest && !apiAuditorOption.value.length) {
|
||||
} else if (record.module === MenuEnum.apiTest && !apiAuditorOption.value.length) {
|
||||
apiAuditorOption.value = await getAuditorOptions(currentProjectId.value, record.module);
|
||||
}
|
||||
if (record.module === MenuEnum.loadTest && !performanceAuditorOption.value.length) {
|
||||
} else if (record.module === MenuEnum.loadTest && !performanceAuditorOption.value.length) {
|
||||
performanceAuditorOption.value = await getAuditorOptions(currentProjectId.value, record.module);
|
||||
}
|
||||
} catch (e) {
|
||||
|
@ -620,6 +703,53 @@
|
|||
|
||||
const handleMenuStatusChange = async (type: string, typeValue: string | boolean, suffix: string) => {
|
||||
try {
|
||||
let hasAuth = false;
|
||||
switch (suffix) {
|
||||
case MenuEnum.workstation:
|
||||
if (hasAnyPermission(['PROJECT_APPLICATION_WORKSTATION:READ+UPDATE'])) {
|
||||
hasAuth = true;
|
||||
}
|
||||
break;
|
||||
case MenuEnum.apiTest:
|
||||
if (hasAnyPermission(['PROJECT_APPLICATION_API:READ+UPDATE'])) {
|
||||
hasAuth = true;
|
||||
}
|
||||
break;
|
||||
case MenuEnum.bugManagement:
|
||||
if (hasAnyPermission(['PROJECT_APPLICATION_BUG:READ+UPDATE'])) {
|
||||
hasAuth = true;
|
||||
}
|
||||
break;
|
||||
case MenuEnum.caseManagement:
|
||||
if (hasAnyPermission(['PROJECT_APPLICATION_CASE:READ+UPDATE'])) {
|
||||
hasAuth = true;
|
||||
}
|
||||
break;
|
||||
case MenuEnum.loadTest:
|
||||
if (hasAnyPermission(['PROJECT_APPLICATION_PERFORMANCE_TEST:READ+UPDATE'])) {
|
||||
hasAuth = true;
|
||||
}
|
||||
break;
|
||||
case MenuEnum.testPlan:
|
||||
if (hasAnyPermission(['PROJECT_APPLICATION_TEST_PLAN:READ+UPDATE'])) {
|
||||
hasAuth = true;
|
||||
}
|
||||
break;
|
||||
case MenuEnum.uiTest:
|
||||
if (hasAnyPermission(['PROJECT_APPLICATION_UI:READ+UPDATE'])) {
|
||||
hasAuth = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('no ');
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hasAuth) {
|
||||
Message.error(t('common.noPermission'));
|
||||
return;
|
||||
}
|
||||
await postUpdateMenu(
|
||||
{
|
||||
projectId: currentProjectId.value,
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<template>
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<a-button type="primary" @click="addUserGroup">{{ t('project.userGroup.add') }}</a-button>
|
||||
<a-button v-permission="['PROJECT_GROUP:READ+ADD']" type="primary" @click="addUserGroup">{{
|
||||
t('project.userGroup.add')
|
||||
}}</a-button>
|
||||
<a-input-search
|
||||
v-model="keyword"
|
||||
:placeholder="t('project.userGroup.searchUser')"
|
||||
|
@ -61,9 +63,14 @@
|
|||
<ms-button class="btn" :disabled="!canSave" @click="handleAuthReset">{{
|
||||
t('system.userGroup.reset')
|
||||
}}</ms-button>
|
||||
<a-button class="btn" :disabled="!canSave" type="primary" @click="handleAuthSave">{{
|
||||
t('common.save')
|
||||
}}</a-button>
|
||||
<a-button
|
||||
v-permission="['PROJECT_GROUP:READ+UPDATE']"
|
||||
class="btn"
|
||||
:disabled="!canSave"
|
||||
type="primary"
|
||||
@click="handleAuthSave"
|
||||
>{{ t('common.save') }}</a-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</MsDrawer>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<MsCard simple>
|
||||
<div class="mb-4 flex items-center justify-between">
|
||||
<div class="mb-[16px] flex items-center justify-between">
|
||||
<a-button type="primary" @click="showAddProject">{{ t('system.organization.createProject') }}</a-button>
|
||||
<a-input-search
|
||||
v-model="keyword"
|
||||
|
@ -31,17 +31,35 @@
|
|||
</template>
|
||||
<template #operation="{ record }">
|
||||
<template v-if="record.deleted">
|
||||
<MsButton @click="handleRevokeDelete(record)">{{ t('common.revokeDelete') }}</MsButton>
|
||||
<MsButton v-permission="['ORGANIZATION_PROJECT:READ+RECOVER']" @click="handleRevokeDelete(record)">{{
|
||||
t('common.revokeDelete')
|
||||
}}</MsButton>
|
||||
</template>
|
||||
<template v-else-if="!record.enable">
|
||||
<MsButton @click="handleEnableOrDisableProject(record)">{{ t('common.enable') }}</MsButton>
|
||||
<MsButton @click="handleDelete(record)">{{ t('common.delete') }}</MsButton>
|
||||
<MsButton v-permission="['ORGANIZATION_PROJECT:READ+UPDATE']" @click="handleEnableOrDisableProject(record)">{{
|
||||
t('common.enable')
|
||||
}}</MsButton>
|
||||
<MsButton v-permission="['ORGANIZATION_PROJECT:READ+DELETE']" @click="handleDelete(record)">{{
|
||||
t('common.delete')
|
||||
}}</MsButton>
|
||||
</template>
|
||||
<template v-else>
|
||||
<MsButton @click="showAddProjectModal(record)">{{ t('common.edit') }}</MsButton>
|
||||
<MsButton @click="showAddUserModal(record)">{{ t('system.organization.addMember') }}</MsButton>
|
||||
<MsButton @click="handleEnableOrDisableProject(record, false)">{{ t('common.end') }}</MsButton>
|
||||
<MsTableMoreAction :list="tableActions" @select="handleMoreAction($event, record)"></MsTableMoreAction>
|
||||
<MsButton v-permission="['ORGANIZATION_PROJECT:READ+UPDATE']" @click="showAddProjectModal(record)">{{
|
||||
t('common.edit')
|
||||
}}</MsButton>
|
||||
<MsButton v-permission="['ORGANIZATION_PROJECT:READ+UPDATE']" @click="showAddUserModal(record)">{{
|
||||
t('system.organization.addMember')
|
||||
}}</MsButton>
|
||||
<MsButton
|
||||
v-permission="['ORGANIZATION_PROJECT:READ+UPDATE']"
|
||||
@click="handleEnableOrDisableProject(record, false)"
|
||||
>{{ t('common.end') }}</MsButton
|
||||
>
|
||||
<MsTableMoreAction
|
||||
v-permission="['ORGANIZATION_PROJECT:READ+DELETE']"
|
||||
:list="tableActions"
|
||||
@select="handleMoreAction($event, record)"
|
||||
></MsTableMoreAction>
|
||||
</template>
|
||||
</template>
|
||||
</MsBaseTable>
|
||||
|
@ -177,6 +195,10 @@
|
|||
dataIndex: 'createTime',
|
||||
width: 180,
|
||||
showDrag: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'system.organization.operation',
|
||||
|
@ -205,9 +227,8 @@
|
|||
tableKey: TableKeyEnum.ORGANIZATION_PROJECT,
|
||||
selectable: false,
|
||||
noDisable: false,
|
||||
size: 'default',
|
||||
showSetting: true,
|
||||
heightUsed: 286,
|
||||
heightUsed: 300,
|
||||
},
|
||||
undefined,
|
||||
(record) => handleNameChange(record)
|
||||
|
|
|
@ -36,11 +36,15 @@
|
|||
ref="userRef"
|
||||
:keyword="currentKeyword"
|
||||
:current="currentUserGroupItem"
|
||||
:delete-permission="['ORGANIZATION_USER_ROLE:READ+DELETE']"
|
||||
:read-permission="['ORGANIZATION_USER_ROLE:READ']"
|
||||
:update-permission="['ORGANIZATION_USER_ROLE:READ+UPDATE']"
|
||||
/>
|
||||
<AuthTable
|
||||
v-if="currentTable === 'auth' && couldShowAuth"
|
||||
:current="currentUserGroupItem"
|
||||
:width="bottomWidth"
|
||||
:save-permission="['ORGANIZATION_GROUP:READ+UPDATE']"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -3,8 +3,15 @@
|
|||
<template #revokeDelete="{ record }">
|
||||
<a-tooltip background-color="#FFFFFF">
|
||||
<template #content>
|
||||
<span>
|
||||
<span class="text-[var(--color-text-1)]">{{ t('system.organization.revokeDeleteToolTip') }}</span>
|
||||
<MsButton class="ml-[8px]" @click="handleRevokeDelete(record)">{{ t('common.revokeDelete') }}</MsButton>
|
||||
<MsButton
|
||||
v-permission="['SYSTEM_ORGANIZATION_PROJECT:READ+RECOVER']"
|
||||
class="ml-[8px]"
|
||||
@click="handleRevokeDelete(record)"
|
||||
>{{ t('common.revokeDelete') }}</MsButton
|
||||
>
|
||||
</span>
|
||||
</template>
|
||||
<MsIcon v-if="record.deleted" type="icon-icon_alarm_clock" class="ml-[4px] text-[rgb(var(--danger-6))]" />
|
||||
</a-tooltip>
|
||||
|
@ -93,6 +100,7 @@
|
|||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import { useTableStore } from '@/store';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { CreateOrUpdateSystemOrgParams, OrgProjectTableItem } from '@/models/setting/system/orgAndProject';
|
||||
import { ColumnEditTypeEnum, TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
@ -122,7 +130,7 @@
|
|||
dataIndex: 'name',
|
||||
width: 300,
|
||||
revokeDeletedSlot: 'revokeDelete',
|
||||
editType: ColumnEditTypeEnum.INPUT,
|
||||
editType: hasAnyPermission(['SYSTEM_ORGANIZATIN_PROJECT:READ+UPDATE']) ? ColumnEditTypeEnum.INPUT : undefined,
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
|
|
|
@ -3,8 +3,15 @@
|
|||
<template #revokeDelete="{ record }">
|
||||
<a-tooltip background-color="#FFFFFF">
|
||||
<template #content>
|
||||
<span>
|
||||
<span class="text-[var(--color-text-1)]">{{ t('system.project.revokeDeleteToolTip') }}</span>
|
||||
<MsButton class="ml-[8px]" @click="handleRevokeDelete(record)">{{ t('common.revokeDelete') }}</MsButton>
|
||||
<MsButton
|
||||
v-permission="['SYSTEM_ORGANIZATION_PROJECT:READ+RECOVER']"
|
||||
class="ml-[8px]"
|
||||
@click="handleRevokeDelete(record)"
|
||||
>{{ t('common.revokeDelete') }}</MsButton
|
||||
>
|
||||
</span>
|
||||
</template>
|
||||
<MsIcon v-if="record.deleted" type="icon-icon_alarm_clock" class="ml-[4px] text-[rgb(var(--danger-6))]" />
|
||||
</a-tooltip>
|
||||
|
@ -91,6 +98,7 @@
|
|||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import { useTableStore } from '@/store';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { UserItem } from '@/models/setting/log';
|
||||
import { CreateOrUpdateSystemProjectParams, OrgProjectTableItem } from '@/models/setting/system/orgAndProject';
|
||||
|
@ -120,7 +128,7 @@
|
|||
title: 'system.organization.name',
|
||||
dataIndex: 'name',
|
||||
revokeDeletedSlot: 'revokeDelete',
|
||||
editType: ColumnEditTypeEnum.INPUT,
|
||||
editType: hasAnyPermission(['SYSTEM_ORGANIZATIN_PROJECT:READ+UPDATE']) ? ColumnEditTypeEnum.INPUT : undefined,
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
|
|
|
@ -2,11 +2,16 @@
|
|||
<MsCard simple>
|
||||
<div class="mb-4 flex items-center justify-between">
|
||||
<div>
|
||||
<a-button type="primary" @click="handleAddOrganization">{{
|
||||
<a-button
|
||||
v-permission="['SYSTEM_ORGANIZATION_PROJECT:READ+ADD']"
|
||||
type="primary"
|
||||
@click="handleAddOrganization"
|
||||
>{{
|
||||
currentTable === 'organization'
|
||||
? t('system.organization.createOrganization')
|
||||
: t('system.organization.createProject')
|
||||
}}</a-button>
|
||||
}}</a-button
|
||||
>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<a-input-search
|
||||
|
|
|
@ -36,11 +36,15 @@
|
|||
ref="userRef"
|
||||
:keyword="currentKeyword"
|
||||
:current="currentUserGroupItem"
|
||||
:delete-permission="['SYSTEM_USER_ROLE:READ+DELETE']"
|
||||
:read-permission="['SYSTEM_USER_ROLE:READ']"
|
||||
:update-permission="['SYSTEM_USER_ROLE:READ+UPDATE']"
|
||||
/>
|
||||
<AuthTable
|
||||
v-if="currentTable === 'auth' && couldShowAuth"
|
||||
:current="currentUserGroupItem"
|
||||
:width="bottomWidth"
|
||||
:save-permission="['PROJECT_GROUP:READ+UPDATE']"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue