From d7d4ae6cfb28adf7ef92f44332ff492f0cc7069c Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期五, 07 八月 2026 15:44:41 +0800
Subject: [PATCH] feat: 完善大屏与光储监控接口
---
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java | 39 +++++----
sql/20260807_energy_storage_monitoring_menu.sql | 87 +++++++++++++++++++++
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/TChargingPileService.java | 3
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingPileController.java | 7 +
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/mapper/TChargingOrderMapper.java | 4 +
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/LargeScreenController.java | 10 +-
ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TChargingOrderMapper.xml | 53 ++++++++++--
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/TChargingPileServiceImpl.java | 16 ++++
8 files changed, 186 insertions(+), 33 deletions(-)
diff --git a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingPileController.java b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingPileController.java
index c0724f3..926f9a7 100644
--- a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingPileController.java
+++ b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingPileController.java
@@ -309,6 +309,13 @@
return AjaxResult.success(chargeMonitoring);
}
+ @ResponseBody
+ @GetMapping("/screenChargeMonitoring/{siteId}")
+ @ApiOperation(value = "获取智慧充电大屏监控数据", tags = {"管理后台-智慧充电大屏"})
+ public AjaxResult<ChargeMonitoring> screenChargeMonitoring(@PathVariable Integer siteId){
+ return AjaxResult.success(chargingPileService.chargeMonitoringForScreen(siteId));
+ }
+
@RequiresPermissions(value = {"/chargingEquipmentMonitoring"}, logical = Logical.OR)
@ResponseBody
@GetMapping("/getChargingMonitoringSiteList")
diff --git a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/TChargingPileService.java b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/TChargingPileService.java
index 65b5ba6..41563bc 100644
--- a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/TChargingPileService.java
+++ b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/TChargingPileService.java
@@ -101,6 +101,9 @@
*/
ChargeMonitoring chargeMonitoring(Integer siteId);
+ /** 智慧充电大屏监控数据,不按菜单权限过滤站点。 */
+ ChargeMonitoring chargeMonitoringForScreen(Integer siteId);
+
List<Site> getChargingMonitoringSiteList();
diff --git a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/TChargingPileServiceImpl.java b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/TChargingPileServiceImpl.java
index f089706..5150148 100644
--- a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/TChargingPileServiceImpl.java
+++ b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/TChargingPileServiceImpl.java
@@ -794,6 +794,22 @@
@Override
public ChargeMonitoring chargeMonitoring(Integer siteId) {
Set<Integer> siteIds = resolveChargingMonitoringSiteIds(siteId);
+ return buildChargeMonitoring(siteIds);
+ }
+
+ @Override
+ public ChargeMonitoring chargeMonitoringForScreen(Integer siteId) {
+ Set<Integer> siteIds;
+ if (siteId != null && siteId > 0) {
+ siteIds = Collections.singleton(siteId);
+ } else {
+ siteIds = siteService.list(new LambdaQueryWrapper<Site>()
+ .eq(Site::getDelFlag, 0)).stream().map(Site::getId).collect(Collectors.toSet());
+ }
+ return buildChargeMonitoring(siteIds);
+ }
+
+ private ChargeMonitoring buildChargeMonitoring(Set<Integer> siteIds) {
List<Site> sites = siteService.list(new LambdaQueryWrapper<Site>()
.in(Site::getId, siteIds)
.eq(Site::getDelFlag, 0));
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/LargeScreenController.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/LargeScreenController.java
index f4d2050..c2608cd 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/LargeScreenController.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/LargeScreenController.java
@@ -36,11 +36,11 @@
return R.ok(chargingOrderService.getLargeScreenSummary(normalizeSiteIds(siteIds)));
}
- @ApiOperation(tags = {"大屏-收入趋势"}, value = "当年按月充电收入")
+ @ApiOperation(tags = {"大屏-收入趋势"}, value = "最近七日充电收入")
@GetMapping("/incomeTrend")
public R<List<SixChargingDto>> incomeTrend(@RequestParam("siteIds") List<Integer> siteIds) {
return R.ok(chargingOrderService.getLargeScreenIncomeTrend(
- normalizeSiteIds(siteIds), LocalDate.now().withDayOfYear(1)));
+ normalizeSiteIds(siteIds), LocalDate.now().minusDays(6)));
}
@ApiOperation(tags = {"大屏-停车场充电功率曲线图"},value = "停车场充电功率曲线图")
@@ -48,14 +48,14 @@
public R<List<LargeChargingPowerVo>> getChargingPower(
@RequestParam(value = "siteIds", required = false) List<Integer> siteIds){
LocalDate today = LocalDate.now();
- LocalDateTime startTime = today.minusDays(7).atStartOfDay();
- LocalDateTime endTime = today.atStartOfDay();
+ LocalDateTime startTime = today.minusDays(6).atStartOfDay();
+ LocalDateTime endTime = today.plusDays(1).atStartOfDay();
List<LargeChargingPowerVo> powerData = chargingOrderService.getLargeScreenChargingPower(
siteIds == null ? null : normalizeSiteIds(siteIds), startTime, endTime);
Map<String, LargeChargingPowerVo> powerByDate = powerData.stream()
.collect(Collectors.toMap(LargeChargingPowerVo::getTime, Function.identity(), (left, right) -> left));
ArrayList<LargeChargingPowerVo> largeChargingPowerVos = new ArrayList<>();
- for (int count = 7; count > 0; count--) {
+ for (int count = 6; count >= 0; count--) {
String time = today.minusDays(count).toString();
LargeChargingPowerVo largeChargingPowerVo = powerByDate.getOrDefault(time, new LargeChargingPowerVo());
largeChargingPowerVo.setTime(time);
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/mapper/TChargingOrderMapper.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/mapper/TChargingOrderMapper.java
index 282501f..2184f4d 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/mapper/TChargingOrderMapper.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/mapper/TChargingOrderMapper.java
@@ -322,6 +322,10 @@
// 接口用: 近 N 月收入趋势(M 行按 period 分组)
List<SixChargingDto> incomeTrendFromStat(@Param("siteIds") List<Integer> siteIds, @Param("sixBefore") String sixBefore);
+ List<SixChargingDto> incomeTrendFromOrders(@Param("siteIds") List<Integer> siteIds,
+ @Param("startTime") String startTime,
+ @Param("endTime") String endTime);
+
// 接口用: 日功率曲线(D 行按 period 分组)
List<Map<String, Object>> powerFromStat(@Param("siteIds") List<Integer> siteIds,
@Param("dayStart") String dayStart, @Param("dayEnd") String dayEnd);
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
index 38a1afb..af8c9c9 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -7082,26 +7082,27 @@
if (cached != null) {
return cached;
}
- LocalDate currentMonth = LocalDate.now().withDayOfMonth(1);
+ LocalDate currentDay = LocalDate.now();
List<SixChargingDto> result = new ArrayList<>();
try {
- String sixBeforeMonth = sixBefore.withDayOfMonth(1).format(LARGE_SCREEN_MONTH_FMT);
- List<SixChargingDto> incomeList = this.baseMapper.incomeTrendFromStat(siteIds, sixBeforeMonth);
- Map<String, SixChargingDto> incomeByMonth = new HashMap<>();
+ List<SixChargingDto> incomeList = this.baseMapper.incomeTrendFromOrders(siteIds,
+ sixBefore.atStartOfDay().format(LARGE_SCREEN_SQL_FMT),
+ currentDay.plusDays(1).atStartOfDay().format(LARGE_SCREEN_SQL_FMT));
+ Map<String, SixChargingDto> incomeByDay = new HashMap<>();
if (incomeList != null) {
for (SixChargingDto income : incomeList) {
if (income != null && income.getMonth() != null) {
- incomeByMonth.put(income.getMonth(), income);
+ incomeByDay.put(income.getMonth(), income);
}
}
}
- LocalDate month = sixBefore.withDayOfMonth(1);
- while (!month.isAfter(currentMonth)) {
- SixChargingDto income = incomeByMonth.get(month.format(LARGE_SCREEN_MONTH_FMT));
+ LocalDate day = sixBefore;
+ while (!day.isAfter(currentDay)) {
+ SixChargingDto income = incomeByDay.get(day.format(LARGE_SCREEN_DAY_FMT));
if (income == null) {
income = new SixChargingDto();
}
- income.setMonth(String.format("%02d", month.getMonthValue()));
+ income.setMonth(day.format(LARGE_SCREEN_DAY_FMT));
if (income.getElectrovalence() == null) {
income.setElectrovalence(BigDecimal.ZERO);
}
@@ -7109,18 +7110,18 @@
income.setServiceCharge(BigDecimal.ZERO);
}
result.add(income);
- month = month.plusMonths(1);
+ day = day.plusDays(1);
}
} catch (Exception e) {
log.warn("大屏收入趋势读取预聚合表失败, siteIds={}, sixBefore={}", siteIds, sixBefore, e);
- LocalDate month = sixBefore.withDayOfMonth(1);
- while (!month.isAfter(currentMonth)) {
+ LocalDate day = sixBefore;
+ while (!day.isAfter(currentDay)) {
SixChargingDto income = new SixChargingDto();
- income.setMonth(String.format("%02d", month.getMonthValue()));
+ income.setMonth(day.format(LARGE_SCREEN_DAY_FMT));
income.setElectrovalence(BigDecimal.ZERO);
income.setServiceCharge(BigDecimal.ZERO);
result.add(income);
- month = month.plusMonths(1);
+ day = day.plusDays(1);
}
}
redisService.setCacheObject(cacheKey, result, LARGE_SCREEN_CACHE_SECONDS, TimeUnit.SECONDS);
@@ -7333,9 +7334,11 @@
stat.put("orderCount", decimalValue(row, "order_count"));
stat.put("userCount", BigDecimal.ZERO);
stat.put("capacity", BigDecimal.ZERO);
- stat.put("electricFee", BigDecimal.ZERO);
- stat.put("serviceFee", BigDecimal.ZERO);
- stat.put("income", BigDecimal.ZERO);
+ BigDecimal electricFee = decimalValue(row, "electric_fee");
+ BigDecimal serviceFee = decimalValue(row, "service_fee");
+ stat.put("electricFee", electricFee);
+ stat.put("serviceFee", serviceFee);
+ stat.put("income", electricFee.add(serviceFee));
stat.put("totalPower", decimalValue(row, "total_power"));
stat.put("registeredUserCount", 0L);
statRows.add(stat);
@@ -7804,7 +7807,7 @@
List<LocalDate> dates = new ArrayList<>();
List<Integer> counts = new ArrayList<>();
LocalDate today = LocalDate.now();
- for (int i = 7; i >= 1; i--) {//升序
+ for (int i = 6; i >= 0; i--) {//升序,最近七日(含当天)
LocalDate day = today.minusDays(i);
LocalDateTime dayStart = day.atStartOfDay();
LocalDateTime dayEnd = day.plusDays(1).atStartOfDay();
diff --git a/ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TChargingOrderMapper.xml b/ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TChargingOrderMapper.xml
index b7148c7..934b64d 100644
--- a/ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TChargingOrderMapper.xml
+++ b/ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TChargingOrderMapper.xml
@@ -3444,16 +3444,25 @@
SELECT COUNT(*) FROM t_large_screen_user_site
</select>
- <!-- 任务用: 按日切片聚合, 口径与 getLargeScreenChargingPower 一致(无 status 过滤) -->
+ <!-- 任务用: 按日切片聚合,功率保持原口径;收入与月度切片一致。 -->
<select id="daySliceAgg" resultType="java.util.Map">
- SELECT site_id AS site_id,
+ SELECT charging_order.site_id AS site_id,
COUNT(1) AS order_count,
- COALESCE(SUM(IFNULL(power, 0)), 0) AS total_power
- FROM t_charging_order
- WHERE del_flag = 0
- AND create_time >= #{startTime}
- AND create_time < #{endTime}
- GROUP BY site_id
+ COALESCE(SUM(IFNULL(charging_order.power, 0)), 0) AS total_power,
+ COALESCE(ROUND(SUM(CASE WHEN charging_order.status = 5
+ AND charging_order.recharge_payment_status = 2 THEN accounting.period_electric_price ELSE 0 END), 2), 0) AS electric_fee,
+ COALESCE(ROUND(SUM(CASE WHEN charging_order.status = 5
+ AND charging_order.recharge_payment_status = 2 AND charging_order.order_source IN (0, 1) THEN accounting.period_service_price
+ WHEN charging_order.status = 5
+ AND charging_order.recharge_payment_status = 2 THEN accounting.period_service_price * 0.8
+ ELSE 0 END), 2), 0) AS service_fee
+ FROM t_charging_order charging_order
+ LEFT JOIN t_charging_order_accounting_strategy accounting
+ ON accounting.charging_order_id = charging_order.id
+ WHERE charging_order.del_flag = 0
+ AND charging_order.create_time >= #{startTime}
+ AND charging_order.create_time < #{endTime}
+ GROUP BY charging_order.site_id
</select>
<!-- 任务用: 注册用户总数 -->
@@ -3499,13 +3508,13 @@
</if>
</select>
- <!-- 接口用: 近 N 月收入趋势(M 行按 period 分组, period 为 yyyy-MM 字典序可比) -->
+ <!-- 接口用: 近 N 日收入趋势(D 行按 period 分组, period 为 yyyy-MM-dd 字典序可比) -->
<select id="incomeTrendFromStat" resultType="com.ruoyi.order.dto.SixChargingDto">
SELECT period AS month,
COALESCE(SUM(electric_fee), 0) AS electrovalence,
COALESCE(SUM(service_fee), 0) AS service_charge
FROM t_large_screen_site_stat
- WHERE stat_type = 'M'
+ WHERE stat_type = 'D'
AND period >= #{sixBefore}
<if test="siteIds != null and siteIds.size() > 0">
AND site_id IN
@@ -3516,6 +3525,30 @@
GROUP BY period
</select>
+ <!-- 接口用: 最近七日收入,直接查询确保历史日切片升级后也能立即显示正确金额。 -->
+ <select id="incomeTrendFromOrders" resultType="com.ruoyi.order.dto.SixChargingDto">
+ SELECT DATE_FORMAT(charging_order.create_time, '%Y-%m-%d') AS month,
+ COALESCE(ROUND(SUM(accounting.period_electric_price), 2), 0) AS electrovalence,
+ COALESCE(ROUND(SUM(CASE WHEN charging_order.order_source IN (0, 1) THEN accounting.period_service_price
+ ELSE accounting.period_service_price * 0.8 END), 2), 0) AS service_charge
+ FROM t_charging_order charging_order
+ LEFT JOIN t_charging_order_accounting_strategy accounting
+ ON accounting.charging_order_id = charging_order.id
+ WHERE charging_order.del_flag = 0
+ AND charging_order.status = 5
+ AND charging_order.recharge_payment_status = 2
+ AND charging_order.create_time >= #{startTime}
+ AND charging_order.create_time < #{endTime}
+ <if test="siteIds != null and siteIds.size() > 0">
+ AND charging_order.site_id IN
+ <foreach collection="siteIds" item="siteId" open="(" separator="," close=")">
+ #{siteId}
+ </foreach>
+ </if>
+ GROUP BY DATE_FORMAT(charging_order.create_time, '%Y-%m-%d')
+ ORDER BY month
+ </select>
+
<!-- 接口用: 日功率曲线(D 行按 period 分组, period 为 yyyy-MM-dd 字典序可比) -->
<select id="powerFromStat" resultType="java.util.Map">
SELECT period AS day,
diff --git a/sql/20260807_energy_storage_monitoring_menu.sql b/sql/20260807_energy_storage_monitoring_menu.sql
new file mode 100644
index 0000000..92bede8
--- /dev/null
+++ b/sql/20260807_energy_storage_monitoring_menu.sql
@@ -0,0 +1,87 @@
+-- 光储监控菜单调整:设备管理重命名,报表重命名,并将视频监控置于数据菜单首位。
+
+UPDATE sys_menu
+SET menu_name = '光储监控设备管理', update_time = NOW()
+WHERE parent_id = 0
+ AND menu_type = 'M'
+ AND (path = '/deviceManagement' OR perms = '/deviceManagement');
+
+SET @energy_data_id := (
+ SELECT menu_id
+ FROM sys_menu
+ WHERE parent_id = 0
+ AND menu_type = 'M'
+ AND (path = '/energyReport' OR perms = '/energyReport')
+ ORDER BY menu_id
+ LIMIT 1
+);
+
+UPDATE sys_menu
+SET menu_name = '光储监控数据', update_time = NOW()
+WHERE menu_id = @energy_data_id;
+
+INSERT INTO sys_menu
+ (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache,
+ menu_type, visible, status, perms, icon, create_by, create_time, remark)
+SELECT '视频监控', @energy_data_id, 1, '/videoMonitor', 'videoMonitor', NULL, 1, 0,
+ 'C', '0', 0, '/energyReport/videoMonitor', '#', 'admin', NOW(), '光储监控数据-视频监控'
+WHERE @energy_data_id IS NOT NULL
+ AND NOT EXISTS (
+ SELECT 1 FROM sys_menu
+ WHERE parent_id = @energy_data_id AND path = '/videoMonitor'
+ );
+
+SET @video_monitor_id := (
+ SELECT menu_id
+ FROM sys_menu
+ WHERE parent_id = @energy_data_id AND path = '/videoMonitor'
+ ORDER BY menu_id
+ LIMIT 1
+);
+
+UPDATE sys_menu
+SET menu_name = '视频监控', order_num = 1, component = 'videoMonitor', menu_type = 'C',
+ visible = '0', status = 0, perms = '/energyReport/videoMonitor', update_time = NOW()
+WHERE menu_id = @video_monitor_id;
+
+UPDATE sys_menu
+SET order_num = order_num + 1, update_time = NOW()
+WHERE parent_id = @energy_data_id
+ AND menu_id <> @video_monitor_id
+ AND order_num >= 1;
+
+-- 已拥有“光储监控数据”目录权限的角色同步获得视频监控权限。
+INSERT IGNORE INTO sys_role_menu (role_id, menu_id)
+SELECT role_id, @video_monitor_id
+FROM sys_role_menu
+WHERE menu_id = @energy_data_id;
+
+-- 光储监控设备管理的子菜单名称及顺序。
+SET @device_monitoring_id := (
+ SELECT menu_id FROM sys_menu
+ WHERE parent_id = 0
+ AND menu_type = 'M'
+ AND (path = '/deviceManagement' OR perms = '/deviceManagement')
+ ORDER BY menu_id
+ LIMIT 1
+);
+
+UPDATE sys_menu
+SET menu_name = '监控摄像头列表', order_num = 1, update_time = NOW()
+WHERE parent_id = @device_monitoring_id AND path = '/deviceManagement/list';
+
+UPDATE sys_menu
+SET menu_name = '光伏电站管理', order_num = 2, update_time = NOW()
+WHERE parent_id = @device_monitoring_id AND path = '/deviceManagement/photovoltaicStation/list';
+
+UPDATE sys_menu
+SET menu_name = '储能电站管理', order_num = 3, update_time = NOW()
+WHERE parent_id = @device_monitoring_id AND path = '/deviceManagement/energyStorage/list';
+
+UPDATE sys_menu
+SET menu_name = '光伏逆变器管理', order_num = 4, update_time = NOW()
+WHERE parent_id = @device_monitoring_id AND path = '/deviceManagement/photovoltaicInverter/list';
+
+UPDATE sys_menu
+SET menu_name = '储能能量链管理', order_num = 5, update_time = NOW()
+WHERE parent_id = @device_monitoring_id AND path = '/deviceManagement/energyChain/list';
--
Gitblit v1.7.1