#10 总览+在线监测: - DashboardService: 今日进出水量/设备概况/能耗药耗/实时监测列表(多维筛选) - VideoService: 视频监控点位+AI人员闯入检测(YOLO mock) #11 水质管控+报警: - WaterQualityService: 全工艺药剂投加监控(混凝/沉淀/过滤/消毒) + 水质台账 - AlertEngine: 报警规则检测/去重/确认/派单/分级(info/warning/critical/emergency) #12 调度工作台+调度业务: - DispatchService: 值班管理(开始/结束/交接) + 指令创建/下发/跟踪 - 应急推演: 爆管模拟(影响区域+关阀方案+恢复时间) + 水质异常处置 #13 数据中心+配置: - DataCenterService: 历史数据查看/报表生成(水量/水质/报警) + 阈值管理 + 信息发布 #15 巡检管理: - PatrolService: 路线CRUD/任务分派/开始-完成/巡检记录/问题上报(自动创建工单) - 统计分析: 执行率/人员里程/工作量/问题分类 ProductionController + PatrolController: 完整 REST API
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
package com.water.patrol.controller;
|
||||
|
||||
import com.water.common.core.result.R;
|
||||
import com.water.patrol.service.PatrolService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.*;
|
||||
|
||||
@Tag(name = "巡检管理")
|
||||
@RestController
|
||||
@RequestMapping("/patrol")
|
||||
@RequiredArgsConstructor
|
||||
public class PatrolController {
|
||||
|
||||
private final PatrolService patrolService;
|
||||
|
||||
// ---- 路线 ----
|
||||
@PostMapping("/route")
|
||||
public R<Map<String, Object>> createRoute(@RequestBody Map<String, Object> req) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> points = (List<Map<String, Object>>) req.getOrDefault("points", List.of());
|
||||
return R.ok(patrolService.createRoute(
|
||||
(String) req.get("routeName"), (String) req.get("area"),
|
||||
points, (int) req.getOrDefault("estimDuration", 60)));
|
||||
}
|
||||
|
||||
@GetMapping("/route/list")
|
||||
public R<List<Map<String, Object>>> routes(@RequestParam String area) {
|
||||
return R.ok(patrolService.getRoutes(area));
|
||||
}
|
||||
|
||||
// ---- 任务 ----
|
||||
@PostMapping("/task")
|
||||
public R<Map<String, Object>> createTask(@RequestBody Map<String, Object> req) {
|
||||
return R.ok(patrolService.createTask(
|
||||
Long.parseLong(String.valueOf(req.get("routeId"))),
|
||||
Long.parseLong(String.valueOf(req.get("assigneeId"))),
|
||||
(String) req.get("taskDate")));
|
||||
}
|
||||
|
||||
@GetMapping("/task/today")
|
||||
public R<List<Map<String, Object>>> todayTasks(@RequestParam Long userId) {
|
||||
return R.ok(patrolService.getTodayTasks(userId));
|
||||
}
|
||||
|
||||
@PutMapping("/task/{id}/start")
|
||||
public R<Map<String, Object>> startTask(@PathVariable Long id) {
|
||||
return R.ok(patrolService.startTask(id));
|
||||
}
|
||||
|
||||
@PutMapping("/task/{id}/complete")
|
||||
public R<Map<String, Object>> completeTask(@PathVariable Long id, @RequestParam double distance) {
|
||||
return R.ok(patrolService.completeTask(id, distance));
|
||||
}
|
||||
|
||||
// ---- 巡检记录 ----
|
||||
@PostMapping("/record")
|
||||
public R<Map<String, Object>> record(@RequestBody Map<String, Object> req) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> items = (List<Map<String, Object>>) req.getOrDefault("checkItems", List.of());
|
||||
return R.ok(patrolService.recordCheck(
|
||||
Long.parseLong(String.valueOf(req.get("taskId"))),
|
||||
(int) req.get("pointSeq"),
|
||||
req.get("deviceId") != null ? Long.parseLong(String.valueOf(req.get("deviceId"))) : null,
|
||||
items,
|
||||
((Number) req.get("lng")).doubleValue(),
|
||||
((Number) req.get("lat")).doubleValue()));
|
||||
}
|
||||
|
||||
@GetMapping("/record/list/{taskId}")
|
||||
public R<List<Map<String, Object>>> records(@PathVariable Long taskId) {
|
||||
return R.ok(patrolService.getTaskRecords(taskId));
|
||||
}
|
||||
|
||||
// ---- 问题上报 ----
|
||||
@PostMapping("/issue/report")
|
||||
public R<Map<String, Object>> reportIssue(@RequestBody Map<String, Object> req) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> photos = (List<String>) req.getOrDefault("photoUrls", List.of());
|
||||
return R.ok(patrolService.reportIssue(
|
||||
Long.parseLong(String.valueOf(req.get("taskId"))),
|
||||
req.get("deviceId") != null ? Long.parseLong(String.valueOf(req.get("deviceId"))) : null,
|
||||
(String) req.get("issueType"), (String) req.get("description"),
|
||||
photos,
|
||||
((Number) req.get("lng")).doubleValue(),
|
||||
((Number) req.get("lat")).doubleValue()));
|
||||
}
|
||||
|
||||
// ---- 统计 ----
|
||||
@GetMapping("/stats")
|
||||
public R<Map<String, Object>> stats(@RequestParam String area,
|
||||
@RequestParam String start,
|
||||
@RequestParam String end) {
|
||||
return R.ok(patrolService.getStats(area, LocalDate.parse(start), LocalDate.parse(end)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package com.water.patrol.service;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PatrolService {
|
||||
|
||||
private final JdbcTemplate jdbc;
|
||||
|
||||
// ========== 路线管理 ==========
|
||||
public Map<String, Object> createRoute(String routeName, String area, List<Map<String, Object>> points, int estimDuration) {
|
||||
jdbc.update("INSERT INTO patrol_route (route_name, area, route_points, estim_duration) VALUES (?,?,?::jsonb,?)",
|
||||
routeName, area, points.toString(), estimDuration);
|
||||
return Map.of("routeName", routeName, "area", area, "points", points.size());
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> getRoutes(String area) {
|
||||
return jdbc.queryForList("SELECT * FROM patrol_route WHERE area = ? AND status = 1", area);
|
||||
}
|
||||
|
||||
// ========== 任务管理 ==========
|
||||
public Map<String, Object> createTask(Long routeId, Long assigneeId, String taskDate) {
|
||||
jdbc.update(
|
||||
"INSERT INTO patrol_task (route_id, assignee_id, task_name, task_date, plan_start, plan_end, status) " +
|
||||
"SELECT ?, ?, route_name, ?, CAST(? AS TIMESTAMP), CAST(? AS TIMESTAMP) + (estim_duration || ' minutes')::INTERVAL, 'pending' " +
|
||||
"FROM patrol_route WHERE id = ?",
|
||||
routeId, assigneeId, taskDate, taskDate + " 09:00:00", taskDate + " 09:00:00", routeId);
|
||||
return Map.of("routeId", routeId, "assigneeId", assigneeId, "date", taskDate, "status", "created");
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> getTodayTasks(Long userId) {
|
||||
return jdbc.queryForList(
|
||||
"SELECT pt.*, pr.route_name, pr.area FROM patrol_task pt " +
|
||||
"LEFT JOIN patrol_route pr ON pt.route_id = pr.id " +
|
||||
"WHERE pt.task_date = CURRENT_DATE AND pt.assignee_id = ? " +
|
||||
"ORDER BY pt.plan_start", userId);
|
||||
}
|
||||
|
||||
public Map<String, Object> startTask(Long taskId) {
|
||||
jdbc.update("UPDATE patrol_task SET status = 'in_progress', actual_start = NOW() WHERE id = ?", taskId);
|
||||
return Map.of("taskId", taskId, "status", "in_progress", "startedAt", new Date());
|
||||
}
|
||||
|
||||
public Map<String, Object> completeTask(Long taskId, double distance) {
|
||||
jdbc.update(
|
||||
"UPDATE patrol_task SET status = 'completed', actual_end = NOW(), distance = ? WHERE id = ?",
|
||||
distance, taskId);
|
||||
return Map.of("taskId", taskId, "status", "completed", "distance", distance);
|
||||
}
|
||||
|
||||
// ========== 巡检记录 ==========
|
||||
public Map<String, Object> recordCheck(Long taskId, int pointSeq, Long deviceId,
|
||||
List<Map<String, Object>> checkItems,
|
||||
double lng, double lat) {
|
||||
jdbc.update(
|
||||
"INSERT INTO patrol_record (task_id, point_seq, device_id, check_items, gps_lng, gps_lat, record_time) " +
|
||||
"VALUES (?,?,?,?::jsonb,?,?,NOW())",
|
||||
taskId, pointSeq, deviceId, checkItems.toString(), lng, lat);
|
||||
return Map.of("taskId", taskId, "pointSeq", pointSeq, "recorded", true);
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> getTaskRecords(Long taskId) {
|
||||
return jdbc.queryForList(
|
||||
"SELECT * FROM patrol_record WHERE task_id = ? ORDER BY point_seq", taskId);
|
||||
}
|
||||
|
||||
// ========== 问题上报(巡检APP) ==========
|
||||
public Map<String, Object> reportIssue(Long taskId, Long deviceId, String issueType,
|
||||
String description, List<String> photoUrls,
|
||||
double lng, double lat) {
|
||||
// 自动创建工单
|
||||
jdbc.update(
|
||||
"INSERT INTO patrol_task (task_name, assignee_id, task_date, status) " +
|
||||
"SELECT CONCAT('问题处理: ', ?), assignee_id, CURRENT_DATE, 'pending' FROM patrol_task WHERE id = ?",
|
||||
issueType + ": " + description.substring(0, Math.min(description.length(), 50)), taskId);
|
||||
|
||||
log.info("Issue reported: type={} desc={}", issueType, description);
|
||||
return Map.of("reported", true, "issueType", issueType, "photos", photoUrls);
|
||||
}
|
||||
|
||||
// ========== 统计分析 ==========
|
||||
public Map<String, Object> getStats(String area, LocalDate start, LocalDate end) {
|
||||
Map<String, Object> stats = new LinkedHashMap<>();
|
||||
|
||||
// 任务执行率
|
||||
stats.put("completionRate", jdbc.queryForMap(
|
||||
"SELECT COUNT(*) as total, SUM(CASE WHEN status='completed' THEN 1 ELSE 0 END) as completed " +
|
||||
"FROM patrol_task WHERE task_date BETWEEN ? AND ?", start, end));
|
||||
|
||||
// 人员里程
|
||||
stats.put("personDistance", jdbc.queryForList(
|
||||
"SELECT u.real_name, SUM(pt.distance) as total_km " +
|
||||
"FROM patrol_task pt JOIN sys_user u ON pt.assignee_id = u.id " +
|
||||
"WHERE pt.task_date BETWEEN ? AND ? GROUP BY u.id, u.real_name", start, end));
|
||||
|
||||
// 巡检工作量
|
||||
stats.put("workload", jdbc.queryForList(
|
||||
"SELECT task_date, COUNT(*) as tasks, SUM(distance) as total_km " +
|
||||
"FROM patrol_task WHERE task_date BETWEEN ? AND ? GROUP BY task_date ORDER BY task_date",
|
||||
start, end));
|
||||
|
||||
// 问题分类统计
|
||||
stats.put("issueStats", jdbc.queryForList(
|
||||
"SELECT SUBSTRING(task_name FROM '^[^:]+') as issue_type, COUNT(*) as count " +
|
||||
"FROM patrol_task WHERE task_name LIKE '%问题处理:%' AND task_date BETWEEN ? AND ? GROUP BY 1",
|
||||
start, end));
|
||||
|
||||
return stats;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user