package cn.iocoder.yudao.module.mes.service.qc.statistics;
|
|
import cn.iocoder.yudao.module.mes.controller.admin.qc.statistics.vo.MesQcStatisticsByProcessVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.qc.statistics.vo.MesQcStatisticsByWorkOrderVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.qc.statistics.vo.MesQcStatisticsOverallVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.qc.statistics.vo.MesQcStatisticsRespVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.qc.statistics.vo.MesQcStatisticsTypeVO;
|
import cn.iocoder.yudao.module.mes.dal.mysql.qc.statistics.MesQcStatisticsMapper;
|
import jakarta.annotation.Resource;
|
import org.springframework.stereotype.Service;
|
import org.springframework.validation.annotation.Validated;
|
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.time.LocalDateTime;
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
/**
|
* MES 质量统计 Service 实现类
|
*
|
* @author 超级管理员
|
*/
|
@Service
|
@Validated
|
public class MesQcStatisticsServiceImpl implements MesQcStatisticsService {
|
|
/**
|
* 固定输出顺序与名称:IQC / IPQC / OQC / RQC,无数据的类型也要返回 0
|
*/
|
private static final Map<String, String> QC_TYPE_NAMES = Map.of(
|
"IQC", "来料检验",
|
"IPQC", "过程检验",
|
"OQC", "出货检验",
|
"RQC", "退货检验");
|
|
private static final List<String> QC_TYPE_ORDER = List.of("IQC", "IPQC", "OQC", "RQC");
|
|
@Resource
|
private MesQcStatisticsMapper statisticsMapper;
|
|
@Override
|
public MesQcStatisticsRespVO getStatisticsSummary(LocalDateTime beginTime, LocalDateTime endTime) {
|
return new MesQcStatisticsRespVO()
|
.setOverall(buildOverall(beginTime, endTime))
|
.setByProcess(buildByProcess(beginTime, endTime))
|
.setByWorkOrder(buildByWorkOrder(beginTime, endTime));
|
}
|
|
private MesQcStatisticsOverallVO buildOverall(LocalDateTime beginTime, LocalDateTime endTime) {
|
Map<String, MesQcStatisticsTypeVO> typeMap = new HashMap<>();
|
for (MesQcStatisticsTypeVO row : statisticsMapper.selectTypeStatistics(beginTime, endTime)) {
|
typeMap.put(row.getQcType(), row);
|
}
|
|
long totalQcCount = 0L;
|
BigDecimal totalCheckQuantity = BigDecimal.ZERO;
|
BigDecimal totalQualifiedQuantity = BigDecimal.ZERO;
|
BigDecimal totalUnqualifiedQuantity = BigDecimal.ZERO;
|
List<MesQcStatisticsTypeVO> types = new ArrayList<>(QC_TYPE_ORDER.size());
|
for (String qcType : QC_TYPE_ORDER) {
|
MesQcStatisticsTypeVO type = typeMap.get(qcType);
|
if (type == null) {
|
type = new MesQcStatisticsTypeVO().setQcType(qcType);
|
}
|
type.setQcTypeName(QC_TYPE_NAMES.get(qcType));
|
type.setQcCount(defaultZero(type.getQcCount()));
|
type.setCheckQuantity(defaultZero(type.getCheckQuantity()));
|
type.setQualifiedQuantity(defaultZero(type.getQualifiedQuantity()));
|
type.setUnqualifiedQuantity(defaultZero(type.getUnqualifiedQuantity()));
|
type.setQualifiedRate(calculateRate(type.getQualifiedQuantity(), type.getCheckQuantity()));
|
type.setUnqualifiedRate(calculateRate(type.getUnqualifiedQuantity(), type.getCheckQuantity()));
|
types.add(type);
|
|
totalQcCount += type.getQcCount();
|
totalCheckQuantity = totalCheckQuantity.add(type.getCheckQuantity());
|
totalQualifiedQuantity = totalQualifiedQuantity.add(type.getQualifiedQuantity());
|
totalUnqualifiedQuantity = totalUnqualifiedQuantity.add(type.getUnqualifiedQuantity());
|
}
|
|
return new MesQcStatisticsOverallVO()
|
.setTotalQcCount(totalQcCount)
|
.setCheckQuantity(totalCheckQuantity)
|
.setQualifiedQuantity(totalQualifiedQuantity)
|
.setUnqualifiedQuantity(totalUnqualifiedQuantity)
|
.setQualifiedRate(calculateRate(totalQualifiedQuantity, totalCheckQuantity))
|
.setUnqualifiedRate(calculateRate(totalUnqualifiedQuantity, totalCheckQuantity))
|
.setTypes(types);
|
}
|
|
private List<MesQcStatisticsByProcessVO> buildByProcess(LocalDateTime beginTime, LocalDateTime endTime) {
|
List<MesQcStatisticsByProcessVO> list = statisticsMapper.selectStatisticsByProcess(beginTime, endTime);
|
for (MesQcStatisticsByProcessVO row : list) {
|
row.setCheckQuantity(defaultZero(row.getCheckQuantity()));
|
row.setQualifiedQuantity(defaultZero(row.getQualifiedQuantity()));
|
row.setUnqualifiedQuantity(defaultZero(row.getUnqualifiedQuantity()));
|
row.setQualifiedRate(calculateRate(row.getQualifiedQuantity(), row.getCheckQuantity()));
|
}
|
return list;
|
}
|
|
private List<MesQcStatisticsByWorkOrderVO> buildByWorkOrder(LocalDateTime beginTime, LocalDateTime endTime) {
|
List<MesQcStatisticsByWorkOrderVO> list = statisticsMapper.selectStatisticsByWorkOrder(beginTime, endTime);
|
for (MesQcStatisticsByWorkOrderVO row : list) {
|
row.setCheckQuantity(defaultZero(row.getCheckQuantity()));
|
row.setQualifiedQuantity(defaultZero(row.getQualifiedQuantity()));
|
row.setUnqualifiedQuantity(defaultZero(row.getUnqualifiedQuantity()));
|
row.setQualifiedRate(calculateRate(row.getQualifiedQuantity(), row.getCheckQuantity()));
|
}
|
return list;
|
}
|
|
private static Long defaultZero(Long value) {
|
return value == null ? 0L : value;
|
}
|
|
private static BigDecimal defaultZero(BigDecimal value) {
|
return value == null ? BigDecimal.ZERO : value;
|
}
|
|
/**
|
* 计算百分比,保留两位小数;分母为空或 0 时返回 0.00,避免除零
|
*/
|
private static BigDecimal calculateRate(BigDecimal part, BigDecimal total) {
|
if (part == null || total == null || total.compareTo(BigDecimal.ZERO) == 0) {
|
return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
|
}
|
return part.multiply(BigDecimal.valueOf(100))
|
.divide(total, 2, RoundingMode.HALF_UP);
|
}
|
|
}
|