diff --git a/src/utils/i18n/en.ts b/src/utils/i18n/en.ts index 4ecfecd..3f41deb 100644 --- a/src/utils/i18n/en.ts +++ b/src/utils/i18n/en.ts @@ -224,6 +224,8 @@ const lang = { 统计分析: { 任务完成统计工位: 'Task Completion Statistics (Workspace)', 任务完成统计学科: 'Task Completion Statistics (Discipline)', + 任务达成统计工位: 'Task Quality Statistics (Workspace)', + 任务达成统计学科: 'Task Quality Statistics (Discipline)', 指标完成统计工位: 'Performance Completion Statistics (Workspace)', 指标完成统计学科: 'Performance Completion Statistics (Discipline)', 成员任务进度统计: 'Member Task Progress Statistics', diff --git a/src/utils/i18n/zh.ts b/src/utils/i18n/zh.ts index 0844f35..133a693 100644 --- a/src/utils/i18n/zh.ts +++ b/src/utils/i18n/zh.ts @@ -221,6 +221,8 @@ const lang = { 统计分析: { 任务完成统计工位: '任务完成统计(工位)', 任务完成统计学科: '任务完成统计(学科)', + 任务达成统计工位: '任务达成统计(工位)', + 任务达成统计学科: '任务达成统计(学科)', 指标完成统计工位: '指标完成统计(工位)', 指标完成统计学科: '指标完成统计(学科)', 成员任务进度统计: '成员任务进度统计', diff --git a/src/views/competenceCenter/condition/components/taskPool.vue b/src/views/competenceCenter/condition/components/taskPool.vue index b3e8da8..47c2073 100644 --- a/src/views/competenceCenter/condition/components/taskPool.vue +++ b/src/views/competenceCenter/condition/components/taskPool.vue @@ -746,26 +746,38 @@ const onVersionChangeFun = () => { }); }; const extractTableData: any = ref([]); -const queryTaskPoolFun = async () => { - if (!currentPoolBriefVersion.value) { +const queryTaskPoolFun = async (poolBriefVersion?: any) => { + const version = poolBriefVersion || currentPoolBriefVersion.value; + if (!version) { return; } const req = { - poolName: currentPoolBriefVersion.value.poolName, - version: currentPoolBriefVersion.value.poolVersion, + poolName: version.poolName, + version: version.poolVersion, }; + console.log('[工况库] 开始加载数据...'); loading.value = true; + const startTime = performance.now(); const res: any = await getTaskPoolApi(req); + const apiTime = performance.now(); + console.log(`[工况库] getTaskPool 请求耗时: ${(apiTime - startTime).toFixed(2)}ms`); loading.value = false; - let tree = []; + let tree: any = []; if (res.code === 200 && res.data.poolBrief && res.data && res.data.nodes) { + const transformStart = performance.now(); tree = transformPoolNodesToTree(res.data.nodes); + console.log(`[工况库] 数据转换耗时: ${(performance.now() - transformStart).toFixed(2)}ms`); tableData.value = tree; - originalSnapshot = cloneDeep(tree); isEmptyPool.value = false; if (currentTableType.value === TableViewType.LIST) { mergeListTableColumnsFun(res.data.nodes); } + nextTick(() => { + console.log(`[工况库] 总渲染耗时: ${(performance.now() - startTime).toFixed(2)}ms`); + setTimeout(() => { + originalSnapshot = cloneDeep(tree); + }, 0); + }); expandAllFun(); } else { tableData.value = []; @@ -858,9 +870,9 @@ const queryTaskPoolPerformanceFun = async () => { performanceData.value = transformPoolNodesToTree(res.data); } }; -const refreshTreeFun = async () => { +const refreshTreeFun = async (poolBriefVersion?: any) => { if (props.pageType === 'loadcase') { - await queryTaskPoolFun(); + await queryTaskPoolFun(poolBriefVersion); } if (props.pageType === 'performance') { await queryTaskPoolPerformanceFun(); @@ -877,17 +889,17 @@ const queryVersionsFun = async () => { poolName: currentPoolBrief.value.poolName, }; const res: any = await getTaskPoolVersionsApi(req); + let targetVersion = null; if (res.code === 200 && res.data && Array.isArray(res.data) && res.data.length > 0) { versionList.value = res.data; - if (versionList.value.length > 0) { - currentPoolBriefVersion.value = versionList.value[0]; - } + targetVersion = res.data[0]; + currentPoolBriefVersion.value = targetVersion; } else { versionList.value = []; currentPoolBriefVersion.value = null; tableData.value = []; } - await refreshTreeFun(); + await refreshTreeFun(targetVersion); }; const addPoolModalVisible = ref(false); const addPoolFun = () => { diff --git a/src/views/data/statistics/index.vue b/src/views/data/statistics/index.vue index 27e6dd3..fbfc560 100644 --- a/src/views/data/statistics/index.vue +++ b/src/views/data/statistics/index.vue @@ -314,11 +314,37 @@ import { } from '@/api/project/node'; import ProjectSelect from '@/components/common/projectSelect/index.vue'; import { TASK_CALCULATE_STATUS_OBJ, TASK_PROCESS_STATUS_OBJ } from '@/utils/enum/task'; +import { getThemeColor } from '@/utils/theme'; const userGroupOptions = ref([]); const disciplineOptions = ref([]); +const statusColorList = [ + getThemeColor('--el-color-info-light-5'), + getThemeColor('--el-color-primary'), + getThemeColor('--el-color-danger'), + getThemeColor('--el-color-success'), + getThemeColor('--el-color-warning'), +]; +const performanceColorList = [ + getThemeColor('--el-color-info-light-5'), + getThemeColor('--el-color-success'), +]; +const difficultyCountColorList = [ + getThemeColor('--el-color-success'), + getThemeColor('--el-color-success-light-5'), + getThemeColor('--el-color-warning-light-5'), + getThemeColor('--el-color-warning'), + getThemeColor('--el-color-danger-light-5'), + getThemeColor('--el-color-danger'), +]; +// 封装方法,根据对象的某个属性对对象数组进行排序 +const sortObjectArray = (arr: any, key: any) => { + return arr.sort((a: any, b: any) => { + return a[key] - b[key]; + }); +}; // const projectStorageSpaceStatisticsFormData = ref({ // userId: '', @@ -400,8 +426,12 @@ const initUserProjectStatistics = async () => { series: [ { type: 'bar', + name: '项目数量', barWidth: '30%', data: yData, + itemStyle: { + color: getThemeColor('--el-color-primary'), + }, }, ], }; @@ -463,10 +493,10 @@ const getUserGroupTaskCompleteStatistics = async () => { }; const initUserTaskComplete = async () => { const { xData, seriesData, legendData } = await getUserGroupTaskCompleteStatistics(); - // 模拟接口延时 userTaskCompleteChartRef.value.commonChartRef.disposeEchartsByKey('chart-2'); userTaskCompleteChartRef.value.commonChartRef.option = { + color: statusColorList, title: { show: false, }, @@ -575,6 +605,7 @@ const initUserDifficultyCoefficientStatistics = async () => { // 模拟接口延时 userDifficultyCoefficientChartRef.value.commonChartRef.disposeEchartsByKey('chart-3'); userDifficultyCoefficientChartRef.value.commonChartRef.option = { + color: difficultyCountColorList, title: { textStyle: { fontSize: 20, @@ -630,7 +661,7 @@ const initUserDifficultyCoefficientStatistics = async () => { }, ] : null, - series: seriesData, + series: sortObjectArray(seriesData, 'name'), }; userDifficultyCoefficientChartRef.value.commonChartRef.initChart(); }; @@ -696,6 +727,7 @@ const initTaskCompletionAtWorkstations = async () => { taskCompletionAtWorkstationsChartRef.value.commonChartRef.disposeEchartsByKey('chart-4'); taskCompletionAtWorkstationsChartRef.value.commonChartRef.option = { + color: statusColorList, title: { show: false, }, @@ -807,6 +839,7 @@ const initTaskCompletionAtDiscipline = async () => { taskCompletionAtDisciplineChartRef.value.commonChartRef.disposeEchartsByKey('chart-5'); taskCompletionAtDisciplineChartRef.value.commonChartRef.option = { + color: statusColorList, title: { show: false, }, @@ -915,7 +948,8 @@ const initPerformanceCompletionAtWorkstations = async () => { } performanceCompletionAtWorkstationsChartRef.value.commonChartRef.disposeEchartsByKey('chart-6'); performanceCompletionAtWorkstationsChartRef.value.commonChartRef.option = { - color: ['#37a93d', '#de4231', '#808080'], + // color: ['#37a93d', '#de4231', '#808080'], + color: performanceColorList, title: { show: false, }, @@ -1029,7 +1063,8 @@ const initPerformanceCompletionAtDiscipline = async () => { performanceCompletionAtDisciplineChartRef.value.commonChartRef.disposeEchartsByKey('chart-7'); performanceCompletionAtDisciplineChartRef.value.commonChartRef.option = { - color: ['#37a93d', '#de4231', '#808080'], + // color: ['#37a93d', '#de4231', '#808080'], + color: performanceColorList, title: { show: false, }, @@ -1135,8 +1170,6 @@ const initReviewPassed = async () => { } } - console.log(seriesData, 'seriesData'); - reviewPassedChartRef.value.commonChartRef.disposeEchartsByKey('chart-8'); reviewPassedChartRef.value.commonChartRef.option = { color: ['#808080', '#b6d634', '#37a93d', '#de4231'], diff --git a/src/views/system/logs/index.vue b/src/views/system/logs/index.vue index ae2bc93..0e52bef 100644 --- a/src/views/system/logs/index.vue +++ b/src/views/system/logs/index.vue @@ -2,7 +2,7 @@
- +
diff --git a/src/views/task/projectDetail/components/statisticAnalysis.vue b/src/views/task/projectDetail/components/statisticAnalysis.vue index da80f80..5865fff 100644 --- a/src/views/task/projectDetail/components/statisticAnalysis.vue +++ b/src/views/task/projectDetail/components/statisticAnalysis.vue @@ -43,6 +43,27 @@ -->
+ +
+ + +
+
+ + +
import { ref, onMounted, reactive, watchEffect } from 'vue'; import EchartCard from '@/components/common/echartCard/index.vue'; -import UserSelect from '@/components/common/userSelect/index.vue'; +// import UserSelect from '@/components/common/userSelect/index.vue'; import { userQueryGroupApi } from '@/api/system/user'; import { getUserGroupProjectStatisticsApi, - getUserGroupTaskCompleteStatisticsApi, + // getUserGroupTaskCompleteStatisticsApi, queryNodeListApi, - getWorkstationReviewStatisticsApi, - getUserGroupDifficultyStatisticsApi, - getCommonCompleteStatisticsApi, + // getWorkstationReviewStatisticsApi, + // getUserGroupDifficultyStatisticsApi, + // getCommonCompleteStatisticsApi, } from '@/api/project/node'; import { getTaskCompleteStatisticsApi, @@ -226,6 +247,7 @@ import { // import ProjectSelect from '@/components/common/projectSelect/index.vue'; import { useDict } from '@/utils/useDict'; import { TASK_CALCULATE_STATUS_OPTIONS } from '@/utils/enum/task'; +import { getThemeColor } from '@/utils/theme'; const { TASK_EXE_STATUS } = useDict('TASK_EXE_STATUS'); const taskCalculateStatusLegendData = TASK_CALCULATE_STATUS_OPTIONS.map((item) => ({ @@ -262,6 +284,37 @@ const disciplineOptions = ref([]); // }); const userProjectChartRef = ref(); +// 进度状态颜色列表:已驳回、未开始、进行中、已完成、已暂停、已关闭、已延期 +const statusColorList = [ + getThemeColor('--el-color-danger'), + getThemeColor('--el-color-info-light-5'), + getThemeColor('--el-color-primary'), + getThemeColor('--el-color-success'), + getThemeColor('--el-color-warning'), + getThemeColor('--el-color-info-light-7'), + getThemeColor('--el-color-danger-light-5'), +]; +// 完成情况颜色列表:未分析、不合格、合格 +const completionStatusColorList = [ + getThemeColor('--el-color-info'), + getThemeColor('--el-color-danger'), + getThemeColor('--el-color-success'), +]; +const difficultyCountColorList = [ + getThemeColor('--el-color-success'), + getThemeColor('--el-color-success-light-5'), + getThemeColor('--el-color-warning-light-5'), + getThemeColor('--el-color-warning'), + getThemeColor('--el-color-danger-light-5'), + getThemeColor('--el-color-danger'), +]; +// 封装方法,根据对象的某个属性对对象数组进行排序 +const sortObjectArray = (arr: any, key: any) => { + return arr.sort((a: any, b: any) => { + return a[key] - b[key]; + }); +}; + const getUserGroupProjectStatistics = async () => { const xData: any = []; const yData: any = []; @@ -349,9 +402,9 @@ const userTaskCompleteFormData = ref({ tag1: '', tag2: '', }); -const userTaskCompleteProjectChangeFun = async () => { - await queryUserTaskCompletion(); -}; +// const userTaskCompleteProjectChangeFun = async () => { +// await queryUserTaskCompletion(); +// }; const getUserTaskCompleteStatistics = async () => { const xData: any = []; const seriesData: any = []; @@ -395,6 +448,7 @@ const queryUserTaskCompletion = async () => { const { xData, seriesData } = await getUserTaskCompleteStatistics(); userTaskCompleteChartRef.value.commonChartRef.disposeEchartsByKey('chart-2'); userTaskCompleteChartRef.value.commonChartRef.option = { + color: statusColorList, title: { show: false, }, @@ -499,6 +553,7 @@ const queryUserDifficultStatistics = async () => { userDifficultyCoefficientChartRef.value.commonChartRef.disposeEchartsByKey('chart-3'); userDifficultyCoefficientChartRef.value.commonChartRef.option = { + color: difficultyCountColorList, title: { textStyle: { fontSize: 20, @@ -554,15 +609,16 @@ const queryUserDifficultStatistics = async () => { }, ] : null, - series: seriesData, + // series: seriesData, + series: sortObjectArray(seriesData, 'name'), }; userDifficultyCoefficientChartRef.value.commonChartRef.initChart(); }; const taskCompletionAtWorkstationsChartRef = ref(); -const taskCompletionAtWorkstationsFormData = reactive({ - tag1: '', -}); +// const taskCompletionAtWorkstationsFormData = reactive({ +// tag1: '', +// }); const queryTaskCompletionByWorkspace = async () => { let xData: any = []; const seriesData: any = []; @@ -604,6 +660,7 @@ const queryTaskCompletionByWorkspace = async () => { } taskCompletionAtWorkstationsChartRef.value.commonChartRef.disposeEchartsByKey('chart-4'); taskCompletionAtWorkstationsChartRef.value.commonChartRef.option = { + color: statusColorList, title: { show: false, }, @@ -654,9 +711,9 @@ const queryTaskCompletionByWorkspace = async () => { taskCompletionAtWorkstationsChartRef.value.commonChartRef.initChart(); }; -const initTaskCompletionAtDisciplineFormData = reactive({ - tag1: '', -}); +// const initTaskCompletionAtDisciplineFormData = reactive({ +// tag1: '', +// }); const taskCompletionAtDisciplineChartRef = ref(); const queryTaskCompletionByDiscipline = async () => { @@ -702,6 +759,7 @@ const queryTaskCompletionByDiscipline = async () => { taskCompletionAtDisciplineChartRef.value.commonChartRef.disposeEchartsByKey('chart-5'); taskCompletionAtDisciplineChartRef.value.commonChartRef.option = { + color: statusColorList, title: { show: false, }, @@ -752,11 +810,109 @@ const queryTaskCompletionByDiscipline = async () => { taskCompletionAtDisciplineChartRef.value.commonChartRef.initChart(); }; +// 新增 任务达成统计 —— 工位 +const taskQualityAtWorkstationsChartRef = ref(); +const queryTaskQualityByWorkspace = async () => { + let xData: any = []; + const seriesData: any = []; + // todo 接口待确认 + const res: any = await getPerformanceCompleteStatisticsApi({ + resultTagType: 'tag5', + tag1: currentProjectUuid.value, + tag2: '', + tag3: '', + tag4: '', + tag5: '', + tag6: '', + tag7: '', + tag8: '', + tag9: '', + tag10: '', + }); + + if (res && res.code === 200) { + xData = res.data.result.map((item: any) => { + return item.name; + }); + + for (let i = 0; i < TASK_CALCULATE_STATUS_OPTIONS.length; i++) { + const item = TASK_CALCULATE_STATUS_OPTIONS[i]; + const obj: any = { + name: item.label, + type: 'bar', + emphasis: { + focus: 'series', + }, + data: [], + }; + + for (let j = 0; j < res.data.result.length; j++) { + obj.data.push(res.data.result[j]?.statusCount[item.value] || 0); + } + + seriesData.push(obj); + } + } + taskQualityAtWorkstationsChartRef.value.commonChartRef.disposeEchartsByKey('chart-Quality-1'); + taskQualityAtWorkstationsChartRef.value.commonChartRef.option = { + // color: ['#808080', '#de4231', '#37a93d'], + color: completionStatusColorList, + title: { + show: false, + }, + tooltip: { + trigger: 'axis', + }, + legend: { + show: true, + top: '0%', + left: 'center', + data: taskCalculateStatusLegendData, + }, + grid: { + top: '10%', + bottom: '10%', + left: '5%', + right: '5%', + }, + xAxis: { + type: 'category', + data: xData, + }, + yAxis: { + type: 'value', + }, + dataZoom: + xData.length > 4 + ? [ + { + type: 'slider', + show: true, + xAxisIndex: [0], + start: 0, + end: 100, + textStyle: { + color: 'transparent', + }, + maxValueSpan: 4, + minValueSpan: 4, + moveHandleSize: 10, + height: 0, + filterMode: 'empty', + bottom: 15, + }, + ] + : null, + series: seriesData, + }; + taskQualityAtWorkstationsChartRef.value.commonChartRef.initChart(); +}; + const performanceCompletionAtWorkstationsChartRef = ref(); -const queryPerfCompletionByWorkspaceFormData = reactive({ - tag1: '', -}); +// const queryPerfCompletionByWorkspaceFormData = reactive({ +// tag1: '', +// }); const queryPerfCompletionByWorkspace = async () => { let xData: any = []; @@ -800,7 +956,8 @@ const queryPerfCompletionByWorkspace = async () => { } performanceCompletionAtWorkstationsChartRef.value.commonChartRef.disposeEchartsByKey('chart-6'); performanceCompletionAtWorkstationsChartRef.value.commonChartRef.option = { - color: ['#808080', '#de4231', '#37a93d'], + // color: ['#808080', '#de4231', '#37a93d'], + color: completionStatusColorList, title: { show: false, }, @@ -852,10 +1009,110 @@ const queryPerfCompletionByWorkspace = async () => { performanceCompletionAtWorkstationsChartRef.value.commonChartRef.initChart(); }; +// 新增 任务达成统计 —— 学科 +const taskQualityAtDisciplineChartRef = ref(); +const queryTaskQualityByDiscipline = async () => { + let xData: any = []; + const seriesData: any = []; + // todo 接口待确认 + const res: any = await getPerformanceCompleteStatisticsApi({ + resultTagType: 'tag6', + tag1: currentProjectUuid.value, + tag2: '', + tag3: '', + tag4: '', + tag5: '', + tag6: '', + tag7: '', + tag8: '', + tag9: '', + tag10: '', + }); + + if (res && res.code === 200) { + xData = res.data.result.map((item: any) => { + return item.name; + }); + + for (let i = 0; i < TASK_CALCULATE_STATUS_OPTIONS.length; i++) { + const item = TASK_CALCULATE_STATUS_OPTIONS[i]; + const obj: any = { + name: item.label, + type: 'bar', + emphasis: { + focus: 'series', + }, + data: [], + }; + + for (let j = 0; j < res.data.result.length; j++) { + obj.data.push(res.data.result[j]?.statusCount[item.value] || 0); + } + + seriesData.push(obj); + } + } + + taskQualityAtDisciplineChartRef.value.commonChartRef.disposeEchartsByKey('chart-Quality-2'); + taskQualityAtDisciplineChartRef.value.commonChartRef.option = { + // color: ['#808080', '#de4231', '#37a93d'], + color: completionStatusColorList, + title: { + show: false, + }, + tooltip: { + trigger: 'axis', + }, + legend: { + show: true, + top: '0%', + left: 'center', + data: taskCalculateStatusLegendData, + }, + grid: { + top: '10%', + bottom: '10%', + left: '5%', + right: '5%', + }, + xAxis: { + type: 'category', + data: xData, + }, + yAxis: { + type: 'value', + }, + dataZoom: + xData.length > 4 + ? [ + { + type: 'slider', + show: true, + xAxisIndex: [0], + start: 0, + end: 100, + textStyle: { + color: 'transparent', + }, + maxValueSpan: 4, + minValueSpan: 4, + moveHandleSize: 10, + height: 0, + filterMode: 'empty', + bottom: 15, + }, + ] + : null, + series: seriesData, + }; + taskQualityAtDisciplineChartRef.value.commonChartRef.initChart(); +}; + const performanceCompletionAtDisciplineChartRef = ref(); -const queryPerfCompletionByDisciplineFormData = reactive({ - tag1: '', -}); + +// const queryPerfCompletionByDisciplineFormData = reactive({ +// tag1: '', +// }); const queryPerfCompletionByDiscipline = async () => { let xData: any = []; @@ -900,7 +1157,8 @@ const queryPerfCompletionByDiscipline = async () => { performanceCompletionAtDisciplineChartRef.value.commonChartRef.disposeEchartsByKey('chart-7'); performanceCompletionAtDisciplineChartRef.value.commonChartRef.option = { - color: ['#808080', '#de4231', '#37a93d'], + // color: ['#808080', '#de4231', '#37a93d'], + color: completionStatusColorList, title: { show: false, }, @@ -1007,6 +1265,12 @@ const initData = async () => { await queryUserTaskCompletion(); // 难度系数统计:难度系数有1、2、3、4、5,统计1有几个,2有几个。。。 await queryUserDifficultStatistics(); + + // 新增 todo 暂时没接口 + // 按照工位统计任务质量达成情况 + // await queryTaskQualityByWorkspace(); + // // 按照学科统计任务质量达成情况 + // await queryTaskQualityByDiscipline(); }; watchEffect(() => { if (props.projectUuid) {