refactor(工作台): 重构工作台首页项目概览和我创建的卡片调整人员概览交互调整
This commit is contained in:
parent
555f9845c4
commit
3723d803ad
|
@ -349,15 +349,6 @@ export default defineComponent(
|
|||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.defaultAllSelect,
|
||||
(val) => {
|
||||
if (val) {
|
||||
handleSelectAllChange(true);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 检测全选状态变化,全选时需要覆盖选择器的输入框内容,展示文本 ‘全部’;非全选时则移除文本 ‘全部’
|
||||
watchEffect(() => {
|
||||
const innerDom = selectRef.value?.$el.nextElementSibling.querySelector('.arco-select-view-inner') as HTMLElement;
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
>
|
||||
</MsSelect>
|
||||
<MsSelect
|
||||
:key="props.refreshKey"
|
||||
v-model:model-value="innerHandleUsers"
|
||||
:options="memberOptions"
|
||||
allow-clear
|
||||
|
@ -215,7 +214,8 @@
|
|||
if (val) {
|
||||
innerProjectIds.value = [val];
|
||||
}
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
watch(
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
import { contentTabList } from '@/config/workbench';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import { addCommasToNumber } from '@/utils';
|
||||
import { characterLimit } from '@/utils';
|
||||
|
||||
import type {
|
||||
ModuleCardItem,
|
||||
|
@ -63,9 +63,9 @@
|
|||
SelectedCardItem,
|
||||
TimeFormParams,
|
||||
} from '@/models/workbench/homePage';
|
||||
import { WorkCardEnum, WorkOverviewEnum } from '@/enums/workbenchEnum';
|
||||
import { WorkCardEnum } from '@/enums/workbenchEnum';
|
||||
|
||||
import { getColorScheme, getCommonBarOptions, handleNoDataDisplay } from '../utils';
|
||||
import { getColorScheme, getCommonBarOptions, getSeriesData, handleNoDataDisplay } from '../utils';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@ -114,85 +114,26 @@
|
|||
|
||||
function handleData(detail: OverViewOfProject) {
|
||||
// 处理模块顺序
|
||||
const tempAxisData = detail.xaxis.map((xAxisKey) => {
|
||||
const data = contentTabList.find((e) => e.value === xAxisKey);
|
||||
cardModuleList.value = contentTabList
|
||||
.map((item) => {
|
||||
return {
|
||||
...data,
|
||||
label: t(data?.label || ''),
|
||||
count: detail.caseCountMap[xAxisKey as WorkOverviewEnum],
|
||||
...item,
|
||||
label: t(item.label),
|
||||
count: detail.caseCountMap[item.value],
|
||||
};
|
||||
});
|
||||
})
|
||||
.filter((e) => Object.keys(detail.caseCountMap).includes(e.value as string));
|
||||
|
||||
cardModuleList.value = tempAxisData as ModuleCardItem[];
|
||||
options.value = getCommonBarOptions(hasRoom.value, getColorScheme(detail.projectCountList.length));
|
||||
const { invisible, text } = handleNoDataDisplay(detail.xaxis, hasPermission.value);
|
||||
options.value.graphic.invisible = invisible;
|
||||
options.value.graphic.style.text = text;
|
||||
// x轴
|
||||
options.value.xAxis.data = cardModuleList.value.map((e) => e.label);
|
||||
options.value.xAxis.data = detail.xaxis.map((e) => characterLimit(e, 10));
|
||||
|
||||
let maxAxis = 5;
|
||||
|
||||
// 处理data数据
|
||||
options.value.series = detail.projectCountList.map((item) => {
|
||||
const countData: Record<string, any>[] = item.count.map((e) => {
|
||||
return {
|
||||
name: item.name,
|
||||
value: e,
|
||||
originValue: e,
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'item',
|
||||
enterable: true,
|
||||
formatter(params: any) {
|
||||
const html = `
|
||||
<div class="w-[186px] h-[50px] p-[16px] flex items-center justify-between">
|
||||
<div class=" flex items-center">
|
||||
<div class="mb-[2px] mr-[8px] h-[8px] w-[8px] rounded-sm bg-[${params.color}]" style="background:${
|
||||
params.color
|
||||
}"></div>
|
||||
<div class="one-line-text max-w-[100px]"" style="color:#959598">${params.name}</div>
|
||||
</div>
|
||||
<div class="text-[#323233] font-medium">${addCommasToNumber(params.value)}</div>
|
||||
</div>
|
||||
`;
|
||||
return html;
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const itemMax = Math.max(...item.count);
|
||||
|
||||
maxAxis = Math.max(itemMax, maxAxis);
|
||||
|
||||
return {
|
||||
name: item.name,
|
||||
type: 'bar',
|
||||
barWidth: 12,
|
||||
legendHoverLink: true,
|
||||
large: true,
|
||||
itemStyle: {
|
||||
borderRadius: [2, 2, 0, 0], // 上边圆角
|
||||
},
|
||||
z: 10,
|
||||
data: countData,
|
||||
barMinHeight: ((optionData: Record<string, any>[]) => {
|
||||
optionData.forEach((itemValue: any, index: number) => {
|
||||
if (itemValue.value === 0) optionData[index].value = null;
|
||||
});
|
||||
let hasZero = false;
|
||||
for (let i = 0; i < optionData.length; i++) {
|
||||
if (optionData[i].value === 0) {
|
||||
hasZero = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return hasZero ? 0 : 5;
|
||||
})(countData),
|
||||
};
|
||||
});
|
||||
options.value.yAxis[0].max = maxAxis < 100 ? 100 : maxAxis + 50;
|
||||
const { maxAxis, data } = getSeriesData(detail.projectCountList);
|
||||
options.value.series = data;
|
||||
options.value.yAxis[0].max = maxAxis;
|
||||
}
|
||||
const showSkeleton = ref(false);
|
||||
const selectAll = computed(() => appStore.projectList.length === innerProjectIds.value.length);
|
||||
|
|
|
@ -16,12 +16,10 @@
|
|||
:search-keys="['name']"
|
||||
class="!w-[200px]"
|
||||
:prefix="t('workbench.homePage.project')"
|
||||
@change="changeProject"
|
||||
>
|
||||
</MsSelect>
|
||||
|
||||
<MsSelect
|
||||
:key="props.refreshKey"
|
||||
v-model:model-value="innerHandleUsers"
|
||||
:options="memberOptions"
|
||||
allow-search
|
||||
|
@ -58,14 +56,13 @@
|
|||
import CardSkeleton from './cardSkeleton.vue';
|
||||
|
||||
import { workMemberViewDetail, workProjectMemberOptions } from '@/api/modules/workbench';
|
||||
import { contentTabList } from '@/config/workbench';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import { characterLimit, sleep } from '@/utils';
|
||||
|
||||
import type { OverViewOfProject, SelectedCardItem, TimeFormParams } from '@/models/workbench/homePage';
|
||||
|
||||
import { getCommonBarOptions, handleNoDataDisplay } from '../utils';
|
||||
import { getColorScheme, getCommonBarOptions, getSeriesData, handleNoDataDisplay } from '../utils';
|
||||
|
||||
const { t } = useI18n();
|
||||
const appStore = useAppStore();
|
||||
|
@ -100,57 +97,18 @@
|
|||
|
||||
const memberOptions = ref<{ label: string; value: string }[]>([]);
|
||||
const options = ref<Record<string, any>>({});
|
||||
const color = ['#811FA3', '#FFCA59', '#00C261', '#FFA1FF', '#F9F871', '#3370FF', '#F24F4F'];
|
||||
|
||||
function handleData(detail: OverViewOfProject) {
|
||||
options.value = getCommonBarOptions(detail.xaxis.length >= 7, color);
|
||||
options.value = getCommonBarOptions(detail.xaxis.length >= 7, getColorScheme(7));
|
||||
const { invisible, text } = handleNoDataDisplay(detail.xaxis, hasPermission.value);
|
||||
options.value.graphic.invisible = invisible;
|
||||
options.value.graphic.style.text = text;
|
||||
options.value.xAxis.data = detail.xaxis.map((e) => characterLimit(e, 10));
|
||||
|
||||
let maxAxis = 5;
|
||||
const { maxAxis, data } = getSeriesData(detail.projectCountList);
|
||||
|
||||
// 处理data数据
|
||||
options.value.series = detail.projectCountList.map((item, sid) => {
|
||||
const countData: Record<string, any>[] = item.count.map((e) => {
|
||||
return {
|
||||
name: item.name,
|
||||
value: e,
|
||||
originValue: e,
|
||||
};
|
||||
});
|
||||
|
||||
const itemMax = Math.max(...item.count);
|
||||
|
||||
maxAxis = Math.max(itemMax, maxAxis);
|
||||
|
||||
return {
|
||||
name: t(contentTabList[sid].label),
|
||||
type: 'bar',
|
||||
barWidth: 12,
|
||||
legendHoverLink: true,
|
||||
large: true,
|
||||
itemStyle: {
|
||||
borderRadius: [2, 2, 0, 0],
|
||||
},
|
||||
data: countData,
|
||||
barMinHeight: ((optionData: Record<string, any>[]) => {
|
||||
optionData.forEach((itemValue: any, index: number) => {
|
||||
if (itemValue.value === 0) optionData[index].value = null;
|
||||
});
|
||||
let hasZero = false;
|
||||
for (let i = 0; i < optionData.length; i++) {
|
||||
if (optionData[i].value === 0) {
|
||||
hasZero = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return hasZero ? 0 : 5;
|
||||
})(countData),
|
||||
};
|
||||
});
|
||||
options.value.yAxis[0].max = maxAxis < 100 ? 100 : maxAxis + 50;
|
||||
options.value.series = data;
|
||||
options.value.yAxis[0].max = maxAxis;
|
||||
}
|
||||
const showSkeleton = ref(false);
|
||||
|
||||
|
@ -187,21 +145,16 @@
|
|||
label: e.name,
|
||||
value: e.id,
|
||||
}));
|
||||
innerHandleUsers.value = innerHandleUsers.value.filter((id: string) =>
|
||||
memberOptions.value.some((member) => member.value === id)
|
||||
);
|
||||
}
|
||||
const isInit = ref(true);
|
||||
|
||||
function changeProject() {
|
||||
innerHandleUsers.value = [];
|
||||
nextTick(() => {
|
||||
getMemberOptions();
|
||||
initOverViewMemberDetail();
|
||||
emit('change');
|
||||
});
|
||||
}
|
||||
|
||||
function changeMember() {
|
||||
function changeMember(value: string[]) {
|
||||
nextTick(() => {
|
||||
initOverViewMemberDetail();
|
||||
innerHandleUsers.value = value;
|
||||
emit('change');
|
||||
});
|
||||
}
|
||||
|
@ -241,19 +194,26 @@
|
|||
|
||||
onMounted(() => {
|
||||
isInit.value = false;
|
||||
initOverViewMemberDetail();
|
||||
if (props.item.projectIds.length) {
|
||||
getMemberOptions();
|
||||
}
|
||||
initOverViewMemberDetail();
|
||||
});
|
||||
|
||||
watch([() => props.refreshKey, () => projectId.value], async () => {
|
||||
watch([() => props.refreshKey, () => projectId.value], async ([_key, newProjectId]) => {
|
||||
await nextTick();
|
||||
initOverViewMemberDetail();
|
||||
await sleep(50);
|
||||
|
||||
if (newProjectId) {
|
||||
innerHandleUsers.value = [];
|
||||
emit('change');
|
||||
}
|
||||
|
||||
if (props.item.projectIds.length) {
|
||||
getMemberOptions();
|
||||
}
|
||||
await sleep(50);
|
||||
|
||||
initOverViewMemberDetail();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
import { toolTipConfig } from '@/config/testPlan';
|
||||
import { commonRatePieOptions, defaultValueMap } from '@/config/workbench';
|
||||
import { commonRatePieOptions, contentTabList, defaultValueMap } from '@/config/workbench';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { addCommasToNumber } from '@/utils';
|
||||
|
||||
import { WorkCardEnum } from '@/enums/workbenchEnum';
|
||||
|
||||
const { t } = useI18n();
|
||||
// 通用颜色配置
|
||||
// TODO 通用颜色配置注: 目前柱状图只用到了7种色阶,其他色阶暂时保留
|
||||
const commonColorConfig: Record<number, string[]> = {
|
||||
2: ['#783887', '#FFC14E'],
|
||||
4: ['#783887', '#FFC14E', '#2DFCEF', '#3370FF'],
|
||||
7: ['#811FA3', '#00C261', '#FF9964', '#50CEFB', '#EE50A3', '#3370FF', '#D34400'],
|
||||
8: ['#783887', '#FFC14E', '#2DFCEF', '#3370FF', '#811FA3', '#00D1FF', '#FFA53D', '#00C261'],
|
||||
12: [
|
||||
'#AA4FBF',
|
||||
|
@ -55,6 +56,7 @@ const commonColorConfig: Record<number, string[]> = {
|
|||
export function getColorScheme(dataLength: number): string[] {
|
||||
if (dataLength <= 2) return commonColorConfig[2];
|
||||
if (dataLength <= 4) return commonColorConfig[4];
|
||||
if (dataLength <= 7) return commonColorConfig[7];
|
||||
if (dataLength <= 8) return commonColorConfig[8];
|
||||
if (dataLength <= 12) return commonColorConfig[12];
|
||||
return commonColorConfig[13];
|
||||
|
@ -543,3 +545,75 @@ export function handleUpdateTabPie(
|
|||
options,
|
||||
};
|
||||
}
|
||||
|
||||
export function getSeriesData(
|
||||
projectCountList: {
|
||||
id: string;
|
||||
name: string;
|
||||
count: number[];
|
||||
}[]
|
||||
) {
|
||||
let maxAxis = 5;
|
||||
const seriesData = projectCountList.map((item, sid) => {
|
||||
const countData: Record<string, any>[] = item.count.map((e) => {
|
||||
return {
|
||||
name: t(contentTabList[sid].label),
|
||||
value: e,
|
||||
originValue: e,
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'item',
|
||||
enterable: true,
|
||||
formatter(params: any) {
|
||||
const html = `
|
||||
<div class="w-[186px] h-[50px] p-[16px] flex items-center justify-between">
|
||||
<div class=" flex items-center">
|
||||
<div class="mb-[2px] mr-[8px] h-[8px] w-[8px] rounded-sm bg-[${params.color}]" style="background:${
|
||||
params.color
|
||||
}"></div>
|
||||
<div class="one-line-text max-w-[100px]"" style="color:#959598">${params.name}</div>
|
||||
</div>
|
||||
<div class="text-[#323233] font-medium">${addCommasToNumber(params.value)}</div>
|
||||
</div>
|
||||
`;
|
||||
return html;
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const itemMax = Math.max(...item.count);
|
||||
|
||||
maxAxis = Math.max(itemMax, maxAxis);
|
||||
|
||||
return {
|
||||
name: t(contentTabList[sid].label),
|
||||
type: 'bar',
|
||||
barWidth: 12,
|
||||
legendHoverLink: true,
|
||||
large: true,
|
||||
itemStyle: {
|
||||
borderRadius: [2, 2, 0, 0],
|
||||
},
|
||||
data: countData,
|
||||
barMinHeight: ((optionData: Record<string, any>[]) => {
|
||||
optionData.forEach((itemValue: any, index: number) => {
|
||||
if (itemValue.value === 0) optionData[index].value = null;
|
||||
});
|
||||
let hasZero = false;
|
||||
for (let i = 0; i < optionData.length; i++) {
|
||||
if (optionData[i].value === 0) {
|
||||
hasZero = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return hasZero ? 0 : 5;
|
||||
})(countData),
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
data: seriesData,
|
||||
maxAxis: maxAxis < 100 ? 100 : maxAxis + 50,
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue