fix(全局): 问题修复

This commit is contained in:
baiqi 2024-02-05 11:44:36 +08:00 committed by 刘瑞斌
parent 9e744abcc0
commit fa94637dc7
42 changed files with 160 additions and 99 deletions

View File

@ -38,6 +38,7 @@ import {
BatchReviewCaseParams, BatchReviewCaseParams,
CommitReviewResultParams, CommitReviewResultParams,
CopyReviewParams, CopyReviewParams,
CopyReviewResponse,
FollowReviewParams, FollowReviewParams,
Review, Review,
ReviewCaseItem, ReviewCaseItem,
@ -97,7 +98,7 @@ export const associateReviewCase = (data: AssociateReviewCaseParams) => {
// 复制评审 // 复制评审
export const copyReview = (data: CopyReviewParams) => { export const copyReview = (data: CopyReviewParams) => {
return MSR.post({ url: CopyReviewUrl, data }); return MSR.post<CopyReviewResponse>({ url: CopyReviewUrl, data });
}; };
// 编辑评审 // 编辑评审

View File

@ -91,11 +91,11 @@ import type {
PreviewImages, PreviewImages,
UpdateModule, UpdateModule,
} from '@/models/caseManagement/featureCase'; } from '@/models/caseManagement/featureCase';
import type { CommonList, MoveModules, TableQueryParams } from '@/models/common'; import type { CommonList, ModuleTreeNode, MoveModules, TableQueryParams } from '@/models/common';
// 获取模块树 // 获取模块树
export function getCaseModuleTree(params: TableQueryParams) { export function getCaseModuleTree(params: TableQueryParams) {
return MSR.get<ModulesTreeType[]>({ url: `${GetCaseModuleTreeUrl}/${params.projectId}` }); return MSR.get<ModuleTreeNode[]>({ url: `${GetCaseModuleTreeUrl}/${params.projectId}` });
} }
// 创建模块树 // 创建模块树
@ -320,7 +320,7 @@ export function getPublicLinkCaseModulesCounts(data: TableQueryParams) {
// 获取关联用例接口模块树 // 获取关联用例接口模块树
export function getPublicLinkModuleTree(data: TableQueryParams) { export function getPublicLinkModuleTree(data: TableQueryParams) {
return MSR.post<ModulesTreeType[]>({ url: GetAssociationPublicModuleTreeUrl, data }); return MSR.post<ModuleTreeNode[]>({ url: GetAssociationPublicModuleTreeUrl, data });
} }
// 关联用例 // 关联用例
export function associationPublicCase(data: TableQueryParams) { export function associationPublicCase(data: TableQueryParams) {

View File

@ -30,7 +30,7 @@ import {
UploadFileUrl, UploadFileUrl,
} from '@/api/requrls/project-management/fileManagement'; } from '@/api/requrls/project-management/fileManagement';
import type { CommonList } from '@/models/common'; import type { CommonList, ModuleTreeNode } from '@/models/common';
import type { import type {
AddModuleParams, AddModuleParams,
AddRepositoryFileParams, AddRepositoryFileParams,
@ -42,7 +42,6 @@ import type {
FileItem, FileItem,
FileListQueryParams, FileListQueryParams,
ModuleCount, ModuleCount,
ModuleTreeNode,
MoveModuleParams, MoveModuleParams,
Repository, Repository,
RepositoryInfo, RepositoryInfo,

View File

@ -159,8 +159,7 @@
import { mapTree } from '@/utils'; import { mapTree } from '@/utils';
import type { CaseManagementTable } from '@/models/caseManagement/featureCase'; import type { CaseManagementTable } from '@/models/caseManagement/featureCase';
import type { CommonList, TableQueryParams } from '@/models/common'; import type { CommonList, ModuleTreeNode, TableQueryParams } from '@/models/common';
import { ModuleTreeNode } from '@/models/projectManagement/file';
import { CaseManagementRouteEnum } from '@/enums/routeEnum'; import { CaseManagementRouteEnum } from '@/enums/routeEnum';
import type { CaseLevel } from './types'; import type { CaseLevel } from './types';

View File

@ -105,13 +105,9 @@
getFormApiImportPageList, getFormApiImportPageList,
} from '@/api/modules/project-management/commonScript'; } from '@/api/modules/project-management/commonScript';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import useAppStore from '@/store/modules/app';
import { mapTree } from '@/utils'; import { mapTree } from '@/utils';
import type { TableQueryParams } from '@/models/common'; import type { ModuleTreeNode, TableQueryParams } from '@/models/common';
import { ModuleTreeNode } from '@/models/projectManagement/file';
const appStore = useAppStore();
const { t } = useI18n(); const { t } = useI18n();

View File

@ -92,8 +92,8 @@
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import type { AssociatedList } from '@/models/caseManagement/featureCase'; import type { AssociatedList } from '@/models/caseManagement/featureCase';
import type { CommonList, TableQueryParams } from '@/models/common'; import type { CommonList, ModuleTreeNode, TableQueryParams } from '@/models/common';
import { FileListQueryParams, ModuleTreeNode, Repository } from '@/models/projectManagement/file'; import { FileListQueryParams, Repository } from '@/models/projectManagement/file';
const { t } = useI18n(); const { t } = useI18n();

View File

@ -41,7 +41,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, onBeforeMount, ref, watch } from 'vue'; import { computed, ref, watch } from 'vue';
import MsIcon from '@/components/pure/ms-icon-font/index.vue'; import MsIcon from '@/components/pure/ms-icon-font/index.vue';
import MsTree from '@/components/business/ms-tree/index.vue'; import MsTree from '@/components/business/ms-tree/index.vue';
@ -51,7 +51,7 @@
import useAppStore from '@/store/modules/app'; import useAppStore from '@/store/modules/app';
import { mapTree } from '@/utils'; import { mapTree } from '@/utils';
import { ModuleTreeNode } from '@/models/projectManagement/file'; import { ModuleTreeNode } from '@/models/common';
const appStore = useAppStore(); const appStore = useAppStore();

View File

@ -65,8 +65,8 @@
import { findNodeByKey, formatFileSize } from '@/utils'; import { findNodeByKey, formatFileSize } from '@/utils';
import type { AssociatedList } from '@/models/caseManagement/featureCase'; import type { AssociatedList } from '@/models/caseManagement/featureCase';
import type { CommonList, TableQueryParams } from '@/models/common'; import type { CommonList, ModuleTreeNode, TableQueryParams } from '@/models/common';
import type { FileListQueryParams, ModuleTreeNode } from '@/models/projectManagement/file'; import type { FileListQueryParams } from '@/models/projectManagement/file';
import { Repository } from '@/models/projectManagement/file'; import { Repository } from '@/models/projectManagement/file';
import { TableKeyEnum } from '@/enums/tableEnum'; import { TableKeyEnum } from '@/enums/tableEnum';

View File

@ -212,7 +212,6 @@
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { SelectValue } from '@/models/projectManagement/menuManagement'; import { SelectValue } from '@/models/projectManagement/menuManagement';
import { OptionsItem } from '@/models/setting/log';
import { OPERATOR_MAP } from './index'; import { OPERATOR_MAP } from './index';
import { AccordBelowType, BackEndEnum, CombineItem, FilterFormItem, FilterResult, FilterType } from './type'; import { AccordBelowType, BackEndEnum, CombineItem, FilterFormItem, FilterResult, FilterType } from './type';

View File

@ -8,9 +8,9 @@
:placeholder="props.searchPlaceholder" :placeholder="props.searchPlaceholder"
class="w-[240px]" class="w-[240px]"
allow-clear allow-clear
@press-enter="emit('keywordSearch', innerKeyword)" @press-enter="emit('keywordSearch', innerKeyword, filterResult)"
@search="emit('keywordSearch', innerKeyword)" @search="emit('keywordSearch', innerKeyword, filterResult)"
@clear="emit('keywordSearch', innerKeyword)" @clear="emit('keywordSearch', innerKeyword, filterResult)"
></a-input-search> ></a-input-search>
<MsTag <MsTag
:type="visible ? 'primary' : 'default'" :type="visible ? 'primary' : 'default'"
@ -28,7 +28,7 @@
</span> </span>
</span> </span>
</MsTag> </MsTag>
<MsTag no-margin size="large" class="cursor-pointer" theme="outline" @click="handleResetSearch"> <MsTag no-margin size="large" class="cursor-pointer" theme="outline" @click="handleRefresh">
<MsIcon class="text-[var(color-text-4)]" :size="16" type="icon-icon_reset_outlined" /> <MsIcon class="text-[var(color-text-4)]" :size="16" type="icon-icon_reset_outlined" />
</MsTag> </MsTag>
<slot name="right"></slot> <slot name="right"></slot>
@ -44,7 +44,7 @@
class="mt-[8px]" class="mt-[8px]"
@on-search="handleFilter" @on-search="handleFilter"
@data-index-change="dataIndexChange" @data-index-change="dataIndexChange"
@reset="emit('reset')" @reset="handleResetFilter"
/> />
</template> </template>
@ -69,26 +69,33 @@
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'update:keyword', value: string): void; (e: 'update:keyword', value: string): void;
(e: 'keywordSearch', value: string | undefined): void; // innerKeyword (e: 'keywordSearch', value: string | undefined, combine: FilterResult): void; // innerKeyword TODO: v-model:keyword
(e: 'advSearch', value: FilterResult): void; // (e: 'advSearch', value: FilterResult): void; //
(e: 'dataIndexChange', value: string): void; // (e: 'dataIndexChange', value: string): void; //
(e: 'reset'): void; (e: 'refresh', value: FilterResult): void;
}>(); }>();
const { t } = useI18n(); const { t } = useI18n();
const innerKeyword = useVModel(props, 'keyword', emit); const innerKeyword = useVModel(props, 'keyword', emit);
const visible = ref(false); const visible = ref(false);
const filterCount = ref(0); const filterCount = ref(0);
const defaultFilterResult: FilterResult = { accordBelow: 'AND', combine: {} };
const filterResult = ref<FilterResult>({ ...defaultFilterResult });
const handleResetSearch = () => { const handleResetFilter = () => {
innerKeyword.value = ''; filterResult.value = { ...defaultFilterResult };
emit('keywordSearch', ''); emit('keywordSearch', '', { ...defaultFilterResult });
}; };
const handleFilter = (filter: FilterResult) => { const handleFilter = (filter: FilterResult) => {
filterResult.value = filter;
emit('advSearch', filter); emit('advSearch', filter);
}; };
const handleRefresh = () => {
emit('refresh', filterResult.value);
};
const dataIndexChange = (dataIndex: string) => { const dataIndexChange = (dataIndex: string) => {
emit('dataIndexChange', dataIndex); emit('dataIndexChange', dataIndex);
}; };

View File

@ -27,7 +27,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { hasAnyPermission } from '@/utils/permission'; import { hasAllPermission } from '@/utils/permission';
interface MenuItem { interface MenuItem {
title: string; title: string;
@ -47,7 +47,7 @@
const currentKey = ref(props.defaultKey); const currentKey = ref(props.defaultKey);
const innerMenuList = computed(() => { const innerMenuList = computed(() => {
return props.menuList.filter((item: any) => hasAnyPermission(item.permission)); return props.menuList.filter((item: any) => hasAllPermission(item.permission));
}); });
watch( watch(

View File

@ -4,7 +4,7 @@
<template v-for="(element, idx) in baseAction" :key="element.label"> <template v-for="(element, idx) in baseAction" :key="element.label">
<a-divider v-if="element.isDivider" class="divider mx-0 my-[6px]" /> <a-divider v-if="element.isDivider" class="divider mx-0 my-[6px]" />
<a-button <a-button
v-if="!element.isDivider && !element.children && hasAnyPermission(element.permission as string[])" v-if="!element.isDivider && !element.children && hasAllPermission(element.permission as string[])"
class="ml-[12px]" class="ml-[12px]"
:class="{ :class="{
'arco-btn-outline--danger': element.danger, 'arco-btn-outline--danger': element.danger,
@ -16,7 +16,7 @@
> >
<!-- baseAction多菜单选择 --> <!-- baseAction多菜单选择 -->
<a-dropdown <a-dropdown
v-if="!element.isDivider && element.children && hasAnyPermission(element.permission as string[])" v-if="!element.isDivider && element.children && hasAllPermission(element.permission as string[])"
position="tr" position="tr"
@select="handleSelect" @select="handleSelect"
> >
@ -48,7 +48,7 @@
<template v-for="element in moreAction" :key="element.label"> <template v-for="element in moreAction" :key="element.label">
<a-divider v-if="element.isDivider" margin="4px" /> <a-divider v-if="element.isDivider" margin="4px" />
<a-doption <a-doption
v-else-if="hasAnyPermission(element.permission as string[])" v-else-if="hasAllPermission(element.permission as string[])"
:value="element" :value="element"
:class="{ delete: element.danger }" :class="{ delete: element.danger }"
> >
@ -67,7 +67,7 @@
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { getNodeWidth } from '@/utils/dom'; import { getNodeWidth } from '@/utils/dom';
import { hasAnyPermission } from '@/utils/permission'; import { hasAllPermission } from '@/utils/permission';
import { BatchActionConfig, BatchActionParams } from './type'; import { BatchActionConfig, BatchActionParams } from './type';
import ResizeObserver from 'resize-observer-polyfill'; import ResizeObserver from 'resize-observer-polyfill';

View File

@ -1,5 +1,9 @@
import { BatchApiParams, TableQueryParams } from '@/models/common'; import { BatchApiParams, TableQueryParams } from '@/models/common';
// 评审状态, PREPARED: 待开始, UNDERWAY: 进行中, COMPLETED: 已完成, ARCHIVED: 已归档
export type ReviewStatus = 'PREPARED' | 'UNDERWAY' | 'COMPLETED' | 'ARCHIVED';
// 评审结果UN_REVIEWED未评审UNDER_REVIEWED评审中PASS通过UN_PASS未通过RE_REVIEWED重新提审
export type ReviewResult = 'UN_REVIEWED' | 'UNDER_REVIEWED' | 'PASS' | 'UN_PASS' | 'RE_REVIEWED';
// 评审模块 // 评审模块
export interface ReviewModule { export interface ReviewModule {
projectId: string; projectId: string;
@ -50,6 +54,27 @@ export interface Review {
export interface CopyReviewParams extends Omit<Review, 'baseAssociateCaseRequest'> { export interface CopyReviewParams extends Omit<Review, 'baseAssociateCaseRequest'> {
copyId: string; copyId: string;
} }
// 复制评审响应内容
export interface CopyReviewResponse {
caseCount: number;
createTime: number;
createUser: string;
description: string;
endTime: number | null;
id: string;
moduleId: string;
name: string;
num: number;
passRate: number;
pos: number;
projectId: string;
reviewPassRule: ReviewPassRule;
startTime: number | null;
status: ReviewStatus;
tags: null;
updateTime: number;
updateUser: string;
}
// 更新评审入参 // 更新评审入参
export interface UpdateReviewParams extends Omit<Review, 'baseAssociateCaseRequest'> { export interface UpdateReviewParams extends Omit<Review, 'baseAssociateCaseRequest'> {
id: string; id: string;
@ -81,10 +106,6 @@ export interface SortReviewParams {
moveMode: ReviewMoveMode; moveMode: ReviewMoveMode;
moveId: string; // 被移动的评审id moveId: string; // 被移动的评审id
} }
// 评审状态, PREPARED: 待开始, UNDERWAY: 进行中, COMPLETED: 已完成, ARCHIVED: 已归档
export type ReviewStatus = 'PREPARED' | 'UNDERWAY' | 'COMPLETED' | 'ARCHIVED';
// 评审结果UN_REVIEWED未评审UNDER_REVIEWED评审中PASS通过UN_PASS未通过RE_REVIEWED重新提审
export type ReviewResult = 'UN_REVIEWED' | 'UNDER_REVIEWED' | 'PASS' | 'UN_PASS' | 'RE_REVIEWED';
// 评审列表查询参数 // 评审列表查询参数
export interface ReviewListQueryParams extends TableQueryParams { export interface ReviewListQueryParams extends TableQueryParams {
moduleIds: string[]; moduleIds: string[];

View File

@ -49,3 +49,14 @@ export interface MoveModules {
dropNodeId: string; // 放入的节点 dropNodeId: string; // 放入的节点
dropPosition: number; // 放入的位置(取值:-1,0,1。 -1dropNodeId节点之前。 0:dropNodeId节点内。 1dropNodeId节点后 dropPosition: number; // 放入的位置(取值:-1,0,1。 -1dropNodeId节点之前。 0:dropNodeId节点内。 1dropNodeId节点后
} }
// 模块树节点
export interface ModuleTreeNode {
id: string;
name: string;
type: string;
children: ModuleTreeNode[];
attachInfo: Record<string, any>; // 附加信息
count: 0;
parentId: string;
path: string;
}

View File

@ -85,13 +85,6 @@ export interface AddModuleParams {
name: string; name: string;
parentId: string; parentId: string;
} }
// 模块树节点
export interface ModuleTreeNode {
id: string;
name: string;
type: string;
children: ModuleTreeNode[];
}
// 文件历史列表项 // 文件历史列表项
export interface FileHistoryItem { export interface FileHistoryItem {
id: string; id: string;

View File

@ -3,7 +3,7 @@ import { defineStore } from 'pinia';
import { getCaseModulesCounts, getRecycleModulesCounts } from '@/api/modules/case-management/featureCase'; import { getCaseModulesCounts, getRecycleModulesCounts } from '@/api/modules/case-management/featureCase';
import type { CaseModuleQueryParams, TabItemType } from '@/models/caseManagement/featureCase'; import type { CaseModuleQueryParams, TabItemType } from '@/models/caseManagement/featureCase';
import { ModuleTreeNode } from '@/models/projectManagement/file'; import { ModuleTreeNode } from '@/models/common';
const useFeatureCaseStore = defineStore('featureCase', { const useFeatureCaseStore = defineStore('featureCase', {
persist: true, persist: true,

View File

@ -194,8 +194,9 @@ export interface TreeNode<T> {
*/ */
export function mapTree<T>( export function mapTree<T>(
tree: TreeNode<T> | TreeNode<T>[] | T | T[], tree: TreeNode<T> | TreeNode<T>[] | T | T[],
customNodeFn: (node: TreeNode<T>) => TreeNode<T> | null = (node) => node, customNodeFn: (node: TreeNode<T>, path: string) => TreeNode<T> | null = (node) => node,
customChildrenKey = 'children' customChildrenKey = 'children',
parentPath = ''
): T[] { ): T[] {
if (!Array.isArray(tree)) { if (!Array.isArray(tree)) {
tree = [tree]; tree = [tree];
@ -203,7 +204,8 @@ export function mapTree<T>(
return tree return tree
.map((node: TreeNode<T>) => { .map((node: TreeNode<T>) => {
const newNode = typeof customNodeFn === 'function' ? customNodeFn(node) : node; const fullPath = node.path ? `${parentPath}/${node.path}`.replace(/\/+/g, '/') : '';
const newNode = typeof customNodeFn === 'function' ? customNodeFn(node, fullPath) : node;
if (newNode && newNode[customChildrenKey] && newNode[customChildrenKey].length > 0) { if (newNode && newNode[customChildrenKey] && newNode[customChildrenKey].length > 0) {
newNode[customChildrenKey] = mapTree(newNode[customChildrenKey], customNodeFn, customChildrenKey); newNode[customChildrenKey] = mapTree(newNode[customChildrenKey], customNodeFn, customChildrenKey);

View File

@ -30,7 +30,10 @@ export function hasPermission(permission: string, typeList: string[]) {
return false; return false;
} }
// 判断是否有权限 /**
*
* @param permissions
*/
export function hasAnyPermission(permissions: string[], typeList = ['PROJECT', 'ORGANIZATION', 'SYSTEM']) { export function hasAnyPermission(permissions: string[], typeList = ['PROJECT', 'ORGANIZATION', 'SYSTEM']) {
if (!permissions || permissions.length === 0) { if (!permissions || permissions.length === 0) {
return true; return true;
@ -38,6 +41,17 @@ export function hasAnyPermission(permissions: string[], typeList = ['PROJECT', '
return permissions.some((permission) => hasPermission(permission, typeList)); return permissions.some((permission) => hasPermission(permission, typeList));
} }
/**
*
* @param permissions
*/
export function hasAllPermission(permissions: string[], typeList = ['PROJECT', 'ORGANIZATION', 'SYSTEM']) {
if (!permissions || permissions.length === 0) {
return true;
}
return permissions.every((permission) => hasPermission(permission, typeList));
}
function filterProject(role: UserRole, id: string) { function filterProject(role: UserRole, id: string) {
return role && role.type === 'PROJECT' && (role.scopeId === id || role.scopeId === 'global'); return role && role.type === 'PROJECT' && (role.scopeId === id || role.scopeId === 'global');
} }

View File

@ -200,7 +200,7 @@
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { registerCatchSaveShortcut, removeCatchSaveShortcut } from '@/utils/event'; import { registerCatchSaveShortcut, removeCatchSaveShortcut } from '@/utils/event';
import type { ModuleTreeNode } from '@/models/projectManagement/file'; import { ModuleTreeNode } from '@/models/common';
import { RequestBodyFormat, RequestComposition, RequestMethods, ResponseComposition } from '@/enums/apiEnum'; import { RequestBodyFormat, RequestComposition, RequestMethods, ResponseComposition } from '@/enums/apiEnum';
const props = defineProps<{ const props = defineProps<{

View File

@ -114,7 +114,7 @@
import useAppStore from '@/store/modules/app'; import useAppStore from '@/store/modules/app';
import { mapTree } from '@/utils'; import { mapTree } from '@/utils';
import { ModuleTreeNode } from '@/models/projectManagement/file'; import { ModuleTreeNode } from '@/models/common';
const props = defineProps<{ const props = defineProps<{
modulesCount?: Record<string, number>; // modulesCount?: Record<string, number>; //

View File

@ -61,7 +61,7 @@
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { parseCurlScript } from '@/utils'; import { parseCurlScript } from '@/utils';
import { ModuleTreeNode } from '@/models/projectManagement/file'; import { ModuleTreeNode } from '@/models/common';
import { RequestContentTypeEnum } from '@/enums/apiEnum'; import { RequestContentTypeEnum } from '@/enums/apiEnum';
const { t } = useI18n(); const { t } = useI18n();

View File

@ -304,7 +304,7 @@
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { mapTree } from '@/utils'; import { mapTree } from '@/utils';
import { ModuleTreeNode } from '@/models/projectManagement/file'; import { ModuleTreeNode } from '@/models/common';
import { RequestImportFormat } from '@/enums/apiEnum'; import { RequestImportFormat } from '@/enums/apiEnum';
const props = defineProps<{ const props = defineProps<{

View File

@ -135,7 +135,7 @@
import useAppStore from '@/store/modules/app'; import useAppStore from '@/store/modules/app';
import { mapTree } from '@/utils'; import { mapTree } from '@/utils';
import { ModuleTreeNode } from '@/models/projectManagement/file'; import { ModuleTreeNode } from '@/models/common';
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{

View File

@ -54,11 +54,7 @@
import management from './components/management/index.vue'; import management from './components/management/index.vue';
import moduleTree from './components/moduleTree.vue'; import moduleTree from './components/moduleTree.vue';
import { useI18n } from '@/hooks/useI18n'; import { ModuleTreeNode } from '@/models/common';
import { ModuleTreeNode } from '@/models/projectManagement/file';
const { t } = useI18n();
const activeModule = ref<string>('all'); const activeModule = ref<string>('all');
const folderTree = ref<ModuleTreeNode[]>([]); const folderTree = ref<ModuleTreeNode[]>([]);

View File

@ -50,7 +50,7 @@
async function initProjects() { async function initProjects() {
try { try {
if (appStore.getCurrentOrgId && hasAnyPermission(['PROJECT_BASE_INFO:READ'])) { if (appStore.getCurrentOrgId && hasAnyPermission(['PROJECT_BASE_INFO:READ'])) {
const res = await getProjectList(appStore.getCurrentOrgId); const res = await getProjectList(appStore.getCurrentOrgId); // TODO:
} else { } else {
projectList.value = []; projectList.value = [];
} }

View File

@ -242,7 +242,7 @@
import { hasAnyPermission } from '@/utils/permission'; import { hasAnyPermission } from '@/utils/permission';
import type { CustomAttributes, DetailCase, TabItemType } from '@/models/caseManagement/featureCase'; import type { CustomAttributes, DetailCase, TabItemType } from '@/models/caseManagement/featureCase';
import { ModuleTreeNode } from '@/models/projectManagement/file'; import { ModuleTreeNode } from '@/models/common';
import { CaseManagementRouteEnum } from '@/enums/routeEnum'; import { CaseManagementRouteEnum } from '@/enums/routeEnum';
import { getCaseLevels } from './utils'; import { getCaseLevels } from './utils';

View File

@ -283,8 +283,7 @@
DetailCase, DetailCase,
StepList, StepList,
} from '@/models/caseManagement/featureCase'; } from '@/models/caseManagement/featureCase';
import type { TableQueryParams } from '@/models/common'; import type { ModuleTreeNode, TableQueryParams } from '@/models/common';
import { ModuleTreeNode } from '@/models/projectManagement/file';
import { convertToFile } from './utils'; import { convertToFile } from './utils';

View File

@ -94,7 +94,7 @@
import { mapTree } from '@/utils'; import { mapTree } from '@/utils';
import type { CreateOrUpdateModule, UpdateModule } from '@/models/caseManagement/featureCase'; import type { CreateOrUpdateModule, UpdateModule } from '@/models/caseManagement/featureCase';
import { ModuleTreeNode } from '@/models/projectManagement/file'; import { ModuleTreeNode } from '@/models/common';
const featureCaseStore = useFeatureCaseStore(); const featureCaseStore = useFeatureCaseStore();

View File

@ -183,8 +183,7 @@
CaseModuleQueryParams, CaseModuleQueryParams,
CustomAttributes, CustomAttributes,
} from '@/models/caseManagement/featureCase'; } from '@/models/caseManagement/featureCase';
import type { TableQueryParams } from '@/models/common'; import type { ModuleTreeNode, TableQueryParams } from '@/models/common';
import { ModuleTreeNode } from '@/models/projectManagement/file';
import { TableKeyEnum } from '@/enums/tableEnum'; import { TableKeyEnum } from '@/enums/tableEnum';
import { getCaseLevels, getReviewStatusClass, getStatusText, getTableFields } from './utils'; import { getCaseLevels, getReviewStatusClass, getStatusText, getTableFields } from './utils';

View File

@ -148,8 +148,7 @@
import { mapTree } from '@/utils'; import { mapTree } from '@/utils';
import type { CaseManagementTable, CaseModuleQueryParams } from '@/models/caseManagement/featureCase'; import type { CaseManagementTable, CaseModuleQueryParams } from '@/models/caseManagement/featureCase';
import type { TableQueryParams } from '@/models/common'; import type { ModuleTreeNode, TableQueryParams } from '@/models/common';
import { ModuleTreeNode } from '@/models/projectManagement/file';
import { CaseManagementRouteEnum } from '@/enums/routeEnum'; import { CaseManagementRouteEnum } from '@/enums/routeEnum';
import { getCaseLevels } from '../../utils'; import { getCaseLevels } from '../../utils';

View File

@ -6,9 +6,9 @@
:filter-config-list="filterConfigList" :filter-config-list="filterConfigList"
:row-count="filterRowCount" :row-count="filterRowCount"
:search-placeholder="t('caseManagement.caseReview.searchPlaceholder')" :search-placeholder="t('caseManagement.caseReview.searchPlaceholder')"
@keyword-search="() => searchCase()" @keyword-search="(val, filter) => searchCase(filter)"
@adv-search="searchCase" @adv-search="searchCase"
@reset="searchCase" @refresh="searchCase"
> >
<template #right> <template #right>
<div class="flex items-center"> <div class="flex items-center">
@ -273,8 +273,7 @@
import useUserStore from '@/store/modules/user'; import useUserStore from '@/store/modules/user';
import { ReviewCaseItem, ReviewItem, ReviewPassRule, ReviewResult } from '@/models/caseManagement/caseReview'; import { ReviewCaseItem, ReviewItem, ReviewPassRule, ReviewResult } from '@/models/caseManagement/caseReview';
import { BatchApiParams } from '@/models/common'; import { BatchApiParams, ModuleTreeNode } from '@/models/common';
import type { ModuleTreeNode } from '@/models/projectManagement/file';
import { CaseManagementRouteEnum } from '@/enums/routeEnum'; import { CaseManagementRouteEnum } from '@/enums/routeEnum';
import { TableKeyEnum } from '@/enums/tableEnum'; import { TableKeyEnum } from '@/enums/tableEnum';

View File

@ -59,7 +59,7 @@
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { mapTree } from '@/utils'; import { mapTree } from '@/utils';
import { ModuleTreeNode } from '@/models/projectManagement/file'; import { ModuleTreeNode } from '@/models/common';
const props = defineProps<{ const props = defineProps<{
modulesCount?: Record<string, number>; // modulesCount?: Record<string, number>; //

View File

@ -111,7 +111,7 @@
import useAppStore from '@/store/modules/app'; import useAppStore from '@/store/modules/app';
import { mapTree } from '@/utils'; import { mapTree } from '@/utils';
import { ModuleTreeNode } from '@/models/projectManagement/file'; import { ModuleTreeNode } from '@/models/common';
const props = defineProps<{ const props = defineProps<{
isModal?: boolean; // isModal?: boolean; //
@ -194,7 +194,13 @@
try { try {
loading.value = true; loading.value = true;
const res = await getReviewModules(appStore.currentProjectId); const res = await getReviewModules(appStore.currentProjectId);
folderTree.value = mapTree<ModuleTreeNode>(res, (e) => { const nodePathObj: Record<string, any> = {};
folderTree.value = mapTree<ModuleTreeNode>(res, (e, fullPath) => {
//
nodePathObj[e.id] = {
path: e.path,
fullPath,
};
return { return {
...e, ...e,
hideMoreAction: e.id === 'root', hideMoreAction: e.id === 'root',
@ -213,7 +219,7 @@
emit('folderNodeSelect', selectedKeys.value, offspringIds); emit('folderNodeSelect', selectedKeys.value, offspringIds);
} }
emit('init', folderTree.value); emit('init', folderTree.value, nodePathObj);
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log(error); console.log(error);

View File

@ -6,9 +6,9 @@
:filter-config-list="filterConfigList" :filter-config-list="filterConfigList"
:row-count="filterRowCount" :row-count="filterRowCount"
:search-placeholder="t('caseManagement.caseReview.searchPlaceholder')" :search-placeholder="t('caseManagement.caseReview.searchPlaceholder')"
@keyword-search="() => searchReview()" @keyword-search="(val, filter) => searchReview(filter)"
@adv-search="searchReview" @adv-search="searchReview"
@reset="searchReview" @refresh="searchReview"
> >
<template #left> <template #left>
<div class="flex items-center"> <div class="flex items-center">
@ -99,6 +99,11 @@
{{ `${record.passRate}%` }} {{ `${record.passRate}%` }}
</div> </div>
</template> </template>
<template #moduleName="{ record }">
<a-tooltip :content="record.fullModuleName">
<div class="one-line-text">{{ record.moduleName }}</div>
</a-tooltip>
</template>
<template #action="{ record }"> <template #action="{ record }">
<MsButton type="text" class="!mr-0" @click="() => editReview(record)"> <MsButton type="text" class="!mr-0" @click="() => editReview(record)">
{{ t('common.edit') }} {{ t('common.edit') }}
@ -185,13 +190,20 @@
ReviewListQueryParams, ReviewListQueryParams,
ReviewStatus, ReviewStatus,
} from '@/models/caseManagement/caseReview'; } from '@/models/caseManagement/caseReview';
import type { ModuleTreeNode } from '@/models/projectManagement/file'; import { ModuleTreeNode } from '@/models/common';
import { CaseManagementRouteEnum } from '@/enums/routeEnum'; import { CaseManagementRouteEnum } from '@/enums/routeEnum';
import { TableKeyEnum } from '@/enums/tableEnum'; import { TableKeyEnum } from '@/enums/tableEnum';
const props = defineProps<{ const props = defineProps<{
activeFolder: string; activeFolder: string;
moduleTree: ModuleTreeNode[]; moduleTree: ModuleTreeNode[];
treePathMap: Record<
string,
{
path: string;
fullPath: string;
}
>;
showType: string; showType: string;
offspringIds: string[]; offspringIds: string[];
}>(); }>();
@ -403,8 +415,9 @@
}, },
{ {
title: 'caseManagement.caseReview.module', title: 'caseManagement.caseReview.module',
dataIndex: 'module', dataIndex: 'moduleName',
width: 90, slotName: 'moduleName',
width: 120,
}, },
{ {
title: 'caseManagement.caseReview.tag', title: 'caseManagement.caseReview.tag',
@ -446,6 +459,8 @@
...item, ...item,
tags: (item.tags || []).map((e: string) => ({ id: e, name: e })), tags: (item.tags || []).map((e: string) => ({ id: e, name: e })),
reviewers: item.reviewers.map((e: ReviewDetailReviewersItem) => e.userName), reviewers: item.reviewers.map((e: ReviewDetailReviewersItem) => e.userName),
moduleName: props.treePathMap[item.moduleId].path,
fullModuleName: props.treePathMap[item.moduleId].fullPath,
cycle: cycle:
item.startTime && item.endTime item.startTime && item.endTime
? `${dayjs(item.startTime).format('YYYY-MM-DD HH:mm:ss')} - ${dayjs(item.endTime).format( ? `${dayjs(item.startTime).format('YYYY-MM-DD HH:mm:ss')} - ${dayjs(item.endTime).format(

View File

@ -291,7 +291,7 @@
try { try {
saveLoading.value = true; saveLoading.value = true;
const { name, folderId, type, cycle, tags, desc, reviewers } = reviewForm.value; const { name, folderId, type, cycle, tags, desc, reviewers } = reviewForm.value;
let res = ''; let res: Record<string, any> = {};
if (isCopy.value) { if (isCopy.value) {
// //
res = await copyReview({ res = await copyReview({
@ -326,7 +326,7 @@
router.replace({ router.replace({
name: CaseManagementRouteEnum.CASE_MANAGEMENT_REVIEW_DETAIL, name: CaseManagementRouteEnum.CASE_MANAGEMENT_REVIEW_DETAIL,
query: { query: {
id: res, id: res.id,
}, },
}); });
} else { } else {

View File

@ -161,7 +161,7 @@
ReviewItem, ReviewItem,
ReviewStatus, ReviewStatus,
} from '@/models/caseManagement/caseReview'; } from '@/models/caseManagement/caseReview';
import type { ModuleTreeNode } from '@/models/projectManagement/file'; import { ModuleTreeNode } from '@/models/common';
import { CaseManagementRouteEnum } from '@/enums/routeEnum'; import { CaseManagementRouteEnum } from '@/enums/routeEnum';
const router = useRouter(); const router = useRouter();

View File

@ -25,6 +25,7 @@
<ReviewTable <ReviewTable
:active-folder="activeFolderId" :active-folder="activeFolderId"
:module-tree="moduleTree" :module-tree="moduleTree"
:tree-path-map="moduleTreePathMap"
:show-type="showType" :show-type="showType"
:offspring-ids="offspringIds" :offspring-ids="offspringIds"
@go-create="goCreateReview" @go-create="goCreateReview"
@ -51,7 +52,7 @@
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { ReviewListQueryParams } from '@/models/caseManagement/caseReview'; import { ReviewListQueryParams } from '@/models/caseManagement/caseReview';
import type { ModuleTreeNode } from '@/models/projectManagement/file'; import { ModuleTreeNode } from '@/models/common';
import { CaseManagementRouteEnum } from '@/enums/routeEnum'; import { CaseManagementRouteEnum } from '@/enums/routeEnum';
const router = useRouter(); const router = useRouter();
@ -65,10 +66,12 @@
const activeFolderId = ref<string>('all'); const activeFolderId = ref<string>('all');
const offspringIds = ref<string[]>([]); const offspringIds = ref<string[]>([]);
const moduleTree = ref<ModuleTreeNode[]>([]); const moduleTree = ref<ModuleTreeNode[]>([]);
const moduleTreePathMap = ref<Record<string, any>>({});
const modulesCount = ref<Record<string, number>>({}); const modulesCount = ref<Record<string, number>>({});
function initModuleTree(tree: ModuleTreeNode[]) { function initModuleTree(tree: ModuleTreeNode[], pathMap: Record<string, any>) {
moduleTree.value = unref(tree); moduleTree.value = unref(tree);
moduleTreePathMap.value = pathMap;
} }
function handleFolderNodeSelect(ids: string[], _offspringIds: string[]) { function handleFolderNodeSelect(ids: string[], _offspringIds: string[]) {

View File

@ -85,7 +85,7 @@
import useAppStore from '@/store/modules/app'; import useAppStore from '@/store/modules/app';
import { mapTree } from '@/utils'; import { mapTree } from '@/utils';
import { ModuleTreeNode } from '@/models/projectManagement/file'; import { ModuleTreeNode } from '@/models/common';
const props = defineProps<{ const props = defineProps<{
isExpandAll: boolean; isExpandAll: boolean;

View File

@ -596,7 +596,11 @@
{ {
tableKey: TableKeyEnum.FILE_MANAGEMENT_FILE, tableKey: TableKeyEnum.FILE_MANAGEMENT_FILE,
showSetting: true, showSetting: true,
selectable: !!hasAnyPermission(['PROJECT_FILE_MANAGEMENT:READ+DOWNLOAD+UPDATE+DELETE']), selectable: !!hasAnyPermission([
'PROJECT_FILE_MANAGEMENT:READ+DOWNLOAD',
'PROJECT_FILE_MANAGEMENT:READ+UPDATE',
'PROJECT_FILE_MANAGEMENT:READ+DELETE',
]),
showSelectAll: true, showSelectAll: true,
}, },
(item) => { (item) => {

View File

@ -78,7 +78,7 @@
{{ t('system.user.editUser') }} {{ t('system.user.editUser') }}
</MsButton> </MsButton>
<MsTableMoreAction <MsTableMoreAction
v-permission="['SYSTEM_USER:READ+UPDATE+DELETE']" v-permission="['SYSTEM_USER:READ+UPDATE', 'SYSTEM_USER:READ+DELETE']"
:list="tableActions" :list="tableActions"
@select="handleSelect($event, record)" @select="handleSelect($event, record)"
></MsTableMoreAction> ></MsTableMoreAction>
@ -378,7 +378,7 @@
{ {
tableKey: TableKeyEnum.SYSTEM_USER, tableKey: TableKeyEnum.SYSTEM_USER,
columns, columns,
selectable: !!hasAnyPermission(['SYSTEM_USER:READ+ADD+UPDATE+DELETE']), selectable: !!hasAnyPermission(['SYSTEM_USER:READ+ADD', 'SYSTEM_USER:READ+UPDATE', 'SYSTEM_USER:READ+DELETE']),
showSetting: true, showSetting: true,
showJumpMethod: true, showJumpMethod: true,
heightUsed: 288, heightUsed: 288,
@ -582,17 +582,17 @@
{ {
label: 'system.user.batchActionAddProject', label: 'system.user.batchActionAddProject',
eventTag: 'batchAddProject', eventTag: 'batchAddProject',
permission: ['SYSTEM_USER:READ+ADD', 'SYSTEM_ORGANIZATION_PROJECT:READ'], permission: ['SYSTEM_USER:READ+UPDATE', 'SYSTEM_ORGANIZATION_PROJECT:READ'],
}, },
{ {
label: 'system.user.batchActionAddUserGroup', label: 'system.user.batchActionAddUserGroup',
eventTag: 'batchAddUserGroup', eventTag: 'batchAddUserGroup',
permission: ['SYSTEM_USER:READ+ADD', 'SYSTEM_USER_ROLE:READ'], permission: ['SYSTEM_USER:READ+UPDATE', 'SYSTEM_USER_ROLE:READ'],
}, },
{ {
label: 'system.user.batchActionAddOrganization', label: 'system.user.batchActionAddOrganization',
eventTag: 'batchAddOrganization', eventTag: 'batchAddOrganization',
permission: ['SYSTEM_USER:READ+ADD', 'SYSTEM_ORGANIZATION_PROJECT:READ'], permission: ['SYSTEM_USER:READ+UPDATE', 'SYSTEM_ORGANIZATION_PROJECT:READ'],
}, },
], ],
moreAction: [ moreAction: [

View File

@ -93,9 +93,8 @@
import { reviewStatusMap } from '@/config/caseManagement'; import { reviewStatusMap } from '@/config/caseManagement';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { useAppStore, useTableStore } from '@/store'; import { useTableStore } from '@/store';
import { ModuleTreeNode } from '@/models/projectManagement/file';
import { ColumnEditTypeEnum, TableKeyEnum } from '@/enums/tableEnum'; import { ColumnEditTypeEnum, TableKeyEnum } from '@/enums/tableEnum';
const tableStore = useTableStore(); const tableStore = useTableStore();

View File

@ -92,7 +92,7 @@
import { mapTree } from '@/utils'; import { mapTree } from '@/utils';
import type { CreateOrUpdateModule, UpdateModule } from '@/models/caseManagement/featureCase'; import type { CreateOrUpdateModule, UpdateModule } from '@/models/caseManagement/featureCase';
import { ModuleTreeNode } from '@/models/projectManagement/file'; import { ModuleTreeNode } from '@/models/common';
const { t } = useI18n(); const { t } = useI18n();
const { openModal } = useModal(); const { openModal } = useModal();