418 lines
15 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.designhub.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.designhub.entity.Department;
import com.designhub.entity.Task;
import com.designhub.entity.User;
import com.designhub.mapper.DepartmentMapper;
import com.designhub.mapper.TaskMapper;
import com.designhub.mapper.UserMapper;
import com.designhub.vo.DesignerStatsVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 设计师统计Service
*/
@Service
@RequiredArgsConstructor
public class DesignerService {
private final UserMapper userMapper;
private final TaskMapper taskMapper;
private final DepartmentMapper departmentMapper;
/**
* 获取所有设计师的统计信息
*/
public List<DesignerStatsVO> getAllDesignerStats() {
// 仅获取接单部门(designer/receiving)的用户
List<Long> receivingDeptIds = departmentMapper.selectList(
new LambdaQueryWrapper<Department>()
.eq(Department::getDeptType, "receiving")
.eq(Department::getStatus, 1)
).stream()
.map(Department::getId)
.collect(Collectors.toList());
if (receivingDeptIds.isEmpty()) {
return new ArrayList<>();
}
List<User> designers = userMapper.selectList(
new LambdaQueryWrapper<User>()
.eq(User::getStatus, 1)
.in(User::getDeptId, receivingDeptIds)
);
return designers.stream()
.map(this::buildDesignerStats)
.collect(Collectors.toList());
}
/**
* 获取单个设计师的统计信息
*/
public DesignerStatsVO getDesignerStats(Long userId) {
User user = userMapper.selectById(userId);
if (user == null) {
return null;
}
return buildDesignerStats(user);
}
/**
* 获取排行榜数据(支持按月查询)
*/
public List<DesignerStatsVO> getLeaderboard(String type, Integer limit, String month) {
List<DesignerStatsVO> stats;
// 如果指定了月份,则查询该月份的数据
if (month != null && !month.isEmpty()) {
stats = getDesignerStatsByMonth(month);
} else {
// 否则查询全部数据
stats = getAllDesignerStats();
}
// 根据类型排序
switch (type) {
case "score":
// 积分榜
stats.sort((a, b) -> Integer.compare(
b.getTotalScore() != null ? b.getTotalScore() : 0,
a.getTotalScore() != null ? a.getTotalScore() : 0
));
break;
case "efficiency":
// 效率榜(完成率)
stats.sort((a, b) -> Double.compare(
b.getCompletionRate() != null ? b.getCompletionRate() : 0.0,
a.getCompletionRate() != null ? a.getCompletionRate() : 0.0
));
break;
case "quality":
// 好评榜
stats.sort((a, b) -> {
int countCompare = Integer.compare(
b.getGoodReviewCount() != null ? b.getGoodReviewCount() : 0,
a.getGoodReviewCount() != null ? a.getGoodReviewCount() : 0
);
if (countCompare == 0) {
// 好评数相同时,比较平均评分
return Double.compare(
b.getAvgRating() != null ? b.getAvgRating() : 0.0,
a.getAvgRating() != null ? a.getAvgRating() : 0.0
);
}
return countCompare;
});
break;
case "diligence":
// 勤勉榜(总任务数)
stats.sort((a, b) -> Integer.compare(
b.getTotalTaskCount() != null ? b.getTotalTaskCount() : 0,
a.getTotalTaskCount() != null ? a.getTotalTaskCount() : 0
));
break;
default:
// 默认按积分排序
stats.sort((a, b) -> Integer.compare(
b.getTotalScore() != null ? b.getTotalScore() : 0,
a.getTotalScore() != null ? a.getTotalScore() : 0
));
}
// 限制返回数量
if (limit != null && limit > 0 && stats.size() > limit) {
return stats.subList(0, limit);
}
return stats;
}
/**
* 构建设计师统计信息
*/
private DesignerStatsVO buildDesignerStats(User user) {
DesignerStatsVO stats = new DesignerStatsVO();
// 基本信息
stats.setUserId(user.getId());
stats.setUserName(user.getRealName());
stats.setAvatar(user.getAvatar());
stats.setDeptName(user.getDeptName());
// 查询任务统计
Long userId = user.getId();
// 总接收任务数
Long totalCountLong = taskMapper.selectCount(
new LambdaQueryWrapper<Task>()
.eq(Task::getReceiverId, userId)
);
Integer totalCount = totalCountLong.intValue();
stats.setTotalTaskCount(totalCount);
// 进行中任务数
Long inProgressCountLong = taskMapper.selectCount(
new LambdaQueryWrapper<Task>()
.eq(Task::getReceiverId, userId)
.eq(Task::getStatus, "in_progress")
);
Integer inProgressCount = inProgressCountLong.intValue();
stats.setInProgressCount(inProgressCount);
// 待接单任务数(队列)- 这里应该是用户已接收但还未开始的任务,实际上应该是0
// 因为一旦接收任务,状态就会变成 in_progress
// 队列数可以理解为用户当前可以接的任务数(这个需要从任务大厅查询,这里暂时设为0)
stats.setQueueCount(0);
// 已完成任务数
Long completedCountLong = taskMapper.selectCount(
new LambdaQueryWrapper<Task>()
.eq(Task::getReceiverId, userId)
.eq(Task::getStatus, "completed")
);
Integer completedCount = completedCountLong.intValue();
stats.setCompletedCount(completedCount);
// 延误任务数
Long delayedCountLong = taskMapper.selectCount(
new LambdaQueryWrapper<Task>()
.eq(Task::getReceiverId, userId)
.eq(Task::getIsDelayed, 1)
);
Integer delayedCount = delayedCountLong.intValue();
stats.setDelayedCount(delayedCount);
// 计算完成率
if (totalCount > 0) {
stats.setCompletionRate(completedCount * 100.0 / totalCount);
} else {
stats.setCompletionRate(0.0);
}
// 计算准时率
if (completedCount > 0) {
Integer ontimeCount = completedCount - delayedCount;
stats.setOntimeRate(ontimeCount * 100.0 / completedCount);
} else {
stats.setOntimeRate(0.0);
}
// 查询已完成任务的详细信息(用于计算积分和评分)
List<Task> completedTasks = taskMapper.selectList(
new LambdaQueryWrapper<Task>()
.eq(Task::getReceiverId, userId)
.eq(Task::getStatus, "completed")
);
// 累计获得积分
Integer totalScore = completedTasks.stream()
.mapToInt(task -> task.getScore() != null ? task.getScore() : 0)
.sum();
stats.setTotalScore(totalScore);
// 平均评分
List<Integer> ratings = completedTasks.stream()
.map(Task::getRating)
.filter(rating -> rating != null && rating > 0)
.collect(Collectors.toList());
if (!ratings.isEmpty()) {
double avgRating = ratings.stream()
.mapToInt(Integer::intValue)
.average()
.orElse(0.0);
stats.setAvgRating(avgRating);
// 好评数(5星)
long goodReviewCount = ratings.stream()
.filter(rating -> rating == 5)
.count();
stats.setGoodReviewCount((int) goodReviewCount);
} else {
stats.setAvgRating(0.0);
stats.setGoodReviewCount(0);
}
// 在线状态(简化处理,实际应该通过WebSocket或心跳机制维护)
stats.setOnlineStatus(1);
stats.setLastActiveTime("刚刚");
return stats;
}
/**
* 获取指定月份的设计师统计信息
*/
private List<DesignerStatsVO> getDesignerStatsByMonth(String month) {
// 解析月份 (YYYY-MM)
String[] parts = month.split("-");
if (parts.length != 2) {
return getAllDesignerStats(); // 格式错误时返回全部数据
}
int year = Integer.parseInt(parts[0]);
int monthNum = Integer.parseInt(parts[1]);
// 计算月份的起始和结束时间
String startDate = String.format("%d-%02d-01 00:00:00", year, monthNum);
String endDate;
if (monthNum == 12) {
endDate = String.format("%d-01-01 00:00:00", year + 1);
} else {
endDate = String.format("%d-%02d-01 00:00:00", year, monthNum + 1);
}
// 获取接单部门的设计师列表
List<Long> receivingDeptIds = departmentMapper.selectList(
new LambdaQueryWrapper<Department>()
.eq(Department::getDeptType, "receiving")
.eq(Department::getStatus, 1)
).stream()
.map(Department::getId)
.collect(Collectors.toList());
if (receivingDeptIds.isEmpty()) {
return new ArrayList<>();
}
List<User> designers = userMapper.selectList(
new LambdaQueryWrapper<User>()
.eq(User::getStatus, 1)
.in(User::getDeptId, receivingDeptIds)
);
// 构建每个设计师的月度统计
return designers.stream()
.map(user -> buildDesignerMonthStats(user, startDate, endDate))
.collect(Collectors.toList());
}
/**
* 构建设计师指定月份的统计信息
*/
private DesignerStatsVO buildDesignerMonthStats(User user, String startDate, String endDate) {
DesignerStatsVO stats = new DesignerStatsVO();
// 基本信息
stats.setUserId(user.getId());
stats.setUserName(user.getRealName());
stats.setAvatar(user.getAvatar());
stats.setDeptName(user.getDeptName());
Long userId = user.getId();
// 当月总接收任务数
Long totalCountLong = taskMapper.selectCount(
new LambdaQueryWrapper<Task>()
.eq(Task::getReceiverId, userId)
.ge(Task::getCreateTime, startDate)
.lt(Task::getCreateTime, endDate)
);
stats.setTotalTaskCount(totalCountLong.intValue());
// 当月进行中任务数(实际在月份查询时应该是0,因为查历史月份)
Long inProgressCountLong = taskMapper.selectCount(
new LambdaQueryWrapper<Task>()
.eq(Task::getReceiverId, userId)
.eq(Task::getStatus, "in_progress")
.ge(Task::getCreateTime, startDate)
.lt(Task::getCreateTime, endDate)
);
stats.setInProgressCount(inProgressCountLong.intValue());
stats.setQueueCount(0);
// 当月已完成任务数
Long completedCountLong = taskMapper.selectCount(
new LambdaQueryWrapper<Task>()
.eq(Task::getReceiverId, userId)
.eq(Task::getStatus, "completed")
.ge(Task::getCompleteTime, startDate)
.lt(Task::getCompleteTime, endDate)
);
stats.setCompletedCount(completedCountLong.intValue());
// 当月总积分(已完成任务的积分之和)
List<Task> completedTasks = taskMapper.selectList(
new LambdaQueryWrapper<Task>()
.eq(Task::getReceiverId, userId)
.eq(Task::getStatus, "completed")
.ge(Task::getCompleteTime, startDate)
.lt(Task::getCompleteTime, endDate)
);
Integer totalScore = completedTasks.stream()
.mapToInt(task -> task.getScore() != null ? task.getScore() : 0)
.sum();
stats.setTotalScore(totalScore);
// 当月延期任务数
Long delayedCountLong = taskMapper.selectCount(
new LambdaQueryWrapper<Task>()
.eq(Task::getReceiverId, userId)
.eq(Task::getIsDelayed, 1)
.ge(Task::getCompleteTime, startDate)
.lt(Task::getCompleteTime, endDate)
);
stats.setDelayedCount(delayedCountLong.intValue());
// 计算当月完成率
if (totalCountLong > 0) {
double completionRate = (completedCountLong.doubleValue() / totalCountLong.doubleValue()) * 100;
stats.setCompletionRate(completionRate);
} else {
stats.setCompletionRate(0.0);
}
// 计算当月按时完成率
if (completedCountLong > 0) {
long ontimeCount = completedCountLong - delayedCountLong;
double ontimeRate = (ontimeCount / (double)completedCountLong) * 100;
stats.setOntimeRate(ontimeRate);
} else {
stats.setOntimeRate(0.0);
}
// 当月平均评分
Double avgRating = completedTasks.stream()
.filter(task -> task.getRating() != null && task.getRating() > 0)
.mapToInt(Task::getRating)
.average()
.orElse(0.0);
stats.setAvgRating(avgRating);
// 当月好评数(评分>=4)
long goodReviewCount = completedTasks.stream()
.filter(task -> task.getRating() != null && task.getRating() >= 4)
.count();
stats.setGoodReviewCount((int)goodReviewCount);
// 在线状态(历史月份时设为离线)
stats.setOnlineStatus(0);
stats.setLastActiveTime(null);
return stats;
}
/**
* 获取设计师进行中的任务列表
*/
public List<Task> getDesignerInProgressTasks(Long userId) {
return taskMapper.selectList(
new LambdaQueryWrapper<Task>()
.eq(Task::getReceiverId, userId)
.eq(Task::getStatus, "in_progress")
.orderByDesc(Task::getCreateTime)
);
}
}