29 changed files with 1921 additions and 1111 deletions
@ -0,0 +1,26 @@ |
|||||
|
package com.ccsens.tall.bean.dto; |
||||
|
|
||||
|
import io.swagger.annotations.ApiModelProperty; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import javax.validation.constraints.NotEmpty; |
||||
|
import javax.validation.constraints.NotNull; |
||||
|
|
||||
|
@Data |
||||
|
public class ChartDto { |
||||
|
|
||||
|
@Data |
||||
|
public static class ProjectTrendDto{ |
||||
|
@NotNull |
||||
|
@ApiModelProperty("项目id") |
||||
|
private Long projectId; |
||||
|
@NotEmpty |
||||
|
@ApiModelProperty("开始日期") |
||||
|
private String start; |
||||
|
@NotEmpty |
||||
|
@ApiModelProperty("结束日期") |
||||
|
private String end; |
||||
|
@ApiModelProperty("角色id") |
||||
|
private Long roleId; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,107 @@ |
|||||
|
package com.ccsens.tall.bean.vo; |
||||
|
|
||||
|
import cn.hutool.core.collection.CollectionUtil; |
||||
|
import cn.hutool.core.util.ObjectUtil; |
||||
|
import com.fasterxml.jackson.annotation.JsonIgnore; |
||||
|
import io.swagger.annotations.ApiModelProperty; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
import java.util.List; |
||||
|
|
||||
|
@Data |
||||
|
public class ChartVo { |
||||
|
|
||||
|
@Data |
||||
|
public static class ExecutorChart{ |
||||
|
@ApiModelProperty("查询类型") |
||||
|
private int type; |
||||
|
@ApiModelProperty("查询类型") |
||||
|
private List<__ExecutorChart> executorChart; |
||||
|
} |
||||
|
@Data |
||||
|
public static class __ExecutorChart{ |
||||
|
@ApiModelProperty("角色id") |
||||
|
private Long roleId; |
||||
|
@ApiModelProperty("角色名") |
||||
|
private String roleName; |
||||
|
@ApiModelProperty("value") |
||||
|
private Integer value; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@Data |
||||
|
public static class CompleteTaskNum{ |
||||
|
@ApiModelProperty("角色id") |
||||
|
private Long roleId; |
||||
|
@ApiModelProperty("角色名") |
||||
|
private String roleName; |
||||
|
@ApiModelProperty("完成数量") |
||||
|
private Integer value; |
||||
|
@ApiModelProperty("任务总数") |
||||
|
private Integer total; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@Data |
||||
|
public static class ProjectTrendVo { |
||||
|
@ApiModelProperty("日期") |
||||
|
private String date; |
||||
|
@ApiModelProperty("当天任务总数") |
||||
|
private Integer total; |
||||
|
@ApiModelProperty("当天已完成的任务数") |
||||
|
private Integer completed; |
||||
|
} |
||||
|
|
||||
|
@Data |
||||
|
public static class ProjectOverview { |
||||
|
@ApiModelProperty("任务总数") |
||||
|
private Integer total; |
||||
|
@ApiModelProperty("已完成的任务数") |
||||
|
private Integer completed; |
||||
|
@ApiModelProperty("未完成的任务数") |
||||
|
private Integer undone; |
||||
|
@ApiModelProperty("按时完成") |
||||
|
private Integer completedOnTime; |
||||
|
@ApiModelProperty("逾期完成") |
||||
|
private Integer completedOverTime; |
||||
|
@ApiModelProperty("今天任务总数") |
||||
|
private Integer today; |
||||
|
@ApiModelProperty("今日已完成") |
||||
|
private Integer todayCompleted; |
||||
|
@ApiModelProperty("今日未完成") |
||||
|
private Integer todayUndone; |
||||
|
|
||||
|
public Integer getUndone(){ |
||||
|
if(ObjectUtil.isNotNull(total) && ObjectUtil.isNotNull(completed)){ |
||||
|
return total - completed; |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
public Integer getCompletedOverTime(){ |
||||
|
if(ObjectUtil.isNotNull(completed) && ObjectUtil.isNotNull(completedOnTime)){ |
||||
|
return completed - completedOnTime; |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Data |
||||
|
public static class BurnoutFigure { |
||||
|
@ApiModelProperty("日期 MM-DD") |
||||
|
private String date; |
||||
|
@ApiModelProperty("理想的剩余任务数,回出现小数 保留1位小数") |
||||
|
private BigDecimal ideal; |
||||
|
@ApiModelProperty("计划的剩余任务数") |
||||
|
private Integer planned; |
||||
|
@ApiModelProperty("实际的剩余任务数") |
||||
|
private Integer realistic; |
||||
|
@JsonIgnore//任务总数
|
||||
|
private Integer total; |
||||
|
@JsonIgnore//每天的任务数
|
||||
|
private Integer totalDay; |
||||
|
@JsonIgnore//每天完成的任务数量
|
||||
|
private Integer completed; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,135 @@ |
|||||
|
package com.ccsens.tall.service; |
||||
|
|
||||
|
import cn.hutool.core.collection.CollectionUtil; |
||||
|
import cn.hutool.core.date.DateUtil; |
||||
|
import cn.hutool.core.util.ObjectUtil; |
||||
|
import com.ccsens.tall.bean.dto.ChartDto; |
||||
|
import com.ccsens.tall.bean.po.SysProject; |
||||
|
import com.ccsens.tall.bean.vo.ChartVo; |
||||
|
import com.ccsens.tall.persist.dao.SysProjectDao; |
||||
|
import com.ccsens.util.CodeEnum; |
||||
|
import com.ccsens.util.exception.BaseException; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
import java.util.List; |
||||
|
import java.util.concurrent.atomic.AtomicInteger; |
||||
|
import java.util.concurrent.atomic.AtomicReference; |
||||
|
|
||||
|
@Service |
||||
|
public class ChartService implements IChartService{ |
||||
|
@Autowired |
||||
|
private SysProjectDao sysProjectDao; |
||||
|
|
||||
|
/** |
||||
|
* 任务执行者分布图 |
||||
|
* @param currentUserId |
||||
|
* @param type |
||||
|
* @return |
||||
|
*/ |
||||
|
@Override |
||||
|
public ChartVo.ExecutorChart getExecutorChart(Long currentUserId,Long projectId,Integer type) { |
||||
|
SysProject sysProject = sysProjectDao.selectByPrimaryKey(projectId); |
||||
|
if(ObjectUtil.isNull(sysProject)){ |
||||
|
throw new BaseException(CodeEnum.NOT_PROJECT); |
||||
|
} |
||||
|
List<ChartVo.__ExecutorChart> executorChartList = sysProjectDao.getExecutorChart(projectId,type); |
||||
|
ChartVo.ExecutorChart executorChart = new ChartVo.ExecutorChart(); |
||||
|
executorChart.setType(type); |
||||
|
executorChart.setExecutorChart(executorChartList); |
||||
|
return executorChart; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 计划时间内完成任务 |
||||
|
* @param currentUserId |
||||
|
* @param projectId |
||||
|
* @return |
||||
|
*/ |
||||
|
@Override |
||||
|
public List<ChartVo.CompleteTaskNum> getCompleteTaskByTime(Long currentUserId, Long projectId) { |
||||
|
//查找所有角色及任务数量
|
||||
|
List<ChartVo.CompleteTaskNum> completeTaskNumList = sysProjectDao.getCompleteTaskByTime(projectId); |
||||
|
return completeTaskNumList; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 项目进展趋势图 |
||||
|
* @param currentUserId |
||||
|
* @param projectTrendDto |
||||
|
* @return |
||||
|
*/ |
||||
|
@Override |
||||
|
public List<ChartVo.ProjectTrendVo> getProjectTrend(Long currentUserId, ChartDto.ProjectTrendDto projectTrendDto) { |
||||
|
Long start = DateUtil.parse(projectTrendDto.getStart()).getTime(); |
||||
|
Long end = DateUtil.parse(projectTrendDto.getEnd()).getTime(); |
||||
|
List<ChartVo.ProjectTrendVo> projectTrendVoList = sysProjectDao.getProjectTrend(projectTrendDto.getProjectId(),start,end,projectTrendDto.getRoleId()); |
||||
|
return projectTrendVoList; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 概览报表 |
||||
|
* @param currentUserId |
||||
|
* @param projectId |
||||
|
* @return |
||||
|
*/ |
||||
|
@Override |
||||
|
public ChartVo.ProjectOverview getOverview(Long currentUserId, Long projectId) { |
||||
|
ChartVo.ProjectOverview projectOverview = sysProjectDao.getOverview(projectId); |
||||
|
return projectOverview; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 燃尽图 |
||||
|
* @param currentUserId |
||||
|
* @param projectTrendDto |
||||
|
* @return |
||||
|
*/ |
||||
|
@Override |
||||
|
public List<ChartVo.BurnoutFigure> getBurnoutFigure(Long currentUserId, ChartDto.ProjectTrendDto projectTrendDto) { |
||||
|
Long start = DateUtil.parse(projectTrendDto.getStart()).getTime(); |
||||
|
Long end = DateUtil.parse(projectTrendDto.getEnd()).getTime(); |
||||
|
//获取任务总数(如果type传1 查询规定条件内的任务总数,若传null,则按天分组查找)
|
||||
|
List<ChartVo.BurnoutFigure> totalList = sysProjectDao.getBurnoutFigure(projectTrendDto.getProjectId(),start,end,projectTrendDto.getRoleId(),1); |
||||
|
//理想
|
||||
|
AtomicReference<BigDecimal> idealTotal = new AtomicReference<>(); |
||||
|
BigDecimal idealTotalInt = new BigDecimal(0); |
||||
|
//计划
|
||||
|
AtomicInteger plannedTotal = new AtomicInteger(); |
||||
|
//实际
|
||||
|
AtomicInteger realTotal = new AtomicInteger(); |
||||
|
if(CollectionUtil.isNotEmpty(totalList)) { |
||||
|
idealTotal.set(BigDecimal.valueOf(totalList.get(0).getTotalDay())); |
||||
|
idealTotalInt = BigDecimal.valueOf(totalList.get(0).getTotalDay()); |
||||
|
plannedTotal.set(totalList.get(0).getTotalDay()); |
||||
|
realTotal.set(totalList.get(0).getTotalDay()); |
||||
|
} |
||||
|
//按天获取信息
|
||||
|
List<ChartVo.BurnoutFigure> burnoutFigureList = sysProjectDao.getBurnoutFigure(projectTrendDto.getProjectId(),start,end,projectTrendDto.getRoleId(),null); |
||||
|
if(CollectionUtil.isNotEmpty(burnoutFigureList)){ |
||||
|
//每天理想完成数,总数/天数=每天理想完成数
|
||||
|
BigDecimal idealFinish = idealTotalInt.divide(BigDecimal.valueOf(burnoutFigureList.size()),1,BigDecimal.ROUND_HALF_UP); |
||||
|
burnoutFigureList.forEach(burnoutFigure -> { |
||||
|
//理想剩余数量
|
||||
|
idealTotal.set(idealTotal.get().subtract(idealFinish)); |
||||
|
if(idealTotal.get().compareTo(BigDecimal.valueOf(0)) < 1){ |
||||
|
burnoutFigure.setIdeal(BigDecimal.valueOf(0)); |
||||
|
}else { |
||||
|
burnoutFigure.setIdeal(idealTotal.get()); |
||||
|
} |
||||
|
//计划剩余数量
|
||||
|
plannedTotal.set(plannedTotal.get() - burnoutFigure.getTotalDay()); |
||||
|
burnoutFigure.setPlanned(plannedTotal.get()); |
||||
|
//实际剩余数量
|
||||
|
if(ObjectUtil.isNotNull(burnoutFigure.getCompleted())){ |
||||
|
realTotal.set(realTotal.get() - burnoutFigure.getCompleted()); |
||||
|
burnoutFigure.setRealistic(realTotal.get()); |
||||
|
}else{ |
||||
|
burnoutFigure.setRealistic(realTotal.get()); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
return burnoutFigureList; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
package com.ccsens.tall.service; |
||||
|
|
||||
|
import com.ccsens.tall.bean.dto.ChartDto; |
||||
|
import com.ccsens.tall.bean.vo.ChartVo; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public interface IChartService { |
||||
|
ChartVo.ExecutorChart getExecutorChart(Long currentUserId,Long projectId, Integer type); |
||||
|
|
||||
|
List<ChartVo.CompleteTaskNum> getCompleteTaskByTime(Long currentUserId, Long projectId); |
||||
|
|
||||
|
List<ChartVo.ProjectTrendVo> getProjectTrend(Long currentUserId, ChartDto.ProjectTrendDto projectTrendDto); |
||||
|
|
||||
|
ChartVo.ProjectOverview getOverview(Long currentUserId, Long projectId); |
||||
|
|
||||
|
List<ChartVo.BurnoutFigure> getBurnoutFigure(Long currentUserId, ChartDto.ProjectTrendDto projectTrendDto); |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,86 @@ |
|||||
|
package com.ccsens.tall.web; |
||||
|
|
||||
|
import com.ccsens.tall.bean.dto.ChartDto; |
||||
|
import com.ccsens.tall.bean.dto.TaskDto; |
||||
|
import com.ccsens.tall.bean.vo.ChartVo; |
||||
|
import com.ccsens.tall.bean.vo.TaskVo; |
||||
|
import com.ccsens.tall.service.IChartService; |
||||
|
import com.ccsens.util.JsonResponse; |
||||
|
import com.ccsens.util.WebConstant; |
||||
|
import io.jsonwebtoken.Claims; |
||||
|
import io.swagger.annotations.*; |
||||
|
import jdk.internal.dynalink.linker.LinkerServices; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.validation.annotation.Validated; |
||||
|
import org.springframework.web.bind.annotation.*; |
||||
|
|
||||
|
import javax.servlet.http.HttpServletRequest; |
||||
|
import java.util.List; |
||||
|
|
||||
|
@Api(tags = "图表相关API", description = "") |
||||
|
@RestController |
||||
|
@RequestMapping("/charts") |
||||
|
public class ChartController { |
||||
|
@Autowired |
||||
|
private IChartService chartService; |
||||
|
|
||||
|
|
||||
|
@ApiOperation(value = "任务执行者分布图",notes = "") |
||||
|
@ApiImplicitParams({ |
||||
|
}) |
||||
|
@RequestMapping(value = "/executor", method = RequestMethod.GET, produces = {"application/json;charset=UTF-8"}) |
||||
|
public JsonResponse<ChartVo.ExecutorChart> getTasksByTaskId(HttpServletRequest request, |
||||
|
@RequestParam(required = true)Long projectId, |
||||
|
@RequestParam(required = false)Integer type) throws Exception{ |
||||
|
type = type == null ? 0 : type; |
||||
|
Long currentUserId = Long.valueOf(((Claims) request.getAttribute(WebConstant.REQUEST_KEY_CLAIMS)).getSubject()); |
||||
|
ChartVo.ExecutorChart executorChart = chartService.getExecutorChart(currentUserId,projectId,type); |
||||
|
return JsonResponse.newInstance().ok(executorChart); |
||||
|
} |
||||
|
|
||||
|
@ApiOperation(value = "计划时间内完成任务",notes = "") |
||||
|
@ApiImplicitParams({ |
||||
|
}) |
||||
|
@RequestMapping(value = "/complete", method = RequestMethod.GET, produces = {"application/json;charset=UTF-8"}) |
||||
|
public JsonResponse<List<ChartVo.CompleteTaskNum>> getCompleteTaskByTime(HttpServletRequest request, |
||||
|
@RequestParam(required = true)Long projectId) throws Exception{ |
||||
|
Long currentUserId = Long.valueOf(((Claims) request.getAttribute(WebConstant.REQUEST_KEY_CLAIMS)).getSubject()); |
||||
|
List<ChartVo.CompleteTaskNum> completeTaskNumList = chartService.getCompleteTaskByTime(currentUserId,projectId); |
||||
|
return JsonResponse.newInstance().ok(completeTaskNumList); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@ApiOperation(value = "项目进展趋势图",notes = "") |
||||
|
@ApiImplicitParams({ |
||||
|
}) |
||||
|
@RequestMapping(value = "/trend", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) |
||||
|
public JsonResponse<List<ChartVo.ProjectTrendVo>> getProjectTrend(HttpServletRequest request, |
||||
|
@Validated @RequestBody ChartDto.ProjectTrendDto projectTrendDto) throws Exception{ |
||||
|
Long currentUserId = Long.valueOf(((Claims) request.getAttribute(WebConstant.REQUEST_KEY_CLAIMS)).getSubject()); |
||||
|
List<ChartVo.ProjectTrendVo> projectTrendVoList = chartService.getProjectTrend(currentUserId,projectTrendDto); |
||||
|
return JsonResponse.newInstance().ok(projectTrendVoList); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@ApiOperation(value = "概览报表",notes = "") |
||||
|
@ApiImplicitParams({ |
||||
|
}) |
||||
|
@RequestMapping(value = "/overview", method = RequestMethod.GET, produces = {"application/json;charset=UTF-8"}) |
||||
|
public JsonResponse<ChartVo.ProjectOverview> getOverview(HttpServletRequest request, |
||||
|
@RequestParam(required = true)Long projectId) throws Exception{ |
||||
|
Long currentUserId = Long.valueOf(((Claims) request.getAttribute(WebConstant.REQUEST_KEY_CLAIMS)).getSubject()); |
||||
|
ChartVo.ProjectOverview projectOverview = chartService.getOverview(currentUserId,projectId); |
||||
|
return JsonResponse.newInstance().ok(projectOverview); |
||||
|
} |
||||
|
|
||||
|
@ApiOperation(value = "燃尽图",notes = "") |
||||
|
@ApiImplicitParams({ |
||||
|
}) |
||||
|
@RequestMapping(value = "/burnout", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) |
||||
|
public JsonResponse<List<ChartVo.BurnoutFigure>> getBurnoutFigure(HttpServletRequest request, |
||||
|
@Validated @RequestBody ChartDto.ProjectTrendDto projectTrendDto) throws Exception{ |
||||
|
Long currentUserId = Long.valueOf(((Claims) request.getAttribute(WebConstant.REQUEST_KEY_CLAIMS)).getSubject()); |
||||
|
List<ChartVo.BurnoutFigure> burnoutFigure = chartService.getBurnoutFigure(currentUserId,projectTrendDto); |
||||
|
return JsonResponse.newInstance().ok(burnoutFigure); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue