fix: 每个分组创建一个子任务,而不是每个任务类型创建一个

This commit is contained in:
Your Name 2026-01-06 23:03:13 +08:00
parent ebc873114c
commit 70c16bfcca
2 changed files with 70 additions and 63 deletions

View File

@ -395,47 +395,67 @@ public class TaskService {
log.info("分组完成,共 {} 个子任务组", currentGroupNo);
// **步骤2:创建子任务,按分组设置状态**
for (int i = 0; i < dto.getItems().size(); i++) {
com.designhub.dto.PipelineTaskDTO.TaskItemDTO itemDto = dto.getItems().get(i);
var demandType = configService.getDemandTypeById(itemDto.getTaskTypeId());
// 解析分组号
// **步骤2:按分组汇总,每个分组创建一个子任务**
// 先按分组号收集任务类型
Map<Integer, List<com.designhub.dto.PipelineTaskDTO.TaskItemDTO>> groupedItems = new java.util.LinkedHashMap<>();
Map<Integer, Long> groupFirstTaskTypeId = new java.util.HashMap<>(); // 每组第一个任务类型ID
for (com.designhub.dto.PipelineTaskDTO.TaskItemDTO itemDto : dto.getItems()) {
int itemGroupNo = itemDto.getSortOrder() / 1000;
int itemIndex = itemDto.getSortOrder() % 1000;
groupedItems.computeIfAbsent(itemGroupNo, k -> new java.util.ArrayList<>()).add(itemDto);
// 记录每组第一个任务类型ID
if (!groupFirstTaskTypeId.containsKey(itemGroupNo)) {
groupFirstTaskTypeId.put(itemGroupNo, itemDto.getTaskTypeId());
}
}
// 为每个分组创建一个子任务
int itemIndex = 1;
for (Map.Entry<Integer, List<com.designhub.dto.PipelineTaskDTO.TaskItemDTO>> entry : groupedItems.entrySet()) {
int groupNo = entry.getKey();
List<com.designhub.dto.PipelineTaskDTO.TaskItemDTO> groupItems = entry.getValue();
// 汇总该分组的积分、工时、数量
int groupTotalScore = 0;
BigDecimal groupTotalHours = BigDecimal.ZERO;
int groupTotalQuantity = 0;
StringBuilder taskTypeIds = new StringBuilder();
for (com.designhub.dto.PipelineTaskDTO.TaskItemDTO itemDto : groupItems) {
var demandType = configService.getDemandTypeById(itemDto.getTaskTypeId());
int itemScore = demandType.getUnitScore().multiply(BigDecimal.valueOf(itemDto.getQuantity())).intValue();
BigDecimal itemHours = demandType.getEstimatedHours() != null
? demandType.getEstimatedHours().multiply(BigDecimal.valueOf(itemDto.getQuantity()))
: BigDecimal.ZERO;
groupTotalScore += itemScore;
groupTotalHours = groupTotalHours.add(itemHours);
groupTotalQuantity += itemDto.getQuantity();
if (taskTypeIds.length() > 0) {
taskTypeIds.append(",");
}
taskTypeIds.append(itemDto.getTaskTypeId());
}
// 创建子任务
com.designhub.entity.TaskItem item = new com.designhub.entity.TaskItem();
item.setTaskId(task.getId());
item.setItemNo(generateTaskItemNo(task.getTaskNo(), i + 1));
item.setGroupNo(itemGroupNo);
item.setTaskTypeId(itemDto.getTaskTypeId());
item.setQuantity(itemDto.getQuantity());
item.setUnitScore(demandType.getUnitScore().intValue());
item.setTotalScore(demandType.getUnitScore().multiply(BigDecimal.valueOf(itemDto.getQuantity())).intValue());
item.setEstimatedHours(demandType.getEstimatedHours() != null ? demandType.getEstimatedHours().multiply(BigDecimal.valueOf(itemDto.getQuantity())) : BigDecimal.ZERO);
item.setSortOrder(i + 1); // 恢复真实的排序号
item.setItemNo(generateTaskItemNo(task.getTaskNo(), itemIndex));
item.setGroupNo(groupNo);
item.setTaskTypeId(groupFirstTaskTypeId.get(groupNo)); // 使用第一个任务类型ID
item.setQuantity(groupTotalQuantity);
item.setUnitScore(groupTotalScore / groupTotalQuantity); // 平均单价
item.setTotalScore(groupTotalScore);
item.setEstimatedHours(groupTotalHours);
item.setSortOrder(itemIndex);
item.setProgress(0);
// 设置子任务指定的接收人
if (itemDto.getReceiverId() != null) {
item.setReceiverId(itemDto.getReceiverId());
// 获取接收人名字
User receiver = userService.getUserById(itemDto.getReceiverId());
if (receiver != null) {
item.setReceiverName(receiver.getRealName());
}
}
// 关键:根据流水线模式和分组设置初始状态
if ("sequential".equals(dto.getPipelineMode())) {
if (itemGroupNo == 1) {
// 顺序流水线:第一组
if (item.getReceiverId() != null) {
item.setStatus("in_progress"); // 指定了人,直接进行中
} else {
item.setStatus("pending"); // 没指定人,待接单
}
if (groupNo == 1) {
// 顺序流水线:第一组待接单
item.setStatus("pending");
item.setIsLocked(0);
item.setPrevItemId(null);
} else {
@ -444,22 +464,20 @@ public class TaskService {
item.setIsLocked(1);
}
} else {
// 并行流水线
if (item.getReceiverId() != null) {
item.setStatus("in_progress");
} else {
item.setStatus("pending");
}
// 并行流水线:全部待接单
item.setStatus("pending");
item.setIsLocked(0);
}
taskItemMapper.insert(item);
log.info("子任务创建成功,ID: {}, 编号: {}, 组号: {}, 状态: {}",
item.getId(), item.getItemNo(), item.getGroupNo(), item.getStatus());
log.info("子任务创建成功,ID: {}, 编号: {}, 组号: {}, 积分: {}, 工时: {}, 状态: {}",
item.getId(), item.getItemNo(), item.getGroupNo(), groupTotalScore, groupTotalHours, item.getStatus());
itemIndex++;
}
log.info("流水线任务创建完成,主任务ID: {}, 子任务数: {}, 分组数: {}",
task.getId(), dto.getItems().size(), currentGroupNo);
task.getId(), groupedItems.size(), currentGroupNo);
return task.getId();
}

View File

@ -200,20 +200,10 @@
class="task-card chart-card"
@click="handleTaskClick(task)"
>
<!-- 带预览图的卡片布局 -->
<div class="card-with-preview">
<!-- 预览图 -->
<div v-if="task.previewImage" class="task-preview">
<img :src="task.previewImage" alt="预览图" />
</div>
<!-- 卡片内容 -->
<div class="card-content" :class="{ 'has-preview': task.previewImage }">
<!-- 任务标题(单独一行) -->
<h3 class="task-title">{{ task.title }}</h3>
<!-- 状态标签(单独一行) -->
<div class="task-badges-row">
<!-- 任务标题 -->
<div class="task-header">
<h3 class="task-title">{{ task.title }}</h3>
<div class="task-badges">
<span v-if="task.isSubTask" class="badge badge-subtask">
<Icon name="layers" size="sm" color="#1890ff" style="margin-right: 4px; vertical-align: middle;" />
子任务
@ -226,11 +216,12 @@
<Icon name="star" size="sm" color="#31f08b" style="margin-right: 4px; vertical-align: middle;" />
高分
</span>
<span v-if="task.isUrgent" class="badge badge-urgent">
<Icon name="fire" size="sm" color="#31f08b" style="margin-right: 4px; vertical-align: middle;" />
紧急
</span>
</div>
<span v-if="task.isUrgent" class="badge badge-urgent">
<Icon name="fire" size="sm" color="#31f08b" style="margin-right: 4px; vertical-align: middle;" />
紧急
</span>
</div>
</div>
<!-- 流程阶段 -->
<div v-if="getProcessStage(task)" class="process-stage">
@ -355,8 +346,6 @@
{{ canGrabTask(task).canGrab ? '抢单' : '不可接单' }}
</button>
</div>
</div> <!-- 结束 card-content -->
</div> <!-- 结束 card-with-preview -->
</div>
</div>