数据分析页面-多维度分析增加任务明细类型分析(一级、二级、三级分类)
This commit is contained in:
parent
3fcc41855a
commit
647e9a777d
@ -1975,6 +1975,12 @@ public class AnalyticsService {
|
||||
result.setDemandDeptAnalysis(buildDemandDeptAnalysis(tasks));
|
||||
result.setPlatformAnalysis(buildPlatformAnalysis(tasks));
|
||||
|
||||
// 构建任务类型分析(一级、二级、三级)
|
||||
Map<Integer, List<DimensionAnalysisVO.TaskTypeAnalysis>> taskTypeAnalysisMap = buildTaskTypeAnalysis(tasks);
|
||||
result.setTaskTypeAnalysis(taskTypeAnalysisMap.getOrDefault(1, new ArrayList<>()));
|
||||
result.setTaskTypeLevel2Analysis(taskTypeAnalysisMap.getOrDefault(2, new ArrayList<>()));
|
||||
result.setTaskTypeLevel3Analysis(taskTypeAnalysisMap.getOrDefault(3, new ArrayList<>()));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -2857,5 +2863,258 @@ public class AnalyticsService {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建任务类型分析数据(一级、二级、三级分类)
|
||||
* @param tasks 任务列表
|
||||
* @return 按层级分组的任务类型分析数据,key为层级(1/2/3)
|
||||
*/
|
||||
private Map<Integer, List<DimensionAnalysisVO.TaskTypeAnalysis>> buildTaskTypeAnalysis(List<Task> tasks) {
|
||||
log.info("开始构建任务类型分析数据,任务数量: {}", tasks.size());
|
||||
|
||||
// 获取所有任务类型
|
||||
List<DemandType> allTypes = demandTypeMapper.selectList(
|
||||
new LambdaQueryWrapper<DemandType>()
|
||||
.eq(DemandType::getDeleted, 0)
|
||||
);
|
||||
|
||||
// 构建类型ID到类型的映射
|
||||
Map<Long, DemandType> typeMap = allTypes.stream()
|
||||
.collect(Collectors.toMap(DemandType::getId, t -> t, (a, b) -> a));
|
||||
|
||||
// 构建父类型名称映射
|
||||
Map<Long, String> typeNameMap = allTypes.stream()
|
||||
.collect(Collectors.toMap(DemandType::getId, t -> t.getName() != null ? t.getName() : "未知", (a, b) -> a));
|
||||
|
||||
// 收集所有任务中涉及的任务类型ID
|
||||
Set<Long> allTaskTypeIds = new HashSet<>();
|
||||
for (Task task : tasks) {
|
||||
// 单个任务类型ID
|
||||
if (task.getTaskTypeId() != null) {
|
||||
allTaskTypeIds.add(task.getTaskTypeId());
|
||||
}
|
||||
// 多个任务类型ID(逗号分隔)
|
||||
if (task.getTaskTypeIds() != null && !task.getTaskTypeIds().trim().isEmpty()) {
|
||||
String[] ids = task.getTaskTypeIds().split(",");
|
||||
for (String id : ids) {
|
||||
try {
|
||||
allTaskTypeIds.add(Long.parseLong(id.trim()));
|
||||
} catch (NumberFormatException e) {
|
||||
// 忽略无效ID
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.info("涉及的任务类型ID数量: {}", allTaskTypeIds.size());
|
||||
|
||||
// 按任务类型ID分组统计任务
|
||||
Map<Long, List<Task>> tasksByTypeId = new HashMap<>();
|
||||
for (Task task : tasks) {
|
||||
Set<Long> typeIds = new HashSet<>();
|
||||
if (task.getTaskTypeId() != null) {
|
||||
typeIds.add(task.getTaskTypeId());
|
||||
}
|
||||
if (task.getTaskTypeIds() != null && !task.getTaskTypeIds().trim().isEmpty()) {
|
||||
String[] ids = task.getTaskTypeIds().split(",");
|
||||
for (String id : ids) {
|
||||
try {
|
||||
typeIds.add(Long.parseLong(id.trim()));
|
||||
} catch (NumberFormatException e) {
|
||||
// 忽略无效ID
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Long typeId : typeIds) {
|
||||
tasksByTypeId.computeIfAbsent(typeId, k -> new ArrayList<>()).add(task);
|
||||
}
|
||||
}
|
||||
|
||||
// 计算每个类型的层级
|
||||
Map<Long, Integer> typeLevelMap = new HashMap<>();
|
||||
for (DemandType type : allTypes) {
|
||||
int level = calculateTypeLevel(type.getId(), typeMap);
|
||||
typeLevelMap.put(type.getId(), level);
|
||||
}
|
||||
|
||||
// 构建各层级的分析数据
|
||||
Map<Integer, List<DimensionAnalysisVO.TaskTypeAnalysis>> result = new HashMap<>();
|
||||
result.put(1, new ArrayList<>());
|
||||
result.put(2, new ArrayList<>());
|
||||
result.put(3, new ArrayList<>());
|
||||
|
||||
for (Long typeId : allTaskTypeIds) {
|
||||
DemandType type = typeMap.get(typeId);
|
||||
if (type == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<Task> typeTasks = tasksByTypeId.getOrDefault(typeId, new ArrayList<>());
|
||||
if (typeTasks.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int level = typeLevelMap.getOrDefault(typeId, 1);
|
||||
|
||||
// 构建分析数据
|
||||
DimensionAnalysisVO.TaskTypeAnalysis analysis = buildSingleTaskTypeAnalysis(
|
||||
type, typeTasks, level, typeMap, typeNameMap
|
||||
);
|
||||
|
||||
result.get(level).add(analysis);
|
||||
}
|
||||
|
||||
// 对各层级按任务数量降序排序
|
||||
for (int level = 1; level <= 3; level++) {
|
||||
List<DimensionAnalysisVO.TaskTypeAnalysis> levelList = result.get(level);
|
||||
levelList.sort((a, b) -> {
|
||||
Integer totalA = a.getTotalTasks() != null ? a.getTotalTasks() : 0;
|
||||
Integer totalB = b.getTotalTasks() != null ? b.getTotalTasks() : 0;
|
||||
return totalB.compareTo(totalA);
|
||||
});
|
||||
}
|
||||
|
||||
log.info("任务类型分析完成: 一级={}, 二级={}, 三级={}",
|
||||
result.get(1).size(), result.get(2).size(), result.get(3).size());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算任务类型的层级
|
||||
* @param typeId 类型ID
|
||||
* @param typeMap 类型映射
|
||||
* @return 层级(1/2/3)
|
||||
*/
|
||||
private int calculateTypeLevel(Long typeId, Map<Long, DemandType> typeMap) {
|
||||
DemandType type = typeMap.get(typeId);
|
||||
if (type == null) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int level = 1;
|
||||
Long parentId = type.getParentId();
|
||||
while (parentId != null && level < 3) {
|
||||
level++;
|
||||
DemandType parent = typeMap.get(parentId);
|
||||
if (parent == null) {
|
||||
break;
|
||||
}
|
||||
parentId = parent.getParentId();
|
||||
}
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建单个任务类型的分析数据
|
||||
*/
|
||||
private DimensionAnalysisVO.TaskTypeAnalysis buildSingleTaskTypeAnalysis(
|
||||
DemandType type,
|
||||
List<Task> typeTasks,
|
||||
int level,
|
||||
Map<Long, DemandType> typeMap,
|
||||
Map<Long, String> typeNameMap) {
|
||||
|
||||
DimensionAnalysisVO.TaskTypeAnalysis analysis = new DimensionAnalysisVO.TaskTypeAnalysis();
|
||||
analysis.setTypeId(type.getId());
|
||||
analysis.setTypeName(type.getName() != null ? type.getName() : "未知");
|
||||
analysis.setParentId(type.getParentId());
|
||||
analysis.setLevel(level);
|
||||
analysis.setUnitScore(type.getUnitScore());
|
||||
analysis.setEstimatedHours(type.getEstimatedHours());
|
||||
|
||||
// 设置父级名称
|
||||
if (type.getParentId() != null) {
|
||||
analysis.setParentName(typeNameMap.getOrDefault(type.getParentId(), "未知"));
|
||||
}
|
||||
|
||||
// 统计任务数量
|
||||
analysis.setTotalTasks(typeTasks.size());
|
||||
|
||||
long completedCount = typeTasks.stream()
|
||||
.filter(t -> "completed".equals(t.getStatus()))
|
||||
.count();
|
||||
analysis.setCompletedTasks((int) completedCount);
|
||||
|
||||
long inProgressCount = typeTasks.stream()
|
||||
.filter(t -> "in_progress".equals(t.getStatus()))
|
||||
.count();
|
||||
analysis.setInProgressTasks((int) inProgressCount);
|
||||
|
||||
long pendingCount = typeTasks.stream()
|
||||
.filter(t -> t.getStatus() != null && t.getStatus().contains("pending"))
|
||||
.count();
|
||||
analysis.setPendingTasks((int) pendingCount);
|
||||
|
||||
// 计算总数量
|
||||
int totalQuantity = typeTasks.stream()
|
||||
.filter(t -> t.getQuantity() != null)
|
||||
.mapToInt(Task::getQuantity)
|
||||
.sum();
|
||||
analysis.setTotalQuantity(totalQuantity);
|
||||
|
||||
// 计算总积分(优先使用 scoreReward)
|
||||
BigDecimal totalScore = typeTasks.stream()
|
||||
.map(t -> {
|
||||
if (t.getScoreReward() != null && t.getScoreReward().compareTo(BigDecimal.ZERO) > 0) {
|
||||
return t.getScoreReward();
|
||||
}
|
||||
return t.getScore() != null ? t.getScore() : BigDecimal.ZERO;
|
||||
})
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
analysis.setTotalScore(totalScore);
|
||||
|
||||
// 计算平均积分
|
||||
if (typeTasks.size() > 0) {
|
||||
analysis.setAvgScore(totalScore.divide(BigDecimal.valueOf(typeTasks.size()), 2, RoundingMode.HALF_UP));
|
||||
} else {
|
||||
analysis.setAvgScore(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
// 计算完成率
|
||||
if (typeTasks.size() > 0) {
|
||||
BigDecimal completionRate = BigDecimal.valueOf(completedCount)
|
||||
.divide(BigDecimal.valueOf(typeTasks.size()), 4, RoundingMode.HALF_UP)
|
||||
.multiply(BigDecimal.valueOf(100));
|
||||
analysis.setCompletionRate(completionRate);
|
||||
} else {
|
||||
analysis.setCompletionRate(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
// 计算准时率(已完成任务中准时完成的比例)
|
||||
if (completedCount > 0) {
|
||||
long onTimeCount = typeTasks.stream()
|
||||
.filter(t -> "completed".equals(t.getStatus()))
|
||||
.filter(t -> {
|
||||
if (t.getDeadline() == null || t.getActualEndTime() == null) {
|
||||
return true; // 没有截止时间或完成时间的视为准时
|
||||
}
|
||||
return !t.getActualEndTime().isAfter(t.getDeadline());
|
||||
})
|
||||
.count();
|
||||
analysis.setOnTimeRate((double) onTimeCount / completedCount * 100);
|
||||
} else {
|
||||
analysis.setOnTimeRate(0.0);
|
||||
}
|
||||
|
||||
// 计算平均完成时长(小时)
|
||||
List<Task> completedTasks = typeTasks.stream()
|
||||
.filter(t -> "completed".equals(t.getStatus())
|
||||
&& t.getActualStartTime() != null
|
||||
&& t.getActualEndTime() != null)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (!completedTasks.isEmpty()) {
|
||||
double totalHours = completedTasks.stream()
|
||||
.mapToDouble(t -> Duration.between(t.getActualStartTime(), t.getActualEndTime()).toMinutes() / 60.0)
|
||||
.sum();
|
||||
analysis.setAvgCompletionHours(totalHours / completedTasks.size());
|
||||
} else {
|
||||
analysis.setAvgCompletionHours(0.0);
|
||||
}
|
||||
|
||||
return analysis;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -42,6 +42,21 @@ public class DimensionAnalysisVO {
|
||||
*/
|
||||
private List<PlatformAnalysis> platformAnalysis;
|
||||
|
||||
/**
|
||||
* 任务类型维度分析(一级分类)
|
||||
*/
|
||||
private List<TaskTypeAnalysis> taskTypeAnalysis;
|
||||
|
||||
/**
|
||||
* 任务类型维度分析(二级分类)
|
||||
*/
|
||||
private List<TaskTypeAnalysis> taskTypeLevel2Analysis;
|
||||
|
||||
/**
|
||||
* 任务类型维度分析(三级分类)
|
||||
*/
|
||||
private List<TaskTypeAnalysis> taskTypeLevel3Analysis;
|
||||
|
||||
/**
|
||||
* 类目分析数据
|
||||
*/
|
||||
@ -170,4 +185,31 @@ public class DimensionAnalysisVO {
|
||||
private Integer demandDeptCount; // 需求部门数量
|
||||
private Integer receivingDeptCount; // 接单部门数量
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务类型分析数据
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class TaskTypeAnalysis {
|
||||
private Long typeId; // 类型ID
|
||||
private String typeName; // 类型名称
|
||||
private Long parentId; // 父级ID
|
||||
private String parentName; // 父级名称
|
||||
private Integer level; // 层级(1=一级,2=二级,3=三级)
|
||||
private Integer totalTasks; // 总任务数
|
||||
private Integer completedTasks; // 已完成任务数
|
||||
private Integer inProgressTasks; // 进行中任务数
|
||||
private Integer pendingTasks; // 待接单任务数
|
||||
private Integer totalQuantity; // 总数量
|
||||
private BigDecimal totalScore; // 总积分
|
||||
private BigDecimal avgScore; // 平均积分
|
||||
private BigDecimal completionRate; // 完成率
|
||||
private Double onTimeRate; // 准时率
|
||||
private Double avgCompletionHours; // 平均完成时长(小时)
|
||||
private BigDecimal unitScore; // 单价分值
|
||||
private BigDecimal estimatedHours; // 预估工时
|
||||
}
|
||||
}
|
||||
|
||||
@ -465,12 +465,36 @@ export interface PlatformAnalysis {
|
||||
totalQuantity: number;
|
||||
}
|
||||
|
||||
// 任务类型分析
|
||||
export interface TaskTypeAnalysis {
|
||||
typeId: number;
|
||||
typeName: string;
|
||||
parentId: number | null;
|
||||
parentName: string | null;
|
||||
level: number;
|
||||
totalTasks: number;
|
||||
completedTasks: number;
|
||||
inProgressTasks: number;
|
||||
pendingTasks: number;
|
||||
totalQuantity: number;
|
||||
totalScore: number;
|
||||
avgScore: number;
|
||||
completionRate: number;
|
||||
onTimeRate: number;
|
||||
avgCompletionHours: number;
|
||||
unitScore: number;
|
||||
estimatedHours: number;
|
||||
}
|
||||
|
||||
export interface DimensionAnalysis {
|
||||
categoryAnalysis: CategoryAnalysis[];
|
||||
brandAnalysis: BrandAnalysis[];
|
||||
receivingDeptAnalysis: DeptAnalysis[];
|
||||
demandDeptAnalysis: DeptAnalysis[];
|
||||
platformAnalysis: PlatformAnalysis[];
|
||||
taskTypeAnalysis: TaskTypeAnalysis[];
|
||||
taskTypeLevel2Analysis: TaskTypeAnalysis[];
|
||||
taskTypeLevel3Analysis: TaskTypeAnalysis[];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -499,7 +523,10 @@ export const getDimensionAnalysis = async (
|
||||
brandAnalysis: [],
|
||||
receivingDeptAnalysis: [],
|
||||
demandDeptAnalysis: [],
|
||||
platformAnalysis: []
|
||||
platformAnalysis: [],
|
||||
taskTypeAnalysis: [],
|
||||
taskTypeLevel2Analysis: [],
|
||||
taskTypeLevel3Analysis: []
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -579,6 +579,138 @@
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
|
||||
<!-- 任务类型分析(一级分类) -->
|
||||
<div class="table-card full-width" style="margin-top: 16px;">
|
||||
<div class="table-header">
|
||||
<h3 class="chart-title">任务类型分析(一级分类)</h3>
|
||||
</div>
|
||||
<a-table
|
||||
:columns="taskTypeColumns"
|
||||
:data-source="dimensionData.taskTypeAnalysis"
|
||||
:pagination="{ pageSize: 10 }"
|
||||
:scroll="{ x: 1200 }"
|
||||
row-key="typeId"
|
||||
size="middle"
|
||||
class="dark-table"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'totalScore'">
|
||||
<span class="score-value">{{ formatScore(record.totalScore) }}</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'avgScore'">
|
||||
<span class="score-value">{{ formatScore(record.avgScore) }}</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'unitScore'">
|
||||
<span class="score-value">{{ formatScore(record.unitScore) }}</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'completionRate'">
|
||||
<span :class="record.completionRate >= 80 ? 'text-success' : record.completionRate >= 50 ? 'text-warning' : 'text-danger'">
|
||||
{{ formatScore(record.completionRate) }}%
|
||||
</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'onTimeRate'">
|
||||
<span :class="record.onTimeRate >= 90 ? 'text-success' : record.onTimeRate >= 70 ? 'text-warning' : 'text-danger'">
|
||||
{{ formatScore(record.onTimeRate) }}%
|
||||
</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'avgCompletionHours'">
|
||||
<span>{{ record.avgCompletionHours ? formatScore(record.avgCompletionHours) + 'h' : '-' }}</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'estimatedHours'">
|
||||
<span>{{ record.estimatedHours ? formatScore(record.estimatedHours) + 'h' : '-' }}</span>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
|
||||
<!-- 任务类型分析(二级分类) -->
|
||||
<div class="table-card full-width" style="margin-top: 16px;">
|
||||
<div class="table-header">
|
||||
<h3 class="chart-title">任务类型分析(二级分类)</h3>
|
||||
</div>
|
||||
<a-table
|
||||
:columns="taskTypeLevel2Columns"
|
||||
:data-source="dimensionData.taskTypeLevel2Analysis"
|
||||
:pagination="{ pageSize: 10 }"
|
||||
:scroll="{ x: 1300 }"
|
||||
row-key="typeId"
|
||||
size="middle"
|
||||
class="dark-table"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'totalScore'">
|
||||
<span class="score-value">{{ formatScore(record.totalScore) }}</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'avgScore'">
|
||||
<span class="score-value">{{ formatScore(record.avgScore) }}</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'unitScore'">
|
||||
<span class="score-value">{{ formatScore(record.unitScore) }}</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'completionRate'">
|
||||
<span :class="record.completionRate >= 80 ? 'text-success' : record.completionRate >= 50 ? 'text-warning' : 'text-danger'">
|
||||
{{ formatScore(record.completionRate) }}%
|
||||
</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'onTimeRate'">
|
||||
<span :class="record.onTimeRate >= 90 ? 'text-success' : record.onTimeRate >= 70 ? 'text-warning' : 'text-danger'">
|
||||
{{ formatScore(record.onTimeRate) }}%
|
||||
</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'avgCompletionHours'">
|
||||
<span>{{ record.avgCompletionHours ? formatScore(record.avgCompletionHours) + 'h' : '-' }}</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'estimatedHours'">
|
||||
<span>{{ record.estimatedHours ? formatScore(record.estimatedHours) + 'h' : '-' }}</span>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
|
||||
<!-- 任务类型分析(三级分类) -->
|
||||
<div class="table-card full-width" style="margin-top: 16px;">
|
||||
<div class="table-header">
|
||||
<h3 class="chart-title">任务类型分析(三级分类)</h3>
|
||||
</div>
|
||||
<a-table
|
||||
:columns="taskTypeLevel3Columns"
|
||||
:data-source="dimensionData.taskTypeLevel3Analysis"
|
||||
:pagination="{ pageSize: 10 }"
|
||||
:scroll="{ x: 1400 }"
|
||||
row-key="typeId"
|
||||
size="middle"
|
||||
class="dark-table"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'totalScore'">
|
||||
<span class="score-value">{{ formatScore(record.totalScore) }}</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'avgScore'">
|
||||
<span class="score-value">{{ formatScore(record.avgScore) }}</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'unitScore'">
|
||||
<span class="score-value">{{ formatScore(record.unitScore) }}</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'completionRate'">
|
||||
<span :class="record.completionRate >= 80 ? 'text-success' : record.completionRate >= 50 ? 'text-warning' : 'text-danger'">
|
||||
{{ formatScore(record.completionRate) }}%
|
||||
</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'onTimeRate'">
|
||||
<span :class="record.onTimeRate >= 90 ? 'text-success' : record.onTimeRate >= 70 ? 'text-warning' : 'text-danger'">
|
||||
{{ formatScore(record.onTimeRate) }}%
|
||||
</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'avgCompletionHours'">
|
||||
<span>{{ record.avgCompletionHours ? formatScore(record.avgCompletionHours) + 'h' : '-' }}</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'estimatedHours'">
|
||||
<span>{{ record.estimatedHours ? formatScore(record.estimatedHours) + 'h' : '-' }}</span>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
|
||||
@ -810,6 +942,7 @@ import {
|
||||
type DelayDeductionItem,
|
||||
type ProgressDeductionItem,
|
||||
type DimensionAnalysis,
|
||||
type TaskTypeAnalysis,
|
||||
type PrimaryDeptStatistics,
|
||||
type PrimaryDeptRanking,
|
||||
type BrandTaskDistribution,
|
||||
@ -916,7 +1049,10 @@ const dimensionData = reactive<DimensionAnalysis>({
|
||||
brandAnalysis: [],
|
||||
receivingDeptAnalysis: [],
|
||||
demandDeptAnalysis: [],
|
||||
platformAnalysis: []
|
||||
platformAnalysis: [],
|
||||
taskTypeAnalysis: [],
|
||||
taskTypeLevel2Analysis: [],
|
||||
taskTypeLevel3Analysis: []
|
||||
})
|
||||
|
||||
// 一级需求部门统计数据
|
||||
@ -1163,6 +1299,59 @@ const platformColumns = [
|
||||
{ title: '总积分', key: 'totalScore', align: 'center', width: 100 }
|
||||
]
|
||||
|
||||
// 任务类型分析列(一级分类)
|
||||
const taskTypeColumns = [
|
||||
{ title: '类型名称', dataIndex: 'typeName', key: 'typeName', ellipsis: true, width: 150 },
|
||||
{ title: '任务数', dataIndex: 'totalTasks', key: 'totalTasks', align: 'center', width: 80 },
|
||||
{ title: '总数量', dataIndex: 'totalQuantity', key: 'totalQuantity', align: 'center', width: 80 },
|
||||
{ title: '已完成', dataIndex: 'completedTasks', key: 'completedTasks', align: 'center', width: 80 },
|
||||
{ title: '进行中', dataIndex: 'inProgressTasks', key: 'inProgressTasks', align: 'center', width: 80 },
|
||||
{ title: '待接单', dataIndex: 'pendingTasks', key: 'pendingTasks', align: 'center', width: 80 },
|
||||
{ title: '完成率', key: 'completionRate', align: 'center', width: 90 },
|
||||
{ title: '准时率', key: 'onTimeRate', align: 'center', width: 90 },
|
||||
{ title: '总积分', key: 'totalScore', align: 'center', width: 100 },
|
||||
{ title: '平均积分', key: 'avgScore', align: 'center', width: 100 },
|
||||
{ title: '单价分值', key: 'unitScore', align: 'center', width: 100 },
|
||||
{ title: '预估工时', key: 'estimatedHours', align: 'center', width: 100 },
|
||||
{ title: '平均完成时长', key: 'avgCompletionHours', align: 'center', width: 120 }
|
||||
]
|
||||
|
||||
// 任务类型分析列(二级分类,带父级名称)
|
||||
const taskTypeLevel2Columns = [
|
||||
{ title: '父级分类', dataIndex: 'parentName', key: 'parentName', ellipsis: true, width: 120 },
|
||||
{ title: '类型名称', dataIndex: 'typeName', key: 'typeName', ellipsis: true, width: 150 },
|
||||
{ title: '任务数', dataIndex: 'totalTasks', key: 'totalTasks', align: 'center', width: 80 },
|
||||
{ title: '总数量', dataIndex: 'totalQuantity', key: 'totalQuantity', align: 'center', width: 80 },
|
||||
{ title: '已完成', dataIndex: 'completedTasks', key: 'completedTasks', align: 'center', width: 80 },
|
||||
{ title: '进行中', dataIndex: 'inProgressTasks', key: 'inProgressTasks', align: 'center', width: 80 },
|
||||
{ title: '待接单', dataIndex: 'pendingTasks', key: 'pendingTasks', align: 'center', width: 80 },
|
||||
{ title: '完成率', key: 'completionRate', align: 'center', width: 90 },
|
||||
{ title: '准时率', key: 'onTimeRate', align: 'center', width: 90 },
|
||||
{ title: '总积分', key: 'totalScore', align: 'center', width: 100 },
|
||||
{ title: '平均积分', key: 'avgScore', align: 'center', width: 100 },
|
||||
{ title: '单价分值', key: 'unitScore', align: 'center', width: 100 },
|
||||
{ title: '预估工时', key: 'estimatedHours', align: 'center', width: 100 },
|
||||
{ title: '平均完成时长', key: 'avgCompletionHours', align: 'center', width: 120 }
|
||||
]
|
||||
|
||||
// 任务类型分析列(三级分类,带父级名称)
|
||||
const taskTypeLevel3Columns = [
|
||||
{ title: '父级分类', dataIndex: 'parentName', key: 'parentName', ellipsis: true, width: 120 },
|
||||
{ title: '类型名称', dataIndex: 'typeName', key: 'typeName', ellipsis: true, width: 150 },
|
||||
{ title: '任务数', dataIndex: 'totalTasks', key: 'totalTasks', align: 'center', width: 80 },
|
||||
{ title: '总数量', dataIndex: 'totalQuantity', key: 'totalQuantity', align: 'center', width: 80 },
|
||||
{ title: '已完成', dataIndex: 'completedTasks', key: 'completedTasks', align: 'center', width: 80 },
|
||||
{ title: '进行中', dataIndex: 'inProgressTasks', key: 'inProgressTasks', align: 'center', width: 80 },
|
||||
{ title: '待接单', dataIndex: 'pendingTasks', key: 'pendingTasks', align: 'center', width: 80 },
|
||||
{ title: '完成率', key: 'completionRate', align: 'center', width: 90 },
|
||||
{ title: '准时率', key: 'onTimeRate', align: 'center', width: 90 },
|
||||
{ title: '总积分', key: 'totalScore', align: 'center', width: 100 },
|
||||
{ title: '平均积分', key: 'avgScore', align: 'center', width: 100 },
|
||||
{ title: '单价分值', key: 'unitScore', align: 'center', width: 100 },
|
||||
{ title: '预估工时', key: 'estimatedHours', align: 'center', width: 100 },
|
||||
{ title: '平均完成时长', key: 'avgCompletionHours', align: 'center', width: 120 }
|
||||
]
|
||||
|
||||
// 一级需求部门排名列
|
||||
const primaryDeptColumns = [
|
||||
{ title: '排名', key: 'rank', dataIndex: 'rank', align: 'center', width: 60 },
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user