Browse Source

feat: 新增任务状态数据删除接口并同步通知中恒

用于清理任务列表脏数据:按 task_patrolled_id 删除 patrol_task_status 记录后,
调用 jb-nessp-external/api/mqtt/sendTopic 推送 topic/env/delete 消息通知中恒。
yanyuan
WangGuangYuan 4 weeks ago
parent
commit
00fc0dd0a8
6 changed files with 229 additions and 1 deletions
  1. +147
    -0
      inspect-main/inspect-main-api/src/main/java/com/inspect/api/service/TaskStatusDeletePushService.java
  2. +51
    -1
      inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/controller/PatrolTaskStatusController.java
  3. +8
    -0
      inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/mapper/PatrolTaskStatusMapper.java
  4. +8
    -0
      inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/service/IPatrolTaskStatusService.java
  5. +8
    -0
      inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/service/impl/PatrolTaskStatusServiceImpl.java
  6. +7
    -0
      inspect-main/inspect-main-task/src/main/resources/mapper/task/PatrolTaskStatusMapper.xml

+ 147
- 0
inspect-main/inspect-main-api/src/main/java/com/inspect/api/service/TaskStatusDeletePushService.java View File

@ -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;
/**
* 动环删除数据推送服务(通知中恒)
* <p>
* 删除任务状态数据后,POST jb-nessp-external/api/mqtt/sendTopic 发送 MQTT 消息:
* 请求头携带 joinbright-token(复用 {@link ExtAuthService}),
* body 为 {@code {"message":"业务消息JSON字符串","topic":"topic/env/delete"}}。
* <p>
* 业务消息字段见《动环删除数据推送信息字段说明》:
* <pre>
* {"idType":"TASK","stationCode":"CZ000000004","ids":["123456789"],"deleteTime":"2026-08-19 10:00:00"}
* </pre>
* 推送失败只记日志,不影响删除结果。
*/
@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<String> 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<AuthTokenData> 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();
}
}

+ 51
- 1
inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/controller/PatrolTaskStatusController.java View File

@ -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 消息通知中恒
* <p>
* 1. 按 task_patrolled_id 删除 patrol_task_status 记录;<br>
* 2. POST jb-nessp-external/api/mqtt/sendTopic 发送 topic/env/delete 消息,
* 报文见《动环删除数据推送信息字段说明》:{ idType, stationCode, ids, deleteTime },
* ids 取 patrol_task_status.task_patrolled_id;<br>
* 3. 推送失败只记日志,不影响删除结果(返回结果用 pushSuccess 标识)。
*
* @param taskPatrolledIds 巡视任务执行ID,多个用逗号分隔
*/
@Log(title = "任务状态数据-删除并同步中恒", businessType = BizType.DELETE)
@PostMapping({"/removeByTaskPatrolledIds/{taskPatrolledIds}"})
public AjaxResult removeByTaskPatrolledIds(@PathVariable String taskPatrolledIds) {
List<String> 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<String, Object> taskCount(PatrolTaskStatus patrolTaskStatus) throws ParseException {
Map<String, Object> map = new HashMap<>();


+ 8
- 0
inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/mapper/PatrolTaskStatusMapper.java View File

@ -40,6 +40,14 @@ public interface PatrolTaskStatusMapper {
int deletePatrolTaskStatusByLineIds(Long[] lineIds);
/**
* 按巡视任务执行ID(task_patrolled_id)批量删除
*
* @param taskPatrolledIds 执行任务ID集合
* @return 删除行数
*/
int deletePatrolTaskStatusByTaskPatrolledIds(@Param("taskPatrolledIds") List<String> taskPatrolledIds);
List<PatrolTaskStatus> selectPatrolTaskStatusListByTaskPatrolledIds(@Param("taskPatrolledIds") List<String> taskPatrolledIds);
List<MonthlyTaskStatsDTO> countMonthlyStatsByYear(Integer year);


+ 8
- 0
inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/service/IPatrolTaskStatusService.java View File

@ -34,6 +34,14 @@ public interface IPatrolTaskStatusService {
int deletePatrolTaskStatusByLineId(Long lineId);
/**
* 按巡视任务执行ID(task_patrolled_id)批量删除任务状态数据(用于清理脏数据)
*
* @param taskPatrolledIds 执行任务ID集合
* @return 删除行数
*/
int deletePatrolTaskStatusByTaskPatrolledIds(List<String> taskPatrolledIds);
int insertIgnorePatrolTaskStatus(PatrolTaskStatus patrolTaskStatusMain);
void updateTaskProgress(Long lineId, String taskProgress, String taskEstimatedTime, String taskState);


+ 8
- 0
inspect-main/inspect-main-task/src/main/java/com/inspect/taskstatus/service/impl/PatrolTaskStatusServiceImpl.java View File

@ -120,6 +120,14 @@ public class PatrolTaskStatusServiceImpl implements IPatrolTaskStatusService {
return this.patrolTaskStatusMapper.deletePatrolTaskStatusByLineId(lineId);
}
@Override
public int deletePatrolTaskStatusByTaskPatrolledIds(List<String> 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) {


+ 7
- 0
inspect-main/inspect-main-task/src/main/resources/mapper/task/PatrolTaskStatusMapper.xml View File

@ -587,4 +587,11 @@
#{lineId}
</foreach>
</delete>
<delete id="deletePatrolTaskStatusByTaskPatrolledIds">
delete from patrol_task_status where task_patrolled_id in
<foreach item="taskPatrolledId" collection="taskPatrolledIds" open="(" separator="," close=")">
#{taskPatrolledId}
</foreach>
</delete>
</mapper>

Loading…
Cancel
Save