feat: 批量操作的权限&缺陷管理权限&用户组权限自动勾选查询&解决控制台vite报错
This commit is contained in:
parent
99d294694c
commit
57f3493219
|
@ -76,6 +76,11 @@ export default defineConfig({
|
|||
},
|
||||
define: {
|
||||
'process.env': {},
|
||||
// 定义特性标志
|
||||
'__VUE_OPTIONS_API__': true,
|
||||
'__VUE_PROD_DEVTOOLS__': false,
|
||||
// 设置hydration不匹配详细信息的标志
|
||||
'__VUE_PROD_HYDRATION_MISMATCH_DETAILS__': true,
|
||||
},
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
|
|
|
@ -12,8 +12,13 @@ import type {
|
|||
} from '@/models/projectManagement/environmental';
|
||||
import { OptionsItem } from '@/models/setting/log';
|
||||
|
||||
export function updateOrAddEnv(data: EnvDetailItem) {
|
||||
return MSR.post<EnvDetailItem>({ url: data.id ? envURL.updateEnvUrl : envURL.addEnvUrl, data });
|
||||
export function updateOrAddEnv(data: { request: EnvDetailItem; fileList: FileItem[] }) {
|
||||
return MSR.uploadFile<EnvDetailItem>(
|
||||
{ url: data.request.id ? envURL.updateEnvUrl : envURL.addEnvUrl },
|
||||
data,
|
||||
'',
|
||||
true
|
||||
);
|
||||
}
|
||||
export function listEnv(data: { projectId: string; keyword: string }) {
|
||||
return MSR.post<EnvListItem[]>({ url: envURL.listEnvUrl, data });
|
||||
|
|
|
@ -28,7 +28,10 @@
|
|||
</template>
|
||||
<template #cell="{ record, rowIndex }">
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<a-checkbox-group v-model="record.perChecked" @change="(v) => handleCellAuthChange(v, rowIndex)">
|
||||
<a-checkbox-group
|
||||
:model-value="record.perChecked"
|
||||
@change="(v, e) => handleCellAuthChange(v, rowIndex, record, e)"
|
||||
>
|
||||
<a-checkbox
|
||||
v-for="item in record.permissions"
|
||||
:key="item.id"
|
||||
|
@ -339,9 +342,32 @@
|
|||
handleAllChange();
|
||||
if (!canSave.value) canSave.value = true;
|
||||
};
|
||||
// 当选中某个权限值时判断当前选中的列中有没有read权限
|
||||
const setAutoRead = (record: TableData, currentValue: string) => {
|
||||
if (!record.perChecked.includes(currentValue)) {
|
||||
// 如果当前没有选中则执行自动添加查询权限逻辑
|
||||
// 添加权限值
|
||||
record.perChecked.push(currentValue);
|
||||
const preStr = currentValue.split(':')[0];
|
||||
const postStr = currentValue.split(':')[1];
|
||||
const existRead = record.perChecked.some((item: string) => item.split(':')[1] === 'READ');
|
||||
if (!existRead && postStr !== 'READ') {
|
||||
record.perChecked.push(`${preStr}:READ`);
|
||||
}
|
||||
} else {
|
||||
// 删除权限值
|
||||
record.perChecked.splice(record.perChecked.indexOf(currentValue), 1);
|
||||
}
|
||||
};
|
||||
|
||||
// 表格第三列的复选框change事件
|
||||
const handleCellAuthChange = (values: (string | number | boolean)[], rowIndex: number) => {
|
||||
const handleCellAuthChange = (
|
||||
values: (string | number | boolean)[],
|
||||
rowIndex: number,
|
||||
record: TableData,
|
||||
e: Event
|
||||
) => {
|
||||
setAutoRead(record, (e.target as HTMLInputElement).value);
|
||||
if (!tableData.value) return;
|
||||
const tmpArr = tableData.value;
|
||||
const length = tmpArr[rowIndex].permissions?.length || 0;
|
||||
|
|
|
@ -1,26 +1,28 @@
|
|||
<template>
|
||||
<a-dropdown :trigger="props.trigger || 'hover'" @select="selectHandler" @popup-visible-change="visibleChange">
|
||||
<slot>
|
||||
<MsButton type="text" size="mini" class="more-icon">
|
||||
<MsIcon type="icon-icon_more_outlined" size="16" class="text-[var(--color-text-4)]" />
|
||||
</MsButton>
|
||||
</slot>
|
||||
<template #content>
|
||||
<template v-for="item of props.list">
|
||||
<a-divider v-if="item.isDivider" :key="`${item.label}-divider`" margin="4px" />
|
||||
<a-doption
|
||||
v-else
|
||||
:key="item.label"
|
||||
:class="item.danger ? 'error-6' : ''"
|
||||
:disabled="item.disabled"
|
||||
:value="item.eventTag"
|
||||
>
|
||||
<MsIcon v-if="item.icon" :type="item.icon" />
|
||||
{{ t(item.label || '') }}
|
||||
</a-doption>
|
||||
<span>
|
||||
<a-dropdown :trigger="props.trigger || 'hover'" @select="selectHandler" @popup-visible-change="visibleChange">
|
||||
<slot>
|
||||
<MsButton type="text" size="mini" class="more-icon">
|
||||
<MsIcon type="icon-icon_more_outlined" size="16" class="text-[var(--color-text-4)]" />
|
||||
</MsButton>
|
||||
</slot>
|
||||
<template #content>
|
||||
<template v-for="item of props.list">
|
||||
<a-divider v-if="item.isDivider" :key="`${item.label}-divider`" margin="4px" />
|
||||
<a-doption
|
||||
v-else
|
||||
:key="item.label"
|
||||
:class="item.danger ? 'error-6' : ''"
|
||||
:disabled="item.disabled"
|
||||
:value="item.eventTag"
|
||||
>
|
||||
<MsIcon v-if="item.icon" :type="item.icon" />
|
||||
{{ t(item.label || '') }}
|
||||
</a-doption>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-dropdown>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<template v-for="(element, idx) in baseAction" :key="element.label">
|
||||
<a-divider v-if="element.isDivider" class="divider mx-0 my-[6px]" />
|
||||
<a-button
|
||||
v-if="!element.isDivider && !element.children"
|
||||
v-if="!element.isDivider && !element.children && hasAnyPermission(element.permission as string[])"
|
||||
class="ml-[12px]"
|
||||
:class="{
|
||||
'arco-btn-outline--danger': element.danger,
|
||||
|
@ -15,7 +15,11 @@
|
|||
>{{ t(element.label as string) }}</a-button
|
||||
>
|
||||
<!-- baseAction多菜单选择 -->
|
||||
<a-dropdown v-if="!element.isDivider && element.children" position="tr" @select="handleSelect">
|
||||
<a-dropdown
|
||||
v-if="!element.isDivider && element.children && hasAnyPermission(element.permission as string[])"
|
||||
position="tr"
|
||||
@select="handleSelect"
|
||||
>
|
||||
<a-button
|
||||
class="ml-[12px]"
|
||||
:class="{
|
||||
|
@ -43,7 +47,11 @@
|
|||
<template #content>
|
||||
<template v-for="element in moreAction" :key="element.label">
|
||||
<a-divider v-if="element.isDivider" margin="4px" />
|
||||
<a-doption v-else :value="element" :class="{ delete: element.danger }">
|
||||
<a-doption
|
||||
v-else-if="hasAnyPermission(element.permission as string[])"
|
||||
:value="element"
|
||||
:class="{ delete: element.danger }"
|
||||
>
|
||||
{{ t(element.label as string) }}
|
||||
</a-doption>
|
||||
</template>
|
||||
|
@ -59,6 +67,7 @@
|
|||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { getNodeWidth } from '@/utils/dom';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { BatchActionConfig, BatchActionParams } from './type';
|
||||
import ResizeObserver from 'resize-observer-polyfill';
|
||||
|
|
|
@ -127,6 +127,7 @@ export interface BatchActionParams {
|
|||
isDivider?: boolean;
|
||||
danger?: boolean;
|
||||
children?: BatchActionParams[];
|
||||
permission?: string[];
|
||||
}
|
||||
export interface BatchActionConfig {
|
||||
baseAction: BatchActionParams[];
|
||||
|
|
|
@ -22,7 +22,7 @@ const BugManagement: AppRouteRecordRaw = {
|
|||
component: () => import('@/views/bug-management/index.vue'),
|
||||
meta: {
|
||||
locale: 'bugManagement.index',
|
||||
roles: ['*'],
|
||||
roles: ['PROJECT_BUG:READ'],
|
||||
isTopMenu: true,
|
||||
},
|
||||
},
|
||||
|
@ -33,7 +33,7 @@ const BugManagement: AppRouteRecordRaw = {
|
|||
component: () => import('@/views/bug-management/edit.vue'),
|
||||
meta: {
|
||||
locale: 'bugManagement.editBug',
|
||||
roles: ['*'],
|
||||
roles: ['PROJECT_BUG:READ+ADD', 'PROJECT_BUG:READ+UPDATE'],
|
||||
breadcrumbs: [
|
||||
{
|
||||
name: BugManagementRouteEnum.BUG_MANAGEMENT_INDEX,
|
||||
|
@ -54,7 +54,7 @@ const BugManagement: AppRouteRecordRaw = {
|
|||
component: () => import('@/views/bug-management/recycle.vue'),
|
||||
meta: {
|
||||
locale: 'bugManagement.recycle',
|
||||
roles: ['*'],
|
||||
roles: ['PROJECT_BUG:READ'],
|
||||
isTopMenu: true,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -22,6 +22,9 @@ export function hasPermission(permission: string, typeList: string[]) {
|
|||
|
||||
// 判断是否有权限
|
||||
export function hasAnyPermission(permissions: string[], typeList = ['PROJECT', 'ORGANIZATION', 'SYSTEM']) {
|
||||
if (!permissions || permissions.length === 0) {
|
||||
return true;
|
||||
}
|
||||
return permissions.some((permission) => hasPermission(permission, typeList));
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,6 @@
|
|||
const router = useRouter();
|
||||
const back = () => {
|
||||
// warning: Go to the node that has the permission
|
||||
router.push({ name: 'workbench' });
|
||||
router.push({ name: 'workstation' });
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -8,8 +8,14 @@
|
|||
>
|
||||
<template #left>
|
||||
<div class="flex gap-[12px]">
|
||||
<a-button type="primary" @click="handleCreate">{{ t('bugManagement.createBug') }} </a-button>
|
||||
<a-button :disabled="syncBugLoading" type="outline" @click="handleSync"
|
||||
<a-button v-permission="['PROJECT_BUG:READ+ADD']" type="primary" @click="handleCreate"
|
||||
>{{ t('bugManagement.createBug') }}
|
||||
</a-button>
|
||||
<a-button
|
||||
v-permission="['PROJECT_BUG:READ+IMPORT']"
|
||||
:disabled="syncBugLoading"
|
||||
type="outline"
|
||||
@click="handleSync"
|
||||
>{{ t('bugManagement.syncBug') }}
|
||||
</a-button>
|
||||
</div>
|
||||
|
@ -40,11 +46,20 @@
|
|||
</template>
|
||||
<template #operation="{ record }">
|
||||
<div class="flex flex-row flex-nowrap">
|
||||
<MsButton class="!mr-0" @click="handleCopy(record)">{{ t('common.copy') }}</MsButton>
|
||||
<a-divider direction="vertical" />
|
||||
<MsButton class="!mr-0" @click="handleEdit(record)">{{ t('common.edit') }}</MsButton>
|
||||
<a-divider direction="vertical" />
|
||||
<MsTableMoreAction :list="moreActionList" trigger="click" @select="handleMoreActionSelect($event, record)" />
|
||||
<span v-permission="['PROJECT_BUG:READ+ADD']" class="flex flex-row">
|
||||
<MsButton class="!mr-0" @click="handleCopy(record)">{{ t('common.copy') }}</MsButton>
|
||||
<a-divider direction="vertical" />
|
||||
</span>
|
||||
<span v-permission="['PROJECT_BUG:READ+UPDATE']" class="flex flex-row">
|
||||
<MsButton class="!mr-0" @click="handleEdit(record)">{{ t('common.edit') }}</MsButton>
|
||||
<a-divider direction="vertical" />
|
||||
</span>
|
||||
<MsTableMoreAction
|
||||
v-permission="['PROJECT_BUG:READ+DELETE']"
|
||||
:list="moreActionList"
|
||||
trigger="click"
|
||||
@select="handleMoreActionSelect($event, record)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #empty> </template>
|
||||
|
@ -364,15 +379,18 @@
|
|||
{
|
||||
label: 'common.export',
|
||||
eventTag: 'export',
|
||||
permission: ['PROJECT_BUG:READ+EXPORT'],
|
||||
},
|
||||
{
|
||||
label: 'common.edit',
|
||||
eventTag: 'edit',
|
||||
permission: ['PROJECT_BUG:READ+UPDATE'],
|
||||
},
|
||||
{
|
||||
label: 'common.delete',
|
||||
eventTag: 'delete',
|
||||
danger: true,
|
||||
permission: ['PROJECT_BUG:READ+DELETE'],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
|
@ -119,7 +119,7 @@
|
|||
try {
|
||||
loading.value = true;
|
||||
store.currentEnvDetailInfo.mock = true;
|
||||
const res = await updateOrAddEnv(store.currentEnvDetailInfo);
|
||||
const res = await updateOrAddEnv({ fileList: [], request: store.currentEnvDetailInfo });
|
||||
store.currentEnvDetailInfo = res;
|
||||
Message.success(t('common.saveSuccess'));
|
||||
} catch (error) {
|
||||
|
|
Loading…
Reference in New Issue