|
|
@@ -0,0 +1,110 @@
|
|
|
+package com.zxyj.service;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.zxyj.entity.Child;
|
|
|
+import com.zxyj.entity.Task;
|
|
|
+import com.zxyj.mapper.ChildMapper;
|
|
|
+import com.zxyj.mapper.TaskMapper;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class TaskStatsService {
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private TaskMapper taskMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private ChildMapper childMapper;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取单个孩子的任务完成统计
|
|
|
+ */
|
|
|
+ public Map<String, Object> getChildStats(Long childId, Date startDate, Date endDate) {
|
|
|
+ List<Task> tasks = queryTasks(null, childId, startDate, endDate);
|
|
|
+ return buildStats(tasks, null, childId);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取家庭维度的任务完成统计
|
|
|
+ */
|
|
|
+ public Map<String, Object> getFamilyStats(Long familyId, Date startDate, Date endDate) {
|
|
|
+ List<Task> tasks = queryTasks(familyId, null, startDate, endDate);
|
|
|
+ Map<String, Object> stats = buildStats(tasks, familyId, null);
|
|
|
+
|
|
|
+ // 按孩子分组
|
|
|
+ List<Child> children = childMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<Child>().eq(Child::getFamilyId, familyId));
|
|
|
+ List<Map<String, Object>> byChild = new ArrayList<>();
|
|
|
+ for (Child child : children) {
|
|
|
+ List<Task> childTasks = tasks.stream()
|
|
|
+ .filter(t -> child.getId().equals(t.getChildId()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ if (!childTasks.isEmpty()) {
|
|
|
+ Map<String, Object> childStat = new HashMap<>();
|
|
|
+ childStat.put("childId", child.getId());
|
|
|
+ childStat.put("childName", child.getNickname());
|
|
|
+ childStat.put("totalTasks", childTasks.size());
|
|
|
+ long completed = childTasks.stream().filter(t -> "completed".equals(t.getStatus())).count();
|
|
|
+ childStat.put("completedTasks", completed);
|
|
|
+ childStat.put("completionRate", childTasks.size() > 0 ? Math.round(completed * 1000.0 / childTasks.size()) / 10.0 : 0);
|
|
|
+ byChild.add(childStat);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ stats.put("byChild", byChild);
|
|
|
+ return stats;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询指定范围的任务(排除模板任务和已取消的)
|
|
|
+ */
|
|
|
+ private List<Task> queryTasks(Long familyId, Long childId, Date startDate, Date endDate) {
|
|
|
+ LambdaQueryWrapper<Task> wrapper = new LambdaQueryWrapper<Task>()
|
|
|
+ .ne(Task::getIsTemplate, 1)
|
|
|
+ .ne(Task::getStatus, "cancelled");
|
|
|
+
|
|
|
+ if (familyId != null) {
|
|
|
+ wrapper.eq(Task::getFamilyId, familyId);
|
|
|
+ }
|
|
|
+ if (childId != null) {
|
|
|
+ wrapper.eq(Task::getChildId, childId);
|
|
|
+ }
|
|
|
+ if (startDate != null) {
|
|
|
+ wrapper.ge(Task::getCreatedAt, startDate);
|
|
|
+ }
|
|
|
+ if (endDate != null) {
|
|
|
+ wrapper.le(Task::getCreatedAt, endDate);
|
|
|
+ }
|
|
|
+ wrapper.orderByDesc(Task::getCreatedAt);
|
|
|
+
|
|
|
+ return taskMapper.selectList(wrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建统计结果
|
|
|
+ */
|
|
|
+ private Map<String, Object> buildStats(List<Task> tasks, Long familyId, Long childId) {
|
|
|
+ Date now = new Date();
|
|
|
+ int total = tasks.size();
|
|
|
+ long completed = tasks.stream().filter(t -> "completed".equals(t.getStatus())).count();
|
|
|
+ long pending = tasks.stream().filter(t -> "pending".equals(t.getStatus())).count();
|
|
|
+ long overdue = tasks.stream()
|
|
|
+ .filter(t -> "pending".equals(t.getStatus()) && t.getDeadline() != null && t.getDeadline().before(now))
|
|
|
+ .count();
|
|
|
+
|
|
|
+ double rate = total > 0 ? Math.round(completed * 1000.0 / total) / 10.0 : 0;
|
|
|
+
|
|
|
+ Map<String, Object> result = new LinkedHashMap<>();
|
|
|
+ result.put("totalTasks", total);
|
|
|
+ result.put("completedTasks", completed);
|
|
|
+ result.put("pendingTasks", pending);
|
|
|
+ result.put("overdueTasks", overdue);
|
|
|
+ result.put("completionRate", rate);
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+}
|