增加智眸AI接口封装

This commit is contained in:
sdy 2026-06-11 14:55:37 +08:00
parent 55273df8d7
commit 67cedde4c5
10 changed files with 429 additions and 19 deletions

View File

@ -8,9 +8,10 @@ package com.multictrl.common.constant;
*/ */
public interface BusinessConstant { public interface BusinessConstant {
String ZHIMOU_AI_CALLBACK_TOPIC = "thing/product/zhimou_ai_callback"; String ZHIMOU_AI_CALLBACK_TOPIC = "thing/product/%s/zhimou_ai_callback";
String WEB_EVENT_TOPIC = "thing/product/%s/web_event"; String WEB_EVENT_TOPIC = "thing/product/%s/web_event";
String NOFLY_ZONE_METHOD = "nofly_zone"; String NOFLY_ZONE_METHOD = "nofly_zone";
String ZHIMOU_AI_CALLBACK = "zhimou_ai_callback";
//********************************* minio *********************************// //********************************* minio *********************************//
String ROUTE_IMG_BUCKET = "route-images";//航线图片桶 String ROUTE_IMG_BUCKET = "route-images";//航线图片桶
@ -91,7 +92,7 @@ public interface BusinessConstant {
String DOCK_NOFLY_ZONE = "dock_nofly_zone_"; String DOCK_NOFLY_ZONE = "dock_nofly_zone_";
String DOCK_NOFLY_ZONE_TRIGGER_SIGN = "dock_nofly_zone_trigger_sign_"; String DOCK_NOFLY_ZONE_TRIGGER_SIGN = "dock_nofly_zone_trigger_sign_";
String ZHIMOU_TOKEN = "zhiMou_token"; String ZHIMOU_TOKEN = "zhiMou_token";
String DOCK_ZHIMOU_TASK_ID = "dock_zhiMou_task_id_"; String DOCK_ZHIMOU_CONFIG = "dock_zhiMou_config_";
//********************************* other *********************************// //********************************* other *********************************//
String HTTP_PROTOCOL = "http://"; String HTTP_PROTOCOL = "http://";

View File

@ -1,18 +1,28 @@
package com.multictrl.modules.business.controller; package com.multictrl.modules.business.controller;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.multictrl.common.annotation.ApiOrder; import com.multictrl.common.annotation.ApiOrder;
import com.multictrl.common.annotation.LogOperation; import com.multictrl.common.annotation.LogOperation;
import com.multictrl.common.utils.Result; import com.multictrl.common.utils.Result;
import com.multictrl.common.validator.ValidatorUtils; import com.multictrl.common.validator.ValidatorUtils;
import com.multictrl.modules.business.dto.zhimou.DownloadReport;
import com.multictrl.modules.business.dto.zhimou.Osd;
import com.multictrl.modules.business.dto.zhimou.ZhiMouAiStart; import com.multictrl.modules.business.dto.zhimou.ZhiMouAiStart;
import com.multictrl.modules.business.service.ZhiMouService; import com.multictrl.modules.business.service.ZhiMouService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
/** /**
* 智眸AI接口封装 * 智眸AI接口封装
* *
@ -29,7 +39,7 @@ public class ZhiMouController {
@Operation(summary = "获取应用列表") @Operation(summary = "获取应用列表")
@GetMapping("/getApp") @GetMapping("/getApp")
@RequiresPermissions("bus:zhimou:getApp") @RequiresPermissions("bus:zhimou:get")
public Result<Object> getApp() { public Result<Object> getApp() {
JSONObject data = zhiMouService.getApp(); JSONObject data = zhiMouService.getApp();
return zhiMouService.resultHandle(data); return zhiMouService.resultHandle(data);
@ -38,7 +48,7 @@ public class ZhiMouController {
@Operation(summary = "开始AI检测任务") @Operation(summary = "开始AI检测任务")
@LogOperation("开始AI检测任务") @LogOperation("开始AI检测任务")
@PostMapping("/startByWeb") @PostMapping("/startByWeb")
@RequiresPermissions("bus:zhimou:startByWeb") @RequiresPermissions("bus:zhimou:start")
public Result<Object> startByWeb(@RequestBody ZhiMouAiStart zhiMouAiStart) { public Result<Object> startByWeb(@RequestBody ZhiMouAiStart zhiMouAiStart) {
ValidatorUtils.validateEntity(zhiMouAiStart); ValidatorUtils.validateEntity(zhiMouAiStart);
JSONObject data = zhiMouService.startByWeb(zhiMouAiStart); JSONObject data = zhiMouService.startByWeb(zhiMouAiStart);
@ -48,9 +58,55 @@ public class ZhiMouController {
@Operation(summary = "停止AI检测任务") @Operation(summary = "停止AI检测任务")
@LogOperation("停止AI检测任务") @LogOperation("停止AI检测任务")
@PostMapping("/stopByWeb") @PostMapping("/stopByWeb")
@RequiresPermissions("bus:zhimou:stopByWeb") @RequiresPermissions("bus:zhimou:stop")
public Result<Object> stopByWeb(@RequestParam String dockSn) { public Result<Object> stopByWeb(@RequestParam String dockSn) {
JSONObject data = zhiMouService.stopByWeb(dockSn); JSONObject data = zhiMouService.stopByWeb(dockSn);
return zhiMouService.resultHandle(data); return zhiMouService.resultHandle(data);
} }
@Operation(summary = "获取AI检测任务")
@GetMapping("/getRunningTaskByWeb")
public Result<Object> getRunningTaskByWeb(@RequestParam String dockSn) {
JSONObject data = zhiMouService.getRunningTaskByWeb(dockSn);
return new Result<>().ok(data);
}
@Operation(summary = "配置AI检测任务")
@LogOperation("配置AI检测任务")
@PostMapping("/configurationByWeb")
@RequiresPermissions("bus:zhimou:config")
public Result<Object> configurationByWeb(@RequestBody Osd osd) {
JSONObject data = zhiMouService.configurationByWeb(osd);
return zhiMouService.resultHandle(data);
}
@Operation(summary = "获取实时检测结果")
@GetMapping("/currentTaskMessageRecord")
public Result<Object> currentTaskMessageRecord(@RequestParam String dockSn) {
JSONObject data = zhiMouService.currentTaskMessageRecord(dockSn);
return zhiMouService.resultHandle(data);
}
@Operation(summary = "获取飞行任务检测结果")
@GetMapping("/getTaskMessageRecord")
@RequiresPermissions("bus:zhiMou:image")
public Result<Object> getTaskMessageRecordList(@RequestParam String taskId) {
JSONArray data = zhiMouService.getTaskMessageRecordList(taskId);
return new Result<>().ok(data);
}
@Operation(summary = "下载AI检测报告")
@PostMapping("/downloadReport")
@RequiresPermissions("ai:zhiMou:downloadReport")
public ResponseEntity<byte[]> getReportByBusinessId(@RequestBody DownloadReport downloadReport) {
ValidatorUtils.validateEntity(downloadReport);
byte[] reportBytes = zhiMouService.downloadReport(downloadReport);
String fileName = "AI报告_" + downloadReport.getTaskId() + ".zip";
String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
return ResponseEntity.ok()
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + encodedFileName)
.body(reportBytes);
}
} }

View File

@ -0,0 +1,16 @@
package com.multictrl.modules.business.dao;
import com.multictrl.common.dao.BaseDao;
import com.multictrl.modules.business.entity.ZhimouCallbackEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* 智眸事件回调
*
* @author Sdy
* @since 1.0.0 2026-06-11
*/
@Mapper
public interface ZhimouCallbackDao extends BaseDao<ZhimouCallbackEntity> {
}

View File

@ -0,0 +1,34 @@
package com.multictrl.modules.business.dto.zhimou;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
/**
* 下载报告参数
*
* @author Sdy
* @since 1.0.0 2026/6/11
*/
@Schema(name = "AI报告参数")
@Data
public class DownloadReport {
@Schema(description = "标题")
private String title;
@Schema(description = "子标题")
private String subtitle;
@Schema(description = "报告单位")
private String reporter;
@Schema(description = "支撑单位")
private String supporter;
@Schema(description = "备注")
private String remark;
@NotBlank(message = "架次编号不能为空")
@Schema(description = "架次编号")
private String taskId;
}

View File

@ -68,7 +68,7 @@ public class Osd {
*/ */
private List<List<Double>> polygon; private List<List<Double>> polygon;
private String deviceId; private String dockSn;
private String taskId; private String taskId;
} }

View File

@ -0,0 +1,50 @@
package com.multictrl.modules.business.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
/**
* 智眸事件回调
*
* @author Sdy
* @since 1.0.0 2026-06-11
*/
@Data
@TableName("bus_zhimou_callback")
public class ZhimouCallbackEntity {
@TableId
private Long id;
/**
* $column.comments
*/
private String appId;
/**
* 飞控任务id
*/
private String businessId;
/**
* 机库SN
*/
private String device;
/**
* 事件
*/
private String event;
/**
* 智眸任务id
*/
private String taskId;
/**
* 上报时间
*/
private Long timestamp;
@TableField(fill = FieldFill.INSERT)
private Date createDate;
}

View File

@ -30,6 +30,7 @@ public class TopicDistributor {
private final StateHandler stateHandler; private final StateHandler stateHandler;
private final ServicesReplyHandler servicesReplyHandler; private final ServicesReplyHandler servicesReplyHandler;
private final EventsHandler eventsHandler; private final EventsHandler eventsHandler;
private final ZhiMouCallbackHandler zhiMouCallbackHandler;
private final Q20OsdTopicHandler q20OsdTopicHandler; private final Q20OsdTopicHandler q20OsdTopicHandler;
private final Q20EventsHandler q20EventsHandler; private final Q20EventsHandler q20EventsHandler;
private final Q20StateTopicHandler q20StateTopicHandler; private final Q20StateTopicHandler q20StateTopicHandler;
@ -48,6 +49,7 @@ public class TopicDistributor {
handlerMap.put(BusinessConstant.STATE, stateHandler); handlerMap.put(BusinessConstant.STATE, stateHandler);
handlerMap.put(BusinessConstant.EVENTS, eventsHandler); handlerMap.put(BusinessConstant.EVENTS, eventsHandler);
handlerMap.put(BusinessConstant.SERVICES_REPLY, servicesReplyHandler); handlerMap.put(BusinessConstant.SERVICES_REPLY, servicesReplyHandler);
handlerMap.put(BusinessConstant.ZHIMOU_AI_CALLBACK, zhiMouCallbackHandler);
q20HandlerMap.put(BusinessConstant.OSD, q20OsdTopicHandler); q20HandlerMap.put(BusinessConstant.OSD, q20OsdTopicHandler);
q20HandlerMap.put(BusinessConstant.EVENTS, q20EventsHandler); q20HandlerMap.put(BusinessConstant.EVENTS, q20EventsHandler);

View File

@ -0,0 +1,41 @@
package com.multictrl.modules.business.handler;
import cn.hutool.json.JSONObject;
import com.multictrl.common.utils.JsonUtils;
import com.multictrl.modules.business.dao.ZhimouCallbackDao;
import com.multictrl.modules.business.entity.ZhimouCallbackEntity;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* 智眸回调处理
*
* @author Sdy
* @since 1.0.0 2026/6/11
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class ZhiMouCallbackHandler implements MessageHandler{
private final ZhimouCallbackDao zhimouCallbackDao;
@Override
public void handleMessage(String topic, String payload, String gateway) {
log.debug("zhiMouCallback --> topic: {}, payload: {}", topic, payload);
JSONObject data = JsonUtils.parseObject(payload, JSONObject.class);
if(data!=null){
String event = data.getStr("event");
if("start".equals(event)||"stop".equals(event)){
ZhimouCallbackEntity entity = new ZhimouCallbackEntity();
entity.setAppId(data.getStr("appId"));
entity.setBusinessId(data.getStr("business_id"));
entity.setDevice(data.getStr("device"));
entity.setEvent(event);
entity.setTaskId(data.getStr("task_id"));
entity.setTimestamp(data.getLong("timestamp"));
zhimouCallbackDao.insert(entity);
}
}
}
}

View File

@ -1,9 +1,13 @@
package com.multictrl.modules.business.service; package com.multictrl.modules.business.service;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.multictrl.common.utils.Result; import com.multictrl.common.utils.Result;
import com.multictrl.modules.business.dto.zhimou.DownloadReport;
import com.multictrl.modules.business.dto.zhimou.Osd;
import com.multictrl.modules.business.dto.zhimou.ZhiMouAiStart; import com.multictrl.modules.business.dto.zhimou.ZhiMouAiStart;
import com.multictrl.modules.business.dto.zhimou.ZhiMouInfo; import com.multictrl.modules.business.dto.zhimou.ZhiMouInfo;
import jakarta.servlet.http.HttpServletResponse;
/** /**
* 智眸AI接口封装 * 智眸AI接口封装
@ -27,4 +31,22 @@ public interface ZhiMouService {
//停止AI检测任务 //停止AI检测任务
JSONObject stopByWeb(String dockSn); JSONObject stopByWeb(String dockSn);
//获取AI检测任务
JSONObject getRunningTaskByWeb(String dockSn);
//配置ai检测任务
JSONObject configurationByWeb(Osd osd);
//获取实时检测结果
JSONObject currentTaskMessageRecord(String dockSn);
//获取信息记录
JSONObject getMessageRecord(String taskId);
//获取飞行任务检测结果
JSONArray getTaskMessageRecordList(String taskId);
//下载AI检测报告
byte[] downloadReport(DownloadReport downloadReport);
} }

View File

@ -5,10 +5,12 @@ import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil; import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method; import cn.hutool.http.Method;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.multictrl.common.config.MqttConfig; import com.multictrl.common.config.MqttConfig;
import com.multictrl.common.config.SysConfig;
import com.multictrl.common.constant.BusinessConstant; import com.multictrl.common.constant.BusinessConstant;
import com.multictrl.common.constant.SysParamsKey; import com.multictrl.common.constant.SysParamsKey;
import com.multictrl.common.exception.ErrorCode; import com.multictrl.common.exception.ErrorCode;
@ -16,21 +18,25 @@ import com.multictrl.common.exception.RenException;
import com.multictrl.common.utils.CacheUtils; import com.multictrl.common.utils.CacheUtils;
import com.multictrl.common.utils.Result; import com.multictrl.common.utils.Result;
import com.multictrl.common.utils.Utils; import com.multictrl.common.utils.Utils;
import com.multictrl.modules.business.dao.ZhimouCallbackDao;
import com.multictrl.modules.business.dto.zhimou.*; import com.multictrl.modules.business.dto.zhimou.*;
import com.multictrl.modules.business.entity.ZhimouCallbackEntity;
import com.multictrl.modules.business.service.SrsService; import com.multictrl.modules.business.service.SrsService;
import com.multictrl.modules.business.service.ZhiMouService; import com.multictrl.modules.business.service.ZhiMouService;
import com.multictrl.modules.sys.dao.SysParamsDao; import com.multictrl.modules.sys.dao.SysParamsDao;
import com.multictrl.modules.sys.entity.SysParamsEntity; import com.multictrl.modules.sys.entity.SysParamsEntity;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Arrays; import java.io.ByteArrayOutputStream;
import java.util.HashMap; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/** /**
* 智眸AI接口封装 * 智眸AI接口封装
@ -45,6 +51,8 @@ public class ZhiMouServiceImpl implements ZhiMouService {
private final SysParamsDao paramsDao; private final SysParamsDao paramsDao;
private final SrsService srsService; private final SrsService srsService;
private final MqttConfig mqttConfig; private final MqttConfig mqttConfig;
private final SysConfig sysConfig;
private final ZhimouCallbackDao zhimouCallbackDao;
private static final String APP_KEY = "appkey"; private static final String APP_KEY = "appkey";
private static final String APP_SECRET = "appsecret"; private static final String APP_SECRET = "appsecret";
private static final String AUTHORIZATION = "Authorization"; private static final String AUTHORIZATION = "Authorization";
@ -237,7 +245,7 @@ public class ZhiMouServiceImpl implements ZhiMouService {
mqtt.setClientID("zhi_mou_ai_" + IdUtil.getSnowflakeNextIdStr()); mqtt.setClientID("zhi_mou_ai_" + IdUtil.getSnowflakeNextIdStr());
mqtt.setUsername(client1.getUsername()); mqtt.setUsername(client1.getUsername());
mqtt.setPassword(client1.getPassword()); mqtt.setPassword(client1.getPassword());
mqtt.setTopic(BusinessConstant.ZHIMOU_AI_CALLBACK_TOPIC); mqtt.setTopic(BusinessConstant.ZHIMOU_AI_CALLBACK_TOPIC.formatted(dockSn));
mqtt.setQos(0L); mqtt.setQos(0L);
report.setMqtt(mqtt); report.setMqtt(mqtt);
zhiMouTask.setReport(report); zhiMouTask.setReport(report);
@ -251,22 +259,18 @@ public class ZhiMouServiceImpl implements ZhiMouService {
.body(); .body();
log.debug("invoke zhiMou start request: {},result: {}", jsonObject, result); log.debug("invoke zhiMou start request: {},result: {}", jsonObject, result);
if (StrUtil.isNotBlank(result)) { if (StrUtil.isNotBlank(result)) {
JSONObject parse = JSONObject.parse(result); return JSONObject.parse(result);
if (parse.containsKey("code") && parse.getInteger("code") == 0) {
String taskId = parse.getJSONObject("data").getString("task_id");
CacheUtils.set(BusinessConstant.DOCK_ZHIMOU_TASK_ID + dockSn, taskId);
}
return parse;
} }
return null; return null;
} }
@Override @Override
public JSONObject stopByWeb(String dockSn) { public JSONObject stopByWeb(String dockSn) {
String taskId = (String) CacheUtils.get(BusinessConstant.DOCK_ZHIMOU_TASK_ID + dockSn); JSONObject running = getRunningTaskByWeb(dockSn);
if (StrUtil.isBlank(taskId)) { if (running == null) {
throw new RenException(ErrorCode.ZHIMOU_TASK_NOT_EXIST); throw new RenException(ErrorCode.ZHIMOU_TASK_NOT_EXIST);
} }
String taskId = running.getString("task_id");
ZhiMouInfo zhiMouInfo = getToken(); ZhiMouInfo zhiMouInfo = getToken();
String result = HttpUtil.createRequest(Method.DELETE, zhiMouInfo.getUrl() + TASK + "/" + taskId) String result = HttpUtil.createRequest(Method.DELETE, zhiMouInfo.getUrl() + TASK + "/" + taskId)
.header(AUTHORIZATION, BEARER + zhiMouInfo.getToken()) .header(AUTHORIZATION, BEARER + zhiMouInfo.getToken())
@ -279,6 +283,190 @@ public class ZhiMouServiceImpl implements ZhiMouService {
return null; return null;
} }
@Override
public JSONObject getRunningTaskByWeb(String dockSn) {
ZhiMouInfo zhiMouInfo = getToken();
String result = HttpUtil.createGet(zhiMouInfo.getUrl() + TASK)
.header(AUTHORIZATION, BEARER + zhiMouInfo.getToken()).execute().body();
log.debug("invoke zhiMou getRunningTask result: {}", result);
if (StrUtil.isNotBlank(result)) {
JSONObject runningTask = JSONObject.parse(result);
JSONObject jsonObject = runningTask.getJSONObject("data");
if (jsonObject != null) {
JSONArray jsonArray = jsonObject.getJSONArray("tasks");
if (jsonArray != null && !jsonArray.isEmpty()) {
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject j2 = jsonArray.getJSONObject(i);
if (j2.getString("device").equals(dockSn)) {
String protocol = BusinessConstant.HTTP_PROTOCOL;
if (sysConfig.getIsSsl()) {
protocol = BusinessConstant.HTTPS_PROTOCOL;
}
j2.remove("report");
j2.remove("input");
j2.remove("output");
j2.remove("dji");
j2.put("appId", j2.getString("app_id"));
j2.remove("app_id");
j2.put("businessId", j2.getString("business_id"));
j2.remove("business_id");
String webrtcUrl = protocol + sysConfig.getIp() + ":" + sysConfig.getPort() + "/rtc/v1/whep/?app=" + dockSn + "&stream=uav_ai.flv";
j2.put("webrtcUrl", webrtcUrl);
j2.put("osd", CacheUtils.get(BusinessConstant.DOCK_ZHIMOU_CONFIG + dockSn));
return j2;
}
}
}
}
}
return null;
}
@Override
public JSONObject configurationByWeb(Osd osd) {
String dockSn = osd.getDockSn();
JSONObject running = getRunningTaskByWeb(dockSn);
if (running == null) {
throw new RenException(ErrorCode.ZHIMOU_TASK_NOT_EXIST);
}
osd.setTaskId(running.getString("task_id"));
JSONObject osdObject = Utils.beanToSnakeJsonFastJson(osd);
ZhiMouInfo zhiMouInfo = getToken();
String result = HttpUtil.createRequest(Method.PUT,
zhiMouInfo.getUrl() + TASK + "/" + osd.getTaskId())
.body(osdObject.toJSONString())
.header(AUTHORIZATION, BEARER + zhiMouInfo.getToken())
.execute()
.body();
log.debug("invoke zhiMou configuration request: {},result: {}", osdObject, result);
if (StrUtil.isNotBlank(result)) {
JSONObject parse = JSONObject.parse(result);
if (parse != null && parse.containsKey("ok")) {
CacheUtils.set(BusinessConstant.DOCK_ZHIMOU_CONFIG + dockSn, osd);
}
return parse;
}
return null;
}
@Override
public JSONObject currentTaskMessageRecord(String dockSn) {
JSONObject running = getRunningTaskByWeb(dockSn);
if (running == null) {
throw new RenException(ErrorCode.ZHIMOU_TASK_NOT_EXIST);
}
String taskId = running.getString("task_id");
return getMessageRecord(taskId);
}
@Override
public JSONObject getMessageRecord(String taskId) {
ZhiMouInfo zhiMouInfo = getToken();
String result = HttpUtil.createGet(zhiMouInfo.getUrl() + MESSAGE_RECORD
+ String.format("?task_id=%s&limit=%s", taskId, Integer.MAX_VALUE))
.header(AUTHORIZATION, BEARER + zhiMouInfo.getToken())
.header("Referer", zhiMouInfo.getUrl())
.execute().body();
log.debug("invoke zhiMou getMessageRecord taskId:{} result: {}", taskId, result);
if (!result.contains("\"code\":0")) {
JSONObject temp = new JSONObject();
temp.put("code", 0);
temp.put("data", new JSONArray());
return temp;
}
JSONObject jsonObject = JSONObject.parseObject(result);
JSONArray data = jsonObject.getJSONArray("data");
if (data == null || data.isEmpty()) {
JSONObject temp = new JSONObject();
temp.put("code", 0);
temp.put("data", new JSONArray());
return temp;
}
for (int i = 0; i < data.size(); i++) {
JSONObject t = data.getJSONObject(i);
JSONArray t2 = t.getJSONArray("objects");
int count = 0;
if (t2 != null) {
count = t2.size();
}
//筛选出带车牌的事件
JSONArray carIds = new JSONArray();
if (t2 != null) {
for (int j = 0; j < t2.size(); j++) {
JSONObject t3 = t2.getJSONObject(j);
if (t3.containsKey("attr_name") && "车牌".equals(t3.getString("attr_name"))) {
carIds.add(t3);
}
}
}
t.remove("objects");
if (!carIds.isEmpty()) {
t.put("objects", carIds);
}
t.put("count", count);
t.put("thumbnail", zhiMouInfo.getUrl() + "/thumbnail" + t.getString("image"));
t.put("image", zhiMouInfo.getUrl() + t.getString("image"));
}
return jsonObject;
}
@Override
public JSONArray getTaskMessageRecordList(String taskId) {
List<ZhimouCallbackEntity> entityList = zhimouCallbackDao.selectList(new QueryWrapper<ZhimouCallbackEntity>()
.eq("business_id", taskId));
if (CollUtil.isEmpty(entityList)) {
throw new RenException(ErrorCode.ZHIMOU_TASK_NOT_EXIST);
}
Set<String> taskIds = entityList.stream().map(ZhimouCallbackEntity::getTaskId).collect(Collectors.toSet());
JSONArray jsonArray = new JSONArray();
for (String zhimouTaskId : taskIds) {
JSONObject result = getMessageRecord(zhimouTaskId);
jsonArray.addAll(result.getJSONArray("data"));
}
jsonArray = jsonArray.stream().map(obj -> (JSONObject) obj)
.sorted(Comparator.comparingLong(
o -> o.getLong("id")))
.collect(JSONArray::new, JSONArray::add, JSONArray::addAll);
return jsonArray;
}
@Override
public byte[] downloadReport(DownloadReport downloadReport) {
List<ZhimouCallbackEntity> entityList = zhimouCallbackDao.selectList(new QueryWrapper<ZhimouCallbackEntity>()
.eq("business_id", downloadReport.getTaskId()));
if (CollUtil.isEmpty(entityList)) {
throw new RenException(ErrorCode.ZHIMOU_TASK_NOT_EXIST);
}
Set<String> taskIds = entityList.stream().map(ZhimouCallbackEntity::getTaskId).collect(Collectors.toSet());
ZhiMouInfo zhiMouInfo = getToken();
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zipOut = new ZipOutputStream(baos)) {
for (String taskId : taskIds) {
JSONObject para = JSON.parseObject(JSON.toJSONString(downloadReport));
para.remove("taskId");
para.put("rule_ids", new JSONArray());
byte[] fileBytes = HttpUtil.createPost(zhiMouInfo.getUrl() + String.format(REPORT, taskId))
.header(AUTHORIZATION, BEARER + zhiMouInfo.getToken())
.body(para.toJSONString())
.execute()
.bodyBytes();
String fileName = para.getString("title") + "_" + taskId + ".docx";
ZipEntry zipEntry = new ZipEntry(fileName);
zipOut.putNextEntry(zipEntry);
zipOut.write(fileBytes);
zipOut.closeEntry();
}
return baos.toByteArray();
} catch (Exception e) {
log.error("下载 AI报告ZIP 失败", e);
throw new RuntimeException("下载AI报告失败", e);
}
}
private String replaceRtmpIpPort(String originalUrl, String newIp, String newPort) { private String replaceRtmpIpPort(String originalUrl, String newIp, String newPort) {
// 定义RTMP URL的正则表达式模式 // 定义RTMP URL的正则表达式模式
Pattern pattern = Pattern.compile("^rtmp://([^/:]+):([^/]+)(/.*)$"); Pattern pattern = Pattern.compile("^rtmp://([^/:]+):([^/]+)(/.*)$");