package com.ruoyi.energymeter.controller; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.energymeter.dto.EnergyMeterDeviceQuery; import com.ruoyi.energymeter.dto.MeterBindRequest; import com.ruoyi.energymeter.dto.MeterCollectRequest; import com.ruoyi.energymeter.dto.MeterManualBindRequest; import com.ruoyi.energymeter.dto.MeterReadingRequest; import com.ruoyi.energymeter.dto.MeterUpdateRequest; import com.ruoyi.energymeter.dto.MeterVerifyRequest; import com.ruoyi.energymeter.pojo.EnergyMeterDevice; import com.ruoyi.energymeter.pojo.EnergyMeterMeasurement; import com.ruoyi.energymeter.service.EnergyMeterDeviceService; import com.ruoyi.energymeter.service.EnergyMeterDemoService; import com.ruoyi.energymeter.service.EnergyMeterStatService; import com.ruoyi.energymeter.service.EnergyMeterSyncService; import com.ruoyi.energymeter.service.ElectricMeterDashboardService; import com.ruoyi.energymeter.util.EnergyMeterSupport; import com.ruoyi.framework.aspectj.lang.annotation.Log; import com.ruoyi.framework.aspectj.lang.enums.BusinessType; import com.ruoyi.framework.web.controller.BaseController; import com.ruoyi.framework.web.domain.AjaxResult; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.RestController; import java.time.LocalDate; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** * 水电表接入与查表接口。 * *

前端只调用本系统后端,第三方授权码不会下发到浏览器。

*/ @RestController @Tag(name = "水电表监测") @RequestMapping("/energyMeter") @RequiredArgsConstructor public class EnergyMeterController extends BaseController { private final EnergyMeterDeviceService deviceService; private final EnergyMeterSyncService syncService; private final EnergyMeterStatService statService; private final EnergyMeterDemoService demoService; private final ElectricMeterDashboardService electricDashboardService; @GetMapping("/devices") @Operation(summary = "设备列表-分页查询") @Log(title = "水电表监测-设备列表", businessType = BusinessType.OTHER) public AjaxResult devices(Page page, EnergyMeterDeviceQuery query) { IPage result = deviceService.pageDevices(page, query); return AjaxResult.success(result); } @GetMapping("/devices/options") @Operation(summary = "设备下拉选项") public AjaxResult deviceOptions(@RequestParam(required = false) String meterType) { return AjaxResult.success(deviceService.listDeviceOptions(meterType)); } @PostMapping("/devices/verify") @Operation(summary = "验证并读取第三方档案") @Log(title = "水电表监测-档案验证", businessType = BusinessType.OTHER) public AjaxResult verify(@RequestBody MeterVerifyRequest request) { return AjaxResult.success(deviceService.verifyArchive(request.getMeterType(), request.getMeterAddress())); } @PostMapping("/devices") @Operation(summary = "新增本地绑定") @Log(title = "水电表监测-新增绑定", businessType = BusinessType.INSERT) public AjaxResult add(@RequestBody MeterBindRequest request) { return AjaxResult.success(deviceService.bind(request)); } @PutMapping("/devices/{id}") @Operation(summary = "修改设备本地字段/启停用") @Log(title = "表具台账-修改设备", businessType = BusinessType.UPDATE) public AjaxResult update(@PathVariable Long id, @RequestBody MeterUpdateRequest request) { return AjaxResult.success(deviceService.updateLocal(id, request)); } @PostMapping("/devices/manual") @Operation(summary = "新增手工抄表设备(水表/电表/气表)") @Log(title = "表具台账-新增手工抄表设备", businessType = BusinessType.INSERT) public AjaxResult addManual(@RequestBody MeterManualBindRequest request) { return AjaxResult.success(deviceService.addManual(request)); } @DeleteMapping("/devices/{id}") @Operation(summary = "删除设备(初始化设备与第三方接入设备不允许删除)") @Log(title = "表具台账-删除设备", businessType = BusinessType.DELETE) public AjaxResult remove(@PathVariable Long id) { deviceService.removeDevice(id); return AjaxResult.success(); } @GetMapping("/devices/{id}/readings") @Operation(summary = "手工抄表记录分页") public AjaxResult readings(@PathVariable Long id, @RequestParam(defaultValue = "1") long current, @RequestParam(defaultValue = "20") long size) { return AjaxResult.success(deviceService.pageReadings(id, current, size)); } @PostMapping("/devices/{id}/readings") @Operation(summary = "录入手工抄表表码") @Log(title = "表具台账-手工录表", businessType = BusinessType.INSERT) public AjaxResult addReading(@PathVariable Long id, @RequestBody MeterReadingRequest request) { return AjaxResult.success(deviceService.addReading(id, request)); } @DeleteMapping("/devices/{id}/readings/{readingId}") @Operation(summary = "删除手工抄表记录") @Log(title = "表具台账-删除抄表记录", businessType = BusinessType.DELETE) public AjaxResult removeReading(@PathVariable Long id, @PathVariable Long readingId) { deviceService.removeReading(id, readingId); return AjaxResult.success(); } @PostMapping("/devices/{id}/collect") @Operation(summary = "单台设备手动查表") @Log(title = "水电表监测-手动查表", businessType = BusinessType.OTHER) public AjaxResult collect(@PathVariable Long id, @RequestBody(required = false) MeterCollectRequest request) { LocalDate start = request == null ? null : request.getStartDate(); LocalDate end = request == null ? null : request.getEndDate(); Boolean includeReadings = request == null ? null : request.getIncludeReadings(); Long runId = syncService.triggerManual(List.of(id), start, end, includeReadings); return AjaxResult.success(runResult(runId)); } @PostMapping("/devices/collect") @Operation(summary = "批量手动查表") @Log(title = "水电表监测-批量查表", businessType = BusinessType.OTHER) public AjaxResult collectBatch(@RequestBody MeterCollectRequest request) { List meterIds = new ArrayList<>(); if (request.getMeterIds() != null) { meterIds.addAll(request.getMeterIds()); } if (request.getMeterId() != null && !meterIds.contains(request.getMeterId())) { meterIds.add(request.getMeterId()); } Long runId = syncService.triggerManual(meterIds, request.getStartDate(), request.getEndDate(), request.getIncludeReadings()); return AjaxResult.success(runResult(runId)); } @GetMapping("/devices/{id}/measurements") @Operation(summary = "设备读数/用量明细") public AjaxResult measurements(@PathVariable Long id, @RequestParam(required = false) String metricCode, @RequestParam(required = false) String granularity, @RequestParam(required = false) String start, @RequestParam(required = false) String end, @RequestParam(defaultValue = "1") long current, @RequestParam(defaultValue = "20") long size) { IPage page = statService.pageMeasurements(id, metricCode, granularity, parseDate(start), parseDate(end), current, size); return AjaxResult.success(page); } @GetMapping("/overview") @Operation(summary = "用能概览") public AjaxResult overview(@RequestParam(defaultValue = "WATER") String meterType, @RequestParam(required = false) Long meterId, @RequestParam(required = false) String month, @RequestParam(required = false) Integer year) { return AjaxResult.success(statService.overview(meterType, meterId, month, year)); } @GetMapping("/electric/dashboard") @Operation(summary = "电表实时看板:今日15分钟曲线与电能质量") public AjaxResult electricDashboard(@RequestParam(required = false) Long meterId, @RequestParam(defaultValue = "0") Integer weekOffset) { return AjaxResult.success(electricDashboardService.dashboard(meterId, weekOffset)); } @PostMapping("/sync/trigger") @Operation(summary = "手动触发一次每日同步(排障用)") @Log(title = "水电表监测-触发同步", businessType = BusinessType.OTHER) public AjaxResult triggerDailySync() { return AjaxResult.success(runResult(syncService.triggerScheduledSync())); } @PostMapping("/sync/recover") @Operation(summary = "手动触发一次重试/超时恢复(排障用)") @Log(title = "水电表监测-触发恢复", businessType = BusinessType.OTHER) public AjaxResult recoverSync() { Map data = new LinkedHashMap<>(); data.put("handled", syncService.recoverDueTasks()); return AjaxResult.success(data); } @GetMapping("/providerStatus") @Operation(summary = "第三方接入模式") public AjaxResult providerStatus() { Map data = new LinkedHashMap<>(); data.put("mockMode", deviceService.mockMode()); return AjaxResult.success(data); } @PostMapping("/sync/gasSimulate") @Operation(summary = "生成气表演示数据(按天,默认今天;同一天重复执行不会重复写入)") @Log(title = "表具台账-气表演示数据", businessType = BusinessType.OTHER) public AjaxResult gasSimulate(@RequestParam(required = false) String date) { LocalDate day = StringUtils.isBlank(date) ? EnergyMeterSupport.today() : parseDate(date); Map data = new LinkedHashMap<>(); data.put("date", day.toString()); data.put("generated", demoService.generateGasDemo(day)); return AjaxResult.success(data); } private Map runResult(Long runId) { Map data = new LinkedHashMap<>(); data.put("runId", runId); return data; } private LocalDate parseDate(String value) { if (StringUtils.isBlank(value)) { return null; } try { return LocalDate.parse(value.trim()); } catch (Exception e) { throw new ServiceException("日期格式应为 yyyy-MM-dd"); } } }