Commit ac8daf92c4705bfb32f3c0258b4791c4b86947e6
1 parent
af16fee7
feat: 增加闵行设备
Showing
13 changed files
with
723 additions
and
60 deletions
README.md
| 1 | 1 |  |
| 2 | -# 开箱即用的28181协议视频平台 | |
| 3 | - | |
| 4 | -[](https://travis-ci.org/xia-chu/ZLMediaKit) | |
| 5 | -[](https://github.com/xia-chu/ZLMediaKit/blob/master/LICENSE) | |
| 6 | -[](https://en.cppreference.com/) | |
| 7 | -[](https://github.com/xia-chu/ZLMediaKit) | |
| 8 | -[](https://github.com/xia-chu/ZLMediaKit/pulls) | |
| 9 | - | |
| 10 | 2 | |
| 11 | 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 | 19 | ZLM使用文档 [https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit) |
| 28 | 20 | > wvp文档由gitee提供服务,如果遇到打不开请多刷新几次。 |
| 29 | 21 | |
| 30 | -# 付费社群 | |
| 31 | -[](https://t.zsxq.com/0d8VAD3Dm) | |
| 32 | -> 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接退款,大家不需要有顾虑,来白嫖三天也不是不可以。 | |
| 33 | - | |
| 34 | 22 | # gitee同步仓库 |
| 35 | 23 | https://gitee.com/pan648540858/wvp-GB28181-pro.git |
| 36 | 24 | |
| 37 | -# 截图 | |
| 38 | - | |
| 39 | - | |
| 40 | - | |
| 41 | - | |
| 42 | - | |
| 43 | - | |
| 44 | - | |
| 45 | - | |
| 46 | 25 | # 功能特性 |
| 47 | 26 | - [X] 集成web界面 |
| 48 | 27 | - [X] 兼容性良好 |
| ... | ... | @@ -110,20 +89,10 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git |
| 110 | 89 | - [X] 支持Mysql,Postgresql,金仓等数据库 |
| 111 | 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 | 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 | 98 | 感谢作者[夏楚](https://github.com/xia-chu) 提供这么棒的开源流媒体服务框架,并在开发过程中给予支持与帮助。 |
| ... | ... | @@ -136,12 +105,3 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git |
| 136 | 105 | [ydpd](https://github.com/ydpd) [szy833](https://github.com/szy833) [ydwxb](https://github.com/ydwxb) [Albertzhu666](https://github.com/Albertzhu666) |
| 137 | 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 | 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 | 11 | assetsPublicPath: "/", |
| 12 | 12 | proxyTable: { |
| 13 | 13 | "/debug": { |
| 14 | - target: "https://61.169.120.202:18080", | |
| 14 | + target: "http://61.169.120.202:18089", | |
| 15 | 15 | changeOrigin: true, |
| 16 | 16 | pathRewrite: { |
| 17 | 17 | "^/debug": "/", |
| 18 | 18 | }, |
| 19 | 19 | }, |
| 20 | 20 | "/static/snap": { |
| 21 | - target: "https://61.169.120.202:18080", | |
| 21 | + target: "http://61.169.120.202:18089", | |
| 22 | 22 | changeOrigin: true, |
| 23 | 23 | // pathRewrite: { |
| 24 | 24 | // '^/static/snap': '/static/snap' | ... | ... |
web_src/package-lock.json
| ... | ... | @@ -14,6 +14,7 @@ |
| 14 | 14 | "echarts": "^4.9.0", |
| 15 | 15 | "element-ui": "^2.15.6", |
| 16 | 16 | "fingerprintjs2": "^2.1.2", |
| 17 | + "flv.js": "^1.6.2", | |
| 17 | 18 | "moment": "^2.29.1", |
| 18 | 19 | "ol": "^6.14.1", |
| 19 | 20 | "postcss-pxtorem": "^5.1.1", |
| ... | ... | @@ -4400,6 +4401,11 @@ |
| 4400 | 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 | 4409 | "node_modules/es6-set": { |
| 4404 | 4410 | "version": "0.1.6", |
| 4405 | 4411 | "resolved": "https://registry.npmmirror.com/es6-set/-/es6-set-0.1.6.tgz", |
| ... | ... | @@ -5027,6 +5033,15 @@ |
| 5027 | 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 | 5045 | "node_modules/follow-redirects": { |
| 5031 | 5046 | "version": "1.15.6", |
| 5032 | 5047 | "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.6.tgz", |
| ... | ... | @@ -14588,6 +14603,11 @@ |
| 14588 | 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 | 14611 | "node_modules/whet.extend": { |
| 14592 | 14612 | "version": "0.9.9", |
| 14593 | 14613 | "resolved": "https://registry.npmmirror.com/whet.extend/-/whet.extend-0.9.9.tgz", |
| ... | ... | @@ -18692,6 +18712,11 @@ |
| 18692 | 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 | 18720 | "es6-set": { |
| 18696 | 18721 | "version": "0.1.6", |
| 18697 | 18722 | "resolved": "https://registry.npmmirror.com/es6-set/-/es6-set-0.1.6.tgz", |
| ... | ... | @@ -19206,6 +19231,15 @@ |
| 19206 | 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 | 19243 | "follow-redirects": { |
| 19210 | 19244 | "version": "1.15.6", |
| 19211 | 19245 | "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.6.tgz", |
| ... | ... | @@ -27144,6 +27178,11 @@ |
| 27144 | 27178 | "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", |
| 27145 | 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 | 27186 | "whet.extend": { |
| 27148 | 27187 | "version": "0.9.9", |
| 27149 | 27188 | "resolved": "https://registry.npmmirror.com/whet.extend/-/whet.extend-0.9.9.tgz", | ... | ... |
web_src/package.json
web_src/src/layout/UiHeader.vue
| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | <div id="UiHeader"> |
| 3 | 3 | |
| 4 | 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 | 7 | <el-menu-item index="/console">控制台</el-menu-item> |
| 8 | 8 | <el-menu-item index="/live">分屏监控</el-menu-item> |
| ... | ... | @@ -13,6 +13,7 @@ |
| 13 | 13 | <el-menu-item index="/cloudRecord">云端录像</el-menu-item> |
| 14 | 14 | <el-menu-item index="/mediaServerManger">节点管理</el-menu-item> |
| 15 | 15 | <el-menu-item index="/parentPlatformList/15/1">国标级联</el-menu-item> |
| 16 | + <el-menu-item index="/minhang/deviceList">闵行设备</el-menu-item> | |
| 16 | 17 | <el-menu-item v-if="editUser" index="/userManager">用户管理</el-menu-item> |
| 17 | 18 | |
| 18 | 19 | <!-- <el-submenu index="/setting">--> |
| ... | ... | @@ -37,13 +38,13 @@ |
| 37 | 38 | </template> |
| 38 | 39 | |
| 39 | 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 | 45 | export default { |
| 45 | 46 | name: "UiHeader", |
| 46 | - components: {Notification, changePasswordDialog}, | |
| 47 | + components: { Notification, changePasswordDialog }, | |
| 47 | 48 | data() { |
| 48 | 49 | return { |
| 49 | 50 | alarmNotify: false, | ... | ... |
web_src/src/router/index.js
| ... | ... | @@ -2,24 +2,26 @@ import Vue from 'vue' |
| 2 | 2 | import VueRouter from 'vue-router' |
| 3 | 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 | 7 | import deviceList from '../components/DeviceList.vue' |
| 7 | -import channelList from '../components/channelList.vue' | |
| 8 | 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 | 12 | import pushVideoList from '../components/PushVideoList.vue' |
| 10 | 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 | 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 | 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 | 26 | import wasmPlayer from '../components/common/jessibuca.vue' |
| 25 | 27 | import rtcPlayer from '../components/dialog/rtcPlayer.vue' |
| ... | ... | @@ -54,6 +56,16 @@ export default new VueRouter({ |
| 54 | 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 | 69 | path: '/pushVideoList', |
| 58 | 70 | component: pushVideoList, |
| 59 | 71 | }, | ... | ... |