fix(测试计划): 修复测试计划bug&修复报告图表自定义tooltip样式

This commit is contained in:
xinxin.wu 2024-06-19 18:02:06 +08:00 committed by Craftsman
parent cf5f9a0b4f
commit ff91f4b77d
26 changed files with 303 additions and 119 deletions

View File

@ -186,37 +186,47 @@
return undefined; return undefined;
} }
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector, setPagination, resetFilterParams } = const {
useTable( propsRes,
getPageList.value, propsEvent,
{ loadList,
columns, setLoadListParams,
showSetting: false, resetSelector,
selectable: true, setPagination,
showSelectAll: true, resetFilterParams,
heightUsed: 310, setTableSelected,
showSelectorAll: false, } = useTable(
}, getPageList.value,
(record) => { {
return { columns,
...record, showSetting: false,
caseLevel: getCaseLevel(record), selectable: true,
tags: (record.tags || []).map((item: string, i: number) => { showSelectAll: true,
return { heightUsed: 310,
id: `${record.id}-${i}`, showSelectorAll: false,
name: item, },
}; (record) => {
}), return {
}; ...record,
} caseLevel: getCaseLevel(record),
); tags: (record.tags || []).map((item: string, i: number) => {
return {
id: `${record.id}-${i}`,
name: item,
};
}),
};
}
);
async function getTableParams() { async function getTableParams() {
const { excludeKeys } = propsRes.value;
return { return {
keyword: props.keyword, keyword: props.keyword,
projectId: props.currentProject, projectId: props.currentProject,
moduleIds: props.activeModule === 'all' || !props.activeModule ? [] : [props.activeModule, ...props.offspringIds], moduleIds: props.activeModule === 'all' || !props.activeModule ? [] : [props.activeModule, ...props.offspringIds],
excludeIds: [...(props.associatedIds || [])], // id excludeIds: [...excludeKeys],
condition: { condition: {
keyword: props.keyword, keyword: props.keyword,
}, },
@ -226,6 +236,11 @@
} }
async function getModuleCount() { async function getModuleCount() {
if (props.associatedIds && props.associatedIds.length) {
props.associatedIds.forEach((hasNotAssociatedId) => {
setTableSelected(hasNotAssociatedId);
});
}
const tableParams = await getTableParams(); const tableParams = await getTableParams();
emit('getModuleCount', { emit('getModuleCount', {
...tableParams, ...tableParams,
@ -235,6 +250,11 @@
} }
async function loadCaseList() { async function loadCaseList() {
if (props.associatedIds && props.associatedIds.length) {
props.associatedIds.forEach((hasNotAssociatedId) => {
setTableSelected(hasNotAssociatedId);
});
}
const tableParams = await getTableParams(); const tableParams = await getTableParams();
setLoadListParams(tableParams); setLoadListParams(tableParams);
loadList(); loadList();
@ -296,7 +316,7 @@
const tableParams = getTableParams(); const tableParams = getTableParams();
return { return {
...tableParams, ...tableParams,
excludeIds: [...excludeKeys].concat(...(props.associatedIds || [])), excludeIds: [...excludeKeys],
selectIds: selectorStatus === 'all' ? [] : [...selectedKeys], selectIds: selectorStatus === 'all' ? [] : [...selectedKeys],
selectAll: selectorStatus === 'all', selectAll: selectorStatus === 'all',
associateApiType: 'API_CASE', associateApiType: 'API_CASE',

View File

@ -160,23 +160,32 @@
}, },
]; ];
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector, setPagination, resetFilterParams } = const {
useTable(getPublicLinkCaseListMap[props.getPageApiType][props.activeSourceType].API, { propsRes,
columns, propsEvent,
showSetting: false, loadList,
selectable: true, setLoadListParams,
showSelectAll: true, resetSelector,
heightUsed: 310, setPagination,
showSelectorAll: false, resetFilterParams,
}); setTableSelected,
} = useTable(getPublicLinkCaseListMap[props.getPageApiType][props.activeSourceType].API, {
columns,
showSetting: false,
selectable: true,
showSelectAll: true,
heightUsed: 310,
showSelectorAll: false,
});
async function getTableParams() { async function getTableParams() {
const { excludeKeys } = propsRes.value;
return { return {
keyword: props.keyword, keyword: props.keyword,
projectId: props.currentProject, projectId: props.currentProject,
protocols: props.protocols, protocols: props.protocols,
moduleIds: props.activeModule === 'all' || !props.activeModule ? [] : [props.activeModule, ...props.offspringIds], moduleIds: props.activeModule === 'all' || !props.activeModule ? [] : [props.activeModule, ...props.offspringIds],
excludeIds: [...(props.associatedIds || [])], // id excludeIds: [...excludeKeys],
condition: { condition: {
keyword: props.keyword, keyword: props.keyword,
}, },
@ -194,6 +203,11 @@
} }
async function loadApiList() { async function loadApiList() {
if (props.associatedIds && props.associatedIds.length) {
props.associatedIds.forEach((hasNotAssociatedId) => {
setTableSelected(hasNotAssociatedId);
});
}
const tableParams = await getTableParams(); const tableParams = await getTableParams();
setLoadListParams(tableParams); setLoadListParams(tableParams);
loadList(); loadList();
@ -255,7 +269,7 @@
const tableParams = getTableParams(); const tableParams = getTableParams();
return { return {
...tableParams, ...tableParams,
excludeIds: [...excludeKeys].concat(...(props.associatedIds || [])), excludeIds: [...excludeKeys],
selectIds: selectorStatus === 'all' ? [] : [...selectedKeys], selectIds: selectorStatus === 'all' ? [] : [...selectedKeys],
selectAll: selectorStatus === 'all', selectAll: selectorStatus === 'all',
associateApiType: 'API', associateApiType: 'API',

View File

@ -82,6 +82,7 @@
(e: 'initModules'): void; (e: 'initModules'): void;
(e: 'update:selectedIds'): void; (e: 'update:selectedIds'): void;
}>(); }>();
const innerSelectedIds = defineModel<string[]>('selectedIds', { required: true });
const reviewResultOptions = computed(() => { const reviewResultOptions = computed(() => {
return Object.keys(statusIconMap).map((key) => { return Object.keys(statusIconMap).map((key) => {
@ -194,37 +195,46 @@
return undefined; return undefined;
} }
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector, setPagination, resetFilterParams } = const {
useTable( propsRes,
getPageList.value, propsEvent,
{ loadList,
columns, setLoadListParams,
showSetting: false, resetSelector,
selectable: true, setPagination,
showSelectAll: true, resetFilterParams,
heightUsed: 310, setTableSelected,
showSelectorAll: false, } = useTable(
}, getPageList.value,
(record) => { {
return { columns,
...record, showSetting: false,
caseLevel: getCaseLevel(record), selectable: true,
tags: (record.tags || []).map((item: string, i: number) => { showSelectAll: true,
return { heightUsed: 310,
id: `${record.id}-${i}`, showSelectorAll: false,
name: item, },
}; (record) => {
}), return {
}; ...record,
} caseLevel: getCaseLevel(record),
); tags: (record.tags || []).map((item: string, i: number) => {
return {
id: `${record.id}-${i}`,
name: item,
};
}),
};
}
);
async function getTableParams() { async function getTableParams() {
const { excludeKeys } = propsRes.value;
return { return {
keyword: props.keyword, keyword: props.keyword,
projectId: props.currentProject, projectId: props.currentProject,
moduleIds: props.activeModule === 'all' || !props.activeModule ? [] : [props.activeModule, ...props.offspringIds], moduleIds: props.activeModule === 'all' || !props.activeModule ? [] : [props.activeModule, ...props.offspringIds],
excludeIds: [...(props.associatedIds || [])], // id excludeIds: [...excludeKeys],
condition: { condition: {
keyword: props.keyword, keyword: props.keyword,
filter: propsRes.value.filter, filter: propsRes.value.filter,
@ -243,6 +253,11 @@
} }
async function loadCaseList() { async function loadCaseList() {
if (props.associatedIds && props.associatedIds.length) {
props.associatedIds.forEach((hasNotAssociatedId) => {
setTableSelected(hasNotAssociatedId);
});
}
const tableParams = await getTableParams(); const tableParams = await getTableParams();
setLoadListParams(tableParams); setLoadListParams(tableParams);
loadList(); loadList();
@ -256,11 +271,12 @@
const tableRef = ref<InstanceType<typeof MsBaseTable>>(); const tableRef = ref<InstanceType<typeof MsBaseTable>>();
function getFunctionalSaveParams() { function getFunctionalSaveParams() {
console.log(111);
const { excludeKeys, selectedKeys, selectorStatus } = propsRes.value; const { excludeKeys, selectedKeys, selectorStatus } = propsRes.value;
const tableParams = getTableParams(); const tableParams = getTableParams();
return { return {
...tableParams, ...tableParams,
excludeIds: [...excludeKeys].concat(...(props.associatedIds || [])), excludeIds: [...excludeKeys],
selectIds: selectorStatus === 'all' ? [] : [...selectedKeys], selectIds: selectorStatus === 'all' ? [] : [...selectedKeys],
selectAll: selectorStatus === 'all', selectAll: selectorStatus === 'all',
}; };
@ -278,8 +294,6 @@
} }
); );
const innerSelectedIds = defineModel<string[]>('selectedIds', { required: true });
const selectIds = computed(() => { const selectIds = computed(() => {
return [...propsRes.value.selectedKeys]; return [...propsRes.value.selectedKeys];
}); });

View File

@ -445,6 +445,9 @@
const selectPopVisible = ref<boolean>(false); const selectPopVisible = ref<boolean>(false);
function loadCaseList() { function loadCaseList() {
if (props.associatedIds && props.associatedIds.length > 0) {
selectedIds.value = props.associatedIds;
}
switch (associationType.value) { switch (associationType.value) {
case CaseLinkEnum.FUNCTIONAL: case CaseLinkEnum.FUNCTIONAL:
return functionalTableRef.value?.loadCaseList(); return functionalTableRef.value?.loadCaseList();

View File

@ -180,22 +180,31 @@
const getPageList = computed(() => { const getPageList = computed(() => {
return getPublicLinkCaseListMap[props.getPageApiType][props.activeSourceType]; return getPublicLinkCaseListMap[props.getPageApiType][props.activeSourceType];
}); });
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector, setPagination, resetFilterParams } = const {
useTable(getPageList.value, { propsRes,
columns, propsEvent,
showSetting: false, loadList,
selectable: true, setLoadListParams,
showSelectAll: true, resetSelector,
heightUsed: 310, setPagination,
showSelectorAll: false, resetFilterParams,
}); setTableSelected,
} = useTable(getPageList.value, {
columns,
showSetting: false,
selectable: true,
showSelectAll: true,
heightUsed: 310,
showSelectorAll: false,
});
async function getTableParams() { async function getTableParams() {
const { excludeKeys } = propsRes.value;
return { return {
keyword: props.keyword, keyword: props.keyword,
projectId: props.currentProject, projectId: props.currentProject,
moduleIds: props.activeModule === 'all' || !props.activeModule ? [] : [props.activeModule, ...props.offspringIds], moduleIds: props.activeModule === 'all' || !props.activeModule ? [] : [props.activeModule, ...props.offspringIds],
excludeIds: [...(props.associatedIds || [])], // id excludeIds: [...excludeKeys],
condition: { condition: {
keyword: props.keyword, keyword: props.keyword,
filter: propsRes.value.filter, filter: propsRes.value.filter,
@ -214,6 +223,11 @@
} }
async function loadScenarioList() { async function loadScenarioList() {
if (props.associatedIds && props.associatedIds.length) {
props.associatedIds.forEach((hasNotAssociatedId) => {
setTableSelected(hasNotAssociatedId);
});
}
const tableParams = await getTableParams(); const tableParams = await getTableParams();
setLoadListParams(tableParams); setLoadListParams(tableParams);
loadList(); loadList();
@ -255,7 +269,7 @@
const tableParams = getTableParams(); const tableParams = getTableParams();
return { return {
...tableParams, ...tableParams,
excludeIds: [...excludeKeys].concat(...(props.associatedIds || [])), excludeIds: [...excludeKeys],
selectIds: selectorStatus === 'all' ? [] : [...selectedKeys], selectIds: selectorStatus === 'all' ? [] : [...selectedKeys],
selectAll: selectorStatus === 'all', selectAll: selectorStatus === 'all',
}; };

View File

@ -55,7 +55,7 @@
async function saveHandler(params: AssociateCaseRequest) { async function saveHandler(params: AssociateCaseRequest) {
if (typeof props.saveApi !== 'function') { if (typeof props.saveApi !== 'function') {
emit('success', { ...params, functionalSelectIds: params.selectIds }); emit('success', { ...params });
} else { } else {
try { try {
confirmLoading.value = true; confirmLoading.value = true;
@ -63,7 +63,7 @@
functionalSelectIds: params.selectIds, functionalSelectIds: params.selectIds,
testPlanId: planId.value, testPlanId: planId.value,
}); });
emit('success', { ...params, functionalSelectIds: params.selectIds }); emit('success', { ...params });
Message.success(t('ms.case.associate.associateSuccess')); Message.success(t('ms.case.associate.associateSuccess'));
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console

View File

@ -107,7 +107,7 @@
<div class="flex items-center"> <div class="flex items-center">
<div class="text-[var(--color-text-2)]"> <div class="text-[var(--color-text-2)]">
{{ {{
t('caseManagement.caseReview.selectedCases', { t('ms.minders.selectedCases', {
count: selectedAssociateCasesParams.selectAll count: selectedAssociateCasesParams.selectAll
? selectedAssociateCasesParams.totalCount ? selectedAssociateCasesParams.totalCount
: selectedAssociateCasesParams.selectIds.length, : selectedAssociateCasesParams.selectIds.length,
@ -769,7 +769,6 @@
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log(error); console.log(error);
selectedAssociateCasesParams.value.selectIds = [];
} finally { } finally {
loading.value = false; loading.value = false;
tempMinderParams.value = { tempMinderParams.value = {
@ -777,6 +776,7 @@
editList: [], editList: [],
deletedIds: [], deletedIds: [],
}; };
selectedAssociateCasesParams.value.selectIds = [];
} }
} }

View File

@ -19,4 +19,5 @@ export default {
'ms.minders.env': 'Environment', 'ms.minders.env': 'Environment',
'ms.minders.item': '{count} Strip', 'ms.minders.item': '{count} Strip',
'ms.minders.unsavedTip': 'Please save your changed configuration first!', 'ms.minders.unsavedTip': 'Please save your changed configuration first!',
'ms.minders.selectedCases': '{count} is selected',
}; };

View File

@ -19,4 +19,5 @@ export default {
'ms.minders.env': '环境', 'ms.minders.env': '环境',
'ms.minders.item': '{count}条', 'ms.minders.item': '{count}条',
'ms.minders.unsavedTip': '请先保存您更改的配置!', 'ms.minders.unsavedTip': '请先保存您更改的配置!',
'ms.minders.selectedCases': '已选 {count} 条',
}; };

View File

@ -988,6 +988,28 @@ export const pathMap: PathMapItem[] = [
route: RouteEnum.TEST_PLAN_REPORT, route: RouteEnum.TEST_PLAN_REPORT,
permission: [], permission: [],
level: MENU_LEVEL[2], level: MENU_LEVEL[2],
children: [
{
key: 'TEST_PLAN_REPORT_TEST_PLAN', // 测试计划报告
locale: 'menu.apiTest.reportTestPlan',
route: RouteEnum.TEST_PLAN_REPORT,
permission: [],
level: MENU_LEVEL[2],
routeQuery: {
type: 'TEST_PLAN',
},
},
{
key: 'TEST_PLAN_REPORT_TEST_PLAN_GROUP', // 测试计划组报告
locale: 'menu.apiTest.reportTestGroupPlan',
route: RouteEnum.TEST_PLAN_REPORT,
permission: [],
level: MENU_LEVEL[2],
routeQuery: {
type: 'GROUP',
},
},
],
}, },
], ],
}, },

View File

@ -1,5 +1,7 @@
import { cloneDeep } from 'lodash-es'; import { cloneDeep } from 'lodash-es';
import { addCommasToNumber } from '@/utils';
import type { PassRateCountDetail, planStatusType, TestPlanDetail } from '@/models/testPlan/testPlan'; import type { PassRateCountDetail, planStatusType, TestPlanDetail } from '@/models/testPlan/testPlan';
import type { countDetail, PlanReportDetail, StatusListType } from '@/models/testPlan/testPlanReport'; import type { countDetail, PlanReportDetail, StatusListType } from '@/models/testPlan/testPlanReport';
import { LastExecuteResults } from '@/enums/caseEnum'; import { LastExecuteResults } from '@/enums/caseEnum';
@ -134,6 +136,31 @@ export const statusConfig: StatusListType[] = [
}, },
]; ];
export const toolTipConfig = {
show: true,
trigger: 'item',
label: {
color: '#959598',
},
backgroundColor: '#fff',
padding: 24,
borderWidth: 0,
formatter(params: any) {
const html = `
<div class="w-[144px] flex items-center justify-between">
<div class=" flex items-center">
<div class="mb-[2px] mr-[8px] h-[6px] w-[6px] rounded-full bg-[${params.color}]" style="background:${
params.color
}"></div>
<div style="color:#959598">${params.name}</div>
</div>
<div class="text-[#323233] font-medium">${addCommasToNumber(params.value)}</div>
</div>
`;
return html;
},
};
export const commonConfig = { export const commonConfig = {
tooltip: { tooltip: {
show: false, show: false,

View File

@ -164,6 +164,7 @@ export default {
'common.image': 'Image', 'common.image': 'Image',
'common.text': 'Text', 'common.text': 'Text',
'common.resourceDeleted': 'Resource has been deleted', 'common.resourceDeleted': 'Resource has been deleted',
'common.resourceExpired': 'Link has failed, please get it again',
'common.refresh': 'Refresh', 'common.refresh': 'Refresh',
'common.searchByNameAndId': 'Search by ID, name, or tag', 'common.searchByNameAndId': 'Search by ID, name, or tag',
'common.archive': 'archive', 'common.archive': 'archive',

View File

@ -40,6 +40,8 @@ export default {
'menu.apiTest.apiScenario': 'Scenario', 'menu.apiTest.apiScenario': 'Scenario',
'menu.apiTest.scenario.recycle': 'Recycle', 'menu.apiTest.scenario.recycle': 'Recycle',
'menu.apiTest.report': 'Report', 'menu.apiTest.report': 'Report',
'menu.apiTest.reportTestPlan': 'Test report',
'menu.apiTest.reportTestGroupPlan': 'Test Group Report',
'menu.apiTest.reportDetail': 'Report Detail', 'menu.apiTest.reportDetail': 'Report Detail',
'menu.uiTest': 'UI Test', 'menu.uiTest': 'UI Test',
'menu.performanceTest': 'Performance Test', 'menu.performanceTest': 'Performance Test',

View File

@ -126,7 +126,7 @@ export default {
'common.move': '移动', 'common.move': '移动',
'common.moveSuccess': '移动成功', 'common.moveSuccess': '移动成功',
'common.batchMove': '批量移动', 'common.batchMove': '批量移动',
'common.batchArchiveSuccess': '归档成功', 'common.batchArchiveSuccess': '归档成功',
'common.batchCopy': '批量复制', 'common.batchCopy': '批量复制',
'common.batchCopySuccess': '批量复制成功', 'common.batchCopySuccess': '批量复制成功',
'common.batchMoveSuccess': '批量移动成功', 'common.batchMoveSuccess': '批量移动成功',
@ -163,6 +163,7 @@ export default {
'common.image': '图片', 'common.image': '图片',
'common.text': '文本', 'common.text': '文本',
'common.resourceDeleted': '资源已被删除', 'common.resourceDeleted': '资源已被删除',
'common.resourceExpired': '链接已失效,请重新获取',
'common.refresh': '刷新', 'common.refresh': '刷新',
'common.searchByIdName': '通过ID 或名称搜索', 'common.searchByIdName': '通过ID 或名称搜索',
'common.searchByIDNameTag': '通过ID、名称或标签搜索', 'common.searchByIDNameTag': '通过ID、名称或标签搜索',

View File

@ -39,6 +39,8 @@ export default {
'menu.apiTest.scenario': '场景', 'menu.apiTest.scenario': '场景',
'menu.apiTest.scenario.recycle': '回收站', 'menu.apiTest.scenario.recycle': '回收站',
'menu.apiTest.report': '报告', 'menu.apiTest.report': '报告',
'menu.apiTest.reportTestPlan': '测试报告',
'menu.apiTest.reportTestGroupPlan': '测试组报告',
'menu.apiTest.reportDetail': '报告详情', 'menu.apiTest.reportDetail': '报告详情',
'menu.uiTest': 'UI测试', 'menu.uiTest': 'UI测试',
'menu.workstation': '工作台', 'menu.workstation': '工作台',

View File

@ -17,9 +17,10 @@
</template> </template>
</a-popover> </a-popover>
</div> </div>
<a-popover position="bottom" content-class="response-popover-content"> <!-- TODO 汇总图例暂时不要了 -->
<div> <MsChart :width="props.size || '120px'" :height="props.size || '120px'" :options="props.options" /></div> <!-- <a-popover position="bottom" content-class="response-popover-content"> -->
<template #content> <div> <MsChart :width="props.size || '120px'" :height="props.size || '120px'" :options="props.options" /></div>
<!-- <template #content>
<div class="min-w-[176px] max-w-[400px] p-4"> <div class="min-w-[176px] max-w-[400px] p-4">
<div v-for="item of legendData" :key="item.value" class="mb-2 flex flex-nowrap justify-between"> <div v-for="item of legendData" :key="item.value" class="mb-2 flex flex-nowrap justify-between">
<div class="chart-flag flex flex-nowrap items-center"> <div class="chart-flag flex flex-nowrap items-center">
@ -29,8 +30,8 @@
<div class="count font-medium">{{ item.count || 0 }}</div> <div class="count font-medium">{{ item.count || 0 }}</div>
</div> </div>
</div> </div>
</template> </template> -->
</a-popover> <!-- </a-popover> -->
</div> </div>
<div class="chart-legend grid flex-1 gap-y-3"> <div class="chart-legend grid flex-1 gap-y-3">

View File

@ -179,6 +179,7 @@
import reportInfoHeader from './step/reportInfoHeaders.vue'; import reportInfoHeader from './step/reportInfoHeaders.vue';
import TiledList from './tiledList.vue'; import TiledList from './tiledList.vue';
import { toolTipConfig } from '@/config/testPlan';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { addCommasToNumber, formatDuration } from '@/utils'; import { addCommasToNumber, formatDuration } from '@/utils';
@ -248,8 +249,7 @@
const legendData = ref<LegendData[]>([]); const legendData = ref<LegendData[]>([]);
const charOptions = ref({ const charOptions = ref({
tooltip: { tooltip: {
trigger: 'item', ...toolTipConfig,
show: false,
}, },
legend: { legend: {
show: false, show: false,

View File

@ -58,6 +58,7 @@
import TiledList from './tiledList.vue'; import TiledList from './tiledList.vue';
import ReportMetricsItem from '@/views/test-plan/report/detail/component/ReportMetricsItem.vue'; import ReportMetricsItem from '@/views/test-plan/report/detail/component/ReportMetricsItem.vue';
import { toolTipConfig } from '@/config/testPlan';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { formatDuration } from '@/utils'; import { formatDuration } from '@/utils';
@ -164,8 +165,7 @@
const stepAnalysisLegendData = ref<LegendData[]>([]); const stepAnalysisLegendData = ref<LegendData[]>([]);
const defaultCharOptions = { const defaultCharOptions = {
tooltip: { tooltip: {
show: false, ...toolTipConfig,
trigger: 'item',
}, },
legend: { legend: {
show: false, show: false,

View File

@ -24,10 +24,22 @@
if (res.deleted) { if (res.deleted) {
router.push({ router.push({
name: NOT_FOUND_RESOURCE, name: NOT_FOUND_RESOURCE,
query: {
type: 'DELETE',
},
}); });
} else {
detail.value = await reportCaseDetail(res.reportId, route.query.shareId as string);
} }
if (res.expired) {
router.push({
name: NOT_FOUND_RESOURCE,
query: {
type: 'EXPIRED',
},
});
return;
}
detail.value = await reportCaseDetail(res.reportId, route.query.shareId as string);
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }

View File

@ -23,10 +23,23 @@
if (res.deleted) { if (res.deleted) {
router.push({ router.push({
name: NOT_FOUND_RESOURCE, name: NOT_FOUND_RESOURCE,
query: {
type: 'DELETE',
},
}); });
} else {
detail.value = await reportScenarioDetail(res.reportId, route.query.shareId as string);
} }
if (res.expired) {
router.push({
name: NOT_FOUND_RESOURCE,
query: {
type: 'EXPIRED',
},
});
return;
}
detail.value = await reportScenarioDetail(res.reportId, route.query.shareId as string);
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }

View File

@ -5,7 +5,7 @@
<div class="content"> <div class="content">
<div class="no-resource-svg"></div> <div class="no-resource-svg"></div>
<div class="title"> <div class="title">
<span>{{ t('common.resourceDeleted') }}</span> <span>{{ resourceType === 'DELETE' ? t('common.resourceDeleted') : t('common.resourceExpired') }}</span>
</div> </div>
</div> </div>
</div> </div>
@ -14,11 +14,15 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { useRouter } from 'vue-router'; import { useRoute } from 'vue-router';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
const { t } = useI18n(); const { t } = useI18n();
const route = useRoute();
const resourceType = ref<string>(route.query.type as string);
</script> </script>
<style lang="less"> <style lang="less">

View File

@ -48,15 +48,15 @@ export default {
'system.config.email.emailErrTip': 'Email format error, please re-enter', 'system.config.email.emailErrTip': 'Email format error, please re-enter',
'system.config.email.updateSuccess': 'Updated successfully', 'system.config.email.updateSuccess': 'Updated successfully',
'system.config.email.testSuccess': 'Email connection is successful', 'system.config.email.testSuccess': 'Email connection is successful',
'system.config.page.style': 'Platform style', 'system.config.page.style': 'Background color',
'system.config.page.styleTip': 'Platform style refers to the page background color style', 'system.config.page.styleTip': 'Platform style refers to the page background color style',
'system.config.page.theme': 'Platform theme color', 'system.config.page.theme': 'Theme color',
'system.config.page.themeTip': 'system.config.page.themeTip':
'The platform theme color refers to the purple color of MeterSphere except the page background color', 'The platform theme color refers to the purple color of MeterSphere except the page background color',
'system.config.page.default': 'Default', 'system.config.page.default': 'Default',
'system.config.page.follow': 'Follow theme', 'system.config.page.follow': 'Follow theme',
'system.config.page.custom': 'Customize', 'system.config.page.custom': 'Customize',
'system.config.page.loginPageConfig': 'Platform login page settings', 'system.config.page.loginPageConfig': 'Login Page Settings',
'system.config.page.pagePreview': 'Page preview', 'system.config.page.pagePreview': 'Page preview',
'system.config.page.reset': 'Reset', 'system.config.page.reset': 'Reset',
'system.config.page.icon': 'Website icon', 'system.config.page.icon': 'Website icon',

View File

@ -47,14 +47,14 @@ export default {
'system.config.email.emailErrTip': '邮箱格式错误,请重新输入', 'system.config.email.emailErrTip': '邮箱格式错误,请重新输入',
'system.config.email.updateSuccess': '更新成功', 'system.config.email.updateSuccess': '更新成功',
'system.config.email.testSuccess': '邮箱连接成功', 'system.config.email.testSuccess': '邮箱连接成功',
'system.config.page.style': '平台风格', 'system.config.page.style': '背景色',
'system.config.page.styleTip': '平台风格是指页面背景色风格', 'system.config.page.styleTip': '平台风格是指页面背景色风格',
'system.config.page.theme': '平台主题色', 'system.config.page.theme': '主题色',
'system.config.page.themeTip': '平台主题色是指除了页面背景色之外的 MeterSphere 紫色系颜色', 'system.config.page.themeTip': '平台主题色是指除了页面背景色之外的 MeterSphere 紫色系颜色',
'system.config.page.default': '默认', 'system.config.page.default': '默认',
'system.config.page.follow': '跟随主题色', 'system.config.page.follow': '跟随主题色',
'system.config.page.custom': '自定义', 'system.config.page.custom': '自定义',
'system.config.page.loginPageConfig': '平台登录页设置', 'system.config.page.loginPageConfig': '登录页设置',
'system.config.page.pagePreview': '页面预览', 'system.config.page.pagePreview': '页面预览',
'system.config.page.reset': '恢复默认', 'system.config.page.reset': '恢复默认',
'system.config.page.icon': '网站 Icon', 'system.config.page.icon': '网站 Icon',

View File

@ -13,7 +13,7 @@
import SetReportChart from '@/views/api-test/report/component/case/setReportChart.vue'; import SetReportChart from '@/views/api-test/report/component/case/setReportChart.vue';
import { commonConfig, seriesConfig, statusConfig } from '@/config/testPlan'; import { seriesConfig, statusConfig, toolTipConfig } from '@/config/testPlan';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import type { LegendData } from '@/models/apiTest/report'; import type { LegendData } from '@/models/apiTest/report';
@ -31,7 +31,9 @@
// //
const executeCharOptions = ref({ const executeCharOptions = ref({
...commonConfig, tooltip: {
...toolTipConfig,
},
series: { series: {
...seriesConfig, ...seriesConfig,
data: [ data: [

View File

@ -30,6 +30,19 @@
if (hrefShareDetail.deleted) { if (hrefShareDetail.deleted) {
router.push({ router.push({
name: NOT_FOUND_RESOURCE, name: NOT_FOUND_RESOURCE,
query: {
type: 'DELETE',
},
});
return;
}
if (hrefShareDetail.expired) {
router.push({
name: NOT_FOUND_RESOURCE,
query: {
type: 'EXPIRED',
},
}); });
return; return;
} }

View File

@ -252,7 +252,6 @@
<MsButton <MsButton
v-if="isShowExecuteButton(record) && hasAnyPermission(['PROJECT_TEST_PLAN:READ+EXECUTE'])" v-if="isShowExecuteButton(record) && hasAnyPermission(['PROJECT_TEST_PLAN:READ+EXECUTE'])"
class="!mx-0" class="!mx-0"
:disabled="executeId == record.id"
@click="executePlan(record)" @click="executePlan(record)"
>{{ t('testPlan.testPlanIndex.execution') }}</MsButton >{{ t('testPlan.testPlanIndex.execution') }}</MsButton
> >
@ -275,13 +274,21 @@
></a-divider> ></a-divider>
<MsButton <MsButton
v-if="!isShowExecuteButton(record) && hasAnyPermission(['PROJECT_TEST_PLAN:READ+ADD'])" v-if="
!isShowExecuteButton(record) &&
hasAnyPermission(['PROJECT_TEST_PLAN:READ+ADD']) &&
record.status !== 'ARCHIVED'
"
class="!mx-0" class="!mx-0"
@click="copyTestPlanOrGroup(record.id)" @click="copyTestPlanOrGroup(record.id)"
>{{ t('common.copy') }}</MsButton >{{ t('common.copy') }}</MsButton
> >
<a-divider <a-divider
v-if="!isShowExecuteButton(record) && hasAnyPermission(['PROJECT_TEST_PLAN:READ+ADD'])" v-if="
!isShowExecuteButton(record) &&
hasAnyPermission(['PROJECT_TEST_PLAN:READ+ADD']) &&
record.status !== 'ARCHIVED'
"
direction="vertical" direction="vertical"
:margin="8" :margin="8"
></a-divider> ></a-divider>
@ -807,18 +814,26 @@
draggableCondition: true, draggableCondition: true,
}); });
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector, resetFilterParams, setPagination } = const {
useTable( propsRes,
getTestPlanList, propsEvent,
tableProps.value, loadList,
(item) => { setLoadListParams,
return { resetSelector,
...item, resetFilterParams,
tags: (item.tags || []).map((e: string) => ({ id: e, name: e })), setPagination,
}; setLoading,
}, } = useTable(
updatePlanName getTestPlanList,
); tableProps.value,
(item) => {
return {
...item,
tags: (item.tags || []).map((e: string) => ({ id: e, name: e })),
};
},
updatePlanName
);
const batchParams = ref<BatchActionQueryParams>({ const batchParams = ref<BatchActionQueryParams>({
selectedIds: [], selectedIds: [],
@ -978,6 +993,7 @@
} finally { } finally {
executeId.value = ''; executeId.value = '';
confirmLoading.value = false; confirmLoading.value = false;
setLoading(false);
} }
} }
@ -1010,6 +1026,7 @@
}, },
}); });
} else { } else {
setLoading(true);
singleExecute(record.id); singleExecute(record.id);
} }
} }