fix: 全局bug&添加用例相关标表头筛选
This commit is contained in:
parent
c8fd930be2
commit
01f4631797
|
@ -156,7 +156,7 @@ export function getCaseDetail(id: string) {
|
|||
return MSR.get({ url: `${DetailCaseUrl}/${id}` });
|
||||
}
|
||||
// 批量删除用例
|
||||
export function batchDeleteCase(data: BatchDeleteType) {
|
||||
export function batchDeleteCase(data: TableQueryParams) {
|
||||
return MSR.post({ url: `${BatchDeleteCaseUrl}`, data });
|
||||
}
|
||||
// 批量编辑属性
|
||||
|
@ -180,7 +180,7 @@ export function getRecycleListRequest(data: TableQueryParams) {
|
|||
return MSR.post<CommonList<CaseManagementTable>>({ url: GetRecycleCaseListUrl, data });
|
||||
}
|
||||
// 获取回收站模块数量
|
||||
export function getRecycleModulesCounts(data: CaseModuleQueryParams) {
|
||||
export function getRecycleModulesCounts(data: TableQueryParams) {
|
||||
return MSR.post({ url: GetRecycleCaseModulesCountUrl, data });
|
||||
}
|
||||
// 获取全部用例模块数量
|
||||
|
@ -188,11 +188,11 @@ export function getCaseModulesCounts(data: TableQueryParams) {
|
|||
return MSR.post({ url: GetCaseModulesCountUrl, data });
|
||||
}
|
||||
// 批量恢复回收站用例表
|
||||
export function restoreCaseList(data: BatchMoveOrCopyType) {
|
||||
export function restoreCaseList(data: TableQueryParams) {
|
||||
return MSR.post({ url: RestoreCaseListUrl, data });
|
||||
}
|
||||
// 批量彻底删除回收站用例表
|
||||
export function batchDeleteRecycleCase(data: BatchMoveOrCopyType) {
|
||||
export function batchDeleteRecycleCase(data: TableQueryParams) {
|
||||
return MSR.post({ url: BatchDeleteRecycleCaseListUrl, data });
|
||||
}
|
||||
// 恢复回收站单个用例
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
EditProjectMemberUrl,
|
||||
GetProjectMemberListUrl,
|
||||
ProjectMemberCommentOptions,
|
||||
ProjectMemberList,
|
||||
ProjectMemberOptions,
|
||||
ProjectUserGroupUrl,
|
||||
RemoveProjectMemberUrl,
|
||||
|
@ -52,6 +53,10 @@ export function getProjectUserGroup(projectId: string) {
|
|||
export function getProjectMemberOptions(projectId: string, keyword?: string) {
|
||||
return MSR.get({ url: `${ProjectMemberOptions}/${projectId}`, params: { keyword } });
|
||||
}
|
||||
// 项目成员下拉选项不包含组织
|
||||
export function getProjectOptions(projectId: string, keyword?: string) {
|
||||
return MSR.get({ url: `${ProjectMemberList}/${projectId}`, params: { keyword } });
|
||||
}
|
||||
|
||||
// 项目成员-@成员下拉选项
|
||||
export function getProjectMemberCommentOptions(projectId: string, keyword?: string) {
|
||||
|
|
|
@ -6,4 +6,5 @@ export const RemoveProjectMemberUrl = '/project/member/remove';
|
|||
export const BatchAddUserGroup = '/project/member/add-role';
|
||||
export const ProjectUserGroupUrl = '/project/member/get-role/option';
|
||||
export const ProjectMemberOptions = '/project/member/get-member/option';
|
||||
export const ProjectMemberList = '/project/get-member/option';
|
||||
export const ProjectMemberCommentOptions = '/project/member/comment/user-option'; // 项目成员-@成员下拉列表
|
||||
|
|
|
@ -333,6 +333,9 @@
|
|||
|
||||
padding-right: 16px;
|
||||
}
|
||||
.arco-textarea-wrapper {
|
||||
resize: vertical !important;
|
||||
}
|
||||
|
||||
/** form-item **/
|
||||
.arco-form-item-content-flex {
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<div class="flex flex-1 items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<a-tooltip :content="props.title">
|
||||
<span> {{ props.title }}</span>
|
||||
<span> {{ characterLimit(props.title) }}</span>
|
||||
</a-tooltip>
|
||||
|
||||
<slot name="headerLeft"></slot>
|
||||
|
@ -119,8 +119,8 @@
|
|||
|
||||
import useFullScreen from '@/hooks/useFullScreen';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { characterLimit } from '@/utils';
|
||||
import { getMaxZIndexLayer } from '@/utils/dom';
|
||||
|
||||
// 懒加载描述组件
|
||||
const MsDescription = defineAsyncComponent(() => import('@/components/pure/ms-description/index.vue'));
|
||||
|
||||
|
|
|
@ -149,11 +149,8 @@ export const TEXTAREA = {
|
|||
value: '',
|
||||
props: {
|
||||
'placeholder': t('formCreate.PleaseEnter'),
|
||||
'auto-size': {
|
||||
minRows: 1,
|
||||
maxRows: 3,
|
||||
},
|
||||
'max-length': 1000,
|
||||
'auto-size': '{ minRows: 1 }',
|
||||
},
|
||||
};
|
||||
export const JIRAKEY = {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<template v-if="showJumpMethod">
|
||||
<div class="mb-2 flex items-center">
|
||||
<span class="text-[var(--color-text-4)]">{{ t('msTable.columnSetting.mode') }}</span>
|
||||
<a-tooltip>
|
||||
<a-tooltip position="right">
|
||||
<template #content>
|
||||
<span>{{ t('msTable.columnSetting.tooltipContentDrawer') }}</span
|
||||
><br />
|
||||
|
|
|
@ -309,46 +309,116 @@ export const pathMap: PathMapItem[] = [
|
|||
level: MENU_LEVEL[1],
|
||||
},
|
||||
{
|
||||
key: 'SETTING_ORGANIZATION_TEMPLATE', // 系统设置-组织-模板
|
||||
locale: 'menu.settings.organization.template',
|
||||
key: 'SETTING_ORGANIZATION_TEMPLATE', // 系统设置-组织-模板管理
|
||||
locale: 'menu.projectManagement.templateManager',
|
||||
route: RouteEnum.SETTING_ORGANIZATION_TEMPLATE,
|
||||
permission: [],
|
||||
level: MENU_LEVEL[1],
|
||||
},
|
||||
{
|
||||
key: 'SETTING_ORGANIZATION_TEMPLATE_FILED_SETTING', // 系统设置-模板管理-字段设置
|
||||
locale: 'menu.settings.organization.templateFieldSetting',
|
||||
route: RouteEnum.SETTING_ORGANIZATION_TEMPLATE_FILED_SETTING,
|
||||
permission: [],
|
||||
level: MENU_LEVEL[1],
|
||||
},
|
||||
{
|
||||
key: 'SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT', // 系统设置-模板管理列表
|
||||
locale: 'menu.settings.organization.templateManagementList',
|
||||
route: RouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT,
|
||||
permission: [],
|
||||
level: MENU_LEVEL[1],
|
||||
},
|
||||
{
|
||||
key: 'SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT_CREATE', // 系统设置-模板管理-创建
|
||||
locale: 'menu.settings.organization.templateManagementDetail',
|
||||
route: RouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT_DETAIL,
|
||||
permission: [],
|
||||
level: MENU_LEVEL[1],
|
||||
},
|
||||
{
|
||||
key: 'SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT_UPDATE', // 系统设置-模板管理-更新模版
|
||||
locale: 'menu.settings.organization.templateManagementEdit',
|
||||
route: RouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT_DETAIL,
|
||||
permission: [],
|
||||
level: MENU_LEVEL[1],
|
||||
},
|
||||
{
|
||||
key: 'SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT_WORKFLOW', // 系统设置-模板管理-工作流
|
||||
locale: 'menu.settings.organization.templateManagementWorkFlow',
|
||||
route: RouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT_WORKFLOW,
|
||||
permission: [],
|
||||
level: MENU_LEVEL[1],
|
||||
children: [
|
||||
{
|
||||
key: 'SETTING_ORGANIZATION_TEMPLATE_FUNCTIONAL', // 模板管理-用例模板
|
||||
locale: 'system.orgTemplate.caseTemplates',
|
||||
route: RouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT,
|
||||
permission: [],
|
||||
routeQuery: {
|
||||
type: 'FUNCTIONAL',
|
||||
},
|
||||
level: MENU_LEVEL[1],
|
||||
children: [
|
||||
{
|
||||
key: 'SETTING_ORGANIZATION_TEMPLATE_FUNCTIONAL_FIELD', // 模板管理-用例模板-用例模板字段管理
|
||||
locale: 'system.orgTemplate.field',
|
||||
route: RouteEnum.SETTING_ORGANIZATION_TEMPLATE_FILED_SETTING,
|
||||
permission: [],
|
||||
routeQuery: {
|
||||
type: 'FUNCTIONAL',
|
||||
},
|
||||
level: MENU_LEVEL[1],
|
||||
},
|
||||
{
|
||||
key: 'SETTING_ORGANIZATION_TEMPLATE_FUNCTIONAL_TEMPLATE', // 模板管理-用例模板-用例模板管理
|
||||
locale: 'system.orgTemplate.caseTemplateManagement',
|
||||
route: RouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT,
|
||||
permission: [],
|
||||
routeQuery: {
|
||||
type: 'FUNCTIONAL',
|
||||
},
|
||||
level: MENU_LEVEL[1],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'SETTING_ORGANIZATION_TEMPLATE_API', // 模板管理-接口模板
|
||||
locale: 'system.orgTemplate.APITemplates',
|
||||
route: RouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT,
|
||||
permission: [],
|
||||
routeQuery: {
|
||||
type: 'API',
|
||||
},
|
||||
level: MENU_LEVEL[1],
|
||||
children: [
|
||||
{
|
||||
key: 'SETTING_ORGANIZATION_TEMPLATE_API_FIELD', // 模板管理-接口模板-接口模板字段管理
|
||||
locale: 'system.orgTemplate.field',
|
||||
route: RouteEnum.SETTING_ORGANIZATION_TEMPLATE_FILED_SETTING,
|
||||
permission: [],
|
||||
routeQuery: {
|
||||
type: 'API',
|
||||
},
|
||||
level: MENU_LEVEL[1],
|
||||
},
|
||||
{
|
||||
key: 'SETTING_ORGANIZATION_TEMPLATE_API_TEMPLATE', // 模板管理-接口模板-接口模板管理
|
||||
locale: 'system.orgTemplate.apiTemplateManagement',
|
||||
route: RouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT,
|
||||
permission: [],
|
||||
routeQuery: {
|
||||
type: 'API',
|
||||
},
|
||||
level: MENU_LEVEL[1],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'SETTING_ORGANIZATION_TEMPLATE_BUG', // 模板管理-缺陷模板
|
||||
locale: 'system.orgTemplate.defectTemplates',
|
||||
route: RouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT,
|
||||
permission: [],
|
||||
routeQuery: {
|
||||
type: 'BUG',
|
||||
},
|
||||
level: MENU_LEVEL[1],
|
||||
children: [
|
||||
{
|
||||
key: 'SETTING_ORGANIZATION_TEMPLATE_BUG_FIELD', // 模板管理-缺陷模板管理-字段管理
|
||||
locale: 'system.orgTemplate.field',
|
||||
route: RouteEnum.SETTING_ORGANIZATION_TEMPLATE_FILED_SETTING,
|
||||
permission: [],
|
||||
routeQuery: {
|
||||
type: 'BUG',
|
||||
},
|
||||
level: MENU_LEVEL[1],
|
||||
},
|
||||
{
|
||||
key: 'SETTING_ORGANIZATION_TEMPLATE_BUG_TEMPLATE', // 模板管理-缺陷模板-缺陷模板管理
|
||||
locale: 'system.orgTemplate.bugTemplateManagement',
|
||||
route: RouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT,
|
||||
permission: [],
|
||||
routeQuery: {
|
||||
type: 'BUG',
|
||||
},
|
||||
level: MENU_LEVEL[1],
|
||||
},
|
||||
{
|
||||
key: 'SETTING_ORGANIZATION_TEMPLATE_BUG_WORKFLOW', // 模板管理-缺陷模板-缺陷工作流
|
||||
locale: 'menu.settings.organization.templateManagementWorkFlow',
|
||||
route: RouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT_WORKFLOW,
|
||||
permission: [],
|
||||
level: MENU_LEVEL[1],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -406,54 +476,118 @@ export const pathMap: PathMapItem[] = [
|
|||
],
|
||||
},
|
||||
{
|
||||
key: 'PROJECT_MANAGEMENT_TEMPLATE', // 项目管理-模板管理
|
||||
locale: 'menu.settings.organization.template',
|
||||
key: 'PROJECT_MANAGEMENT_TEMPLATE', // 系统设置-组织-模板管理
|
||||
locale: 'menu.projectManagement.templateManager',
|
||||
route: RouteEnum.PROJECT_MANAGEMENT_TEMPLATE,
|
||||
permission: [],
|
||||
level: MENU_LEVEL[2],
|
||||
},
|
||||
{
|
||||
key: 'PROJECT_MANAGEMENT_TEMPLATE_FIELD_SETTING', // 项目管理-模板管理-字段设置
|
||||
locale: 'menu.settings.organization.templateFieldSetting',
|
||||
route: RouteEnum.PROJECT_MANAGEMENT_TEMPLATE_FIELD_SETTING,
|
||||
permission: [],
|
||||
level: MENU_LEVEL[2],
|
||||
},
|
||||
{
|
||||
key: 'PROJECT_CUSTOM_FIELD', // 项目管理-模板管理-字段设置-新增字段
|
||||
locale: 'system.orgTemplate.addField',
|
||||
route: '',
|
||||
permission: [],
|
||||
level: MENU_LEVEL[2],
|
||||
},
|
||||
{
|
||||
key: 'PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT', // 项目管理-模板管理列表
|
||||
locale: 'menu.settings.organization.templateManagementList',
|
||||
route: RouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT,
|
||||
permission: [],
|
||||
level: MENU_LEVEL[2],
|
||||
},
|
||||
{
|
||||
key: 'PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT_CREATE', // 项目管理-模板管理-创建模版
|
||||
locale: 'menu.settings.organization.templateManagementDetail',
|
||||
route: RouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT_DETAIL,
|
||||
permission: [],
|
||||
level: MENU_LEVEL[2],
|
||||
},
|
||||
{
|
||||
key: 'PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT_UPDATE', // 项目管理-模板管理-更新模版
|
||||
locale: 'menu.settings.organization.templateManagementEdit',
|
||||
route: RouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT_DETAIL,
|
||||
permission: [],
|
||||
level: MENU_LEVEL[2],
|
||||
},
|
||||
{
|
||||
key: 'PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT_WORKFLOW', // 项目管理-模板管理-工作流
|
||||
locale: 'menu.settings.organization.templateManagementWorkFlow',
|
||||
route: RouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT_WORKFLOW,
|
||||
permission: [],
|
||||
level: MENU_LEVEL[2],
|
||||
level: MENU_LEVEL[1],
|
||||
children: [
|
||||
{
|
||||
key: 'PROJECT_MANAGEMENT_TEMPLATE_FUNCTIONAL', // 模板管理-用例模板
|
||||
locale: 'system.orgTemplate.caseTemplates',
|
||||
route: RouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT,
|
||||
permission: [],
|
||||
routeQuery: {
|
||||
type: 'FUNCTIONAL',
|
||||
},
|
||||
level: MENU_LEVEL[1],
|
||||
children: [
|
||||
{
|
||||
key: 'PROJECT_MANAGEMENT_TEMPLATE_FUNCTIONAL_FIELD', // 模板管理-用例模板-用例模板字段管理
|
||||
locale: 'system.orgTemplate.field',
|
||||
route: RouteEnum.PROJECT_MANAGEMENT_TEMPLATE_FIELD_SETTING,
|
||||
permission: [],
|
||||
routeQuery: {
|
||||
type: 'FUNCTIONAL',
|
||||
},
|
||||
level: MENU_LEVEL[1],
|
||||
},
|
||||
{
|
||||
key: 'PROJECT_MANAGEMENT_TEMPLATE_FUNCTIONAL_TEMPLATE', // 模板管理-用例模板-用例模板管理
|
||||
locale: 'system.orgTemplate.caseTemplateManagement',
|
||||
route: RouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT,
|
||||
permission: [],
|
||||
routeQuery: {
|
||||
type: 'FUNCTIONAL',
|
||||
},
|
||||
level: MENU_LEVEL[1],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'PROJECT_MANAGEMENT_TEMPLATE_API', // 模板管理-接口模板
|
||||
locale: 'system.orgTemplate.APITemplates',
|
||||
route: RouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT,
|
||||
permission: [],
|
||||
routeQuery: {
|
||||
type: 'API',
|
||||
},
|
||||
level: MENU_LEVEL[1],
|
||||
children: [
|
||||
{
|
||||
key: 'PROJECT_MANAGEMENT_TEMPLATE_API_FIELD', // 模板管理-接口模板-接口模板字段管理
|
||||
locale: 'system.orgTemplate.field',
|
||||
route: RouteEnum.PROJECT_MANAGEMENT_TEMPLATE_FIELD_SETTING,
|
||||
permission: [],
|
||||
routeQuery: {
|
||||
type: 'API',
|
||||
},
|
||||
level: MENU_LEVEL[1],
|
||||
},
|
||||
{
|
||||
key: 'PROJECT_MANAGEMENT_TEMPLATE_API_TEMPLATE', // 模板管理-接口模板-接口模板管理
|
||||
locale: 'system.orgTemplate.apiTemplateManagement',
|
||||
route: RouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT,
|
||||
permission: [],
|
||||
routeQuery: {
|
||||
type: 'API',
|
||||
},
|
||||
level: MENU_LEVEL[1],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'PROJECT_MANAGEMENT_TEMPLATE_BUG', // 模板管理-缺陷模板
|
||||
locale: 'system.orgTemplate.defectTemplates',
|
||||
route: RouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT,
|
||||
permission: [],
|
||||
routeQuery: {
|
||||
type: 'BUG',
|
||||
},
|
||||
level: MENU_LEVEL[1],
|
||||
children: [
|
||||
{
|
||||
key: 'PROJECT_MANAGEMENT_TEMPLATE_BUG_FIELD', // 模板管理-缺陷模板管理-字段管理
|
||||
locale: 'system.orgTemplate.field',
|
||||
route: RouteEnum.PROJECT_MANAGEMENT_TEMPLATE_FIELD_SETTING,
|
||||
permission: [],
|
||||
routeQuery: {
|
||||
type: 'BUG',
|
||||
},
|
||||
level: MENU_LEVEL[1],
|
||||
},
|
||||
{
|
||||
key: 'PROJECT_MANAGEMENT_TEMPLATE_BUG_TEMPLATE', // 模板管理-缺陷模板-缺陷模板管理
|
||||
locale: 'system.orgTemplate.bugTemplateManagement',
|
||||
route: RouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT,
|
||||
permission: [],
|
||||
routeQuery: {
|
||||
type: 'BUG',
|
||||
},
|
||||
level: MENU_LEVEL[1],
|
||||
},
|
||||
{
|
||||
key: 'PROJECT_MANAGEMENT_TEMPLATE_BUG_WORKFLOW', // 模板管理-缺陷模板-缺陷工作流
|
||||
locale: 'menu.settings.organization.templateManagementWorkFlow',
|
||||
route: RouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT_WORKFLOW,
|
||||
permission: [],
|
||||
level: MENU_LEVEL[1],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
key: 'PROJECT_MANAGEMENT_FILE_MANAGEMENT', // 项目管理-文件管理
|
||||
locale: 'menu.projectManagement.fileManagement',
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
import { defineStore } from 'pinia';
|
||||
|
||||
import { getCaseModulesCounts, getRecycleModulesCounts } from '@/api/modules/case-management/featureCase';
|
||||
import {
|
||||
getCaseDefaultFields,
|
||||
getCaseDetail,
|
||||
getCaseModulesCounts,
|
||||
getRecycleModulesCounts,
|
||||
} from '@/api/modules/case-management/featureCase';
|
||||
|
||||
import type { CaseModuleQueryParams, TabItemType } from '@/models/caseManagement/featureCase';
|
||||
import { ModuleTreeNode } from '@/models/common';
|
||||
import type { CaseModuleQueryParams, CustomAttributes, TabItemType } from '@/models/caseManagement/featureCase';
|
||||
import { ModuleTreeNode, TableQueryParams } from '@/models/common';
|
||||
|
||||
import useAppStore from '../app';
|
||||
|
||||
const useFeatureCaseStore = defineStore('featureCase', {
|
||||
persist: true,
|
||||
|
@ -15,6 +22,8 @@ const useFeatureCaseStore = defineStore('featureCase', {
|
|||
operatingState: boolean; // 操作状态
|
||||
tabSettingList: TabItemType[]; // 详情tab
|
||||
activeTab: string; // 激活tab
|
||||
defaultFields: CustomAttributes[];
|
||||
defaultCount: Record<string, any>;
|
||||
} => ({
|
||||
moduleId: [],
|
||||
caseTree: [],
|
||||
|
@ -23,6 +32,8 @@ const useFeatureCaseStore = defineStore('featureCase', {
|
|||
operatingState: false,
|
||||
tabSettingList: [],
|
||||
activeTab: 'detail',
|
||||
defaultFields: [],
|
||||
defaultCount: {},
|
||||
}),
|
||||
actions: {
|
||||
// 设置选择moduleId
|
||||
|
@ -38,18 +49,17 @@ const useFeatureCaseStore = defineStore('featureCase', {
|
|||
this.caseTree = tree;
|
||||
},
|
||||
// 获取模块数量
|
||||
async getCaseModulesCount(params: CaseModuleQueryParams) {
|
||||
async getCaseModulesCount(params: TableQueryParams) {
|
||||
try {
|
||||
this.modulesCount = {};
|
||||
// this.modulesCount = {};
|
||||
this.modulesCount = await getCaseModulesCounts(params);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
// 获取模块数量
|
||||
async getRecycleModulesCount(params: CaseModuleQueryParams) {
|
||||
async getRecycleModulesCount(params: TableQueryParams) {
|
||||
try {
|
||||
this.recycleModulesCount = {};
|
||||
this.recycleModulesCount = await getRecycleModulesCounts(params);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
@ -90,6 +100,39 @@ const useFeatureCaseStore = defineStore('featureCase', {
|
|||
};
|
||||
});
|
||||
},
|
||||
// 获取默认模版
|
||||
async getDefaultTemplate() {
|
||||
try {
|
||||
const appStore = useAppStore();
|
||||
const result = await getCaseDefaultFields(appStore.currentProjectId);
|
||||
this.defaultFields = result.customFields;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
// 获取系统字段用例等级
|
||||
getSystemCaseLevelFields() {
|
||||
return this.defaultFields.find((item: any) => item.internal && item.fieldName === '用例等级')?.options || [];
|
||||
},
|
||||
|
||||
// 获取详情
|
||||
async getCaseCounts(caseId: string) {
|
||||
try {
|
||||
const result = await getCaseDetail(caseId);
|
||||
const { bugCount, caseCount, caseReviewCount, demandCount, relateEdgeCount, testPlanCount } = result;
|
||||
const countMap: Record<string, any> = {
|
||||
case: caseCount,
|
||||
dependency: relateEdgeCount,
|
||||
caseReview: caseReviewCount,
|
||||
testPlan: testPlanCount,
|
||||
bug: bugCount,
|
||||
requirement: demandCount,
|
||||
};
|
||||
this.initCountMap(countMap);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -160,10 +160,12 @@
|
|||
|
||||
// 复制步骤
|
||||
function copyStep(record: StepList) {
|
||||
stepData.value.push({
|
||||
const index = stepData.value.map((item: any) => item.id).indexOf(record.id);
|
||||
const insertItem = {
|
||||
...record,
|
||||
id: getGenerateId(),
|
||||
});
|
||||
};
|
||||
stepData.value.splice(index + 1, 0, insertItem);
|
||||
}
|
||||
|
||||
// 删除步骤
|
||||
|
|
|
@ -158,6 +158,7 @@
|
|||
formRef.value?.resetFields();
|
||||
form.value = { ...initForm };
|
||||
formRules.value = [{ ...initDefaultForm }];
|
||||
form.value.tags = [];
|
||||
}
|
||||
|
||||
async function confirmHandler(enable: boolean | undefined) {
|
||||
|
@ -174,12 +175,12 @@
|
|||
});
|
||||
const { selectedIds, selectAll } = props.batchParams;
|
||||
const params: TableQueryParams = {
|
||||
selectedIds,
|
||||
selectIds: selectAll ? [] : selectedIds,
|
||||
selectAll,
|
||||
projectId: currentProjectId.value,
|
||||
append: enable as boolean,
|
||||
tags: form.value.tags,
|
||||
customField,
|
||||
customField: form.value.selectedAttrsId === 'systemTags' ? {} : customField,
|
||||
};
|
||||
await batchEditAttrs(params);
|
||||
Message.success(t('caseManagement.featureCase.editSuccess'));
|
||||
|
|
|
@ -186,6 +186,12 @@
|
|||
<span class="label"> {{ t('caseManagement.featureCase.tableColumnCreateTime') }}</span>
|
||||
<span>{{ dayjs(detailInfo?.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
|
||||
</div>
|
||||
<div class="baseItem">
|
||||
<span class="label"> {{ t('caseManagement.featureCase.tableColumnCreateTime') }}</span>
|
||||
<span>
|
||||
<MsTag v-for="item of detailInfo.tags" :key="item"> {{ item }} </MsTag>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</MsSplitBox>
|
||||
|
@ -216,6 +222,7 @@
|
|||
import type { FormItem, FormRuleItem } from '@/components/pure/ms-form-create/types';
|
||||
import MsSplitBox from '@/components/pure/ms-split-box/index.vue';
|
||||
import type { MsPaginationI } from '@/components/pure/ms-table/type';
|
||||
import MsTag from '@/components/pure/ms-tag/ms-tag.vue';
|
||||
import caseLevel from '@/components/business/ms-case-associate/caseLevel.vue';
|
||||
import type { CaseLevel } from '@/components/business/ms-case-associate/types';
|
||||
import inputComment from '@/components/business/ms-comment/input.vue';
|
||||
|
@ -365,6 +372,7 @@
|
|||
|
||||
async function updateSuccess() {
|
||||
detailDrawerRef.value?.initDetail();
|
||||
emit('success');
|
||||
}
|
||||
|
||||
function updateHandler(type: string) {
|
||||
|
@ -627,6 +635,7 @@
|
|||
line-height: 32px;
|
||||
@apply flex;
|
||||
.label {
|
||||
flex-shrink: 0;
|
||||
width: 38%;
|
||||
color: var(--color-text-3);
|
||||
}
|
||||
|
|
|
@ -37,12 +37,14 @@
|
|||
@change="changeHandler"
|
||||
>
|
||||
<template #num="{ record, rowIndex }">
|
||||
<a-button type="text" class="flex w-full" @click="showCaseDetail(record.id, rowIndex)">{{ record.num }}</a-button>
|
||||
<span type="text" class="px-0" @click="showCaseDetail(record.id, rowIndex)">{{ record.num }}</span>
|
||||
</template>
|
||||
<template #name="{ record, rowIndex }">
|
||||
<span type="text" class="px-0" @click="showCaseDetail(record.id, rowIndex)">{{ record.name }}</span>
|
||||
<a-button type="text" class="flex w-full" @click="showCaseDetail(record.id, rowIndex)">{{
|
||||
record.name
|
||||
}}</a-button>
|
||||
</template>
|
||||
<template #updateUser="{ record }">
|
||||
<template #updateUserName="{ record }">
|
||||
<span type="text" class="px-0">{{ record.updateUserName || '-' }}</span>
|
||||
</template>
|
||||
<template #caseLevel="{ record }">
|
||||
|
@ -337,7 +339,7 @@
|
|||
getCustomFieldsTable,
|
||||
updateCaseRequest,
|
||||
} from '@/api/modules/case-management/featureCase';
|
||||
import { getProjectMemberOptions } from '@/api/modules/project-management/projectMember';
|
||||
import { getProjectOptions } from '@/api/modules/project-management/projectMember';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import { useAppStore, useTableStore } from '@/store';
|
||||
|
@ -491,6 +493,7 @@
|
|||
{
|
||||
title: 'caseManagement.featureCase.tableColumnLevel',
|
||||
slotName: 'caseLevel',
|
||||
dataIndex: 'caseLevel',
|
||||
titleSlotName: 'caseLevelFilter',
|
||||
showInTable: true,
|
||||
width: 200,
|
||||
|
@ -541,7 +544,7 @@
|
|||
},
|
||||
{
|
||||
title: 'caseManagement.featureCase.tableColumnUpdateUser',
|
||||
slotName: 'updateUser',
|
||||
slotName: 'updateUserName,',
|
||||
dataIndex: 'updateUser',
|
||||
titleSlotName: 'updateUserFilter',
|
||||
sortable: {
|
||||
|
@ -657,9 +660,11 @@
|
|||
const searchCustomFields = ref<FilterFormItem[]>([]);
|
||||
const scrollWidth = ref<number>(3400);
|
||||
const memberOptions = ref<{ label: string; value: string }[]>([]);
|
||||
const updateUserFilters = ref<string[]>([]);
|
||||
const createUserFilters = ref<string[]>([]);
|
||||
async function initFilter() {
|
||||
const result = await getCustomFieldsTable(currentProjectId.value);
|
||||
memberOptions.value = await getProjectMemberOptions(appStore.currentProjectId, keyword.value);
|
||||
memberOptions.value = await getProjectOptions(appStore.currentProjectId, keyword.value);
|
||||
memberOptions.value = memberOptions.value.map((e: any) => ({ label: e.name, value: e.id }));
|
||||
filterConfigList.value = [
|
||||
{
|
||||
|
@ -796,7 +801,7 @@
|
|||
selectable: true,
|
||||
showJumpMethod: true,
|
||||
showSetting: true,
|
||||
heightUsed: 374,
|
||||
heightUsed: 380,
|
||||
enableDrag: true,
|
||||
},
|
||||
(record) => {
|
||||
|
@ -815,13 +820,41 @@
|
|||
updateCaseName
|
||||
);
|
||||
|
||||
const batchParams = ref<BatchActionQueryParams>({
|
||||
selectedIds: [],
|
||||
selectAll: false,
|
||||
excludeIds: [],
|
||||
currentSelectCount: 0,
|
||||
});
|
||||
const statusFilters = ref<string[]>(Object.keys(statusIconMap));
|
||||
const caseFilters = ref<string[]>([]);
|
||||
const executeResultFilters = ref(Object.keys(executionResultMap));
|
||||
|
||||
function initTableParams() {
|
||||
return {
|
||||
keyword: keyword.value,
|
||||
moduleIds: props.activeFolder === 'all' ? [] : [props.activeFolder, ...props.offspringIds],
|
||||
projectId: currentProjectId.value,
|
||||
|
||||
filter: {
|
||||
reviewStatus: statusFilters.value,
|
||||
caseLevel: caseFilters.value,
|
||||
lastExecuteResult: executeResultFilters.value,
|
||||
updateUserName: updateUserFilters.value,
|
||||
createUserName: createUserFilters.value,
|
||||
},
|
||||
condition: {
|
||||
keyword: keyword.value,
|
||||
filter: propsRes.value.filter,
|
||||
combine: batchParams.value.condition,
|
||||
},
|
||||
};
|
||||
}
|
||||
// 获取父组件模块数量
|
||||
function emitTableParams() {
|
||||
const moduleIds = props.activeFolder === 'all' ? [] : [props.activeFolder, ...props.offspringIds];
|
||||
emit('init', {
|
||||
keyword: keyword.value,
|
||||
moduleIds,
|
||||
projectId: currentProjectId.value,
|
||||
...initTableParams(),
|
||||
current: propsRes.value.msPagination?.current,
|
||||
pageSize: propsRes.value.msPagination?.pageSize,
|
||||
});
|
||||
|
@ -837,7 +870,7 @@
|
|||
projectId: currentProjectId.value,
|
||||
moduleIds: [],
|
||||
});
|
||||
const statusFilters = ref<string[]>(Object.keys(statusIconMap));
|
||||
|
||||
const caseLevelFields = ref<Record<string, any>>({});
|
||||
// 用例等级表头检索
|
||||
const caseFilterVisible = ref(false);
|
||||
|
@ -846,10 +879,6 @@
|
|||
return caseLevelFields.value?.options || [];
|
||||
});
|
||||
|
||||
const executeResultFilters = ref(Object.keys(executionResultMap));
|
||||
const updateUserFilters = ref(memberOptions.value.map((item) => item.value));
|
||||
const createUserFilters = ref(memberOptions.value.map((item) => item.value));
|
||||
|
||||
function getExecuteResultList() {
|
||||
const list: any = [];
|
||||
Object.keys(executionResultMap).forEach((key) => {
|
||||
|
@ -860,7 +889,6 @@
|
|||
return list;
|
||||
}
|
||||
const executeResultFilterList = ref(getExecuteResultList());
|
||||
const caseFilters = ref<string[]>([]);
|
||||
|
||||
function getLoadListParams() {
|
||||
if (props.activeFolder === 'all') {
|
||||
|
@ -868,17 +896,7 @@
|
|||
} else {
|
||||
searchParams.value.moduleIds = [...featureCaseStore.moduleId, ...props.offspringIds];
|
||||
}
|
||||
setLoadListParams({
|
||||
...searchParams.value,
|
||||
keyword: keyword.value,
|
||||
filter: {
|
||||
reviewStatus: statusFilters.value,
|
||||
caseLevel: caseFilters.value,
|
||||
lastExecuteResult: executeResultFilters.value,
|
||||
updateUserName: updateUserFilters.value,
|
||||
createUserName: createUserFilters.value,
|
||||
},
|
||||
});
|
||||
setLoadListParams(initTableParams());
|
||||
}
|
||||
|
||||
// 执行结果表头检索
|
||||
|
@ -971,13 +989,6 @@
|
|||
const selectedModuleKeys = ref<string[]>([]); // 移动文件选中节点
|
||||
const batchMoveCaseLoading = ref(false);
|
||||
|
||||
const batchParams = ref<BatchActionQueryParams>({
|
||||
selectedIds: [],
|
||||
selectAll: false,
|
||||
excludeIds: [],
|
||||
currentSelectCount: 0,
|
||||
});
|
||||
|
||||
const isMove = ref<boolean>(false);
|
||||
// 批量移动和复制
|
||||
async function handleCaseMoveOrCopy() {
|
||||
|
@ -987,7 +998,11 @@
|
|||
selectIds: batchParams.value.selectedIds || [],
|
||||
selectAll: !!batchParams.value?.selectAll,
|
||||
excludeIds: batchParams.value?.excludeIds || [],
|
||||
condition: { keyword: keyword.value },
|
||||
condition: {
|
||||
keyword: keyword.value,
|
||||
filter: propsRes.value.filter,
|
||||
combine: batchParams.value.condition,
|
||||
},
|
||||
projectId: currentProjectId.value,
|
||||
moduleIds: props.activeFolder === 'all' ? [] : [props.activeFolder, ...props.offspringIds],
|
||||
moduleId: selectedModuleKeys.value[0],
|
||||
|
@ -1056,9 +1071,17 @@
|
|||
},
|
||||
onBeforeOk: async () => {
|
||||
try {
|
||||
const { selectedIds, selectAll, excludeIds } = batchParams.value;
|
||||
await batchDeleteCase({
|
||||
selectIds: batchParams.value.selectedIds as string[],
|
||||
projectId: currentProjectId.value,
|
||||
selectIds: selectAll ? [] : selectedIds,
|
||||
excludeIds: excludeIds || [],
|
||||
condition: {
|
||||
keyword: keyword.value,
|
||||
filter: propsRes.value.filter,
|
||||
combine: batchParams.value.condition,
|
||||
},
|
||||
selectAll,
|
||||
});
|
||||
resetSelector();
|
||||
Message.success(t('common.deleteSuccess'));
|
||||
|
@ -1132,14 +1155,12 @@
|
|||
|
||||
const fetchData = (keywordStr = '') => {
|
||||
setKeyword(keywordStr);
|
||||
getLoadListParams();
|
||||
loadList();
|
||||
initData();
|
||||
};
|
||||
|
||||
function successHandler() {
|
||||
initData();
|
||||
emitTableParams();
|
||||
resetSelector();
|
||||
initData();
|
||||
}
|
||||
const showDetailDrawer = ref(false);
|
||||
const activeDetailId = ref<string>('');
|
||||
|
@ -1165,6 +1186,7 @@
|
|||
|
||||
// 处理自定义字段展示
|
||||
async function getDefaultFields() {
|
||||
customFieldsColumns = [];
|
||||
const result = await getCaseDefaultFields(currentProjectId.value);
|
||||
initDefaultFields.value = result.customFields;
|
||||
customFieldsColumns = initDefaultFields.value
|
||||
|
@ -1180,7 +1202,7 @@
|
|||
};
|
||||
});
|
||||
|
||||
caseLevelFields.value = result.customFields.find((item: any) => item.internal);
|
||||
caseLevelFields.value = result.customFields.find((item: any) => item.internal && item.fieldName === '用例等级');
|
||||
caseFilters.value = caseLevelFields.value.options.map((item: any) => item.value);
|
||||
fullColumns = [
|
||||
...columns.slice(0, columns.length - 1),
|
||||
|
@ -1419,7 +1441,7 @@
|
|||
showCaseDetail(route.query.id as string, 0);
|
||||
}
|
||||
await getDefaultFields();
|
||||
initFilter();
|
||||
await initFilter();
|
||||
initData();
|
||||
});
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@
|
|||
<a-form-item
|
||||
field="moduleId"
|
||||
asterisk-position="end"
|
||||
:label="t('system.orgTemplate.modules')"
|
||||
:label="t('caseManagement.featureCase.ModuleOwned')"
|
||||
:rules="[{ required: true, message: t('system.orgTemplate.moduleRuleTip') }]"
|
||||
@change="changeSelectModule"
|
||||
>
|
||||
|
@ -505,7 +505,7 @@
|
|||
const { customFields, attachments, steps } = detailResult;
|
||||
form.value = {
|
||||
...detailResult,
|
||||
name: route.params.mode === 'copy' ? `${detailResult.name}_copy` : detailResult.name,
|
||||
name: route.params.mode === 'copy' ? `copy_${detailResult.name}` : detailResult.name,
|
||||
};
|
||||
// 处理自定义字段
|
||||
formRules.value = (customFields || []).map((item: any) => {
|
||||
|
|
|
@ -66,8 +66,9 @@
|
|||
:filter-config-list="filterConfigList"
|
||||
:custom-fields-config-list="searchCustomFields"
|
||||
:row-count="filterRowCount"
|
||||
@keyword-search="initRecycleList"
|
||||
@keyword-search="fetchData"
|
||||
@adv-search="handleAdvSearch"
|
||||
@refresh="fetchData()"
|
||||
>
|
||||
<template #left>
|
||||
<div class="text-[var(--color-text-1)]"
|
||||
|
@ -196,9 +197,12 @@
|
|||
<span class="one-line-text inline-block">{{ getModules(record.moduleId) }}</span>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template #updateUser="{ record }">
|
||||
<template #updateUserName="{ record }">
|
||||
<span type="text" class="px-0">{{ record.updateUserName || '-' }}</span>
|
||||
</template>
|
||||
<template #createUserName="{ record }">
|
||||
<span type="text" class="px-0">{{ record.createUserName || '-' }}</span>
|
||||
</template>
|
||||
<!-- 回收站自定义字段 -->
|
||||
<template v-for="item in customFieldsColumns" :key="item.slotName" #[item.slotName]="{ record }">
|
||||
<a-tooltip
|
||||
|
@ -260,19 +264,14 @@
|
|||
recoverRecycleCase,
|
||||
restoreCaseList,
|
||||
} from '@/api/modules/case-management/featureCase';
|
||||
import { getProjectMemberOptions } from '@/api/modules/project-management/projectMember';
|
||||
import { getProjectOptions } from '@/api/modules/project-management/projectMember';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import { useAppStore, useTableStore } from '@/store';
|
||||
import useFeatureCaseStore from '@/store/modules/case/featureCase';
|
||||
import { characterLimit, findNodeByKey, findNodePathByKey, mapTree } from '@/utils';
|
||||
|
||||
import type {
|
||||
BatchMoveOrCopyType,
|
||||
CaseManagementTable,
|
||||
CaseModuleQueryParams,
|
||||
CustomAttributes,
|
||||
} from '@/models/caseManagement/featureCase';
|
||||
import type { BatchMoveOrCopyType, CaseManagementTable, CustomAttributes } from '@/models/caseManagement/featureCase';
|
||||
import type { ModuleTreeNode, TableQueryParams } from '@/models/common';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
||||
|
@ -291,7 +290,7 @@
|
|||
const currentProjectId = computed(() => appStore.currentProjectId);
|
||||
const scrollWidth = ref<number>(3400);
|
||||
|
||||
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector, setAdvanceFilter } = useTable(
|
||||
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector, setAdvanceFilter, setKeyword } = useTable(
|
||||
getRecycleListRequest,
|
||||
{
|
||||
tableKey: TableKeyEnum.CASE_MANAGEMENT_RECYCLE_TABLE,
|
||||
|
@ -299,7 +298,7 @@
|
|||
selectable: true,
|
||||
showSetting: true,
|
||||
showJumpMethod: true,
|
||||
heightUsed: 340,
|
||||
heightUsed: 380,
|
||||
enableDrag: true,
|
||||
},
|
||||
(record) => ({
|
||||
|
@ -395,7 +394,7 @@
|
|||
},
|
||||
{
|
||||
title: 'caseManagement.featureCase.tableColumnUpdateUser',
|
||||
slotName: 'updateUser',
|
||||
slotName: 'updateUserName',
|
||||
dataIndex: 'updateUser',
|
||||
titleSlotName: 'updateUserFilter',
|
||||
sortable: {
|
||||
|
@ -421,7 +420,8 @@
|
|||
{
|
||||
title: 'caseManagement.featureCase.tableColumnCreateUser',
|
||||
slotName: 'createUserName',
|
||||
dataIndex: 'createUserName',
|
||||
dataIndex: 'createUser',
|
||||
titleSlotName: 'createUserFilter',
|
||||
showInTable: true,
|
||||
width: 200,
|
||||
showDrag: true,
|
||||
|
@ -562,23 +562,30 @@
|
|||
: findNodeByKey<Record<string, any>>(caseTree.value, featureCaseStore.moduleId[0], 'id')?.name;
|
||||
});
|
||||
const memberOptions = ref<{ label: string; value: string }[]>([]);
|
||||
|
||||
const searchParams = ref<TableQueryParams>({
|
||||
projectId: currentProjectId.value,
|
||||
moduleIds: [],
|
||||
});
|
||||
|
||||
const batchParams = ref<BatchActionQueryParams>({
|
||||
selectedIds: [],
|
||||
selectAll: false,
|
||||
excludeIds: [],
|
||||
currentSelectCount: 0,
|
||||
});
|
||||
|
||||
// 用例等级表头检索
|
||||
const statusFilters = ref<string[]>(Object.keys(statusIconMap));
|
||||
const caseLevelFields = ref<Record<string, any>>({});
|
||||
// 用例等级表头检索
|
||||
const caseFilterVisible = ref(false);
|
||||
const caseLevelList = computed(() => {
|
||||
return caseLevelFields.value?.options || [];
|
||||
});
|
||||
const caseFilters = ref<string[]>([]);
|
||||
const executeResultFilters = ref(Object.keys(executionResultMap));
|
||||
|
||||
const updateUserFilters = ref(memberOptions.value.map((item) => item.value));
|
||||
const createUserFilters = ref(memberOptions.value.map((item) => item.value));
|
||||
const updateUserFilters = ref<string[]>([]);
|
||||
const createUserFilters = ref<string[]>([]);
|
||||
|
||||
function getExecuteResultList() {
|
||||
const list: any = [];
|
||||
|
@ -591,41 +598,58 @@
|
|||
}
|
||||
const executeResultFilterList = ref(getExecuteResultList());
|
||||
|
||||
// 回收站模块树count参数
|
||||
const emitTableParams: CaseModuleQueryParams = {
|
||||
keyword: keyword.value,
|
||||
moduleIds: [],
|
||||
projectId: currentProjectId.value,
|
||||
current: propsRes.value.msPagination?.current,
|
||||
pageSize: propsRes.value.msPagination?.pageSize,
|
||||
};
|
||||
|
||||
// 获取回收站模块数量
|
||||
function initRecycleModulesCount() {
|
||||
featureCaseStore.getRecycleModulesCount(emitTableParams);
|
||||
}
|
||||
|
||||
const batchParams = ref<BatchActionQueryParams>({
|
||||
selectedIds: [],
|
||||
selectAll: false,
|
||||
excludeIds: [],
|
||||
currentSelectCount: 0,
|
||||
});
|
||||
|
||||
// 获取批量操作参数
|
||||
function getBatchParams(): BatchMoveOrCopyType {
|
||||
function getBatchParams(): TableQueryParams {
|
||||
return {
|
||||
excludeIds: batchParams.value.excludeIds,
|
||||
selectAll: batchParams.value.selectAll,
|
||||
selectIds: batchParams.value.selectedIds,
|
||||
condition: {
|
||||
keyword: keyword.value,
|
||||
},
|
||||
moduleIds: searchParams.value.moduleIds,
|
||||
projectId: currentProjectId.value,
|
||||
filter: {
|
||||
reviewStatus: statusFilters.value,
|
||||
caseLevel: caseFilters.value,
|
||||
lastExecuteResult: executeResultFilters.value,
|
||||
updateUserName: updateUserFilters.value,
|
||||
createUserName: createUserFilters.value,
|
||||
},
|
||||
condition: {
|
||||
keyword: keyword.value,
|
||||
filter: propsRes.value.filter,
|
||||
combine: batchParams.value.condition,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function initTableParams() {
|
||||
return {
|
||||
keyword: keyword.value,
|
||||
moduleIds: activeFolder.value === 'all' ? [] : [activeFolder.value, ...offspringIds.value],
|
||||
projectId: currentProjectId.value,
|
||||
filter: {
|
||||
reviewStatus: statusFilters.value,
|
||||
caseLevel: caseFilters.value,
|
||||
lastExecuteResult: executeResultFilters.value,
|
||||
updateUserName: updateUserFilters.value,
|
||||
createUserName: createUserFilters.value,
|
||||
},
|
||||
condition: {
|
||||
keyword: keyword.value,
|
||||
filter: propsRes.value.filter,
|
||||
combine: batchParams.value.condition,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// 获取回收站模块数量
|
||||
function initRecycleModulesCount() {
|
||||
featureCaseStore.getRecycleModulesCount({
|
||||
...initTableParams(),
|
||||
current: propsRes.value.msPagination?.current,
|
||||
pageSize: propsRes.value.msPagination?.pageSize,
|
||||
});
|
||||
}
|
||||
|
||||
// 获取用例参数
|
||||
function getLoadListParams() {
|
||||
if (activeFolder.value === 'all') {
|
||||
|
@ -633,17 +657,7 @@
|
|||
} else {
|
||||
searchParams.value.moduleIds = [activeFolder.value, ...offspringIds.value];
|
||||
}
|
||||
setLoadListParams({
|
||||
...searchParams.value,
|
||||
keyword: keyword.value,
|
||||
filter: {
|
||||
reviewStatus: statusFilters.value,
|
||||
caseLevel: caseFilters.value,
|
||||
lastExecuteResult: executeResultFilters.value,
|
||||
updateUserName: updateUserFilters.value,
|
||||
createUserName: createUserFilters.value,
|
||||
},
|
||||
});
|
||||
setLoadListParams(initTableParams());
|
||||
}
|
||||
|
||||
// 执行结果表头检索
|
||||
|
@ -652,19 +666,24 @@
|
|||
const createUserFilterVisible = ref(false);
|
||||
|
||||
// 初始化回收站列表
|
||||
function initRecycleList() {
|
||||
async function initRecycleList() {
|
||||
getLoadListParams();
|
||||
loadList();
|
||||
await loadList();
|
||||
initRecycleModulesCount();
|
||||
}
|
||||
|
||||
const fetchData = (keywordStr = '') => {
|
||||
setKeyword(keywordStr);
|
||||
initRecycleList();
|
||||
};
|
||||
|
||||
// 批量恢复
|
||||
async function handleBatchRecover() {
|
||||
try {
|
||||
await restoreCaseList(getBatchParams());
|
||||
Message.success(t('caseManagement.featureCase.recoveredSuccessfully'));
|
||||
initRecycleList();
|
||||
resetSelector();
|
||||
initRecycleModulesCount();
|
||||
initRecycleList();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
@ -684,9 +703,8 @@
|
|||
try {
|
||||
await batchDeleteRecycleCase(getBatchParams());
|
||||
Message.success(t('common.deleteSuccess'));
|
||||
loadList();
|
||||
resetSelector();
|
||||
initRecycleModulesCount();
|
||||
initRecycleList();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
@ -723,9 +741,8 @@
|
|||
try {
|
||||
await recoverRecycleCase(id);
|
||||
Message.success(t('caseManagement.featureCase.recoveredSuccessfully'));
|
||||
loadList();
|
||||
resetSelector();
|
||||
initRecycleModulesCount();
|
||||
initRecycleList();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
@ -746,8 +763,8 @@
|
|||
try {
|
||||
await deleteRecycleCaseList(record.id);
|
||||
Message.success(t('common.deleteSuccess'));
|
||||
loadList();
|
||||
initRecycleModulesCount();
|
||||
resetSelector();
|
||||
initRecycleList();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
@ -783,7 +800,6 @@
|
|||
|
||||
// 处理自定义字段列
|
||||
let customFieldsColumns: Record<string, any>[] = [];
|
||||
const tableRef = ref<InstanceType<typeof MsBaseTable> | null>(null);
|
||||
|
||||
const initDefaultFields = ref<CustomAttributes[]>([]);
|
||||
|
||||
|
@ -791,6 +807,7 @@
|
|||
|
||||
// 处理自定义字段展示
|
||||
async function getDefaultFields() {
|
||||
customFieldsColumns = [];
|
||||
const result = await getCaseDefaultFields(currentProjectId.value);
|
||||
initDefaultFields.value = result.customFields.filter((item: any) => !item.internal);
|
||||
customFieldsColumns = initDefaultFields.value.map((item: any) => {
|
||||
|
@ -803,7 +820,7 @@
|
|||
width: 300,
|
||||
};
|
||||
});
|
||||
caseLevelFields.value = result.customFields.find((item: any) => item.internal);
|
||||
caseLevelFields.value = result.customFields.find((item: any) => item.internal && item.fieldName === '用例等级');
|
||||
caseFilters.value = caseLevelFields.value.options.map((item: any) => item.value);
|
||||
fullColumns = [
|
||||
...columns.slice(0, columns.length - 1),
|
||||
|
@ -815,7 +832,7 @@
|
|||
|
||||
async function initFilter() {
|
||||
const result = await getCustomFieldsTable(currentProjectId.value);
|
||||
memberOptions.value = await getProjectMemberOptions(appStore.currentProjectId, keyword.value);
|
||||
memberOptions.value = await getProjectOptions(appStore.currentProjectId, keyword.value);
|
||||
memberOptions.value = memberOptions.value.map((e: any) => ({ label: e.name, value: e.id }));
|
||||
filterConfigList.value = [
|
||||
{
|
||||
|
@ -953,11 +970,10 @@
|
|||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await getDefaultFields();
|
||||
initFilter();
|
||||
initRecycleList();
|
||||
getRecycleModules();
|
||||
initRecycleModulesCount();
|
||||
await getDefaultFields();
|
||||
await initFilter();
|
||||
initRecycleList();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -17,14 +17,14 @@
|
|||
</div>
|
||||
<div v-else class="font-medium">{{ t('caseManagement.featureCase.testPlanLinkList') }}</div>
|
||||
<div class="mb-4">
|
||||
<!-- <a-radio-group v-model:model-value="showType" type="button" class="file-show-type ml-[4px]">
|
||||
<a-radio-group v-model:model-value="showType" type="button" class="file-show-type ml-[4px]">
|
||||
<a-radio value="link" class="show-type-icon p-[2px]">{{
|
||||
t('caseManagement.featureCase.directLink')
|
||||
}}</a-radio>
|
||||
<a-radio value="testPlan" class="show-type-icon p-[2px]">{{
|
||||
<!-- <a-radio value="testPlan" class="show-type-icon p-[2px]">{{
|
||||
t('caseManagement.featureCase.testPlan')
|
||||
}}</a-radio>
|
||||
</a-radio-group> -->
|
||||
}}</a-radio> -->
|
||||
</a-radio-group>
|
||||
<a-input-search
|
||||
v-model:model-value="keyword"
|
||||
:placeholder="t('caseManagement.featureCase.searchByNameAndId')"
|
||||
|
@ -267,8 +267,7 @@
|
|||
} else {
|
||||
setTestPlanListParams({ keyword: keyword.value, projectId: appStore.currentProjectId, caseId: props.caseId });
|
||||
await testPlanLinkList();
|
||||
const { msPagination } = testPlanPropsRes.value;
|
||||
featureCaseStore.setListCount(featureCaseStore.activeTab, msPagination?.total || 0);
|
||||
featureCaseStore.getCaseCounts(props.caseId);
|
||||
}
|
||||
}
|
||||
const cancelLoading = ref<boolean>(false);
|
||||
|
|
|
@ -265,8 +265,7 @@
|
|||
sourceType: currentSelectCase.value,
|
||||
});
|
||||
await loadList();
|
||||
const { msPagination } = propsRes.value;
|
||||
featureCaseStore.setListCount(featureCaseStore.activeTab, msPagination?.total || 0);
|
||||
featureCaseStore.getCaseCounts(props.caseId);
|
||||
}
|
||||
|
||||
async function searchCase() {
|
||||
|
|
|
@ -99,15 +99,14 @@
|
|||
columns,
|
||||
tableKey: TableKeyEnum.CASE_MANAGEMENT_TAB_REVIEW,
|
||||
scroll: { x: '100%' },
|
||||
heightUsed: 340,
|
||||
heightUsed: 360,
|
||||
enableDrag: true,
|
||||
});
|
||||
|
||||
async function initData() {
|
||||
setLoadListParams({ keyword: keyword.value, caseId: props.caseId });
|
||||
await loadList();
|
||||
const { msPagination } = propsRes.value;
|
||||
featureCaseStore.setListCount(featureCaseStore.activeTab, msPagination?.total || 0);
|
||||
featureCaseStore.getCaseCounts(props.caseId);
|
||||
}
|
||||
|
||||
const searchList = debounce(() => {
|
||||
|
|
|
@ -225,8 +225,7 @@
|
|||
module: 'FUNCTIONAL_CASE',
|
||||
});
|
||||
await loadList();
|
||||
const { msPagination } = propsRes.value;
|
||||
featureCaseStore.setListCount(featureCaseStore.activeTab, msPagination?.total || 0);
|
||||
featureCaseStore.getCaseCounts(props.caseId);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:visible', v: boolean): void;
|
||||
(e: 'update:form', v: CreateOrUpdateDemand): void;
|
||||
(e: 'success'): void;
|
||||
(e: 'save', params: CreateOrUpdateDemand, isContinue: boolean): void;
|
||||
}>();
|
||||
|
@ -85,8 +86,6 @@
|
|||
|
||||
const showModal = ref<boolean>(false);
|
||||
|
||||
// const confirmLoading = ref<boolean>(false);
|
||||
|
||||
const initModelForm: DemandFormList = {
|
||||
demandId: '',
|
||||
demandName: '',
|
||||
|
@ -124,6 +123,12 @@
|
|||
}
|
||||
});
|
||||
}
|
||||
const title = ref<string>('');
|
||||
watchEffect(() => {
|
||||
title.value = form.value.id
|
||||
? t('caseManagement.featureCase.updateDemand', { name: props.form.demandName })
|
||||
: t('caseManagement.featureCase.addDemand');
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
|
@ -139,22 +144,25 @@
|
|||
}
|
||||
);
|
||||
|
||||
const title = ref<string>('');
|
||||
watchEffect(() => {
|
||||
title.value = form.value.id
|
||||
? t('caseManagement.featureCase.updateDemand', { name: props.form.demandName })
|
||||
: t('caseManagement.featureCase.addDemand');
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.form,
|
||||
(val) => {
|
||||
form.value.id = '';
|
||||
modelForm.value = { ...val };
|
||||
form.value.id = val.id;
|
||||
updateName.value = val.demandName;
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => form.value,
|
||||
(val) => {
|
||||
if (val) {
|
||||
emit('update:form', val);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
defineExpose({
|
||||
resetForm,
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
>
|
||||
</template>
|
||||
<template #operation="{ record }">
|
||||
<MsButton v-if="record.demandPlatform !== pageConfig.platformName" @click="emit('cancel', record)">
|
||||
<MsButton @click="emit('cancel', record)">
|
||||
{{ t('caseManagement.featureCase.cancelAssociation') }}
|
||||
</MsButton>
|
||||
<MsButton v-if="record.demandPlatform === pageConfig.platformName" @click="emit('update', record)">
|
||||
|
@ -77,7 +77,7 @@
|
|||
width: 200,
|
||||
},
|
||||
{
|
||||
title: 'caseManagement.featureCase.tableColumnName',
|
||||
title: 'caseManagement.featureCase.name',
|
||||
slotName: 'demandName',
|
||||
dataIndex: 'demandName',
|
||||
width: 300,
|
||||
|
@ -95,7 +95,7 @@
|
|||
slotName: 'operation',
|
||||
dataIndex: 'operation',
|
||||
fixed: 'right',
|
||||
width: 100,
|
||||
width: 150,
|
||||
showInTable: true,
|
||||
showDrag: false,
|
||||
},
|
||||
|
@ -107,13 +107,13 @@
|
|||
scroll: { x: '100%' },
|
||||
selectable: false,
|
||||
showSetting: false,
|
||||
heightUsed: 360,
|
||||
});
|
||||
|
||||
const initData = async () => {
|
||||
setLoadListParams({ ...props.funParams });
|
||||
await loadList();
|
||||
const { msPagination } = propsRes.value;
|
||||
featureCaseStore.setListCount(featureCaseStore.activeTab, msPagination?.total || 0);
|
||||
featureCaseStore.getCaseCounts(props.funParams.caseId);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
<AddDemandModal
|
||||
ref="demandModalRef"
|
||||
v-model:visible="showAddModel"
|
||||
v-model:form="modelForm"
|
||||
:case-id="props.caseId"
|
||||
:form="modelForm"
|
||||
:loading="confirmLoading"
|
||||
@save="saveHandler"
|
||||
@success="searchList()"
|
||||
|
@ -121,10 +121,7 @@
|
|||
|
||||
const showAddModel = ref<boolean>(false);
|
||||
|
||||
function addDemand() {
|
||||
showAddModel.value = true;
|
||||
}
|
||||
const modelForm = ref<DemandItem>({
|
||||
const initModelForm: DemandItem = {
|
||||
id: '',
|
||||
caseId: '', // 功能用例ID
|
||||
demandId: '', // 需求ID
|
||||
|
@ -136,6 +133,10 @@
|
|||
createUser: '',
|
||||
updateUser: '',
|
||||
children: [], // 平台下对应的需求
|
||||
};
|
||||
|
||||
const modelForm = ref<DemandItem>({
|
||||
...initModelForm,
|
||||
});
|
||||
|
||||
// 更新需求
|
||||
|
@ -181,6 +182,7 @@
|
|||
columns: fullColumns.value,
|
||||
rowKey: 'demandId',
|
||||
scroll: { x: '100%' },
|
||||
heightUsed: 290,
|
||||
selectable: true,
|
||||
showSetting: false,
|
||||
});
|
||||
|
@ -348,6 +350,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
function addDemand() {
|
||||
showAddModel.value = true;
|
||||
modelForm.value = { ...initModelForm };
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const result = await getCaseRelatedInfo(currentProjectId.value);
|
||||
|
|
|
@ -87,6 +87,20 @@
|
|||
<template #caseLevel="{ record }">
|
||||
<caseLevel :case-level="getCaseLevels(record.customFields)" />
|
||||
</template>
|
||||
<template #caseLevelFilter="{ columnConfig }">
|
||||
<TableFilter
|
||||
v-model:visible="caseFilterVisible"
|
||||
v-model:status-filters="caseFilters"
|
||||
:title="(columnConfig.title as string)"
|
||||
:list="caseLevelList"
|
||||
value-key="value"
|
||||
@search="searchCase()"
|
||||
>
|
||||
<template #item="{ item }">
|
||||
<div class="flex"> <caseLevel :case-level="item.text" /></div>
|
||||
</template>
|
||||
</TableFilter>
|
||||
</template>
|
||||
<template v-if="(keyword || '').trim() === ''" #empty>
|
||||
<div class="flex w-full items-center justify-center p-[8px] text-[var(--color-text-4)]">
|
||||
{{ t('caseManagement.caseReview.tableNoData') }}
|
||||
|
@ -135,6 +149,7 @@
|
|||
import type { CaseLevel } from '@/components/business/ms-case-associate/types';
|
||||
import MsTree from '@/components/business/ms-tree/index.vue';
|
||||
import type { MsTreeNodeData } from '@/components/business/ms-tree/types';
|
||||
import TableFilter from '../../tableFilter.vue';
|
||||
|
||||
import {
|
||||
addPrepositionRelation,
|
||||
|
@ -145,9 +160,10 @@
|
|||
} from '@/api/modules/case-management/featureCase';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import useFeatureCaseStore from '@/store/modules/case/featureCase';
|
||||
import { mapTree } from '@/utils';
|
||||
|
||||
import type { CaseManagementTable, CaseModuleQueryParams } from '@/models/caseManagement/featureCase';
|
||||
import type { CaseManagementTable, CaseModuleQueryParams, OptionsFieldId } from '@/models/caseManagement/featureCase';
|
||||
import type { ModuleTreeNode, TableQueryParams } from '@/models/common';
|
||||
import { CaseManagementRouteEnum } from '@/enums/routeEnum';
|
||||
|
||||
|
@ -155,6 +171,7 @@
|
|||
|
||||
const appStore = useAppStore();
|
||||
const currentProjectId = computed(() => appStore.currentProjectId);
|
||||
const featureStore = useFeatureCaseStore();
|
||||
|
||||
const { t } = useI18n();
|
||||
const props = defineProps<{
|
||||
|
@ -276,7 +293,8 @@
|
|||
title: 'ms.case.associate.caseLevel',
|
||||
dataIndex: 'caseLevel',
|
||||
slotName: 'caseLevel',
|
||||
width: 90,
|
||||
titleSlotName: 'caseLevelFilter',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: 'caseManagement.featureCase.tableColumnVersion',
|
||||
|
@ -299,7 +317,7 @@
|
|||
},
|
||||
showSetting: false,
|
||||
selectable: true,
|
||||
heightUsed: 300,
|
||||
heightUsed: 380,
|
||||
showSelectAll: true,
|
||||
},
|
||||
(record) => {
|
||||
|
@ -376,6 +394,11 @@
|
|||
moduleIds: [],
|
||||
excludeIds: [],
|
||||
});
|
||||
// 用例等级表头检索
|
||||
const caseLevelFields = ref<Record<string, any>>({});
|
||||
const caseFilterVisible = ref(false);
|
||||
const caseLevelList = ref<OptionsFieldId[]>([]);
|
||||
const caseFilters = ref<string[]>([]);
|
||||
|
||||
// 获取用例参数
|
||||
function getLoadListParams() {
|
||||
|
@ -389,6 +412,9 @@
|
|||
keyword: keyword.value,
|
||||
id: props.caseId,
|
||||
type: props.showType === 'preposition' ? 'PRE' : 'POST',
|
||||
filter: {
|
||||
caseLevel: caseFilters.value,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -441,10 +467,17 @@
|
|||
}
|
||||
}
|
||||
|
||||
async function initFilter() {
|
||||
await featureStore.getDefaultTemplate();
|
||||
caseLevelList.value = featureStore.getSystemCaseLevelFields();
|
||||
caseFilters.value = caseLevelList.value.map((item) => item.value);
|
||||
}
|
||||
|
||||
watch(
|
||||
() => innerVisible.value,
|
||||
(val) => {
|
||||
if (val) {
|
||||
initFilter();
|
||||
searchCase();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="mb-4 flex items-center justify-between">
|
||||
<div>
|
||||
<a-button v-if="showType === 'preposition'" class="mr-3" type="primary" @click="addCase">
|
||||
{{ t('caseManagement.featureCase.addPresetCase') }}
|
||||
|
@ -27,6 +27,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<ms-base-table ref="tableRef" v-bind="propsRes" v-on="propsEvent">
|
||||
<template #num="{ record }">
|
||||
{{ record.num }}
|
||||
</template>
|
||||
<template #operation="{ record }">
|
||||
<MsRemoveButton
|
||||
position="br"
|
||||
|
@ -94,7 +97,8 @@
|
|||
const columns: MsTableColumn = [
|
||||
{
|
||||
title: 'caseManagement.featureCase.tableColumnID',
|
||||
dataIndex: 'id',
|
||||
dataIndex: 'num',
|
||||
slotName: 'num',
|
||||
width: 200,
|
||||
showInTable: true,
|
||||
showTooltip: true,
|
||||
|
@ -140,7 +144,7 @@
|
|||
const { propsRes, propsEvent, loadList, setLoadListParams } = useTable(getDependOnCase, {
|
||||
columns,
|
||||
scroll: { x: '100%' },
|
||||
heightUsed: 340,
|
||||
heightUsed: 360,
|
||||
selectable: false,
|
||||
noDisable: true,
|
||||
showSetting: false,
|
||||
|
@ -159,8 +163,7 @@
|
|||
async function initData() {
|
||||
getParams();
|
||||
await loadList();
|
||||
const { msPagination } = propsRes.value;
|
||||
featureCaseStore.setListCount(featureCaseStore.activeTab, msPagination?.total || 0);
|
||||
featureCaseStore.getCaseCounts(props.caseId);
|
||||
}
|
||||
|
||||
const cancelLoading = ref<boolean>(false);
|
||||
|
|
|
@ -157,7 +157,7 @@
|
|||
<!-- 本地文件 -->
|
||||
<div v-if="item.local || item.status === 'init'" class="flex flex-nowrap">
|
||||
<MsButton
|
||||
v-if="item.status !== 'init'"
|
||||
v-if="item.file.type.includes('/image')"
|
||||
type="button"
|
||||
status="primary"
|
||||
class="!mr-[4px]"
|
||||
|
@ -192,7 +192,7 @@
|
|||
<!-- 关联文件 -->
|
||||
<div v-else class="flex flex-nowrap">
|
||||
<MsButton
|
||||
v-if="item.status !== 'init'"
|
||||
v-if="item.file.type.includes('/image')"
|
||||
type="button"
|
||||
status="primary"
|
||||
class="!mr-[4px]"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { MsTableColumnData } from '@/components/pure/ms-table/type';
|
||||
import { getFileEnum } from '@/components/pure/ms-upload/iconMap';
|
||||
import type { MsFileItem } from '@/components/pure/ms-upload/types';
|
||||
import type { CaseLevel } from '@/components/business/ms-case-associate/types';
|
||||
|
||||
|
@ -91,7 +92,11 @@ export const executionResultMap = {
|
|||
export function convertToFile(fileInfo: AssociatedList): MsFileItem {
|
||||
const gatewayAddress = `${window.location.protocol}//${window.location.hostname}:${window.location.port}`;
|
||||
const fileName = fileInfo.fileType ? `${fileInfo.name}.${fileInfo.fileType || ''}` : `${fileInfo.name}`;
|
||||
const type = fileName.split('.')[1];
|
||||
|
||||
const fileFormatMatch = fileName.match(/\.([a-zA-Z0-9]+)$/);
|
||||
const fileFormatType = fileFormatMatch ? fileFormatMatch[1] : 'none';
|
||||
const type = getFileEnum(fileFormatType);
|
||||
console.log(type);
|
||||
const file = new File([new Blob()], `${fileName}`, {
|
||||
type: `application/${type}`,
|
||||
});
|
||||
|
@ -132,9 +137,10 @@ export function getTableFields(customFields: CustomAttributes[], itemDataIndex:
|
|||
);
|
||||
|
||||
if (currentColumnData) {
|
||||
let selectValue;
|
||||
// 处理多选项
|
||||
if (multipleExcludes.includes(currentColumnData.type)) {
|
||||
const selectValue = JSON.parse(currentColumnData.defaultValue);
|
||||
if (multipleExcludes.includes(currentColumnData.type) && currentColumnData.defaultValue) {
|
||||
selectValue = JSON.parse(currentColumnData.defaultValue);
|
||||
return (
|
||||
(currentColumnData.options || [])
|
||||
.filter((item: any) => selectValue.includes(item.value))
|
||||
|
|
|
@ -146,6 +146,7 @@
|
|||
import useFeatureCaseStore from '@/store/modules/case/featureCase';
|
||||
|
||||
import type { CaseModuleQueryParams, CreateOrUpdateModule, ValidateInfo } from '@/models/caseManagement/featureCase';
|
||||
import { TableQueryParams } from '@/models/common';
|
||||
import { CaseManagementRouteEnum } from '@/enums/routeEnum';
|
||||
|
||||
import type { FileItem } from '@arco-design/web-vue';
|
||||
|
@ -241,7 +242,7 @@
|
|||
}
|
||||
|
||||
// 表格搜索参数
|
||||
const tableFilterParams = ref<CaseModuleQueryParams>({
|
||||
const tableFilterParams = ref<TableQueryParams>({
|
||||
moduleIds: [],
|
||||
projectId: '',
|
||||
});
|
||||
|
@ -257,7 +258,7 @@
|
|||
/**
|
||||
* 右侧表格数据刷新后,若当前展示的是模块,则刷新模块树的统计数量
|
||||
*/
|
||||
function initModulesCount(params: CaseModuleQueryParams) {
|
||||
function initModulesCount(params: TableQueryParams) {
|
||||
featureCaseStore.getCaseModulesCount(params);
|
||||
featureCaseStore.getRecycleModulesCount(params);
|
||||
tableFilterParams.value = { ...params };
|
||||
|
|
|
@ -32,6 +32,8 @@ export default {
|
|||
'caseManagement.featureCase.moduleMoveSuccess': 'Move successfully',
|
||||
'caseManagement.featureCase.tableColumnID': 'ID',
|
||||
'caseManagement.featureCase.tableColumnName': 'Case Name',
|
||||
'caseManagement.featureCase.demandName': 'Demand Name',
|
||||
'caseManagement.featureCase.demandID': 'ID',
|
||||
'caseManagement.featureCase.tableColumnLevel': 'Case Level',
|
||||
'caseManagement.featureCase.tableColumnCaseState': 'Case State',
|
||||
'caseManagement.featureCase.tableColumnReviewResult': 'Review Result',
|
||||
|
@ -253,4 +255,5 @@ export default {
|
|||
'caseManagement.featureCase.sortSuccess': 'Sort successfully',
|
||||
'caseManagement.featureCase.zentao': 'zentao',
|
||||
'caseManagement.featureCase.searchPlaceholder': 'Search by ID, name, or tag',
|
||||
'caseManagement.featureCase.ModuleOwned': 'Module owned',
|
||||
};
|
||||
|
|
|
@ -31,6 +31,8 @@ export default {
|
|||
'caseManagement.featureCase.moduleMoveSuccess': '移动成功',
|
||||
'caseManagement.featureCase.tableColumnID': 'ID',
|
||||
'caseManagement.featureCase.tableColumnName': '用例名称',
|
||||
'caseManagement.featureCase.demandName': '需求名称',
|
||||
'caseManagement.featureCase.demandID': '需求ID',
|
||||
'caseManagement.featureCase.tableColumnLevel': '用例等级',
|
||||
'caseManagement.featureCase.tableColumnCaseState': '用例状态',
|
||||
'caseManagement.featureCase.tableColumnReviewResult': '评审结果',
|
||||
|
@ -248,4 +250,5 @@ export default {
|
|||
'caseManagement.featureCase.sortSuccess': '排序成功',
|
||||
'caseManagement.featureCase.zentao': '禅道',
|
||||
'caseManagement.featureCase.searchPlaceholder': '通过ID、名称或标签搜索',
|
||||
'caseManagement.featureCase.ModuleOwned': '所属模块',
|
||||
};
|
||||
|
|
|
@ -39,9 +39,8 @@
|
|||
v-model="templateForm.remark"
|
||||
:max-length="1000"
|
||||
:placeholder="t('system.orgTemplate.resDescription')"
|
||||
:auto-size="{
|
||||
maxRows: 1,
|
||||
}"
|
||||
:auto-size="{ minRows: 1 }"
|
||||
style="resize: vertical"
|
||||
class="max-w-[732px]"
|
||||
></a-textarea>
|
||||
</a-form-item>
|
||||
|
@ -193,7 +192,7 @@
|
|||
const { name, customFields, systemFields } = res;
|
||||
templateForm.value = {
|
||||
...res,
|
||||
name: route.params.mode === 'copy' ? `${name}_copy` : name,
|
||||
name: route.params.mode === 'copy' ? `copy_${name}` : name,
|
||||
};
|
||||
if (route.params.mode === 'copy') {
|
||||
templateForm.value.id = undefined;
|
||||
|
|
|
@ -53,9 +53,11 @@
|
|||
</template>
|
||||
<template #name="{ record }">
|
||||
<div class="flex items-center">
|
||||
<span class="ml-2 cursor-pointer text-[rgb(var(--primary-5))]" @click="previewDetail(record)">{{
|
||||
record.name
|
||||
}}</span>
|
||||
<span
|
||||
class="one-line-text ml-2 cursor-pointer text-[rgb(var(--primary-5))]"
|
||||
@click="previewDetail(record.id)"
|
||||
>{{ record.name }}</span
|
||||
>
|
||||
<MsTag v-if="record.internal" size="small" class="ml-2">{{ t('system.orgTemplate.isSystem') }}</MsTag>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -171,6 +173,7 @@
|
|||
fixed: 'left',
|
||||
showDrag: true,
|
||||
showInTable: true,
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
title: 'system.orgTemplate.defaultTemplate',
|
||||
|
@ -356,13 +359,14 @@
|
|||
const titleDetail = ref<string>();
|
||||
const defectForm = ref<Record<string, any>>({ ...initDetailForm });
|
||||
// 预览详情
|
||||
const previewDetail = async (record: OrdTemplateManagement) => {
|
||||
const previewDetail = async (id: string) => {
|
||||
showDetailVisible.value = true;
|
||||
titleDetail.value = record.name;
|
||||
|
||||
try {
|
||||
totalData.value = await getProjectFieldList({ scopedId: currentProjectId.value, scene: route.query.type });
|
||||
getFieldOptionList();
|
||||
const res = await getProjectTemplateInfo(record.id);
|
||||
const res = await getProjectTemplateInfo(id);
|
||||
titleDetail.value = res.name;
|
||||
selectData.value = getCustomDetailFields(totalData.value as DefinedFieldItem[], res.customFields);
|
||||
res.systemFields.forEach((item: any) => {
|
||||
defectForm.value[item.fieldId] = item.defaultValue;
|
||||
|
@ -400,6 +404,12 @@
|
|||
return route.query.type !== 'BUG';
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
if (route.query.id) {
|
||||
previewDetail(route.query.id as string);
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
fetchData();
|
||||
updateColumns();
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<a-textarea
|
||||
v-model:model-value="form.remark"
|
||||
:max-length="1000"
|
||||
:placeholder="t('system.config.auth.descPlaceholder')"
|
||||
:placeholder="t('system.orgTemplate.enterStatusDesc')"
|
||||
allow-clear
|
||||
></a-textarea>
|
||||
</a-form-item>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
:width="800"
|
||||
:show-continue="!isEdit"
|
||||
@confirm="handleDrawerConfirm"
|
||||
@continue="handleDrawerConfirm(true)"
|
||||
@continue="saveAndContinue"
|
||||
@cancel="handleDrawerCancel"
|
||||
>
|
||||
<div class="form">
|
||||
|
@ -31,9 +31,8 @@
|
|||
v-model="fieldForm.remark"
|
||||
:max-length="1000"
|
||||
:placeholder="t('system.orgTemplate.resDescription')"
|
||||
:auto-size="{
|
||||
maxRows: 1,
|
||||
}"
|
||||
:auto-size="{ minRows: 1 }"
|
||||
style="resize: vertical"
|
||||
></a-textarea>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
|
@ -251,10 +250,8 @@
|
|||
|
||||
const { addOrUpdate, detail } = getFieldRequestApi(props.mode);
|
||||
// 保存
|
||||
const confirmHandler = async (isContinue: boolean) => {
|
||||
const confirmHandler = async (isContinue = false) => {
|
||||
try {
|
||||
drawerLoading.value = true;
|
||||
|
||||
const formCopy = cloneDeep(fieldForm.value);
|
||||
|
||||
formCopy.scene = route.query.type;
|
||||
|
@ -291,7 +288,7 @@
|
|||
params.id = id;
|
||||
}
|
||||
await addOrUpdate(params);
|
||||
Message.success(isEdit.value ? t('common.updateSuccess') : t('common.addSuccess'));
|
||||
Message.success(isEdit.value ? t('common.updateSuccess') : t('common.newSuccess'));
|
||||
if (!isContinue) {
|
||||
handleDrawerCancel();
|
||||
}
|
||||
|
@ -303,27 +300,48 @@
|
|||
drawerLoading.value = false;
|
||||
}
|
||||
};
|
||||
const fieldDefaultValues = ref<FormItemModel[]>([]);
|
||||
function userFormFiledValidate(cb: () => Promise<any>) {
|
||||
fieldFormRef.value?.validate((errors: undefined | Record<string, ValidatedError>) => {
|
||||
if (errors) {
|
||||
return;
|
||||
}
|
||||
batchFormRef.value?.formValidate(async (list: any) => {
|
||||
try {
|
||||
drawerLoading.value = true;
|
||||
fieldDefaultValues.value = [...list];
|
||||
if (showOptionsSelect) {
|
||||
fieldForm.value.options = (batchFormRef.value?.getFormResult() || []).map((item: any) => {
|
||||
return {
|
||||
...item,
|
||||
value: fieldForm.value.enableOptionKey ? item.value : getGenerateId(),
|
||||
};
|
||||
});
|
||||
}
|
||||
await cb();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
} finally {
|
||||
drawerLoading.value = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 新增 || 保存并继续添加
|
||||
const handleDrawerConfirm = (isContinue: boolean) => {
|
||||
fieldFormRef.value?.validate(async (errors: Record<string, ValidatedError> | undefined) => {
|
||||
if (!errors) {
|
||||
if (showOptionsSelect) {
|
||||
fieldForm.value.options = (batchFormRef.value?.getFormResult() || []).map((item: any) => {
|
||||
return {
|
||||
...item,
|
||||
value: fieldForm.value.enableOptionKey ? item.value : getGenerateId(),
|
||||
};
|
||||
});
|
||||
}
|
||||
confirmHandler(isContinue);
|
||||
}
|
||||
});
|
||||
userFormFiledValidate(confirmHandler);
|
||||
};
|
||||
function saveAndContinue() {
|
||||
userFormFiledValidate(async () => {
|
||||
await confirmHandler(true);
|
||||
resetForm();
|
||||
});
|
||||
}
|
||||
|
||||
// 字段类型列表选项
|
||||
const fieldOptions = ref<fieldIconAndNameModal[]>([]);
|
||||
const fieldDefaultValues = ref([]);
|
||||
|
||||
// 获取字段选项详情
|
||||
const getFieldDetail = async (id: string) => {
|
||||
|
|
|
@ -1,10 +1,23 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-alert class="mb-6" :type="isEnabledTemplate && props.mode === 'organization' ? 'warning' : 'info'">{{
|
||||
isEnabledTemplate && props.mode === 'organization'
|
||||
? t('system.orgTemplate.enableDescription')
|
||||
: t('system.orgTemplate.fieldLimit')
|
||||
}}</a-alert>
|
||||
<a-alert
|
||||
v-if="isShowTip"
|
||||
class="mb-6"
|
||||
:type="isEnabledTemplate && props.mode === 'organization' ? 'warning' : 'info'"
|
||||
>
|
||||
<div class="flex items-start justify-between">
|
||||
<span>
|
||||
{{
|
||||
isEnabledTemplate && props.mode === 'organization'
|
||||
? t('system.orgTemplate.enableDescription')
|
||||
: t('system.orgTemplate.fieldLimit')
|
||||
}}</span
|
||||
>
|
||||
<span class="cursor-pointer text-[var(--color-text-2)]" @click="noRemindHandler">{{
|
||||
t('system.orgTemplate.noReminders')
|
||||
}}</span>
|
||||
</div>
|
||||
</a-alert>
|
||||
<div class="mb-4 flex items-center justify-between">
|
||||
<span v-if="isEnabledTemplate" class="font-medium">{{ t('system.orgTemplate.fieldList') }}</span>
|
||||
<a-button v-permission="props.createPermission" type="primary" :disabled="isDisabled" @click="fieldHandler">
|
||||
|
@ -145,6 +158,7 @@
|
|||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import useVisit from '@/hooks/useVisit';
|
||||
import { useAppStore, useTableStore } from '@/store';
|
||||
import useTemplateStore from '@/store/modules/setting/template';
|
||||
import { characterLimit } from '@/utils';
|
||||
|
@ -157,6 +171,9 @@
|
|||
|
||||
const templateStore = useTemplateStore();
|
||||
|
||||
const visitedKey = 'notRemindField';
|
||||
const { addVisited } = useVisit(visitedKey);
|
||||
const { getIsVisited } = useVisit(visitedKey);
|
||||
const { t } = useI18n();
|
||||
const tableStore = useTableStore();
|
||||
const appStore = useAppStore();
|
||||
|
@ -363,7 +380,20 @@
|
|||
fetchData();
|
||||
};
|
||||
|
||||
const isShowTip = ref<boolean>(true);
|
||||
|
||||
// 不再提醒
|
||||
const doCheckIsTip = () => {
|
||||
isShowTip.value = !getIsVisited();
|
||||
};
|
||||
|
||||
const noRemindHandler = () => {
|
||||
isShowTip.value = false;
|
||||
addVisited();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
doCheckIsTip();
|
||||
isEnableOperation();
|
||||
fetchData();
|
||||
});
|
||||
|
|
|
@ -39,9 +39,8 @@
|
|||
v-model="templateForm.remark"
|
||||
:max-length="1000"
|
||||
:placeholder="t('system.orgTemplate.resDescription')"
|
||||
:auto-size="{
|
||||
maxRows: 1,
|
||||
}"
|
||||
:auto-size="{ minRows: 1 }"
|
||||
style="resize: vertical"
|
||||
class="max-w-[732px]"
|
||||
></a-textarea>
|
||||
</a-form-item>
|
||||
|
@ -187,7 +186,7 @@
|
|||
const { name, customFields, systemFields } = res;
|
||||
templateForm.value = {
|
||||
...res,
|
||||
name: route.params.mode === 'copy' ? `${name}_copy` : name,
|
||||
name: route.params.mode === 'copy' ? `copy_${name}` : name,
|
||||
};
|
||||
if (route.params.mode === 'copy') {
|
||||
templateForm.value.id = undefined;
|
||||
|
|
|
@ -103,4 +103,12 @@
|
|||
width: 428px;
|
||||
}
|
||||
}
|
||||
:deep(.arco-picker-disabled) {
|
||||
border-color: var(--color-text-n8);
|
||||
background: var(--color-text-n8);
|
||||
&:hover {
|
||||
border-color: var(--color-text-n8);
|
||||
background: var(--color-text-n8);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -173,7 +173,9 @@
|
|||
<span class="label">{{ t('system.orgTemplate.description') }}</span>
|
||||
</div>
|
||||
<div class="flex w-[60%] flex-col">
|
||||
<span class="content">{{ detailInfo?.name }}</span>
|
||||
<a-tooltip position="left" :content="detailInfo?.name">
|
||||
<span class="content">{{ characterLimit(detailInfo?.name) }}</span>
|
||||
</a-tooltip>
|
||||
<span class="content">{{ detailInfo?.remark || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -184,4 +184,9 @@ export default {
|
|||
'system.orgTemplate.associatedField': 'Associated field ',
|
||||
'system.orgTemplate.associatedHasField': 'Associate an added field',
|
||||
'system.orgTemplate.addFieldDesc': 'Adds a new field',
|
||||
'system.orgTemplate.enterStatusDesc': 'Please enter a status description',
|
||||
'system.orgTemplate.field': 'Field',
|
||||
'system.orgTemplate.caseTemplateManagement': 'Use case template management',
|
||||
'system.orgTemplate.apiTemplateManagement': 'Interface template management',
|
||||
'system.orgTemplate.bugTemplateManagement': 'Defect template management',
|
||||
};
|
||||
|
|
|
@ -175,4 +175,9 @@ export default {
|
|||
'system.orgTemplate.addFieldDesc': '新增一个新的字段',
|
||||
'system.orgTemplate.toTop': '上移',
|
||||
'system.orgTemplate.toBottom': '下移',
|
||||
'system.orgTemplate.enterStatusDesc': '请输入状态描述',
|
||||
'system.orgTemplate.field': '字段',
|
||||
'system.orgTemplate.caseTemplateManagement': '用例模板管理',
|
||||
'system.orgTemplate.apiTemplateManagement': '接口模板管理',
|
||||
'system.orgTemplate.bugTemplateManagement': '缺陷模板管理',
|
||||
};
|
||||
|
|
|
@ -392,7 +392,7 @@
|
|||
enable: !record.enable,
|
||||
};
|
||||
await updatePlugin(params);
|
||||
Message.success(t('system.plugin.disablePluginSuccess'));
|
||||
Message.success(t('system.plugin.enablePluginSuccess'));
|
||||
loadData();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
|
Loading…
Reference in New Issue