fix: 修复被驳回流水线任务无法重新编辑的问题,支持PipelineTaskDTO格式更新
This commit is contained in:
parent
2f0ec3d622
commit
ddb5e729b9
@ -95,13 +95,35 @@ public class TaskController {
|
||||
return Result.success(task);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新任务", description = "更新任务信息")
|
||||
@Operation(summary = "更新任务", description = "更新任务信息,支持普通任务和流水线任务")
|
||||
@PutMapping("/{id}")
|
||||
public Result<String> updateTask(@PathVariable Long id, @RequestBody Task task, @RequestHeader("Authorization") String authHeader) {
|
||||
public Result<String> updateTask(@PathVariable Long id, @RequestBody Object taskData, @RequestHeader("Authorization") String authHeader) {
|
||||
log.info("更新任务: {}", id);
|
||||
String token = jwtUtil.extractTokenFromHeader(authHeader);
|
||||
Long userId = jwtUtil.getUserIdFromToken(token);
|
||||
taskService.updateTask(id, task, userId);
|
||||
|
||||
// 判断是否是流水线任务(检查是否有isPipeline字段或items字段)
|
||||
try {
|
||||
com.fasterxml.jackson.databind.ObjectMapper objectMapper = new com.fasterxml.jackson.databind.ObjectMapper();
|
||||
String json = objectMapper.writeValueAsString(taskData);
|
||||
com.fasterxml.jackson.databind.JsonNode jsonNode = objectMapper.readTree(json);
|
||||
|
||||
// 检查是否是流水线任务格式
|
||||
if (jsonNode.has("isPipeline") && jsonNode.get("isPipeline").asBoolean() ||
|
||||
jsonNode.has("items") && jsonNode.get("items").isArray()) {
|
||||
// 流水线任务更新
|
||||
com.designhub.dto.PipelineTaskDTO dto = objectMapper.convertValue(taskData, com.designhub.dto.PipelineTaskDTO.class);
|
||||
taskService.updatePipelineTask(id, dto, userId);
|
||||
} else {
|
||||
// 普通任务更新
|
||||
Task task = objectMapper.convertValue(taskData, Task.class);
|
||||
taskService.updateTask(id, task, userId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("解析任务数据失败", e);
|
||||
throw new com.designhub.exception.BusinessException(com.designhub.common.ResultCode.PARAM_ERROR, "任务数据格式错误");
|
||||
}
|
||||
|
||||
return Result.success("更新成功");
|
||||
}
|
||||
|
||||
|
||||
@ -1098,7 +1098,7 @@ public class TaskService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新任务
|
||||
* 更新任务(普通任务)
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateTask(Long id, Task task, Long userId) {
|
||||
@ -1129,6 +1129,295 @@ public class TaskService {
|
||||
|
||||
log.info("任务更新成功: taskId={}, userId={}, isRejected={}", id, userId, isRejected);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新流水线任务
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updatePipelineTask(Long id, com.designhub.dto.PipelineTaskDTO dto, Long userId) {
|
||||
Task existTask = getTaskById(id);
|
||||
|
||||
// 验证权限:只有任务发布人才能更新任务
|
||||
boolean isAdmin = isAdminUser(userId);
|
||||
if (!isAdmin && !userId.equals(existTask.getPublisherId())) {
|
||||
throw new BusinessException(ResultCode.FORBIDDEN, "只有任务发布人可以更新任务");
|
||||
}
|
||||
|
||||
// 验证任务是否是流水线任务
|
||||
if (existTask.getIsPipeline() == null || existTask.getIsPipeline() != 1) {
|
||||
throw new BusinessException(ResultCode.PARAM_ERROR, "该任务不是流水线任务");
|
||||
}
|
||||
|
||||
// 允许更新被驳回的任务(approvalStatus包含rejected或status为draft)
|
||||
boolean isRejected = (existTask.getApprovalStatus() != null &&
|
||||
(existTask.getApprovalStatus().contains("rejected") ||
|
||||
"draft".equals(existTask.getApprovalStatus()))) ||
|
||||
"draft".equals(existTask.getStatus());
|
||||
|
||||
if (!isRejected) {
|
||||
throw new BusinessException(ResultCode.PARAM_ERROR, "只能更新被驳回或草稿状态的任务");
|
||||
}
|
||||
|
||||
// 验证流水线模式
|
||||
if (!"sequential".equals(dto.getPipelineMode()) && !"parallel".equals(dto.getPipelineMode())) {
|
||||
throw new BusinessException(ResultCode.PARAM_ERROR, "流水线模式必须是 sequential 或 parallel");
|
||||
}
|
||||
|
||||
// 验证子任务列表
|
||||
if (dto.getItems() == null || dto.getItems().isEmpty()) {
|
||||
throw new BusinessException(ResultCode.PARAM_ERROR, "流水线任务至少需要一个子任务");
|
||||
}
|
||||
|
||||
// 计算总积分和工时
|
||||
int totalScore = 0;
|
||||
double totalHours = 0;
|
||||
for (com.designhub.dto.PipelineTaskDTO.TaskItemDTO itemDto : dto.getItems()) {
|
||||
var demandType = configService.getDemandTypeById(itemDto.getTaskTypeId());
|
||||
if (demandType == null) {
|
||||
throw new BusinessException(ResultCode.PARAM_ERROR, "任务类型ID无效: " + itemDto.getTaskTypeId());
|
||||
}
|
||||
|
||||
int itemScore = demandType.getUnitScore().multiply(BigDecimal.valueOf(itemDto.getQuantity())).intValue();
|
||||
double itemHours = demandType.getEstimatedHours() != null ?
|
||||
demandType.getEstimatedHours().multiply(BigDecimal.valueOf(itemDto.getQuantity())).doubleValue() : 0;
|
||||
|
||||
totalScore += itemScore;
|
||||
totalHours += itemHours;
|
||||
}
|
||||
|
||||
// 检查部门积分是否充足(管理员跳过积分检查)
|
||||
User user = userService.getUserById(userId);
|
||||
if (!isAdmin && user.getDeptId() != null) {
|
||||
if (!teamScorePoolService.checkBalance(user.getDeptId(), totalScore)) {
|
||||
throw new BusinessException(ResultCode.INSUFFICIENT_SCORE, "部门积分余额不足");
|
||||
}
|
||||
|
||||
if (!teamScorePoolService.checkPeriodLimit(user.getDeptId(), totalScore)) {
|
||||
throw new BusinessException(ResultCode.SCORE_LIMIT_EXCEEDED, "超过本周期积分消耗限制");
|
||||
}
|
||||
}
|
||||
|
||||
// 更新主任务信息
|
||||
existTask.setTitle(dto.getTitle());
|
||||
existTask.setPipelineMode(dto.getPipelineMode());
|
||||
existTask.setScore(totalScore);
|
||||
existTask.setEstimatedHours(BigDecimal.valueOf(totalHours));
|
||||
existTask.setBrandId(dto.getBrandId());
|
||||
existTask.setCategoryId(dto.getCategoryId());
|
||||
existTask.setPlatformId(dto.getPlatformId());
|
||||
existTask.setSpuInfo(dto.getSpuInfo());
|
||||
existTask.setTaskSubType(dto.getTaskSubType());
|
||||
existTask.setAttachmentUrl(dto.getAttachmentUrl());
|
||||
existTask.setPreviewImage(dto.getPreviewImage());
|
||||
existTask.setRemark(dto.getRemark());
|
||||
existTask.setPriority(dto.getPriority() != null ? dto.getPriority() : 1);
|
||||
existTask.setReleaseType(dto.getReleaseType() != null ? dto.getReleaseType() : "recruitment");
|
||||
|
||||
// 设置商品条码列表
|
||||
if (dto.getProductBarcodes() != null && !dto.getProductBarcodes().isEmpty()) {
|
||||
existTask.setProductBarcodes(String.join(",", dto.getProductBarcodes()));
|
||||
}
|
||||
|
||||
// 设置任务类型ID
|
||||
if (dto.getItems() != null && !dto.getItems().isEmpty()) {
|
||||
existTask.setTaskTypeId(dto.getItems().get(0).getTaskTypeId());
|
||||
String taskTypeIds = dto.getItems().stream()
|
||||
.map(item -> String.valueOf(item.getTaskTypeId()))
|
||||
.collect(Collectors.joining(","));
|
||||
existTask.setTaskTypeIds(taskTypeIds);
|
||||
}
|
||||
|
||||
// 重置审核状态为draft,以便重新提交审核
|
||||
existTask.setApprovalStatus("draft");
|
||||
existTask.setStatus("draft");
|
||||
existTask.setRejectReason(null); // 清空驳回原因
|
||||
existTask.setCurrentApproverId(null);
|
||||
existTask.setCurrentApproverRole(null);
|
||||
existTask.setUpdateTime(LocalDateTime.now());
|
||||
|
||||
// 如果是assigned模式,设置接收人
|
||||
Long mainReceiverId = dto.getReceiverId();
|
||||
if ("assigned".equals(dto.getReleaseType()) && mainReceiverId == null && dto.getItems() != null && !dto.getItems().isEmpty()) {
|
||||
mainReceiverId = dto.getItems().get(0).getReceiverId();
|
||||
}
|
||||
if ("assigned".equals(dto.getReleaseType()) && mainReceiverId != null) {
|
||||
existTask.setReceiverId(mainReceiverId);
|
||||
User receiver = userService.getUserById(mainReceiverId);
|
||||
if (receiver != null && receiver.getDeptId() != null) {
|
||||
existTask.setReceiverDeptId(receiver.getDeptId());
|
||||
}
|
||||
} else {
|
||||
existTask.setReceiverId(null);
|
||||
existTask.setReceiverDeptId(null);
|
||||
}
|
||||
|
||||
// 更新主任务
|
||||
taskMapper.updateById(existTask);
|
||||
log.info("主任务更新成功: taskId={}, taskNo={}", existTask.getId(), existTask.getTaskNo());
|
||||
|
||||
// 删除旧的子任务
|
||||
taskItemMapper.delete(new LambdaQueryWrapper<com.designhub.entity.TaskItem>()
|
||||
.eq(com.designhub.entity.TaskItem::getTaskId, id));
|
||||
log.info("已删除旧的子任务: taskId={}", id);
|
||||
|
||||
// 重新创建子任务(使用与createPipelineTask相同的逻辑)
|
||||
createPipelineTaskItemsForUpdate(existTask, dto);
|
||||
|
||||
// 重新初始化审核状态并发送通知
|
||||
initApprovalStatus(existTask);
|
||||
sendApprovalNotification(existTask);
|
||||
|
||||
log.info("流水线任务更新成功: taskId={}, userId={}", id, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 为更新操作创建流水线子任务(复用createPipelineTask的子任务创建逻辑)
|
||||
*/
|
||||
private void createPipelineTaskItemsForUpdate(Task mainTask, com.designhub.dto.PipelineTaskDTO dto) {
|
||||
// **步骤1:按接单部门自动分组**
|
||||
int currentGroupNo = 1;
|
||||
String lastDeptKey = null;
|
||||
|
||||
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());
|
||||
|
||||
// 获取当前任务类型的接单部门配置
|
||||
String currentDeptKey;
|
||||
if (itemDto.getSelectedDeptId() != null) {
|
||||
currentDeptKey = String.valueOf(itemDto.getSelectedDeptId());
|
||||
} else {
|
||||
currentDeptKey = demandType.getAllowedDeptIds();
|
||||
if (currentDeptKey == null && demandType.getParentId() != null) {
|
||||
var parentType = configService.getDemandTypeById(demandType.getParentId());
|
||||
if (parentType != null) {
|
||||
currentDeptKey = parentType.getAllowedDeptIds();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 判断是否需要创建新分组
|
||||
boolean needNewGroup = false;
|
||||
if (i > 0) {
|
||||
if (currentDeptKey == null || lastDeptKey == null) {
|
||||
needNewGroup = true;
|
||||
} else if (!currentDeptKey.equals(lastDeptKey)) {
|
||||
needNewGroup = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (needNewGroup) {
|
||||
currentGroupNo++;
|
||||
}
|
||||
|
||||
itemDto.setSortOrder(currentGroupNo * 1000 + i);
|
||||
lastDeptKey = currentDeptKey;
|
||||
}
|
||||
|
||||
// **步骤2:按分组汇总,每个分组创建一个子任务**
|
||||
Map<Integer, List<com.designhub.dto.PipelineTaskDTO.TaskItemDTO>> groupedItems = new java.util.LinkedHashMap<>();
|
||||
Map<Integer, Long> groupFirstTaskTypeId = new java.util.HashMap<>();
|
||||
|
||||
for (com.designhub.dto.PipelineTaskDTO.TaskItemDTO itemDto : dto.getItems()) {
|
||||
int itemGroupNo = itemDto.getSortOrder() / 1000;
|
||||
groupedItems.computeIfAbsent(itemGroupNo, k -> new java.util.ArrayList<>()).add(itemDto);
|
||||
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();
|
||||
java.util.List<java.util.Map<String, Object>> typeDetailsList = new java.util.ArrayList<>();
|
||||
|
||||
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());
|
||||
|
||||
java.util.Map<String, Object> detail = new java.util.LinkedHashMap<>();
|
||||
detail.put("typeId", itemDto.getTaskTypeId());
|
||||
detail.put("typeName", demandType.getName());
|
||||
detail.put("quantity", itemDto.getQuantity());
|
||||
detail.put("unitScore", demandType.getUnitScore());
|
||||
detail.put("totalScore", itemScore);
|
||||
typeDetailsList.add(detail);
|
||||
}
|
||||
|
||||
// 创建子任务
|
||||
com.designhub.entity.TaskItem item = new com.designhub.entity.TaskItem();
|
||||
item.setTaskId(mainTask.getId());
|
||||
item.setItemNo(generateTaskItemNo(mainTask.getTaskNo(), itemIndex));
|
||||
item.setGroupNo(groupNo);
|
||||
item.setTaskTypeId(groupFirstTaskTypeId.get(groupNo));
|
||||
try {
|
||||
com.fasterxml.jackson.databind.ObjectMapper objectMapper = new com.fasterxml.jackson.databind.ObjectMapper();
|
||||
item.setTypeDetails(objectMapper.writeValueAsString(typeDetailsList));
|
||||
} catch (Exception e) {
|
||||
log.warn("序列化任务类型明细失败: {}", e.getMessage());
|
||||
}
|
||||
item.setQuantity(groupTotalQuantity);
|
||||
item.setUnitScore(groupTotalScore / groupTotalQuantity);
|
||||
item.setTotalScore(groupTotalScore);
|
||||
item.setEstimatedHours(groupTotalHours);
|
||||
item.setSortOrder(itemIndex);
|
||||
item.setProgress(0);
|
||||
|
||||
// 如果是assigned模式,设置子任务的接收人
|
||||
if ("assigned".equals(dto.getReleaseType()) && !groupItems.isEmpty()) {
|
||||
Long itemReceiverId = groupItems.get(0).getReceiverId();
|
||||
if (itemReceiverId != null) {
|
||||
item.setReceiverId(itemReceiverId);
|
||||
User itemReceiver = userService.getUserById(itemReceiverId);
|
||||
if (itemReceiver != null && itemReceiver.getDeptId() != null) {
|
||||
item.setReceiverDeptId(itemReceiver.getDeptId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 根据流水线模式和分组设置初始状态
|
||||
if ("sequential".equals(dto.getPipelineMode())) {
|
||||
if (groupNo == 1) {
|
||||
item.setStatus("pending");
|
||||
item.setIsLocked(0);
|
||||
item.setPrevItemId(null);
|
||||
} else {
|
||||
item.setStatus("locked");
|
||||
item.setIsLocked(1);
|
||||
}
|
||||
} else {
|
||||
item.setStatus("pending");
|
||||
item.setIsLocked(0);
|
||||
}
|
||||
|
||||
taskItemMapper.insert(item);
|
||||
log.info("子任务创建成功,ID: {}, 编号: {}, 组号: {}", item.getId(), item.getItemNo(), item.getGroupNo());
|
||||
|
||||
itemIndex++;
|
||||
}
|
||||
|
||||
log.info("流水线子任务创建完成,主任务ID: {}, 子任务数: {}", mainTask.getId(), groupedItems.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* 抢单
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user