Commit ac8daf92c4705bfb32f3c0258b4791c4b86947e6

Authored by guzijian
1 parent af16fee7

feat: 增加闵行设备

README.md
1 ![logo](doc/_media/logo.png) 1 ![logo](doc/_media/logo.png)
2 -# 开箱即用的28181协议视频平台  
3 -  
4 -[![Build Status](https://travis-ci.org/xia-chu/ZLMediaKit.svg?branch=master)](https://travis-ci.org/xia-chu/ZLMediaKit)  
5 -[![license](http://img.shields.io/badge/license-MIT-green.svg)](https://github.com/xia-chu/ZLMediaKit/blob/master/LICENSE)  
6 -[![JAVA](https://img.shields.io/badge/language-java-red.svg)](https://en.cppreference.com/)  
7 -[![platform](https://img.shields.io/badge/platform-linux%20|%20macos%20|%20windows-blue.svg)](https://github.com/xia-chu/ZLMediaKit)  
8 -[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-yellow.svg)](https://github.com/xia-chu/ZLMediaKit/pulls)  
9 -  
10 2
11 WEB VIDEO PLATFORM是一个基于GB28181-2016标准实现的开箱即用的网络视频平台,负责实现核心信令与设备管理后台部分,支持NAT穿透,支持海康、大华、宇视等品牌的IPC、NVR接入。支持国标级联,支持将不带国标功能的摄像机/直播流/直播推流转发到其他国标平台。 3 WEB VIDEO PLATFORM是一个基于GB28181-2016标准实现的开箱即用的网络视频平台,负责实现核心信令与设备管理后台部分,支持NAT穿透,支持海康、大华、宇视等品牌的IPC、NVR接入。支持国标级联,支持将不带国标功能的摄像机/直播流/直播推流转发到其他国标平台。
12 4
@@ -27,22 +19,9 @@ wvp使用文档 [https://doc.wvp-pro.cn](https://doc.wvp-pro.cn) @@ -27,22 +19,9 @@ wvp使用文档 [https://doc.wvp-pro.cn](https://doc.wvp-pro.cn)
27 ZLM使用文档 [https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit) 19 ZLM使用文档 [https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit)
28 > wvp文档由gitee提供服务,如果遇到打不开请多刷新几次。 20 > wvp文档由gitee提供服务,如果遇到打不开请多刷新几次。
29 21
30 -# 付费社群  
31 -[![社群](doc/_media/shequ.png "shequ")](https://t.zsxq.com/0d8VAD3Dm)  
32 -> 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接退款,大家不需要有顾虑,来白嫖三天也不是不可以。  
33 -  
34 # gitee同步仓库 22 # gitee同步仓库
35 https://gitee.com/pan648540858/wvp-GB28181-pro.git 23 https://gitee.com/pan648540858/wvp-GB28181-pro.git
36 24
37 -# 截图  
38 -![index](doc/_media/index.png "index.png")  
39 -![2](doc/_media/2.png "2.png")  
40 -![3](doc/_media/3.png "3.png")  
41 -![3-1](doc/_media/3-1.png "3-1.png")  
42 -![3-2](doc/_media/3-2.png "3-2.png")  
43 -![3-3](doc/_media/3-3.png "3-3.png")  
44 -![build_1](https://images.gitee.com/uploads/images/2022/0304/101919_ee5b8c79_1018729.png "2022-03-04_10-13.png")  
45 -  
46 # 功能特性 25 # 功能特性
47 - [X] 集成web界面 26 - [X] 集成web界面
48 - [X] 兼容性良好 27 - [X] 兼容性良好
@@ -110,20 +89,10 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git @@ -110,20 +89,10 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git
110 - [X] 支持Mysql,Postgresql,金仓等数据库 89 - [X] 支持Mysql,Postgresql,金仓等数据库
111 - [X] 支持Onvif(目前在onvif分支,需要安装onvif服务,服务请在知识星球获取) 90 - [X] 支持Onvif(目前在onvif分支,需要安装onvif服务,服务请在知识星球获取)
112 91
113 -# 非开源的内容  
114 -- [X] ONVIF设备的接入,支持点播,云台控制,国标级联点播,自动点播。在[知识星球](https://t.zsxq.com/10WAnH2MP)放了试用安装包以及使用教程,没有使用时间限制,需要源码可以星球私信我或者邮箱联系。  
115 -- [X] 支持国标28181-2022协议,支持巡航轨迹查询,PTZ精准控制,存储卡格式化,设备软件升级,OSD配置,h265+aac,支持辅码流,录像倒放等。具体的功能列表可在[知识星球](https://t.zsxq.com/18GXkpkqs)查看,需要源码和测试可以在星球私信联系或者发邮件给我  
116 -  
117 92
118 # 授权协议 93 # 授权协议
119 本项目自有代码使用宽松的MIT协议,在保留版权信息的情况下可以自由应用于各自商用、非商业的项目。 但是本项目也零碎的使用了一些其他的开源代码,在商用的情况下请自行替代或剔除; 由于使用本项目而产生的商业纠纷或侵权行为一概与本项目及开发者无关,请自行承担法律风险。 在使用本项目代码时,也应该在授权协议中同时表明本项目依赖的第三方库的协议 94 本项目自有代码使用宽松的MIT协议,在保留版权信息的情况下可以自由应用于各自商用、非商业的项目。 但是本项目也零碎的使用了一些其他的开源代码,在商用的情况下请自行替代或剔除; 由于使用本项目而产生的商业纠纷或侵权行为一概与本项目及开发者无关,请自行承担法律风险。 在使用本项目代码时,也应该在授权协议中同时表明本项目依赖的第三方库的协议
120 95
121 -# 技术支持  
122 -  
123 -[知识星球](https://t.zsxq.com/0d8VAD3Dm)专栏列表:,  
124 -- [使用入门系列一:WVP-PRO能做什么](https://t.zsxq.com/0dLguVoSp)  
125 -  
126 -有偿技术支持,请发送邮件到648540858@qq.com  
127 96
128 # 致谢 97 # 致谢
129 感谢作者[夏楚](https://github.com/xia-chu) 提供这么棒的开源流媒体服务框架,并在开发过程中给予支持与帮助。 98 感谢作者[夏楚](https://github.com/xia-chu) 提供这么棒的开源流媒体服务框架,并在开发过程中给予支持与帮助。
@@ -136,12 +105,3 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git @@ -136,12 +105,3 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git
136 [ydpd](https://github.com/ydpd) [szy833](https://github.com/szy833) [ydwxb](https://github.com/ydwxb) [Albertzhu666](https://github.com/Albertzhu666) 105 [ydpd](https://github.com/ydpd) [szy833](https://github.com/szy833) [ydwxb](https://github.com/ydwxb) [Albertzhu666](https://github.com/Albertzhu666)
137 [mk1990](https://github.com/mk1990) [SaltFish001](https://github.com/SaltFish001) 106 [mk1990](https://github.com/mk1990) [SaltFish001](https://github.com/SaltFish001)
138 107
139 -  
140 -ffmpeg -re -i 123.mp3 -acodec pcm_alaw -ar 8000 -ac 1 -f rtsp rtsp://192.168.1.3:30554/broadcast/34020000001320000101_34020000001310000001  
141 -  
142 -ffmpeg -re -i 123.mp3 -acodec pcm_alaw -ar 8000 -ac 1 -f rtsp rtsp://192.168.1.3:30554/talk/34020000001320000011_34020000001370000001  
143 -  
144 -  
145 -  
146 -ffmpeg -re -i 123.mp3 -acodec pcm_alaw -ar 8000 -ac 1 -f rtsp rtsp://192.168.1.3:30554/talk/34020000001320000101_34020000001310000001  
147 -  
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisTool.java 0 → 100644
  1 +package com.genersoft.iot.vmp.utils.redis;
  2 +import java.util.Collection;
  3 +import java.util.Iterator;
  4 +import java.util.List;
  5 +import java.util.Map;
  6 +import java.util.Set;
  7 +import java.util.concurrent.TimeUnit;
  8 +
  9 +import org.springframework.beans.factory.annotation.Autowired;
  10 +import org.springframework.data.redis.core.BoundSetOperations;
  11 +import org.springframework.data.redis.core.HashOperations;
  12 +import org.springframework.data.redis.core.RedisTemplate;
  13 +import org.springframework.data.redis.core.ValueOperations;
  14 +import org.springframework.stereotype.Component;
  15 +
  16 +/**
  17 + * spring redis 工具类
  18 + *
  19 + * @author ruoyi
  20 + **/
  21 +@SuppressWarnings(value = {"unchecked", "rawtypes"})
  22 +@Component
  23 +public class RedisTool {
  24 + @Autowired
  25 + public RedisTemplate redisTemplate;
  26 +
  27 + /**
  28 + * 缓存基本的对象,Integer、String、实体类等
  29 + *
  30 + * @param key 缓存的键值
  31 + * @param value 缓存的值
  32 + */
  33 + public <T> void setCacheObject(final String key, final T value) {
  34 + redisTemplate.opsForValue().set(key, value);
  35 + }
  36 +
  37 + /**
  38 + * 缓存基本的对象,Integer、String、实体类等
  39 + *
  40 + * @param key 缓存的键值
  41 + * @param value 缓存的值
  42 + * @param timeout 时间
  43 + * @param timeUnit 时间颗粒度
  44 + */
  45 + public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
  46 + redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
  47 + }
  48 +
  49 + public <T> void setCacheObject(final String key, final T value, final Long timeout, final TimeUnit timeUnit) {
  50 + redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
  51 + }
  52 +
  53 + /**
  54 + * 设置有效时间
  55 + *
  56 + * @param key Redis键
  57 + * @param timeout 超时时间
  58 + * @return true=设置成功;false=设置失败
  59 + */
  60 + public boolean expire(final String key, final long timeout) {
  61 + return expire(key, timeout, TimeUnit.SECONDS);
  62 + }
  63 +
  64 + /**
  65 + * 设置有效时间
  66 + *
  67 + * @param key Redis键
  68 + * @param timeout 超时时间
  69 + * @param unit 时间单位
  70 + * @return true=设置成功;false=设置失败
  71 + */
  72 + public boolean expire(final String key, final long timeout, final TimeUnit unit) {
  73 + return redisTemplate.expire(key, timeout, unit);
  74 + }
  75 +
  76 + /**
  77 + * 设置有效时间
  78 + *
  79 + * @param key Redis键
  80 + * @param timeout 超时时间
  81 + * @param unit 时间单位
  82 + * @return true=设置成功;false=设置失败
  83 + */
  84 + public void expire(final String key,Object val ,final long timeout, final TimeUnit unit) {
  85 + redisTemplate.opsForValue().set(key, val,timeout, unit);
  86 + }
  87 +
  88 +
  89 + /**
  90 + * 获取有效时间
  91 + *
  92 + * @param key Redis键
  93 + * @return 有效时间
  94 + */
  95 + public long getExpire(final String key) {
  96 + return redisTemplate.getExpire(key);
  97 + }
  98 +
  99 + /**
  100 + * 判断 key是否存在
  101 + *
  102 + * @param key 键
  103 + * @return true 存在 false不存在
  104 + */
  105 + public Boolean hasKey(String key) {
  106 + return redisTemplate.hasKey(key);
  107 + }
  108 +
  109 + /**
  110 + * 获得缓存的基本对象。
  111 + *
  112 + * @param key 缓存键值
  113 + * @return 缓存键值对应的数据
  114 + */
  115 + public <T> T getCacheObject(final String key) {
  116 + ValueOperations<String, T> operation = redisTemplate.opsForValue();
  117 + return operation.get(key);
  118 + }
  119 +
  120 + /**
  121 + * 删除单个对象
  122 + *
  123 + * @param key
  124 + */
  125 + public boolean deleteObject(final String key) {
  126 + return redisTemplate.delete(key);
  127 + }
  128 +
  129 + /**
  130 + * 删除集合对象
  131 + *
  132 + * @param collection 多个对象
  133 + * @return
  134 + */
  135 + public boolean deleteObject(final Collection collection) {
  136 + return redisTemplate.delete(collection) > 0;
  137 + }
  138 +
  139 + /**
  140 + * 缓存List数据
  141 + *
  142 + * @param key 缓存的键值
  143 + * @param dataList 待缓存的List数据
  144 + * @return 缓存的对象
  145 + */
  146 + public <T> long setCacheList(final String key, final List<T> dataList) {
  147 + Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
  148 + return count == null ? 0 : count;
  149 + }
  150 +
  151 + /**
  152 + * 获得缓存的list对象
  153 + *
  154 + * @param key 缓存的键值
  155 + * @return 缓存键值对应的数据
  156 + */
  157 + public <T> List<T> getCacheList(final String key) {
  158 + return redisTemplate.opsForList().range(key, 0, -1);
  159 + }
  160 +
  161 + /**
  162 + * 缓存Set
  163 + *
  164 + * @param key 缓存键值
  165 + * @param dataSet 缓存的数据
  166 + * @return 缓存数据的对象
  167 + */
  168 + public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet) {
  169 + BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
  170 + Iterator<T> it = dataSet.iterator();
  171 + while (it.hasNext()) {
  172 + setOperation.add(it.next());
  173 + }
  174 + return setOperation;
  175 + }
  176 +
  177 + /**
  178 + * 获得缓存的set
  179 + *
  180 + * @param key
  181 + * @return
  182 + */
  183 + public <T> Set<T> getCacheSet(final String key) {
  184 + return redisTemplate.opsForSet().members(key);
  185 + }
  186 +
  187 + /**
  188 + * 缓存Map
  189 + *
  190 + * @param key
  191 + * @param dataMap
  192 + */
  193 + public <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
  194 + if (dataMap != null) {
  195 + redisTemplate.opsForHash().putAll(key, dataMap);
  196 + }
  197 + }
  198 +
  199 + /**
  200 + * 缓存map并设置key
  201 + *
  202 + * @param key
  203 + * @param dataMap
  204 + * @param timeOut
  205 + * @param timeUnit
  206 + * @param <T>
  207 + */
  208 + public <T> void setCacheMap(final String key, final Map<String, T> dataMap, long timeOut, TimeUnit timeUnit) {
  209 + if (dataMap != null) {
  210 + redisTemplate.opsForHash().putAll(key, dataMap);
  211 + redisTemplate.expire(key, timeOut, timeUnit);
  212 + }
  213 + }
  214 +
  215 + /**
  216 + * 获得缓存的Map
  217 + *
  218 + * @param key
  219 + * @return
  220 + */
  221 + public <T> Map<String, T> getCacheMap(final String key) {
  222 + return redisTemplate.opsForHash().entries(key);
  223 + }
  224 +
  225 + /**
  226 + * 往Hash中存入数据
  227 + *
  228 + * @param key Redis键
  229 + * @param hKey Hash键
  230 + * @param value 值
  231 + */
  232 + public <T> void setCacheMapValue(final String key, final String hKey, final T value) {
  233 + redisTemplate.opsForHash().put(key, hKey, value);
  234 + }
  235 +
  236 + /**
  237 + * 往Hash中存入数据 并设置过期时间
  238 + *
  239 + * @param key Redis键
  240 + * @param hKey Hash键
  241 + * @param value 值
  242 + */
  243 + public <T> void setCacheMapValue(final String key, final String hKey, final T value, long timeOut, TimeUnit timeUnit) {
  244 + redisTemplate.opsForHash().put(key, hKey, value);
  245 + redisTemplate.expire(key, timeOut, timeUnit);
  246 + }
  247 +
  248 + /**
  249 + * 获取Hash中的数据
  250 + *
  251 + * @param key Redis键
  252 + * @param hKey Hash键
  253 + * @return Hash中的对象
  254 + */
  255 + public <T> T getCacheMapValue(final String key, final String hKey) {
  256 + HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
  257 + return opsForHash.get(key, hKey);
  258 + }
  259 +
  260 + /**
  261 + * 获取多个Hash中的数据
  262 + *
  263 + * @param key Redis键
  264 + * @param hKeys Hash键集合
  265 + * @return Hash对象集合
  266 + */
  267 + public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys) {
  268 + return redisTemplate.opsForHash().multiGet(key, hKeys);
  269 + }
  270 +
  271 + /**
  272 + * 删除Hash中的某条数据
  273 + *
  274 + * @param key Redis键
  275 + * @param hKey Hash键
  276 + * @return 是否成功
  277 + */
  278 + public boolean deleteCacheMapValue(final String key, final String hKey) {
  279 + return redisTemplate.opsForHash().delete(key, hKey) > 0;
  280 + }
  281 +
  282 + public Integer setIncrementMapValue(String key, String hkey, Integer value) {
  283 + return redisTemplate.opsForHash().increment(key, hkey, value.longValue()).intValue();
  284 + }
  285 +
  286 + /**
  287 + * 获得缓存的基本对象列表
  288 + *
  289 + * @param pattern 字符串前缀
  290 + * @return 对象列表
  291 + */
  292 + public Collection<String> keys(final String pattern) {
  293 + return redisTemplate.keys(pattern);
  294 + }
  295 +
  296 + public <T> Set<T> getHashKeys(String key) {
  297 + return redisTemplate.opsForHash().keys(key);
  298 + }
  299 +
  300 + public boolean setNx(String key, Object val) {
  301 + Boolean result = redisTemplate.opsForValue().setIfAbsent(key, val);
  302 + return result != null && result;
  303 + }
  304 +
  305 + public Long increment(String key) {
  306 + Long increment = redisTemplate.opsForValue().increment(key);
  307 + return increment;
  308 + }
  309 +}
src/main/java/com/genersoft/iot/vmp/vehicle/controller/VehicleController.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vehicle.controller;
  2 +
  3 +import com.genersoft.iot.vmp.vehicle.pojo.vo.VehicleVo;
  4 +import com.genersoft.iot.vmp.vehicle.service.VehicleDeviceService;
  5 +import org.springframework.beans.factory.annotation.Autowired;
  6 +import org.springframework.web.bind.annotation.GetMapping;
  7 +import org.springframework.web.bind.annotation.RequestMapping;
  8 +import org.springframework.web.bind.annotation.RequestParam;
  9 +import org.springframework.web.bind.annotation.RestController;
  10 +
  11 +
  12 +@RestController
  13 +@RequestMapping("/api/vehicle")
  14 +public class VehicleController {
  15 +
  16 + @Autowired
  17 + private VehicleDeviceService vehicleDeviceService;
  18 +
  19 +
  20 + @GetMapping("/query")
  21 + public VehicleVo queryVehicleList(@RequestParam("pageNo") Integer pageNo, @RequestParam("pageSize") Integer pageSize) {
  22 + return vehicleDeviceService.queryVehicleList(pageNo,pageSize);
  23 + }
  24 +
  25 +
  26 + @GetMapping("/onPlay")
  27 + public String onPlay(@RequestParam("deviceId") String deviceId,@RequestParam("channel")String channel) {
  28 + return vehicleDeviceService.onPlay(deviceId,channel);
  29 + }
  30 +
  31 +}
src/main/java/com/genersoft/iot/vmp/vehicle/pojo/response/VehicleNvrDeviceRes.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vehicle.pojo.response;
  2 +
  3 +import org.apache.commons.lang3.builder.EqualsBuilder;
  4 +import org.apache.commons.lang3.builder.HashCodeBuilder;
  5 +
  6 +import java.util.List;
  7 +
  8 +/**
  9 + * 车载nvr基本信息
  10 + */
  11 +public class VehicleNvrDeviceRes {
  12 + private Integer errCode;
  13 + private List<ResData> data;
  14 + private List<ResSelect> select2;
  15 +
  16 +
  17 + public static class ResData {
  18 + private String zxzt;
  19 + private String vehicle;
  20 + private String insideCode;
  21 + private String deviceId;
  22 + private String lineId;
  23 +
  24 + private Boolean oldDevice;
  25 +
  26 + private String status;
  27 +
  28 + public Boolean getOldDevice() {
  29 + return oldDevice;
  30 + }
  31 +
  32 + public void setOldDevice(Boolean oldDevice) {
  33 + this.oldDevice = oldDevice;
  34 + }
  35 +
  36 + public String getStatus() {
  37 + return status;
  38 + }
  39 +
  40 + public void setStatus(String status) {
  41 + this.status = status;
  42 + }
  43 +
  44 + @Override
  45 + public String toString() {
  46 + return "ResData{" +
  47 + "zxzt='" + zxzt + '\'' +
  48 + ", vehicle='" + vehicle + '\'' +
  49 + ", insideCode='" + insideCode + '\'' +
  50 + ", deviceId='" + deviceId + '\'' +
  51 + ", lineId='" + lineId + '\'' +
  52 + ", oldDevice=" + oldDevice +
  53 + ", status='" + status + '\'' +
  54 + '}';
  55 + }
  56 +
  57 + public String getZxzt() {
  58 + return zxzt;
  59 + }
  60 +
  61 + public void setZxzt(String zxzt) {
  62 + this.zxzt = zxzt;
  63 + }
  64 +
  65 + public String getVehicle() {
  66 + return vehicle;
  67 + }
  68 +
  69 + public void setVehicle(String vehicle) {
  70 + this.vehicle = vehicle;
  71 + }
  72 +
  73 + public String getInsideCode() {
  74 + return insideCode;
  75 + }
  76 +
  77 + public void setInsideCode(String insideCode) {
  78 + this.insideCode = insideCode;
  79 + }
  80 +
  81 + public String getDeviceId() {
  82 + return deviceId;
  83 + }
  84 +
  85 + public void setDeviceId(String deviceId) {
  86 + this.deviceId = deviceId;
  87 + }
  88 +
  89 + public String getLineId() {
  90 + return lineId;
  91 + }
  92 +
  93 + public void setLineId(String lineId) {
  94 + this.lineId = lineId;
  95 + }
  96 + }
  97 +
  98 + public static class ResSelect {
  99 + private String text;
  100 + private String id;
  101 +
  102 + @Override
  103 + public String toString() {
  104 + return "ResSelect{" +
  105 + "text='" + text + '\'' +
  106 + ", id='" + id + '\'' +
  107 + '}';
  108 + }
  109 +
  110 + public String getText() {
  111 + return text;
  112 + }
  113 +
  114 + public void setText(String text) {
  115 + this.text = text;
  116 + }
  117 +
  118 + public String getId() {
  119 + return id;
  120 + }
  121 +
  122 + public void setId(String id) {
  123 + this.id = id;
  124 + }
  125 + }
  126 +
  127 + public Integer getErrCode() {
  128 + return errCode;
  129 + }
  130 +
  131 + public void setErrCode(Integer errCode) {
  132 + this.errCode = errCode;
  133 + }
  134 +
  135 + public List<ResData> getData() {
  136 + return data;
  137 + }
  138 +
  139 + public void setData(List<ResData> data) {
  140 + this.data = data;
  141 + }
  142 +
  143 + public List<ResSelect> getSelect2() {
  144 + return select2;
  145 + }
  146 +
  147 + public void setSelect2(List<ResSelect> select2) {
  148 + this.select2 = select2;
  149 + }
  150 +
  151 + @Override
  152 + public String toString() {
  153 + return "VehicleNvrDeviceRes{" +
  154 + "errCode=" + errCode +
  155 + ", data=" + data +
  156 + ", select2=" + select2 +
  157 + '}';
  158 + }
  159 +
  160 + @Override
  161 + public boolean equals(Object o) {
  162 + if (this == o) return true;
  163 +
  164 + if (o == null || getClass() != o.getClass()) return false;
  165 +
  166 + VehicleNvrDeviceRes that = (VehicleNvrDeviceRes) o;
  167 +
  168 + return new EqualsBuilder().append(getErrCode(), that.getErrCode()).append(getData(), that.getData()).append(getSelect2(), that.getSelect2()).isEquals();
  169 + }
  170 +
  171 + @Override
  172 + public int hashCode() {
  173 + return new HashCodeBuilder(17, 37).append(getErrCode()).append(getData()).append(getSelect2()).toHashCode();
  174 + }
  175 +}
src/main/java/com/genersoft/iot/vmp/vehicle/pojo/vo/VehicleVo.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vehicle.pojo.vo;
  2 +
  3 +import com.genersoft.iot.vmp.vehicle.pojo.response.VehicleNvrDeviceRes;
  4 +
  5 +import java.util.List;
  6 +
  7 +public class VehicleVo {
  8 + private Integer total;
  9 + private List<VehicleNvrDeviceRes.ResData> list;
  10 +
  11 + @Override
  12 + public String toString() {
  13 + return "VehicleVo{" +
  14 + "total=" + total +
  15 + ", list=" + list +
  16 + '}';
  17 + }
  18 +
  19 + public Integer getTotal() {
  20 + return total;
  21 + }
  22 +
  23 + public void setTotal(Integer total) {
  24 + this.total = total;
  25 + }
  26 +
  27 + public List<VehicleNvrDeviceRes.ResData> getList() {
  28 + return list;
  29 + }
  30 +
  31 + public void setList(List<VehicleNvrDeviceRes.ResData> list) {
  32 + this.list = list;
  33 + }
  34 +}
src/main/java/com/genersoft/iot/vmp/vehicle/service/VehicleDeviceService.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vehicle.service;
  2 +
  3 +import com.genersoft.iot.vmp.vehicle.pojo.vo.VehicleVo;
  4 +
  5 +import java.util.List;
  6 +
  7 +public interface VehicleDeviceService {
  8 + VehicleVo queryVehicleList(Integer pageNo, Integer pageSize);
  9 +
  10 + String onPlay(String deviceId, String channel);
  11 +}
0 \ No newline at end of file 12 \ No newline at end of file
src/main/java/com/genersoft/iot/vmp/vehicle/service/impl/VehicleDeviceServiceImpl.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vehicle.service.impl;
  2 +
  3 +import com.alibaba.fastjson2.JSONObject;
  4 +import com.genersoft.iot.vmp.utils.redis.RedisTool;
  5 +import com.genersoft.iot.vmp.vehicle.pojo.response.VehicleNvrDeviceRes;
  6 +import com.genersoft.iot.vmp.vehicle.pojo.vo.VehicleVo;
  7 +import com.genersoft.iot.vmp.vehicle.service.VehicleDeviceService;
  8 +import org.springframework.beans.factory.annotation.Autowired;
  9 +import org.springframework.core.ParameterizedTypeReference;
  10 +import org.springframework.http.HttpMethod;
  11 +import org.springframework.http.ResponseEntity;
  12 +import org.springframework.stereotype.Service;
  13 +import org.springframework.web.client.RestTemplate;
  14 +
  15 +import java.util.ArrayList;
  16 +import java.util.Date;
  17 +import java.util.List;
  18 +import java.util.Set;
  19 +import java.util.stream.Collectors;
  20 +
  21 +@Service
  22 +public class VehicleDeviceServiceImpl implements VehicleDeviceService {
  23 +
  24 + @Autowired
  25 + private RedisTool redisTool;
  26 +
  27 + @Override
  28 + public VehicleVo queryVehicleList(Integer pageNo, Integer pageSize) {
  29 + String key = "vehicle";
  30 + VehicleNvrDeviceRes nvrDeviceRes = redisTool.getCacheObject(key);
  31 + if (nvrDeviceRes == null) {
  32 + nvrDeviceRes = getVehicleNvrDeviceRes();
  33 + redisTool.setCacheObject(key, nvrDeviceRes);
  34 + }
  35 + List<VehicleNvrDeviceRes.ResData> list = nvrDeviceRes.getData();
  36 + int total = list.size();
  37 + int remainder = total % pageSize;
  38 + int currentPage = pageNo > 0 ? (pageNo - 1) * pageSize : pageNo * pageSize;
  39 + // 怕页码超出界限了 超出界限就通过currenPage (3 * 10) > total (25) ? currentPage (20) - (pageSize (10) - remainder (3)) : currentPage
  40 + int startPage = currentPage > total ? currentPage - (pageSize - remainder) : currentPage;
  41 + int endPage = Math.min(startPage + pageSize, total);
  42 + List<VehicleNvrDeviceRes.ResData> resData = list.subList(startPage, endPage);
  43 + for (VehicleNvrDeviceRes.ResData data : resData) {
  44 + // 模糊匹配
  45 + if (data.getInsideCode().contains("离线")) {
  46 + data.setStatus("离线");
  47 + } else {
  48 + data.setStatus("在线");
  49 + }
  50 + if (data.getInsideCode().contains("老")) {
  51 + data.setOldDevice(true);
  52 + }else {
  53 + data.setOldDevice(false);
  54 + }
  55 + }
  56 + VehicleVo vo = new VehicleVo();
  57 + vo.setList(resData);
  58 + vo.setTotal(total);
  59 + return vo;
  60 + }
  61 +
  62 + @Override
  63 + public String onPlay(String deviceId, String channel) {
  64 + String playUrl = getPlayUrl(deviceId, channel);
  65 + return playUrl;
  66 + }
  67 +
  68 + private String getPlayUrl(String deviceId, String channel) {
  69 + String url = "http://27.115.69.123:9020/transport_server/lssnvr/play/" + deviceId + "/" + channel + "/" + 4 + "?_=" + System.currentTimeMillis();
  70 + RestTemplate template = new RestTemplate();
  71 + String str = template.getForObject(url, String.class);
  72 + JSONObject jsonObject = JSONObject.parseObject(str);
  73 + JSONObject data = jsonObject.getJSONObject("data");
  74 + String rtmp = data.getString("rtmp");
  75 + return rtmp.replace("rtmp://27.115.69.123:1935","http://27.115.69.123:1986") + ".flv";
  76 + }
  77 +
  78 +
  79 + private VehicleNvrDeviceRes getVehicleNvrDeviceRes() {
  80 + String url = "http://27.115.69.123:9020/transport_server/basic/device.do?q=-&zbh=A-09149D+userid=4";
  81 + RestTemplate template = new RestTemplate();
  82 + ParameterizedTypeReference<VehicleNvrDeviceRes> reference = new ParameterizedTypeReference<VehicleNvrDeviceRes>() {
  83 + };
  84 + ResponseEntity<VehicleNvrDeviceRes> response = template.exchange(url, HttpMethod.GET, null, reference);
  85 + VehicleNvrDeviceRes deviceRes = response.getBody();
  86 + return deviceRes;
  87 + }
  88 +
  89 +
  90 +}
web_src/config/index.js
@@ -11,14 +11,14 @@ module.exports = { @@ -11,14 +11,14 @@ module.exports = {
11 assetsPublicPath: "/", 11 assetsPublicPath: "/",
12 proxyTable: { 12 proxyTable: {
13 "/debug": { 13 "/debug": {
14 - target: "https://61.169.120.202:18080", 14 + target: "http://61.169.120.202:18089",
15 changeOrigin: true, 15 changeOrigin: true,
16 pathRewrite: { 16 pathRewrite: {
17 "^/debug": "/", 17 "^/debug": "/",
18 }, 18 },
19 }, 19 },
20 "/static/snap": { 20 "/static/snap": {
21 - target: "https://61.169.120.202:18080", 21 + target: "http://61.169.120.202:18089",
22 changeOrigin: true, 22 changeOrigin: true,
23 // pathRewrite: { 23 // pathRewrite: {
24 // '^/static/snap': '/static/snap' 24 // '^/static/snap': '/static/snap'
web_src/package-lock.json
@@ -14,6 +14,7 @@ @@ -14,6 +14,7 @@
14 "echarts": "^4.9.0", 14 "echarts": "^4.9.0",
15 "element-ui": "^2.15.6", 15 "element-ui": "^2.15.6",
16 "fingerprintjs2": "^2.1.2", 16 "fingerprintjs2": "^2.1.2",
  17 + "flv.js": "^1.6.2",
17 "moment": "^2.29.1", 18 "moment": "^2.29.1",
18 "ol": "^6.14.1", 19 "ol": "^6.14.1",
19 "postcss-pxtorem": "^5.1.1", 20 "postcss-pxtorem": "^5.1.1",
@@ -4400,6 +4401,11 @@ @@ -4400,6 +4401,11 @@
4400 "event-emitter": "~0.3.5" 4401 "event-emitter": "~0.3.5"
4401 } 4402 }
4402 }, 4403 },
  4404 + "node_modules/es6-promise": {
  4405 + "version": "4.2.8",
  4406 + "resolved": "https://registry.npmmirror.com/es6-promise/-/es6-promise-4.2.8.tgz",
  4407 + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
  4408 + },
4403 "node_modules/es6-set": { 4409 "node_modules/es6-set": {
4404 "version": "0.1.6", 4410 "version": "0.1.6",
4405 "resolved": "https://registry.npmmirror.com/es6-set/-/es6-set-0.1.6.tgz", 4411 "resolved": "https://registry.npmmirror.com/es6-set/-/es6-set-0.1.6.tgz",
@@ -5027,6 +5033,15 @@ @@ -5027,6 +5033,15 @@
5027 "readable-stream": "^2.3.6" 5033 "readable-stream": "^2.3.6"
5028 } 5034 }
5029 }, 5035 },
  5036 + "node_modules/flv.js": {
  5037 + "version": "1.6.2",
  5038 + "resolved": "https://registry.npmmirror.com/flv.js/-/flv.js-1.6.2.tgz",
  5039 + "integrity": "sha512-xre4gUbX1MPtgQRKj2pxJENp/RnaHaxYvy3YToVVCrSmAWUu85b9mug6pTXF6zakUjNP2lFWZ1rkSX7gxhB/2A==",
  5040 + "dependencies": {
  5041 + "es6-promise": "^4.2.8",
  5042 + "webworkify-webpack": "^2.1.5"
  5043 + }
  5044 + },
5030 "node_modules/follow-redirects": { 5045 "node_modules/follow-redirects": {
5031 "version": "1.15.6", 5046 "version": "1.15.6",
5032 "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.6.tgz", 5047 "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.6.tgz",
@@ -14588,6 +14603,11 @@ @@ -14588,6 +14603,11 @@
14588 "node": ">=0.8.0" 14603 "node": ">=0.8.0"
14589 } 14604 }
14590 }, 14605 },
  14606 + "node_modules/webworkify-webpack": {
  14607 + "version": "2.1.5",
  14608 + "resolved": "https://registry.npmmirror.com/webworkify-webpack/-/webworkify-webpack-2.1.5.tgz",
  14609 + "integrity": "sha512-2akF8FIyUvbiBBdD+RoHpoTbHMQF2HwjcxfDvgztAX5YwbZNyrtfUMgvfgFVsgDhDPVTlkbb5vyasqDHfIDPQw=="
  14610 + },
14591 "node_modules/whet.extend": { 14611 "node_modules/whet.extend": {
14592 "version": "0.9.9", 14612 "version": "0.9.9",
14593 "resolved": "https://registry.npmmirror.com/whet.extend/-/whet.extend-0.9.9.tgz", 14613 "resolved": "https://registry.npmmirror.com/whet.extend/-/whet.extend-0.9.9.tgz",
@@ -18692,6 +18712,11 @@ @@ -18692,6 +18712,11 @@
18692 "event-emitter": "~0.3.5" 18712 "event-emitter": "~0.3.5"
18693 } 18713 }
18694 }, 18714 },
  18715 + "es6-promise": {
  18716 + "version": "4.2.8",
  18717 + "resolved": "https://registry.npmmirror.com/es6-promise/-/es6-promise-4.2.8.tgz",
  18718 + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
  18719 + },
18695 "es6-set": { 18720 "es6-set": {
18696 "version": "0.1.6", 18721 "version": "0.1.6",
18697 "resolved": "https://registry.npmmirror.com/es6-set/-/es6-set-0.1.6.tgz", 18722 "resolved": "https://registry.npmmirror.com/es6-set/-/es6-set-0.1.6.tgz",
@@ -19206,6 +19231,15 @@ @@ -19206,6 +19231,15 @@
19206 "readable-stream": "^2.3.6" 19231 "readable-stream": "^2.3.6"
19207 } 19232 }
19208 }, 19233 },
  19234 + "flv.js": {
  19235 + "version": "1.6.2",
  19236 + "resolved": "https://registry.npmmirror.com/flv.js/-/flv.js-1.6.2.tgz",
  19237 + "integrity": "sha512-xre4gUbX1MPtgQRKj2pxJENp/RnaHaxYvy3YToVVCrSmAWUu85b9mug6pTXF6zakUjNP2lFWZ1rkSX7gxhB/2A==",
  19238 + "requires": {
  19239 + "es6-promise": "^4.2.8",
  19240 + "webworkify-webpack": "^2.1.5"
  19241 + }
  19242 + },
19209 "follow-redirects": { 19243 "follow-redirects": {
19210 "version": "1.15.6", 19244 "version": "1.15.6",
19211 "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.6.tgz", 19245 "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.6.tgz",
@@ -27144,6 +27178,11 @@ @@ -27144,6 +27178,11 @@
27144 "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", 27178 "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
27145 "dev": true 27179 "dev": true
27146 }, 27180 },
  27181 + "webworkify-webpack": {
  27182 + "version": "2.1.5",
  27183 + "resolved": "https://registry.npmmirror.com/webworkify-webpack/-/webworkify-webpack-2.1.5.tgz",
  27184 + "integrity": "sha512-2akF8FIyUvbiBBdD+RoHpoTbHMQF2HwjcxfDvgztAX5YwbZNyrtfUMgvfgFVsgDhDPVTlkbb5vyasqDHfIDPQw=="
  27185 + },
27147 "whet.extend": { 27186 "whet.extend": {
27148 "version": "0.9.9", 27187 "version": "0.9.9",
27149 "resolved": "https://registry.npmmirror.com/whet.extend/-/whet.extend-0.9.9.tgz", 27188 "resolved": "https://registry.npmmirror.com/whet.extend/-/whet.extend-0.9.9.tgz",
web_src/package.json
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 "echarts": "^4.9.0", 16 "echarts": "^4.9.0",
17 "element-ui": "^2.15.6", 17 "element-ui": "^2.15.6",
18 "fingerprintjs2": "^2.1.2", 18 "fingerprintjs2": "^2.1.2",
  19 + "flv.js": "^1.6.2",
19 "moment": "^2.29.1", 20 "moment": "^2.29.1",
20 "ol": "^6.14.1", 21 "ol": "^6.14.1",
21 "postcss-pxtorem": "^5.1.1", 22 "postcss-pxtorem": "^5.1.1",
web_src/src/layout/UiHeader.vue
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 <div id="UiHeader"> 2 <div id="UiHeader">
3 3
4 <el-menu router :default-active="activeIndex" menu-trigger="click" background-color="#001529" text-color="#fff" 4 <el-menu router :default-active="activeIndex" menu-trigger="click" background-color="#001529" text-color="#fff"
5 - active-text-color="#1890ff" mode="horizontal"> 5 + active-text-color="#1890ff" mode="horizontal">
6 6
7 <el-menu-item index="/console">控制台</el-menu-item> 7 <el-menu-item index="/console">控制台</el-menu-item>
8 <el-menu-item index="/live">分屏监控</el-menu-item> 8 <el-menu-item index="/live">分屏监控</el-menu-item>
@@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
13 <el-menu-item index="/cloudRecord">云端录像</el-menu-item> 13 <el-menu-item index="/cloudRecord">云端录像</el-menu-item>
14 <el-menu-item index="/mediaServerManger">节点管理</el-menu-item> 14 <el-menu-item index="/mediaServerManger">节点管理</el-menu-item>
15 <el-menu-item index="/parentPlatformList/15/1">国标级联</el-menu-item> 15 <el-menu-item index="/parentPlatformList/15/1">国标级联</el-menu-item>
  16 + <el-menu-item index="/minhang/deviceList">闵行设备</el-menu-item>
16 <el-menu-item v-if="editUser" index="/userManager">用户管理</el-menu-item> 17 <el-menu-item v-if="editUser" index="/userManager">用户管理</el-menu-item>
17 18
18 <!-- <el-submenu index="/setting">--> 19 <!-- <el-submenu index="/setting">-->
@@ -37,13 +38,13 @@ @@ -37,13 +38,13 @@
37 </template> 38 </template>
38 39
39 <script> 40 <script>
40 -import changePasswordDialog from '../components/dialog/changePassword.vue'  
41 -import userService from '../components/service/UserService'  
42 -import {Notification} from 'element-ui'; 41 +import { Notification } from 'element-ui';
  42 +import changePasswordDialog from '../components/dialog/changePassword.vue';
  43 +import userService from '../components/service/UserService';
43 44
44 export default { 45 export default {
45 name: "UiHeader", 46 name: "UiHeader",
46 - components: {Notification, changePasswordDialog}, 47 + components: { Notification, changePasswordDialog },
47 data() { 48 data() {
48 return { 49 return {
49 alarmNotify: false, 50 alarmNotify: false,
web_src/src/router/index.js
@@ -2,24 +2,26 @@ import Vue from &#39;vue&#39; @@ -2,24 +2,26 @@ import Vue from &#39;vue&#39;
2 import VueRouter from 'vue-router' 2 import VueRouter from 'vue-router'
3 import Layout from "../layout/index.vue" 3 import Layout from "../layout/index.vue"
4 4
5 -import console from '../components/console.vue' 5 +import cloudRecord from '../components/CloudRecord.vue'
  6 +import cloudRecordDetail from '../components/CloudRecordDetail.vue'
6 import deviceList from '../components/DeviceList.vue' 7 import deviceList from '../components/DeviceList.vue'
7 -import channelList from '../components/channelList.vue'  
8 import gbRecordDetail from '../components/GBRecordDetail.vue' 8 import gbRecordDetail from '../components/GBRecordDetail.vue'
  9 +import login from '../components/Login.vue'
  10 +import mediaServerManger from '../components/MediaServerManger.vue'
  11 +import parentPlatformList from '../components/ParentPlatformList.vue'
9 import pushVideoList from '../components/PushVideoList.vue' 12 import pushVideoList from '../components/PushVideoList.vue'
10 import streamProxyList from '../components/StreamProxyList.vue' 13 import streamProxyList from '../components/StreamProxyList.vue'
  14 +import userManager from '../components/UserManager.vue'
  15 +import channelList from '../components/channelList.vue'
  16 +import deviceTree from '../components/common/DeviceTree.vue'
  17 +import minhang from '../components/common/minhang.vue'
  18 +import minhangChannel from '../components/common/minhangChannel.vue'
  19 +import console from '../components/console.vue'
  20 +import live from '../components/live.vue'
11 import map from '../components/map.vue' 21 import map from '../components/map.vue'
12 -import login from '../components/Login.vue'  
13 -import parentPlatformList from '../components/ParentPlatformList.vue'  
14 -import cloudRecord from '../components/CloudRecord.vue'  
15 -import cloudRecordDetail from '../components/CloudRecordDetail.vue'  
16 -import mediaServerManger from '../components/MediaServerManger.vue'  
17 -import web from '../components/setting/Web.vue'  
18 -import sip from '../components/setting/Sip.vue'  
19 import media from '../components/setting/Media.vue' 22 import media from '../components/setting/Media.vue'
20 -import live from '../components/live.vue'  
21 -import deviceTree from '../components/common/DeviceTree.vue'  
22 -import userManager from '../components/UserManager.vue' 23 +import sip from '../components/setting/Sip.vue'
  24 +import web from '../components/setting/Web.vue'
23 25
24 import wasmPlayer from '../components/common/jessibuca.vue' 26 import wasmPlayer from '../components/common/jessibuca.vue'
25 import rtcPlayer from '../components/dialog/rtcPlayer.vue' 27 import rtcPlayer from '../components/dialog/rtcPlayer.vue'
@@ -54,6 +56,16 @@ export default new VueRouter({ @@ -54,6 +56,16 @@ export default new VueRouter({
54 component: deviceList, 56 component: deviceList,
55 }, 57 },
56 { 58 {
  59 + path: '/minhang/deviceList',
  60 + name: 'minhang',
  61 + component: minhang,
  62 + },
  63 + {
  64 + path: '/minhang/deviceList/channel/:deviceId',
  65 + name: 'minhangChannel',
  66 + component: minhangChannel,
  67 + },
  68 + {
57 path: '/pushVideoList', 69 path: '/pushVideoList',
58 component: pushVideoList, 70 component: pushVideoList,
59 }, 71 },
web_src/static/js/config.js
1 -window.baseUrl = "https://61.169.120.202:18080"; 1 +window.baseUrl = "http://61.169.120.202:18089";
2 2
3 // map组件全局参数, 注释此内容可以关闭地图功能 3 // map组件全局参数, 注释此内容可以关闭地图功能
4 window.mapParam = { 4 window.mapParam = {