diff --git a/backend/src/main/java/com/designhub/service/TaskService.java b/backend/src/main/java/com/designhub/service/TaskService.java index 106762c..66bf162 100644 --- a/backend/src/main/java/com/designhub/service/TaskService.java +++ b/backend/src/main/java/com/designhub/service/TaskService.java @@ -125,6 +125,15 @@ public class TaskService { } // 验证任务类型并计算积分(支持多类型) + // 对于一级需求部门且关闭了任务明细填写的情况,允许不填写任务类型 + boolean canSkipTaskType = false; + if (isPrimaryTask) { + // 检查系统配置:一级需求部门是否可以填写任务明细 + Boolean canFillDetail = systemConfigService.getBooleanValue("task.primary_dept_can_fill_detail", true); + canSkipTaskType = !canFillDetail; + log.info("一级需求部门任务,canFillDetail={}, canSkipTaskType={}", canFillDetail, canSkipTaskType); + } + if (task.getQuantity() != null) { // 优先处理多类型 if (task.getTaskTypeIds() != null && !task.getTaskTypeIds().isEmpty()) { @@ -172,7 +181,12 @@ public class TaskService { log.info("创建单类型任务: typeId={}, score={}", task.getTaskTypeId(), totalScoreSingle); } else { - throw new BusinessException(ResultCode.PARAM_ERROR, "请选择任务类型"); + // 如果一级需求部门且关闭了任务明细,允许不填写任务类型 + if (!canSkipTaskType) { + throw new BusinessException(ResultCode.PARAM_ERROR, "请选择任务类型"); + } else { + log.info("一级需求部门任务,允许不填写任务类型"); + } } } @@ -275,8 +289,16 @@ public class TaskService { throw new BusinessException(ResultCode.PARAM_ERROR, "流水线模式必须是 sequential 或 parallel"); } - // 验证子任务列表 - if (dto.getItems() == null || dto.getItems().isEmpty()) { + // 检查一级需求部门是否可以跳过任务明细 + boolean canSkipTaskDetail = false; + if (isPrimaryTask) { + Boolean canFillDetail = systemConfigService.getBooleanValue("task.primary_dept_can_fill_detail", true); + canSkipTaskDetail = !canFillDetail; + log.info("一级需求部门流水线任务,canFillDetail={}, canSkipTaskDetail={}", canFillDetail, canSkipTaskDetail); + } + + // 验证子任务列表(一级需求部门且关闭任务明细时可以为空) + if ((dto.getItems() == null || dto.getItems().isEmpty()) && !canSkipTaskDetail) { throw new BusinessException(ResultCode.PARAM_ERROR, "流水线任务至少需要一个子任务"); } @@ -284,18 +306,20 @@ public class TaskService { BigDecimal totalScoreDecimal = BigDecimal.ZERO; double totalHours = 0; int totalQuantity = 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()); + if (dto.getItems() != null && !dto.getItems().isEmpty()) { + 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()); + } + + BigDecimal itemScore = demandType.getUnitScore().multiply(BigDecimal.valueOf(itemDto.getQuantity())); + double itemHours = demandType.getEstimatedHours() != null ? demandType.getEstimatedHours().multiply(BigDecimal.valueOf(itemDto.getQuantity())).doubleValue() : 0; + + totalScoreDecimal = totalScoreDecimal.add(itemScore); + totalHours += itemHours; + totalQuantity += itemDto.getQuantity(); } - - BigDecimal itemScore = demandType.getUnitScore().multiply(BigDecimal.valueOf(itemDto.getQuantity())); - double itemHours = demandType.getEstimatedHours() != null ? demandType.getEstimatedHours().multiply(BigDecimal.valueOf(itemDto.getQuantity())).doubleValue() : 0; - - totalScoreDecimal = totalScoreDecimal.add(itemScore); - totalHours += itemHours; - totalQuantity += itemDto.getQuantity(); } // 保留2位小数 diff --git a/frontend/src/views/CreateTask.vue b/frontend/src/views/CreateTask.vue index 92e6bd6..686a21a 100644 --- a/frontend/src/views/CreateTask.vue +++ b/frontend/src/views/CreateTask.vue @@ -1534,11 +1534,13 @@ const handleSubmit = async () => { // 验证表单 await formRef.value.validate() - // 验证任务类型 - const validTaskTypes = formData.taskTypes.filter(item => item.taskTypeId && item.quantity > 0) - if (validTaskTypes.length === 0) { - message.error('请至少添加一个任务类型') - return + // 验证任务类型(一级需求部门且关闭任务明细时跳过验证) + if (shouldShowTaskDetail.value) { + const validTaskTypes = formData.taskTypes.filter(item => item.taskTypeId && item.quantity > 0) + if (validTaskTypes.length === 0) { + message.error('请至少添加一个任务类型') + return + } } // 检查库存(如果需要)