diff --git a/backend/src/main/java/com/designhub/mapper/TaskItemMapper.java b/backend/src/main/java/com/designhub/mapper/TaskItemMapper.java index 5a3e80e..6947a22 100644 --- a/backend/src/main/java/com/designhub/mapper/TaskItemMapper.java +++ b/backend/src/main/java/com/designhub/mapper/TaskItemMapper.java @@ -331,6 +331,22 @@ public interface TaskItemMapper extends BaseMapper { @Param("receiverDeptId") Long receiverDeptId, @Param("deadline") LocalDateTime deadline); + /** + * 指定任务接单(用于已预先指定设计师的任务) + * 只有被指定的设计师才能接单 + */ + @Update("UPDATE task_item SET " + + "status = 'in_progress', " + + "deadline = CASE WHEN #{deadline} IS NOT NULL THEN #{deadline} ELSE deadline END, " + + "update_time = NOW() " + + "WHERE id = #{itemId} " + + "AND status = 'pending' " + + "AND is_locked = 0 " + + "AND receiver_id = #{receiverId}") + int grabAssignedItem(@Param("itemId") Long itemId, + @Param("receiverId") Long receiverId, + @Param("deadline") LocalDateTime deadline); + /** * 解锁子任务 */ diff --git a/backend/src/main/java/com/designhub/service/TaskItemService.java b/backend/src/main/java/com/designhub/service/TaskItemService.java index e9111dc..cfac8fc 100644 --- a/backend/src/main/java/com/designhub/service/TaskItemService.java +++ b/backend/src/main/java/com/designhub/service/TaskItemService.java @@ -358,8 +358,25 @@ public class TaskItemService { throw new BusinessException(ResultCode.TASK_STATUS_ERROR, "该子任务已被锁定,请等待前序任务完成"); } + // 🔥 检查是否是指定任务:如果子任务已预先指定了接收人 + boolean isAssignedItem = false; if (item.getReceiverId() != null) { - throw new BusinessException(ResultCode.TASK_ALREADY_TAKEN, "该子任务已被接单"); + // 检查主任务是否是指定模式 + Task mainTaskForCheck = taskMapper.selectById(item.getTaskId()); + boolean isAssignedMode = mainTaskForCheck != null && "assigned".equals(mainTaskForCheck.getReleaseType()); + + if (isAssignedMode) { + // 指定任务模式:只有被指定的设计师才能接单 + if (!item.getReceiverId().equals(userId)) { + throw new BusinessException(ResultCode.FORBIDDEN, "该子任务已指定给其他设计师"); + } + // 被指定的设计师可以接单,继续执行 + isAssignedItem = true; + log.info("指定任务模式:设计师 {} 是被指定的接收人,允许接单", userId); + } else { + // 非指定任务模式:已有接收人则不能再接单 + throw new BusinessException(ResultCode.TASK_ALREADY_TAKEN, "该子任务已被接单"); + } } // 计算deadline @@ -371,13 +388,21 @@ public class TaskItemService { now, item.getEstimatedHours(), deadline); } - // 乐观锁抢单(同时设置接单部门ID和deadline) - int result = taskItemMapper.grabItem(itemId, userId, user.getRealName(), user.getDeptId(), deadline); + // 🔥 根据是否是指定任务使用不同的抢单方法 + int result; + if (isAssignedItem) { + // 指定任务:使用专用方法,只更新状态和deadline + result = taskItemMapper.grabAssignedItem(itemId, userId, deadline); + } else { + // 普通任务:乐观锁抢单(同时设置接单部门ID和deadline) + result = taskItemMapper.grabItem(itemId, userId, user.getRealName(), user.getDeptId(), deadline); + } + if (result == 0) { throw new BusinessException(ResultCode.TASK_ALREADY_TAKEN, "抢单失败,该子任务可能已被他人接单"); } - log.info("设计师 {} 成功抢单子任务 {}", userId, itemId); + log.info("设计师 {} 成功抢单子任务 {} (指定任务: {})", userId, itemId, isAssignedItem); // 更新主任务状态 Task mainTask = taskMapper.selectById(item.getTaskId()); diff --git a/扣分逻辑说明.md b/扣分逻辑说明.md index ee55c35..fde669a 100644 --- a/扣分逻辑说明.md +++ b/扣分逻辑说明.md @@ -1,4 +1,4 @@ -# 设计师绩效排行榜扣分逻辑说明 +# 由壹点「视觉需求」系统扣分逻辑说明 ## 一、当前系统扣分机制概述