增加了工作项完成的时间线变化

master
yang.yongquan 2022-07-10 21:30:37 +08:00
parent 5da87af6e3
commit 0cda29574f
6 changed files with 186 additions and 6 deletions

View File

@ -96,4 +96,16 @@ public class TaskController {
return ResponseMap.ofSuccess(); return ResponseMap.ofSuccess();
} }
@SneakyThrows
@GetMapping("/stats")
public ResponseMap getTaskTrend(
@RequestHeader("Token") String token,
@PathVariable Integer projectId
) {
if(!projectService.checkOpenStatus(projectId)) {
throw new BadRequestException(IProjectService.PROJECT_UNOPENED);
}
return ResponseMap.ofSuccess("查询成功", taskService.getProjectTaskTrend(token, projectId));
}
} }

View File

@ -36,6 +36,7 @@ public class Task {
public static final String STATUS_PROCESSING = "进行中"; public static final String STATUS_PROCESSING = "进行中";
public static final String STATUS_COMPLETED = "已完成"; public static final String STATUS_COMPLETED = "已完成";
public static final String STATUS_CLOSED = "关闭"; public static final String STATUS_CLOSED = "关闭";
public static final String STATUS_UNCLOSED = "未关闭";
@TableId(type = IdType.AUTO) @TableId(type = IdType.AUTO)
private Long taskId; private Long taskId;

View File

@ -1,11 +1,13 @@
package cn.edu.hfut.rmdjzz.projectmanagement.mapper; package cn.edu.hfut.rmdjzz.projectmanagement.mapper;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Task; import cn.edu.hfut.rmdjzz.projectmanagement.entity.Task;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.TaskDTO;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.StaffProcessDTO; import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.StaffProcessDTO;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.TaskDTO;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.TaskTrendDTO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.time.LocalDate;
import java.util.List; import java.util.List;
/** /**
@ -16,4 +18,12 @@ public interface TaskMapper extends BaseMapper<Task> {
List<TaskDTO> selectSubTaskList(@Param("projectId") Integer projectId, @Param("fatherId") Long fatherId); List<TaskDTO> selectSubTaskList(@Param("projectId") Integer projectId, @Param("fatherId") Long fatherId);
List<StaffProcessDTO> selectProjectProcessOfStaff(@Param("projectId") Integer projectId, @Param("staffId") Integer staffId); List<StaffProcessDTO> selectProjectProcessOfStaff(@Param("projectId") Integer projectId, @Param("staffId") Integer staffId);
List<TaskTrendDTO> selectClosedTaskTrendBeforeDate(@Param("projectId") Integer projectId, @Param("startDate") LocalDate startDate);
TaskTrendDTO selectUnclosedTaskTrendBeforeDate(@Param("projectId") Integer projectId, @Param("startDate") LocalDate startDate);
List<TaskTrendDTO> selectTaskClosedNum(@Param("projectId") Integer projectId, @Param("startDate") LocalDate startDate, @Param("endDate") LocalDate endDate);
List<TaskTrendDTO> selectTaskUnclosedNum(@Param("projectId") Integer projectId, @Param("startDate") LocalDate startDate, @Param("endDate") LocalDate endDate);
} }

View File

@ -3,11 +3,13 @@ package cn.edu.hfut.rmdjzz.projectmanagement.service;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Task; import cn.edu.hfut.rmdjzz.projectmanagement.entity.Task;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.StaffProcessDTO; import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.StaffProcessDTO;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.TaskDTO; import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.TaskDTO;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.TaskTrendDTO;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException; import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.ForbiddenException; import cn.edu.hfut.rmdjzz.projectmanagement.exception.ForbiddenException;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* @author * @author
@ -41,4 +43,6 @@ public interface ITaskService extends IService<Task> {
Task insertTask(String token, Task task) throws BadRequestException, ForbiddenException; Task insertTask(String token, Task task) throws BadRequestException, ForbiddenException;
Task modifyTask(String token, Task task) throws BadRequestException, ForbiddenException; Task modifyTask(String token, Task task) throws BadRequestException, ForbiddenException;
Map<String, List<TaskTrendDTO>> getProjectTaskTrend(String token, Integer projectId) throws BadRequestException, ForbiddenException;
} }

View File

@ -3,6 +3,7 @@ package cn.edu.hfut.rmdjzz.projectmanagement.service.impl;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Task; import cn.edu.hfut.rmdjzz.projectmanagement.entity.Task;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.StaffProcessDTO; import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.StaffProcessDTO;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.TaskDTO; import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.TaskDTO;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.TaskTrendDTO;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException; import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.ForbiddenException; import cn.edu.hfut.rmdjzz.projectmanagement.exception.ForbiddenException;
import cn.edu.hfut.rmdjzz.projectmanagement.mapper.TaskMapper; import cn.edu.hfut.rmdjzz.projectmanagement.mapper.TaskMapper;
@ -11,16 +12,16 @@ import cn.edu.hfut.rmdjzz.projectmanagement.service.ITaskService;
import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils; import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -233,10 +234,10 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements IT
typeChangeValue = 2; typeChangeValue = 2;
} }
System.out.println(!task.checkModification(rawTask)); System.out.println(!task.checkModification(rawTask));
if (!task.checkModification(rawTask) || !task.checkInsert() ) { if (!task.checkModification(rawTask) || !task.checkInsert()) {
throw new BadRequestException(BadRequestException.WRONG_PARAMETERS); throw new BadRequestException(BadRequestException.WRONG_PARAMETERS);
} }
if(typeChangeValue == 1 && !canBeDone(task.getTaskId())){ if (typeChangeValue == 1 && !canBeDone(task.getTaskId())) {
throw new BadRequestException("还有子工作尚未完成"); throw new BadRequestException("还有子工作尚未完成");
} }
try { try {
@ -255,4 +256,101 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements IT
} }
return task; return task;
} }
@Override
public Map<String, List<TaskTrendDTO>> getProjectTaskTrend(String token, Integer projectId) throws BadRequestException, ForbiddenException {
if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) {
throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE);
}
LocalDate endDate = LocalDate.now();
LocalDate startDate = endDate.plusDays(-14);
Map<String, List<TaskTrendDTO>> res = new HashMap<>();
List<TaskTrendDTO> resList = getResultTaskStatus(projectId, startDate);
TaskTrendDTO lastTaskTrend = new TaskTrendDTO();
lastTaskTrend.setTaskDate(endDate.plusDays(1));
List<TaskTrendDTO> unclosedList = baseMapper.selectTaskUnclosedNum(projectId, startDate, endDate);
unclosedList.add(lastTaskTrend);
List<TaskTrendDTO> closedList = baseMapper.selectTaskClosedNum(projectId, startDate, endDate);
closedList.add(lastTaskTrend);
for (TaskTrendDTO iterTask : resList) {
List<TaskTrendDTO> taskList = new ArrayList<>();
ListIterator<TaskTrendDTO> closedIter = closedList.listIterator();
ListIterator<TaskTrendDTO> unclosedIter = unclosedList.listIterator();
TaskTrendDTO closedTaskTrend = null;
TaskTrendDTO unclosedTaskTrend = null;
closedTaskTrend = closedIter.next();
unclosedTaskTrend = unclosedIter.next();
Long lastNum = iterTask.getTaskNum();
LocalDate iterDate = startDate;
while (!iterDate.isAfter(endDate)) {
TaskTrendDTO taskTrend = new TaskTrendDTO();
taskTrend.setTaskDate(iterDate);
taskTrend.setTaskStatus(iterTask.getTaskStatus());
taskTrend.setTaskNum(lastNum);
while (true) {
if (iterDate.isBefore(unclosedTaskTrend.getTaskDate())) {
break;
}
taskTrend.changeForUnclosed(unclosedTaskTrend);
if (unclosedIter.hasNext()) {
unclosedTaskTrend = unclosedIter.next();
}
}
while (true) {
if (iterDate.isBefore(closedTaskTrend.getTaskDate())) {
break;
}
taskTrend.changeForClosed(closedTaskTrend);
if (closedIter.hasNext()) {
closedTaskTrend = closedIter.next();
}
}
taskList.add(taskTrend);
iterDate = iterDate.plusDays(1);
lastNum = taskTrend.getTaskNum();
// System.out.println(taskTrend.toString());
}
res.put(iterTask.getTaskStatus(), taskList);
}
return res;
}
private List<TaskTrendDTO> getResultTaskStatus(Integer projectId, LocalDate startDate) {
List<TaskTrendDTO> resList = baseMapper.selectClosedTaskTrendBeforeDate(projectId, startDate);
List<TaskTrendDTO> taskList = new ArrayList<>();
Boolean existClosed = false;
Boolean existCompleted = false;
for(TaskTrendDTO taskTrendDTO: resList) {
if(Objects.equals(Task.STATUS_CLOSED, taskTrendDTO.getTaskStatus())) {
existClosed = true;
}
if(Objects.equals(Task.STATUS_COMPLETED, taskTrendDTO.getTaskStatus())) {
existCompleted = true;
}
taskList.add(taskTrendDTO);
}
if(!existClosed) {
taskList.add(getZeroNumInstance(Task.STATUS_CLOSED));
}
if(!existCompleted) {
taskList.add(getZeroNumInstance(Task.STATUS_COMPLETED));
}
TaskTrendDTO unclosedTask = baseMapper.selectUnclosedTaskTrendBeforeDate(projectId, startDate);
taskList.add(unclosedTask);
return taskList;
}
@NonNull
private TaskTrendDTO getZeroNumInstance(String taskStatus) {
TaskTrendDTO taskTrendDTO = new TaskTrendDTO();
taskTrendDTO.setTaskStatus(taskStatus);
taskTrendDTO.setTaskNum(0L);
return taskTrendDTO;
}
} }

View File

@ -48,4 +48,59 @@
RIGHT JOIN (SELECT DISTINCT task_type FROM task) AS t2 RIGHT JOIN (SELECT DISTINCT task_type FROM task) AS t2
ON t1.task_type = t2.task_type ON t1.task_type = t2.task_type
</select> </select>
<select id="selectTaskClosedNum" resultType="cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.TaskTrendDTO">
SELECT closed_date AS task_date,
task_status,
COUNT(*) AS task_num
FROM (SELECT DATE_FORMAT(task_closed_time, '%Y-%m-%d') AS closed_date,
task_status
FROM task
WHERE task_project_id = #{projectId}
AND is_deleted != true
AND task_closed_time IS NOT NULL) AS T
WHERE (closed_date &gt;= #{startDate}
AND closed_date &lt;= #{endDate})
GROUP BY closed_date, task_status
ORDER BY closed_date
</select>
<select id="selectTaskUnclosedNum" resultType="cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.TaskTrendDTO">
SELECT created_date AS task_date,
task_status,
COUNT(*) AS task_num
FROM (SELECT DATE_FORMAT(task_created_time, '%Y-%m-%d') AS created_date,
task_status
FROM task
WHERE task_project_id = #{projectId}
AND is_deleted != true) AS T
WHERE (created_date &gt;= #{startDate}
AND created_date &lt;= #{endDate})
GROUP BY created_date, task_status
ORDER BY created_date
</select>
<select id="selectClosedTaskTrendBeforeDate"
resultType="cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.TaskTrendDTO">
SELECT task_status,
COUNT(*) AS task_num
FROM (SELECT DATE_FORMAT(task_closed_time, '%Y-%m-%d') AS closed_date,
task_status
FROM task
WHERE task_project_id = #{projectId}
AND is_deleted != true
AND task_closed_time IS NOT NULL) AS T
WHERE closed_date &lt; #{startDate}
GROUP BY task_status
</select>
<select id="selectUnclosedTaskTrendBeforeDate"
resultType="cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.TaskTrendDTO">
SELECT '未关闭' AS task_status,
COUNT(*) AS task_num
FROM (SELECT DATE_FORMAT(task_created_time, '%Y-%m-%d') AS created_date,
DATE_FORMAT(task_closed_time, '%Y-%m-%d') AS closed_date,
task_status
FROM task
WHERE task_project_id = 58
AND !is_deleted) AS T
WHERE created_date &lt; #{startDate}
AND (closed_date IS NULL OR closed_date &gt;= #{startDate})
</select>
</mapper> </mapper>