diff --git a/inspect-main/inspect-main-api/src/main/java/com/inspect/api/service/TaskStatusDeletePushService.java b/inspect-main/inspect-main-api/src/main/java/com/inspect/api/service/TaskStatusDeletePushService.java new file mode 100644 index 0000000..d755fcb --- /dev/null +++ b/inspect-main/inspect-main-api/src/main/java/com/inspect/api/service/TaskStatusDeletePushService.java @@ -0,0 +1,147 @@ +package com.inspect.api.service; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.inspect.api.domain.ApiResult; +import com.inspect.api.domain.AuthTokenData; +import com.inspect.base.core.utils.DateUtils; +import com.inspect.base.core.utils.StringUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 动环删除数据推送服务(通知中恒) + *

+ * 删除任务状态数据后,POST jb-nessp-external/api/mqtt/sendTopic 发送 MQTT 消息: + * 请求头携带 joinbright-token(复用 {@link ExtAuthService}), + * body 为 {@code {"message":"业务消息JSON字符串","topic":"topic/env/delete"}}。 + *

+ * 业务消息字段见《动环删除数据推送信息字段说明》: + *

+ * {"idType":"TASK","stationCode":"CZ000000004","ids":["123456789"],"deleteTime":"2026-08-19 10:00:00"}
+ * 
+ * 推送失败只记日志,不影响删除结果。 + */ +@Slf4j +@Service +public class TaskStatusDeletePushService { + + /** token 请求头名称(外部平台固定) */ + private static final String TOKEN_HEADER = "joinbright-token"; + + /** MQTT 消息发送接口地址 */ + @Value("${inspect.taskStatus-delete-push.send-topic-url:http://192.168.129.2:32799/jb-gateway/jb-nessp-external/api/mqtt/sendTopic}") + private String sendTopicUrl; + + /** 推送主题 */ + @Value("${inspect.taskStatus-delete-push.topic:topic/env/delete}") + private String topic; + + /** http 连接/读取超时(秒) */ + @Value("${inspect.taskStatus-delete-push.http-timeout-seconds:30}") + private int httpTimeoutSeconds; + + private final ExtAuthService extAuthService; + + public TaskStatusDeletePushService(ExtAuthService extAuthService) { + this.extAuthService = extAuthService; + } + + /** + * 推送删除消息,ids 取 patrol_task_status.task_patrolled_id + * + * @return 是否推送成功 + */ + public boolean pushTaskDelete(String stationCode, List taskPatrolledIds) { + if (StringUtils.isEmpty(stationCode) || taskPatrolledIds == null || taskPatrolledIds.isEmpty()) { + log.error("[TASK_STATUS_DELETE] 推送参数为空, stationCode: {}, ids: {}", stationCode, taskPatrolledIds); + return false; + } + // 业务消息体 + JSONObject message = new JSONObject(true); + message.put("idType", "TASK"); + message.put("stationCode", stationCode); + message.put("ids", new JSONArray(new ArrayList<>(taskPatrolledIds))); + message.put("deleteTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, new Date())); + + // 接口报文 + JSONObject body = new JSONObject(true); + body.put("message", message.toJSONString()); + body.put("topic", topic); + + String requestJson = body.toJSONString(); + HttpURLConnection conn = null; + try { + conn = (HttpURLConnection) new URL(sendTopicUrl).openConnection(); + conn.setRequestMethod("POST"); + conn.setDoOutput(true); + conn.setConnectTimeout(httpTimeoutSeconds * 1000); + conn.setReadTimeout(httpTimeoutSeconds * 1000); + conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8"); + conn.setRequestProperty(TOKEN_HEADER, getToken()); + + try (OutputStream out = conn.getOutputStream()) { + out.write(requestJson.getBytes(StandardCharsets.UTF_8)); + out.flush(); + } + + int responseCode = conn.getResponseCode(); + String response = readResponse(conn, responseCode); + log.info("[TASK_STATUS_DELETE] 推送响应: code={}, body={}, request={}", responseCode, response, requestJson); + if (responseCode == 200) { + JSONObject resp = JSONObject.parseObject(response); + if (resp != null && Boolean.TRUE.equals(resp.getBoolean("success"))) { + return true; + } + log.error("[TASK_STATUS_DELETE] 上传业务失败: {}", response); + } else { + log.error("[TASK_STATUS_DELETE] 上传HTTP失败: {}, body: {}", responseCode, response); + } + return false; + } catch (Exception e) { + log.error("[TASK_STATUS_DELETE] 推送删除消息异常, url: {}", sendTopicUrl, e); + return false; + } finally { + if (conn != null) { + conn.disconnect(); + } + } + } + + /** 获取 Joinbright-Token */ + private String getToken() { + ApiResult result = extAuthService.getAuthToken(); + if (result == null || !result.isSuccess() || result.getData() == null) { + log.error("[TASK_STATUS_DELETE] 获取 Joinbright-Token 失败: {}", result); + return ""; + } + return result.getData().getAccess_token(); + } + + private String readResponse(HttpURLConnection conn, int code) throws Exception { + InputStream in = code >= 400 ? conn.getErrorStream() : conn.getInputStream(); + if (in == null) { + return ""; + } + StringBuilder sb = new StringBuilder(); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) { + String line; + while ((line = reader.readLine()) != null) { + sb.append(line); + } + } + return sb.toString(); + } +} diff --git a/inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/controller/PatrolTaskStatusController.java b/inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/controller/PatrolTaskStatusController.java index 25b40f8..924ee01 100644 --- a/inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/controller/PatrolTaskStatusController.java +++ b/inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/controller/PatrolTaskStatusController.java @@ -5,6 +5,7 @@ import com.github.pagehelper.PageInfo; import com.inspect.analysis.domain.ResultAnalysis; import com.inspect.analysis.domain.ResultAnalysisSummaryDTO; import com.inspect.analysis.service.IResultAnalysisService; +import com.inspect.api.service.TaskStatusDeletePushService; import com.inspect.base.core.constant.AlgConstants; import com.inspect.base.core.constant.RedisConst; import com.inspect.base.core.domain.maintain.MaintainRegion; @@ -77,6 +78,12 @@ public class PatrolTaskStatusController extends BaseController { private PatrolTaskController patrolTaskController; private IPatrolTaskResultMainService patrolTaskResultMainService; + /** 场站编码 Redis key(场站 code) */ + private static final String STATION_CODE_REDIS_KEY = "sys_config:STATION_CODE"; + + /** 删除脏数据后推送消息通知中恒 */ + private final TaskStatusDeletePushService taskStatusDeletePushService; + @Resource private IResultAnalysisService resultAnalysisService; @@ -97,7 +104,8 @@ public class PatrolTaskStatusController extends BaseController { FeignTaskClient feignTaskClient, FeignJobTaskClient feignJobTaskClient, RedisService redisService, - IPatrolTaskResultMainService patrolTaskResultMainService) { + IPatrolTaskResultMainService patrolTaskResultMainService, + TaskStatusDeletePushService taskStatusDeletePushService) { this.patrolTaskController = patrolTaskController; this.patrolTaskStatusService = patrolTaskStatusService; this.patrolResultService = patrolResultService; @@ -106,6 +114,7 @@ public class PatrolTaskStatusController extends BaseController { this.feignJobTaskClient = feignJobTaskClient; this.redisService = redisService; this.patrolTaskResultMainService = patrolTaskResultMainService; + this.taskStatusDeletePushService = taskStatusDeletePushService; } // @GetMapping({"/list"}) @@ -375,6 +384,47 @@ public class PatrolTaskStatusController extends BaseController { return this.toAjax(this.patrolTaskStatusService.deletePatrolTaskStatusByLineIds(lineIds)); } + /** + * 删除任务状态数据(taskstatus/list 脏数据清理),并推送 MQTT 消息通知中恒 + *

+ * 1. 按 task_patrolled_id 删除 patrol_task_status 记录;
+ * 2. POST jb-nessp-external/api/mqtt/sendTopic 发送 topic/env/delete 消息, + * 报文见《动环删除数据推送信息字段说明》:{ idType, stationCode, ids, deleteTime }, + * ids 取 patrol_task_status.task_patrolled_id;
+ * 3. 推送失败只记日志,不影响删除结果(返回结果用 pushSuccess 标识)。 + * + * @param taskPatrolledIds 巡视任务执行ID,多个用逗号分隔 + */ + @Log(title = "任务状态数据-删除并同步中恒", businessType = BizType.DELETE) + @PostMapping({"/removeByTaskPatrolledIds/{taskPatrolledIds}"}) + public AjaxResult removeByTaskPatrolledIds(@PathVariable String taskPatrolledIds) { + List ids = Arrays.stream(taskPatrolledIds.split("[,/]")) + .map(String::trim) + .filter(StringUtils::isNotEmpty) + .distinct() + .collect(Collectors.toList()); + if (ids.isEmpty()) { + return AjaxResult.error("执行任务ID不能为空"); + } + log.info("[TASK_STATUS_DELETE] remove taskStatus, taskPatrolledIds: {}", ids); + + // 删除任务状态数据 + int deleteCount = this.patrolTaskStatusService.deletePatrolTaskStatusByTaskPatrolledIds(ids); + log.info("[TASK_STATUS_DELETE] 删除完成, taskPatrolledIds: {}, deleteCount: {}", ids, deleteCount); + + // 推送消息通知中恒(失败不影响删除结果) + String stationCode = (String) redisService.redisTemplate.opsForValue().get(STATION_CODE_REDIS_KEY); + boolean pushSuccess = taskStatusDeletePushService.pushTaskDelete(stationCode, ids); + if (!pushSuccess) { + log.error("[TASK_STATUS_DELETE] 推送删除消息失败, taskPatrolledIds: {}, stationCode: {}", ids, stationCode); + } + AjaxResult result = AjaxResult.success(); + result.put("deleteCount", deleteCount); + result.put("stationCode", stationCode); + result.put("pushSuccess", pushSuccess); + return result; + } + @GetMapping({"/taskcount"}) public Map taskCount(PatrolTaskStatus patrolTaskStatus) throws ParseException { Map map = new HashMap<>(); diff --git a/inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/mapper/PatrolTaskStatusMapper.java b/inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/mapper/PatrolTaskStatusMapper.java index 8ad51d1..cde4a0f 100644 --- a/inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/mapper/PatrolTaskStatusMapper.java +++ b/inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/mapper/PatrolTaskStatusMapper.java @@ -40,6 +40,14 @@ public interface PatrolTaskStatusMapper { int deletePatrolTaskStatusByLineIds(Long[] lineIds); + /** + * 按巡视任务执行ID(task_patrolled_id)批量删除 + * + * @param taskPatrolledIds 执行任务ID集合 + * @return 删除行数 + */ + int deletePatrolTaskStatusByTaskPatrolledIds(@Param("taskPatrolledIds") List taskPatrolledIds); + List selectPatrolTaskStatusListByTaskPatrolledIds(@Param("taskPatrolledIds") List taskPatrolledIds); List countMonthlyStatsByYear(Integer year); diff --git a/inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/service/IPatrolTaskStatusService.java b/inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/service/IPatrolTaskStatusService.java index 2b82f28..0a37781 100644 --- a/inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/service/IPatrolTaskStatusService.java +++ b/inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/service/IPatrolTaskStatusService.java @@ -34,6 +34,14 @@ public interface IPatrolTaskStatusService { int deletePatrolTaskStatusByLineId(Long lineId); + /** + * 按巡视任务执行ID(task_patrolled_id)批量删除任务状态数据(用于清理脏数据) + * + * @param taskPatrolledIds 执行任务ID集合 + * @return 删除行数 + */ + int deletePatrolTaskStatusByTaskPatrolledIds(List taskPatrolledIds); + int insertIgnorePatrolTaskStatus(PatrolTaskStatus patrolTaskStatusMain); void updateTaskProgress(Long lineId, String taskProgress, String taskEstimatedTime, String taskState); diff --git a/inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/service/impl/PatrolTaskStatusServiceImpl.java b/inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/service/impl/PatrolTaskStatusServiceImpl.java index fa67491..2bc6ccb 100644 --- a/inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/service/impl/PatrolTaskStatusServiceImpl.java +++ b/inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/service/impl/PatrolTaskStatusServiceImpl.java @@ -120,6 +120,14 @@ public class PatrolTaskStatusServiceImpl implements IPatrolTaskStatusService { return this.patrolTaskStatusMapper.deletePatrolTaskStatusByLineId(lineId); } + @Override + public int deletePatrolTaskStatusByTaskPatrolledIds(List taskPatrolledIds) { + if (taskPatrolledIds == null || taskPatrolledIds.isEmpty()) { + return 0; + } + return this.patrolTaskStatusMapper.deletePatrolTaskStatusByTaskPatrolledIds(taskPatrolledIds); + } + @Override @TaskStatusChange(targetState = "1", async = true) // "1"表示已完成状态 public int insertIgnorePatrolTaskStatus(PatrolTaskStatus patrolTaskStatusMain) { diff --git a/inspect-main/inspect-main-task/src/main/resources/mapper/task/PatrolTaskStatusMapper.xml b/inspect-main/inspect-main-task/src/main/resources/mapper/task/PatrolTaskStatusMapper.xml index d447d54..00b0ffd 100644 --- a/inspect-main/inspect-main-task/src/main/resources/mapper/task/PatrolTaskStatusMapper.xml +++ b/inspect-main/inspect-main-task/src/main/resources/mapper/task/PatrolTaskStatusMapper.xml @@ -587,4 +587,11 @@ #{lineId} + + + delete from patrol_task_status where task_patrolled_id in + + #{taskPatrolledId} + +