feat:添加app质量概况接口

main
HuangHuiKang 1 week ago
parent 1ea54b1f57
commit 13183a6a2a

@ -625,6 +625,12 @@ public class PlanController {
return success(vo); return success(vo);
} }
@GetMapping("/quality-overview")
@Operation(summary = "质量概况")
public CommonResult<PlanQualityOverviewRespVO> getQualityOverview(@Valid PlanQualityOverviewReqVO reqVO) {
return success(planService.getQualityOverview(reqVO));
}
@GetMapping("/getLastDaysRate") @GetMapping("/getLastDaysRate")

@ -0,0 +1,12 @@
package cn.iocoder.yudao.module.mes.controller.admin.plan.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "管理后台 - 生产计划质量概况 Request VO")
public class PlanQualityOverviewReqVO {
@Schema(description = "时间区间LAST_WEEK/THIS_WEEK/LAST_7_DAYS/LAST_MONTH/THIS_MONTH")
private String period;
}

@ -0,0 +1,67 @@
package cn.iocoder.yudao.module.mes.controller.admin.plan.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
@Schema(description = "管理后台 - 生产计划质量概况 Response VO")
public class PlanQualityOverviewRespVO {
@Schema(description = "报工总数")
private Long totalWangongNumber;
@Schema(description = "合格总数")
private Long totalPassNumber;
@Schema(description = "不合格总数")
private Long totalNoPassNumber;
@Schema(description = "总合格率")
private BigDecimal totalPassRate;
@Schema(description = "按产品合格率排行")
private List<ProductPassRateItem> productPassRateList;
@Schema(description = "双折线图数据")
private List<TrendItem> trendList;
@Data
@Schema(description = "产品合格率项")
public static class ProductPassRateItem {
@Schema(description = "产品ID")
private Long productId;
@Schema(description = "产品名称")
private String productName;
@Schema(description = "报工总数")
private Long wangongNumber;
@Schema(description = "合格数")
private Long passNumber;
@Schema(description = "不合格数")
private Long noPassNumber;
@Schema(description = "合格率")
private BigDecimal passRate;
}
@Data
@Schema(description = "趋势项")
public static class TrendItem {
@Schema(description = "日期")
private String day;
@Schema(description = "合格数")
private Long passNumber;
@Schema(description = "不合格数")
private Long noPassNumber;
}
}

@ -109,6 +109,8 @@ public interface PlanService {
List<Map<String, Object>> getLastSevenDaysCompletedCount(); List<Map<String, Object>> getLastSevenDaysCompletedCount();
PlanQualityOverviewRespVO getQualityOverview(PlanQualityOverviewReqVO reqVO);
List<DevicePlanGanttRespVO> getDevicePlanGantt(DevicePlanGanttReqVO reqVO); List<DevicePlanGanttRespVO> getDevicePlanGantt(DevicePlanGanttReqVO reqVO);
PageResult<PlanProductCapacityRespVO> getPlanProductCapacityPage(PlanProductCapacityPageReqVO reqVO); PageResult<PlanProductCapacityRespVO> getPlanProductCapacityPage(PlanProductCapacityPageReqVO reqVO);

@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO;
import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpWarehouseMapper; import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpWarehouseMapper;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService; import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.iot.controller.admin.device.enums.DeviceRateTrendPeriodEnum;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockInService; import cn.iocoder.yudao.module.erp.service.stock.ErpStockInService;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockOutService; import cn.iocoder.yudao.module.erp.service.stock.ErpStockOutService;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockService; import cn.iocoder.yudao.module.erp.service.stock.ErpStockService;
@ -460,6 +461,103 @@ public class PlanServiceImpl implements PlanService {
return result; return result;
} }
@Override
public PlanQualityOverviewRespVO getQualityOverview(PlanQualityOverviewReqVO reqVO) {
DeviceRateTrendPeriodEnum.DateRange dateRange = DeviceRateTrendPeriodEnum
.valueOfCode(reqVO.getPeriod())
.resolve(LocalDate.now());
LocalDate startDate = dateRange.getStart();
LocalDate endDate = dateRange.getEnd();
if (endDate.isBefore(startDate)) {
endDate = startDate;
}
LocalDateTime startTime = startDate.atStartOfDay();
LocalDateTime endTime = endDate.plusDays(1).atStartOfDay();
List<PlanDO> planList = planMapper.selectList(new LambdaQueryWrapper<PlanDO>()
.ge(PlanDO::getCreateTime, startTime)
.lt(PlanDO::getCreateTime, endTime));
PlanQualityOverviewRespVO respVO = new PlanQualityOverviewRespVO();
long totalWangongNumber = 0L;
long totalPassNumber = 0L;
long totalNoPassNumber = 0L;
Map<Long, PlanQualityOverviewRespVO.ProductPassRateItem> productMap = new HashMap<>();
Map<LocalDate, PlanQualityOverviewRespVO.TrendItem> trendMap = new LinkedHashMap<>();
for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
PlanQualityOverviewRespVO.TrendItem trendItem = new PlanQualityOverviewRespVO.TrendItem();
trendItem.setDay(date.toString());
trendItem.setPassNumber(0L);
trendItem.setNoPassNumber(0L);
trendMap.put(date, trendItem);
}
for (PlanDO plan : planList) {
long wangongNumber = Optional.ofNullable(plan.getWangongNumber()).orElse(0L);
long passNumber = Optional.ofNullable(plan.getPassNumber()).orElse(0L);
long noPassNumber = Optional.ofNullable(plan.getNoPassNumber()).orElse(0L);
totalWangongNumber += wangongNumber;
totalPassNumber += passNumber;
totalNoPassNumber += noPassNumber;
if (plan.getProductId() != null) {
PlanQualityOverviewRespVO.ProductPassRateItem item = productMap.computeIfAbsent(plan.getProductId(), key -> {
PlanQualityOverviewRespVO.ProductPassRateItem value = new PlanQualityOverviewRespVO.ProductPassRateItem();
value.setProductId(key);
value.setWangongNumber(0L);
value.setPassNumber(0L);
value.setNoPassNumber(0L);
value.setPassRate(BigDecimal.ZERO);
return value;
});
item.setWangongNumber(item.getWangongNumber() + wangongNumber);
item.setPassNumber(item.getPassNumber() + passNumber);
item.setNoPassNumber(item.getNoPassNumber() + noPassNumber);
}
LocalDate trendDate = Optional.ofNullable(plan.getCreateTime())
.map(LocalDateTime::toLocalDate)
.orElse(null);
if (trendDate != null && trendMap.containsKey(trendDate)) {
PlanQualityOverviewRespVO.TrendItem trendItem = trendMap.get(trendDate);
trendItem.setPassNumber(trendItem.getPassNumber() + passNumber);
trendItem.setNoPassNumber(trendItem.getNoPassNumber() + noPassNumber);
}
}
Map<Long, ErpProductRespVO> productRespMap = erpProductService.getProductVOMap(productMap.keySet());
List<PlanQualityOverviewRespVO.ProductPassRateItem> productPassRateList = new ArrayList<>(productMap.values());
productPassRateList.forEach(item -> {
ErpProductRespVO product = productRespMap.get(item.getProductId());
if (product != null) {
item.setProductName(product.getName());
}
item.setPassRate(calculatePassRate(item.getPassNumber(), item.getWangongNumber()));
});
productPassRateList.sort(Comparator.comparing(PlanQualityOverviewRespVO.ProductPassRateItem::getPassRate,
Comparator.reverseOrder()).thenComparing(PlanQualityOverviewRespVO.ProductPassRateItem::getProductId,
Comparator.nullsLast(Long::compareTo)));
respVO.setTotalWangongNumber(totalWangongNumber);
respVO.setTotalPassNumber(totalPassNumber);
respVO.setTotalNoPassNumber(totalNoPassNumber);
respVO.setTotalPassRate(calculatePassRate(totalPassNumber, totalWangongNumber));
respVO.setProductPassRateList(productPassRateList);
respVO.setTrendList(new ArrayList<>(trendMap.values()));
return respVO;
}
private BigDecimal calculatePassRate(Long passNumber, Long totalNumber) {
if (totalNumber == null || totalNumber <= 0) {
return BigDecimal.ZERO;
}
return BigDecimal.valueOf(Optional.ofNullable(passNumber).orElse(0L))
.multiply(BigDecimal.valueOf(100))
.divide(BigDecimal.valueOf(totalNumber), 2, RoundingMode.HALF_UP);
}
@Override @Override
public PageResult<PlanRespVO> getPlanPage(PlanPageReqVO pageReqVO) { public PageResult<PlanRespVO> getPlanPage(PlanPageReqVO pageReqVO) {

Loading…
Cancel
Save