diff --git a/backend/src/main/java/com/designhub/service/TaskItemService.java b/backend/src/main/java/com/designhub/service/TaskItemService.java index 008c877..31944ac 100644 --- a/backend/src/main/java/com/designhub/service/TaskItemService.java +++ b/backend/src/main/java/com/designhub/service/TaskItemService.java @@ -328,9 +328,70 @@ public class TaskItemService { } } + List allowedDeptIds = resolveAllowedQueueDeptIds(item); + if (!allowedDeptIds.isEmpty()) { + if (viewerDeptId != null) { + Long matchedDeptId = null; + int bestDistance = Integer.MAX_VALUE; + for (Long candidateDeptId : allowedDeptIds) { + if (candidateDeptId == null || !isDeptMatchedOrInherited(viewerDeptId, candidateDeptId)) { + continue; + } + int distance = getDeptDistance(viewerDeptId, candidateDeptId); + if (distance < bestDistance) { + bestDistance = distance; + matchedDeptId = candidateDeptId; + } + } + if (matchedDeptId != null) { + return matchedDeptId; + } + } + return allowedDeptIds.get(0); + } + return unlockStatuses.get(0).getDeptId(); } + private List resolveAllowedQueueDeptIds(TaskItem item) { + if (item == null || item.getTaskTypeId() == null) { + return java.util.Collections.emptyList(); + } + + com.designhub.entity.DemandType demandType = configService.getDemandTypeById(item.getTaskTypeId()); + String allowedDeptIds = null; + if (demandType != null) { + allowedDeptIds = demandType.getAllowedDeptIds(); + if ((allowedDeptIds == null || allowedDeptIds.isBlank()) && demandType.getParentId() != null) { + com.designhub.entity.DemandType parentType = configService.getDemandTypeById(demandType.getParentId()); + if (parentType != null) { + allowedDeptIds = parentType.getAllowedDeptIds(); + } + } + } + + if (allowedDeptIds == null || allowedDeptIds.isBlank()) { + return java.util.Collections.emptyList(); + } + + List result = new java.util.ArrayList<>(); + Set seen = new java.util.HashSet<>(); + for (String deptIdText : allowedDeptIds.split(",")) { + if (deptIdText == null || deptIdText.isBlank()) { + continue; + } + try { + Long deptId = Long.parseLong(deptIdText.trim()); + if (seen.add(deptId)) { + result.add(deptId); + } + } catch (NumberFormatException e) { + log.warn("解析排队部门ID失败: taskItemId={}, deptIdText={}", item.getId(), deptIdText); + } + } + return result; + } + private int getDeptDistance(Long userDeptId, Long targetDeptId) { if (userDeptId == null || targetDeptId == null) { return Integer.MAX_VALUE; diff --git a/backend/src/main/java/com/designhub/service/TaskUnlockService.java b/backend/src/main/java/com/designhub/service/TaskUnlockService.java index 89120ca..3ff736c 100644 --- a/backend/src/main/java/com/designhub/service/TaskUnlockService.java +++ b/backend/src/main/java/com/designhub/service/TaskUnlockService.java @@ -550,8 +550,8 @@ public class TaskUnlockService { if (isUnlocked == null) { // 没有记录:补全排队记录,避免“新任务绕过排队” - LocalDate publishDate = item.getCreateTime() != null ? item.getCreateTime().toLocalDate() : LocalDate.now(); - unlockStatusMapper.insertIfNotExists(item.getId(), deptId, publishDate, 0); + ensureUnlockStatusExists(taskItemId(item), deptId); + tryTopUpDeptQueue(deptId); isUnlocked = unlockStatusMapper.isUnlocked(item.getId(), deptId); // 兜底:依然查不到则按排队中处理 @@ -624,9 +624,11 @@ public class TaskUnlockService { Integer isUnlocked = unlockStatusMapper.isUnlocked(taskItemId, deptId); if (isUnlocked == null) { - // 没有记录:补全排队记录,默认排队中(不可抢) + // 没有记录:补全排队记录,并尝试按部门阈值补位 ensureUnlockStatusExists(taskItemId, deptId); - return false; + tryTopUpDeptQueue(deptId); + isUnlocked = unlockStatusMapper.isUnlocked(taskItemId, deptId); + return isUnlocked != null && isUnlocked == 1; } return isUnlocked == 1; @@ -666,6 +668,21 @@ public class TaskUnlockService { } } + private void tryTopUpDeptQueue(Long deptId) { + if (deptId == null || !isUnlockEnabled()) { + return; + } + try { + unlockTasksForDept(deptId, getDailyUnlockMin()); + } catch (Exception e) { + log.warn("补齐部门可接任务失败: deptId={}, error={}", deptId, e.getMessage()); + } + } + + private Long taskItemId(TaskItem item) { + return item == null ? null : item.getId(); + } + /** * 获取任务的目标接单部门ID列表(支持多部门 & 三级分类继承) */