40 changed files with 2154 additions and 1281 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,114 @@ |
|||
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; |
|||
} |
|||
|
|||
public Integer getTodayUndone(){ |
|||
if(ObjectUtil.isNotNull(today) && ObjectUtil.isNotNull(todayCompleted)){ |
|||
return today - todayCompleted; |
|||
} |
|||
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,146 @@ |
|||
package com.ccsens.tall.service; |
|||
|
|||
import cn.hutool.core.collection.CollectionUtil; |
|||
import cn.hutool.core.date.DateTime; |
|||
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.Date; |
|||
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) throws Exception { |
|||
//获取全部的数据
|
|||
ChartVo.ProjectOverview projectOverview = sysProjectDao.getOverview(projectId); |
|||
//获取当天零点和二十四点的时间
|
|||
Long startTime = DateUtil.beginOfDay(new Date()).getTime(); |
|||
Long endTime = DateUtil.endOfDay(new Date()).getTime(); |
|||
//获取当天的数据
|
|||
ChartVo.ProjectOverview projectOverview1 = sysProjectDao.getOverviewByToDay(projectId,startTime,endTime); |
|||
//将数据整合在一起
|
|||
projectOverview.setTodayCompleted(projectOverview1.getTodayCompleted() == null ? 0 : projectOverview1.getTodayCompleted()); |
|||
projectOverview.setToday(projectOverview1.getToday()); |
|||
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) throws Exception; |
|||
|
|||
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