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> |