diff --git a/backend/src/main/java/com/designhub/controller/TaskItemController.java b/backend/src/main/java/com/designhub/controller/TaskItemController.java index c308726..d66831a 100644 --- a/backend/src/main/java/com/designhub/controller/TaskItemController.java +++ b/backend/src/main/java/com/designhub/controller/TaskItemController.java @@ -80,7 +80,9 @@ public class TaskItemController { if (isAdmin) { // 管理员:看到所有进行中的子任务(如果指定了deptId则按部门过滤) if (deptId != null) { - items = taskItemService.getInProgressItemsByDeptIds(page, pageSize, List.of(deptId), keyword); + // 获取指定部门及其所有子部门 + List deptAndChildIds = getDeptAndChildIds(deptId); + items = taskItemService.getInProgressItemsByDeptIds(page, pageSize, deptAndChildIds, keyword); } else { items = taskItemService.getInProgressItems(page, pageSize, null, null, keyword); } @@ -93,13 +95,20 @@ public class TaskItemController { // 如果指定了deptId,验证是否在负责的部门列表中 if (deptId != null) { if (leadingDeptIds.contains(deptId)) { - items = taskItemService.getInProgressItemsByDeptIds(page, pageSize, List.of(deptId), keyword); + // 获取指定部门及其所有子部门 + List deptAndChildIds = getDeptAndChildIds(deptId); + items = taskItemService.getInProgressItemsByDeptIds(page, pageSize, deptAndChildIds, keyword); } else { // 无权查看该部门 items = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(); } } else { - items = taskItemService.getInProgressItemsByDeptIds(page, pageSize, leadingDeptIds, keyword); + // 获取所有负责部门及其子部门 + List allDeptIds = new java.util.ArrayList<>(); + for (Long leadDeptId : leadingDeptIds) { + allDeptIds.addAll(getDeptAndChildIds(leadDeptId)); + } + items = taskItemService.getInProgressItemsByDeptIds(page, pageSize, allDeptIds, keyword); } } else { // 普通设计师:只看自己的子任务 @@ -142,7 +151,9 @@ public class TaskItemController { if (isAdmin) { // 管理员:看到所有已完成的子任务(如果指定了deptId则按部门过滤) if (deptId != null) { - items = taskItemService.getCompletedItemsByDeptIds(page, pageSize, List.of(deptId), keyword); + // 获取指定部门及其所有子部门 + List deptAndChildIds = getDeptAndChildIds(deptId); + items = taskItemService.getCompletedItemsByDeptIds(page, pageSize, deptAndChildIds, keyword); } else { items = taskItemService.getCompletedItems(page, pageSize, null, null, keyword); } @@ -155,12 +166,19 @@ public class TaskItemController { // 如果指定了deptId,验证是否在负责的部门列表中 if (deptId != null) { if (leadingDeptIds.contains(deptId)) { - items = taskItemService.getCompletedItemsByDeptIds(page, pageSize, List.of(deptId), keyword); + // 获取指定部门及其所有子部门 + List deptAndChildIds = getDeptAndChildIds(deptId); + items = taskItemService.getCompletedItemsByDeptIds(page, pageSize, deptAndChildIds, keyword); } else { items = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(); } } else { - items = taskItemService.getCompletedItemsByDeptIds(page, pageSize, leadingDeptIds, keyword); + // 获取所有负责部门及其子部门 + List allDeptIds = new java.util.ArrayList<>(); + for (Long leadDeptId : leadingDeptIds) { + allDeptIds.addAll(getDeptAndChildIds(leadDeptId)); + } + items = taskItemService.getCompletedItemsByDeptIds(page, pageSize, allDeptIds, keyword); } } else { // 普通设计师:只看自己的子任务 @@ -377,4 +395,33 @@ public class TaskItemController { log.info("最终返回 {} 个待审核子任务组", allGroups.size()); return Result.success(allGroups); } + + /** + * 获取指定部门及其所有子部门的ID列表 + */ + private List getDeptAndChildIds(Long deptId) { + List result = new java.util.ArrayList<>(); + result.add(deptId); + + // 递归查询所有子部门 + collectChildDeptIds(deptId, result); + + return result; + } + + /** + * 递归收集所有子部门ID + */ + private void collectChildDeptIds(Long parentId, List result) { + List children = departmentMapper.selectList( + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(com.designhub.entity.Department::getParentId, parentId) + .eq(com.designhub.entity.Department::getStatus, 1) + ); + + for (com.designhub.entity.Department child : children) { + result.add(child.getId()); + collectChildDeptIds(child.getId(), result); + } + } } diff --git a/frontend/src/views/TaskHall.vue b/frontend/src/views/TaskHall.vue index f5075b5..d62546a 100644 --- a/frontend/src/views/TaskHall.vue +++ b/frontend/src/views/TaskHall.vue @@ -221,7 +221,7 @@

{{ task.title }}

- + 子任务 @@ -902,11 +902,11 @@

{{ task.title }}

- + 子任务 - + 指定 @@ -1620,7 +1620,7 @@ {{ getTaskStatusText(task.status, task) }} - + 指定 @@ -2069,13 +2069,14 @@ 交付路径
- - - {{ selectedTask.deliveryPath }} - + + + 下载素材 +

{{ selectedTask.deliveryPath }}

@@ -2173,10 +2174,14 @@
- - - {{ path }} - + + + {{ extractLabel(path) }} + {{ path }}
@@ -4895,6 +4900,21 @@ const extractUrl = (str: string) => { return urlMatch ? urlMatch[0] : str } +// 从子任务交付路径提取标签(例如 "【TASK...】https://..." -> "下载 TASK...") +const extractLabel = (str: string) => { + // 尝试提取【】中的内容作为标签 + const labelMatch = str.match(/【([^】]+)】/) + if (labelMatch) { + return `下载 ${labelMatch[1]}` + } + return '下载素材' +} + +// 打开交付路径 +const openDeliveryPath = (url: string) => { + window.open(url, '_blank') +} + // 监听配置更新事件 const handleConfigUpdate = async (event: CustomEvent) => { console.log('配置已更新,刷新配置数据:', event.detail) @@ -5587,9 +5607,9 @@ onUnmounted(() => { } .badge-subtask { - background: rgba(24, 144, 255, 0.1); - border: 1px solid rgba(24, 144, 255, 0.3); - color: #1890ff; + background: rgba(49, 240, 139, 0.1); + border: 1px solid rgba(49, 240, 139, 0.3); + color: #31f08b; } .badge-new { @@ -5611,9 +5631,9 @@ onUnmounted(() => { } .badge-assigned { - background: rgba(24, 144, 255, 0.1); - border: 1px solid rgba(24, 144, 255, 0.2); - color: #1890ff; + background: rgba(49, 240, 139, 0.1); + border: 1px solid rgba(49, 240, 139, 0.2); + color: #31f08b; } // 待填写ID状态样式 - 醒目警告色 @@ -5948,8 +5968,8 @@ onUnmounted(() => { } &.in-progress { - background: rgba(24, 144, 255, 0.1); - color: #1890ff; + background: rgba(49, 240, 139, 0.1); + color: #31f08b; } &.pending { @@ -6058,17 +6078,17 @@ onUnmounted(() => { // 进行中状态 &.in-progress { .node-dot { - background: #1890ff; - border-color: #1890ff; - box-shadow: 0 0 10px rgba(24, 144, 255, 0.6); + background: #31f08b; + border-color: #31f08b; + box-shadow: 0 0 10px rgba(49, 240, 139, 0.6); animation: pulse 1.5s ease-in-out infinite; } .node-label { - color: #1890ff; + color: #31f08b; font-weight: 600; } .node-status { - color: #1890ff; + color: #31f08b; } } @@ -6250,12 +6270,12 @@ onUnmounted(() => { flex-wrap: wrap; .prev-assets-btn { - background: rgba(24, 144, 255, 0.1); - border-color: #1890ff; - color: #1890ff; + background: rgba(49, 240, 139, 0.1); + border-color: #31f08b; + color: #31f08b; &:hover { - background: rgba(24, 144, 255, 0.2); + background: rgba(49, 240, 139, 0.2); } } margin-top: $space-md;