|
|
@@ -0,0 +1,181 @@
|
|
|
+package com.zksy.web.controller.gasbasic;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.zksy.base.alarm.domain.AlarmData;
|
|
|
+import com.zksy.base.alarm.service.AlarmDataService;
|
|
|
+import com.zksy.base.domain.EquipmentBase;
|
|
|
+import com.zksy.base.domain.EquipmentType;
|
|
|
+import com.zksy.base.mapper.EquipmentBaseMapper;
|
|
|
+import com.zksy.base.mapper.EquipmentTypeMapper;
|
|
|
+import com.zksy.base.constant.GasEquipmentTypeEnum;
|
|
|
+import com.zksy.common.annotation.Anonymous;
|
|
|
+import com.zksy.common.core.domain.AjaxResult;
|
|
|
+import io.swagger.annotations.Api;
|
|
|
+import io.swagger.annotations.ApiOperation;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.web.bind.annotation.*;
|
|
|
+
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 可燃气体浓度报警
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@RestController
|
|
|
+@RequestMapping("/api/gas-alarm")
|
|
|
+@Api(tags = "燃气监测-可燃气体报警")
|
|
|
+public class GasAlarmController {
|
|
|
+
|
|
|
+ @Autowired private AlarmDataService alarmDataService;
|
|
|
+ @Autowired private EquipmentTypeMapper equipmentTypeMapper;
|
|
|
+ @Autowired private EquipmentBaseMapper equipmentBaseMapper;
|
|
|
+
|
|
|
+ /** 获取燃气探测器设备编码集合 (type_id = gas_detector) */
|
|
|
+ private Set<String> getDetectorCodes() {
|
|
|
+ List<EquipmentType> types = equipmentTypeMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<EquipmentType>().eq(EquipmentType::getTypeId, GasEquipmentTypeEnum.GAS_DETECTOR));
|
|
|
+ Set<String> detectorTypeIds = types.stream().map(EquipmentType::getId).collect(Collectors.toSet());
|
|
|
+ List<EquipmentBase> eqs = detectorTypeIds.isEmpty()
|
|
|
+ ? Collections.emptyList()
|
|
|
+ : equipmentBaseMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<EquipmentBase>().in(EquipmentBase::getEquipmentTypeId, detectorTypeIds));
|
|
|
+ return eqs.stream().map(EquipmentBase::getEquipmentCode).filter(Objects::nonNull).collect(Collectors.toSet());
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 加载设备编码→设备信息映射 */
|
|
|
+ private Map<String, EquipmentBase> loadEquipMap() {
|
|
|
+ return equipmentBaseMapper.selectList(null).stream()
|
|
|
+ .collect(Collectors.toMap(EquipmentBase::getEquipmentCode, e -> e, (a, b) -> a));
|
|
|
+ }
|
|
|
+
|
|
|
+ private static final java.time.format.DateTimeFormatter FMT = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
+
|
|
|
+ private Map<String, Object> toVo(AlarmData a, Map<String, EquipmentBase> eqMap) {
|
|
|
+ EquipmentBase eq = eqMap.get(a.getDeviceCode());
|
|
|
+ Map<String, Object> m = new LinkedHashMap<>();
|
|
|
+ m.put("id", a.getId());
|
|
|
+ m.put("deviceCode", a.getDeviceCode());
|
|
|
+ m.put("stationName", eq != null ? eq.getEquipmentName() : a.getDeviceCode());
|
|
|
+ m.put("address", eq != null ? eq.getEquipmentLocation() : "");
|
|
|
+ m.put("concentration", a.getActualValue());
|
|
|
+ m.put("threshold", a.getMaxValue());
|
|
|
+ m.put("alarmLevel", a.getAlarmLevel());
|
|
|
+ m.put("alarmLevelText", a.getAlarmLevel() != null && a.getAlarmLevel() == 1 ? "严重" : "预警");
|
|
|
+ m.put("alarmTime", a.getAlarmTime() != null ? a.getAlarmTime().format(FMT) : "");
|
|
|
+ m.put("alarmStatus", a.getAlarmStatus());
|
|
|
+ m.put("statusText", a.getAlarmStatus() != null && a.getAlarmStatus() == 0 ? "待处理" : "已处理");
|
|
|
+ m.put("resolveTime", a.getHandleTime() != null ? a.getHandleTime().format(FMT) : null);
|
|
|
+ m.put("handler", a.getHandleUser());
|
|
|
+ m.put("remark", a.getHandleRemark());
|
|
|
+ return m;
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 获取所有探测器设备(去重),含最新报警数据 */
|
|
|
+ @GetMapping("/equipment")
|
|
|
+ @ApiOperation("燃气探测器设备列表(含最新报警值)")
|
|
|
+ @Anonymous
|
|
|
+ public AjaxResult equipment() {
|
|
|
+ Set<String> codes = getDetectorCodes();
|
|
|
+ List<EquipmentBase> eqs = equipmentBaseMapper.selectList(null).stream()
|
|
|
+ .filter(e -> codes.contains(e.getEquipmentCode())).collect(Collectors.toList());
|
|
|
+ // 查所有报警,按设备聚合最新一条
|
|
|
+ List<AlarmData> allAlarms = codes.isEmpty() ? Collections.emptyList()
|
|
|
+ : alarmDataService.list(new LambdaQueryWrapper<AlarmData>().in(AlarmData::getDeviceCode, codes)
|
|
|
+ .orderByDesc(AlarmData::getAlarmTime));
|
|
|
+ Map<String, AlarmData> latestMap = allAlarms.stream()
|
|
|
+ .collect(Collectors.toMap(AlarmData::getDeviceCode, a -> a, (a, b) -> a));
|
|
|
+
|
|
|
+ List<Map<String, Object>> rows = new ArrayList<>();
|
|
|
+ for (EquipmentBase eq : eqs) {
|
|
|
+ AlarmData latest = latestMap.get(eq.getEquipmentCode());
|
|
|
+ Map<String, Object> m = new LinkedHashMap<>();
|
|
|
+ m.put("equipmentId", eq.getEquipmentId());
|
|
|
+ m.put("equipmentCode", eq.getEquipmentCode());
|
|
|
+ m.put("equipmentName", eq.getEquipmentName());
|
|
|
+ m.put("location", eq.getEquipmentLocation());
|
|
|
+ m.put("hasAlarm", latest != null && latest.getAlarmStatus() != null && latest.getAlarmStatus() == 0);
|
|
|
+ m.put("latestConcentration", latest != null ? latest.getActualValue() : null);
|
|
|
+ m.put("latestThreshold", latest != null ? latest.getMaxValue() : null);
|
|
|
+ m.put("latestAlarmTime", latest != null && latest.getAlarmTime() != null ? latest.getAlarmTime().format(FMT) : null);
|
|
|
+ m.put("latestAlarmLevel", latest != null ? latest.getAlarmLevel() : null);
|
|
|
+ rows.add(m);
|
|
|
+ }
|
|
|
+ return AjaxResult.success(rows);
|
|
|
+ }
|
|
|
+
|
|
|
+ @GetMapping("/history")
|
|
|
+ @ApiOperation("历史报警分页(支持按设备筛选)")
|
|
|
+ @Anonymous
|
|
|
+ public AjaxResult history(@RequestParam(defaultValue = "1") int pageNum,
|
|
|
+ @RequestParam(defaultValue = "8") int pageSize,
|
|
|
+ @RequestParam(required = false) String startDate,
|
|
|
+ @RequestParam(required = false) String endDate,
|
|
|
+ @RequestParam(required = false) String deviceCode) {
|
|
|
+ LambdaQueryWrapper<AlarmData> qw = new LambdaQueryWrapper<AlarmData>();
|
|
|
+ if (deviceCode != null && !deviceCode.isEmpty()) {
|
|
|
+ qw.eq(AlarmData::getDeviceCode, deviceCode);
|
|
|
+ } else {
|
|
|
+ Set<String> codes = getDetectorCodes();
|
|
|
+ if (codes.isEmpty()) return AjaxResult.success(new Page<>(pageNum, pageSize, 0));
|
|
|
+ qw.in(AlarmData::getDeviceCode, codes);
|
|
|
+ }
|
|
|
+ if (startDate != null && !startDate.isEmpty()) qw.ge(AlarmData::getAlarmTime, startDate + " 00:00:00");
|
|
|
+ if (endDate != null && !endDate.isEmpty()) qw.le(AlarmData::getAlarmTime, endDate + " 23:59:59");
|
|
|
+ qw.orderByDesc(AlarmData::getAlarmTime);
|
|
|
+ Page<AlarmData> page = alarmDataService.page(new Page<>(pageNum, pageSize), qw);
|
|
|
+ Map<String, EquipmentBase> eqMap = loadEquipMap();
|
|
|
+ List<Map<String, Object>> rows = page.getRecords().stream().map(a -> toVo(a, eqMap)).collect(Collectors.toList());
|
|
|
+ Map<String, Object> result = new LinkedHashMap<>();
|
|
|
+ result.put("records", rows);
|
|
|
+ result.put("total", page.getTotal());
|
|
|
+ return AjaxResult.success(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ @GetMapping("/stats")
|
|
|
+ @ApiOperation("报警统计")
|
|
|
+ @Anonymous
|
|
|
+ public AjaxResult stats() {
|
|
|
+ Set<String> codes = getDetectorCodes();
|
|
|
+ List<AlarmData> all = codes.isEmpty() ? Collections.emptyList()
|
|
|
+ : alarmDataService.list(new LambdaQueryWrapper<AlarmData>().in(AlarmData::getDeviceCode, codes));
|
|
|
+ long realtime = all.stream().filter(a -> a.getAlarmStatus() != null && a.getAlarmStatus() == 0)
|
|
|
+ .map(AlarmData::getDeviceCode).filter(Objects::nonNull).distinct().count();
|
|
|
+ AlarmData maxAlarm = all.stream().filter(a -> a.getActualValue() != null)
|
|
|
+ .max(Comparator.comparing(a -> a.getActualValue())).orElse(null);
|
|
|
+ double maxConc = maxAlarm != null ? maxAlarm.getActualValue().doubleValue() : 0;
|
|
|
+ String maxDevice = maxAlarm != null ? maxAlarm.getDeviceCode() : "";
|
|
|
+ Map<String, EquipmentBase> eqMap = loadEquipMap();
|
|
|
+ EquipmentBase maxEq = eqMap.get(maxDevice);
|
|
|
+ Map<String, Object> r = new LinkedHashMap<>();
|
|
|
+ r.put("realtimeCount", realtime);
|
|
|
+ r.put("pendingCount", (int) realtime);
|
|
|
+ r.put("maxConcentration", (int) maxConc);
|
|
|
+ r.put("maxConcentrationPoint", maxEq != null ? maxEq.getEquipmentName() : maxDevice);
|
|
|
+ r.put("totalStations", codes.size());
|
|
|
+ return AjaxResult.success(r);
|
|
|
+ }
|
|
|
+
|
|
|
+ @PutMapping("/resolve/{id}")
|
|
|
+ @ApiOperation("标记已处理")
|
|
|
+ @Anonymous
|
|
|
+ public AjaxResult resolve(@PathVariable String id) {
|
|
|
+ AlarmData e = alarmDataService.getById(id);
|
|
|
+ if (e == null) return AjaxResult.error("记录不存在");
|
|
|
+ e.setAlarmStatus(1);
|
|
|
+ e.setHandleTime(java.time.LocalDateTime.now());
|
|
|
+ e.setHandleUser("当前用户");
|
|
|
+ alarmDataService.updateById(e);
|
|
|
+ return AjaxResult.success("已处理");
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping("/dispatch/{id}")
|
|
|
+ @ApiOperation("派发工单(伪)")
|
|
|
+ @Anonymous
|
|
|
+ public AjaxResult dispatch(@PathVariable String id) {
|
|
|
+ // TODO: 后续调用工单系统接口实现真正的派单逻辑
|
|
|
+ return AjaxResult.success("工单已派发(伪)");
|
|
|
+ }
|
|
|
+}
|