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

610 lines
25 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}