增加智眸AI接口封装
This commit is contained in:
parent
55273df8d7
commit
67cedde4c5
|
|
@ -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://";
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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://([^/:]+):([^/]+)(/.*)$");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue