| | |
| | | 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") |
| | |
| | | */ |
| | | ChargeMonitoring chargeMonitoring(Integer siteId); |
| | | |
| | | /** 智慧充电大屏监控数据,不按菜单权限过滤站点。 */ |
| | | ChargeMonitoring chargeMonitoringForScreen(Integer siteId); |
| | | |
| | | List<Site> getChargingMonitoringSiteList(); |
| | | |
| | | |
| | |
| | | @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)); |
| | |
| | | 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 = "停车场充电功率曲线图") |
| | |
| | | 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); |
| | |
| | | // 接口用: 近 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); |
| | |
| | | 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); |
| | | } |
| | |
| | | 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); |
| | |
| | | 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); |
| | |
| | | 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(); |
| | |
| | | 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> |
| | | |
| | | <!-- 任务用: 注册用户总数 --> |
| | |
| | | </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 |
| | |
| | | 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, |
| New file |
| | |
| | | -- 光储监控菜单调整:设备管理重命名,报表重命名,并将视频监控置于数据菜单首位。 |
| | | |
| | | 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'; |