feat(工作台): 联调工作台测试计划一揽子率
This commit is contained in:
parent
d4191a07d8
commit
954ecca484
|
@ -13,6 +13,8 @@ import type {
|
||||||
PassRateDataType,
|
PassRateDataType,
|
||||||
SelectedCardItem,
|
SelectedCardItem,
|
||||||
WorkHomePageDetail,
|
WorkHomePageDetail,
|
||||||
|
WorkTestPlanDetail,
|
||||||
|
WorkTestPlanRageDetail,
|
||||||
} from '@/models/workbench/homePage';
|
} from '@/models/workbench/homePage';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -45,6 +47,7 @@ import {
|
||||||
WorkProOverviewDetailUrl,
|
WorkProOverviewDetailUrl,
|
||||||
WorkReviewListUrl,
|
WorkReviewListUrl,
|
||||||
WorkScenarioCaseCountDetailUrl,
|
WorkScenarioCaseCountDetailUrl,
|
||||||
|
WorkTestPlanRageUrl,
|
||||||
WorkTodoBugListUrl,
|
WorkTodoBugListUrl,
|
||||||
WorkTodoPlanListUrl,
|
WorkTodoPlanListUrl,
|
||||||
WorkTodoReviewListUrl,
|
WorkTodoReviewListUrl,
|
||||||
|
@ -196,6 +199,10 @@ export function workPlanLegacyBug(data: WorkHomePageDetail) {
|
||||||
export function workApiCountCoverRage(projectId: string) {
|
export function workApiCountCoverRage(projectId: string) {
|
||||||
return MSR.get<ApiCoverageData>({ url: WorkApiCountCoverRateUrl, params: projectId }, { ignoreCancelToken: true });
|
return MSR.get<ApiCoverageData>({ url: WorkApiCountCoverRateUrl, params: projectId }, { ignoreCancelToken: true });
|
||||||
}
|
}
|
||||||
|
// 工作台-首页-测试计划数量
|
||||||
|
export function workTestPlanRage(data: WorkTestPlanDetail) {
|
||||||
|
return MSR.post<WorkTestPlanRageDetail>({ url: WorkTestPlanRageUrl, data }, { ignoreCancelToken: true });
|
||||||
|
}
|
||||||
|
|
||||||
// 待办-用例评审列表
|
// 待办-用例评审列表
|
||||||
export function workbenchTodoReviewList(data: TableQueryParams) {
|
export function workbenchTodoReviewList(data: TableQueryParams) {
|
||||||
|
|
|
@ -30,3 +30,4 @@ export const WorkBugByMeCreatedUrl = '/dashboard/create_bug_by_me'; // 工作台
|
||||||
export const WorkBugHandleByMeUrl = '/dashboard/handle_bug_by_me'; // 工作台-首页-待我处理的缺陷
|
export const WorkBugHandleByMeUrl = '/dashboard/handle_bug_by_me'; // 工作台-首页-待我处理的缺陷
|
||||||
export const WorkPlanLegacyBugUrl = '/dashboard/plan_legacy_bug'; // 工作台-首页-测试计划遗留缺陷
|
export const WorkPlanLegacyBugUrl = '/dashboard/plan_legacy_bug'; // 工作台-首页-测试计划遗留缺陷
|
||||||
export const WorkApiCountCoverRateUrl = '/api/definition/rage'; // 工作台-首页-覆盖率
|
export const WorkApiCountCoverRateUrl = '/api/definition/rage'; // 工作台-首页-覆盖率
|
||||||
|
export const WorkTestPlanRageUrl = '/test-plan/rage'; // 工作台-首页-测试计划数
|
||||||
|
|
|
@ -180,7 +180,7 @@ export const defaultValueMap: Record<string, any> = {
|
||||||
},
|
},
|
||||||
pass: {
|
pass: {
|
||||||
defaultList: cloneDeep(defaultPass),
|
defaultList: cloneDeep(defaultPass),
|
||||||
color: ['#D4D4D8', '#00C261'],
|
color: ['#00C261', '#D4D4D8'],
|
||||||
defaultName: 'workbench.homePage.passRate',
|
defaultName: 'workbench.homePage.passRate',
|
||||||
},
|
},
|
||||||
complete: {
|
complete: {
|
||||||
|
|
|
@ -39,6 +39,24 @@ export interface WorkHomePageDetail extends TableQueryParams {
|
||||||
organizationId: string;
|
organizationId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface WorkTestPlanDetail {
|
||||||
|
dayNumber: number | string;
|
||||||
|
startTime: number | null;
|
||||||
|
endTime: number | null;
|
||||||
|
projectId: string;
|
||||||
|
}
|
||||||
|
export interface WorkTestPlanRageDetail {
|
||||||
|
unExecute: number;
|
||||||
|
executed: number;
|
||||||
|
passed: number;
|
||||||
|
notPassed: number;
|
||||||
|
finished: number;
|
||||||
|
running: number;
|
||||||
|
prepared: number;
|
||||||
|
archived: number;
|
||||||
|
errorCode: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface TimeFormParams {
|
export interface TimeFormParams {
|
||||||
dayNumber: number | string;
|
dayNumber: number | string;
|
||||||
startTime: number;
|
startTime: number;
|
||||||
|
|
|
@ -176,7 +176,7 @@
|
||||||
return props.item.key === WorkCardEnum.API_CASE_COUNT
|
return props.item.key === WorkCardEnum.API_CASE_COUNT
|
||||||
? {
|
? {
|
||||||
name: t('workbench.homePage.caseExecutionRate'),
|
name: t('workbench.homePage.caseExecutionRate'),
|
||||||
color: ['#00C261', '#EDEDF1'],
|
color: ['#EDEDF1', '#00C261'],
|
||||||
tooltipText: t('workbench.homePage.apiCaseCountExecuteRateTooltip'),
|
tooltipText: t('workbench.homePage.apiCaseCountExecuteRateTooltip'),
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
|
@ -190,12 +190,12 @@
|
||||||
return props.item.key === WorkCardEnum.API_CASE_COUNT
|
return props.item.key === WorkCardEnum.API_CASE_COUNT
|
||||||
? {
|
? {
|
||||||
name: t('workbench.homePage.casePassedRate'),
|
name: t('workbench.homePage.casePassedRate'),
|
||||||
color: ['#00C261', '#ED0303'],
|
color: ['#ED0303', '#00C261'],
|
||||||
tooltipText: t('workbench.homePage.apiCaseCountPassRateTooltip'),
|
tooltipText: t('workbench.homePage.apiCaseCountPassRateTooltip'),
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
name: t('workbench.homePage.executionRate'),
|
name: t('workbench.homePage.executionRate'),
|
||||||
color: ['#00C261', '#ED0303'],
|
color: ['#ED0303', '#00C261'],
|
||||||
tooltipText: t('workbench.homePage.scenarioCaseCountPassRateTooltip'),
|
tooltipText: t('workbench.homePage.scenarioCaseCountPassRateTooltip'),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -212,6 +212,7 @@
|
||||||
props.item.key === WorkCardEnum.API_CASE_COUNT ? unCoverWithApiCase : unCoverWithApiScenario;
|
props.item.key === WorkCardEnum.API_CASE_COUNT ? unCoverWithApiCase : unCoverWithApiScenario;
|
||||||
|
|
||||||
const coverWithCase = WorkCardEnum.API_CASE_COUNT ? coverWithApiCase : coverWithApiScenario;
|
const coverWithCase = WorkCardEnum.API_CASE_COUNT ? coverWithApiCase : coverWithApiScenario;
|
||||||
|
coverData.value = cloneDeep(initCoverRate);
|
||||||
coverData.value = [
|
coverData.value = [
|
||||||
{
|
{
|
||||||
value: Number(coverage.split('%')[0]),
|
value: Number(coverage.split('%')[0]),
|
||||||
|
|
|
@ -115,7 +115,7 @@
|
||||||
|
|
||||||
const apiCountOptions = ref({});
|
const apiCountOptions = ref({});
|
||||||
const hasPermission = ref<boolean>(false);
|
const hasPermission = ref<boolean>(false);
|
||||||
function handleCoverData(detail: ApiCoverageData) {
|
async function handleCoverData(detail: ApiCoverageData) {
|
||||||
const { unCoverWithApiDefinition, coverWithApiDefinition, apiCoverage } = detail;
|
const { unCoverWithApiDefinition, coverWithApiDefinition, apiCoverage } = detail;
|
||||||
const coverData: {
|
const coverData: {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -139,8 +139,8 @@
|
||||||
hasPermission.value,
|
hasPermission.value,
|
||||||
`${props.item.key}-cover`
|
`${props.item.key}-cover`
|
||||||
);
|
);
|
||||||
coverValueList.value = coverList;
|
coverValueList.value = [...coverList];
|
||||||
coverOptions.value = covOptions;
|
coverOptions.value = { ...covOptions };
|
||||||
}
|
}
|
||||||
async function initApiCountRate() {
|
async function initApiCountRate() {
|
||||||
try {
|
try {
|
||||||
|
@ -213,6 +213,15 @@
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => hasPermission.value,
|
||||||
|
() => {
|
||||||
|
if (props.cover) {
|
||||||
|
handleCoverData(props.cover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.status,
|
() => props.status,
|
||||||
(val) => {
|
(val) => {
|
||||||
|
|
|
@ -220,7 +220,7 @@
|
||||||
...item,
|
...item,
|
||||||
children: item.children.filter(
|
children: item.children.filter(
|
||||||
(child) =>
|
(child) =>
|
||||||
child.label.toLowerCase().includes(searchKeyword.value.toLowerCase()) &&
|
t(child.label).toLowerCase().includes(searchKeyword.value.toLowerCase()) &&
|
||||||
!innerSelectedIds.value.includes(child.value)
|
!innerSelectedIds.value.includes(child.value)
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -138,20 +138,20 @@
|
||||||
|
|
||||||
function initOptions() {
|
function initOptions() {
|
||||||
const { name, color } = props.rateConfig;
|
const { name, color } = props.rateConfig;
|
||||||
|
options.value.series.data = [...props.data.slice(1)];
|
||||||
|
|
||||||
|
options.value.legend.formatter = (seriousName: string) => {
|
||||||
|
const item = props.data.find((e) => e.name === seriousName);
|
||||||
|
return `{a|${seriousName}} {b|${addCommasToNumber(item?.value || 0)}}`;
|
||||||
|
};
|
||||||
|
|
||||||
if (props.hasPermission) {
|
if (props.hasPermission) {
|
||||||
options.value.series.data = props.data.slice(1);
|
|
||||||
|
|
||||||
options.value.legend.formatter = (seriousName: string) => {
|
|
||||||
const item = props.data.find((e) => e.name === seriousName);
|
|
||||||
return `{a|${seriousName}} {b|${addCommasToNumber(item?.value || 0)}}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
options.value.title.subtext = `${props.data[0].value ?? 0}%`;
|
options.value.title.subtext = `${props.data[0].value ?? 0}%`;
|
||||||
} else {
|
} else {
|
||||||
options.value.series.data = [];
|
options.value.series.data = [];
|
||||||
options.value.title.subtext = `-%`;
|
options.value.title.subtext = `-%`;
|
||||||
}
|
}
|
||||||
|
|
||||||
options.value.graphic.invisible = !!props.hasPermission;
|
options.value.graphic.invisible = !!props.hasPermission;
|
||||||
options.value.tooltip.show = !!props.hasPermission;
|
options.value.tooltip.show = !!props.hasPermission;
|
||||||
options.value.title.text = name;
|
options.value.title.text = name;
|
||||||
|
@ -168,6 +168,13 @@
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.hasPermission,
|
||||||
|
() => {
|
||||||
|
initOptions();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initOptions();
|
initOptions();
|
||||||
});
|
});
|
||||||
|
|
|
@ -50,10 +50,16 @@
|
||||||
import PassRatePie from './passRatePie.vue';
|
import PassRatePie from './passRatePie.vue';
|
||||||
import TabCard from './tabCard.vue';
|
import TabCard from './tabCard.vue';
|
||||||
|
|
||||||
|
import { workTestPlanRage } from '@/api/modules/workbench';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import useAppStore from '@/store/modules/app';
|
import useAppStore from '@/store/modules/app';
|
||||||
|
|
||||||
import type { PassRateDataType, SelectedCardItem, TimeFormParams } from '@/models/workbench/homePage';
|
import type {
|
||||||
|
SelectedCardItem,
|
||||||
|
TimeFormParams,
|
||||||
|
WorkTestPlanDetail,
|
||||||
|
WorkTestPlanRageDetail,
|
||||||
|
} from '@/models/workbench/homePage';
|
||||||
|
|
||||||
import { handlePieData, handleUpdateTabPie } from '../utils';
|
import { handlePieData, handleUpdateTabPie } from '../utils';
|
||||||
|
|
||||||
|
@ -83,33 +89,6 @@
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO 假数据后边几个要用
|
|
||||||
const detail = ref<PassRateDataType>({
|
|
||||||
statusStatisticsMap: {
|
|
||||||
execute: [
|
|
||||||
{ name: '覆盖率', count: 10 },
|
|
||||||
{ name: '已覆盖', count: 2 },
|
|
||||||
{ name: '未覆盖', count: 1 },
|
|
||||||
],
|
|
||||||
pass: [
|
|
||||||
{ name: '覆盖率', count: 10 },
|
|
||||||
{ name: '已覆盖', count: 2 },
|
|
||||||
{ name: '未覆盖', count: 1 },
|
|
||||||
],
|
|
||||||
complete: [
|
|
||||||
{ name: '覆盖率', count: 10 },
|
|
||||||
{ name: '已覆盖', count: 2 },
|
|
||||||
{ name: '未覆盖', count: 1 },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
statusPercentList: [
|
|
||||||
{ status: 'HTTP', count: 1, percentValue: '10%' },
|
|
||||||
{ status: 'TCP', count: 3, percentValue: '0%' },
|
|
||||||
{ status: 'BBB', count: 6, percentValue: '0%' },
|
|
||||||
],
|
|
||||||
errorCode: 109001,
|
|
||||||
});
|
|
||||||
|
|
||||||
const executionOptions = ref<Record<string, any>>({});
|
const executionOptions = ref<Record<string, any>>({});
|
||||||
const passOptions = ref<Record<string, any>>({});
|
const passOptions = ref<Record<string, any>>({});
|
||||||
const completeOptions = ref<Record<string, any>>({});
|
const completeOptions = ref<Record<string, any>>({});
|
||||||
|
@ -146,42 +125,112 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
const testPlanCountOptions = ref({});
|
const testPlanCountOptions = ref({});
|
||||||
|
// 测试计划权限
|
||||||
const hasPermission = ref<boolean>(false);
|
const hasPermission = ref<boolean>(false);
|
||||||
async function initTestPlanCount() {
|
async function initTestPlanCount() {
|
||||||
try {
|
try {
|
||||||
const { startTime, endTime, dayNumber } = timeForm.value;
|
const { startTime, endTime, dayNumber } = timeForm.value;
|
||||||
const params = {
|
const params: WorkTestPlanDetail = {
|
||||||
current: 1,
|
|
||||||
pageSize: 5,
|
|
||||||
startTime: dayNumber ? null : startTime,
|
startTime: dayNumber ? null : startTime,
|
||||||
endTime: dayNumber ? null : endTime,
|
endTime: dayNumber ? null : endTime,
|
||||||
dayNumber: dayNumber ?? null,
|
dayNumber: dayNumber ?? null,
|
||||||
projectIds: innerProjectIds.value,
|
projectId: innerProjectIds.value[0],
|
||||||
organizationId: appStore.currentOrgId,
|
|
||||||
handleUsers: [],
|
|
||||||
};
|
};
|
||||||
const { statusStatisticsMap, statusPercentList, errorCode } = detail.value;
|
const detail: WorkTestPlanRageDetail = await workTestPlanRage(params);
|
||||||
|
const { unExecute, executed, passed, notPassed, finished, running, prepared, archived, errorCode } = detail;
|
||||||
hasPermission.value = errorCode !== 109001;
|
hasPermission.value = errorCode !== 109001;
|
||||||
testPlanCountOptions.value = handlePieData(props.item.key, hasPermission.value, statusPercentList);
|
|
||||||
|
const executeRate =
|
||||||
|
executed + unExecute > 0 ? parseFloat(((executed / (executed + unExecute)) * 100).toFixed(2)) : 0;
|
||||||
|
const executeData: {
|
||||||
|
name: string;
|
||||||
|
count: number;
|
||||||
|
}[] = [
|
||||||
|
{
|
||||||
|
name: t('workbench.homePage.executeRate'),
|
||||||
|
count: executeRate,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: t('common.unExecute'),
|
||||||
|
count: unExecute,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: t('common.executed'),
|
||||||
|
count: executed,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const passRate = passed + notPassed > 0 ? parseFloat(((passed / (passed + notPassed)) * 100).toFixed(2)) : 0;
|
||||||
|
|
||||||
|
const passData = [
|
||||||
|
{
|
||||||
|
name: t('workbench.homePage.passRate'),
|
||||||
|
count: passRate,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: t('workbench.homePage.havePassed'),
|
||||||
|
count: passed,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: t('workbench.homePage.notPass'),
|
||||||
|
count: notPassed,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const statusPercentList = [
|
||||||
|
{ status: t('common.notStarted'), count: prepared, percentValue: '0%' },
|
||||||
|
{ status: t('common.inProgress'), count: running, percentValue: '0%' },
|
||||||
|
{ status: t('common.completed'), count: finished, percentValue: '0%' },
|
||||||
|
{ status: t('common.archived'), count: archived, percentValue: '0%' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const total = statusPercentList.reduce((sum, item) => sum + item.count, 0);
|
||||||
|
|
||||||
|
const listStatusPercentList = statusPercentList.map((item) => ({
|
||||||
|
...item,
|
||||||
|
percentValue: total > 0 ? `${((item.count / total) * 100).toFixed(2)}%` : '0%',
|
||||||
|
}));
|
||||||
|
|
||||||
|
const completeRate = total > 0 ? parseFloat(((finished / total) * 100).toFixed(2)) : 0;
|
||||||
|
|
||||||
|
const completeData = [
|
||||||
|
{
|
||||||
|
name: t('workbench.homePage.completeRate'),
|
||||||
|
count: completeRate,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: t('common.completed'),
|
||||||
|
count: finished,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: t('common.inProgress'),
|
||||||
|
count: running,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: t('common.notStarted'),
|
||||||
|
count: prepared,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
testPlanCountOptions.value = handlePieData(props.item.key, hasPermission.value, listStatusPercentList);
|
||||||
|
|
||||||
// 执行率
|
// 执行率
|
||||||
const { options: executedOptions, valueList: executedList } = handleUpdateTabPie(
|
const { options: executedOptions, valueList: executedList } = handleUpdateTabPie(
|
||||||
statusStatisticsMap?.execute || [],
|
executeData,
|
||||||
hasPermission.value,
|
hasPermission.value,
|
||||||
`${props.item.key}-execute`
|
`${props.item.key}-execute`
|
||||||
);
|
);
|
||||||
|
|
||||||
// 通过率
|
// 通过率
|
||||||
const { options: passedOptions, valueList: passList } = handleUpdateTabPie(
|
const { options: passedOptions, valueList: passList } = handleUpdateTabPie(
|
||||||
statusStatisticsMap?.pass || [],
|
passData,
|
||||||
hasPermission.value,
|
hasPermission.value,
|
||||||
`${props.item.key}-pass`
|
`${props.item.key}-pass`
|
||||||
);
|
);
|
||||||
|
|
||||||
// 完成率
|
// 完成率
|
||||||
const { options: comOptions, valueList: completeList } = handleUpdateTabPie(
|
const { options: comOptions, valueList: completeList } = handleUpdateTabPie(
|
||||||
statusStatisticsMap?.complete || [],
|
completeData,
|
||||||
hasPermission.value,
|
hasPermission.value,
|
||||||
`${props.item.key}-complete`
|
`${props.item.key}-complete`
|
||||||
);
|
);
|
||||||
|
|
|
@ -95,7 +95,7 @@
|
||||||
:type="item.key"
|
:type="item.key"
|
||||||
:item="item"
|
:item="item"
|
||||||
:status="projectLoadingStatus[item.projectIds[0]]"
|
:status="projectLoadingStatus[item.projectIds[0]]"
|
||||||
:cover="requestResults.get(item.projectIds[0])"
|
:cover="requestResults[item.projectIds[0]]"
|
||||||
@change="changeHandler"
|
@change="changeHandler"
|
||||||
/>
|
/>
|
||||||
<ApiChangeList
|
<ApiChangeList
|
||||||
|
@ -123,7 +123,7 @@
|
||||||
v-model:projectIds="item.projectIds"
|
v-model:projectIds="item.projectIds"
|
||||||
:status="projectLoadingStatus[item.projectIds[0]]"
|
:status="projectLoadingStatus[item.projectIds[0]]"
|
||||||
:item="item"
|
:item="item"
|
||||||
:cover="requestResults.get(item.projectIds[0])"
|
:cover="requestResults[item.projectIds[0]]"
|
||||||
@change="changeHandler"
|
@change="changeHandler"
|
||||||
/>
|
/>
|
||||||
<TestPlanCount
|
<TestPlanCount
|
||||||
|
@ -173,7 +173,7 @@
|
||||||
import { sleep } from '@/utils';
|
import { sleep } from '@/utils';
|
||||||
import { getLocalStorage, setLocalStorage } from '@/utils/local-storage';
|
import { getLocalStorage, setLocalStorage } from '@/utils/local-storage';
|
||||||
|
|
||||||
import { SelectedCardItem, TimeFormParams } from '@/models/workbench/homePage';
|
import { ApiCoverageData, SelectedCardItem, TimeFormParams } from '@/models/workbench/homePage';
|
||||||
import { WorkCardEnum } from '@/enums/workbenchEnum';
|
import { WorkCardEnum } from '@/enums/workbenchEnum';
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
@ -235,33 +235,9 @@
|
||||||
const defaultWorkList = ref<SelectedCardItem[]>([]);
|
const defaultWorkList = ref<SelectedCardItem[]>([]);
|
||||||
|
|
||||||
const showNoData = ref(false);
|
const showNoData = ref(false);
|
||||||
async function initDefaultList() {
|
|
||||||
try {
|
|
||||||
appStore.showLoading();
|
|
||||||
const result = await getDashboardLayout(appStore.currentOrgId);
|
|
||||||
defaultWorkList.value = result;
|
|
||||||
} catch (error) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(error);
|
|
||||||
} finally {
|
|
||||||
if (!defaultWorkList.value.length) {
|
|
||||||
showNoData.value = true;
|
|
||||||
}
|
|
||||||
appStore.hideLoading();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function changeHandler() {
|
|
||||||
try {
|
|
||||||
await editDashboardLayout(defaultWorkList.value, appStore.currentOrgId);
|
|
||||||
} catch (error) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 用来存储每个请求的结果,key 是项目ID
|
// 用来存储每个请求的结果,key 是项目ID
|
||||||
const requestResults = ref(new Map());
|
const requestResults = ref<Record<string, ApiCoverageData>>({});
|
||||||
// 用来存储已请求过的项目
|
// 用来存储已请求过的项目
|
||||||
const requestedIds = ref(new Set());
|
const requestedIds = ref(new Set());
|
||||||
|
|
||||||
|
@ -271,7 +247,7 @@
|
||||||
try {
|
try {
|
||||||
projectLoadingStatus.value[projectId] = true;
|
projectLoadingStatus.value[projectId] = true;
|
||||||
const result = await workApiCountCoverRage(projectId);
|
const result = await workApiCountCoverRage(projectId);
|
||||||
requestResults.value.set(projectId, result);
|
requestResults.value[projectId] = result;
|
||||||
projectLoadingStatus.value[projectId] = false;
|
projectLoadingStatus.value[projectId] = false;
|
||||||
await sleep(300);
|
await sleep(300);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -285,6 +261,8 @@
|
||||||
// 针对项目id不重复的依次请求
|
// 针对项目id不重复的依次请求
|
||||||
async function requestQueue() {
|
async function requestQueue() {
|
||||||
requestedIds.value = new Set([]);
|
requestedIds.value = new Set([]);
|
||||||
|
requestResults.value = {};
|
||||||
|
|
||||||
const awaitType = [WorkCardEnum.API_COUNT, WorkCardEnum.API_CASE_COUNT, WorkCardEnum.SCENARIO_COUNT];
|
const awaitType = [WorkCardEnum.API_COUNT, WorkCardEnum.API_CASE_COUNT, WorkCardEnum.SCENARIO_COUNT];
|
||||||
const queueList = defaultWorkList.value.filter((item) => awaitType.includes(item.key));
|
const queueList = defaultWorkList.value.filter((item) => awaitType.includes(item.key));
|
||||||
for (let i = 0; i < queueList.length; i++) {
|
for (let i = 0; i < queueList.length; i++) {
|
||||||
|
@ -297,13 +275,40 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 刷新
|
async function initDefaultList() {
|
||||||
async function handleRefresh() {
|
if (appStore.currentOrgId) {
|
||||||
await initDefaultList();
|
try {
|
||||||
requestQueue();
|
appStore.showLoading();
|
||||||
|
const result = await getDashboardLayout(appStore.currentOrgId);
|
||||||
|
defaultWorkList.value = result;
|
||||||
|
requestQueue();
|
||||||
|
} catch (error) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
if (!defaultWorkList.value.length) {
|
||||||
|
showNoData.value = true;
|
||||||
|
}
|
||||||
|
appStore.hideLoading();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
async function changeHandler() {
|
||||||
|
try {
|
||||||
|
await editDashboardLayout(defaultWorkList.value, appStore.currentOrgId);
|
||||||
|
} catch (error) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新
|
||||||
|
async function handleRefresh() {
|
||||||
|
initDefaultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
const defaultTime = getLocalStorage(`WORK_TIME_${userStore.id}`);
|
const defaultTime = getLocalStorage(`WORK_TIME_${userStore.id}`);
|
||||||
if (!defaultTime) {
|
if (!defaultTime) {
|
||||||
setLocalStorage(`WORK_TIME_${userStore.id}`, JSON.stringify(timeForm.value));
|
setLocalStorage(`WORK_TIME_${userStore.id}`, JSON.stringify(timeForm.value));
|
||||||
|
@ -314,8 +319,7 @@
|
||||||
rangeTime.value = [startTime, endTime];
|
rangeTime.value = [startTime, endTime];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await initDefaultList();
|
initDefaultList();
|
||||||
requestQueue();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const time = ref({ ...timeForm.value });
|
const time = ref({ ...timeForm.value });
|
||||||
|
|
|
@ -42,6 +42,7 @@ export default {
|
||||||
'workbench.homePage.associationCASE': 'Association CASE',
|
'workbench.homePage.associationCASE': 'Association CASE',
|
||||||
'workbench.homePage.associatedScene': 'Associated scenarios',
|
'workbench.homePage.associatedScene': 'Associated scenarios',
|
||||||
'workbench.homePage.pendingDefect': 'Defects for me to deal with',
|
'workbench.homePage.pendingDefect': 'Defects for me to deal with',
|
||||||
|
'workbench.homePage.defectProcessingNumber': 'Statistics of defect handlers',
|
||||||
'workbench.homePage.defectTotal': 'Total defect',
|
'workbench.homePage.defectTotal': 'Total defect',
|
||||||
'workbench.homePage.legacyDefectsNumber': 'Legacy defects number',
|
'workbench.homePage.legacyDefectsNumber': 'Legacy defects number',
|
||||||
'workbench.homePage.createdBugByMe': 'My created defects',
|
'workbench.homePage.createdBugByMe': 'My created defects',
|
||||||
|
|
|
@ -42,7 +42,7 @@ export default {
|
||||||
'workbench.homePage.associationCASE': '关联CASE',
|
'workbench.homePage.associationCASE': '关联CASE',
|
||||||
'workbench.homePage.associatedScene': '关联场景',
|
'workbench.homePage.associatedScene': '关联场景',
|
||||||
'workbench.homePage.pendingDefect': '待我处理的缺陷',
|
'workbench.homePage.pendingDefect': '待我处理的缺陷',
|
||||||
'workbench.homePage.defectProcessingNumber': '缺陷处理人数',
|
'workbench.homePage.defectProcessingNumber': '缺陷处理人统计',
|
||||||
'workbench.homePage.defectTotal': '缺陷总数',
|
'workbench.homePage.defectTotal': '缺陷总数',
|
||||||
'workbench.homePage.legacyDefectsNumber': '遗留缺陷数',
|
'workbench.homePage.legacyDefectsNumber': '遗留缺陷数',
|
||||||
'workbench.homePage.createdBugByMe': '我创建的缺陷',
|
'workbench.homePage.createdBugByMe': '我创建的缺陷',
|
||||||
|
|
|
@ -446,6 +446,7 @@ export function handlePieData(
|
||||||
options.title.subtext = addCommasToNumber(totalCount);
|
options.title.subtext = addCommasToNumber(totalCount);
|
||||||
if (!hasPermission) {
|
if (!hasPermission) {
|
||||||
options.title.subtext = '-';
|
options.title.subtext = '-';
|
||||||
|
options.series.data = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置图例的格式化函数,显示百分比
|
// 设置图例的格式化函数,显示百分比
|
||||||
|
|
|
@ -16,12 +16,12 @@
|
||||||
v-model:model-value="features"
|
v-model:model-value="features"
|
||||||
:options="featureOptions"
|
:options="featureOptions"
|
||||||
:allow-search="false"
|
:allow-search="false"
|
||||||
allow-clear
|
|
||||||
class="!w-[240px]"
|
class="!w-[240px]"
|
||||||
:prefix="t('project.messageManagement.function')"
|
:prefix="t('project.messageManagement.function')"
|
||||||
:multiple="true"
|
:multiple="true"
|
||||||
:has-all-select="true"
|
:has-all-select="true"
|
||||||
:default-all-select="true"
|
:default-all-select="true"
|
||||||
|
:at-least-one="true"
|
||||||
/>
|
/>
|
||||||
<a-button type="outline" class="arco-btn-outline--secondary p-[10px]" @click="() => handleRefresh()">
|
<a-button type="outline" class="arco-btn-outline--secondary p-[10px]" @click="() => handleRefresh()">
|
||||||
<MsIcon type="icon-icon_reset_outlined" size="14" />
|
<MsIcon type="icon-icon_reset_outlined" size="14" />
|
||||||
|
|
Loading…
Reference in New Issue