fix(工作台): 修复个工作台测试计划概览&缺陷饼图bug
This commit is contained in:
parent
0e2894eea6
commit
0a7787a0cd
|
@ -230,7 +230,7 @@ export function workbenchTodoTestPlanList(data: TableQueryParams) {
|
||||||
}
|
}
|
||||||
// 待办-测试计划列表
|
// 待办-测试计划列表
|
||||||
export function getWorkTestPlanListUrl(projectId: string) {
|
export function getWorkTestPlanListUrl(projectId: string) {
|
||||||
return MSR.get<CascaderOption[]>({ url: `${WorkTestPlanListUrl}/${projectId}` });
|
return MSR.get<CascaderOption[]>({ url: `${WorkTestPlanListUrl}/${projectId}` }, { ignoreCancelToken: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 工作台-测试计划概览
|
// 工作台-测试计划概览
|
||||||
|
|
|
@ -9,7 +9,7 @@ export default function bindDataZoomEvent(
|
||||||
const chartDom = chartRef.value?.chartRef;
|
const chartDom = chartRef.value?.chartRef;
|
||||||
|
|
||||||
const handleDataZoom = (params: any) => {
|
const handleDataZoom = (params: any) => {
|
||||||
const containerWidth = chartDom.getDom().offsetWidth;
|
const containerWidth = chartDom.getDom()?.offsetWidth;
|
||||||
// 计算缩放百分比
|
// 计算缩放百分比
|
||||||
const percent = (params.end - params.start) / 100;
|
const percent = (params.end - params.start) / 100;
|
||||||
// 计算单组条形图的宽度(包括间隔和最小宽度)
|
// 计算单组条形图的宽度(包括间隔和最小宽度)
|
||||||
|
@ -52,8 +52,9 @@ export default function bindDataZoomEvent(
|
||||||
|
|
||||||
const handleResize = () => {
|
const handleResize = () => {
|
||||||
if (chartDom) {
|
if (chartDom) {
|
||||||
const currentOptions = chartDom.chart.getOption();
|
const currentOptions = chartDom.chart?.getOption();
|
||||||
if (currentOptions.dataZoom.length) {
|
|
||||||
|
if (currentOptions && currentOptions?.dataZoom.length) {
|
||||||
handleDataZoom({ start: currentOptions.dataZoom[0].start, end: currentOptions.dataZoom[0].end });
|
handleDataZoom({ start: currentOptions.dataZoom[0].start, end: currentOptions.dataZoom[0].end });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
color: var(--color-text-4);
|
color: var(--color-text-4);
|
||||||
background-color: var(--color-text-fff);
|
background-color: var(--color-text-fff);
|
||||||
@apply flex items-center justify-center;
|
@apply flex w-full items-center justify-center;
|
||||||
}
|
}
|
||||||
.no-config-svg {
|
.no-config-svg {
|
||||||
margin: 0 auto 24px;
|
margin: 0 auto 24px;
|
||||||
|
|
|
@ -97,21 +97,15 @@
|
||||||
const hasPermission = ref<boolean>(false);
|
const hasPermission = ref<boolean>(false);
|
||||||
|
|
||||||
function handleData(detail: OverViewOfProject) {
|
function handleData(detail: OverViewOfProject) {
|
||||||
const labelCount: Record<string, any> = {};
|
const data = detail.projectCountList.map((e) => {
|
||||||
const uniqueData = detail.projectCountList.map((e) => {
|
return {
|
||||||
const { name } = e;
|
value: '',
|
||||||
if (!labelCount[name]) {
|
label: e.name,
|
||||||
labelCount[name] = 1;
|
};
|
||||||
return { value: '', label: name };
|
|
||||||
}
|
|
||||||
|
|
||||||
labelCount[name] += 1;
|
|
||||||
// 添加序号后缀
|
|
||||||
return { value: '', label: `${name} (${labelCount[name]})` };
|
|
||||||
});
|
});
|
||||||
|
|
||||||
options.value = getSeriesData(
|
options.value = getSeriesData(
|
||||||
uniqueData,
|
data,
|
||||||
detail,
|
detail,
|
||||||
[...defectStatusColor, ...getColorScheme(13)],
|
[...defectStatusColor, ...getColorScheme(13)],
|
||||||
false,
|
false,
|
||||||
|
|
|
@ -161,12 +161,20 @@
|
||||||
showSkeleton.value = false;
|
showSkeleton.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const chartRef = ref<InstanceType<typeof MsChart>>();
|
||||||
|
|
||||||
async function handleProjectChange(shouldEmit = false) {
|
async function handleProjectChange(shouldEmit = false) {
|
||||||
await nextTick();
|
await nextTick();
|
||||||
innerSelectAll.value = appStore.projectList.length === innerProjectIds.value.length;
|
innerSelectAll.value = appStore.projectList.length === innerProjectIds.value.length;
|
||||||
await nextTick();
|
await nextTick();
|
||||||
initOverViewDetail();
|
await initOverViewDetail();
|
||||||
|
|
||||||
|
const chartDom = chartRef.value?.chartRef;
|
||||||
|
|
||||||
|
if (chartDom && chartDom.chart) {
|
||||||
|
createCustomTooltip(chartDom);
|
||||||
|
bindDataZoomEvent(chartRef, options);
|
||||||
|
}
|
||||||
if (shouldEmit) emit('change');
|
if (shouldEmit) emit('change');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +185,6 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const chartRef = ref<InstanceType<typeof MsChart>>();
|
|
||||||
|
|
||||||
async function handleRefreshKeyChange() {
|
async function handleRefreshKeyChange() {
|
||||||
await nextTick(() => {
|
await nextTick(() => {
|
||||||
|
@ -191,7 +198,6 @@
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await initOverViewDetail();
|
await initOverViewDetail();
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const chartDom = chartRef.value?.chartRef;
|
const chartDom = chartRef.value?.chartRef;
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,9 @@
|
||||||
<MsChart height="76px" width="76px" :options="execOptions" />
|
<MsChart height="76px" width="76px" :options="execOptions" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<HeaderCard :content-tab-list="cardModuleList" />
|
<div class="flex-1">
|
||||||
|
<HeaderCard :content-tab-list="cardModuleList" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<MsChart ref="chartRef" height="280px" :options="options" />
|
<MsChart ref="chartRef" height="280px" :options="options" />
|
||||||
|
@ -318,16 +320,18 @@
|
||||||
const [newProjectId] = innerProjectIds.value;
|
const [newProjectId] = innerProjectIds.value;
|
||||||
const projectName = projectOptions.value.find((e) => e.value === newProjectId)?.label;
|
const projectName = projectOptions.value.find((e) => e.value === newProjectId)?.label;
|
||||||
|
|
||||||
const treeList = childrenData.value[newProjectId];
|
const treeList = childrenData.value[newProjectId] || [];
|
||||||
|
|
||||||
const modules = findNodePathByKey(treeList, id, undefined, 'value');
|
if (treeList.length) {
|
||||||
|
const modules = findNodePathByKey(treeList, id, undefined, 'value');
|
||||||
|
|
||||||
if (modules) {
|
if (modules) {
|
||||||
const moduleName = (modules || [])?.treePath.map((item: any) => item.label);
|
const moduleName = (modules || [])?.treePath.map((item: any) => item.label);
|
||||||
if (moduleName.length === 1) {
|
if (moduleName.length === 1) {
|
||||||
return `${projectName}/${moduleName[0]}`;
|
return `${projectName}/${moduleName[0]}`;
|
||||||
|
}
|
||||||
|
return `${projectName}/${moduleName.join(' / ')}`;
|
||||||
}
|
}
|
||||||
return `${projectName}/${moduleName.join(' / ')}`;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,7 +407,9 @@
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
projectOptions.value = appStore.projectList.map((e) => ({ value: e.id, label: e.name }));
|
projectOptions.value = appStore.projectList.map((e) => ({ value: e.id, label: e.name }));
|
||||||
const [newProjectId] = props.item.projectIds;
|
const [newProjectId] = props.item.projectIds;
|
||||||
selectValue.value = [newProjectId, props.item.planId];
|
if (props.item.planId) {
|
||||||
|
selectValue.value = [newProjectId, props.item.planId];
|
||||||
|
}
|
||||||
refreshHandler(newProjectId);
|
refreshHandler(newProjectId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -132,10 +132,7 @@ export function getCommonBarOptions(
|
||||||
<div class="flex h-[18px] items-center justify-between">
|
<div class="flex h-[18px] items-center justify-between">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="mb-[2px] mr-[8px] h-[8px] w-[8px] rounded-sm" style="background:${item.color}"></div>
|
<div class="mb-[2px] mr-[8px] h-[8px] w-[8px] rounded-sm" style="background:${item.color}"></div>
|
||||||
<div class="one-line-text max-w-[100px] text-[var(--color-text-2)]">${item.seriesName.replace(
|
<div class="one-line-text max-w-[100px] text-[var(--color-text-2)]">${item.seriesName}</div>
|
||||||
/\s\(\d+\)$/,
|
|
||||||
''
|
|
||||||
)}</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="text-[var(--color-text-1)] font-semibold">${addCommasToNumber(item.data.originValue || 0)}</div>
|
<div class="text-[var(--color-text-1)] font-semibold">${addCommasToNumber(item.data.originValue || 0)}</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -256,7 +253,7 @@ export function getCommonBarOptions(
|
||||||
ellipsis: '...',
|
ellipsis: '...',
|
||||||
},
|
},
|
||||||
formatter(name: string) {
|
formatter(name: string) {
|
||||||
return name.replace(/\s\(\d+\)$/, ''); // 去掉后缀 "(数字) 确保seriesName 重复也可以展示为正常"
|
return name;
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
show: true,
|
show: true,
|
||||||
|
@ -320,7 +317,7 @@ export function getCommonBarOptions(
|
||||||
}
|
}
|
||||||
|
|
||||||
// 下方饼图配置
|
// 下方饼图配置
|
||||||
export function getPieCharOptions(key: WorkCardEnum) {
|
export function getPieCharOptions() {
|
||||||
return {
|
return {
|
||||||
title: {
|
title: {
|
||||||
show: true,
|
show: true,
|
||||||
|
@ -341,7 +338,7 @@ export function getPieCharOptions(key: WorkCardEnum) {
|
||||||
},
|
},
|
||||||
textAlign: 'center', // 确保副标题居中
|
textAlign: 'center', // 确保副标题居中
|
||||||
},
|
},
|
||||||
color: colorMapConfig[key],
|
|
||||||
tooltip: { show: true },
|
tooltip: { show: true },
|
||||||
legend: {
|
legend: {
|
||||||
show: false,
|
show: false,
|
||||||
|
@ -351,6 +348,8 @@ export function getPieCharOptions(key: WorkCardEnum) {
|
||||||
type: 'pie',
|
type: 'pie',
|
||||||
radius: ['75%', '90%'],
|
radius: ['75%', '90%'],
|
||||||
center: [90, '48%'],
|
center: [90, '48%'],
|
||||||
|
minAngle: 5, // 设置扇区的最小角度
|
||||||
|
minShowLabelAngle: 10, // 设置标签显示的最小角度
|
||||||
avoidLabelOverlap: false,
|
avoidLabelOverlap: false,
|
||||||
label: {
|
label: {
|
||||||
show: false,
|
show: false,
|
||||||
|
@ -404,27 +403,29 @@ export function handlePieData(
|
||||||
}[]
|
}[]
|
||||||
| null = []
|
| null = []
|
||||||
) {
|
) {
|
||||||
const options: Record<string, any> = getPieCharOptions(key);
|
const options: Record<string, any> = getPieCharOptions();
|
||||||
const lastStatusPercentList = statusPercentList ?? [];
|
const lastStatusPercentList = statusPercentList ?? [];
|
||||||
const hasDataLength = lastStatusPercentList.filter((e) => Number(e.count) > 0).length;
|
const hasDataLength = lastStatusPercentList.filter((e) => Number(e.count) > 0).length;
|
||||||
const pieBorderWidth = hasDataLength === 1 ? 0 : 2;
|
const pieBorderWidth = hasDataLength === 1 ? 0 : 2;
|
||||||
|
|
||||||
options.series.data =
|
const lastData = lastStatusPercentList
|
||||||
hasDataLength > 0
|
.map((item, color) => ({
|
||||||
? lastStatusPercentList.map((item) => ({
|
name: item.status,
|
||||||
name: item.status,
|
value: item.count,
|
||||||
value: item.count,
|
tooltip: {
|
||||||
tooltip: {
|
...toolTipConfig,
|
||||||
...toolTipConfig,
|
position: 'right',
|
||||||
position: 'right',
|
show: !!hasPermission,
|
||||||
show: !!hasPermission,
|
},
|
||||||
},
|
itemStyle: {
|
||||||
itemStyle: {
|
color: colorMapConfig[key][color],
|
||||||
borderWidth: pieBorderWidth,
|
borderWidth: pieBorderWidth,
|
||||||
borderColor: '#ffffff',
|
borderColor: '#ffffff',
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
: [];
|
.filter((e) => e.value !== 0);
|
||||||
|
|
||||||
|
options.series.data = hasDataLength > 0 ? lastData : [];
|
||||||
|
|
||||||
// 计算总数和图例格式
|
// 计算总数和图例格式
|
||||||
const tempObject: Record<string, any> = {};
|
const tempObject: Record<string, any> = {};
|
||||||
|
@ -677,10 +678,7 @@ export function getSeriesData(
|
||||||
<div class="mb-[2px] mr-[8px] h-[8px] w-[8px] rounded-sm bg-[${params.color}]" style="background:${
|
<div class="mb-[2px] mr-[8px] h-[8px] w-[8px] rounded-sm bg-[${params.color}]" style="background:${
|
||||||
params.color
|
params.color
|
||||||
}"></div>
|
}"></div>
|
||||||
<div class="one-line-text max-w-[100px]"" style="color:#959598">${params.name.replace(
|
<div class="one-line-text max-w-[100px]"" style="color:#959598">${params.name}</div>
|
||||||
/\s\(\d+\)$/,
|
|
||||||
''
|
|
||||||
)}</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="text-[var(--color-text-1)] font-semibold">${addCommasToNumber(params.value)}</div>
|
<div class="text-[var(--color-text-1)] font-semibold">${addCommasToNumber(params.value)}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue