feat(bonus-smart-site): 新增球机控制相关功能

- 添加 BallMachineControl 类用于球机控制
- 新增 3D 云台控制相关方法和接口
- 增加球机调试权限相关功能
- 优化视频设备管理相关接口
- 新增 XML 解析和处理工具类
- 添加杰克逊 JSON序列化和反序列化工具类
This commit is contained in:
jjLv 2025-01-24 17:48:06 +08:00
parent b8fd5bbbc7
commit b913e1f91f
12 changed files with 598 additions and 14 deletions

View File

@ -115,6 +115,32 @@
<artifactId>okhttp</artifactId>
</dependency>
<!--jackson core-->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<!--jackson mapper-->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<!-- Apache POI dependencies -->
<dependency>

View File

@ -9,13 +9,12 @@ import com.bonus.common.core.web.page.TableDataInfo;
import com.bonus.common.log.annotation.SysLog;
import com.bonus.common.log.enums.OperaType;
import com.bonus.common.redis.service.RedisService;
import com.bonus.smartsite.basic.domain.BallMachineControl;
import com.bonus.smartsite.basic.domain.PlatformConfiguration;
import com.bonus.smartsite.basic.domain.VideoEquipment;
import com.bonus.smartsite.basic.service.IVideoEquipmentService;
import com.bonus.smartsite.common.annotation.PreventRepeatSubmit;
import com.bonus.smartsite.common.utils.DateTimeHelper;
import com.bonus.smartsite.common.utils.HttpClient;
import com.bonus.smartsite.common.utils.SystemUtils;
import com.bonus.smartsite.common.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
@ -61,6 +60,9 @@ public class VideoEquipmentController extends BaseController {
* 设置视频叠加文字
*/
private static final String WATERMARK_URL = "IV/F_IV_TextAdd";
private static final String TYPE_CLEAR = "清新";
private static final String TYPE_CREATION = "创世";
private static final String TYPE_UNIFIED = "统一";
/**
* 查询视频设备管理列表
@ -293,17 +295,18 @@ public class VideoEquipmentController extends BaseController {
public AjaxResult updateWaterMark(@RequestBody VideoEquipment bean) {
try {
String token = redisService.getCacheObject("videoToken");
String text = bean.getOneText() + "\r\n" + bean.getTwoText();
Map<String, Object> jsonMap = new HashMap<>(16);
jsonMap.put("puid", bean.getPuId());
jsonMap.put("idx", 0);
jsonMap.put("text", text);
jsonMap.put("align", "右下对齐");
jsonMap.put("xpos", "2");
jsonMap.put("ypos", "2");
String json = JSON.toJSONString(jsonMap);
String res = HttpClient.sendPost(bean.getVideoPath() + WATERMARK_URL + "?token=" + token, json);
return success(res);
// String text = bean.getOneText() + "\r\n" + bean.getTwoText();
// Map<String, Object> jsonMap = new HashMap<>(128);
// jsonMap.put("puid", bean.getPuId());
// jsonMap.put("idx", 0);
// jsonMap.put("text", text);
// jsonMap.put("align", "右下对齐");
// jsonMap.put("xpos", "2");
// jsonMap.put("ypos", "2");
// String json = JSON.toJSONString(jsonMap);
// String res = HttpClient.sendPost(bean.getVideoPath() + WATERMARK_URL + "?token=" + token, json);
String str = QxVideotape.setOsdText(bean,token);
return success(str);
} catch (Exception e) {
logger.error(e.toString(), e);
}
@ -311,4 +314,78 @@ public class VideoEquipmentController extends BaseController {
}
/**
* 球机调试权限
* 暂时废弃
*/
@ApiOperation(value = "球机调试权限")
@PostMapping("/getDebugBallMachine")
public AjaxResult getDebugBallMachine(VideoEquipment bean) {
try {
if(service.getDebugBallMachine(bean) > 0){
return success();
} else {
String typeName = getTypeName(bean.getType());
return error(typeName +"平台配置未启用!");
}
} catch (Exception e) {
logger.error(e.toString(), e);
}
return error("系统异常,请联系管理员");
}
private String getTypeName(String type) {
if (type == null) {
return "";
}
switch (type) {
case "1":
return TYPE_CLEAR;
case "2":
return TYPE_CREATION;
case "3":
return TYPE_UNIFIED;
default:
return "";
}
}
/**
* 设置3D云台
* @param bean bean
* @return AjaxResult
*/
@PostMapping("set3dCloudConfig")
public AjaxResult set3dCloudConfig(@RequestBody BallMachineControl bean) {
AjaxResult ar = new AjaxResult();
try {
String token = redisService.getCacheObject("videoToken");
// 校验输入参数
validateBean(bean);
String resultMsg = QxVideotape.set3DyunConfig(
bean.getSx(), bean.getSy(), bean.getEx(), bean.getEy(), bean.getPuid(), bean.getUrl(),token
);
return AjaxResult.success(resultMsg);
} catch (IllegalArgumentException e) {
log.error("参数校验失败: {}", e.getMessage());
return AjaxResult.error("设置失败");
} catch (Exception e) {
log.error("设置3D云配置时发生异常", e);
return AjaxResult.error("设置异常");
}
}
private void validateBean(BallMachineControl bean) {
if (bean == null) {
throw new IllegalArgumentException("请求参数不能为空");
}
if (bean.getSx() == null || bean.getSy() == null || bean.getEx() == null || bean.getEy() == null
|| bean.getPuid() == null || bean.getUrl() == null) {
throw new IllegalArgumentException("请求参数包含空值");
}
}
}

View File

@ -0,0 +1,19 @@
package com.bonus.smartsite.basic.domain;
import lombok.Data;
@Data
public class BallMachineControl {
private String puid;
private String sx;
private String sy;
private String ex;
private String ey;
private String url;
}

View File

@ -183,4 +183,9 @@ public class VideoEquipment implements Serializable {
*/
private String videoPath;
/**
* 平台类型
*/
private String type;
}

View File

@ -77,4 +77,11 @@ public interface VideoEquipmentMapper {
* 获取视频设备平台配置详细信息
*/
PlatformConfiguration getVideoEquipment();
/**
* 球机调试权限
* @param bean VideoEquipment
* @return int
*/
int getDebugBallMachine(VideoEquipment bean);
}

View File

@ -4,6 +4,7 @@ import com.bonus.smartsite.basic.domain.PlatformConfiguration;
import com.bonus.smartsite.basic.domain.VideoEquipment;
import java.util.List;
import java.util.Map;
/**
* 视频设备管理Service接口
@ -60,4 +61,12 @@ public interface IVideoEquipmentService {
* 获取视频设备平台配置详细信息
*/
PlatformConfiguration getVideoEquipment();
/**
* 球机调试权限
* @param bean VideoEquipment
* @return int
*/
int getDebugBallMachine(VideoEquipment bean);
}

View File

@ -127,4 +127,14 @@ public class VideoEquipmentServiceImpl implements IVideoEquipmentService {
public PlatformConfiguration getVideoEquipment() {
return videoEquipmentMapper.getVideoEquipment();
}
/**
* 球机调试权限
* @param bean VideoEquipment
* @return int
*/
@Override
public int getDebugBallMachine(VideoEquipment bean) {
return videoEquipmentMapper.getDebugBallMachine(bean);
}
}

View File

@ -0,0 +1,48 @@
package com.bonus.smartsite.common.utils;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import java.io.IOException;
/**
* @author 19814
*/
public class JacksonHelper implements JsonHelper {
@Override
public String jsonSerialize(Object value) {
ObjectMapper objectMapper = new ObjectMapper();
try {
return objectMapper.writeValueAsString(value);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
@Override
@SuppressWarnings("unchecked")
public <T> T jsonDeserialize(String value, Class<?> tClass) {
ObjectMapper objectMapper = new ObjectMapper();
try {
return (T) objectMapper.readValue(value, tClass);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
@SuppressWarnings("unchecked")
public <T> T jsonDeserialize(String value,
TypeReference<T> typeReference) {
ObjectMapper objectMapper = new ObjectMapper();
try {
return (T) objectMapper.readValue(value, typeReference);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -0,0 +1,159 @@
package com.bonus.smartsite.common.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.util.List;
public interface JsonHelper {
public String jsonSerialize(Object value);
public <T> T jsonDeserialize(String value, Class<?> tClass);
/**
* 将任意bean转换成json字符串
* fast json
* @param bean
* @param <T>
* @return
*/
public static <T> String beanToJsonStr(T bean) {
String jsonStr = JSON.toJSONString(bean);
return jsonStr;
}
/**
* 把一个json字符串转换成bean对象
* fast json
* @param str
* @param <T>
* @return
*/
public static <T> T jsonStrToBean(String str, Class<T> clazz) {
T bean = JSON.parseObject(str, clazz);
return bean;
}
/**
* 把一个jsonObj转换成bean对象
* fast json
* @param jsonObj
* @param <T>
* @return
*/
public static <T> T jsonObjToBean(JSONObject jsonObj, Class<T> clazz) {
String s = jsonObj.toJSONString();
T bean = JSON.parseObject(s, clazz);
return bean;
}
/**
* 把一个bean对象转换成jsonObj
* fast json
* @param bean
* @param <T>
* @return
*/
public static <T> JSONObject beanToJsonObj(T bean) {
Object o = JSON.toJSON(bean);
return (JSONObject) o;
}
/**
* 把一个jsonStr转换成jsonObj
* fast json
* @param str
* @return
*/
public static JSONObject jsonStrToJsonObj(String str) {
Object o = JSON.parseObject(str);
return (JSONObject) o;
}
/**
* 把一个jsonObj转换成jsonStr
* fast json
* @param jsonObj
* @return
*/
public static String jsonObjToJsonStr(JSONObject jsonObj) {
String s = jsonObj.toJSONString();
return s;
}
/**
* 把一个beanList对象转换成jsonArrStr
* fast json
* @param beanList
* @param <T>
* @return
*/
public static <T> JSONArray beanListToJsonArrStr(List<T> beanList) {
Object o = JSON.toJSON(beanList);
return (JSONArray) o;
}
/**
* 把一个jsonArrStr转换成beanList对象
* fast json
* @param jsonArrStr
* @param <T>
* @return
*/
public static <T> List<T> jsonArrStrToBeanList(String jsonArrStr,Class<T> clazz) {
List<T> ts = JSON.parseArray(jsonArrStr, clazz);
return ts;
}
/**
* 把一个JsonArr转换成JsonArrStr
* fast json
* @param jsonArr
* @return
*/
public static String jsonArrToJsonArrStr(JSONArray jsonArr) {
String s = JSON.toJSONString(jsonArr);
return s;
}
/**
* 把一个JsonArrStr文本转换成JsonArr
* fast json
* @param jsonArrStr
* @return
*/
public static JSONArray jsonArrStrToJsonArr(String jsonArrStr) {
Object o = JSON.parse(jsonArrStr);
return (JSONArray) o;
}
/**
* 把一个JsonArr转换成beanList
* fast json
* @param jsonArr
* @return
*/
public static <T> List<T> jsonArrToBeanList(JSONArray jsonArr,Class<T> clazz) {
String s = JSON.toJSONString(jsonArr);
List<T> ts = JSON.parseArray(s, clazz);
return ts;
}
/**
* 把一个beanList文本转换成JsonArr
* fast json
* @param beanList
* @return
*/
public static <T> JSONArray beanListToJsonArr(List<T> beanList) {
Object o = JSON.toJSON(beanList);
return (JSONArray) o;
}
}

View File

@ -0,0 +1,116 @@
package com.bonus.smartsite.common.utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.httpclient.methods.PostMethod;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import java.io.IOException;
import java.util.Iterator;
import org.apache.commons.httpclient.NameValuePair;
@Slf4j
public class PostXml {
/**
* 获取3d云台报文
*
* @param Sx 开始横坐标
* @param Sy 开始y坐标
* @param Ex 结束点很坐标
* @param Ey 结束点 y坐标
* @return
*/
public static String get3DyunXmlData(String Sx, String Sy, String Ex, String Ey) {
StringBuffer builder = new StringBuffer();
try {
builder.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
builder.append("<M Type=\"ComReq\">");
builder.append("<C Type=\"C\" Prio=\"1\" EPID=\"system\">");
builder.append("<Res Type=\"PTZ\" Idx=\"0\" OptID=\"C_PTZ_SelectZoom\">");
builder.append("<Param BeginX=\"" + Sx + "\" BeginY=\"" + Sy + "\" EndX=\"" + Ex + "\" EndY=\"" + Ey + "\"></Param>");
builder.append("</Res>");
builder.append("</C>");
builder.append("</M>");
} catch (Exception e) {
log.error(e.toString(), e);
}
return builder.toString();
}
/**
* 设置水印
*
* @param value
* @return
*/
public static String getOsDText(String value) {
StringBuffer builder = new StringBuffer();
try {
builder.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
builder.append("<M Type=\"ComReq\">");
builder.append("<C Type=\"S\" Prio=\"1\" EPID=\"system\">");
builder.append("<Res Type=\"IV\" Idx=\"0\" OptID=\"F_IV_TextAdd\">");
builder.append("<Param Value=\"" + value + "\"></Param>");
builder.append("</Res>");
builder.append("</C>");
builder.append("</M>");
} catch (Exception e) {
log.error(e.toString(), e);
}
return builder.toString();
}
public static String sedPostXml(String postUrl, String xmlString) throws IOException {
String postURL;
PostMethod postMethod = null;
postMethod = new PostMethod(postUrl);
postMethod.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
//参数设置需要注意的就是里边不能传NULL要传空字符串
NameValuePair[] data = {
new NameValuePair("xml", xmlString),
};
postMethod.setRequestBody(data);
org.apache.commons.httpclient.HttpClient httpClient = new org.apache.commons.httpclient.HttpClient();
int response = httpClient.executeMethod(postMethod); // 执行POST方法
String result = postMethod.getResponseBodyAsString();
return result;
}
/**
* xml解析
*
* @return
*/
public static String getXml3dYunConfigData(String xml) {
String msg = "设置成功";
try {
Document doc = DocumentHelper.parseText(xml); // 将字符串转为XML
Element rootElt = doc.getRootElement(); // 获取根节点
// System.out.println("根节点:" + rootElt.getName()); // 拿到根节点的名称
Element C = rootElt.element("C");
// System.out.println("子节点:" + C.getName()); // 拿到子节点名称
Iterator iter = C.elementIterator("Res"); // 获取结果点下的返回数据集合
while (iter.hasNext()) {
Element Event = (Element) iter.next();//子节点名//父类节点
// System.out.println("根节点:" + Event.getName()); // 拿到根节点的名称
String type = Event.attributeValue("Type");
if (!"PTZ".equals(type)) {
msg = "设置失败";
}
}
} catch (Exception e) {
msg = "设置失败";
}
return msg;
}
}

View File

@ -0,0 +1,103 @@
package com.bonus.smartsite.common.utils;
import com.bonus.common.redis.service.RedisService;
import com.bonus.smartsite.basic.domain.VideoEquipment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* 清新平台数据获取
*
* @author 吕继龙
*/
@Slf4j
@Component
public class QxVideotape {
@Autowired
private RedisService redisService;
private static final String EPID = "system";// 登录平台企业ID
private static final int BFIX = 1;// 登录平台是否通过网闸模式
private static final String LOGIN_URL = "login";// 登录地址
private static final String LOGIN_URL2 = "login2";// 加密登录
private static final String GETBALLURL = "CAS/C_CAS_QueryPUIDRes";// 球机状态批量获取
private static final String GETBALLFILE = "SG/C_SG_QueryRecordFiles"; // 获取前端录像-图片-
private static final String GETBALLLIST = "CAS/C_CAS_QueryPUIDSets"; // 获取平台下球机列表
private static final String GPSBALLURL = "GPS/C_GS_QueryLastGPSData";//获取球机gps
private static final String GETBALLLoadFile = "SG/C_SG_DownLoadFile_PushMode"; //下载前端抓拍文件
private static final String ON_DEMAND_VIDEO = "SG/VODFile.flv"; //前端存储 - 点播前端录像
private static final String ONDEMANDVIDEOPLATFORM = "CSS/VODFile.flv"; //云台点播 - 点播云台录像
private static final String QUERYSTORAGEFILES = "CSS/C_CSS_QueryStorageFiles"; //云存储 - 查询云录像云抓拍
private static final String QUERYPICTUREFILES = "CSS/C_CSS_DownloadFile";//云存储 - 下载云平台图片文件
private static final String DOWN_WEB_URL="SG/C_SG_DownLoadFile_PushMode";
private static final String BallUpdown = "RawRequest?dstType=8&dstID=&token=";//球机上下线
private static final String setConfig = "RawRequest?dstType=201&dstID=";//裸命令接口
private static final String set3dConfig = "RawRequest?dstType=201&dstID=";//裸命令接口
private static final String WATERMARK_URL = "IV/F_IV_TextAdd";//设置视频叠加文字
private static final String RawRequest_URL = "RawRequest";//设置视频叠加文字
public static final String pictureQuery = QUERYPICTUREFILES; //云存储 - 下载云平台图片文件
public static final String videoQuery = ONDEMANDVIDEOPLATFORM;//云台点播 - 点播云台录像
public static final String videoWebQuery = ON_DEMAND_VIDEO;//前端录像点播
private static final String setDeviceText = "xml?dstType=201&dstID=";
public static String set3DyunConfig(String Sx, String Sy, String Ex, String Ey, String puid, String Q2HTTPURL,String token ) {
String msg = "设置成功";
try {
String xml = PostXml.get3DyunXmlData(Sx, Sy, Ex, Ey);
Map<String, String> jsonMap = new HashMap<>(16);
jsonMap.put("xml", xml);
String json = new JacksonHelper().jsonSerialize(jsonMap);
String resultXml = HttpClient.sendPost(Q2HTTPURL + set3dConfig + puid + "&token=" + token, json);
msg = PostXml.getXml3dYunConfigData(resultXml);
} catch (Exception e) {
msg = "设置失败";
log.error(e.toString(), e);
}
return msg;
}
/**
* 设置叠加文字
*
* @param o
* @return
*/
public static String setOsdText(VideoEquipment o,String token) {
String text = o.getOneText() + "\r\n" + o.getTwoText();
try {
//登录
log.info("xml:" + o.getVideoPath() + setDeviceText + o.getPuId() + "&token=" + token);
String xml = PostXml.getOsDText(text);
String str = PostXml.sedPostXml(o.getVideoPath() + setDeviceText + o.getPuId() + "&token=" + token, xml);
return str;
} catch (Exception e) {
log.error(e.toString(), e);
return "";
}
}
}

View File

@ -122,4 +122,9 @@
FROM sys_video_config
WHERE del_flag = 0 AND status = 1
</select>
<select id="getDebugBallMachine" resultType="java.lang.Integer">
SELECT count(1)
FROM sys_video_config
WHERE del_flag = 0 AND status = 1 AND type = #{type}
</select>
</mapper>