定义第三方接口信息

This commit is contained in:
lin
2025-09-29 16:15:32 +08:00
parent 85d47af644
commit eff1773101
16 changed files with 394 additions and 31 deletions

View File

@@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.gb28181.dao.provider.ChannelProvider;
import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
import com.genersoft.iot.vmp.streamPush.bean.StreamPush;
import com.genersoft.iot.vmp.web.custom.bean.CameraChannel;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;
@@ -603,4 +604,10 @@ public interface CommonGBChannelMapper {
"</foreach> " +
"</script>")
void updateGps(List<CommonGBChannel> commonGBChannels);
@SelectProvider(type = ChannelProvider.class, method = "queryListForSy")
List<CameraChannel> queryListForSy(@Param("query") String query, @Param("sortName") String sortName, @Param("order") String order,
@Param("groupDeviceId") String groupDeviceId, @Param("online") Boolean online, @Param("containMobileDevice") Boolean containMobileDevice);
}

View File

@@ -292,4 +292,7 @@ public interface GroupMapper {
@Select("SELECT * from wvp_common_group WHERE alias = #{alias} ")
Group queryGroupByAlias(@Param("alias") String alias);
@Select("SELECT * from wvp_common_group WHERE alias = #{alias} and business_group = #{businessGroup}")
Group queryGroupByAliasAndBusinessGroup(@Param("alias") String alias, @Param("deviceId") String businessGroup);
}

View File

@@ -484,4 +484,31 @@ public class ChannelProvider {
sqlBuild.append(" AND wdc.channel_type = 0 ");
return sqlBuild.toString();
}
public String queryListForSy(Map<String, Object> params ){
StringBuilder sqlBuild = new StringBuilder();
sqlBuild.append(BASE_SQL);
sqlBuild.append(" where channel_type = 0 ");
if (params.get("query") != null) {
sqlBuild.append(" AND (coalesce(gb_device_id, device_id) LIKE concat('%',#{query},'%') escape '/'" +
" OR coalesce(gb_name, name) LIKE concat('%',#{query},'%') escape '/' )")
;
}
if (params.get("online") != null && (Boolean)params.get("online")) {
sqlBuild.append(" AND coalesce(gb_status, status) = 'ON'");
}
if (params.get("online") != null && !(Boolean)params.get("online")) {
sqlBuild.append(" AND coalesce(gb_status, status) = 'OFF'");
}
if (params.get("containMobileDevice") != null && !(Boolean)params.get("containMobileDevice")) {
sqlBuild.append(" AND gb_ptz_type = 99");
}
if (params.get("groupDeviceId") != null) {
sqlBuild.append(" AND coalesce(gb_parent_id, parent_id) = #{groupDeviceId}");
}else {
sqlBuild.append(" AND coalesce(gb_parent_id, parent_id) is null");
}
return sqlBuild.toString();
}
}

View File

@@ -26,4 +26,5 @@ public interface IGroupService {
PageInfo<Group> queryList(Integer page, Integer count, String query);
Group queryGroupByAlias(String groupAlias);
}

View File

@@ -43,10 +43,7 @@ import oshi.software.os.OperatingSystem;
import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
@SuppressWarnings("rawtypes")
@Tag(name = "服务控制")
@@ -369,6 +366,9 @@ public class ServerController {
@ResponseBody
@Operation(summary = "获取地图配置", security = @SecurityRequirement(name = JwtUtils.HEADER))
public List<MapConfig> getMapConfig() {
if (mapService == null) {
return Collections.emptyList();
}
return mapService.getConfig();
}
}

View File

@@ -1,17 +1,20 @@
package com.genersoft.iot.vmp.web.custom;
import com.genersoft.iot.vmp.conf.security.JwtUtils;
import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import com.genersoft.iot.vmp.web.custom.bean.CameraChannel;
import com.genersoft.iot.vmp.web.custom.bean.CameraStreamContent;
import com.genersoft.iot.vmp.web.custom.bean.IdsQueryParam;
import com.genersoft.iot.vmp.web.custom.bean.PolygonQueryParam;
import com.genersoft.iot.vmp.web.custom.service.CameraChannelService;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult;
import java.util.List;
@@ -21,10 +24,54 @@ import java.util.List;
@RequestMapping(value = "/api/sy")
public class CameraChannelController {
@Autowired
private CameraChannelService channelService;
@GetMapping(value = "/camera/list/group")
@ResponseBody
@Operation(summary = "查询摄像机列表, 只查询当前虚拟组织下的", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "page", description = "当前页")
@Parameter(name = "count", description = "每页查询数量")
@Parameter(name = "query", description = "查询内容")
@Parameter(name = "sortName", description = "排序字段名")
@Parameter(name = "order", description = "排序方式(升序 asc 或降序 desc ")
@Parameter(name = "groupAlias", description = "分组别名")
@Parameter(name = "topGroupAlias", description = "虚拟组织别名")
@Parameter(name = "geoCoordSys", description = "坐标系类型WGS84,GCJ02、BD09")
@Parameter(name = "status", description = "摄像头状态")
@Parameter(name = "containMobileDevice", description = "是否包含移动设备")
public PageInfo<CameraChannel> queryListInCurrentGroup(@RequestParam(required = false, value = "page", defaultValue = "1" )Integer page,
@RequestParam(required = false, value = "page", defaultValue = "100")Integer count,
@RequestParam(required = false) String query,
@RequestParam(required = false) String sortName,
@RequestParam(required = false) String order,
@RequestParam(required = false) String groupAlias,
@RequestParam(required = false) String topGroupAlias,
@RequestParam(required = false) Boolean status,
@RequestParam(required = false) Boolean containMobileDevice){
if (ObjectUtils.isEmpty(query)) {
query = null;
}
if (ObjectUtils.isEmpty(sortName)) {
sortName = null;
}
if (ObjectUtils.isEmpty(order)) {
order = null;
}
if (ObjectUtils.isEmpty(groupAlias)) {
groupAlias = null;
}
if (ObjectUtils.isEmpty(topGroupAlias)) {
topGroupAlias = null;
}
return channelService.queryList(page, count, query, sortName, order, groupAlias, topGroupAlias, status, containMobileDevice);
}
@GetMapping(value = "/camera/list")
@ResponseBody
@Operation(summary = "查询摄像机列表", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Operation(summary = "查询摄像机列表, 查询当前虚拟组织下以及全部子节点", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "page", description = "当前页")
@Parameter(name = "count", description = "每页查询数量")
@Parameter(name = "query", description = "查询内容")
@@ -44,14 +91,30 @@ public class CameraChannelController {
@RequestParam(required = false) String topGroupAlias,
@RequestParam(required = false) Boolean status,
@RequestParam(required = false) Boolean containMobileDevice){
if (ObjectUtils.isEmpty(query)) {
query = null;
}
if (ObjectUtils.isEmpty(sortName)) {
sortName = null;
}
if (ObjectUtils.isEmpty(order)) {
order = null;
}
if (ObjectUtils.isEmpty(groupAlias)) {
groupAlias = null;
}
if (ObjectUtils.isEmpty(topGroupAlias)) {
topGroupAlias = null;
}
return null;
return channelService.queryList(page, count, query, sortName, order, groupAlias, topGroupAlias, status, containMobileDevice);
}
@GetMapping(value = "/camera/one")
@ResponseBody
@Operation(summary = "查询单个摄像头信息", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "deviceId", description = "通道编号")
@Parameter(name = "deviceCode", description = "摄像头设备国标编号, 对于非国标摄像头可以不设置此参数")
@Parameter(name = "geoCoordSys", description = "坐标系类型WGS84,GCJ02、BD09")
public CameraChannel getOne(@RequestParam(required = true) String deviceId,
@RequestParam(required = false) String geoCoordSys) {
@@ -62,30 +125,28 @@ public class CameraChannelController {
@ResponseBody
@Operation(summary = "更新摄像头信息", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "deviceId", description = "通道编号")
@Parameter(name = "deviceCode", description = "摄像头设备国标编号, 对于非国标摄像头可以不设置此参数")
@Parameter(name = "name", description = "通道名称")
@Parameter(name = "longitude", description = "经度")
@Parameter(name = "latitude", description = "纬度")
@Parameter(name = "geoCoordSys", description = "坐标系类型WGS84,GCJ02、BD09")
public CameraChannel updateCamera(@RequestParam(required = false) String deviceId,
public CameraChannel updateCamera(String deviceId,
@RequestParam(required = false) String name,
@RequestParam(required = false) Double longitude,
@RequestParam(required = false) Double latitude) {
return null;
}
@GetMapping(value = "/camera/list/ids")
@PostMapping(value = "/camera/list/ids")
@ResponseBody
@Operation(summary = "根据编号查询多个摄像头信息", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "deviceIds", description = "通道编号列表")
@Parameter(name = "geoCoordSys", description = "坐标系类型WGS84,GCJ02、BD09")
public List<CameraChannel> queryListByNos(@RequestParam(value = "deviceIds[]") String[] deviceIds,
@RequestParam(required = false) String geoCoordSys) {
public List<CameraChannel> queryListByNos(@RequestBody IdsQueryParam param) {
return null;
}
@GetMapping(value = "/camera/list/box")
@ResponseBody
@Operation(summary = "根据指定的地理区域和参数查询地图上的摄像头信息", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Operation(summary = "根据矩形查询摄像头", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "minLongitude", description = "最小经度")
@Parameter(name = "maxLongitude", description = "最大经度")
@Parameter(name = "minLatitude", description = "最小纬度")
@@ -96,27 +157,27 @@ public class CameraChannelController {
@Parameter(name = "geoCoordSys", description = "坐标系类型WGS84,GCJ02、BD09")
public List<CameraChannel> queryListInBox(Double minLongitude, Double maxLongitude,
Double minLatitude, Double maxLatitude,
Integer level, String groupAlias,
String topGroupAlias, String geoCoordSys) {
@RequestParam(required = false) Integer level,
String groupAlias, String topGroupAlias,
@RequestParam(required = false) String geoCoordSys) {
return null;
}
@GetMapping(value = "/camera/list/polygon")
@ResponseBody
@Operation(summary = "根据多边形查询摄像头", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Operation(summary = "根据多边形查询摄像头", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "position", description = "多边形位置,格式: [{'lng':116.32, 'lat': 39: 39.2}, {'lng':115.32, 'lat': 39: 38.2}, {'lng':125.32, 'lat': 39: 38.2}]")
@Parameter(name = "level", description = "地图级别")
@Parameter(name = "groupAlias", description = "分组别名")
@Parameter(name = "topGroupAlias", description = "虚拟组织别名")
@Parameter(name = "geoCoordSys", description = "坐标系类型WGS84,GCJ02、BD09")
public List<CameraChannel> queryListInPolygon(String position, Integer level, String groupAlias,
String topGroupAlias, String geoCoordSys) {
public List<CameraChannel> queryListInPolygon(@RequestBody PolygonQueryParam param) {
return null;
}
@GetMapping(value = "/camera/list/circle")
@ResponseBody
@Operation(summary = "根据圆范围查询摄像头", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Operation(summary = "根据圆范围查询摄像头", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "centerLongitude", description = "圆心经度")
@Parameter(name = "centerLatitude", description = "圆心纬度")
@Parameter(name = "radius", description = "查询范围的半径,单位米")
@@ -143,7 +204,7 @@ public class CameraChannelController {
@Operation(summary = "播放摄像头", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "deviceId", description = "通道编号")
@Parameter(name = "deviceCode", description = "摄像头设备国标编号, 对于非国标摄像头可以不设置此参数")
public StreamContent play(String deviceId, @RequestParam(required = false) String deviceCode) {
public CameraStreamContent play(String deviceId, @RequestParam(required = false) String deviceCode) {
return null;
}
@@ -152,8 +213,7 @@ public class CameraChannelController {
@Operation(summary = "停止播放摄像头", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "deviceId", description = "通道编号")
@Parameter(name = "deviceCode", description = "摄像头设备国标编号, 对于非国标摄像头可以不设置此参数")
public StreamContent stopPlay(String deviceId, @RequestParam(required = false) String deviceCode) {
return null;
public void stopPlay(String deviceId, @RequestParam(required = false) String deviceCode) {
}
@Operation(summary = "云台控制", security = @SecurityRequirement(name = JwtUtils.HEADER))
@@ -162,10 +222,9 @@ public class CameraChannelController {
@Parameter(name = "command", description = "控制指令,允许值: left, right, up, down, upleft, upright, downleft, downright, zoomin, zoomout, stop", required = true)
@Parameter(name = "speed", description = "速度(0-100)", required = true)
@GetMapping("/camera/control/ptz")
public DeferredResult<WVPResult<String>> ptz(Integer channelId, String command, Integer speed){
public void ptz(String deviceId, @RequestParam(required = false) String deviceCode, String command, Integer speed){
return null;
}

View File

@@ -0,0 +1,21 @@
package com.genersoft.iot.vmp.web.custom.bean;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
@
public class CameraStreamContent extends StreamContent {
public CameraStreamContent(StreamInfo streamInfo) {
super(streamInfo);
}
private String name;
// 0不可动1可动
private Integer controltype;
}

View File

@@ -0,0 +1,15 @@
package com.genersoft.iot.vmp.web.custom.bean;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "通道信息")
public class ChannelParam {
@Schema(description = "摄像头设备国标编号, 对于非国标摄像头可以不设置此参数")
private String deviceCode;
@Schema(description = "通道编号")
private String deviceId;
}

View File

@@ -0,0 +1,17 @@
package com.genersoft.iot.vmp.web.custom.bean;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@Schema(description = "根据多个ID获取摄像头列表")
public class IdsQueryParam {
@Schema(description = "通道编号列表")
private List<ChannelParam> deviceIds;
@Schema(description = "坐标系类型WGS84,GCJ02、BD09")
private String geoCoordSys;
}

View File

@@ -0,0 +1,13 @@
package com.genersoft.iot.vmp.web.custom.bean;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "坐标")
public class Point {
private double lng;
private double lat;
}

View File

@@ -0,0 +1,17 @@
package com.genersoft.iot.vmp.web.custom.bean;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@Schema(description = "多边形检索摄像头参数")
public class PolygonQueryParam {
private List<Point> position;
private Integer level;
private String groupAlias;
private String topGroupAlias;
private String geoCoordSys;
}

View File

@@ -0,0 +1,72 @@
package com.genersoft.iot.vmp.web.custom.service;
import com.genersoft.iot.vmp.gb28181.bean.Group;
import com.genersoft.iot.vmp.gb28181.dao.CommonGBChannelMapper;
import com.genersoft.iot.vmp.gb28181.dao.GroupMapper;
import com.genersoft.iot.vmp.web.custom.bean.CameraChannel;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.xiaoymin.knife4j.core.util.Assert;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
@Slf4j
@Service
public class CameraChannelService implements CommandLineRunner {
@Autowired
private CommonGBChannelMapper channelMapper;
@Autowired
private GroupMapper groupMapper;
@Autowired
private RedisTemplate<Object, Object> redisTemplate;
@Override
public void run(String... args) throws Exception {
// 启动时获取全局token
}
public PageInfo<CameraChannel> queryList(Integer page, Integer count, String query, String sortName, String order, String groupAlias, String topGroupAlias, Boolean status, Boolean containMobileDevice) {
// 构建组织结构信息
String groupDeviceId = null;
if (topGroupAlias != null && groupAlias != null) {
// 根据别名获取分组信息
Group businessGroup = groupMapper.queryGroupByAlias(topGroupAlias);
Assert.notNull(businessGroup, "域信息未找到");
Group group = groupMapper.queryGroupByAliasAndBusinessGroup(groupAlias, businessGroup.getDeviceId());
Assert.notNull(businessGroup, "获取组织结构失败");
groupDeviceId = group.getDeviceId();
}
// 构建分页
PageHelper.startPage(page, count);
if (query != null) {
query = query.replaceAll("/", "//")
.replaceAll("%", "/%")
.replaceAll("_", "/_");
}
List<CameraChannel> all = channelMapper.queryListForSy(query, sortName, order, groupDeviceId, status, containMobileDevice);
PageInfo<CameraChannel> groupPageInfo = new PageInfo<>(all);
List<CameraChannel> list = addIconPathForCameraChannelList(groupPageInfo.getList());
groupPageInfo.setList(list);
return groupPageInfo;
}
/**
* 为通道增加图片信息
*/
private List<CameraChannel> addIconPathForCameraChannelList(List<CameraChannel> channels) {
return channels;
}
}

View File

@@ -0,0 +1,87 @@
package com.genersoft.iot.vmp.web.custom.service;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.genersoft.iot.vmp.service.IMapService;
import com.genersoft.iot.vmp.vmanager.bean.MapConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* 第三方平台适配
*/
@Slf4j
@Service
public class SyServiceImpl implements IMapService, CommandLineRunner {
@Autowired
private RedisTemplate<Object, Object> redisTemplate;
// 启动后请求组织结构同步
@Override
public void run(String... args) throws Exception {
String key = VideoManagerConstants.VM_MSG_GROUP_LIST_REQUEST;
log.info("[redis发送通知] 发送 同步组织结构请求 {}", key);
redisTemplate.convertAndSend(key, "");
}
@Override
public List<MapConfig> getConfig() {
List<MapConfig> configList = new ArrayList<>();
JSONObject configObject = (JSONObject)redisTemplate.opsForValue().get("interfaceConfig1");
if (configObject == null) {
return configList;
}
// 浅色地图
MapConfig mapConfigForDefault = readConfig("FRAGMENTIMG_SERVER", configObject);
if (mapConfigForDefault != null) {
mapConfigForDefault.setName("浅色地图");
configList.add(mapConfigForDefault);
}
// 深色地图
MapConfig mapConfigForDark = readConfig("POLARNIGHTBLUE_FRAGMENTIMG_SERVER", configObject);
if (mapConfigForDark != null) {
mapConfigForDark.setName("深色地图");
configList.add(mapConfigForDark);
}
// 卫星地图
MapConfig mapConfigForSatellited = readConfig("SATELLITE_FRAGMENTIMG_SERVER", configObject);
if (mapConfigForSatellited != null) {
mapConfigForSatellited.setName("卫星地图");
configList.add(mapConfigForSatellited);
}
return configList;
}
private MapConfig readConfig(String key, JSONObject jsonObject) {
JSONArray fragmentimgServerArray = jsonObject.getJSONArray(key);
if (fragmentimgServerArray == null || fragmentimgServerArray.isEmpty()) {
return null;
}
JSONObject fragmentimgServer = fragmentimgServerArray.getJSONObject(0);
// 坐标系
String geoCoordSys = fragmentimgServer.getString("csysType").toUpperCase();
// 获取地址
String path = fragmentimgServer.getString("path");
String ip = fragmentimgServer.getString("ip");
JSONObject portJson = fragmentimgServer.getJSONObject("port");
JSONObject httpPortJson = portJson.getJSONObject("httpPort");
String protocol = httpPortJson.getString("portType");
Integer port = httpPortJson.getInteger("port");
String tileUrl = String.format("%s://%s:%s%s", protocol, ip, port, path);
MapConfig mapConfig = new MapConfig();
mapConfig.setCoordinateSystem(geoCoordSys);
mapConfig.setTilesUrl(tileUrl);
return mapConfig;
}
}

View File

@@ -598,3 +598,14 @@ export function getAllForMap({ query, online, hasRecordPlan, channelType }) {
}
})
}
export function test() {
return request({
method: 'get',
url: '/api/sy/camera/list/ids',
params: {
deviceIds: ['a', 'b', 'c'].join(','),
geoCoordSys: 'GCJ02',
traditional: true
}
})
}

View File

@@ -48,7 +48,7 @@ import {
stopPlayback,
pausePlayback,
resumePlayback,
seekPlayback, speedPlayback, getAllForMap
seekPlayback, speedPlayback, getAllForMap, test
} from '@/api/commonChannel'
const actions = {
@@ -571,6 +571,16 @@ const actions = {
reject(error)
})
})
},
test({ commit }) {
return new Promise((resolve, reject) => {
test().then(response => {
const { data } = response
resolve(data)
}).catch(error => {
reject(error)
})
})
}
}

View File

@@ -35,9 +35,9 @@
<div class="map-tool-btn" title="图层抽稀">
<i class="iconfont icon-mti-sandian"></i> <span>图层抽稀</span>
</div>
<!-- <div class="map-tool-btn" title="位置编辑">-->
<!-- <i class="el-icon-edit"></i> <span>位置编辑</span>-->
<!-- </div>-->
<div class="map-tool-btn" title="位置编辑" @click="testArray">
<i class="el-icon-edit"></i> <span>位置编辑</span>
</div>
</div>
</div>
<div class="map-tool-box-top-right">
@@ -385,6 +385,9 @@ export default {
if (this.infoBoxId !== null) {
this.$refs.mapComponent.closeInfoBox(this.infoBoxId)
}
},
testArray: function (){
this.$store.dispatch('commonChanel/test')
}
}