From aa593aecbbb342bf7d181837f85bcc1f6a65af64 Mon Sep 17 00:00:00 2001 From: yinhuaiwei Date: Mon, 2 Nov 2026 19:27:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20eqpbookChannel=E8=A1=A8=E6=96=B0?= =?UTF-8?q?=E5=A2=9EuseMode=E5=AD=97=E6=AE=B5=E7=9A=84=E6=B1=87=E8=81=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agg/entity/AggBasedataEqpbookChannel.java | 2 + .../agg/service/AggStatisticService.java | 64 +++++++++---------- .../agg/service/ChannelSyncService.java | 1 + .../agg/service/EqpbookTreeService.java | 20 +++++- .../inspect/agg/web/AggTreeController.java | 3 +- .../AggBasedataEqpbookChannelMapper.xml | 7 +- 6 files changed, 56 insertions(+), 41 deletions(-) diff --git a/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/entity/AggBasedataEqpbookChannel.java b/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/entity/AggBasedataEqpbookChannel.java index 415a7fa..915cb4f 100644 --- a/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/entity/AggBasedataEqpbookChannel.java +++ b/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/entity/AggBasedataEqpbookChannel.java @@ -38,6 +38,8 @@ public class AggBasedataEqpbookChannel { private String deviceSource; /** 通道能力(JSON 字符串,树接口返回时解析为对象) */ private String capabilities; + /** 使用类型(源表 basedata_eqpbook_channel.use_mode) */ + private String useMode; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime updateTime; private LocalDateTime syncedAt; diff --git a/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/service/AggStatisticService.java b/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/service/AggStatisticService.java index 4bc6e45..81be0d0 100644 --- a/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/service/AggStatisticService.java +++ b/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/service/AggStatisticService.java @@ -13,7 +13,6 @@ import java.util.Map; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; -import com.inspect.agg.config.AggProperties; import com.inspect.agg.entity.AggAnalysisDefectMonth; import com.inspect.agg.entity.AggStation; import com.inspect.agg.enums.AlgCategory; @@ -31,39 +30,49 @@ public class AggStatisticService { private static final String MONTH = "month"; private static final String QUARTER = "quarter"; private static final String YEAR = "year"; + /** 统计窗口下限:最早只能查 2026-10(季度下限即 2026-Q4 的首月)。 */ + private static final YearMonth MIN_STAT_MONTH = YearMonth.of(2026, 10); + private static final YearMonth MIN_STAT_QUARTER_START = YearMonth.of(2026, 10); private final AggAnalysisDefectMonthMapper defectMonthMapper; private final AggPatrolTaskStatusMapper taskStatusMapper; private final AggStationMapper stationMapper; - private final AggProperties props; public List> defectStatistic(String stationCode, String algCategory, String dateType) { List categories = parseCategories(algCategory); String normalizedType = normalizeDateType(dateType); YearMonth current = YearMonth.now(); - LocalDate begin; - LocalDate endExclusive; - if (QUARTER.equals(normalizedType)) { - YearMonth currentQuarter = quarterStart(current); - begin = currentQuarter.minusMonths(9).atDay(1); - endExclusive = currentQuarter.plusMonths(3).atDay(1); - } else if (YEAR.equals(normalizedType)) { - begin = LocalDate.of(current.getYear() - 2, 1, 1); - endExclusive = LocalDate.of(current.getYear() + 1, 1, 1); + + // 固定长度窗口:月 12 个、季 4 个、年 3 个;右端对齐当前周期, + // 若左端早于统计下限(2026-10),整体右移,窗口长度不变。 + YearMonth windowStart; + int windowMonths; + if (YEAR.equals(normalizedType)) { + int startYear = Math.max(current.getYear() - 2, MIN_STAT_MONTH.getYear()); + windowStart = YearMonth.of(startYear, 1); + windowMonths = 36; + } else if (QUARTER.equals(normalizedType)) { + YearMonth start = quarterStart(current).minusMonths(9); + windowStart = start.isBefore(MIN_STAT_QUARTER_START) ? MIN_STAT_QUARTER_START : start; + windowMonths = 12; } else { - begin = current.minusMonths(11).atDay(1); - endExclusive = current.plusMonths(1).atDay(1); + YearMonth start = current.minusMonths(11); + windowStart = start.isBefore(MIN_STAT_MONTH) ? MIN_STAT_MONTH : start; + windowMonths = 12; } + LocalDate begin = windowStart.atDay(1); + LocalDate endExclusive = windowStart.plusMonths(windowMonths).atDay(1); List rows = defectMonthMapper.selectRange(stationCode, begin, endExclusive); Map monthlyMap = toMonthlyMap(rows, categories); String stationName = stationDisplayName(stationCode); List> result = new ArrayList<>(); if (YEAR.equals(normalizedType)) { - int currentYear = current.getYear(); - for (int year = currentYear - 2; year <= currentYear; year++) { + int startYear = windowStart.getYear(); + for (int i = 0; i < 3; i++) { + int year = startYear + i; Counts counts = new Counts(); for (int monthOffset = 0; monthOffset < 12; monthOffset++) { counts.add(monthlyMap.get(YearMonth.of(year, 1).plusMonths(monthOffset))); @@ -75,9 +84,8 @@ public class AggStatisticService { } if (QUARTER.equals(normalizedType)) { - YearMonth firstQuarter = quarterStart(current).minusMonths(9); for (int i = 0; i < 4; i++) { - YearMonth quarter = firstQuarter.plusMonths(i * 3L); + YearMonth quarter = windowStart.plusMonths(i * 3L); Counts counts = new Counts(); for (int monthOffset = 0; monthOffset < 3; monthOffset++) { counts.add(monthlyMap.get(quarter.plusMonths(monthOffset))); @@ -89,9 +97,8 @@ public class AggStatisticService { return result; } - YearMonth first = current.minusMonths(11); for (int i = 0; i < 12; i++) { - YearMonth month = first.plusMonths(i); + YearMonth month = windowStart.plusMonths(i); Counts counts = monthlyMap.getOrDefault(month, new Counts()); result.add(toPeriodResult(counts, month.format(MONTH_FORMAT), normalizedType, algCategory, stationCode, stationName)); @@ -161,7 +168,6 @@ public class AggStatisticService { item.put("stationCode", stationCode); item.put("stationName", stationName != null ? stationName : stationCode); } - item.put("minorCount", minorCount(counts)); item.put("generalCount", counts.general); item.put("seriousCount", counts.serious); item.put("urgentCount", counts.urgent); @@ -182,21 +188,16 @@ public class AggStatisticService { result.put("inspectedTaskCount", number(taskStats, "inspected_task_count")); result.put("completedTaskCount", number(taskStats, "completed_task_count")); result.put("defectCount", defectCount(defectStats)); - result.put("minorCount", minorCount(defectStats)); result.put("generalCount", defectStats.general); result.put("seriousCount", defectStats.serious); result.put("urgentCount", defectStats.urgent); return result; } - private int minorCount(Counts counts) { - return props.getStatistic().isMinorDefectEnabled() ? counts.minor : 0; - } - + /** + * 缺陷总数只统计一般及以上缺陷,轻微缺陷不计入。 + */ private long defectCount(Counts counts) { - if (props.getStatistic().isMinorDefectEnabled()) { - return counts.defectCount(); - } return (long) counts.general + counts.serious + counts.urgent; } @@ -262,7 +263,6 @@ public class AggStatisticService { } private static class Counts { - private int minor; private int general; private int serious; private int urgent; @@ -272,7 +272,6 @@ public class AggStatisticService { if (row == null) { return; } - minor += nz(row.getMinorCount()); general += nz(row.getGeneralCount()); serious += nz(row.getSeriousCount()); urgent += nz(row.getUrgentCount()); @@ -283,17 +282,12 @@ public class AggStatisticService { if (other == null) { return; } - minor += other.minor; general += other.general; serious += other.serious; urgent += other.urgent; normal += other.normal; } - private long defectCount() { - return minor + general + serious + urgent; - } - private static int nz(Integer value) { return value == null ? 0 : value; } diff --git a/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/service/ChannelSyncService.java b/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/service/ChannelSyncService.java index 14ae3c0..08cacfd 100644 --- a/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/service/ChannelSyncService.java +++ b/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/service/ChannelSyncService.java @@ -93,6 +93,7 @@ public class ChannelSyncService { c.setUpSystemDeviceCode(Rows.text(r, "upSystemDeviceCode")); c.setDeviceSource(Rows.text(r, "deviceSource")); c.setCapabilities(Rows.jsonText(r, "capabilities")); + c.setUseMode(Rows.text(r, "useMode", "use_mode")); c.setUpdateTime(Rows.date(r, "updateTime")); c.setSyncedAt(LocalDateTime.now()); c.setIsDeleted(0); diff --git a/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/service/EqpbookTreeService.java b/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/service/EqpbookTreeService.java index 15f50e7..7b6ecb4 100644 --- a/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/service/EqpbookTreeService.java +++ b/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/service/EqpbookTreeService.java @@ -41,7 +41,8 @@ public class EqpbookTreeService { String patrolDeviceName, String onlineStatus, String patrolDeviceTypeFlag, - String deviceSource) { + String deviceSource, + String useMode) { List areas = areaMapper.listForTree(stationCode); List eqpbooks = eqpbookMapper.list(stationCode, 0); List channels = channelMapper.list(stationCode, 0); @@ -53,7 +54,7 @@ public class EqpbookTreeService { Map> channelIndex = new HashMap<>(); for (AggBasedataEqpbookChannel channel : channels) { - if (!matchesDeviceSource(channel, deviceSource)) { + if (!matchesDeviceSource(channel, deviceSource) || !matchesUseMode(channel, useMode)) { continue; } channelIndex.computeIfAbsent(eqpbookKey(channel.getStationCode(), channel.getEqpbookId()), @@ -159,6 +160,7 @@ public class EqpbookTreeService { channelNode.put("channelType", channel.getChannelType()); channelNode.put("deviceSource", channel.getDeviceSource()); channelNode.put("capabilities", parseCapabilities(channel.getCapabilities())); + channelNode.put("useMode", channel.getUseMode()); channelNode.put("host", channel.getHost()); channelNode.put("port", channel.getPort()); channelNode.put("stationCode", channel.getStationCode()); @@ -243,6 +245,20 @@ public class EqpbookTreeService { return expected.equals(actual); } + private static boolean matchesUseMode(AggBasedataEqpbookChannel channel, String useMode) { + if (!StringUtils.hasText(useMode)) { + return true; + } + String actual = channel.getUseMode() == null ? "" : channel.getUseMode().trim(); + for (String expected : useMode.split(",")) { + String value = expected.trim(); + if (!value.isEmpty() && value.equals(actual)) { + return true; + } + } + return false; + } + private static boolean matchesType(AggBasedataEqpbook eqpbook, String flag) { if (!StringUtils.hasText(flag)) return true; String type = eqpbook.getDeviceType(); diff --git a/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/web/AggTreeController.java b/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/web/AggTreeController.java index 02498a1..972aa28 100644 --- a/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/web/AggTreeController.java +++ b/inspect-main/inspect-main-agg/src/main/java/com/inspect/agg/web/AggTreeController.java @@ -35,9 +35,10 @@ public class AggTreeController { @RequestParam(value = "onlineStatus", required = false) String onlineStatus, @RequestParam(value = "patroldeviceTypeFlag", required = false) String patrolDeviceTypeFlag, @RequestParam(value = "deviceSource", required = false) String deviceSource, + @RequestParam(required = false) String useMode, @RequestParam(required = false) String stationCode) { List> tree = eqpbookTreeService.buildFilterTree( - stationCode, patrolDeviceName, onlineStatus, patrolDeviceTypeFlag, deviceSource); + stationCode, patrolDeviceName, onlineStatus, patrolDeviceTypeFlag, deviceSource, useMode); return AjaxResult.success(tree); } diff --git a/inspect-main/inspect-main-agg/src/main/resources/mapper/AggBasedataEqpbookChannelMapper.xml b/inspect-main/inspect-main-agg/src/main/resources/mapper/AggBasedataEqpbookChannelMapper.xml index 730771a..fcbd476 100644 --- a/inspect-main/inspect-main-agg/src/main/resources/mapper/AggBasedataEqpbookChannelMapper.xml +++ b/inspect-main/inspect-main-agg/src/main/resources/mapper/AggBasedataEqpbookChannelMapper.xml @@ -21,16 +21,16 @@ + - - INSERT INTO agg_basedata_eqpbook_channel (station_code, channel_id, channel_code, channel_name, channel_type, online_state, channel_content, host, port, area_id, area_name, eqpbook_id, patrol_device_code, up_system_device_code, device_source, capabilities, update_time, synced_at, is_deleted) - VALUES (#{stationCode}, #{channelId}, #{channelCode}, #{channelName}, #{channelType}, #{onlineState}, #{channelContent}, #{host}, #{port}, #{areaId}, #{areaName}, #{eqpbookId}, #{patrolDeviceCode}, #{upSystemDeviceCode}, #{deviceSource}, #{capabilities}, #{updateTime}, #{syncedAt}, #{isDeleted}) + INSERT INTO agg_basedata_eqpbook_channel (station_code, channel_id, channel_code, channel_name, channel_type, online_state, channel_content, host, port, area_id, area_name, eqpbook_id, patrol_device_code, up_system_device_code, device_source, capabilities, use_mode, update_time, synced_at, is_deleted) + VALUES (#{stationCode}, #{channelId}, #{channelCode}, #{channelName}, #{channelType}, #{onlineState}, #{channelContent}, #{host}, #{port}, #{areaId}, #{areaName}, #{eqpbookId}, #{patrolDeviceCode}, #{upSystemDeviceCode}, #{deviceSource}, #{capabilities}, #{useMode}, #{updateTime}, #{syncedAt}, #{isDeleted}) ON DUPLICATE KEY UPDATE channel_code = VALUES(channel_code), channel_name = VALUES(channel_name), @@ -46,6 +46,7 @@ up_system_device_code = VALUES(up_system_device_code), device_source = VALUES(device_source), capabilities = VALUES(capabilities), + use_mode = VALUES(use_mode), update_time = VALUES(update_time), synced_at = VALUES(synced_at), is_deleted = VALUES(is_deleted),