Commit 5bc4d5ed42cef9933420daad71e14ae27423b695
1 parent
c525d7d9
✨ feat(statistics): 新增 MES 首页统计功能
实现了 MES 首页的统计功能,包括工单状态分布、生产趋势和汇总统计。新增了相关的 VO 类、服务接口及实现,支持从数据库获取统计数据并返回给前端。 - 添加 MesHomeStatisticsController 控制器 - 实现 MesHomeStatisticsService 接口及其实现 - 新增数据访问层 Mapper 和 XML 配置 - 定义响应 VO 类以适应前端需求
Showing
8 changed files
with
506 additions
and
0 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/statistics/MesHomeStatisticsController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.controller.admin.statistics; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 4 | +import cn.iocoder.yudao.module.mes.controller.admin.statistics.vo.MesHomeProductionTrendRespVO; | |
| 5 | +import cn.iocoder.yudao.module.mes.controller.admin.statistics.vo.MesHomeSummaryRespVO; | |
| 6 | +import cn.iocoder.yudao.module.mes.controller.admin.statistics.vo.MesHomeWorkOrderStatusRespVO; | |
| 7 | +import cn.iocoder.yudao.module.mes.service.statistics.MesHomeStatisticsService; | |
| 8 | +import io.swagger.v3.oas.annotations.Operation; | |
| 9 | +import io.swagger.v3.oas.annotations.Parameter; | |
| 10 | +import io.swagger.v3.oas.annotations.tags.Tag; | |
| 11 | +import jakarta.annotation.Resource; | |
| 12 | +import org.springframework.security.access.prepost.PreAuthorize; | |
| 13 | +import org.springframework.validation.annotation.Validated; | |
| 14 | +import org.springframework.web.bind.annotation.GetMapping; | |
| 15 | +import org.springframework.web.bind.annotation.RequestMapping; | |
| 16 | +import org.springframework.web.bind.annotation.RequestParam; | |
| 17 | +import org.springframework.web.bind.annotation.RestController; | |
| 18 | + | |
| 19 | +import java.util.List; | |
| 20 | + | |
| 21 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 22 | + | |
| 23 | +@Tag(name = "管理后台 - MES 首页统计") | |
| 24 | +@RestController | |
| 25 | +@RequestMapping("/mes/home-statistics") | |
| 26 | +@Validated | |
| 27 | +public class MesHomeStatisticsController { | |
| 28 | + | |
| 29 | + @Resource | |
| 30 | + private MesHomeStatisticsService homeStatisticsService; | |
| 31 | + | |
| 32 | + @GetMapping("/summary") | |
| 33 | + @Operation(summary = "获得首页汇总统计") | |
| 34 | + @PreAuthorize("@ss.hasPermission('mes:statistics:query')") | |
| 35 | + public CommonResult<MesHomeSummaryRespVO> getHomeSummary() { | |
| 36 | + return success(homeStatisticsService.getHomeSummary()); | |
| 37 | + } | |
| 38 | + | |
| 39 | + @GetMapping("/work-order-status") | |
| 40 | + @Operation(summary = "获得工单状态分布") | |
| 41 | + @PreAuthorize("@ss.hasPermission('mes:statistics:query')") | |
| 42 | + public CommonResult<List<MesHomeWorkOrderStatusRespVO>> getWorkOrderStatusDistribution() { | |
| 43 | + return success(homeStatisticsService.getWorkOrderStatusDistribution()); | |
| 44 | + } | |
| 45 | + | |
| 46 | + @GetMapping("/production-trend") | |
| 47 | + @Operation(summary = "获得生产趋势") | |
| 48 | + @Parameter(name = "days", description = "天数", example = "7") | |
| 49 | + @PreAuthorize("@ss.hasPermission('mes:statistics:query')") | |
| 50 | + public CommonResult<List<MesHomeProductionTrendRespVO>> getProductionTrend( | |
| 51 | + @RequestParam(value = "days", defaultValue = "7") Integer days) { | |
| 52 | + return success(homeStatisticsService.getProductionTrend(days)); | |
| 53 | + } | |
| 54 | + | |
| 55 | +} | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/statistics/vo/MesHomeProductionTrendRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.controller.admin.statistics.vo; | |
| 2 | + | |
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 4 | +import lombok.AllArgsConstructor; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.NoArgsConstructor; | |
| 7 | + | |
| 8 | +import java.math.BigDecimal; | |
| 9 | + | |
| 10 | +@Schema(description = "管理后台 - MES 首页生产趋势 Response VO") | |
| 11 | +@Data | |
| 12 | +@NoArgsConstructor | |
| 13 | +@AllArgsConstructor | |
| 14 | +public class MesHomeProductionTrendRespVO { | |
| 15 | + | |
| 16 | + @Schema(description = "日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-04-05") | |
| 17 | + private String date; | |
| 18 | + | |
| 19 | + @Schema(description = "产量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1234") | |
| 20 | + private BigDecimal quantity; | |
| 21 | + | |
| 22 | + @Schema(description = "合格品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1200") | |
| 23 | + private BigDecimal qualifiedQuantity; | |
| 24 | + | |
| 25 | + @Schema(description = "不良品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "34") | |
| 26 | + private BigDecimal unqualifiedQuantity; | |
| 27 | + | |
| 28 | +} | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/statistics/vo/MesHomeSummaryRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.controller.admin.statistics.vo; | |
| 2 | + | |
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 4 | +import lombok.Data; | |
| 5 | + | |
| 6 | +import java.math.BigDecimal; | |
| 7 | + | |
| 8 | +@Schema(description = "管理后台 - MES 首页汇总统计 Response VO") | |
| 9 | +@Data | |
| 10 | +public class MesHomeSummaryRespVO { | |
| 11 | + | |
| 12 | + // ========== 工单统计 ========== | |
| 13 | + | |
| 14 | + @Schema(description = "进行中工单数", requiredMode = Schema.RequiredMode.REQUIRED, example = "12") | |
| 15 | + private Long workOrderActiveCount; | |
| 16 | + | |
| 17 | + @Schema(description = "待排产工单数(草稿)", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") | |
| 18 | + private Long workOrderPrepareCount; | |
| 19 | + | |
| 20 | + @Schema(description = "已完成工单数", requiredMode = Schema.RequiredMode.REQUIRED, example = "30") | |
| 21 | + private Long workOrderFinishedCount; | |
| 22 | + | |
| 23 | + // ========== 产量统计 ========== | |
| 24 | + | |
| 25 | + @Schema(description = "今日报工总产量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1234") | |
| 26 | + private BigDecimal todayOutput; | |
| 27 | + | |
| 28 | + @Schema(description = "昨日报工总产量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1100") | |
| 29 | + private BigDecimal yesterdayOutput; | |
| 30 | + | |
| 31 | + // ========== 质量统计 ========== | |
| 32 | + | |
| 33 | + @Schema(description = "今日合格品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1200") | |
| 34 | + private BigDecimal todayQualifiedQuantity; | |
| 35 | + | |
| 36 | + @Schema(description = "今日不良品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "34") | |
| 37 | + private BigDecimal todayUnqualifiedQuantity; | |
| 38 | + | |
| 39 | + // ========== 设备统计 ========== | |
| 40 | + | |
| 41 | + @Schema(description = "设备总数", requiredMode = Schema.RequiredMode.REQUIRED, example = "20") | |
| 42 | + private Long machineryTotal; | |
| 43 | + | |
| 44 | + @Schema(description = "运行中设备数", requiredMode = Schema.RequiredMode.REQUIRED, example = "15") | |
| 45 | + private Long machineryProducing; | |
| 46 | + | |
| 47 | + @Schema(description = "停机设备数", requiredMode = Schema.RequiredMode.REQUIRED, example = "3") | |
| 48 | + private Long machineryStop; | |
| 49 | + | |
| 50 | + @Schema(description = "维护中设备数", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | |
| 51 | + private Long machineryMaintenance; | |
| 52 | + | |
| 53 | + // ========== 异常/待办统计 ========== | |
| 54 | + | |
| 55 | + @Schema(description = "未处置安灯报警数", requiredMode = Schema.RequiredMode.REQUIRED, example = "3") | |
| 56 | + private Long andonActiveCount; | |
| 57 | + | |
| 58 | + @Schema(description = "未完成维修工单数", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | |
| 59 | + private Long repairActiveCount; | |
| 60 | + | |
| 61 | +} | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/statistics/vo/MesHomeWorkOrderStatusRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.controller.admin.statistics.vo; | |
| 2 | + | |
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 4 | +import lombok.AllArgsConstructor; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.NoArgsConstructor; | |
| 7 | + | |
| 8 | +@Schema(description = "管理后台 - MES 首页工单状态分布 Response VO") | |
| 9 | +@Data | |
| 10 | +@NoArgsConstructor | |
| 11 | +@AllArgsConstructor | |
| 12 | +public class MesHomeWorkOrderStatusRespVO { | |
| 13 | + | |
| 14 | + @Schema(description = "状态值", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") | |
| 15 | + private Integer status; | |
| 16 | + | |
| 17 | + @Schema(description = "状态名", requiredMode = Schema.RequiredMode.REQUIRED, example = "草稿") | |
| 18 | + private String statusName; | |
| 19 | + | |
| 20 | + @Schema(description = "工单数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "12") | |
| 21 | + private Long count; | |
| 22 | + | |
| 23 | +} | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/statistics/MesHomeStatisticsMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.dal.mysql.statistics; | |
| 2 | + | |
| 3 | +import org.apache.ibatis.annotations.Mapper; | |
| 4 | +import org.apache.ibatis.annotations.Param; | |
| 5 | + | |
| 6 | +import java.math.BigDecimal; | |
| 7 | +import java.time.LocalDateTime; | |
| 8 | +import java.util.List; | |
| 9 | +import java.util.Map; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * MES 首页统计 Mapper | |
| 13 | + * | |
| 14 | + * @author 芋道源码 | |
| 15 | + */ | |
| 16 | +@Mapper | |
| 17 | +public interface MesHomeStatisticsMapper { | |
| 18 | + | |
| 19 | + /** | |
| 20 | + * 按状态统计工单数量 | |
| 21 | + * | |
| 22 | + * @return [{ "status": 0, "count": 5 }, ...] | |
| 23 | + */ | |
| 24 | + List<Map<String, Object>> selectWorkOrderCountGroupByStatus(); | |
| 25 | + | |
| 26 | + /** | |
| 27 | + * 统计报工产量合计 | |
| 28 | + * | |
| 29 | + * @param beginTime >= 开始时间 | |
| 30 | + * @param endTime < 结束时间 | |
| 31 | + * @return [feedbackQuantity, qualifiedQuantity, unqualifiedQuantity] | |
| 32 | + */ | |
| 33 | + Map<String, BigDecimal> selectFeedbackSummary(@Param("beginTime") LocalDateTime beginTime, | |
| 34 | + @Param("endTime") LocalDateTime endTime); | |
| 35 | + | |
| 36 | + /** | |
| 37 | + * 按设备状态统计设备台数 | |
| 38 | + * | |
| 39 | + * @return [{ "status": 1, "count": 3 }, ...] | |
| 40 | + */ | |
| 41 | + List<Map<String, Object>> selectMachineryCountGroupByStatus(); | |
| 42 | + | |
| 43 | + /** | |
| 44 | + * 统计未处置安灯记录数 | |
| 45 | + * | |
| 46 | + * @return 数量 | |
| 47 | + */ | |
| 48 | + Long selectAndonActiveCount(); | |
| 49 | + | |
| 50 | + /** | |
| 51 | + * 统计未完成维修工单数(草稿 + 维修中 + 待验收) | |
| 52 | + * | |
| 53 | + * @return 数量 | |
| 54 | + */ | |
| 55 | + Long selectRepairActiveCount(); | |
| 56 | + | |
| 57 | + /** | |
| 58 | + * 按天聚合报工产量(近 N 天) | |
| 59 | + * | |
| 60 | + * @param beginTime >= 开始时间 | |
| 61 | + * @param endTime < 结束时间 | |
| 62 | + * @return [{ "date": "2026-04-05", "quantity": 1234, "qualifiedQuantity": 1200, "unqualifiedQuantity": 34 }, ...] | |
| 63 | + */ | |
| 64 | + List<Map<String, Object>> selectDailyFeedbackTrend(@Param("beginTime") LocalDateTime beginTime, | |
| 65 | + @Param("endTime") LocalDateTime endTime); | |
| 66 | + | |
| 67 | +} | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/statistics/MesHomeStatisticsService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.service.statistics; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.mes.controller.admin.statistics.vo.MesHomeProductionTrendRespVO; | |
| 4 | +import cn.iocoder.yudao.module.mes.controller.admin.statistics.vo.MesHomeSummaryRespVO; | |
| 5 | +import cn.iocoder.yudao.module.mes.controller.admin.statistics.vo.MesHomeWorkOrderStatusRespVO; | |
| 6 | + | |
| 7 | +import java.util.List; | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * MES 首页统计 Service 接口 | |
| 11 | + * | |
| 12 | + * @author 芋道源码 | |
| 13 | + */ | |
| 14 | +public interface MesHomeStatisticsService { | |
| 15 | + | |
| 16 | + /** | |
| 17 | + * 获得首页汇总统计 | |
| 18 | + * | |
| 19 | + * @return 汇总统计数据 | |
| 20 | + */ | |
| 21 | + MesHomeSummaryRespVO getHomeSummary(); | |
| 22 | + | |
| 23 | + /** | |
| 24 | + * 获得工单状态分布 | |
| 25 | + * | |
| 26 | + * @return 各状态的工单数量列表 | |
| 27 | + */ | |
| 28 | + List<MesHomeWorkOrderStatusRespVO> getWorkOrderStatusDistribution(); | |
| 29 | + | |
| 30 | + /** | |
| 31 | + * 获得生产趋势(近 N 天) | |
| 32 | + * | |
| 33 | + * @param days 天数 | |
| 34 | + * @return 每天的产量数据 | |
| 35 | + */ | |
| 36 | + List<MesHomeProductionTrendRespVO> getProductionTrend(Integer days); | |
| 37 | + | |
| 38 | +} | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/statistics/MesHomeStatisticsServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.service.statistics; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; | |
| 4 | +import cn.iocoder.yudao.module.mes.controller.admin.statistics.vo.MesHomeProductionTrendRespVO; | |
| 5 | +import cn.iocoder.yudao.module.mes.controller.admin.statistics.vo.MesHomeSummaryRespVO; | |
| 6 | +import cn.iocoder.yudao.module.mes.controller.admin.statistics.vo.MesHomeWorkOrderStatusRespVO; | |
| 7 | +import cn.iocoder.yudao.module.mes.dal.mysql.statistics.MesHomeStatisticsMapper; | |
| 8 | +import cn.iocoder.yudao.module.mes.enums.dv.MesDvMachineryStatusEnum; | |
| 9 | +import cn.iocoder.yudao.module.mes.enums.pro.MesProWorkOrderStatusEnum; | |
| 10 | +import jakarta.annotation.Resource; | |
| 11 | +import org.springframework.stereotype.Service; | |
| 12 | + | |
| 13 | +import java.math.BigDecimal; | |
| 14 | +import java.time.LocalDate; | |
| 15 | +import java.time.LocalDateTime; | |
| 16 | +import java.time.format.DateTimeFormatter; | |
| 17 | +import java.util.*; | |
| 18 | + | |
| 19 | +/** | |
| 20 | + * MES 首页统计 Service 实现类 | |
| 21 | + * | |
| 22 | + * @author 芋道源码 | |
| 23 | + */ | |
| 24 | +@Service | |
| 25 | +public class MesHomeStatisticsServiceImpl implements MesHomeStatisticsService { | |
| 26 | + | |
| 27 | + @Resource | |
| 28 | + private MesHomeStatisticsMapper homeStatisticsMapper; | |
| 29 | + | |
| 30 | + @Override | |
| 31 | + public MesHomeSummaryRespVO getHomeSummary() { | |
| 32 | + MesHomeSummaryRespVO summary = new MesHomeSummaryRespVO(); | |
| 33 | + | |
| 34 | + // 1. 工单统计 | |
| 35 | + List<Map<String, Object>> workOrderStats = homeStatisticsMapper.selectWorkOrderCountGroupByStatus(); | |
| 36 | + long activeCount = 0L; | |
| 37 | + long prepareCount = 0L; | |
| 38 | + long finishedCount = 0L; | |
| 39 | + for (Map<String, Object> stat : workOrderStats) { | |
| 40 | + int status = ((Number) stat.get("status")).intValue(); | |
| 41 | + long count = ((Number) stat.get("count")).longValue(); | |
| 42 | + if (status == MesProWorkOrderStatusEnum.CONFIRMED.getStatus()) { | |
| 43 | + activeCount = count; | |
| 44 | + } else if (status == MesProWorkOrderStatusEnum.PREPARE.getStatus()) { | |
| 45 | + prepareCount = count; | |
| 46 | + } else if (status == MesProWorkOrderStatusEnum.FINISHED.getStatus()) { | |
| 47 | + finishedCount = count; | |
| 48 | + } | |
| 49 | + } | |
| 50 | + summary.setWorkOrderActiveCount(activeCount); | |
| 51 | + summary.setWorkOrderPrepareCount(prepareCount); | |
| 52 | + summary.setWorkOrderFinishedCount(finishedCount); | |
| 53 | + | |
| 54 | + // 2. 今日产量 | |
| 55 | + LocalDateTime today = LocalDateTimeUtils.getToday(); | |
| 56 | + LocalDateTime yesterday = LocalDateTimeUtils.getYesterday(); | |
| 57 | + Map<String, BigDecimal> todayFeedback = homeStatisticsMapper.selectFeedbackSummary(today, null); | |
| 58 | + summary.setTodayOutput(getDecimal(todayFeedback, "feedbackQuantity")); | |
| 59 | + summary.setTodayQualifiedQuantity(getDecimal(todayFeedback, "qualifiedQuantity")); | |
| 60 | + summary.setTodayUnqualifiedQuantity(getDecimal(todayFeedback, "unqualifiedQuantity")); | |
| 61 | + | |
| 62 | + // 3. 昨日产量 | |
| 63 | + Map<String, BigDecimal> yesterdayFeedback = homeStatisticsMapper.selectFeedbackSummary(yesterday, today); | |
| 64 | + summary.setYesterdayOutput(getDecimal(yesterdayFeedback, "feedbackQuantity")); | |
| 65 | + | |
| 66 | + // 4. 设备统计 | |
| 67 | + List<Map<String, Object>> machineryStats = homeStatisticsMapper.selectMachineryCountGroupByStatus(); | |
| 68 | + long total = 0L; | |
| 69 | + long producing = 0L; | |
| 70 | + long stop = 0L; | |
| 71 | + long maintenance = 0L; | |
| 72 | + for (Map<String, Object> stat : machineryStats) { | |
| 73 | + int status = ((Number) stat.get("status")).intValue(); | |
| 74 | + long count = ((Number) stat.get("count")).longValue(); | |
| 75 | + total += count; | |
| 76 | + if (status == MesDvMachineryStatusEnum.PRODUCING.getStatus()) { | |
| 77 | + producing = count; | |
| 78 | + } else if (status == MesDvMachineryStatusEnum.STOP.getStatus()) { | |
| 79 | + stop = count; | |
| 80 | + } else if (status == MesDvMachineryStatusEnum.MAINTENANCE.getStatus()) { | |
| 81 | + maintenance = count; | |
| 82 | + } | |
| 83 | + } | |
| 84 | + summary.setMachineryTotal(total); | |
| 85 | + summary.setMachineryProducing(producing); | |
| 86 | + summary.setMachineryStop(stop); | |
| 87 | + summary.setMachineryMaintenance(maintenance); | |
| 88 | + | |
| 89 | + // 5. 异常/待办 | |
| 90 | + summary.setAndonActiveCount(homeStatisticsMapper.selectAndonActiveCount()); | |
| 91 | + summary.setRepairActiveCount(homeStatisticsMapper.selectRepairActiveCount()); | |
| 92 | + | |
| 93 | + return summary; | |
| 94 | + } | |
| 95 | + | |
| 96 | + @Override | |
| 97 | + public List<MesHomeWorkOrderStatusRespVO> getWorkOrderStatusDistribution() { | |
| 98 | + List<Map<String, Object>> stats = homeStatisticsMapper.selectWorkOrderCountGroupByStatus(); | |
| 99 | + List<MesHomeWorkOrderStatusRespVO> result = new ArrayList<>(); | |
| 100 | + for (MesProWorkOrderStatusEnum statusEnum : MesProWorkOrderStatusEnum.values()) { | |
| 101 | + long count = 0L; | |
| 102 | + for (Map<String, Object> stat : stats) { | |
| 103 | + if (((Number) stat.get("status")).intValue() == statusEnum.getStatus()) { | |
| 104 | + count = ((Number) stat.get("count")).longValue(); | |
| 105 | + break; | |
| 106 | + } | |
| 107 | + } | |
| 108 | + result.add(new MesHomeWorkOrderStatusRespVO(statusEnum.getStatus(), statusEnum.getName(), count)); | |
| 109 | + } | |
| 110 | + return result; | |
| 111 | + } | |
| 112 | + | |
| 113 | + @Override | |
| 114 | + public List<MesHomeProductionTrendRespVO> getProductionTrend(Integer days) { | |
| 115 | + LocalDate endDate = LocalDate.now().plusDays(1); | |
| 116 | + LocalDate startDate = endDate.minusDays(days); | |
| 117 | + LocalDateTime beginTime = startDate.atStartOfDay(); | |
| 118 | + LocalDateTime endTime = endDate.atStartOfDay(); | |
| 119 | + | |
| 120 | + // 查询数据库 | |
| 121 | + List<Map<String, Object>> dbData = homeStatisticsMapper.selectDailyFeedbackTrend(beginTime, endTime); | |
| 122 | + Map<String, Map<String, Object>> dateMap = new LinkedHashMap<>(); | |
| 123 | + for (Map<String, Object> row : dbData) { | |
| 124 | + dateMap.put((String) row.get("date"), row); | |
| 125 | + } | |
| 126 | + | |
| 127 | + // 补全所有日期(无数据的日期填 0) | |
| 128 | + DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd"); | |
| 129 | + List<MesHomeProductionTrendRespVO> result = new ArrayList<>(); | |
| 130 | + for (LocalDate d = startDate; d.isBefore(endDate); d = d.plusDays(1)) { | |
| 131 | + String dateStr = d.format(fmt); | |
| 132 | + Map<String, Object> row = dateMap.get(dateStr); | |
| 133 | + MesHomeProductionTrendRespVO vo = new MesHomeProductionTrendRespVO(); | |
| 134 | + vo.setDate(dateStr); | |
| 135 | + if (row != null) { | |
| 136 | + vo.setQuantity(getDecimalFromObj(row.get("quantity"))); | |
| 137 | + vo.setQualifiedQuantity(getDecimalFromObj(row.get("qualifiedQuantity"))); | |
| 138 | + vo.setUnqualifiedQuantity(getDecimalFromObj(row.get("unqualifiedQuantity"))); | |
| 139 | + } else { | |
| 140 | + vo.setQuantity(BigDecimal.ZERO); | |
| 141 | + vo.setQualifiedQuantity(BigDecimal.ZERO); | |
| 142 | + vo.setUnqualifiedQuantity(BigDecimal.ZERO); | |
| 143 | + } | |
| 144 | + result.add(vo); | |
| 145 | + } | |
| 146 | + return result; | |
| 147 | + } | |
| 148 | + | |
| 149 | + // ========== 工具方法 ========== | |
| 150 | + | |
| 151 | + private BigDecimal getDecimal(Map<String, BigDecimal> map, String key) { | |
| 152 | + if (map == null || map.get(key) == null) { | |
| 153 | + return BigDecimal.ZERO; | |
| 154 | + } | |
| 155 | + return map.get(key); | |
| 156 | + } | |
| 157 | + | |
| 158 | + private BigDecimal getDecimalFromObj(Object obj) { | |
| 159 | + if (obj == null) { | |
| 160 | + return BigDecimal.ZERO; | |
| 161 | + } | |
| 162 | + if (obj instanceof BigDecimal) { | |
| 163 | + return (BigDecimal) obj; | |
| 164 | + } | |
| 165 | + return new BigDecimal(obj.toString()); | |
| 166 | + } | |
| 167 | + | |
| 168 | +} | ... | ... |
yudao-module-mes/src/main/resources/mapper/statistics/MesHomeStatisticsMapper.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |
| 3 | +<mapper namespace="cn.iocoder.yudao.module.mes.dal.mysql.statistics.MesHomeStatisticsMapper"> | |
| 4 | + | |
| 5 | + <!-- 按状态统计工单数量 --> | |
| 6 | + <select id="selectWorkOrderCountGroupByStatus" resultType="java.util.Map"> | |
| 7 | + SELECT status, COUNT(*) AS count | |
| 8 | + FROM mes_pro_work_order | |
| 9 | + WHERE deleted = 0 | |
| 10 | + GROUP BY status | |
| 11 | + </select> | |
| 12 | + | |
| 13 | + <!-- 统计报工产量合计 --> | |
| 14 | + <select id="selectFeedbackSummary" resultType="java.util.Map"> | |
| 15 | + SELECT IFNULL(SUM(feedback_quantity), 0) AS feedbackQuantity, | |
| 16 | + IFNULL(SUM(qualified_quantity), 0) AS qualifiedQuantity, | |
| 17 | + IFNULL(SUM(unqualified_quantity), 0) AS unqualifiedQuantity | |
| 18 | + FROM mes_pro_feedback | |
| 19 | + WHERE deleted = 0 | |
| 20 | + AND feedback_time >= #{beginTime} | |
| 21 | + <if test="endTime != null"> | |
| 22 | + AND feedback_time < #{endTime} | |
| 23 | + </if> | |
| 24 | + </select> | |
| 25 | + | |
| 26 | + <!-- 按设备状态统计设备台数 --> | |
| 27 | + <select id="selectMachineryCountGroupByStatus" resultType="java.util.Map"> | |
| 28 | + SELECT status, COUNT(*) AS count | |
| 29 | + FROM mes_dv_machinery | |
| 30 | + WHERE deleted = 0 | |
| 31 | + GROUP BY status | |
| 32 | + </select> | |
| 33 | + | |
| 34 | + <!-- 统计未处置安灯记录数 --> | |
| 35 | + <select id="selectAndonActiveCount" resultType="java.lang.Long"> | |
| 36 | + SELECT COUNT(*) | |
| 37 | + FROM mes_pro_andon_record | |
| 38 | + WHERE deleted = 0 | |
| 39 | + AND status = 0 | |
| 40 | + </select> | |
| 41 | + | |
| 42 | + <!-- 统计未完成维修工单数(草稿 0、维修中 1、待验收 2) --> | |
| 43 | + <select id="selectRepairActiveCount" resultType="java.lang.Long"> | |
| 44 | + SELECT COUNT(*) | |
| 45 | + FROM mes_dv_repair | |
| 46 | + WHERE deleted = 0 | |
| 47 | + AND status IN (0, 1, 2) | |
| 48 | + </select> | |
| 49 | + | |
| 50 | + <!-- 按天聚合报工产量 --> | |
| 51 | + <select id="selectDailyFeedbackTrend" resultType="java.util.Map"> | |
| 52 | + SELECT DATE_FORMAT(feedback_time, '%Y-%m-%d') AS date, | |
| 53 | + IFNULL(SUM(feedback_quantity), 0) AS quantity, | |
| 54 | + IFNULL(SUM(qualified_quantity), 0) AS qualifiedQuantity, | |
| 55 | + IFNULL(SUM(unqualified_quantity), 0) AS unqualifiedQuantity | |
| 56 | + FROM mes_pro_feedback | |
| 57 | + WHERE deleted = 0 | |
| 58 | + AND feedback_time >= #{beginTime} | |
| 59 | + <if test="endTime != null"> | |
| 60 | + AND feedback_time < #{endTime} | |
| 61 | + </if> | |
| 62 | + GROUP BY DATE_FORMAT(feedback_time, '%Y-%m-%d') | |
| 63 | + ORDER BY date | |
| 64 | + </select> | |
| 65 | + | |
| 66 | +</mapper> | ... | ... |