IntelligentRecognition/ah-jjsp-service/.svn/pristine/73/73f91d95e49d495cc7ceb09782b...

610 lines
25 KiB
Plaintext
Raw Normal View History

2024-05-24 16:09:40 +08:00
package com.sercurityControl.proteam.util;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.securityControl.common.core.constant.CacheConstants;
import com.securityControl.common.core.utils.DateUtils;
import com.securityControl.common.core.utils.StringUtils;
import com.securityControl.common.redis.service.RedisService;
import com.sercurityControl.proteam.domain.TEquipment;
import com.sercurityControl.proteam.domain.TImageLibrary;
import com.sercurityControl.proteam.mapper.TEquipmentMapper;
import com.sercurityControl.proteam.mapper.TImageLibraryMapper;
import com.sercurityControl.proteam.service.TImageLibraryService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* @author xxx
*/
@Component
@Slf4j
public class VideoUtil {
private static final Map<String, Object> responseMp = new HashMap<>(16);
@Resource
public RedisService redisService;
/**
* 统一视频平台地址
*/
@Value("${video.address}")
private String VIDEO_ADDRESS;
/**
* 统一视频平台账号
*/
@Value("${video.username}")
private String VIDEO_USERNAME;
/**
* 统一视频平台密码
*/
@Value("${video.password}")
private String VIDEO_PASSWORD;
/**
* 图片文件存储在本地的根路径
*/
/* @Value("${file.path}")
private String localFilePath;*/
/**
* 人工智能平台请求接口
*/
@Value("${ai.url}")
private String url;
/**
* 配置是否启用抓图到人工智能平台0-未启用1-启用)
*/
private Integer VIDEO_START=0;
@Autowired
private TImageLibraryService tImageLibraryService;
@Autowired
private TImageLibraryMapper tImageLibraryMapper;
@Autowired
private TEquipmentMapper tEquipmentMapper;
@Resource(name = "testTaskExecutor")
private ThreadPoolTaskExecutor taskExecutor;
/**
* 违章类型
*/
private static final String[] RISK_CONSTANTS = new String[]{"未佩戴安全帽", "未规范着装", "未佩戴安全带", "警戒区闯入", "吸烟", "作业无监护", "登高行为", "作业现场无人"};
/**
* 登录统一视频平台登录接口
*/
private final String LOGIN_URL = "/uvp-backend-common/api/v1/authorization";
/**
* 统一视频平台获取设备列表
*/
private final String DEVICE_LIST = "/uvp-backend-mc/api/v1/resource/getDevListByDev?ak=%s&token=%s&timestamp=%s&nonce=%s";
/**
* 统一视频平台单次抓图
*/
private final String CATCH_PICTURE = "/uvp-micro-service/storage/api/v1/snap?ak=%s&token=%s&timestamp=%s&nonce=%s";
/**
* 统一视屏平台下载图片文件
*/
private final String DOWNLOAD_PICTURE = "/uvp-micro-service/download?fileid=%s&ak=%s&token=%s&timestamp=%s&nonce=%s";
/**
* 从第三方文件服务器中下载图片
*/
public void downloadPic() {
if (Objects.equals(0, 0)) {
log.warn("++++++++++++++++未启用人工智能平台相关功能之图片下载+++++++++++");
return;
}
log.info("++++++++启用人工智能平台之图片下载++++++++++++");
String token = getToken();
if (StringUtils.isEmpty(token)) {
log.error("==========单次抓图获取统一视频平台token异常======");
return;
}
//获取所有的设备列表
List<TEquipment> equipmentList = tEquipmentMapper.getAllEquipmentList();
if (CollUtil.isEmpty(equipmentList)) {
log.info("=============本地设备列表数据为空========");
return;
}
for (TEquipment equipment : equipmentList) {
taskExecutor.submit(() -> {
Integer status = equipment.getStatus();
if (1 != status) {
//log.info("==========设备未启用code为{}", equipment.getEquipCode());
return;
}
if (null == equipment.getFileId()) {
return;
}
String COMPLETE_DOWNLOAD_PICTURE = VIDEO_ADDRESS + String.format(DOWNLOAD_PICTURE, equipment.getFileId(), VIDEO_USERNAME, token, DateUtils.getTimeStamp(), UUID.randomUUID());
log.info("============统一视频下载图片地址为:{}", COMPLETE_DOWNLOAD_PICTURE);
HttpResponse execute = HttpUtil.createGet(COMPLETE_DOWNLOAD_PICTURE).execute();
boolean ok = execute.isOk();
log.info("===========设备code{},请求统一视屏中心下载图片结果是否成功:{}==========", equipment.getEquipCode(), ok ? "成功" : "失败");
if (ok) {
log.info("===============统一视频下载图片请求成功===============");
String responseBody = execute.body();
//交给人工智能平台处理
//aiProcess(responseBody, equipment.getEquipCode(), equipment.getFileId());
} else {
log.error("=============统一视频下载图片请求接口失败=============");
}
});
}
}
/**
* 人工智能平台处理图片判断风险
*
* @param base64Img 图片
* @param equipCode 设备code
* @param fileId 第三方文件id
*/
private void aiProcess(String base64Img, String equipCode, String fileId) {
log.info("==============进入人工智能处理图片信息流程=============");
Map<String, Object> body = new HashMap<>(16);
//aqm:安全帽gz:未着装规范aqd:未佩戴安全帽jjqcr:警戒区闯入xy:吸烟zywjh:作业无监护
String[] arr = new String[]{"aqm", "gz", "aqd", "jjqcr", "xy", "zywjh"};
body.put("detect_type", arr);
body.put("format", "0");
body.put("image", base64Img);
HttpResponse execute = HttpUtil.createPost(url).body(JSON.toJSONString(body)).execute();
boolean ok = execute.isOk();
log.info("===========请求人工智能平台结果是否成功:{}==========", ok ? "成功" : "失败");
if (ok) {
String responseBody = execute.body();
responseData responseData = JSON.parseObject(responseBody, responseData.class);
List<ImageDefect> imageDefect = responseData.getImageDefect();
//本次动作
String className = imageDefect.stream().map(ImageDefect::getClassName).collect(Collectors.joining(","));
//是否含有违章行为
boolean illegal = hasIllegalBehavior(imageDefect);
log.info("动作是否违章:{}", illegal ? "没有违章" : "违章");
log.info("-------动作是否违章:{}-------", illegal ? "没有违章" : "违章");
//获取上次动作
Map<String, Object> preEquipMap = (Map<String, Object>) responseMp.get(equipCode);
String preClassName = (String) preEquipMap.get("className");
//有违章&&非重复动作
boolean repeatAndIllegal = hasIllegalBehaviorAndRepeat(illegal, preClassName, className);
if (repeatAndIllegal) {
log.info("设备code{},发生动作变化,变化之前动作:{},变化之后动作:{}", equipCode, preClassName, className);
log.info("------------设备code{},发生动作变化,变化之前动作:{},变化之后动作:{}--------------", equipCode, preClassName, className);
TImageLibrary imageLibrary = new TImageLibrary();
imageLibrary.setClassName(className);
/*todo 上传到oss服务器*/
imageLibrary.setImgUrl("");
imageLibrary.setFileId(fileId);
imageLibrary.setEquipCode(equipCode);
imageLibrary.setStartTime(DateUtils.getNowDate());
imageLibrary.setEndTime(DateUtils.getNowDate());
tImageLibraryService.insert(imageLibrary);
//查询该动作最新的一条数据
if (null != preClassName) {
//修改最近动作结束时间
TImageLibrary preImage = tImageLibraryMapper.getByClassNameAndCode(preClassName, equipCode);
if (null != preImage) {
preImage.setEndTime(DateUtils.getNowDate());
tImageLibraryService.updateEndTime(preImage);
}
}
}
//记录本次动作
Map<String, Object> afterEquipMap = new HashMap<>(16);
afterEquipMap.put("className", className);
responseMp.put(equipCode, afterEquipMap);
} else {
log.error("--------请求人工智能平台失败:{}", execute);
}
}
/**
* 单次抓图
*/
public void catchPicture() {
if (Objects.equals(VIDEO_START, 0)) {
log.warn("++++++++++++++++ stop catch picture running, place check the nacos config the value of video.start +++++++++++");
return;
}
log.info("+++++++++++++++++ start catch picture +++++++++++++++++");
String token = getToken();
if (StringUtils.isEmpty(token)) {
log.error("========== catch picture interface, get token error ======");
return;
}
String COMPLETE_CATCH_PICTURE = VIDEO_ADDRESS + String.format(CATCH_PICTURE, VIDEO_USERNAME, token, DateUtils.getTimeStamp(), UUID.randomUUID());
// log.info("============!!!!!!!!========= catch picture interface url is {}", COMPLETE_CATCH_PICTURE);
//获取所有的设备列表
List<TEquipment> equipmentList = tEquipmentMapper.getAllEquipmentList();
if (CollUtil.isEmpty(equipmentList)) {
log.info("============= there is no equipmentList in dataBase ========");
return;
}
log.info("============ equipmentList number is {} ========", equipmentList.size());
//for (TEquipment equipment : equipmentList) {
for (int i = 0; i < 3; i++) {
TEquipment equipment = equipmentList.get(i);
//taskExecutor.execute(() -> {
String equipCode = equipment.getEquipCode();
Integer status = equipment.getStatus();
if (1 != status) {
//log.info("=========== equipment off line the code is{}do not execution =========", equipCode);
return;
}
log.info("============== equipment on the line, the code is {}, execute catch picture ==========", equipCode);
Map<String, Object> body = new HashMap<>(16);
body.put("sessionId", UUID.randomUUID());
body.put("code", equipCode);
log.info("============!!!!!!!!========= catch picture interface url is {}", COMPLETE_CATCH_PICTURE);
log.info("============!!!!!!!!========= catch picture interface query body is {}", JSON.toJSONString(body));
HttpResponse execute = HttpUtil.createPost(COMPLETE_CATCH_PICTURE).body(JSON.toJSONString(body)).execute();
boolean ok = execute.isOk();
log.info("================= equipment code{}, response header from catch picture {}", equipCode, JSON.toJSONString(execute.headers()));
log.info("================= equipment code{}, response body from catch picture {}", equipCode, JSON.toJSONString(execute.body()));
log.info("================= equipment code{}, response status from catch picture {}", equipCode, JSON.toJSONString(execute.getStatus()));
if (ok) {
String responseBody = execute.body();
CommonResp commonResp = JSON.parseObject(responseBody, CommonResp.class);
if (Objects.equals("true", commonResp.successful)) {
log.info("============= equipment code{}, result by catch picture is {}", equipCode, "success!!!");
Map<String, Object> resultValue = commonResp.resultValue;
String fileUrl = (String) resultValue.get("fileUrl");
String[] split = fileUrl.split("=");
String fileId = split[1];
//更新抓取的图片信息
TEquipment updateEquip = new TEquipment();
updateEquip.setId(equipment.getId());
updateEquip.setFileUrl(fileUrl);
updateEquip.setFileId(fileId);
updateEquip.setCatchTime(new Date());
tEquipmentMapper.update(updateEquip);
} else {
log.info("============= equipment code{}, result by catch picture is {}", equipCode, "error!!!");
}
}
//});
}
log.info("+++++++++++++++++ end catch picture +++++++++++++++++");
}
public String toStr(Object obj) {
if (null == obj) {
return null;
}
return String.valueOf(obj);
}
/**
* 同步统一视频中心设备列表
*/
public void asyncDeviceList() {
if (Objects.equals(0, 0)) {
log.warn("++++++++++++++++未启用人工智能平台相关功能之同步设备+++++++++++");
return;
}
log.info("++++++++启用人工智能平台之同步设备++++++++++++");
String token = getToken();
if (StringUtils.isEmpty(token)) {
log.error("==========同步设备获取统一视频平台token异常======");
return;
}
// String COMPLETE_DEVICE_LIST = String.format(DEVICE_LIST, VIDEO_USERNAME, token, DateUtils.getTimeStamp(), UUID.randomUUID());
String COMPLETE_DEVICE_LIST = VIDEO_ADDRESS + String.format(DEVICE_LIST, VIDEO_USERNAME, token, DateUtils.getTimeStamp(), UUID.randomUUID());
DeviceQueryVo deviceQueryVo = new DeviceQueryVo();
/*todo 其他参数未知*/
List<String> list = new ArrayList<>();
list.add("01");
deviceQueryVo.setDevType(list);
deviceQueryVo.setPageNo(1);
deviceQueryVo.setPageSize(10);
log.info("================第一次请求统一视频同步设备接口参数:{}", JSON.toJSONString(deviceQueryVo));
log.info("================第一次请求统一视频同步设备接口地址为:{}", COMPLETE_DEVICE_LIST);
HttpResponse execute = HttpUtil.createPost(COMPLETE_DEVICE_LIST).body(JSON.toJSONString(deviceQueryVo)).execute();
boolean ok = execute.isOk();
log.info("第一次请求统一视频平台获取设备列表接口结果是否成功:{}", ok ? "成功" : "失败");
log.info("===========第一次请求统一视屏平台获取设备列表接口结果是否成功:{}", ok ? "成功" : "失败");
if (ok) {
String responseBody = execute.body();
log.info("第一次请求统一视频平台返回结果:{}", responseBody);
log.info("========获取统一视频设备列表,第一次请求统一视频平台返回结果:{}", responseBody);
CommonResp commonResp = JSON.parseObject(responseBody, CommonResp.class);
if (Objects.equals("true", commonResp.successful)) {
List<String> thirdEquipmentList = new ArrayList<>();
Map<String, Object> resultValue = commonResp.getResultValue();
Integer total = (Integer) resultValue.get("total");
//每页5000条
double value = NumberUtil.div(String.valueOf(total), "5000").doubleValue();
int pageNum = (int) Math.ceil(value);
//查询本地是否有重复数据
List<String> allEquipmentIdList = tEquipmentMapper.getEquipmentIdList();
//查询的总数量
int totalCount = 0;
//新增的总数量
int insertCount = 0;
//删除的总数量
int deleteCount = 0;
for (int i = 1; i <= pageNum; i++) {
List<TEquipment> insertEquipmentList = new ArrayList<>();
DeviceQueryVo deviceQueryBody = new DeviceQueryVo();
/*todo 其他参数未知*/
deviceQueryBody.setDevType(list);
deviceQueryBody.setPageNo(pageNum);
deviceQueryBody.setPageSize(5000);
HttpResponse afterExecute = HttpUtil.createPost(COMPLETE_DEVICE_LIST).body(JSON.toJSONString(deviceQueryBody)).execute();
boolean executeOk = afterExecute.isOk();
log.info("第{}次请求统一视屏平台获取设备列表接口结果是否成功:{}", i + 1, executeOk ? "成功" : "失败");
if (executeOk) {
CommonResp resp = JSON.parseObject(afterExecute.body(), CommonResp.class);
Map<String, Object> respResultValue = resp.getResultValue();
List<Map<String, Object>> devList = (List<Map<String, Object>>) respResultValue.get("devList");
TEquipment equipment;
for (Map<String, Object> map : devList) {
totalCount++;
//如果没有则新增
String equipId = toStr(map.get("id"));
if (!allEquipmentIdList.contains(equipId)) {
equipment = new TEquipment();
equipment.setEquipCode(toStr(map.get("devCode")));
equipment.setEquipId(equipId);
equipment.setEquipType(toStr(map.get("devType")));
equipment.setEquipName(toStr(map.get("devName")));
equipment.setEquipShortName(toStr(map.get("devShortName")));
equipment.setNodeCode(toStr(map.get("nodeCode")));
equipment.setStatus((Integer) map.get("status"));
equipment.setDecoderTag(toStr(map.get("decoderTag")));
equipment.setLongitude(toStr(map.get("longLtude")));
equipment.setLatitude(toStr(map.get("latLtude")));
equipment.setCreateTime(DateUtils.parseDate(toStr(map.get("createTime"))));
equipment.setUpdateTime(DateUtils.parseDate(toStr(map.get("updateTime"))));
equipment.setScore((Integer) map.get("socre"));
insertEquipmentList.add(equipment);
}
//第三方的所有数据
thirdEquipmentList.add(equipId);
}
}
//批量新增
List<List<TEquipment>> split = CollUtil.split(insertEquipmentList, 500);
for (List<TEquipment> equipmentList : split) {
int rows = tEquipmentMapper.insertBatch(equipmentList);
insertCount += rows;
}
}
log.info("查询统一视频平台所有的数据量为:{}条", totalCount);
log.info("新增入数据库数据量为:{}", insertCount);
//移除多余的设备
/*List<String> collect = allEquipmentIdList.stream().filter(it -> !thirdEquipmentList.contains(it)).collect(Collectors.toList());
tEquipmentMapper.deleteByIds(StringUtils.join(collect, ","));*/
}
}
}
/**
* 统一视频平台登录获取token
*
* @return
*/
private String getToken() {
String token = redisService.getCacheObject(getTokenKey(VIDEO_USERNAME));
if (StringUtils.isNotEmpty(token)) {
return token;
} else {
log.info("=========获取新的token=========");
Map<String, Object> body = new HashMap<>(16);
body.put("ak", VIDEO_USERNAME);
body.put("sk", Base64.getEncoder().encodeToString(VIDEO_PASSWORD.getBytes()));
HttpResponse execute = HttpUtil.createPost(VIDEO_ADDRESS + LOGIN_URL).body(JSON.toJSONString(body)).execute();
log.info("=======获取token接口参数为{}", JSON.toJSONString(body));
String COMPLETE_AUTH_URL = VIDEO_ADDRESS + LOGIN_URL;
log.info("=======获取token接口请求地址为{}", COMPLETE_AUTH_URL);
// HttpResponse execute = HttpUtil.createPost(COMPLETE_AUTH_URL).body(JSON.toJSONString(body)).execute();
boolean ok = execute.isOk();
log.info("请求统一视屏平台登录接口结果是否成功:{}", ok ? "成功" : "失败");
if (ok) {
log.info("===========请求统一视频平台接口通畅========");
String responseBody = execute.body();
log.info("统一视屏平台登录返回结果:{}", responseBody);
AuthResultDto authResultDto = JSON.parseObject(responseBody, AuthResultDto.class);
if (Objects.equals("true", authResultDto.getSuccessful())) {
token = authResultDto.getResultValue().getToken();
log.info("========获取的token成功=======");
redisService.setCacheObject(getTokenKey(VIDEO_USERNAME), token, CacheConstants.VIDEO_TOKEN_KEY_EXPIRATION, TimeUnit.MINUTES);
return token;
} else {
log.error("=============获取token失败============");
}
} else {
log.error("====获取token接口请求失败=======返回结果为:{}", execute);
}
return null;
}
}
/**
* 判断是否违章
*
* @param imageDefect
* @return
*/
private boolean hasIllegalBehavior(List<ImageDefect> imageDefect) {
boolean illegal = true;
for (String risk : RISK_CONSTANTS) {
boolean contains = imageDefect.stream().map(ImageDefect::getClassName).collect(Collectors.toList()).contains(risk);
if (contains) {
illegal = false;
break;
}
}
return illegal;
}
/**
* 是否为重复动作&& 是否违章
*/
private boolean hasIllegalBehaviorAndRepeat(boolean illegal, String preClassName, String className) {
boolean repeat = Objects.equals(preClassName, className);
return illegal && !repeat;
}
@Data
private static class responseData {
private String resultCode;
private String resultMsg;
private List<ImageDefect> imageDefect;
public String getResultCode() {
return resultCode;
}
public void setResultCode(String resultCode) {
this.resultCode = resultCode;
}
public String getResultMsg() {
return resultMsg;
}
public void setResultMsg(String resultMsg) {
this.resultMsg = resultMsg;
}
public List<ImageDefect> getImageDefect() {
return imageDefect;
}
public void setImageDefect(List<ImageDefect> imageDefect) {
this.imageDefect = imageDefect;
}
}
@Data
private static class ImageDefect {
private String className;
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
}
@Data
private static class AuthResultDto {
private String successful;
private ResultValue resultValue;
private String resultHint;
@Data
private static class ResultValue {
private String ak;
private String token;
}
}
/**
* 登录账户密码错误次数缓存键名
*
* @param username 用户名
* @return 缓存键key
*/
private String getTokenKey(String username) {
return CacheConstants.VIDEO_TOKEN_KEY + username;
}
@Data
private static class DeviceQueryVo {
/**
* 设备标签集合
*/
private List<String> devDecoderTagList;
/**
* 设备名称
*/
private List<String> devName;
/**
* 设备名称
*/
private List<String> devSocreList;
/**
* 设备状态集合
*/
private List<String> devStatusList;
/**
* 设备评级集合
*/
private List<String> devType;
private int pageNo;
private int pageSize;
}
@Data
public static class CommonResp {
private String successful;
private Map<String, Object> resultValue;
private String resultHint;
}
}