update 增加难度系数占比图表

This commit is contained in:
2026-04-08 17:29:41 +08:00
parent 516729d4e2
commit 5b17750e02
8 changed files with 231 additions and 26 deletions

View File

@@ -42,7 +42,7 @@ interface ChartConfig {
id: string;
title: string;
component: any;
props: Record<string, any>;
props?: Record<string, any>;
}
interface Props {
@@ -104,12 +104,17 @@ const updateConfigFun = async (info: any) => {
const setConfig = (dataStatisticsSetting: any) => {
if (dataStatisticsSetting) {
const configInfo = JSON.parse(dataStatisticsSetting);
// 找到baseList中存在但configInfo中不存在的项新增项
const newItems = props.baseList.filter(
(baseItem) => !configInfo.some((config: any) => config.key === baseItem.id)
);
// 根据配置的结果对展示的图表进行排序
const list = configInfo
.filter((config: any) => config.inBoard)
.map((config: any) => props.baseList.find((item) => item.id === config.key))
.filter(Boolean);
currentList.value = list as ChartConfig[];
// 将新增项添加到列表最后
currentList.value = [...list, ...newItems] as ChartConfig[];
} else {
currentList.value = props.baseList;
}

View File

@@ -100,11 +100,27 @@ watch(
);
const updateTable = () => {
if (props.configJson) {
tableData.value = JSON.parse(props.configJson);
// 解析配置JSON
const configData = JSON.parse(props.configJson);
// 找到baseList中存在但configJson中不存在的项新增项
const newItems = props.baseList
.filter((baseItem) => !configData.some((config: any) => config.key === baseItem.id))
.map((item) => ({
key: item.id,
title: item.title,
inBoard: true,
}));
// 过滤掉baseList中不存在但configJson中存在的项已删除的表
const validConfigData = configData.filter((config: any) =>
props.baseList.some((baseItem) => baseItem.id === config.key)
);
// 将新增项添加到配置列表的最后面
tableData.value = [...validConfigData, ...newItems];
} else {
tableData.value = getBaseTable();
}
};
const updateFun = () => {
emit('update:modelValue', false);
emit('updateConfig', JSON.stringify(tableData.value));

View File

@@ -351,6 +351,7 @@ const lang = {
: 'Workspace Review Statistics',
: 'Project Task Completion Statistics',
: 'File Operate Statistics',
: 'Difficulty Coefficient Ratio',
},
: {
: 'Phase',

View File

@@ -346,6 +346,7 @@ const lang = {
: '工位评审通过统计',
: '项目任务完成情况统计',
: '文件操作统计',
: '难度系数占比',
},
: {
: '阶段',

View File

@@ -6,6 +6,9 @@
<script setup lang="ts">
import { getThemeColor } from '@/utils/theme';
import { useDict } from '@/utils/useDict';
import { useProjectList } from '@/utils/useProjectList';
import { getTaskStatusColorList, getAchieveColorList } from '@/utils/enum/task';
// 引入子组件
import fileOperateChart from './dataStatistics/fileOperateChart.vue';
import userGroupProjectChart from './dataStatistics/userGroupProjectChart.vue';
@@ -16,9 +19,7 @@ import performanceCompletion from './dataStatistics/performanceCompletion.vue';
import projectTaskComplete from './dataStatistics/projectTaskComplete.vue';
import reviewPassed from './dataStatistics/reviewPassed.vue';
import dashboardSetting from '@/components/common/dashboardSetting/index.vue';
import { useDict } from '@/utils/useDict';
import { useProjectList } from '@/utils/useProjectList';
import { getTaskStatusColorList, getAchieveColorList } from '@/utils/enum/task';
import userDifficultyRateChart from './dataStatistics/userDifficultyRateChart.vue';
// 统一请求项目列表
useProjectList();
@@ -30,15 +31,6 @@ const { TASK_ACHIEVE_STATUS, RESULT_ACHIEVE_STATUS } = useDict(
const statusColorList = getTaskStatusColorList(Object.keys(TASK_ACHIEVE_STATUS.value.O));
const performanceColorList = getAchieveColorList(Object.keys(RESULT_ACHIEVE_STATUS.value.O));
// 难度系数颜色列表
const difficultyCountColorList = [
'#67c23a',
'rgb(179, 225, 157)',
'rgb(248, 227, 197)',
'rgb(243, 209, 158)',
'rgb(248, 152, 152)',
'#f56c6c',
];
// 流程状态颜色列表
const processNodeColorList = [
'rgb(200, 201, 204)', // 未评审
@@ -59,9 +51,11 @@ const baseList = [
id: 'userDifficultyCoefficient',
title: '用户组难度系数统计',
component: userDifficultyCoefficientChart, // 用户组难度系数统计
props: {
difficultyCountColorList,
},
},
{
id: 'userDifficultyRate',
title: '难度系数占比',
component: userDifficultyRateChart, // 难度系数占比
},
{
id: 'userTaskComplete',

View File

@@ -25,18 +25,22 @@ import commonFilterChart from '@/components/common/echartCard/commonFilterChart.
import { getUserGroupDifficultyStatisticsApi } from '@/api/project/node';
import { useDict } from '@/utils/useDict';
const props = defineProps({
difficultyCountColorList: {
type: Array,
default: () => [],
},
});
// 数组对象排序
const sortObjectArray = (arr: any, key: any) => {
return arr.sort((a: any, b: any) => {
return a[key] - b[key];
});
};
const getDifficultyLevelColor = (difficulty: number) => {
// 1 低难度 2 中难度 3 高难度
if (Number(difficulty) <= 1) {
return '#67c23a'; // 绿色
} else if (Number(difficulty) == 2) {
return 'rgb(248, 227, 197)';
} else {
return '#f56c6c'; // 红色
}
};
// 难度系数字典
const { DIFFICULTY_COEFFICIENT } = useDict('DIFFICULTY_COEFFICIENT');
const getDifficultyLevel = (difficulty: number) => {
@@ -49,6 +53,7 @@ const chartOption = ref();
const initUserDifficultyCoefficientChart = async (formData: any) => {
let xData: any = [];
let titles: any = [];
let colors: any = [];
const seriesList: any = [];
const params = {
...formData,
@@ -62,6 +67,9 @@ const initUserDifficultyCoefficientChart = async (formData: any) => {
return item.userName;
}) || [];
titles = res.data?.alldifficultyValue || [];
colors = titles
.sort((a: any, b: any) => Number(a) - Number(b))
.map((key: any) => getDifficultyLevelColor(Number(key)));
for (let i = 0; i < titles.length; i++) {
const str = titles[i].toFixed(1);
const obj: any = {
@@ -79,7 +87,7 @@ const initUserDifficultyCoefficientChart = async (formData: any) => {
seriesList.push(obj);
}
const option = {
color: props.difficultyCountColorList,
color: colors,
legend: {
data: titles,
},

View File

@@ -0,0 +1,166 @@
<template>
<commonFilterChart
:title="$t('数据统计.难度系数占比')"
:charts-id="'chart-difficulty-rate'"
:bar-type="'pieChart'"
:option="chartOption"
:filterItems="[
'userGroup',
'user',
'projectName',
'projectCode',
'discipline',
'createTime',
'finishTime',
]"
:multipleItems="['user']"
:nodata="nodata"
@update="updateStatistics"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import commonFilterChart from '@/components/common/echartCard/commonFilterChart.vue';
import { getUserGroupDifficultyStatisticsApi } from '@/api/project/node';
import { useDict } from '@/utils/useDict';
// 难度系数字典
const { DIFFICULTY_COEFFICIENT } = useDict('DIFFICULTY_COEFFICIENT');
const getDifficultyLevel = (difficulty: number) => {
const str = DIFFICULTY_COEFFICIENT.value.O[Number(difficulty)];
return str ? str : '难度系数';
};
const getDifficultyLevelColor = (difficulty: number) => {
// 1 低难度 2 中难度 3 高难度
if (Number(difficulty) <= 1) {
return '#67c23a'; // 绿色
} else if (Number(difficulty) == 2) {
return 'rgb(248, 227, 197)';
} else {
return '#f56c6c'; // 红色
}
};
// 初始化用户组项目统计
const chartOption = ref();
const nodata = ref(false);
const updateStatistics = async (formData: any) => {
const params = {
...formData,
userIds: formData.userId ? formData.userId.split(',') : [],
};
delete params.userId;
const res: any = await getUserGroupDifficultyStatisticsApi(params);
if (res && res.code === 200) {
const difficultyCount: Record<any, number> = {};
res.data.result.forEach((item: any) => {
// 遍历item.difficultyCount这个对象将key和value分别存入difficultyCount对象中如果key已经存在则将value累加
Object.keys(item.difficultyCount).forEach((key: any) => {
if (difficultyCount[key]) {
difficultyCount[key] += item.difficultyCount[key];
} else {
difficultyCount[key] = item.difficultyCount[key];
}
});
});
const seriesData = Object.keys(difficultyCount).map((key: any) => {
return {
key: Number(key),
name: getDifficultyLevel(key) + key,
value: difficultyCount[key],
};
});
const colorList = Object.keys(difficultyCount)
.sort((a, b) => Number(a) - Number(b))
.map((key: any) => getDifficultyLevelColor(Number(key)));
chartOption.value = getPieOptions(colorList, sortObjectArray(seriesData, 'key'));
}
};
// 数组对象排序
const sortObjectArray = (arr: any, key: any) => {
return arr.sort((a: any, b: any) => {
return a[key] - b[key];
});
};
// 饼图配置 statusColorList 颜色列表 seriesData 数据 [{ name: '分类1', value: 10 },{ name: '分类2', value: 20 }]
const getPieOptions = (statusColorList: any, seriesData: any) => {
const option = {
color: statusColorList,
legend: {
show: true,
icon: 'circle',
itemWidth: 12,
itemHeight: 12,
borderWidth: 0,
top: '0',
formatter: (name: any) => {
const str = seriesData.filter((item: any) => item.name === name)[0];
return `{name|${name}} {value|${str.value}}`;
},
textStyle: {
// color: 'inherit',
rich: {
name: {
fontSize: 14,
align: 'left',
},
value: {
fontSize: 14,
fontWeight: '700',
align: 'right',
},
},
},
// orient: 'vertical', // 方向
itemGap: 14,
},
series: [
{
name: '',
type: 'pie',
radius: ['30%', '55%'],
center: ['50%', '55%'],
emphasis: {
disabled: true, // 禁用emphasis效果
},
itemStyle: {
borderRadius: 0,
borderWidth: 0,
},
label: {
formatter: (params: { name: any; percent: any }) => {
return '{icon|●}{name|' + params.name + '} {value|' + params.percent + '%' + '}';
},
alignTo: 'labelLine',
rich: {
icon: {
fontSize: 20,
color: 'inherit',
},
name: {
fontSize: 14,
padding: [0, 6, 0, 4],
color: 'inherit',
},
value: {
fontSize: 12,
fontWeight: 'bolder',
color: 'inherit',
},
},
},
labelLine: {
lineStyle: {
cap: 'round',
},
},
data: seriesData,
},
],
};
return option;
};
</script>

View File

@@ -211,11 +211,22 @@ const getDifficultyLevel = (difficulty: number) => {
const str = DIFFICULTY_COEFFICIENT.value.O[difficulty];
return str ? str : '难度系数';
};
const getDifficultyLevelColor = (difficulty: number) => {
// 1 低难度 2 中难度 3 高难度
if (Number(difficulty) <= 1) {
return '#67c23a'; // 绿色
} else if (Number(difficulty) == 2) {
return 'rgb(248, 227, 197)';
} else {
return '#f56c6c'; // 红色
}
};
const userDifficultyCoefficientOption = ref();
const queryUserDifficultStatistics = async () => {
let xData: any = [];
let titles: any = [];
let seriesData: any = [];
let colors: any = [];
const res: any = await getUserDifficultyStatisticsApi({
tag1: currentProjectUuid.value,
});
@@ -224,6 +235,9 @@ const queryUserDifficultStatistics = async () => {
return item.userName;
});
titles = res.data.alldifficultyValue;
colors = titles
.sort((a: any, b: any) => Number(a) - Number(b))
.map((key: any) => getDifficultyLevelColor(Number(key)));
seriesData = titles.map((title: any) => {
const str = title.toFixed(1);
return {
@@ -238,7 +252,7 @@ const queryUserDifficultStatistics = async () => {
});
}
const option = {
color: difficultyCountColorList,
color: colors,
legend: { data: titles },
grid: { bottom: xData.length > 5 ? '50' : '10' },
xAxis: { data: xData },