diff --git a/backend/src/main/java/com/designhub/controller/TaskController.java b/backend/src/main/java/com/designhub/controller/TaskController.java index e73be33..661c5d2 100644 --- a/backend/src/main/java/com/designhub/controller/TaskController.java +++ b/backend/src/main/java/com/designhub/controller/TaskController.java @@ -314,11 +314,12 @@ public class TaskController { @GetMapping("/dashboard/stats") public Result getDashboardStats( @Parameter(description = "月份,格式:YYYY-MM,不传则查询当月") @RequestParam(required = false) String month, + @Parameter(description = "指定部门ID(部门负责人切换视角时使用)") @RequestParam(required = false) Long deptId, @RequestHeader("Authorization") String authHeader) { String token = jwtUtil.extractTokenFromHeader(authHeader); Long userId = jwtUtil.getUserIdFromToken(token); - log.info("获取工作台统计数据: userId={}, month={}", userId, month); - return Result.success(taskService.getDashboardStats(userId, month)); + log.info("获取工作台统计数据: userId={}, month={}, deptId={}", userId, month, deptId); + return Result.success(taskService.getDashboardStats(userId, month, deptId)); } @Operation(summary = "获取我的进行中任务") diff --git a/backend/src/main/java/com/designhub/service/TaskService.java b/backend/src/main/java/com/designhub/service/TaskService.java index b83780c..c035f48 100644 --- a/backend/src/main/java/com/designhub/service/TaskService.java +++ b/backend/src/main/java/com/designhub/service/TaskService.java @@ -1784,14 +1784,30 @@ public class TaskService { /** * 获取工作台统计数据 */ - public DashboardStatsVO getDashboardStats(Long userId, String month) { + public DashboardStatsVO getDashboardStats(Long userId, String month, Long deptId) { try { // 获取用户角色,判断是否为管理员 List roles = roleService.getRolesByUserId(userId); boolean isAdmin = roles.stream() .anyMatch(role -> "ADMIN".equals(role.getRoleCode()) || "SUPER_ADMIN".equals(role.getRoleCode())); - log.info("获取工作台统计数据: userId={}, isAdmin={}, month={}", userId, isAdmin, month); + // 检查是否是部门负责人切换视角(传入了deptId) + boolean isDeptView = deptId != null; + List deptAndChildIds = null; + String deptType = null; + + if (isDeptView) { + // 获取指定部门及其所有子部门 + deptAndChildIds = getDeptAndChildIds(deptId); + // 获取部门类型 + Department dept = departmentMapper.selectById(deptId); + if (dept != null) { + deptType = dept.getDeptType(); + } + log.info("部门负责人视角: deptId={}, deptType={}, childDeptCount={}", deptId, deptType, deptAndChildIds.size()); + } + + log.info("获取工作台统计数据: userId={}, isAdmin={}, month={}, deptId={}", userId, isAdmin, month, deptId); // 解析月份,如果不传则使用当前月份 LocalDate targetMonth; @@ -1828,28 +1844,63 @@ public class TaskService { LocalDateTime lastWeekEndTime = LocalDateTime.of(lastWeekEnd, LocalTime.MAX); // 进行中的任务数 - LambdaQueryWrapper inProgressQuery = new LambdaQueryWrapper() - .eq(Task::getStatus, "in_progress"); - if (!isAdmin) { - inProgressQuery.eq(Task::getReceiverId, userId); + Long inProgressCount = 0L; + if (isDeptView && "receiving".equals(deptType)) { + // 接单部门视角:统计该部门(含子部门)设计师接单的任务 + inProgressCount = taskMapper.selectCount(new LambdaQueryWrapper() + .eq(Task::getStatus, "in_progress") + .in(Task::getReceiverDeptId, deptAndChildIds)); + } else if (isDeptView && "demand".equals(deptType)) { + // 需求部门视角:统计该部门发起的任务 + inProgressCount = taskMapper.selectCount(new LambdaQueryWrapper() + .eq(Task::getStatus, "in_progress") + .in(Task::getPublisherDeptId, deptAndChildIds)); + } else if (!isAdmin) { + inProgressCount = taskMapper.selectCount(new LambdaQueryWrapper() + .eq(Task::getStatus, "in_progress") + .eq(Task::getReceiverId, userId)); + } else { + inProgressCount = taskMapper.selectCount(new LambdaQueryWrapper() + .eq(Task::getStatus, "in_progress")); } - Long inProgressCount = taskMapper.selectCount(inProgressQuery); // 已完成的任务数 - LambdaQueryWrapper completedQuery = new LambdaQueryWrapper() - .eq(Task::getStatus, "completed"); - if (!isAdmin) { - completedQuery.eq(Task::getReceiverId, userId); + Long completedCount = 0L; + if (isDeptView && "receiving".equals(deptType)) { + completedCount = taskMapper.selectCount(new LambdaQueryWrapper() + .eq(Task::getStatus, "completed") + .in(Task::getReceiverDeptId, deptAndChildIds)); + } else if (isDeptView && "demand".equals(deptType)) { + completedCount = taskMapper.selectCount(new LambdaQueryWrapper() + .eq(Task::getStatus, "completed") + .in(Task::getPublisherDeptId, deptAndChildIds)); + } else if (!isAdmin) { + completedCount = taskMapper.selectCount(new LambdaQueryWrapper() + .eq(Task::getStatus, "completed") + .eq(Task::getReceiverId, userId)); + } else { + completedCount = taskMapper.selectCount(new LambdaQueryWrapper() + .eq(Task::getStatus, "completed")); } - Long completedCount = taskMapper.selectCount(completedQuery); // 待审核的任务数 - LambdaQueryWrapper reviewQuery = new LambdaQueryWrapper() - .eq(Task::getStatus, "review"); - if (!isAdmin) { - reviewQuery.eq(Task::getReceiverId, userId); + Long reviewCount = 0L; + if (isDeptView && "receiving".equals(deptType)) { + reviewCount = taskMapper.selectCount(new LambdaQueryWrapper() + .eq(Task::getStatus, "review") + .in(Task::getReceiverDeptId, deptAndChildIds)); + } else if (isDeptView && "demand".equals(deptType)) { + reviewCount = taskMapper.selectCount(new LambdaQueryWrapper() + .eq(Task::getStatus, "review") + .in(Task::getPublisherDeptId, deptAndChildIds)); + } else if (!isAdmin) { + reviewCount = taskMapper.selectCount(new LambdaQueryWrapper() + .eq(Task::getStatus, "review") + .eq(Task::getReceiverId, userId)); + } else { + reviewCount = taskMapper.selectCount(new LambdaQueryWrapper() + .eq(Task::getStatus, "review")); } - Long reviewCount = taskMapper.selectCount(reviewQuery); // 今日开始的任务数 LambdaQueryWrapper todayStartedQuery = new LambdaQueryWrapper() @@ -1924,13 +1975,30 @@ public class TaskService { .mapToInt(t -> t.getScoreReward().intValue()) .sum(); - // 获取当前用户当月发布的任务数 - LambdaQueryWrapper publishedQuery = new LambdaQueryWrapper() - .eq(Task::getPublisherId, userId) - .ge(Task::getCreateTime, monthStart) - .le(Task::getCreateTime, monthEnd) - .eq(Task::getDeleted, 0); - Long publishedCount = taskMapper.selectCount(publishedQuery); + // 获取当月发布的任务数 + Long publishedCount = 0L; + if (isDeptView && "demand".equals(deptType)) { + // 需求部门视角:统计该部门发起的任务数 + publishedCount = taskMapper.selectCount(new LambdaQueryWrapper() + .in(Task::getPublisherDeptId, deptAndChildIds) + .ge(Task::getCreateTime, monthStart) + .le(Task::getCreateTime, monthEnd) + .eq(Task::getDeleted, 0)); + } else if (isDeptView && "receiving".equals(deptType)) { + // 接单部门视角:统计该部门接单的任务数 + publishedCount = taskMapper.selectCount(new LambdaQueryWrapper() + .in(Task::getReceiverDeptId, deptAndChildIds) + .ge(Task::getCreateTime, monthStart) + .le(Task::getCreateTime, monthEnd) + .eq(Task::getDeleted, 0)); + } else { + // 当前用户发布的任务数 + publishedCount = taskMapper.selectCount(new LambdaQueryWrapper() + .eq(Task::getPublisherId, userId) + .ge(Task::getCreateTime, monthStart) + .le(Task::getCreateTime, monthEnd) + .eq(Task::getDeleted, 0)); + } DashboardStatsVO result = DashboardStatsVO.builder() .availableCount(availableCount.intValue()) @@ -2527,5 +2595,30 @@ public class TaskService { } } } + + /** + * 获取指定部门及其所有子部门的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 LambdaQueryWrapper() + .eq(Department::getParentId, parentId) + .eq(Department::getStatus, 1) + ); + for (Department child : children) { + result.add(child.getId()); + collectChildDeptIds(child.getId(), result); + } + } } diff --git a/frontend/src/api/task.ts b/frontend/src/api/task.ts index fbd1b39..06974ce 100644 --- a/frontend/src/api/task.ts +++ b/frontend/src/api/task.ts @@ -343,7 +343,7 @@ export interface DashboardStats { /** * 获取工作台统计数据 */ -export const getDashboardStats = (params?: { month?: string }) => { +export const getDashboardStats = (params?: { month?: string; deptId?: number }) => { return request.get('/tasks/dashboard/stats', { params }) } diff --git a/frontend/src/views/TaskHall.vue b/frontend/src/views/TaskHall.vue index d62546a..dd416fd 100644 --- a/frontend/src/views/TaskHall.vue +++ b/frontend/src/views/TaskHall.vue @@ -3930,7 +3930,13 @@ const handlePublishedFiltersReset = () => { const loadDashboardStats = async () => { try { const month = selectedMonth.value?.format('YYYY-MM') - const response = await taskApi.getDashboardStats(month ? { month } : undefined) + const params: { month?: string; deptId?: number } = {} + if (month) params.month = month + // 如果切换了部门视角,传递部门ID + if (currentDeptView.value !== undefined) { + params.deptId = currentDeptView.value + } + const response = await taskApi.getDashboardStats(Object.keys(params).length > 0 ? params : undefined) if (response.code === 200) { const data = response.data dataCards.value[0].value = data.publishedCount || 0 // 发布的任务数(当月)