feat(工作台统计): 我的产品、我的产品数据统计

This commit is contained in:
liuhuazhong 2024-12-11 16:35:34 +08:00
parent d836f0f95d
commit ffc71ba7b6
12 changed files with 293 additions and 3 deletions

View File

@ -1,6 +1,7 @@
package com.microservices.pms.dashboard.controller;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.domain.R;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.core.utils.bean.BeanUtils;
import com.microservices.common.core.web.controller.BaseController;
@ -11,9 +12,13 @@ import com.microservices.pms.dashboard.domain.vo.MyDashboardVo;
import com.microservices.pms.dashboard.domain.vo.MyProjectIssuesSearchVo;
import com.microservices.pms.product.domain.PmsProduct;
import com.microservices.pms.product.domain.PmsProductRequirement;
import com.microservices.pms.product.domain.vo.PmsProductSearchVo;
import com.microservices.pms.product.domain.PmsProductStatus;
import com.microservices.pms.product.domain.enums.ProductReqStatus;
import com.microservices.pms.product.domain.vo.*;
import com.microservices.pms.product.service.IPmsProductPlanService;
import com.microservices.pms.product.service.IPmsProductRequirementService;
import com.microservices.pms.product.service.IPmsProductService;
import com.microservices.pms.product.service.IPmsProductStatusService;
import com.microservices.pms.project.domain.PmsProject;
import com.microservices.pms.project.domain.vo.*;
import com.microservices.pms.project.service.IPmsProjectService;
@ -24,13 +29,16 @@ import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@RestController
@RequestMapping("/{enterpriseIdentifier}/dashboard")
@ -53,6 +61,12 @@ public class PmsDashboardController extends BaseController {
@Autowired
private IPmsProductService pmsProductService;
@Autowired
private IPmsProductPlanService pmsProductPlanService;
@Autowired
private IPmsProductStatusService pmsProductStatusService;
/**
* 我的工作台统计信息
@ -128,4 +142,141 @@ public class PmsDashboardController extends BaseController {
pmsProjectSprintSearchVo.setPmsProjectIds(StringUtils.join(projectList.stream().map(PmsProject::getId).toArray(), ","));
return pmsProjectSprintService.selectAllPmsProjectSprintList(pmsProjectSprintSearchVo);
}
/**
* 我的产品
*/
@ApiOperation(value = "我的产品")
@GetMapping("/myProduct")
public GenericsTableDataInfo<PmsProductStatVo> myProduct(@PathVariable String enterpriseIdentifier,
@Validated PmsProductSearchVo pmsProductSearchVo) {
startPage();
pmsProductSearchVo.setPmsEnterpriseIdentifier(enterpriseIdentifier);
//获取组织下所有的产品信息
GenericsTableDataInfo<PmsProductDataVo> productsInfo = pmsProductService.selectPmsProductPageList(pmsProductSearchVo);
List<PmsProductDataVo> rows = productsInfo.getRows();
// 统计需求数量
List<PmsProductStatVo> statVos = rows.stream().map(e -> {
PmsProductStatVo statVo = new PmsProductStatVo();
String pmsProductIdentifier = e.getProductIdentifier();
Integer requirementCount = pmsProductRequirementService.countByIdentifierAndStatus(pmsProductIdentifier, getUserReqList());
Integer reqSpecsCount = pmsProductRequirementService.countByIdentifierAndStatus(pmsProductIdentifier, getReqSpecsList());
BeanUtils.copyProperties(e, statVo);
statVo.setReqSpecsCount(reqSpecsCount);
statVo.setUserReqCount(requirementCount);
return statVo;
}).collect(Collectors.toList());
GenericsTableDataInfo<PmsProductStatVo> result = new GenericsTableDataInfo<>();
result.setRows(statVos);
result.setTotal(productsInfo.getTotal());
return result;
}
@ApiOperation(value = "我的产品数据统计-用户需求统计")
@ApiImplicitParam(name = "productIdentifier", value = "产品标识", paramType = "query", dataType = "String")
@GetMapping("/userRequirementStat")
public R<PmsRequirementStatResVo> UserRequirementStat(String productIdentifier){
PmsRequirementStatResVo pmsRequirementStatResVo = buildPmsRequirementStatResVo(
productIdentifier,
getUserReqList(),
ProductReqStatus.REVIEWED_USER_REQ);
return R.ok(pmsRequirementStatResVo);
}
@ApiOperation(value = "我的产品数据统计-需求规格统计")
@ApiImplicitParam(name = "productIdentifier", value = "产品标识", paramType = "query", dataType = "String")
@GetMapping("/productRequirementSpecsStat")
public R<PmsRequirementStatResVo> ProductRequirementSpecsStat(String productIdentifier){
PmsRequirementStatResVo pmsRequirementStatResVo = buildPmsRequirementStatResVo(
productIdentifier,
getReqSpecsList(),
ProductReqStatus.REVIEWED_REQ_SPECS);
return R.ok(pmsRequirementStatResVo);
}
@ApiOperation(value = "我的产品数据统计-里程碑状态分布统计")
@ApiImplicitParam(name = "productIdentifier", value = "产品标识", paramType = "query", dataType = "String")
@GetMapping("/milestoneStatusStat")
public R<PmsRequirementStatResVo> milestoneStatusStat(String productIdentifier){
Map<String, Integer> status2NumMap = pmsProductPlanService.countPmsProductPlanGroupByStatus(productIdentifier)
.stream().collect(Collectors.toMap(EnumCommonVo::getKey, ReqStatusStatVo::getNum));
PmsProductStatus pmsProductStatus = new PmsProductStatus();
pmsProductStatus.setType(1);
List<PmsTypeDataVo> pmsTypeDataVos = pmsProductStatusService.selectPmsProductStatusList(pmsProductStatus);
List<ReqStatusStatVo> statusStatVos = pmsTypeDataVos.stream().map(e -> {
ReqStatusStatVo vo = new ReqStatusStatVo();
vo.setKey(String.valueOf(e.getId()));
vo.setNum(status2NumMap.getOrDefault(String.valueOf(e.getId()), 0));
vo.setName(e.getName());
return vo;
}).collect(Collectors.toList());
PmsRequirementStatResVo resVo = new PmsRequirementStatResVo();
resVo.setPmsProductStatVos(statusStatVos);
resVo.setRatio(0);
return R.ok(resVo);
}
/**
* 获取 需求规格状态list
* @return 需求规格状态list
*/
private List<String> getReqSpecsList() {
return Stream.of(ProductReqStatus.PENDING_REVIEW_REQ_SPECS.getKey(),
ProductReqStatus.PLANNED_REQ_SPECS.getKey(),
ProductReqStatus.REJECTED_CHANGE_REQ_SPECS.getKey(),
ProductReqStatus.REVIEWED_REQ_SPECS.getKey(),
ProductReqStatus.COMPLETED_REQ_SPECS.getKey(),
ProductReqStatus.CHANGED_REQ_SPECS.getKey())
.collect(Collectors.toList());
}
/**
* 获取 用户需求状态list
* @return 用户需求状态list
*/
private List<String> getUserReqList() {
return Stream.of(ProductReqStatus.PENDING_REVIEW_USER_REQ.getKey(),
ProductReqStatus.REJECTED_USER_REQ.getKey(),
ProductReqStatus.REVIEWED_USER_REQ.getKey())
.collect(Collectors.toList());
}
/**
* 拼接统计返回结果
* @param productIdentifier 产品标识
* @param statusList 状态列表
* @param productReqStatus x
* @return
*/
private PmsRequirementStatResVo buildPmsRequirementStatResVo(String productIdentifier,List<String> statusList, ProductReqStatus productReqStatus) {
Map<String, Integer> status2NumMap = pmsProductRequirementService
.selectReqCountGroupByStatus(productIdentifier, statusList)
.stream().collect(Collectors.toMap(EnumCommonVo::getKey, ReqStatusStatVo::getNum));
//组装各个状态的数量
List<ReqStatusStatVo> statusStatVos = statusList.stream().map(e -> {
ReqStatusStatVo vo = new ReqStatusStatVo();
vo.setKey(e);
vo.setNum(status2NumMap.getOrDefault(e, 0));
vo.setName(ProductReqStatus.getByKey(e).getName());
return vo;
}).collect(Collectors.toList());
PmsRequirementStatResVo resVo = new PmsRequirementStatResVo();
resVo.setPmsProductStatVos(statusStatVos);
resVo.setRatio(0);
//计算 各自的比率
int sum = statusStatVos.stream().mapToInt(ReqStatusStatVo::getNum).sum();
if (sum > 0){
Integer reviewedUserReqCount = status2NumMap.getOrDefault(productReqStatus.getName(), 0);
resVo.setRatio(reviewedUserReqCount/sum * 100);
}
return resVo;
}
}

View File

@ -0,0 +1,18 @@
package com.microservices.pms.product.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel("我的产品统计对象")
public class PmsProductStatVo extends PmsProductDataVo{
@ApiModelProperty(value = "用户需求数量")
private Integer userReqCount;
@ApiModelProperty(value = "规格需求数量")
private Integer ReqSpecsCount;
}

View File

@ -0,0 +1,15 @@
package com.microservices.pms.product.domain.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
public class PmsRequirementStatResVo {
@ApiModelProperty(value = "数据统计列表")
private List<ReqStatusStatVo> pmsProductStatVos;
@ApiModelProperty(value = "统计的比率")
private Integer ratio;
}

View File

@ -0,0 +1,15 @@
package com.microservices.pms.product.domain.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* @author OTTO
*/
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
public class ReqStatusStatVo extends EnumCommonVo {
private Integer num;
}

View File

@ -1,7 +1,9 @@
package com.microservices.pms.product.mapper;
import com.microservices.pms.product.domain.PmsProductPlan;
import com.microservices.pms.product.domain.vo.ReqStatusStatVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
@ -83,4 +85,11 @@ public interface PmsProductPlanMapper
* @param productIdentifier 产品标识
*/
void deletePmsProductPlanByProductIdentifier(String productIdentifier);
/**
* 根据状态分组统计
* @param productIdentifier 产品标识
* @return 分组统计结果列表
*/
List<ReqStatusStatVo> countPmsProductPlanGroupByStatus(@Param("productIdentifier") String productIdentifier);
}

View File

@ -4,10 +4,12 @@ import com.microservices.pms.product.domain.PmsProductRequirement;
import com.microservices.pms.product.domain.vo.PmsProductRequirementBatchUpdateVo;
import com.microservices.pms.product.domain.vo.ProductReqSpecsSearchVo;
import com.microservices.pms.product.domain.vo.ProductUserReqSearchVo;
import com.microservices.pms.product.domain.vo.ReqStatusStatVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* 产品需求Mapper接口
@ -110,4 +112,8 @@ public interface PmsProductRequirementMapper
List<PmsProductRequirement> selectReqSpecsList(ProductReqSpecsSearchVo productReqSpecsSearchVo);
Integer selectReqSpecsCountByIdentifier(@Param("identifier") String identifier);
Integer countByIdentifierAndStatus(@Param("pmsProductIdentifier") String pmsProductIdentifier, @Param("statusList") List<String> statusList);
List<ReqStatusStatVo> selectReqCountGroupByStatus(@Param("pmsProductIdentifier") String pmsProductIdentifier, @Param("statusList") List<String> statusList);
}

View File

@ -3,6 +3,9 @@ package com.microservices.pms.product.service;
import com.microservices.common.core.web.page.GenericsTableDataInfo;
import com.microservices.pms.product.domain.PmsProductPlan;
import com.microservices.pms.product.domain.vo.PmsProductPlanDataVo;
import com.microservices.pms.product.domain.vo.ReqStatusStatVo;
import java.util.List;
/**
* 产品计划Service接口
@ -89,4 +92,11 @@ public interface IPmsProductPlanService
* @param productIdentifier 产品标识
*/
void deletePmsProductPlanByProductIdentifier(String productIdentifier);
/**
* 根据状态分组统计
* @param productIdentifier 产品标识
* @return 分组统计结果列表
*/
List<ReqStatusStatVo> countPmsProductPlanGroupByStatus(String productIdentifier);
}

View File

@ -125,4 +125,13 @@ public interface IPmsProductRequirementService
List<EnumCommonVo> selectReqSpecsTypeList();
JSONObject selectReqSpecsAssociatedPlanData(Long reqSpecsId);
Integer countByIdentifierAndStatus(String pmsProductIdentifier, List<String> statusList);
/**
*
* @param pmsProductIdentifier 项目标识
* @param statusList 项目对应的类型
* @return List<ReqStatusStatVo>
*/
List<ReqStatusStatVo> selectReqCountGroupByStatus(String pmsProductIdentifier, List<String> statusList);
}

View File

@ -8,6 +8,7 @@ import com.microservices.common.security.utils.SecurityUtils;
import com.microservices.pms.product.domain.PmsProduct;
import com.microservices.pms.product.domain.PmsProductPlan;
import com.microservices.pms.product.domain.vo.PmsProductPlanDataVo;
import com.microservices.pms.product.domain.vo.ReqStatusStatVo;
import com.microservices.pms.product.mapper.PmsProductPlanMapper;
import com.microservices.pms.product.service.*;
import com.microservices.pms.utils.PmsConstants;
@ -19,6 +20,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
/**
* 产品计划Service业务层处理
@ -236,4 +238,10 @@ public class PmsProductPlanServiceImpl implements IPmsProductPlanService {
, pmsProductPlan.getPmsProductIdentifier()));
return pmsProductPlanDataVo;
}
@Override
public List<ReqStatusStatVo> countPmsProductPlanGroupByStatus(String productIdentifier) {
return pmsProductPlanMapper.countPmsProductPlanGroupByStatus(productIdentifier);
}
}

View File

@ -36,8 +36,7 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.*;
import java.util.regex.Pattern;
import static com.microservices.common.core.utils.PageUtils.startPage;
@ -947,4 +946,27 @@ public class PmsProductRequirementServiceImpl implements IPmsProductRequirementS
throw new ServiceException("该模块不属于当前产品(模块名称[%s],产品名称[%s])", pmsProductModule.getModuleName(), pmsProduct.getProductName());
}
}
@Override
public Integer countByIdentifierAndStatus(String pmsProductIdentifier, List<String> statusList) {
if (StringUtils.isEmpty(pmsProductIdentifier)) {
throw new ServiceException("产品标识不能为空");
}
if (StringUtils.isEmpty(statusList)) {
return 0;
}
return pmsProductRequirementMapper.countByIdentifierAndStatus(pmsProductIdentifier, statusList);
}
@Override
public List<ReqStatusStatVo> selectReqCountGroupByStatus(String pmsProductIdentifier, List<String> statusList) {
if (StringUtils.isEmpty(pmsProductIdentifier)) {
throw new ServiceException("产品标识不能为空");
}
if (StringUtils.isEmpty(statusList)) {
return new ArrayList<>();
}
return pmsProductRequirementMapper.selectReqCountGroupByStatus(pmsProductIdentifier, statusList);
}
}

View File

@ -161,4 +161,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
from pms_product_plan
where pms_product_identifier = #{productIdentifier}
</delete>
<select id="countPmsProductPlanGroupByStatus" resultType="com.microservices.pms.product.domain.vo.ReqStatusStatVo">
select ppp.status_id as `key`,ppp.num as num ,pps.name as name from
(SELECT
status_id,
count(1) as num
FROM
pms_product_plan where pms_product_identifier = #{productIdentifier} group by status_id) ppp
left join pms_product_status pps on ppp.status_id = pps.id where pps.type = 1
</select>
</mapper>

View File

@ -359,4 +359,21 @@
#{id}
</foreach>
</delete>
<select id="countByIdentifierAndStatus" resultType="java.lang.Integer">
select count(0) from pms_product_requirement
where pms_product_identifier = #{pmsProductIdentifier} and `status` in
<foreach collection="statusList" item="item" index="idx" close=")" open="(" separator=",">
#{item}
</foreach>
</select>
<select id="selectReqCountGroupByStatus" resultType="com.microservices.pms.product.domain.vo.ReqStatusStatVo">
select count(1) as num, `status` as `key` from pms_product_requirement
where pms_product_identifier = #{pmsProductIdentifier} and `status` in
<foreach collection="statusList" item="item" index="idx" close=")" open="(" separator=",">
#{item}
</foreach>
group by `status`
</select>
</mapper>