Compare commits

...

599 Commits

Author SHA1 Message Date
CODE 3c486af6f8 ! 注释与安心云的绑定数据通信 1 year ago
CODE 7ffc28208e redis 鉴权数据查询 1 year ago
sunyue 328207c451 更新 'code/VideoAccess-VCMP/script/1.3.1/data/1_sync_camera_data/index.js' 1 year ago
iris_cx a70131ebf3 更新 'jenkinsfile_vcmp_script_1.3.1' 1 year ago
iris_cx 1529084fc6 更新 'code/VideoAccess-VCMP/script/1.3.1/data/1_sync_camera_data/Dockerfile' 1 year ago
iris_cx 5667297052 更新 'code/VideoAccess-VCMP/script/1.3.1/data/1_sync_camera_data/Dockerfile' 1 year ago
iris_cx 88ad42659d 更新 'jenkinsfilenew_web' 1 year ago
iris_cx 1ebf2a37ca 更新 'jenkinsfilenew_web' 1 year ago
巴林闲侠 c0781d19c2 test 新的 28181接口服务 1 year ago
wenlele 1e29e99178 scheduleInit 2 years ago
wenlele b2d7d66600 dev_trial 2 years ago
wenlele 9c8ea37c94 Dockerfilenew 2 years ago
wenlele 8c001f7c33 code/VideoAccess-VCMP 2 years ago
wenlele 768e37a4a3 free-sun 2 years ago
wenlele 9c2a9e8d35 jenkinsfilenew 2 years ago
wenlele 039c5f42f5 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele 6c7bdcc78c 默认清晰度 2 years ago
iris_cx 179e691665 更新 'code/VideoAccess-VCMP/api/Dockerfilenew' 2 years ago
iris_cx 1b1fcb55f2 更新 'code/VideoAccess-VCMP/web/Dockerfilenew' 2 years ago
iris_cx 1acb1876f5 更新 'jenkinsfilenew_api' 2 years ago
iris_cx d3e556b0cd 更新 'jenkinsfilenew_web' 2 years ago
iris_cx a144e40763 更新 'jenkinsfilenew_web' 2 years ago
iris_cx 6ae1eae8d3 更新 'jenkinsfilenew_api' 2 years ago
iris_cx db56433aa8 更新 'jenkinsfilenew_api' 2 years ago
iris_cx d487454a84 添加 'jenkinsfilenew_web' 2 years ago
iris_cx 564cac18e4 添加 'jenkinsfilenew_api' 2 years ago
iris_cx 960c8cdddf 添加 'code/VideoAccess-VCMP/api/Dockerfilenew' 2 years ago
iris_cx ea54a88f33 添加 'code/VideoAccess-VCMP/web/Dockerfilenew' 2 years ago
巴林闲侠 a107089c79 图标文件 async 2 years ago
wenlele 002bd4d961 重复播放 2 years ago
wenlele e4eea06493 摄像头播放不成功时重复执行 2 years ago
wenlele e41e1789ae 历史时间点击确认 2 years ago
wenlele 0ed28d8597 摄像头历史选择日期确认方式(点击按钮确认) 2 years ago
wenlele 82cb234e4d RUN rm -rf package-lock.json 2 years ago
wenlele 256cbb1574 1.3.7 脚本 2 years ago
wenlele 245245a69a 列表展开与勾选 2 years ago
巴林闲侠 271fd8cc0f 镜像全屏播放画面变化 2 years ago
wenlele e12655910c 脚本位置修改 2 years ago
wenlele 1ff85c71f0 镜像大屏列表是否展示 2 years ago
巴林闲侠 f4acee9557 构建配置文件 2 years ago
巴林闲侠 2a791857eb 构建配置文件 2 years ago
巴林闲侠 bb53ca80dd 构建配置文件 2 years ago
巴林闲侠 ca564a9f6c 批量录入摄像头 2 years ago
巴林闲侠 bc9ea4cb10 批量录入摄像头 2 years ago
巴林闲侠 56df5405f6 增加萤石账号 2 years ago
巴林闲侠 dd15b754a2 增加萤石账号 2 years ago
巴林闲侠 fb2cd9354f ·· 2 years ago
巴林闲侠 313b0adfa7 FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node:12-dev as builder 2 years ago
wenlele f8bcc17e95 测试1 2 years ago
wenlele be6d1a412f 测试 2 years ago
wenlele 9e7c52f337 ceshi 2 years ago
wenlele 91af0880bc ceshi 2 years ago
wenlele 155d292140 ceshi 2 years ago
wenlele 7b40375d89 ceshi 2 years ago
wenlele ab613a1bdb ceshi 2 years ago
wenlele 9c84c31d76 ceshi 2 years ago
wenlele 4ba0582f95 ceshi 2 years ago
wenlele 9e1e011fb7 ceshi 2 years ago
wenlele 72185fd407 ceshi 2 years ago
wenlele 4a5849b2b2 ceshi 2 years ago
wenlele 38e381a5e1 测试 2 years ago
wenlele 3550b8932f 测试 2 years ago
wenlele 29b39d5fe9 测试 2 years ago
wenlele 1ac3584cbe ceshi 2 years ago
wenlele f540c75851 测试 2 years ago
wenlele 8dbfc112a2 测试 2 years ago
wenlele b026fd7f58 测试 2 years ago
wenlele 6dcdfc8b60 ceshi 2 years ago
wenlele 46e76c83a1 测试 2 years ago
wenlele 70daa152c9 测试 2 years ago
wenlele cd8c6765d3 测试 2 years ago
wenlele 1f0f9ead93 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele 6c9f9f7acc 检测 2 years ago
巴林闲侠 0e8eab15ba 上下线记录 注释 2 years ago
wenlele 439bf94ef6 镜像 2 years ago
巴林闲侠 d53e3ef2d0 ?did 2 years ago
巴林闲侠 27bd20f8b3 debug 查询耗时 2 years ago
巴林闲侠 9ebf51063d 镜像 check 2 years ago
巴林闲侠 6102243dd3 更新镜像服务id 2 years ago
巴林闲侠 73fa9b77ca 更新镜像服务id 2 years ago
巴林闲侠 1813789134 更新镜像服务id 2 years ago
巴林闲侠 4c392b9475 flv bye 2 years ago
巴林闲侠 fffef81fe3 iotVideoPlayServer 作为 flv 播放前缀 2 years ago
wenlele 8028b8a443 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele ac3d85184e 时间设置 条件修改 2 years ago
deartibers 1707d71bfd camera表里的kindId为null的变成1314 2 years ago
wenlele 1be4b614f6 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele e6fe7868ff 视频播放修改 2 years ago
巴林闲侠 86e898c8d5 fix GB28181 参数请求及解析恢复至原版 2 years ago
巴林闲侠 06758cab85 fix GB28181 参数请求及解析恢复至原版 2 years ago
巴林闲侠 e98e157854 wss flv 播放国标视频 静音 2 years ago
巴林闲侠 c71076f5de wss flv 播放国标视频 静音 2 years ago
巴林闲侠 318aaef04a wss flv 播放国标视频 2 years ago
巴林闲侠 3c209c95a0 wss flv 播放国标视频 2 years ago
巴林闲侠 28ac2b47be hdl flv 播放国标视频 2 years ago
巴林闲侠 752ce83e73 hdl flv 播放国标视频 2 years ago
巴林闲侠 c233cccc28 fix 视频推送 2 years ago
wenlele f08837803e Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele e9d8d1de7b 解决冲突 2 years ago
wenlele 5812cf82bd debug 2 years ago
巴林闲侠 8e7f0d994e fix 推送数量 2 years ago
巴林闲侠 2b77ef4cfe 视频告警记录至运维平台 2 years ago
巴林闲侠 f7be561a4d flv 播放国标摄像头 2 years ago
巴林闲侠 5a096c2b89 flv 播放国标摄像头 2 years ago
巴林闲侠 a1a63390b1 flv 播放国标摄像头 2 years ago
wenlele 848c14d9ab bye 视频推流关闭 2 years ago
wenlele 74e71e97f8 视频编号请求修改 2 years ago
wenlele cddbb2f028 topSerialNo 视频请求参数 2 years ago
wenlele 908fe91784 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele 5ddfedaf06 推流播放参数添加 2 years ago
巴林闲侠 4f6fd291ad Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
巴林闲侠 9b5c2b2d28 getCmaeraUniqueConfig 增加状态和更新时间 2 years ago
wenlele c00c085919 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele f5707e23b8 视频播放缩放修改 2 years ago
巴林闲侠 7cae018b1e fix 更新视频告警 2 years ago
巴林闲侠 f1c9e66a5c 视频告警取消时区记录 2 years ago
巴林闲侠 c4bf7bf019 视频告警确认 2 years ago
巴林闲侠 8d8ec1b7d2 debug 2 years ago
巴林闲侠 d007072b6a /status/check 不鉴权 2 years ago
巴林闲侠 a3ce4ce67a 更改数据库信息 2 years ago
巴林闲侠 50458a3a15 视频告警自动恢复逻辑 2 years ago
巴林闲侠 b60bf61233 /status/check 还是要鉴权 2 years ago
巴林闲侠 4fca7d75b9 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
巴林闲侠 40bda2ba3a /status/check 不鉴权 2 years ago
wenlele 9ca1d9c6f0 videoToken 视频播放token 2 years ago
巴林闲侠 7133f16c37 * 2 years ago
巴林闲侠 38ecd4bec2 视频告警确认 2 years ago
巴林闲侠 dd8f6f9528 获取序列号+通道号唯一的全部摄像头 2 years ago
巴林闲侠 24334393d1 获取推送配置路由改为 push_list 2 years ago
巴林闲侠 aefcce58d3 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
巴林闲侠 57e82130c3 fix /video_play_status 商用不能正常加载 2 years ago
wenlele a9c800143c Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele 361f06603d gb 2 years ago
巴林闲侠 6ea960327d Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
巴林闲侠 37a23bc1d0 corUser[0].namePresent 保护 2 years ago
wenlele 5677c3bc75 api 2 years ago
wenlele a7a33e71f9 http 2 years ago
wenlele dc4572ae23 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele 6aaff35ff5 jessibuca 调试 2 years ago
巴林闲侠 04c06b07dd 视频管理权限用账号区分,用户只能查看自己接入的视频,为后续设备共享权限管理预留功能开发 2 years ago
巴林闲侠 d290ea69be video play check 2 years ago
wenlele 5d7aaf18bd 语音,云台 2 years ago
wenlele 48c333d3f2 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele 311226953a 镜像调用服务 2 years ago
巴林闲侠 e5beb9af36 有 -> 新增 2 years ago
巴林闲侠 6413c6c3c3 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
巴林闲侠 082e8efa3e 有 -> 新增 2 years ago
deartibers 85002c799c 样式名称修改 2 years ago
wenlele df2093417e Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele 0119674648 背景修改 2 years ago
deartibers 6fd9c3b287 查看接口查询时间 2 years ago
巴林闲侠 d39fe62a45 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
巴林闲侠 7c5272ccda setHideFullScreenBut 2 years ago
wenlele 9d2299e43c shiyi 2 years ago
wenlele 379fdfd707 paraphrase 2 years ago
wenlele b50f9baca1 Merge branch 'dev_trial' of 2 years ago
wenlele 6ab833d407 遮罩层添加 2 years ago
巴林闲侠 303239eea3 历史视频 2 years ago
巴林闲侠 fd38d78dfc 视频全屏 2 years ago
wenlele 340344a722 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele 6c71e1cf98 bug 2 years ago
巴林闲侠 26f79c6967 同步萤石 2 years ago
deartibers 4ebb23c85a 间距问题 2 years ago
deartibers 4f7fdd5a3d 问题修改 2 years ago
wenlele 78a551d6c7 拉取 2 years ago
wenlele 3aac22db88 拉取 2 years ago
deartibers 254072137c 视频播放修改 2 years ago
wenlele c1435d4ade Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele c2f35c74f1 冲突解决 2 years ago
deartibers 81be16ab8c 视频播放修改 2 years ago
wenlele 0a69db2d33 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele 9c70d13519 视频全屏和背投冲突需修改 2 years ago
deartibers a479033da9 问题修改 2 years ago
wenlele b1cc8f0903 部分bug修改 2 years ago
wenlele 52b77c3843 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele bb6d485925 备注修改完成 2 years ago
巴林闲侠 818fabc1e3 注释camera查询用户限制 2 years ago
巴林闲侠 be673dc6b1 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
巴林闲侠 e37d0ac53b 频率限制 2 years ago
wenlele c2b7eeee16 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele a60cf9bbae 颜色 2 years ago
巴林闲侠 d87ed7bcb5 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
巴林闲侠 3639ddd59a VcmpApp height 100% 2 years ago
deartibers 3467a866e2 字数限制 2 years ago
wenlele 8899e2a57a 镜像服务模块三套模板样式 2 years ago
wenlele 3f6aea6661 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele cbc9791a4b 树状勾选修改 2 years ago
巴林闲侠 8493d14d6f 数据库配置 2 years ago
巴林闲侠 ca45b970e6 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
巴林闲侠 5a52d453d0 脚本数据库 2 years ago
deartibers a5f11323f3 问题修改 2 years ago
wenlele 6545f7ce78 搜索更改 2 years ago
wenlele 08ec4505ac Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele 57d5122333 视频图片 2 years ago
巴林闲侠 0040b0dd58 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
巴林闲侠 aaf31906e3 dockerfile 2 years ago
deartibers faa32a6a4b 字符修改 2 years ago
wenlele fd80e69cfe Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele 79ef365e2b 分页修改 2 years ago
deartibers 1b10eba24f 去重 2 years ago
巴林闲侠 c01b9a9a60 dockerfile 2 years ago
巴林闲侠 c49bde63ad Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
巴林闲侠 9e6e5a0584 镜像服务数据库脚本 2 years ago
deartibers ef6020e48a 判断是否编辑过 2 years ago
wenlele 3c99b1c4e3 预览数据连通 2 years ago
巴林闲侠 998915aac7 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
巴林闲侠 efe5131415 获取完整镜像信息 2 years ago
deartibers f1d2ca45b9 镜像服务接口联调 2 years ago
deartibers 3571c81e86 接口联调 2 years ago
deartibers 0ed05daa6e Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
deartibers 5b98b9e395 镜像服务联调 2 years ago
巴林闲侠 35606216fb CameraListAll order 2 years ago
巴林闲侠 877fe9272a 安心云摄像头同步 2 years ago
巴林闲侠 057ae2ed92 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
巴林闲侠 3c646eda7b 同步安心云萤石摄像头sql 2 years ago
deartibers ab36628c9b 镜像联调 2 years ago
deartibers 8374ffd4ee 功能筛选组项 2 years ago
巴林闲侠 eb1a31bf2d MicroApp mirrorId 2 years ago
巴林闲侠 21e12d47ef mirror api 60% 2 years ago
巴林闲侠 97f26b4145 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
巴林闲侠 705b0a12f9 mirror api 60% 2 years ago
wenlele e3dc416bd5 预览嵌入 2 years ago
wenlele 5e2185fd08 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
wenlele 49fcae7088 视频 2 years ago
wenlele a38accd952 视频 2 years ago
deartibers e7599f76d0 镜像页面添加摄像头 2 years ago
deartibers b19ac3ded2 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
deartibers b055eb5f18 镜像管理详情页面 2 years ago
巴林闲侠 738e12ada2 did 2 years ago
wenlele e62633981a basicAction引入修改 2 years ago
巴林闲侠 a537453812 mocroApp 2 years ago
巴林闲侠 8ab00cfd25 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
巴林闲侠 00f4ca57ec user -vcmpUser 2 years ago
wenlele 28adf60344 查询,树状展示结构,视屏的联动 2 years ago
wenlele 35f4535618 宫格,查询完成 2 years ago
wenlele a805e34a8d 分屏,轮询 2 years ago
巴林闲侠 cdf84d59fb MicroApp 80% 2 years ago
巴林闲侠 51cdd8d454 .semi-portal-inner 300px 2 years ago
巴林闲侠 fdbd9690b6 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 2 years ago
巴林闲侠 4086422ed2 microApp 2 years ago
wenlele 8f2f0eb0ed bug修改 3 years ago
wenlele 5875b805be bug修改 3 years ago
wenlele 33d19ed200 应用管理页面数据接入完成 3 years ago
deartibers f0d3a1144d 修改问题 3 years ago
deartibers 72b2a73aef 问题修改 3 years ago
deartibers 8fcb4a60b1 镜像服务静态页面 3 years ago
wenlele 8ff790190c 冲突修改 3 years ago
wenlele b5a95f5b33 应用删除禁用接口 3 years ago
巴林闲侠 3b4e90c91c OAuth2 3 years ago
巴林闲侠 4c0d85ce14 app check 3 years ago
巴林闲侠 1d228509e3 app check 3 years ago
巴林闲侠 467aa7ce2e app check 3 years ago
wenlele d9cb940da2 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 3 years ago
wenlele beac398659 应用增改接口 3 years ago
巴林闲侠 fbc1c40703 优化推送逻辑 3 years ago
巴林闲侠 4dcd501d98 优化推送逻辑 3 years ago
巴林闲侠 043ac8747e 优化推送逻辑 3 years ago
巴林闲侠 3330f07be4 优化推送逻辑 3 years ago
巴林闲侠 0a8e9ad4f0 优化推送逻辑 3 years ago
巴林闲侠 114804bce6 优化推送逻辑 3 years ago
巴林闲侠 fe24239555 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 8ab59917f5 萤石查询间隔 4min 3 years ago
wenlele f3f11e8a66 创建api文件 3 years ago
巴林闲侠 6a01f3c757 application table 3 years ago
巴林闲侠 7bc12c9861 debug 3 years ago
巴林闲侠 00acfb8ca9 debug 3 years ago
巴林闲侠 0380240df0 短信模板 3 years ago
巴林闲侠 52f55f31e3 短信模板 3 years ago
deartibers c2d9b39d36 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 3 years ago
deartibers 170f2b1fbb 修改问题 3 years ago
巴林闲侠 b78bb49264 定時任務 3 years ago
巴林闲侠 0ef8bd183a cameraOnlinePush 3 years ago
巴林闲侠 32f955049e timing 3 years ago
巴林闲侠 3ee9869fd6 CameraStatusPushMonitor del 3 years ago
巴林闲侠 cebfc7270b Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 9291083f33 camera_status_offline_log 3 years ago
wenlele e6682fe482 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 3 years ago
wenlele 1b0a571441 地址拼写 3 years ago
巴林闲侠 86dccaf1de Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 ed0e95ad5b 删除设备 删除推送配置相关 3 years ago
deartibers 0a6969f1f2 修改问题 3 years ago
deartibers 18dd2d085e 通道号 3 years ago
巴林闲侠 87f5360204 freshYingshiState interval 3 years ago
巴林闲侠 39b07a8733 萤石刷新 3 years ago
巴林闲侠 a516468d32 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 452cc0ed1c fix 复制出来的策略未处于禁用状态 3 years ago
wenlele d50f2cf566 查看名称修改 3 years ago
wenlele 464f33ef67 视频 3 years ago
wenlele d70ea89d19 尺寸问题解决 3 years ago
deartibers bb18782141 信鸽服务接口联调 3 years ago
巴林闲侠 3f08d7e86f 数据推送 3 years ago
巴林闲侠 4d9787693f Resolve bulkcreate debug 3 years ago
巴林闲侠 d3333029a0 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 658d6cea85 Resolve bulkcreate debug 3 years ago
wenlele 634e10e64b Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 3 years ago
wenlele ba4697ac53 视频颜色 3 years ago
巴林闲侠 9d55d70bc2 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 50b5cdaeb1 信鸽推送 80% 3 years ago
deartibers 707567a139 修改icon 3 years ago
deartibers 622b7ec40f 信鸽服务接口联调 3 years ago
wenlele b53cd0ae4e Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 3 years ago
wenlele 8efcd2a77b 应用管理页面完成 3 years ago
巴林闲侠 9e2b6277ec api参数 3 years ago
巴林闲侠 98dcbe6308 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 03c69cedc8 信鸽故障fix 3 years ago
wenlele da90aa7fc2 播放器修改 3 years ago
deartibers 5b9d2c746e 信鸽服务 3 years ago
巴林闲侠 80ddf0695a sql 3 years ago
巴林闲侠 da1ea56186 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 bc5ecd3738 信鸽API 3 years ago
wenlele 5820112bc8 注释http转化成https的限制条件 3 years ago
deartibers bac88851a7 状态码问题修改 3 years ago
wenlele 396458a380 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 3 years ago
wenlele 3836ddde90 播放组件的修改 3 years ago
deartibers d4c9bca218 状态码释义接口联调 3 years ago
巴林闲侠 3f8c4138db camera_status sql 3 years ago
deartibers 8323f72ce0 Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 562bc0746e Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 1381d67ed6 camera status 3 years ago
deartibers bdb2dbe84c 状态码页面静态页面及接口联调 3 years ago
yangsen eded873264 信鸽页面未完成 3 years ago
yangsen 1bd681b64c Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
yangsen a40ad82452 信鸽页面暂存 3 years ago
deartibers fca2333459 表格属性 3 years ago
deartibers 6915209046 状态码管理和信鸽服务主页面 3 years ago
wenlele 1453d187c4 播放修改 3 years ago
巴林闲侠 ce3e1c932d 萤石设备播放地址更新查询用时 3 years ago
巴林闲侠 df40d3d9df redis.Cluster 3 years ago
巴林闲侠 4e192fe454 redis pswd 3 years ago
巴林闲侠 a9ced94fc7 播放器 params.videoObj 3 years ago
巴林闲侠 a31d4c04d3 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 f0760bd0e5 https->http 3 years ago
deartibers d588ac9661 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
deartibers 56e277b099 备注视频样式修改 3 years ago
巴林闲侠 13524a5cf1 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 04663f3cbf /camera 暂时不鉴权 3 years ago
deartibers 405c723228 备注按id排序 3 years ago
巴林闲侠 1ae93b7676 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 ffc064fcb0 备注排序x 3 years ago
deartibers bb385d7536 默认信息 3 years ago
巴林闲侠 55928225d5 camera_remark 3 years ago
巴林闲侠 d372ce14fc Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 c079740238 视频备注 100% 3 years ago
wenlele e6c365494d Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
wenlele 766935ed75 表格添加备注功能 3 years ago
deartibers c15990cd60 备注修改 3 years ago
deartibers 761c829c0e 备注滚动 3 years ago
巴林闲侠 a9ce108e9d CameraRemark 排序 3 years ago
wenlele 29244b7288 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
wenlele cb6d752abc 测试 3 years ago
deartibers c38fb8cbf9 备注功能 3 years ago
巴林闲侠 f05ade2b91 获取流 同时获取备注 3 years ago
巴林闲侠 bfdf962443 定时任务 3 years ago
巴林闲侠 f0a380d64d 1.1.0 3 years ago
deartibers 36052b634c Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
deartibers d067752179 文件包和备注 3 years ago
wenlele 06fc355304 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
wenlele 0c08d9e55d 置灰修改完成 3 years ago
巴林闲侠 c8a00261a0 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 9131be6873 定时任务即刻启用 3 years ago
wenlele 17de5056e4 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
wenlele 37b84265a1 播放完成 3 years ago
巴林闲侠 ed1423141f Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 ccaa56c1ea yingshi talk 3 years ago
deartibers c9bd721035 nvr全选显示时间 3 years ago
巴林闲侠 9d2420130b Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 e3a6dc6e85 jessibuca.destroy() 3 years ago
wenlele 8cb1cfcf8b NVR添加名称格式修改 3 years ago
巴林闲侠 8e74408c87 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 efdde52111 GB视频播放 3 years ago
deartibers c6b6345116 nav图标 3 years ago
巴林闲侠 f72a28c30b mqtt 视频状态推送 3 years ago
巴林闲侠 707f8437fe 定时更新时间 3 years ago
巴林闲侠 f6a7c66c68 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 b6a763e3c8 安心云摄像头查询信息增加 3 years ago
wenlele feb1824eed 播放完成 3 years ago
deartibers 623fae136e 解决合并冲突 3 years ago
deartibers 73ee59529f 主题 3 years ago
巴林闲侠 30ccd213a7 视频播放cross 3 years ago
巴林闲侠 13a97ea076 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 b0d21b367c 萤石播放器 99.9% 3 years ago
wenlele 885c69d4d6 查询信息修改完毕 3 years ago
deartibers 97d8d0337e Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
deartibers 769ff49451 主题设置 3 years ago
巴林闲侠 09f72f5c9d 萤石播放器 89.9% 3 years ago
巴林闲侠 faf23bb4f6 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 6c646018a6 萤石播放器 88.8% 3 years ago
deartibers bccf70dec1 上下线推送 3 years ago
wenlele 96e04ea0db 测试置灰完成 3 years ago
wenlele ab2e4dc81a nvr摄像头视频流bug解决 3 years ago
巴林闲侠 09af37576b Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 32ded7ec5a 萤石状态更新逻辑 3 years ago
wenlele 3d1242fa31 级联视频流功能完成 3 years ago
巴林闲侠 1bbcd0c6a5 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 517929e1ce 播放地址拼接 3 years ago
wenlele a6c4ac075f Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
wenlele d255cb4ef6 级联视频流 80% 3 years ago
巴林闲侠 39fa23c823 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 263c79d246 萤石状态获取 3 years ago
巴林闲侠 ee1dee9f84 萤石状态获取 3 years ago
wenlele 7ed76c4208 搜索修改 3 years ago
wenlele 8d29279fd9 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
wenlele bb9974c8b2 查询复制地址完成 3 years ago
巴林闲侠 4a3946d4cc 萤石状态推送 3 years ago
巴林闲侠 756231efa7 fix websocket 信息推送 3 years ago
巴林闲侠 eb9789e6c0 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 1b16c8a05b makeDir 3 years ago
wenlele 35ab0b2fa6 完善导出 3 years ago
巴林闲侠 e9e4b42060 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 b3caa8a43a 级联添加接口 3 years ago
wenlele 26aa1c6ae8 头部敬语和摄像头页面设备状态查询添加 3 years ago
巴林闲侠 a7d98ddcfc dockerfile 3 years ago
巴林闲侠 8deb57ba1f Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 fa513c5e8e 萤石状态广播测试 3 years ago
wenlele 5a0da83039 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
wenlele f69525056b socket 3 years ago
巴林闲侠 57e99c139a Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 7279365a62 iourl = root 3 years ago
wenlele e8d0d7c2d7 登录页添加背景文字 3 years ago
巴林闲侠 1f3dc736fb Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 cfc281eddc yingshi state 3 years ago
wenlele d171c80b5a 添加新的模块 3 years ago
巴林闲侠 28756bee04 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 eb5bbc2758 萤石状态查询 3 years ago
wenlele 03fc11ead2 NVR添加成功后弹框跳转和不再提醒功能(根据用户判断是否提醒) 100% 3 years ago
巴林闲侠 de5d8f4283 videoOperationHistroyTime 3 years ago
巴林闲侠 06f310034e Merge branches 'dev_trial' and 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 7826cbc581 videoOperationTime 3 years ago
wenlele af10506c47 从安心云四个摄像头的添加跳转到视频平台对应的摄像头添加 3 years ago
巴林闲侠 b288d2156e 参数提示 3 years ago
巴林闲侠 b712b36be8 debug 3 years ago
巴林闲侠 7db8194212 参数提示 3 years ago
巴林闲侠 a421a1671e docker 3 years ago
巴林闲侠 5ad052f205 docker 3 years ago
巴林闲侠 6553443e41 引用错误 3 years ago
巴林闲侠 ee23345513 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 89749c7dc2 定时任务 3 years ago
wenlele d1dbeeccae 删掉一个不用的按钮 3 years ago
wenlele 26a9ff2b1f 冲突解决 3 years ago
wenlele 45761dd89b 解决冲突 3 years ago
wenlele 9958510f5c 从安心云四个摄像头的添加跳转到视频平台对应的摄像头添加 50% 3 years ago
巴林闲侠 4d6398b7e5 dockerfile 3 years ago
巴林闲侠 25902d6f22 jenkinsfile 3 years ago
巴林闲侠 e1dd11c50e sql脚本 3 years ago
巴林闲侠 aff86a6820 jenkinsfile 3 years ago
巴林闲侠 54d4227b59 登录背景mp4 3 years ago
巴林闲侠 65f427a12d sql脚本 3 years ago
巴林闲侠 1cd95e5ad3 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 0debdb7c1d docker 文件 ,部分播放器样式 3 years ago
wenlele 3430ecb5e2 萤石,级联,ipc添加修改时通过接口测试的功能完成 3 years ago
wenlele 2d9f850a9f NVR跳转传参功能完成,NVR摄像头获取视频流时交互样式 3 years ago
巴林闲侠 0594201af5 播放器样式 100% 3 years ago
wenlele 4cb212cbcf 级联摄像头的修改,表格项目信息 3 years ago
巴林闲侠 acc1f98e13 video play UI 88% 3 years ago
巴林闲侠 c0ec917f01 语音样式 3 years ago
巴林闲侠 5cc1e758ef Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 e3d08b97f0 云控样式 3 years ago
wenlele ab8b7bc8d1 级联摄像头修改50% 3 years ago
wenlele 6369ae4c5e Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
wenlele 53515f4a3d 表格设备名称的条件搜索 3 years ago
巴林闲侠 a15fb7be51 登出、配置 3 years ago
巴林闲侠 b86cbbd98e Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 2c64beb088 跳转 100% 3 years ago
wenlele fa9cabdef0 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
wenlele 68a7d60fa0 解决冲突 3 years ago
巴林闲侠 3b23a41e80 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
巴林闲侠 93b4754159 setAuthCrossLoading(false) 3 years ago
wenlele 0a210e2729 解决冲突 3 years ago
wenlele 4b87887396 添加级联摄像头 3 years ago
wenlele ec2b6fd849 添加级联摄像头 3 years ago
巴林闲侠 f0842505d1 暂时的ip配置 3 years ago
yuan_yi b75fee46ea 视频播放组件 40% 3 years ago
yuan_yi 0956159fc8 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
yuan_yi 12815a3cee mqtt 引入 40% 3 years ago
wenlele f468021def NVR添加修改的测试校验功能完成 3 years ago
yuan_yi dfcac5c2fb setAuthCrossLoading(false) 3 years ago
yuan_yi c8e54329a7 摄像头验证接口 3 years ago
yuan_yi d9739eed96 摄像头验证接口 3 years ago
yuan_yi 720f3e29ef setAuthCrossLoading(false) 3 years ago
yuan_yi a0e55f01e7 http://10.8.30.82 3 years ago
yuan_yi 51c2f84976 ifream visibility: 'hidden' 3 years ago
wenlele 7dea13915d 添加NVR摄像头,解决NVR页面部分自测问题 3 years ago
wenlele 8fd9b56cc7 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
wenlele b31d5a8c1d 添加NVR摄像头,解决NVR页面部分自测问题 3 years ago
yuan_yi 63e8968c10 AUTH CROSS 3 years ago
yuan_yi f8e5e30e57 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
yuan_yi 538fb4630a import react 3 years ago
wenlele 205f8f177e 萤石云摄像头和IPC摄像头的添加,摄像头删除 3 years ago
yuan_yi 4794d63ffe 监控中心 3 years ago
yuan_yi f7bd48bfaa 监控中心页 3 years ago
yuan_yi ce47dbadcf 完善sider选择逻辑 3 years ago
yuan_yi 77efe48d7c 回收站建设页 3 years ago
yuan_yi 377503cbcb 导出实操 3 years ago
yuan_yi 33e9e9b42a 导出实操 3 years ago
yuan_yi 9d1096583e ipc 摄像头添加 3 years ago
yuan_yi cffc4e95be 摄像头信息导出 3 years ago
yuan_yi 44606dfd4c nvr 信息导出 3 years ago
yuan_yi 8c5407347d xlsx简单文件通用下载 3 years ago
wenlele 345a2014db 解决冲突 3 years ago
yuan_yi 8589ead102 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
yuan_yi 6dbcca3fa9 导出通用接口 30% 3 years ago
yuan_yi e175e6ade5 导出通用接口 30% 3 years ago
wenlele 1fd486536b 解决了表格数据展现的BUG 3 years ago
yuan_yi b009f18bc2 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
yuan_yi 24c1294aad 安心云数据查询bug 3 years ago
wenlele e632b74387 数据修改 3 years ago
wenlele 6efe633899 添加骨架屏 3 years ago
deartibers 5a86abc520 摄像头添加 3 years ago
yuan_yi 8a9b814ea6 nvr table 3 years ago
wenlele 28e2133a7c Merge branch 'dev_trial' of ssh://gitea.free-sun.vip:2022/free-sun/FS-IOT into dev_trial 3 years ago
wenlele 3f3d357f1e 解决报错问题 3 years ago
yuan_yi efab54dbdc Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
yuan_yi 5919ec2850 摄像头萤石 3 years ago
wenlele 5c5334ff72 摄像头分页 3 years ago
wenlele cf93351a5a 表格查看和其它功能的数据对接 3 years ago
yuan_yi 5750c3872e 萤石摄像头添加 3 years ago
yuan_yi 96954a8a6e "babel-polyfill": "^6.26.0", 3 years ago
yuan_yi f638047ae7 webpack 3 years ago
yuan_yi 7801359f73 统一提示 3 years ago
yuan_yi fff6d76346 数据接口 3 years ago
yuan_yi a033e13a2e 设备筛选 3 years ago
yuan_yi ddc013104d 高德服务 3 years ago
yuan_yi c61d69a720 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
yuan_yi 79d4f26ec1 摄像头若干接口 3 years ago
deartibers a1c20552b1 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
deartibers 38f9bf91da 设备厂家必填 3 years ago
wenlele 70080015d7 表格设置和查询的修改 3 years ago
yuan_yi 64fa1bc28c AXY_API_URL 3 years ago
yuan_yi 1efb405f19 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
yuan_yi 974455267e 多平台请求抽象化 3 years ago
deartibers 20daa99a47 添加摄像头弹框 3 years ago
yuan_yi 54737dba51 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
yuan_yi 9dc3554c7d 摄像头获取接口 3 years ago
wenlele 99b8aca186 查询功能样式完成 3 years ago
wenlele dc0136a212 设备信息和头部样式 3 years ago
wenlele 70d75b164a 列表的设置选择问题 3 years ago
wenlele 1d6877ce2d Merge branch 'dev_trial' of ssh://gitea.free-sun.vip:2022/free-sun/FS-IOT into dev_trial 3 years ago
wenlele 068ccda661 摄像头列表设置完成 3 years ago
deartibers 47a80141b0 修改less文件位置 3 years ago
deartibers b4f2dc62e3 首页样式修改 3 years ago
yuan_yi 224bc45174 socket 优化 3 years ago
yuan_yi 9e8de3ff47 socket 优化 3 years ago
yuan_yi caa85094bd socket 优化 3 years ago
yuan_yi d1be1ce22d Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
yuan_yi 0c1b8f8d99 websocket 3 years ago
deartibers 25c88dea6b nvr新增刷新列表 3 years ago
wenlele f1f3a17be3 解决冲突 3 years ago
wenlele 870afbcd47 解决冲突 3 years ago
deartibers ee8881a661 修改nvr 3 years ago
wenlele b9ac39955c 表格功能完成 3 years ago
wenlele c23c764238 表格功能完成 3 years ago
deartibers 981dc894c4 nvr接口调试以及摄像头页面 3 years ago
yuan_yi 37779c29b9 注释以运行 3 years ago
yuan_yi 255466ef39 api -u 3 years ago
yuan_yi 12be6e0ba6 redis精简 3 years ago
yuan_yi 29de0083a4 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
yuan_yi 685f65affd 获取nvr的接口 3 years ago
wenlele 2bee6dc9a3 Merge branch 'dev_trial' of ssh://gitea.free-sun.vip:2022/free-sun/FS-IOT into dev_trial 3 years ago
wenlele 7113aaf672 表格设置完成 3 years ago
deartibers a45a0a9a50 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
deartibers c3a82d8979 添加摄像头页面 3 years ago
yuan_yi 4168be60d7 删除 AUTH 3 years ago
yuan_yi 8c4cffa8b5 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
yuan_yi 068c0a6e50 NVR 增删接口 3 years ago
deartibers bdbd43ef73 删除px 3 years ago
deartibers b1d1b4bfb5 nvr弹出框交互 3 years ago
wenlele 525d99c736 BUG修改 3 years ago
yuan_yi 90b6c11a3f auth 参数配置 3 years ago
yuan_yi 6f23175395 namePresent 3 years ago
yuan_yi 3e898f7a3e 登录登出 3 years ago
yuan_yi 85b64e95c4 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
yuan_yi d18dfa9c30 登录登出 3 years ago
deartibers 27594bada8 弹框修改 3 years ago
wenlele 5744fe52b8 表格修改 3 years ago
wenlele 6c712920c8 Merge branch 'dev_trial' of ssh://gitea.free-sun.vip:2022/free-sun/FS-IOT into dev_trial 3 years ago
wenlele b6ed892275 冲突更改 3 years ago
deartibers 1aad3c3bef 修改问题 3 years ago
wenlele 3f5742570b 表格 3 years ago
deartibers 00610e8c2a Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
deartibers 1ebc1f15ae 添加nvr弹框 3 years ago
yuan_yi f1c3748571 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
yuan_yi c494dce09e recycle_banner.mp4 3 years ago
deartibers 72f2e341b4 nvr管理头部弹框 3 years ago
yuan_yi 07f13a617f video banner 3 years ago
yuan_yi d192b64407 camera_banner 3 years ago
yuan_yi 333330d9c3 nvr banner 3 years ago
yuan_yi b122c1e11c Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
yuan_yi 06648ff786 DB模型 3 years ago
deartibers 33b42ed889 banner视频 3 years ago
wenlele a8f7b63cac 格式 3 years ago
wenlele 29a904dce8 冲突解决 3 years ago
wenlele 911e502bf4 Merge 3 years ago
wenlele 6e92a71354 测试 3 years ago
deartibers 67c41bd4d9 nvr头部 3 years ago
deartibers 15420f0c96 Merge branch 'dev_trial' of https://gitea.free-sun.vip/free-sun/FS-IOT into dev_trial 3 years ago
deartibers 26390a2a81 创建设备仓库文件 3 years ago
yuan_yi 40a022484b bg-img 3 years ago
yuan_yi 05e60fb524 fix utils 3 years ago
yuan_yi 052d73e231 fix utils 3 years ago
  1. 1
      .gitignore
  2. 13
      Dockerfilenew-api
  3. 17
      Dockerfilenew-web
  4. 92
      code/VideoAccess-VCMP/api/.vscode/launch.json
  5. 34
      code/VideoAccess-VCMP/api/Dockerfile
  6. 13
      code/VideoAccess-VCMP/api/Dockerfilenew
  7. 200
      code/VideoAccess-VCMP/api/app/lib/controllers/application/index.js
  8. 189
      code/VideoAccess-VCMP/api/app/lib/controllers/auth/index.js
  9. 573
      code/VideoAccess-VCMP/api/app/lib/controllers/camera/create.js
  10. 646
      code/VideoAccess-VCMP/api/app/lib/controllers/camera/index.js
  11. 589
      code/VideoAccess-VCMP/api/app/lib/controllers/mirror/index.js
  12. 465
      code/VideoAccess-VCMP/api/app/lib/controllers/nvr/index.js
  13. 130
      code/VideoAccess-VCMP/api/app/lib/controllers/status/alarm.js
  14. 289
      code/VideoAccess-VCMP/api/app/lib/controllers/status/index.js
  15. 410
      code/VideoAccess-VCMP/api/app/lib/controllers/status/push.js
  16. 23
      code/VideoAccess-VCMP/api/app/lib/controllers/vender/index.js
  17. 134
      code/VideoAccess-VCMP/api/app/lib/index.js
  18. 2
      code/VideoAccess-VCMP/api/app/lib/middlewares/api-log.js
  19. 233
      code/VideoAccess-VCMP/api/app/lib/middlewares/authenticator.js
  20. 50
      code/VideoAccess-VCMP/api/app/lib/middlewares/business-rest.js
  21. 72
      code/VideoAccess-VCMP/api/app/lib/models/application.js
  22. 35
      code/VideoAccess-VCMP/api/app/lib/models/ax_project.js
  23. 294
      code/VideoAccess-VCMP/api/app/lib/models/camera.js
  24. 34
      code/VideoAccess-VCMP/api/app/lib/models/camera_ability.js
  25. 52
      code/VideoAccess-VCMP/api/app/lib/models/camera_ability_bind.js
  26. 34
      code/VideoAccess-VCMP/api/app/lib/models/camera_kind.js
  27. 48
      code/VideoAccess-VCMP/api/app/lib/models/camera_remark.js
  28. 79
      code/VideoAccess-VCMP/api/app/lib/models/camera_status.js
  29. 119
      code/VideoAccess-VCMP/api/app/lib/models/camera_status_alarm.js
  30. 47
      code/VideoAccess-VCMP/api/app/lib/models/camera_status_log.js
  31. 52
      code/VideoAccess-VCMP/api/app/lib/models/camera_status_offline_log.js
  32. 79
      code/VideoAccess-VCMP/api/app/lib/models/camera_status_push_config.js
  33. 88
      code/VideoAccess-VCMP/api/app/lib/models/camera_status_push_log.js
  34. 51
      code/VideoAccess-VCMP/api/app/lib/models/camera_status_push_monitor.js
  35. 47
      code/VideoAccess-VCMP/api/app/lib/models/camera_status_push_receiver.js
  36. 47
      code/VideoAccess-VCMP/api/app/lib/models/camera_status_resolve.js
  37. 170
      code/VideoAccess-VCMP/api/app/lib/models/gb_camera.js
  38. 124
      code/VideoAccess-VCMP/api/app/lib/models/mirror.js
  39. 69
      code/VideoAccess-VCMP/api/app/lib/models/mirror_camera.js
  40. 47
      code/VideoAccess-VCMP/api/app/lib/models/mirror_filter.js
  41. 56
      code/VideoAccess-VCMP/api/app/lib/models/mirror_filter_group.js
  42. 65
      code/VideoAccess-VCMP/api/app/lib/models/mirror_tree.js
  43. 128
      code/VideoAccess-VCMP/api/app/lib/models/nvr.js
  44. 63
      code/VideoAccess-VCMP/api/app/lib/models/secret_yingshi.js
  45. 36
      code/VideoAccess-VCMP/api/app/lib/models/vender.js
  46. 26
      code/VideoAccess-VCMP/api/app/lib/routes/application/index.js
  47. 32
      code/VideoAccess-VCMP/api/app/lib/routes/auth/index.js
  48. 79
      code/VideoAccess-VCMP/api/app/lib/routes/camera/index.js
  49. 23
      code/VideoAccess-VCMP/api/app/lib/routes/index.js
  50. 26
      code/VideoAccess-VCMP/api/app/lib/routes/mirror/index.js
  51. 23
      code/VideoAccess-VCMP/api/app/lib/routes/nvr/index.js
  52. 52
      code/VideoAccess-VCMP/api/app/lib/routes/status/index.js
  53. 8
      code/VideoAccess-VCMP/api/app/lib/routes/vender/index.js
  54. 377
      code/VideoAccess-VCMP/api/app/lib/schedule/cameraStatePush.js
  55. 210
      code/VideoAccess-VCMP/api/app/lib/schedule/freshYingshiMsg.js
  56. 36
      code/VideoAccess-VCMP/api/app/lib/schedule/index.js
  57. 40
      code/VideoAccess-VCMP/api/app/lib/service/mqttVideoServer.js
  58. 67
      code/VideoAccess-VCMP/api/app/lib/service/paasRequest.js
  59. 41
      code/VideoAccess-VCMP/api/app/lib/service/redis.js
  60. 33
      code/VideoAccess-VCMP/api/app/lib/service/socket.js
  61. 171
      code/VideoAccess-VCMP/api/app/lib/utils/camera.js
  62. 16
      code/VideoAccess-VCMP/api/app/lib/utils/index.js
  63. 54
      code/VideoAccess-VCMP/api/app/lib/utils/oauth2.js
  64. 62
      code/VideoAccess-VCMP/api/app/lib/utils/push.js
  65. 158
      code/VideoAccess-VCMP/api/app/lib/utils/token4yingshi.js
  66. 82
      code/VideoAccess-VCMP/api/app/lib/utils/xlsxDownload.js
  67. 265
      code/VideoAccess-VCMP/api/config.js
  68. 9
      code/VideoAccess-VCMP/api/package.json
  69. 66
      code/VideoAccess-VCMP/api/sequelize-automate.config.js
  70. 15
      code/VideoAccess-VCMP/api/utils/forward-api.js
  71. 3
      code/VideoAccess-VCMP/script/.vscode/settings.json
  72. 543
      code/VideoAccess-VCMP/script/0.0.1/0_init_db.sql
  73. 14
      code/VideoAccess-VCMP/script/1.1.0/1.camera_remark.sql
  74. 17
      code/VideoAccess-VCMP/script/1.1.1/data/1_update_status_code_data/.vscode/launch.json
  75. 69
      code/VideoAccess-VCMP/script/1.1.1/data/1_update_status_code_data/index.js
  76. 16
      code/VideoAccess-VCMP/script/1.1.1/data/1_update_status_code_data/package.json
  77. BIN
      code/VideoAccess-VCMP/script/1.1.1/data/1_update_status_code_data/云录制错误码.xlsx
  78. 141
      code/VideoAccess-VCMP/script/1.1.1/data/2.insert_camera_status.sql
  79. 140
      code/VideoAccess-VCMP/script/1.1.1/schema/1.create_camera_status_table.sql
  80. 21
      code/VideoAccess-VCMP/script/1.1.2/schema/1.update_camera_status_config.sql
  81. 5
      code/VideoAccess-VCMP/script/1.1.2/schema/2.update_push_log.sql
  82. 4
      code/VideoAccess-VCMP/script/1.1.2/schema/3.update_camera_channel_no.sql
  83. 13
      code/VideoAccess-VCMP/script/1.1.2/schema/4.create_camera_status_offline_log.sql
  84. 19
      code/VideoAccess-VCMP/script/1.2.1/schema/1.create_application.sql
  85. 4
      code/VideoAccess-VCMP/script/1.3.0/schema/1.alert_gbcamera_did.sql
  86. 90
      code/VideoAccess-VCMP/script/1.3.0/schema/2.create_mirror_table.sql
  87. 17
      code/VideoAccess-VCMP/script/1.3.1/data/1_sync_camera_data/.vscode/launch.json
  88. 8
      code/VideoAccess-VCMP/script/1.3.1/data/1_sync_camera_data/Dockerfile
  89. 156
      code/VideoAccess-VCMP/script/1.3.1/data/1_sync_camera_data/index.js
  90. 18
      code/VideoAccess-VCMP/script/1.3.1/data/1_sync_camera_data/package.json
  91. 5
      code/VideoAccess-VCMP/script/1.3.2/schema/1.collect_all_camera_to_one_user.sql
  92. 33
      code/VideoAccess-VCMP/script/1.3.3/schema/1.create_camera_status_alarm.sql
  93. 10
      code/VideoAccess-VCMP/script/1.3.4/schema/1.alert_tables.sql
  94. 1
      code/VideoAccess-VCMP/script/1.3.5.1/data/1.update_secret_yingshi.sql
  95. 1
      code/VideoAccess-VCMP/script/1.3.5/data/1.camera_kindId_update.sql
  96. 17
      code/VideoAccess-VCMP/script/1.3.6/data/1_batch_entry_camera/.vscode/launch.json
  97. 21
      code/VideoAccess-VCMP/script/1.3.6/data/1_batch_entry_camera/Dockerfile
  98. 78
      code/VideoAccess-VCMP/script/1.3.6/data/1_batch_entry_camera/index.js
  99. 17
      code/VideoAccess-VCMP/script/1.3.6/data/1_batch_entry_camera/package.json
  100. BIN
      code/VideoAccess-VCMP/script/1.3.6/data/1_batch_entry_camera/摄像头信息对接.xlsx

1
.gitignore

@ -138,3 +138,4 @@ dist
*yarn.lock
*package-lock.json
*log/
*downloadFiles/

13
Dockerfilenew-api

@ -0,0 +1,13 @@
FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node:12-dev as builder
COPY ./code/VideoAccess-VCMP/api/ /var/app
WORKDIR /var/app
EXPOSE 8080
RUN npm config set registry=https://nexus.ngaiot.com/repository/fs-npm/
RUN echo "{\"time\":\"$BUILD_TIMESTAMP\",\"build\": \"$BUILD_NUMBER\",\"revision\": \"$SVN_REVISION_1\",\"URL\":\"$SVN_URL_1\"}" > version.json
RUN npm cache clean -f
RUN rm -rf package-lock.json
RUN npm install --registry https://nexus.ngaiot.com/repository/fs-npm/
FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node:12
COPY --from=builder --chown=node /var/app /home/node/app
WORKDIR /home/node/app
CMD ["node", "server.js"]

17
Dockerfilenew-web

@ -0,0 +1,17 @@
FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node:12-dev as builder
COPY ./code/VideoAccess-VCMP/web/ /var/app
WORKDIR /var/app
EXPOSE 8080
RUN npm config set registry=https://nexus.ngaiot.com/repository/fs-npm/
RUN echo "{\"time\":\"$BUILD_TIMESTAMP\",\"build\": \"$BUILD_NUMBER\",\"revision\": \"$SVN_REVISION_1\",\"URL\":\"$SVN_URL_1\"}" > version.json
RUN npm cache clean -f
RUN rm -rf package-lock.json
RUN npm install --registry https://nexus.ngaiot.com/repository/fs-npm/
RUN npm run build
RUN rm -rf client/src
RUN rm -rf node_modules
RUN npm install --production --registry https://nexus.ngaiot.com/repository/fs-npm/
FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node-16:7.22-06-20
COPY --from=builder --chown=node /var/app /home/node/app
WORKDIR /home/node/app
CMD ["node", "server.js"]

92
code/VideoAccess-VCMP/api/.vscode/launch.json

@ -1,41 +1,55 @@
{
// 使 IntelliSense
//
// 访: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "启动API",
"program": "${workspaceRoot}/server.js",
"env": {
"NODE_ENV": "development"
},
"args": [
"-p 14000",
"-f http://localhost:14000",
// "-g postgres://postgres:123@10.8.30.32:5432/yinjiguanli",
// "-g postgres://postgres:123456@221.230.55.27:5432/yinjiguanli",
// "-g postgres://FashionAdmin:123456@10.8.30.156:5432/SmartEmergency",
"-g postgres://postgres:Mantis1921@116.63.50.139:54327/smartYingji"
]
},
{
"type": "node",
"request": "launch",
"name": "run mocha",
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
"stopOnEntry": false,
"args": [
"app/test/*.test.js",
"--no-timeouts"
],
"cwd": "${workspaceRoot}",
"runtimeExecutable": null,
"env": {
"NODE_ENV": "development"
}
}
]
// 使 IntelliSense
//
// 访: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "启动API",
"program": "${workspaceRoot}/server.js",
"env": {
"NODE_ENV": "development"
},
"args": [
"-p 4000",
"-f http://localhost:4000",
// "-g postgres://postgres:123@10.8.30.166:5432/video-access",
"-g postgres://postgres:123@10.8.30.166:5432/video_access-dev",
"--redisHost 127.0.0.1",
"--redisPort 6379",
"--axyApiUrl http://127.0.0.1:4100",
// "--axyApiUrl http://10.8.30.161:31260",
"--iotAuthApi http://127.0.0.1:4200",
"--pomsApiUrl http://127.0.0.1:4600",
"--godUrl https://restapi.amap.com/v3",
"--godKey 21c2d970e1646bb9a795900dd00093ce",
"--mqttVideoServer mqtt://10.8.30.71:30883",
"--iotVideoServerUrl http://10.8.30.42:8082",
// "--iotVideoServerUrl http://10.8.30.59:8080",
"--cameraPlayWsHost ws://221.230.55.27:8081",
"--cameraPlayHttpFlvHost http://221.230.55.27:2020",
"--cameraPlayHlsHost http://221.230.55.27:8081",
"--cameraPlayRtmpHost rtmp://221.230.55.27:1935",
"--cameraPlayRtspHost rtsp://221.230.55.27:554"
]
},
{
"type": "node",
"request": "launch",
"name": "run mocha",
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
"stopOnEntry": false,
"args": [
"app/test/*.test.js",
"--no-timeouts"
],
"cwd": "${workspaceRoot}",
"runtimeExecutable": null,
"env": {
"NODE_ENV": "development"
}
}
]
}

34
code/VideoAccess-VCMP/api/Dockerfile

@ -1,7 +1,4 @@
FROM repository.anxinyun.cn/base-images/nodejs12:20.10.12.2
MAINTAINER liuxinyi "liu.xinyi@free-sun.com.cn"
FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node:12-dev as builder
COPY . /var/app
@ -9,6 +6,31 @@ WORKDIR /var/app
EXPOSE 8080
CMD ["-g", "postgres://FashionAdmin:123456@iota-m1:5433/SmartRiver", "--qnak", "5XrM4wEB9YU6RQwT64sPzzE6cYFKZgssdP5Kj3uu", "--qnsk", "w6j2ixR_i-aelc6I7S3HotKIX-ukMzcKmDfH6-M5", "--qnbkt", "anxinyun-test", "--qndmn", "http://test.resources.anxinyun.cn"]
RUN npm config set registry=http://10.8.30.22:7000
RUN echo "{\"time\":\"$BUILD_TIMESTAMP\",\"build\": \"$BUILD_NUMBER\",\"revision\": \"$SVN_REVISION_1\",\"URL\":\"$SVN_URL_1\"}" > version.json
RUN npm cache clean -f
RUN rm -rf package-lock.json
RUN npm install --registry http://10.8.30.22:7000
FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node:12
COPY --from=builder --chown=node /var/app /home/node/app
WORKDIR /home/node/app
CMD ["node", "server.js"]
# 旧版本构建方式
# FROM repository.anxinyun.cn/base-images/nodejs12:20.10.12.2
# COPY . /var/app
# WORKDIR /var/app
# EXPOSE 8080
# CMD ["-u", "http://localhost:8088"]
ENTRYPOINT [ "node", "server.js" ]
# ENTRYPOINT [ "node", "server.js" ]

13
code/VideoAccess-VCMP/api/Dockerfilenew

@ -0,0 +1,13 @@
FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node:12-dev as builder
COPY ./code/VideoAccess-VCMP/api/ /var/app
WORKDIR /var/app
EXPOSE 8080
RUN npm config set registry=https://nexus.ngaiot.com/repository/fs-npm/
RUN echo "{\"time\":\"$BUILD_TIMESTAMP\",\"build\": \"$BUILD_NUMBER\",\"revision\": \"$SVN_REVISION_1\",\"URL\":\"$SVN_URL_1\"}" > version.json
RUN npm cache clean -f
RUN rm -rf package-lock.json
RUN npm install --registry https://nexus.ngaiot.com/repository/fs-npm/
FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node:12
COPY --from=builder --chown=node /var/app /home/node/app
WORKDIR /home/node/app
CMD ["node", "server.js"]

200
code/VideoAccess-VCMP/api/app/lib/controllers/application/index.js

@ -0,0 +1,200 @@
'use strict';
const fs = require('fs');
const moment = require('moment')
const uuid = require('uuid');
async function check (ctx) {
try {
const { models } = ctx.fs.dc;
const { authorization } = ctx.headers;
const { utils: { oauthParseAuthHeader, oauthParseBody } } = ctx.app.fs
const keySplit = await oauthParseAuthHeader(authorization);
const existRes = await models.Application.findOne({
where: {
appKey: keySplit[0],
appSecret: keySplit[1],
}
})
if (!existRes) {
throw new Error('应用不存在');
} else if (existRes.forbidden) {
throw new Error('应用已被禁用');
}
ctx.status = 204;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = error
}
}
async function edit (ctx, next) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
const { models } = ctx.fs.dc;
const { userId } = ctx.fs.api
const data = ctx.request.body;
let findOption = { where: { name: data.name } }
if (data.appId) {
findOption.where.id = { $ne: data.appId }
}
const applicationRes = await models.Application.findOne(findOption)
if (applicationRes) {
throw '已有相同应用名称'
}
if (data.appId) {
// 修改
const storageData = Object.assign({}, data,)
await models.Application.update(storageData, {
where: {
id: data.appId
},
transaction
})
} else {
// 添加
const storageData = Object.assign({}, data, {
appKey: uuid.v4(),
appSecret: uuid.v4(),
createUserId: userId,
createTime: moment().format(),
forbidden: true
})
await models.Application.create(storageData, { transaction })
}
await transaction.commit();
ctx.status = 204;
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function get (ctx) {
try {
const models = ctx.fs.dc.models;
const { userId, token } = ctx.fs.api
const { limit, page, orderBy, orderDirection } = ctx.query
let findOption = {
where: {
// createUserId: userId,
},
order: [
[orderBy || 'id', orderDirection || 'DESC'] //查询排序
],
}
if (limit) {
findOption.limit = limit
}
if (page && limit) {
findOption.offset = page * limit
}
const applicationRes = await models.Application.findAndCountAll(findOption)
let createUserIds = new Set()
let cameraIds = []
for (let c of applicationRes.rows) {
cameraIds.push(c.id)
createUserIds.add(c.createUserId)
}
// 查用户信息
const createUserRes = await ctx.app.fs.authRequest.get(`user/${[...createUserIds].join(',') || -1}/message`, { query: { token } })
for (let { dataValues: n } of applicationRes.rows) {
const corCreateUser = createUserRes.find(u => u.id == n.createUserId)
n.createUser = {
name: corCreateUser ? corCreateUser.username : ''
}
}
ctx.status = 200;
ctx.body = {
total: applicationRes.count,
data: applicationRes.rows
}
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function put (ctx) {
try {
const { models } = ctx.fs.dc;
const data = ctx.request.body;
// TODO 向视频服务发送通知
// 库记录
await models.Application.update({
forbidden: data.forbidden
}, {
where: {
id: data.appId
}
})
ctx.status = 204;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function del (ctx, next) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
const models = ctx.fs.dc.models;
const { token } = ctx.fs.api
const { appId } = ctx.params
const { appKey } = await models.Application.findOne({
where: {
id: appId
},
}) || {}
await models.Application.destroy({
where: {
id: appId
},
transaction
})
await ctx.app.fs.authRequest.delete(`oauth2/token/invalidate_all`, {
query: { token, appKey }
})
await transaction.commit();
ctx.status = 204;
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
module.exports = {
edit,
get,
put,
del,
check,
};

189
code/VideoAccess-VCMP/api/app/lib/controllers/auth/index.js

@ -1,189 +0,0 @@
'use strict';
const Hex = require('crypto-js/enc-hex');
const MD5 = require('crypto-js/md5');
const moment = require('moment');
const uuid = require('uuid');
async function login(ctx, next) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
const models = ctx.fs.dc.models;
const params = ctx.request.body;
let password = Hex.stringify(MD5(params.password));
const userRes = await models.User.findOne({
where: {
username: params.username,
password: password,
delete: false,
},
attributes: { exclude: ['password'] },
include: [{
attributes: ["resourceId"],
model: models.UserResource
}]
});
if (!userRes) {
ctx.status = 400;
ctx.body = {
"message": "账号或密码错误"
}
} else if (!userRes.enable) {
ctx.status = 400;
ctx.body = { message: "该用户已被禁用" }
} else {
const token = uuid.v4();
let userRslt = Object.assign(userRes.dataValues, {
authorized: true,
token: token,
userResources: userRes.userResources.map(r => r.resourceId),
});
await models.UserToken.create({
token: token,
userInfo: userRslt,
expired: moment().add(30, 'days').format()
});
ctx.status = 200;
ctx.body = userRslt;
}
await transaction.commit();
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
"message": "登录失败"
}
}
}
/**
* 微信小程序登录
* @@requires.body {phone-手机号, password-密码} ctx
*/
async function wxLogin(ctx, next) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
const models = ctx.fs.dc.models;
const params = ctx.request.body;
let password = Hex.stringify(MD5(params.password));
const userRes = await models.User.findOne({
where: {
phone: params.phone,
password: password,
delete: false,
},
attributes: { exclude: ['password'] }
});
if (!userRes) {
ctx.status = 400;
ctx.body = { message: "手机号或密码错误" }
} else if (!userRes.enable) {
ctx.status = 400;
ctx.body = { message: "该用户已被禁用" }
} else {
const token = uuid.v4();
//获取用户关注区域信息
const departmentRes = await models.Department.findOne({ where: { id: userRes.departmentId } });
let attentionRegion = departmentRes;
while (attentionRegion.dependence && attentionRegion.type != 1) {
const departmentParent = await models.Department.findOne({ where: { id: attentionRegion.dependence } });
attentionRegion = {
...departmentParent.dataValues,
nextRegin: attentionRegion
}
}
//获取用户权限信息
const resourceRes = await models.UserResource.findAll({
where: {
userId: userRes.id
},
include: [{
model: models.Resource,
attributes: ['code', 'name'],
}],
attributes: []
});
let userRslt = Object.assign({
authorized: true,
token: token,
...userRes.dataValues
});
await models.UserToken.create({
token: token,
userInfo: userRslt,
expired: moment().add(30, 'day').format('YYYY-MM-DD HH:mm:ss')
}, { transaction: transaction });
ctx.status = 200;
ctx.body = Object.assign({
...userRslt,
userRegionType: departmentRes.type,//1-市级,2-区县级,3-乡镇级,4-村级
attentionRegion: attentionRegion,
resources: resourceRes.map(r => r.resource)
});
}
await transaction.commit();
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
"message": "登录失败"
}
}
}
async function logout(ctx) {
try {
const { token, code } = ctx.request.body;
const models = ctx.fs.dc.models;
await models.UserToken.destroy({
where: {
token: token,
},
});
ctx.status = 204;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
"message": "登出失败"
}
}
}
/**
* 微信小程序登出
* @request.body {token-用户登录Token} ctx
*/
async function wxLogout(ctx) {
try {
const { token } = ctx.request.body;
const models = ctx.fs.dc.models;
await models.UserToken.destroy({
where: {
token: token,
},
});
ctx.status = 204;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
"message": "登出失败"
}
}
}
module.exports = {
login,
wxLogin,
logout,
wxLogout
};

573
code/VideoAccess-VCMP/api/app/lib/controllers/camera/create.js

@ -0,0 +1,573 @@
'use strict';
const moment = require('moment')
async function verifyYingshi (ctx) {
let errMsg = '校验萤石摄像头信息失败'
const { utils: { verifyYingshiInfo } } = ctx.app.fs
try {
const { serialNo } = ctx.request.body;
await verifyYingshiInfo({ serialNo })
ctx.status = 204;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : errMsg
}
}
}
async function createYingshi (ctx) {
let errMsg = '萤石摄像头失败'
const transaction = await ctx.fs.dc.orm.transaction();
try {
const { models } = ctx.fs.dc
const { userId, token } = ctx.fs.api
const { utils: { verifyYingshiInfo } } = ctx.app.fs
const {
id, name, cloudControl, highDefinition, memoryCard,
voice, kindId, abilityId, rtmp, serialNo, longitude, latitude,
channelNo,definition
} = ctx.request.body;
let handleCameraId = id
errMsg = (handleCameraId ? '修改' : '添加') + errMsg
const beloneSecret = await verifyYingshiInfo({ serialNo })
const corGbYingshiRes = await models.GbCamera.findOne({
where: {
streamid: String(serialNo).toUpperCase(),
ipctype: 'yingshi'
}
})
let storageData = {
type: 'yingshi', name, cloudControl, highDefinition, memoryCard,
voice, longitude, latitude, kindId, rtmp,
serialNo: String(serialNo).toUpperCase(),
yingshiSecretId: beloneSecret.id,
gbId: corGbYingshiRes ? corGbYingshiRes.id : null,
channelNo,definition
}
if (handleCameraId) {
await models.Camera.update(storageData, {
where: {
id: handleCameraId,
},
transaction
})
} else {
storageData.createTime = moment().format()
storageData.createUserId = userId
storageData.forbidden = false
const createRes = await models.Camera.create(storageData, {
transaction
})
handleCameraId = createRes.id
}
await models.CameraAbilityBind.destroy({
where: {
cameraId: handleCameraId
},
transaction
})
if (abilityId && handleCameraId) {
let storageData = abilityId.map(aid => {
return {
cameraId: handleCameraId,
abilityId: aid
}
})
if (storageData.length) {
await models.CameraAbilityBind.bulkCreate(storageData, {
transaction
})
}
}
await transaction.commit();
ctx.status = 204;
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : errMsg
}
}
}
async function getNvrSteam (ctx) {
let errMsg = '获取 NVR 视频流失败'
try {
const { models } = ctx.fs.dc
const { streamId } = ctx.query
const { utils: { getGbCameraLevel3ByStreamId, getPlayUrl } } = ctx.app.fs
const nvrRes = await models.Nvr.findOne({
where: {
serialNo: streamId,
}
})
if (!nvrRes) {
errMsg = '没有找到已配置的 NVR 信息'
throw errMsg
}
const addedRes = await models.Camera.findAll({
attributes: ['id', 'name', 'serialNo', 'cloudControl'],
where: {
nvrId: nvrRes.id
},
include: [{
model: models.CameraRemark,
attributes: ['remark'],
order: [
['id', 'DESC']
],
}],
})
const cameraRes = await getGbCameraLevel3ByStreamId({ streamId })
for (let c of cameraRes) {
let preAdd = addedRes.find(ad => ad.dataValues.serialNo == c.streamid)
if (preAdd) {
c.dataValues.camera = preAdd.dataValues
} else {
c.dataValues.camera = null
}
c.dataValues.playUrl = await getPlayUrl({ topSerialNo: streamId, serialNo: c.dataValues.streamid })
}
ctx.status = 200;
ctx.body = cameraRes
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : errMsg
}
}
}
async function getNvrSteamById (ctx) {
try {
const { models } = ctx.fs.dc
const { nvrId } = ctx.params
const { utils: { getGbCameraLevel3ByStreamId } } = ctx.app.fs
const cameraRes = await getGbCameraLevel3ByStreamId({ streamId, errMsg })
const nvrRes = await models.Nvr.findOne({
where: {
id: nvrId
}
})
ctx.status = 200;
ctx.body = {
serialNo: nvrRes.dataValues.serialNo,
stream: cameraRes
}
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function createNvrCamera (ctx) {
let errMsg = ''
const transaction = await ctx.fs.dc.orm.transaction();
try {
const { models } = ctx.fs.dc
const { userId, token } = ctx.fs.api
const { utils: { getGbCameraLevel3ByStreamId } } = ctx.app.fs
const data = ctx.request.body
const { data: camera, serialNo } = data
if (!serialNo || !camera) {
errMsg = '参数错误'
throw errMsg
}
const nvrRes = await models.Nvr.findOne({
where: {
serialNo
}
})
if (!nvrRes) {
errMsg = '尚未添加相应的 NVR 设备'
throw errMsg
}
const addedCameraRes = await models.Camera.findAll({
where: {
nvrId: nvrRes.id
}
})
const allCameraRes = await getGbCameraLevel3ByStreamId({ streamId: serialNo })
let createData = []
let updateData = []
for (let c of camera) {
const corCamera = allCameraRes.find(ac => ac.streamid == c.streamid)
if (corCamera) {
const addedData = addedCameraRes.find(ac => ac.serialNo == c.streamid)
if (addedData) {
updateData.push({
...addedData.dataValues,
serialNo: c.streamid,
topSerialNo: serialNo,
name: c.name,
sip: corCamera.sipip,
cloudControl: c.cloudControl,
gbId: corCamera.id,
})
} else {
createData.push({
type: 'nvr',
serialNo: c.streamid,
topSerialNo: serialNo,
name: c.name,
sip: corCamera.sipip,
cloudControl: c.cloudControl,
nvrId: nvrRes.id,
createTime: moment().format(),
createUserId: userId,
forbidden: false,
gbId: corCamera.id,
})
}
} else {
errMsg = '参数错误'
throw errMsg
}
}
if (createData.length) {
await models.Camera.bulkCreate(createData, {
transaction
})
}
if (updateData.length) {
for (let u of updateData) {
await models.Camera.update(u, {
where: {
id: u.id
},
transaction
})
}
}
await transaction.commit();
ctx.status = 204;
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: errMsg ? undefined : errMsg
}
}
}
async function verifyIpcCamera (ctx) {
let errMsg = '校验萤石摄像头信息失败'
try {
const { utils: { verifyIpcInfo } } = ctx.app.fs
const { serialNo, } = ctx.request.body;
await verifyIpcInfo({ serialNo })
ctx.status = 204;
} catch (error) {
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : errMsg
}
}
}
async function createIpcCamera (ctx) {
const transaction = await ctx.fs.dc.orm.transaction();
let errMsg = ' IPC 网络摄像头失败'
try {
const { models } = ctx.fs.dc
const { userId, token } = ctx.fs.api
const { utils: { verifyIpcInfo } } = ctx.app.fs
const {
id, name, cloudControl, memoryCard,
voice, longitude, latitude, venderId, rtmp,
serialNo, kindId, abilityId,
} = ctx.request.body;
let handleCameraId = id
errMsg = (handleCameraId ? '修改' : '添加') + errMsg
let storageData = {
type: 'ipc', name, cloudControl, memoryCard,
voice, longitude, latitude, rtmp, venderId,
serialNo, kindId,
}
const gbCameraRes = await verifyIpcInfo({ serialNo })
storageData.sip = gbCameraRes.sipip
storageData.gbId = gbCameraRes.id
if (handleCameraId) {
await models.Camera.update(storageData, {
where: {
id: handleCameraId,
},
transaction
})
} else {
storageData.createTime = moment().format()
storageData.createUserId = userId
storageData.forbidden = false
const createRes = await models.Camera.create(storageData, {
transaction
})
handleCameraId = createRes.id
}
// 保存设备能力
await models.CameraAbilityBind.destroy({
where: {
cameraId: handleCameraId
},
transaction
})
if (abilityId && handleCameraId) {
let storageData = abilityId.map(aid => {
return {
cameraId: handleCameraId,
abilityId: aid
}
})
if (storageData.length) {
await models.CameraAbilityBind.bulkCreate(storageData, {
transaction
})
}
}
await transaction.commit();
ctx.status = 204;
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : errMsg
}
}
}
async function getCascadeSipList (ctx) {
try {
const { models } = ctx.fs.dc
const sipListRes = await models.GbCamera.findAll({
attributes: ['id', 'streamid', 'sipip'],
where: {
level: 0,
ipctype: '级联',
// sipip: { $ne: null }
}
})
ctx.status = 200;
ctx.body = sipListRes
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function verifyCascadeCamera (ctx) {
let errMsg = '校验级联摄像头信息失败'
try {
const { utils: { verifyCascadeInfo } } = ctx.app.fs
const { streamId } = ctx.request.body
await verifyCascadeInfo({ streamId })
ctx.status = 204;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : errMsg
}
}
}
async function getCascadeSteam (ctx) {
let errMsg = '获取级联摄像头视频流失败'
try {
const { models } = ctx.fs.dc
const { streamId } = ctx.query
const { utils: { getGbCameraLevel3ByStreamId, getPlayUrl } } = ctx.app.fs
const cascadeRes = await models.GbCamera.findOne({
where: {
streamid: streamId
}
})
if (!cascadeRes) {
errMsg = '没有找到已记录的级联摄像头信息'
throw errMsg
}
const cameraRes = await getGbCameraLevel3ByStreamId({ streamId: cascadeRes.streamid })
const allStreamid = cameraRes.map(c => c.streamid)
const addedRes = await models.Camera.findAll({
attributes: ['id', 'name', 'serialNo'],
where: {
serialNo: { $in: allStreamid }
},
include: [{
model: models.CameraRemark,
attributes: ['remark'],
order: [
['id', 'DESC']
],
}],
})
for (let c of cameraRes) {
let preAdd = addedRes.find(ad => ad.dataValues.serialNo == c.streamid)
if (preAdd) {
c.dataValues.camera = preAdd.dataValues
} else {
c.dataValues.camera = null
}
c.dataValues.playUrl = await getPlayUrl({ topSerialNo: cascadeRes.streamid, serialNo: c.dataValues.streamid })
}
ctx.status = 200;
ctx.body = cameraRes
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : errMsg
}
}
}
async function getCascadeCameraGrandParentSip (ctx) {
let errMsg = '查询级联设备失败'
try {
const { models } = ctx.fs.dc
const { cameraSerialNo } = ctx.query
const { utils: { getGbCameraLevel1ByStreamId } } = ctx.app.fs
const parent = await getGbCameraLevel1ByStreamId({
streamId: cameraSerialNo,
where: { ipctype: '级联' }
})
if (!parent) {
errMsg = `没有找到相应级联设备`
throw errMsg
}
ctx.status = 200;
ctx.body = parent
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : errMsg
}
}
}
async function createCascadeCamera (ctx) {
let errMsg = '添加级联摄像头信息失败'
const transaction = await ctx.fs.dc.orm.transaction();
try {
const { models } = ctx.fs.dc
const { userId, token } = ctx.fs.api
const { streamId, camera = [], externalDomain, cascadeType } = ctx.request.body
const { utils: { getGbCameraLevel3ByStreamId, verifyCascadeInfo } } = ctx.app.fs
const cameraParentRes = await verifyCascadeInfo({ streamId })
const allCameraRes = await getGbCameraLevel3ByStreamId({ streamId: cameraParentRes.streamid })
const allCameraIds = allCameraRes.map(c => c.id)
const addedCmeraRes = allCameraIds.length ?
await models.Camera.findAll({
where: {
type: 'cascade',
gbId: { $in: allCameraIds },
delete: false
}
}) : []
let addData = []
let updateData = []
for (let c of camera) {
const corGbCamera = allCameraRes.find(ac => ac.id == c.id)
if (!corGbCamera) {
errMsg = '数据信息错误'
throw errMsg
}
let storageData = {
externalDomain,
cascadeType,
serialNo: corGbCamera.streamid,
topSerialNo: cameraParentRes.streamid,
sip: corGbCamera.sipip,
name: c.name,
gbId: corGbCamera.id,
}
const added = addedCmeraRes.find(ac => ac.gbId == corGbCamera.id)
if (added) {
let data = {
...storageData,
id: added.id,
}
updateData.push(data)
await models.Camera.update(data, {
where: { id: added.id },
transaction
})
} else {
addData.push({
...storageData,
type: 'cascade',
createTime: moment().format(),
createUserId: userId,
forbidden: false
})
}
}
await models.Camera.bulkCreate(addData, {
transaction
})
await transaction.commit();
ctx.status = 204;
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : errMsg
}
}
}
module.exports = {
verifyYingshi,
createYingshi,
getNvrSteam,
getNvrSteamById,
createNvrCamera,
verifyIpcCamera,
createIpcCamera,
getCascadeSipList,
verifyCascadeCamera,
getCascadeSteam,
getCascadeCameraGrandParentSip,
createCascadeCamera,
};

646
code/VideoAccess-VCMP/api/app/lib/controllers/camera/index.js

@ -0,0 +1,646 @@
'use strict';
const fs = require('fs');
const moment = require('moment')
async function getCameraProject (ctx, next) {
try {
const models = ctx.fs.dc.models;
const { limit, page, orderBy, orderDirection, keyword, abilityId, type, venderId, nvrId, externalDomain, state, serialNo } = ctx.query
const { userId, token } = ctx.fs.api
const { utils: { getPlayUrl } } = ctx.app.fs
let findOption = {
attributes: { exclude: ['delete', 'recycleTime',] },
where: {
createUserId: userId,
recycleTime: null,
delete: false
},
order: [
[orderBy || 'id', orderDirection || 'DESC']
],
include: [{
model: models.CameraKind
}, {
model: models.Nvr,
where: nvrId ? {
id: nvrId
} : {},
required: Boolean(nvrId),
attributes: ['id', 'name', 'serialNo']
}, {
model: models.SecretYingshi,
attributes: ['token']
}, {
model: models.CameraRemark,
attributes: ['id', 'remark'],
order: ['id']
}],
distinct: true
}
let abilityFind = {
model: models.CameraAbility
}
let gbCameraOption = {
model: models.GbCamera,
attributes: ['id', 'online', 'playUrl', 'did'],
required: false
}
if (limit) {
findOption.limit = limit
}
if (page && limit) {
findOption.offset = page * limit
}
if (keyword) {
// findOption.where.name = { $like: `%${keyword}%` }
findOption.where.$or = [
{
name: { $like: `%${keyword}%` }
},
// {
// serialNo: { $like: `%${keyword}%` }
// }
]
}
if (type) {
findOption.where.type = type
}
if (venderId) {
findOption.where.venderId = venderId
}
if (abilityId) {
abilityFind.where = {
abilityId: abilityId
}
}
if (externalDomain) {
findOption.where.externalDomain = externalDomain
}
if (serialNo) {
findOption.where['$or'] = {
serialNo: { $in: serialNo.split(',') },
topSerialNo: { $in: serialNo.split(',') }
}
}
if (state) {
if (state == 'DISABLED') {
findOption.where.forbidden = true
} else {
findOption.where.forbidden = false
const onLineMap = {
ON: ['ON', 'ONLINE'],
OFF: ['OFF'],
// UNKONW: [],
// DISABLED: []
}
let unknowState = []
for (let k in onLineMap) {
unknowState = unknowState.concat(onLineMap[k])
}
gbCameraOption.where = {
online: state == 'UNKONW' ?
{ $notIn: unknowState }
: { $in: onLineMap[state] }
}
gbCameraOption.required = true
}
}
findOption.include.push(gbCameraOption)
findOption.include.push(abilityFind)
const cameraRes = await models.Camera.findAll(findOption)
// const cameraRes = await models.Camera.findAndCountAll(findOption)
delete findOption.order
delete findOption.limit
delete findOption.offset
delete findOption.attributes
const total = await models.Camera.count(findOption)
let cameraIds = []
let createUserIds = new Set()
for (let c of cameraRes) {
cameraIds.push(c.dataValues.id)
createUserIds.add(c.dataValues.createUserId)
}
// 查在安心云绑定的数据
const axbindCameraRes = []
// await ctx.app.fs.axyRequest.get('vcmp/camera/project', { query: { token, cameraId: cameraIds.join(',') } })
// 查对应创建者信息
const corUsers =
createUserIds.size ?
await ctx.app.fs.authRequest.get(`user/${[...createUserIds].join(',') || -1}/message`, {
query: { token }
})
: []
for (let { dataValues: camera } of cameraRes) {
const corBindCamera = axbindCameraRes.filter(b => b.cameraId == camera.id)
camera.station = corBindCamera.reduce((station, c) => {
return station.concat.apply(station, c.stations)
}, [])
const corUser = corUsers.find(u => u.id == camera.createUserId)
camera.createUser = {
namePresent: corUser ? corUser.namePresent : ''
}
// if (camera.type != 'yingshi') {
// const playUrl = await getPlayUrl({ topSerialNo: camera.topSerialNo, serialNo: camera.serialNo })
// camera.gbCamera.dataValues.playUrl = playUrl
// }
}
ctx.status = 200;
ctx.body = {
total: total,
data: cameraRes
}
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function getCamera (ctx) {
try {
const { models } = ctx.fs.dc;
const { cameraId } = ctx.query
const cameraRes = await models.Camera.findAll({
attributes: { exclude: ['delete', 'recycleTime',] },
where: {
id: { $in: cameraId.split(',') }
},
include: [{
model: models.CameraAbility
}, {
model: models.CameraKind
}, {
model: models.Vender
}, {
model: models.SecretYingshi,
attributes: ['token'],
required: false
}, {
model: models.GbCamera,
attributes: ['id', 'online', 'playUrl', 'did'],
required: false
}, {
model: models.CameraRemark,
attributes: ['remark'],
order: [
['id', 'DESC']
],
}]
})
ctx.status = 200;
ctx.body = cameraRes
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function detail (ctx) {
let errMsg = `获取摄像头详情失败`
try {
const { models } = ctx.fs.dc;
const { cameraId } = ctx.params
const { userId, token } = ctx.fs.api
const { utils: { getPlayUrl } } = ctx.app.fs
const cameraRes = await models.Camera.findOne({
where: {
id: cameraId
},
include: {
model: models.GbCamera,
attributes: ['id', 'online', 'playUrl'],
required: false
}
})
if (!cameraRes) {
throw errMsg
}
const cameraProject = []
// await ctx.app.fs.axyRequest.get('vcmp/camera/project', { query: { token, cameraId: cameraRes.id } })
const bindStations = []
for (let c of cameraProject) {
for (let s of c.stations) {
bindStations.push(s)
}
}
const corUser = await ctx.app.fs.authRequest.get(`user/${cameraRes.createUserId}/message`, { query: { token } })
let rslt = {
...cameraRes.dataValues,
station: bindStations,
createUser: {
namePresent: corUser.length && corUser[0].namePresent ? corUser[0].namePresent : ''
}
}
if (cameraRes.type != 'yingshi') {
rslt.gbCamera.playUrl = await getPlayUrl({ topSerialNo: cameraRes.topSerialNo, serialNo: cameraRes.serialNo })
}
ctx.status = 200;
ctx.body = rslt
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: errMsg
}
}
}
async function getCameraListAll (ctx) {
try {
const { models } = ctx.fs.dc;
const { userId, token } = ctx.fs.api
const cameraRes = await models.Camera.findAll({
attributes: { exclude: ['delete', 'recycleTime', 'rtmp', 'createUserId', 'nvrId', 'kindId', 'yingshiSecretId', 'gbId'] },
order: [['id', 'DESC']],
where: {
createUserId: userId,
delete: false,
recycleTime: null,
},
include: [{
model: models.SecretYingshi,
attributes: ['token'],
required: false
}, {
model: models.GbCamera,
attributes: ['id', 'online', 'playUrl', 'did'],
required: false
}, {
model: models.CameraRemark,
attributes: ['remark'],
order: [
['id', 'DESC']
],
}]
})
ctx.status = 200;
ctx.body = cameraRes
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function getCmaeraUniqueConfig (ctx) {
// 为 李玉 python 摄像头状态查询的摄像头列表查询
// 获取所有已配置的序列号+通道号唯一的摄像头
try {
const { models } = ctx.fs.dc;
const sequelize = ctx.fs.dc.orm;
// TODO: 目前只获取 yingshi 的
const cameraRes = await sequelize.query(`
SELECT DISTINCT ON ("serial_no", "channel_no")
camera.id,
"camera"."serial_no" AS "serialNo",
"camera"."type" AS "type",
"camera"."channel_no" AS "channelNo",
"secretYingshi"."token" AS "yingshiToken",
camera_status_offline_log."status" AS "status",
camera_status_offline_log."time" AS "updateTime"
FROM "camera" AS "camera"
LEFT JOIN "secret_yingshi" AS "secretYingshi"
ON "camera"."yingshi_secret_id" = "secretYingshi"."id"
LEFT JOIN (
SELECT camera_id, MAX(time) AS time FROM camera_status_offline_log GROUP BY camera_id
) AS offlineLogMax
ON offlineLogMax."camera_id" = "camera"."id"
LEFT JOIN camera_status_offline_log
ON camera_status_offline_log.time = offlineLogMax.time
WHERE "camera"."delete" = false
AND "camera"."type" = 'yingshi'
AND "camera"."recycle_time" IS NULL;
`)
ctx.status = 200;
ctx.body = cameraRes[0]
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function banned (ctx) {
try {
const { models } = ctx.fs.dc;
const data = ctx.request.body;
// TODO 向视频服务发送通知
// 库记录
await models.Camera.update({
forbidden: data.forbidden
}, {
where: {
id: data.cameraId
}
})
ctx.status = 204;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function del (ctx) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
const { models } = ctx.fs.dc;
const { cameraId } = ctx.params
const { token } = ctx.fs.api
await models.MirrorCamera.destroy({
where: {
cameraId: cameraId
},
transaction
})
await models.CameraStatusPushMonitor.destroy({
where: {
cameraId: cameraId
},
transaction
})
await models.CameraAbilityBind.destroy({
where: {
cameraId: cameraId
},
transaction
})
await models.CameraRemark.destroy({
where: {
cameraId: cameraId
},
transaction
})
await models.Camera.destroy({
where: {
id: cameraId
},
transaction
})
if (cameraId) {
// await ctx.app.fs.axyRequest.delete('vcmp/camera/project', { query: { token, cameraId: cameraId } })
}
await transaction.commit();
ctx.status = 204;
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function cameraExport (ctx) {
try {
const { models } = ctx.fs.dc
const { userId, token } = ctx.fs.api
const { utils: { simpleExcelDown } } = ctx.app.fs
const header = [{
title: "设备名称",
key: "name",
}, {
title: "设备厂家",
key: "vender",
}, {
title: "接入类型",
key: "type",
}, {
title: "设备状态",
key: "state",
}, {
title: "云台支持",
key: "cloudControl",
}, {
title: "内存卡信息",
key: "memoryCard",
}, {
title: "设备创建时间",
key: "createTime",
}, {
title: "设备添加账号",
key: "createUser",
}, {
title: "项目名称",
key: "projectName",
}, {
title: "pcode",
key: "pcode",
}, {
title: "结构物",
key: "structure",
}, {
title: "测点",
key: "stationName",
}, {
title: "监测因素",
key: "factor",
},];
const cameraRes = await models.Camera.findAll({
where: {
createUserId: userId,
recycleTime: null,
delete: false
},
include: [{
model: models.CameraAbility
}, {
model: models.CameraKind
}, {
model: models.Vender
}]
})
let cameraIds = []
let createUserIds = new Set()
for (let c of cameraRes) {
cameraIds.push(c.dataValues.id)
createUserIds.add(c.dataValues.createUserId)
}
// 查在安心云绑定的数据
const axbindCameraRes = []
// await ctx.app.fs.axyRequest.get('vcmp/camera/project', { query: { token, cameraId: cameraIds.join(',') } })
// 查对应创建者信息
const corUsers = await ctx.app.fs.authRequest.get(`user/${[...createUserIds].join(',') || -1}/message`, { query: { token } })
let exportData = []
let typeMap = {
yingshi: '萤石云平台摄像头',
nvr: 'NVR摄像头',
ipc: 'IPC 网络摄像头',
cascade: '不明厂家',
}
for (let { dataValues: camera } of cameraRes) {
camera.vender = camera.vender ? camera.vender.name : ''
camera.type = typeMap[camera.type]
const corUser = corUsers.find(u => u.id == camera.createUserId)
camera.createUser = corUser ? corUser.username : ''
let stationName = new Set(),
projectName = new Set(),
pcode = new Set(),
structure = new Set(),
factor = new Set()
const corBindCamera = axbindCameraRes.find(b => b.cameraId == camera.id)
if (corBindCamera) {
for (let station of corBindCamera.stations) {
stationName.add(station.name)
factor.add(station.factor.name)
structure.add(station.structure.name)
for (let project of station.structure.projects) {
projectName.add(project.name)
pcode.add(project.url)
}
}
}
camera.stationName = [...stationName].join('\r\n')
camera.factor = [...factor].join('\r\n')
camera.projectName = [...projectName].join('\r\n')
camera.pcode = [...pcode].join('\r\n')
camera.structure = [...structure].join('\r\n')
exportData.push(camera)
}
const fileName = `摄像头信息列表_${userId}_${moment().format('YYYYMMDDHHmmss')}` + '.csv'
const filePath = await simpleExcelDown({ data: exportData, header, fileName: fileName })
const fileData = fs.readFileSync(filePath);
ctx.status = 200;
ctx.set('Content-Type', 'application/x-xls');
ctx.set('Content-disposition', 'attachment; filename=' + encodeURI(fileName));
ctx.body = fileData;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function getAbility (ctx) {
try {
const { models } = ctx.fs.dc;
const abilityRes = await models.CameraAbility.findAll()
ctx.status = 200;
ctx.body = abilityRes
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function getKind (ctx) {
try {
const { models } = ctx.fs.dc;
const kindRes = await models.CameraKind.findAll()
ctx.status = 200;
ctx.body = kindRes
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function remark (ctx) {
const transaction = await ctx.fs.dc.orm.transaction();
let errMsg = undefined
try {
const { models } = ctx.fs.dc
const { cameraId, remark, } = ctx.request.body;
const cameraRes = await models.Camera.findOne({
where: {
id: cameraId
}
})
if (!cameraRes) {
errMsg = '摄像头不存在'
}
await models.CameraRemark.destroy({
where: {
cameraId
},
transaction
})
await models.CameraRemark.bulkCreate(remark.map(r => {
return {
cameraId,
remark: r
}
}), {
transaction
})
await transaction.commit();
ctx.status = 204;
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: errMsg
}
}
}
module.exports = {
getCameraProject,
getCamera,
getCameraListAll,
getCmaeraUniqueConfig,
detail,
banned,
del,
cameraExport,
getAbility,
getKind,
remark,
};

589
code/VideoAccess-VCMP/api/app/lib/controllers/mirror/index.js

@ -0,0 +1,589 @@
'use strict';
const moment = require('moment')
async function edit (ctx) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
const sequelize = ctx.fs.dc.orm;
const { models } = ctx.fs.dc;
const { userId } = ctx.fs.api
const data = ctx.request.body
const timeNow = moment()
const { mirrorId, tree = [], filterGroup = [], listOpen = false ,check=[] } = data
let mirrorId_ = mirrorId
if (mirrorId_) {
let upData = {
template: data.template,
updateTime: timeNow.format(),
title: data.title,
showHeader: Boolean(data.showHeader),
listOpen:listOpen,
check:check
}
if (data.publish) {
upData.publish = true
upData.publishTime = timeNow.format()
}
await models.Mirror.update(upData, {
where: {
id: mirrorId_
},
transaction
})
// 除 Mirror 外的信息全删除并重建
await models.MirrorCamera.destroy({
where: {
mirrorId: mirrorId_
},
transaction
})
await sequelize.query('DELETE FROM mirror_filter WHERE group_id IN (SELECT id FROM mirror_filter_group WHERE mirror_id=?)', {
replacements: [mirrorId_],
transaction
})
await models.MirrorFilterGroup.destroy({
where: {
mirrorId: mirrorId_
},
transaction
})
await models.MirrorTree.destroy({
where: {
mirrorId: mirrorId_
},
transaction
})
} else {
// 创建 镜像信息
let createData = {
template: data.template,
createUser: userId,
createTime: timeNow.format(),
title: data.title,
showHeader: Boolean(data.showHeader),
publish: false,
mid: timeNow.format(`ssmmHHDDMMYY${Math.floor(Math.random() * 89 + 10)}`),
listOpen: listOpen,
check:check
}
if (data.publish) {
createData.publish = true
createData.publishTime = timeNow.format()
}
const mirrorCreateRes = await models.Mirror.create(createData, {
transaction
})
mirrorId_ = mirrorCreateRes.id
}
let cameraStorage = {}
const dealTree = async (child, lastNodeStorageId, level) => {
// 递归 tree 获得扁平信息
let curLevel = level
for (let c of child) {
if (c.cameraId) {
// 摄像头节点为末端节点
// 不创建节点
if (cameraStorage[c.cameraId]) {
cameraStorage[c.cameraId].treeIds.push(lastNodeStorageId)
} else {
cameraStorage[c.cameraId] = {
treeIds: [lastNodeStorageId],
filterIds: []
}
}
} else {
const treeStorageRes = await models.MirrorTree.create({
name: c.label,
level: curLevel,
dependence: lastNodeStorageId,
mirrorId: mirrorId_
}, {
transaction
})
if (c.children) {
await dealTree(c.children, treeStorageRes.id, curLevel + 1)
}
}
}
}
await dealTree(tree, null, 1)
for (let g of filterGroup) {
// 遍历创建筛选分组
const filterGroupStorageRes = await models.MirrorFilterGroup.create({
name: g.name,
forbidden: g.forbidden,
mirrorId: mirrorId_
}, {
transaction
})
if (g.filters) {
for (let f of g.filters) {
// 遍历创建筛选项
const filterStorageRes = await models.MirrorFilter.create({
name: f.name,
groupId: filterGroupStorageRes.id
}, {
transaction
})
for (let cid of f.cameraIds) {
if (cameraStorage[cid]) {
cameraStorage[cid].filterIds.push(filterStorageRes.id)
}
}
}
}
}
let bulkCreateCameraD = []
for (let cid in cameraStorage) {
bulkCreateCameraD.push({
cameraId: cid,
...cameraStorage[cid],
mirrorId: mirrorId_
})
}
if (bulkCreateCameraD.length) {
await models.MirrorCamera.bulkCreate(bulkCreateCameraD, {
transaction
})
}
await transaction.commit();
ctx.status = 204;
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function refreshId (ctx) {
try {
const { models } = ctx.fs.dc;
const { mirrorId } = ctx.params
if (!mirrorId) throw '更新镜像服务ID失败';
const nextId = moment().format(`ssmmHHDDMMYY${Math.floor(Math.random() * 89 + 10)}`)
await models.Mirror.update({
mid: nextId
}, {
where: {
id: mirrorId
}
})
ctx.status = 200;
ctx.body = { mid: nextId }
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: error`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function list (ctx) {
try {
const { models } = ctx.fs.dc;
const { userId, token } = ctx.fs.api
let startTime = moment()
const mirrorRes = await models.Mirror.findAll({
attributes: {
exclude: ['showHeader']
},
where: {},
order: [['id', 'DESC']]
})
console.log(`S1 = ${moment().diff(startTime, 'milliseconds')}`);
let createUserIds = new Set()
for (let c of mirrorRes) {
createUserIds.add(c.dataValues.createUser)
}
console.log(`S1 = ${moment().diff(startTime, 'milliseconds')}`);
// 查对应创建者信息
const corUsers = await ctx.app.fs.authRequest.get(`user/${[...createUserIds].join(',') || -1}/message`, { query: { token } })
console.log(`S3 = ${moment().diff(startTime, 'milliseconds')}`);
for (let { dataValues: mirror } of mirrorRes) {
const corUser = corUsers.find(u => u.id == mirror.createUser)
mirror.createUser = corUser ? corUser.username : ''
}
console.log(`S4 = ${moment().diff(startTime, 'milliseconds')}`);
ctx.status = 200;
ctx.body = mirrorRes
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function get (ctx) {
try {
// 下次这样的关关联联要用数据库关联 !!!
// 不然逻辑好绕啊
const { models } = ctx.fs.dc;
const { userId } = ctx.fs.api
const { mid } = ctx.params
const { check } = ctx.query
// 查当前镜像的全部信息
const mirrorRes = await models.Mirror.findOne({
attributes: {
exclude: ['createUser']
},
order: [['id', 'ASC']],
where: {
mid: mid
},
include: [{
model: models.MirrorTree,
required: false
}, {
model: models.MirrorFilterGroup,
attributes: {
exclude: ['mirrorId']
},
required: false,
include: [{
model: models.MirrorFilter,
attributes: {
exclude: ['groupId']
},
required: false
}]
}, {
model: models.MirrorCamera,
required: false,
include: {
model: models.Camera,
attributes: {
exclude: ['rtmp', 'venderId', 'createTime', 'recycleTime', 'delete', 'createUserId', 'nvrId', 'kindId', 'yingshiSecretId', 'gbId']
},
include: [{
model: models.SecretYingshi,
attributes: ['token']
}, {
model: models.GbCamera,
attributes: ['id', 'online', 'playUrl',],
required: false
}, {
model: models.CameraRemark,
attributes: ['remark'],
order: [
['id', 'DESC']
],
}]
}
}]
})
let returnData
if (mirrorRes) {
if (check && !mirrorRes.publish) {
throw '尚未发布'
}
const { mirrorCameras, mirrorFilterGroups, mirrorTrees } = mirrorRes.dataValues
returnData = {
...mirrorRes.dataValues,
tree: [],
filterGroup: []
}
// 反向构建出树节点
const buildTree = (treeNodes = [], lastLevelKey = '') => {
const nextKeyPre = lastLevelKey ? lastLevelKey + '-' : lastLevelKey
treeNodes.forEach((tn, index) => {
const curKey = nextKeyPre + index
let child = JSON.parse(JSON.stringify(mirrorTrees.filter(mt => mt.dependence == tn.id)))
let cameras = mirrorCameras.filter(mc => mc.treeIds.includes(tn.id))
if (cameras.length) {
// 有摄像头 向下再创建一级节点
tn.children = cameras.map((c, cIndex) => {
return {
label: c.dataValues.camera.name,
key: curKey + '-' + cIndex,
cameraId: c.dataValues.cameraId,
camera: c.dataValues.camera
}
})
} else {
tn.children = child
buildTree(child, curKey)
}
tn.label = tn.name
tn.key = curKey
delete tn.name
delete tn.level
delete tn.dependence
delete tn.mirrorId
})
}
let tree = JSON.parse(JSON.stringify(mirrorTrees.filter(t => t.level == 1)))
buildTree(tree)
returnData.tree = tree
// 构建筛选分组及筛选项
for (let { dataValues: g } of mirrorFilterGroups) {
for (let { dataValues: f } of g.mirrorFilters) {
f.cameraIds = (mirrorCameras.filter(mc => mc.filterIds.includes(f.id)) || []).map(mc => mc.cameraId)
}
g.filters = g.mirrorFilters
delete g.mirrorFilters
}
returnData.filterGroup = mirrorFilterGroups
delete returnData.mirrorCameras
delete returnData.mirrorFilterGroups
delete returnData.mirrorTrees
} else {
throw '没有查询到对应的镜像服务'
}
ctx.status = 200;
ctx.body = returnData
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function del (ctx) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
const { models } = ctx.fs.dc;
const { userId } = ctx.fs.api
const { mirrorId } = ctx.params
if (!mirrorId) throw '镜像服务删除失败';
const sequelize = ctx.fs.dc.orm;
// 除 Mirror 外的信息全删除并重建
await models.MirrorCamera.destroy({
where: {
mirrorId: mirrorId
},
transaction
})
await sequelize.query('DELETE FROM mirror_filter WHERE group_id IN (SELECT id FROM mirror_filter_group WHERE mirror_id=?)', {
replacements: [mirrorId],
transaction
})
await models.MirrorFilterGroup.destroy({
where: {
mirrorId: mirrorId
},
transaction
})
await models.MirrorTree.destroy({
where: {
mirrorId: mirrorId
},
transaction
})
await models.Mirror.destroy({
where: {
id: mirrorId
},
transaction
})
await transaction.commit();
ctx.status = 204;
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function publish (ctx) {
try {
const { models } = ctx.fs.dc;
const { userId } = ctx.fs.api
const { mirrorId } = ctx.params
if (!mirrorId) throw '发布镜像服务失败';
await models.Mirror.update({
publish: true,
publishTime: moment().format()
}, {
where: {
id: mirrorId
}
})
ctx.status = 204;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function copy (ctx) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
const { models } = ctx.fs.dc;
const { userId } = ctx.fs.api
const { mirrorId } = ctx.params
const timeNow = moment()
// 查当前镜像的全部信息
const mirrorRes = await models.Mirror.findOne({
attributes: {
exclude: ['createUser']
},
order: [['id', 'ASC']],
where: {
id: mirrorId
},
include: [{
model: models.MirrorTree,
required: false
}, {
model: models.MirrorFilterGroup,
required: false,
include: [{
model: models.MirrorFilter,
required: false
}]
}, {
model: models.MirrorCamera,
required: false,
}]
})
if (mirrorRes) {
const { mirrorCameras, mirrorFilterGroups, mirrorTrees } = mirrorRes.dataValues
const newMirrorRes = await models.Mirror.create({
template: mirrorRes.template,
createUser: userId,
createTime: timeNow.format(),
title: mirrorRes.title + '-副本',
showHeader: mirrorRes.showHeader,
publish: mirrorRes.publish,
mid: timeNow.format(`ssmmHHDDMMYY${Math.floor(Math.random() * 89 + 10)}`)
}, {
transaction
})
const newMirrorId = newMirrorRes.id
let cameraStorage = {}
// 重新存一遍树节点
const storageTree = async (node, lastNodeStorageId) => {
for (let n of node) {
// 创建新节点
const newTreeNodeStorageRes = await models.MirrorTree.create({
name: n.name,
level: n.level,
dependence: lastNodeStorageId,
mirrorId: newMirrorId
}, {
transaction
})
// 筛选老节点所下辖的摄像头
let corCamera = mirrorCameras.filter((mc) => mc.treeIds.includes(n.id))
for (let c of corCamera) {
// 为摄像头存新的节点id
if (cameraStorage[c.cameraId]) {
cameraStorage[c.cameraId].treeIds.push(newTreeNodeStorageRes.id)
} else {
cameraStorage[c.cameraId] = {
treeIds: [newTreeNodeStorageRes.id],
filterIds: []
}
}
}
const nextNode = mirrorTrees.filter(mt => mt.dependence == n.id)
if (nextNode.length) {
await storageTree(nextNode)
}
}
}
let treeLevelOne = mirrorTrees.filter(mt => mt.level == 1)
await storageTree(treeLevelOne, null)
// 重新存一遍筛选分组、筛选项
for (let { dataValues: g } of mirrorFilterGroups) {
const newGroupStorageRes = await models.MirrorFilterGroup.create({
name: g.name,
forbidden: g.forbidden,
mirrorId: newMirrorId
}, {
transaction
})
for (let { dataValues: f } of g.mirrorFilters) {
const newFilterStorageRes = await models.MirrorFilter.create({
name: f.name,
groupId: newGroupStorageRes.id
}, {
transaction
})
let corCamera = mirrorCameras.filter((mc) => mc.filterIds.includes(f.id))
for (let c of corCamera) {
// 为摄像头存新的节点id
if (cameraStorage[c.cameraId]) {
cameraStorage[c.cameraId].filterIds.push(newFilterStorageRes.id)
}
}
}
}
let bulkCreateCameraD = []
for (let cid in cameraStorage) {
bulkCreateCameraD.push({
cameraId: cid,
...cameraStorage[cid],
mirrorId: newMirrorId
})
}
if (bulkCreateCameraD.length) {
await models.MirrorCamera.bulkCreate(bulkCreateCameraD, {
transaction
})
}
}
await transaction.commit();
ctx.status = 204;
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
module.exports = {
edit,
refreshId,
list,
get,
del,
publish,
copy,
};

465
code/VideoAccess-VCMP/api/app/lib/controllers/nvr/index.js

@ -0,0 +1,465 @@
'use strict';
const fs = require('fs');
const moment = require('moment')
async function edit (ctx, next) {
let errMsg = '添加 NVR 设备失败'
const transaction = await ctx.fs.dc.orm.transaction();
try {
const { utils: { getGbCameraLevel3ByStreamId } } = ctx.app.fs
const { models } = ctx.fs.dc;
const { userId } = ctx.fs.api
const data = ctx.request.body;
const { serialNo } = data
const nvrGbRes = await models.GbCamera.findOne({
where: {
streamid: serialNo,
level: 0,
// ipctype: 'nvr'
}
})
if (!nvrGbRes) {
errMsg = '没有找到已接入的 NVR 服务信息'
throw errMsg
}
const channelRes = await getGbCameraLevel3ByStreamId({ streamId: serialNo, errMsg })
// 或取其他服务信息
const nvrData = {
channelCount: channelRes.length,
port: 8080,
sip: nvrGbRes.sipip,
}
if (data.id) {
// 修改
const storageData = Object.assign({}, data, nvrData)
await models.Nvr.update(storageData, {
where: {
id: data.id
},
transaction
})
} else {
// 添加
const storageData = Object.assign({}, data, nvrData, {
createTime: moment().format(),
createUserId: userId,
delete: false,
})
await models.Nvr.create(storageData, { transaction })
}
await transaction.commit();
ctx.status = 204;
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: errMsg
}
}
}
async function verify (ctx, next) {
let errMsg = '校验 NVR 设备信息失败'
try {
const { models } = ctx.fs.dc;
const { userId } = ctx.fs.api
const data = ctx.request.body;
const { serialNo } = data
const nvrGbRes = await models.GbCamera.findOne({
where: {
streamid: serialNo,
level: 0,
// ipctype: 'nvr'
}
})
if (!nvrGbRes) {
errMsg = '没有找到已接入的 NVR 服务信息'
throw errMsg
}
ctx.status = 204;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
resaon: errMsg
}
}
}
async function get (ctx) {
try {
const models = ctx.fs.dc.models;
const { userId, token } = ctx.fs.api
const { limit, page, orderBy, orderDirection, keyword, venderId, state } = ctx.query
let findOption = {
attributes: { exclude: ['delete'] },
where: {
createUserId: userId,
delete: false,
},
order: [
[orderBy || 'id', orderDirection || 'DESC']
],
include: [],
distinct: true
}
let gbNvrOption = {
model: models.GbCamera,
as: 'gbNvr',
// attributes: ['id', 'address', 'name', 'online'],
required: false
}
if (limit) {
findOption.limit = limit
}
if (page && limit) {
findOption.offset = page * limit
}
if (keyword) {
findOption.where.name = { $like: `%${keyword}%` }
}
if (venderId) {
findOption.where.venderId = venderId
}
if (state) {
const onLineMap = {
ON: ['ON', 'ONLINE'],
OFF: ['OFF'],
// UNKONW: [],
DISABLED: []
}
let unknowState = []
for (let k in onLineMap) {
unknowState = unknowState.concat(onLineMap[k])
}
gbNvrOption.where = {
online: state == 'UNKONW' ?
{ $notIn: unknowState }
: { $in: onLineMap[state] }
}
gbNvrOption.required = true
}
findOption.include.push(gbNvrOption)
const nvrRes = await models.Nvr.findAndCountAll(findOption)
const nvrIds = nvrRes.rows.map(r => r.id)
const cameraRes = await models.Camera.findAll({
where: {
nvrId: { $in: nvrIds }
}
})
let createUserIds = new Set()
let cameraIds = []
for (let c of cameraRes) {
cameraIds.push(c.id)
createUserIds.add(c.createUserId)
}
// 查在安心云绑定的数据
const axbindCameraRes = []
// cameraIds.length ?
// await ctx.app.fs.axyRequest.get('vcmp/camera/project', { query: { token, cameraId: cameraIds.join(',') } })
// : []
// 查用户信息
const createUserRes = await ctx.app.fs.authRequest.get(`user/${[...createUserIds].join(',') || -1}/message`, { query: { token } })
for (let { dataValues: n } of nvrRes.rows) {
const corCameras = cameraRes.filter(c => c.nvrId == n.id)
const corBind = axbindCameraRes.filter(b => corCameras.some(c => c.id == b.cameraId))
const corCreateUser = createUserRes.find(u => u.id == n.createUserId)
n.createUser = {
name: corCreateUser ? corCreateUser.username : ''
}
if (corBind.length) {
n.station = []
for (let c of corBind) {
n.station = n.station.concat(c.stations)
}
} else {
n.station = []
}
}
ctx.status = 200;
ctx.body = {
total: nvrRes.count,
data: nvrRes.rows
}
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function del (ctx, next) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
const models = ctx.fs.dc.models;
const { userId, token } = ctx.fs.api
const { nvrId } = ctx.params
await models.Nvr.destroy({
where: {
id: nvrId
},
transaction
})
const cameraRes = await models.Camera.findAll({
where: {
nvrId
}
})
const cameraIds = cameraRes.map(c => c.id)
await models.Camera.destroy({
where: {
nvrId,
}
})
if (cameraIds.length) {
// await ctx.app.fs.axyRequest.delete('vcmp/camera/project', { query: { token, cameraId: cameraIds.join(',') } })
}
await transaction.commit();
ctx.status = 204;
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function detail (ctx) {
let errMsg = '获取 NVR 详情失败'
try {
const models = ctx.fs.dc.models;
const { userId, token } = ctx.fs.api
const { nvrId } = ctx.params
const nvrRes = await models.Nvr.findOne({
attributes: { exclude: ['delete'] },
where: {
id: nvrId
},
include: [{
model: models.Vender
}, {
model: models.GbCamera,
as: 'gbNvr',
// attributes: ['id', 'address', 'name', 'online', 'registerTime', 'updateTime'],
required: false
}]
})
if (!nvrRes) {
throw errMsg
}
// 查询对应的后端服务相关信息
const cameraRes = await models.Camera.findAll({
attributes: ['id', 'name', 'channelName', 'serialNo', 'rtmp'],
where: {
nvrId
}
})
let cameras = []
let cameraIds = []
for (let c of cameraRes) {
cameraIds.push(c.id)
cameras.push(c.dataValues)
}
const cameraProject = []
// await ctx.app.fs.axyRequest.get('vcmp/camera/project', { query: { token, cameraId: cameraIds.join(',') } })
const bindStations = []
for (let c of cameraProject) {
for (let s of c.stations) {
bindStations.push(s)
}
}
const corUser = await ctx.app.fs.authRequest.get(`user/${nvrRes.createUserId || -1}/message`, { query: { token } })
// const serverDRes = (await ctx.app.fs.videoServerRequest.post(`gb28181/api/plugins`) || '')
const serverDRes = (await ctx.app.fs.videoServerRequest.post(`gateway/plugins`) || '')
const serverDArr = JSON.parse(serverDRes.replace(/'/g, '"')) || []
const serverDConfig = serverDArr.find(s => s.Name == 'GB28181')
let serveD = {}
if (serverDConfig) {
const { Config } = serverDConfig
let ConfigArr = Config.split('\n')
for (let c of ConfigArr) {
let config = c.split(' = ')
if (config.length == 2) {
serveD[config[0].trim()] = config[1].trim().replace(/\"/g, '')
}
}
}
let nvrDetail = {
...nvrRes.dataValues,
station: bindStations,
camera: cameras,
createUser: {
namePresent: corUser.length ? corUser[0].namePresent : ''
},
accessWay: 'GB/T28181',
accessInfo: serveD
}
ctx.status = 200;
ctx.body = nvrDetail
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = { message: errMsg }
}
}
async function nvrExport (ctx) {
try {
const { models } = ctx.fs.dc
const { userId, token } = ctx.fs.api
const { utils: { simpleExcelDown } } = ctx.app.fs
const header = [{
title: "设备名称",
key: "name",
}, {
title: "SIP地址",
key: "sip",
}, {
title: "设备厂家",
key: "vender",
}, {
title: "添加账号",
key: "createUser",
}, {
title: "通道数",
key: "channelCount",
}, {
title: "端口",
key: "port",
}, {
title: "设备状态",
key: "state",
}, {
title: "创建时间",
key: "createTime",
}, {
title: "项目名称",
key: "projectName",
}, {
title: "pcode",
key: "pcode",
}, {
title: "结构物",
key: "structure",
},];
const nvrRes = await models.Nvr.findAll({
where: {
createUserId: userId,
},
include: [{
model: models.Vender
}]
})
const nvrIds = nvrRes.map(r => r.id)
const cameraRes = await models.Camera.findAll({
where: {
nvrId: { $in: nvrIds }
}
})
let createUserIds = new Set()
let cameraIds = []
for (let c of cameraRes) {
cameraIds.push(c.id)
createUserIds.add(c.createUserId)
}
// 查在安心云绑定的数据
const axbindCameraRes = []
// cameraIds.length ?
// await ctx.app.fs.axyRequest.get('vcmp/camera/project', { query: { token, cameraId: cameraIds.join(',') } })
// : []
// 查用户信息
const createUserRes = await ctx.app.fs.authRequest.get(`user/${[...createUserIds].join(',') || -1}/message`, { query: { token } })
let exportData = []
for (let { dataValues: n } of nvrRes) {
const corCameras = cameraRes.filter(c => c.nvrId == n.id)
const corBind = axbindCameraRes.filter(b => corCameras.some(c => c.id == b.cameraId))
const corCreateUser = createUserRes.find(u => u.id == n.createUserId)
n.createUser = {
name: corCreateUser ? corCreateUser.username : ''
}
n.vender = n.vender ? n.vender.name : ''
n.createTime = moment(n.createTime).format('YYYY-MM-DD HH:mm:ss')
let projectName = new Set(),
pcode = new Set(),
structure = new Set();
if (corBind.length) {
for (let c of corBind) {
for (let station of c.stations) {
structure.add(station.structure.name)
for (let project of station.structure.projects) {
projectName.add(project.name)
pcode.add(project.url)
}
}
}
}
n.projectName = [...projectName].join('\r\n')
n.pcode = [...pcode].join('\r\n')
n.structure = [...structure].join('\r\n')
exportData.push(n)
}
const fileName = `NVR信息列表_${userId}_${moment().format('YYYYMMDDHHmmss')}` + '.csv'
const filePath = await simpleExcelDown({ data: exportData, header, fileName: fileName })
const fileData = fs.readFileSync(filePath);
ctx.status = 200;
ctx.set('Content-Type', 'application/x-xls');
ctx.set('Content-disposition', 'attachment; filename=' + encodeURI(fileName));
ctx.body = fileData;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
module.exports = {
edit,
verify,
get,
del,
detail,
nvrExport,
};

130
code/VideoAccess-VCMP/api/app/lib/controllers/status/alarm.js

@ -0,0 +1,130 @@
'use strict';
const moment = require('moment');
async function record (ctx) {
try {
const { models } = ctx.fs.dc;
const { statusCode, description = '', platform = 'yingshi', serialNo, channelNo } = ctx.request.body;
// statusCode == 0 是自动恢复
const isRestore = statusCode == 0
let statusRes = isRestore ? null :
await models.CameraStatus.findOne({
where: {
status: statusCode,
platform,
}
})
let alarmRes = null;
if (!statusRes && !isRestore) {
// 没有这种告警状态就新建一个
statusRes = await models.CameraStatus.create({
platform: platform,
status: statusCode,
describe: description,
forbidden: false,
})
} else {
let findWhere = {
confirmTime: null,
serialNo,
channelNo,
platform,
}
if (isRestore) {
} else {
findWhere.description = description
}
if (statusRes) {
findWhere.statusId = statusRes.id
}
alarmRes = await models.CameraStatusAlarm[isRestore ? 'findAll' : 'findOne']({
where: findWhere
})
}
if (
(!isRestore && alarmRes)
|| (isRestore && alarmRes && alarmRes.length)
) {
let updateD = {
updateTime: moment().format('YYYY-MM-DD HH:mm:ss'),
}
if (isRestore) {
updateD.autoRestore = true
updateD.confirmTime = moment().format('YYYY-MM-DD HH:mm:ss')
}
await models.CameraStatusAlarm.update(updateD, {
where: {
id: {
$in: isRestore ? alarmRes.map(a => a.id) : [alarmRes.id]
}
}
})
} else if (!isRestore) {
const createTime = moment().format('YYYY-MM-DD HH:mm:ss');
alarmRes = await models.CameraStatusAlarm.create({
statusId: statusRes.id,
description,
createTime: createTime,
serialNo,
channelNo,
platform,
})
try {
ctx.app.fs.pomsRequest.post(`alarm/video/added_log`, {
data: {
serial_no: serialNo,
channel_no: channelNo,
create_time: createTime,
description: description,
status_id: statusRes.id,
}
})
} catch (error) {
ctx.fs.logger.error(` error: ${error}`);
}
}
ctx.status = 204;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function confirm (ctx) {
try {
const { models } = ctx.fs.dc;
const { alarmId, content } = ctx.request.body;
await models.CameraStatusAlarm.update({
confirm: content,
confirmTime: moment().format(),
}, {
where: {
id: { $in: alarmId },
confirmTime: null
}
})
ctx.status = 204;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
module.exports = {
record,
confirm,
};

289
code/VideoAccess-VCMP/api/app/lib/controllers/status/index.js

@ -0,0 +1,289 @@
'use strict';
const moment = require('moment')
async function get (ctx) {
try {
const models = ctx.fs.dc.models;
const { userId, token } = ctx.fs.api
const { limit, page, orderBy, orderDirection, keyword, forbidden, paraphraseCustom } = ctx.query
const sequelize = ctx.fs.dc.ORM;
let findOption = {
attributes: {
include: [
[sequelize.fn('COUNT', sequelize.col('cameraStatusLogs.id')), 'logCount']
]
},
where: {},
order: [
[orderBy || 'id', orderDirection || 'DESC']
],
distinct: true,
subQuery: false,
group: [
'cameraStatus.id',
'cameraStatusLogs.status_id',
// 'cameraStatusResolves.id'
],
include: [
// {
// model: models.CameraStatusResolve,
// attributes: { exclude: ['statusId'] },
// required: false,
// duplicating: true
// },
{
model: models.CameraStatusLog,
attributes: [],
duplicating: false,
required: false,
}
],
}
if (orderBy) {
if (orderBy == 'logCount') {
findOption.order = sequelize.literal(`"logCount" ${orderDirection || 'DESC'}`)
}
}
if (limit) {
findOption.limit = limit
}
if (page && limit) {
findOption.offset = page * limit
}
if (keyword) {
findOption.where['$or'] = {
describe: {
$like: `%${keyword}%`
},
paraphrase: {
$like: `%${keyword}%`
},
paraphraseCustom: {
$like: `%${keyword}%`
},
}
}
if (forbidden) {
if (forbidden === 'true') {
findOption.where.forbidden = true
} else if (forbidden === 'false') {
findOption.where.forbidden = false
}
}
if (paraphraseCustom) {
if (paraphraseCustom === 'true') {
findOption.where.paraphraseCustom = {
$or: [{
$eq: null
}, {
$eq: ''
}]
}
} else if (paraphraseCustom === 'false') {
findOption.where.paraphraseCustom = {
$and: [{
$ne: null
}, {
$ne: ''
}]
}
}
}
const statusRes = await models.CameraStatus.findAll(findOption)
delete findOption.order
delete findOption.limit
delete findOption.offset
delete findOption.attributes
delete findOption.group
const count = await models.CameraStatus.count(findOption)
const statusIds = statusRes.map(r => r.id)
const statusResolveRes = await models.CameraStatusResolve.findAll({
where: {
statusId: {
$in: statusIds
}
}
})
for (let { dataValues: s } of statusRes) {
const corResolve = statusResolveRes.filter(r => r.statusId === s.id)
s.resolve = corResolve
}
ctx.status = 200;
ctx.body = {
count,
rows: statusRes,
}
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function getSimpleAll (ctx) {
try {
const models = ctx.fs.dc.models;
const statusRes = await models.CameraStatus.findAll({
attributes: ['id', 'platform', 'status', 'describe'],
})
ctx.status = 200;
ctx.body = statusRes
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function banned (ctx) {
try {
const { models } = ctx.fs.dc;
const data = ctx.request.body;
// 库记录
await models.CameraStatus.update({
forbidden: data.forbidden
}, {
where: {
id: data.statusId
}
})
ctx.status = 204;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function paraphraseCustom (ctx) {
try {
const models = ctx.fs.dc.models;
const { userId, token } = ctx.fs.api
const data = ctx.request.body
await models.CameraStatus.update({
paraphraseCustom: data.paraphrase,
}, {
where: {
id: { $in: data.statusId }
}
})
ctx.status = 204;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function resolveEdit (ctx) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
const models = ctx.fs.dc.models;
const { userId, token } = ctx.fs.api
const data = ctx.request.body
await models.CameraStatusResolve.destroy({
where: {
statusId: data.statusId
},
transaction
})
const bulkCreateD = data.resolve.map(r => {
return {
statusId: data.statusId,
resolve: r,
}
})
console.log(bulkCreateD);
await models.CameraStatusResolve.bulkCreate(bulkCreateD,
{ transaction }
)
await transaction.commit();
ctx.status = 204;
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
console.log('err.name', error.name);
console.log('err.message', error.message);
console.log('err.errors', error.errors);
ctx.status = 400;
ctx.body = {}
}
}
async function statusCheck (ctx) {
try {
const models = ctx.fs.dc.models;
const { userId, token } = ctx.fs.api
const { status, platform, describe } = ctx.query
if (!status || !platform) {
throw 'status and platform is required'
}
const statusRes = await models.CameraStatus.findOne({
where: {
status,
platform,
},
include: [{
model: models.CameraStatusResolve,
attributes: { exclude: ['statusId'] },
required: false,
}],
})
if (!statusRes && describe) {
await models.CameraStatus.create({
status, platform, describe
})
}
ctx.status = 200;
ctx.body = statusRes
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function statusRecord (ctx) {
try {
const models = ctx.fs.dc.models;
ctx.status = 20;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
module.exports = {
get,
getSimpleAll,
banned,
paraphraseCustom,
resolveEdit,
statusCheck,
statusRecord,
};

410
code/VideoAccess-VCMP/api/app/lib/controllers/status/push.js

@ -0,0 +1,410 @@
'use strict';
const moment = require('moment')
async function edit (ctx) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
const models = ctx.fs.dc.models;
const { userId, token } = ctx.fs.api
const {
configId, name, pushWay, noticeWay, timing,
receiver, cameraId
} = ctx.request.body;
let configId_ = configId
let receiverSorted = receiver.sort()
let cameraIdSorted = cameraId.sort()
let noticeWaySorted = noticeWay.sort()
let editDataExist = false
// 判重
const configAllRes = await models.CameraStatusPushConfig.findAll({
include: [{
model: models.CameraStatusPushMonitor,
attributes: ['cameraId'],
required: false,
duplicating: true,
}, {
model: models.CameraStatusPushReceiver,
attributes: ['receiver'],
duplicating: false,
required: false,
},]
})
for (let c of configAllRes) {
if (configId_ && c.id == configId_) {
editDataExist = true
continue
} else if (c.name == name) {
throw '已有同名称配置信息'
}
const cReceiver = c.cameraStatusPushReceivers.map(r => r.receiver)
const cCameraId = c.cameraStatusPushMonitors.map(m => m.cameraId)
const cReceiverSorted = cReceiver.sort()
const cCameraIdSorted = cCameraId.sort()
if (
receiverSorted.join(',') == cReceiverSorted.join(',') && cameraIdSorted.join(',') == cCameraIdSorted.join(',') &&
c.pushWay == pushWay &&
c.noticeWay.sort().join(',') == noticeWaySorted.join(',') &&
(
(!c.timing && !timing) ||
c.timing == timing
)
) {
throw '已有相同配置信息'
}
}
let config = {
name, pushWay, noticeWay, timing
}
if (configId) {
if (!editDataExist) {
throw '参数错误'
} else {
// DO UPDATE
await models.CameraStatusPushConfig.update(config, {
where: { id: configId },
transaction
})
await models.CameraStatusPushReceiver.destroy({
where: { configId },
transaction
})
await models.CameraStatusPushMonitor.destroy({
where: { configId },
transaction
})
}
} else {
// DO CREATE
config.createUser = userId
config.forbidden = false
const createConfigRes = await models.CameraStatusPushConfig.create(config, {
transaction
})
configId_ = createConfigRes.id
}
if (receiver && receiver.length) {
await models.CameraStatusPushReceiver.bulkCreate(
receiver.map(item => ({
configId: configId_,
receiver: item,
})),
{
transaction
}
)
}
if (cameraId && cameraId.length) {
await models.CameraStatusPushMonitor.bulkCreate(
cameraId.map(item => ({
configId: configId_,
cameraId: item,
})),
{
transaction
}
)
}
await transaction.commit();
ctx.status = 204;
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function getStatusPushList (ctx) {
try {
const models = ctx.fs.dc.models;
const sequelize = ctx.fs.dc.ORM;
const { userId, token } = ctx.fs.api
const { limit, page, orderBy, orderDirection, name, pushWay } = ctx.query
let findOption = {
where: {},
order: [
[orderBy || 'id', orderDirection || 'DESC']
]
}
if (limit) {
findOption.limit = limit
}
if (page && limit) {
findOption.offset = page * limit
}
if (name) {
findOption.where['$or'] = {
name: {
$like: `%${name}%`
},
}
}
if (pushWay) {
findOption.where.pushWay = pushWay
}
const configLimitRes = await models.CameraStatusPushConfig.findAll(findOption)
delete findOption.limit
delete findOption.offset
const configIds = configLimitRes.map(c => c.id)
findOption.where.id = { $in: configIds }
findOption.order = [
[orderBy || 'id', orderDirection || 'DESC']
]
findOption.include = [
{
model: models.CameraStatusPushMonitor,
attributes: ['cameraId'],
required: false,
duplicating: true,
include: [{
model: models.Camera,
attributes: ['name'],
}]
},
{
model: models.CameraStatusPushReceiver,
attributes: ['receiver'],
duplicating: false,
required: false,
},
]
const configRes = await models.CameraStatusPushConfig.findAll(findOption)
delete findOption.order
delete findOption.include
delete findOption.where.id
const count = await models.CameraStatusPushConfig.count(findOption)
// 获取所有id
const pushLogCountRes = await models.CameraStatusPushLog.findAll({
attributes: [
'pushConfigId',
[sequelize.fn('COUNT', sequelize.col('id')), 'count']
],
where: {
pushConfigId: { $in: configIds }
},
group: ['pushConfigId']
})
for (let { dataValues: c } of configRes) {
c.monitorCount = c.cameraStatusPushMonitors.length;
let corLofCount = pushLogCountRes.find(p => p.dataValues.pushConfigId == c.id)
c.logCount = corLofCount ? corLofCount.dataValues.count : 0
delete c.cameraStatusPushLogs
}
ctx.status = 200;
ctx.body = {
count: count,
rows: configRes
}
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function banned (ctx) {
try {
const models = ctx.fs.dc.models;
const { userId, token } = ctx.fs.api
const data = ctx.request.body;
await models.CameraStatusPushConfig.update({
forbidden: data.forbidden
}, {
where: {
id: data.configId
}
})
ctx.status = 204;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function del (ctx) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
const models = ctx.fs.dc.models;
const { userId, token } = ctx.fs.api
const { configId } = ctx.params;
await models.CameraStatusPushReceiver.destroy({
where: {
configId
},
transaction
})
await models.CameraStatusPushMonitor.destroy({
where: {
configId
},
transaction
})
await models.CameraStatusPushConfig.destroy({
where: {
id: configId
},
transaction
})
await transaction.commit();
ctx.status = 204;
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
async function copy (ctx) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
const models = ctx.fs.dc.models;
const { userId, token } = ctx.fs.api
const { configId } = ctx.params;
const configRes = await models.CameraStatusPushConfig.findOne({
where: {
id: configId
},
include: [
{
model: models.CameraStatusPushMonitor,
attributes: ['cameraId'],
required: false,
duplicating: true
},
{
model: models.CameraStatusPushLog,
attributes: [],
duplicating: false,
required: false,
},
{
model: models.CameraStatusPushReceiver,
attributes: ['receiver'],
duplicating: false,
required: false,
},
],
})
if (!configRes) {
throw '参数错误'
}
let copyConfig = JSON.parse(JSON.stringify(configRes.dataValues))
let returnConfig = JSON.parse(JSON.stringify(configRes.dataValues))
delete copyConfig.id
let cameraStatusPushMonitors = copyConfig.cameraStatusPushMonitors
let cameraStatusPushReceiver = copyConfig.cameraStatusPushReceivers
delete copyConfig.cameraStatusPushMonitors
delete copyConfig.cameraStatusPushReceivers
copyConfig.name += '-副本'
copyConfig.createUser = userId
copyConfig.forbidden = true
let newConfig = await models.CameraStatusPushConfig.create(copyConfig, {
transaction
})
if (cameraStatusPushMonitors && cameraStatusPushMonitors.length) {
await models.CameraStatusPushMonitor.bulkCreate(
cameraStatusPushMonitors.map(item => ({
configId: newConfig.id,
cameraId: item.cameraId,
})),
{
transaction
}
)
}
if (cameraStatusPushReceiver && cameraStatusPushReceiver.length) {
await models.CameraStatusPushReceiver.bulkCreate(
cameraStatusPushReceiver.map(item => ({
configId: newConfig.id,
receiver: item.receiver,
})),
{
transaction
}
)
}
returnConfig.id = newConfig.id
await transaction.commit();
ctx.status = 200;
ctx.body = returnConfig
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function pushLog (ctx) {
try {
const models = ctx.fs.dc.models;
const { userId, token } = ctx.fs.api
const { configId } = ctx.params;
const sequelize = ctx.fs.dc.ORM;
const logRes = await models.CameraStatusPushLog.findAll({
where: {
pushConfigId: configId
},
order: [['time', 'DESC']],
})
let cameraIds = new Set()
for (let lr of logRes) {
for (let c of lr.camera) {
cameraIds.add(c)
}
}
let cameraRes = await models.Camera.findAll({
attributes: ['id', 'name'],
where: {
id: { $in: Array.from(cameraIds) }
}
})
for (let lr of logRes) {
let camera = cameraRes.filter(c => lr.camera.some(lrc => lrc == c.id))
lr.camera = camera
}
ctx.status = 200;
ctx.body = logRes
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
module.exports = {
edit, getStatusPushList, banned, del, copy, pushLog
};

23
code/VideoAccess-VCMP/api/app/lib/controllers/vender/index.js

@ -0,0 +1,23 @@
'use strict';
async function getVenderList (ctx) {
const models = ctx.fs.dc.models;
try {
const res = await models.Vender.findAll({
order: [
['id', 'ASC']
]
})
ctx.status = 200;
ctx.body = res
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
}
}
module.exports = {
getVenderList,
};

134
code/VideoAccess-VCMP/api/app/lib/index.js

@ -1,36 +1,126 @@
'use strict';
const fs = require('fs');
const path = require('path');
const utils = require('./utils')
const routes = require('./routes');
const redisConnect = require('./service/redis')
const socketConect = require('./service/socket')
const mqttVideoServer = require('./service/mqttVideoServer')
const paasRequest = require('./service/paasRequest');
const authenticator = require('./middlewares/authenticator');
const schedule = require('./schedule')
// const apiLog = require('./middlewares/api-log');
const businessRest = require('./middlewares/business-rest');
module.exports.entry = function (app, router, opts) {
app.fs.logger.log('info', '[FS-AUTH]', 'Inject auth and api mv into router.');
app.fs.logger.log('info', '[FS-AUTH]', 'Inject auth and api mv into router.');
app.fs.api = app.fs.api || {};
app.fs.api.authAttr = app.fs.api.authAttr || {};
app.fs.api.logAttr = app.fs.api.logAttr || {};
app.fs.api = app.fs.api || {};
app.fs.utils = app.fs.utils || {};
app.fs.api.authAttr = app.fs.api.authAttr || {};
app.fs.api.logAttr = app.fs.api.logAttr || {};
router.use(authenticator(app, opts));
router.use(businessRest(app, router, opts));
// router.use(apiLog(app, opts));
// 顺序固定 ↓
redisConnect(app, opts)
socketConect(app, opts)
mqttVideoServer(app, opts)
router = routes(app, router, opts);
// 实例其他平台请求方法
paasRequest(app, opts)
// 工具类函数
utils(app, opts)
// 定时任务
schedule(app, opts)
// 鉴权中间件
router.use(authenticator(app, opts));
// 日志记录
// router.use(apiLog(app, opts));
router = routes(app, router, opts);
};
module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Sequelize, models: {} }
require('./models/user')(dc);
require('./models/user_token')(dc);
require('./models/department')(dc);
require('./models/resource')(dc);
require('./models/user_resource')(dc);
require('./models/places')(dc);
require('./models/user_placeSecurityRecord')(dc);
require('./models/report_type')(dc);
require('./models/report_downManage')(dc);
require('./models/department')(dc);
require('./models/report_configition')(dc);
require('./models/report_collection')(dc);
require('./models/report_rectify')(dc);
// 加载定义模型 历史写法
// require('./models/nvr')(dc);
// 模型关系摘出来 初始化之后再定义关系才行
fs.readdirSync(path.join(__dirname, '/models')).forEach((filename) => {
require(`./models/${filename}`)(dc)
});
const {
Nvr, Camera, CameraAbility, CameraAbilityBind, CameraKind, CameraRemark,
GbCamera, SecretYingshi, Vender, CameraStatus, CameraStatusResolve, CameraStatusLog,
CameraStatusPushConfig, CameraStatusPushMonitor, CameraStatusPushLog, CameraStatusPushReceiver, CameraStatusOfflineLog,
Mirror, MirrorTree, MirrorFilterGroup, MirrorFilter, MirrorCamera
} = dc.models;
// Nvr.belongsTo(User, { foreignKey: 'userId', targetKey: 'id' });
// User.hasMany(Nvr, { foreignKey: 'userId', sourceKey: 'id' });
Camera.belongsToMany(CameraAbility, { through: CameraAbilityBind, foreignKey: 'cameraId', otherKey: 'abilityId' });
CameraRemark.belongsTo(Camera, { foreignKey: 'cameraId', targetKey: 'id' });
Camera.hasMany(CameraRemark, { foreignKey: 'cameraId', sourceKey: 'id' });
Camera.belongsTo(CameraKind, { foreignKey: 'kindId', targetKey: 'id' });
CameraKind.hasMany(Camera, { foreignKey: 'kindId', sourceKey: 'id' });
Camera.belongsTo(Nvr, { foreignKey: 'nvrId', targetKey: 'id' });
Nvr.hasMany(Camera, { foreignKey: 'nvrId', sourceKey: 'id' });
Nvr.belongsTo(GbCamera, { foreignKey: 'serialNo', targetKey: 'streamid', as: 'gbNvr' });
GbCamera.hasMany(Nvr, { foreignKey: 'serialNo', sourceKey: 'streamid', as: 'gbNvr' });
Camera.belongsTo(GbCamera, { foreignKey: 'gbId', targetKey: 'id' });
GbCamera.hasMany(Camera, { foreignKey: 'gbId', sourceKey: 'id' });
Camera.belongsTo(SecretYingshi, { foreignKey: 'yingshiSecretId', targetKey: 'id' });
SecretYingshi.hasMany(Camera, { foreignKey: 'yingshiSecretId', sourceKey: 'id' });
Camera.belongsTo(Vender, { foreignKey: 'venderId', targetKey: 'id' });
Vender.hasMany(Camera, { foreignKey: 'venderId', sourceKey: 'id' });
Nvr.belongsTo(Vender, { foreignKey: 'venderId', targetKey: 'id' });
Vender.hasMany(Nvr, { foreignKey: 'venderId', sourceKey: 'id' });
CameraStatusResolve.belongsTo(CameraStatus, { foreignKey: 'statusId', targetKey: 'id' });
CameraStatus.hasMany(CameraStatusResolve, { foreignKey: 'statusId', sourceKey: 'id' });
CameraStatusLog.belongsTo(CameraStatus, { foreignKey: 'statusId', targetKey: 'id' });
CameraStatus.hasMany(CameraStatusLog, { foreignKey: 'statusId', sourceKey: 'id' });
CameraStatusPushMonitor.belongsTo(CameraStatusPushConfig, { foreignKey: 'configId', targetKey: 'id' });
CameraStatusPushConfig.hasMany(CameraStatusPushMonitor, { foreignKey: 'configId', sourceKey: 'id' });
CameraStatusPushMonitor.belongsTo(Camera, { foreignKey: 'cameraId', targetKey: 'id' });
Camera.hasMany(CameraStatusPushMonitor, { foreignKey: 'cameraId', sourceKey: 'id' });
CameraStatusPushLog.belongsTo(CameraStatusPushConfig, { foreignKey: 'pushConfigId', targetKey: 'id' });
CameraStatusPushConfig.hasMany(CameraStatusPushLog, { foreignKey: 'pushConfigId', sourceKey: 'id' });
CameraStatusPushReceiver.belongsTo(CameraStatusPushConfig, { foreignKey: 'configId', targetKey: 'id' });
CameraStatusPushConfig.hasMany(CameraStatusPushReceiver, { foreignKey: 'configId', sourceKey: 'id' });
CameraStatusOfflineLog.belongsTo(Camera, { foreignKey: 'cameraId', targetKey: 'id' });
Camera.hasMany(CameraStatusOfflineLog, { foreignKey: 'cameraId', sourceKey: 'id' });
MirrorTree.belongsTo(Mirror, { foreignKey: 'mirrorId', targetKey: 'id' });
Mirror.hasMany(MirrorTree, { foreignKey: 'mirrorId', sourceKey: 'id' });
MirrorFilterGroup.belongsTo(Mirror, { foreignKey: 'mirrorId', targetKey: 'id' });
Mirror.hasMany(MirrorFilterGroup, { foreignKey: 'mirrorId', sourceKey: 'id' });
MirrorFilter.belongsTo(MirrorFilterGroup, { foreignKey: 'groupId', targetKey: 'id' });
MirrorFilterGroup.hasMany(MirrorFilter, { foreignKey: 'groupId', sourceKey: 'id' });
MirrorCamera.belongsTo(Camera, { foreignKey: 'cameraId', targetKey: 'id' });
Camera.hasMany(MirrorCamera, { foreignKey: 'cameraId', sourceKey: 'id' });
MirrorCamera.belongsTo(Mirror, { foreignKey: 'mirrorId', targetKey: 'id' });
Mirror.hasMany(MirrorCamera, { foreignKey: 'mirrorId', sourceKey: 'id' });
};

2
code/VideoAccess-VCMP/api/app/lib/middlewares/api-log.js

@ -71,7 +71,7 @@ function factory(app, opts) {
partition: 0
}];
await sendToEsAsync(producer, payloads);
// await sendToEsAsync(producer, payloads);
} catch (e) {
ctx.fs.logger.error(`日志记录失败: ${e}`);

233
code/VideoAccess-VCMP/api/app/lib/middlewares/authenticator.js

@ -8,42 +8,42 @@ const util = require('util');
const moment = require('moment');
class ExcludesUrls {
constructor(opts) {
this.allUrls = undefined;
this.reload(opts);
}
constructor(opts) {
this.allUrls = undefined;
this.reload(opts);
}
sanitizePath(path) {
if (!path) return '/';
const p = '/' + path.replace(/^\/+/i, '').replace(/\/+$/, '').replace(/\/{2,}/, '/');
return p;
}
sanitizePath (path) {
if (!path) return '/';
const p = '/' + path.replace(/^\/+/i, '').replace(/\/+$/, '').replace(/\/{2,}/, '/');
return p;
}
reload(opts) {
// load all url
if (!this.allUrls) {
this.allUrls = opts;
let that = this;
this.allUrls.forEach(function (url, i, arr) {
if (typeof url === "string") {
url = { p: url, o: '*' };
arr[i] = url;
}
const keys = [];
let eachPath = url.p;
url.p = (!eachPath || eachPath === '(.*)' || util.isRegExp(eachPath)) ? eachPath : that.sanitizePath(eachPath);
url.pregexp = pathToRegexp(eachPath, keys);
});
}
}
reload (opts) {
// load all url
if (!this.allUrls) {
this.allUrls = opts;
let that = this;
this.allUrls.forEach(function (url, i, arr) {
if (typeof url === "string") {
url = { p: url, o: '*' };
arr[i] = url;
}
const keys = [];
let eachPath = url.p;
url.p = (!eachPath || eachPath === '(.*)' || util.isRegExp(eachPath)) ? eachPath : that.sanitizePath(eachPath);
url.pregexp = pathToRegexp(eachPath, keys);
});
}
}
isExcluded(path, method) {
return this.allUrls.some(function (url) {
return !url.auth
&& url.pregexp.test(path)
&& (url.o === '*' || url.o.indexOf(method) !== -1);
});
}
isExcluded (path, method) {
return this.allUrls.some(function (url) {
return !url.auth
&& url.pregexp.test(path)
&& (url.o === '*' || url.o.indexOf(method) !== -1);
});
}
}
/**
@ -53,98 +53,99 @@ class ExcludesUrls {
* @param {*} method 当前request的method
*/
let isPathExcluded = function (opts, path, method) {
let excludeAll = Boolean(opts.exclude && opts.exclude.length && opts.exclude[0] == '*');
let excludes = null;
if (!excludeAll) {
let excludeOpts = opts.exclude || [];
excludeOpts.push({ p: '/login', o: 'POST' });
excludeOpts.push({ p: '/wxLogin', o: 'POST' });
excludeOpts.push({ p: '/logout', o: 'PUT' });
excludeOpts.push({ p: '/wxLogout', o: 'PUT' });
excludes = new ExcludesUrls(excludeOpts);
}
let excluded = excludeAll || excludes.isExcluded(path, method);
return excluded;
let excludeAll = Boolean(opts.exclude && opts.exclude.length && opts.exclude[0] == '*');
let excludes = null;
if (!excludeAll) {
let excludeOpts = opts.exclude || [];
excludeOpts.push({ p: '/login', o: 'POST' });
excludeOpts.push({ p: '/logout', o: 'PUT' });
excludes = new ExcludesUrls(excludeOpts);
}
let excluded = excludeAll || excludes.isExcluded(path, method);
return excluded;
};
let authorizeToken = async function (ctx, token) {
let rslt = null;
const tokenFormatRegexp = /^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$/g;
if (token && tokenFormatRegexp.test(token)) {
try {
const axyRes = await ctx.fs.dc.models.UserToken.findOne({
where: {
token: token,
expired: { $gte: moment().format('YYYY-MM-DD HH:mm:ss') }
}
});
const { userInfo, expired } = axyRes;
if (!expired || moment().valueOf() <= moment(expired).valueOf()) {
rslt = {
'authorized': userInfo.authorized,
'resources': (userInfo || {}).resources || [],
};
ctx.fs.api.userId = userInfo.id;
ctx.fs.api.userInfo = userInfo;
ctx.fs.api.token = token;
}
} catch (err) {
const { error } = err.response || {};
ctx.fs.logger.log('[anxinyun]', '[AUTH] failed', (error || {}).message || `cannot GET /users/${token}`);
}
}
return rslt;
let rslt = null;
const tokenFormatRegexp = /^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$/g;
if (token && tokenFormatRegexp.test(token)) {
try {
// const expired = await ctx.redis.hget(token, 'expired');
let userInfo = await ctx.redis.get(token);
if (
userInfo
// expired && moment().valueOf() <= moment(expired).valueOf()
) {
// const userInfo = JSON.parse(await ctx.redis.hget(token, 'userInfo'));
userInfo = JSON.parse(userInfo);
rslt = {
'authorized': userInfo.authorized,
'resources': (userInfo || {}).resources || [],
};
ctx.fs.api.userId = userInfo.id;
ctx.fs.api.userInfo = userInfo;
ctx.fs.api.token = token;
}
} catch (err) {
console.error(err);
const { error } = err.response || {};
ctx.fs.logger.log('[anxinyun]', '[AUTH] failed', (error || {}).message || `cannot GET /users/${token}`);
}
}
return rslt;
};
let isResourceAvailable = function (resources, options) {
let authCode = null;
// authorize user by authorization attribute
const { authAttr, method, path } = options;
console.log(resources, options)
for (let prop in authAttr) {
let keys = [];
let re = pathToRegexp(prop.replace(/\:[A-Za-z_\-]+\b/g, '(\\d+)'), keys);
if (re.test(`${method}${path}`)) {
authCode = authAttr[prop];
break;
}
}
return !authCode || (resources || []).some(code => code === authCode);
let authCode = null;
// authorize user by authorization attribute
const { authAttr, method, path } = options;
for (let prop in authAttr) {
let keys = [];
let re = pathToRegexp(prop.replace(/\:[A-Za-z_\-]+\b/g, '(\\d+)'), keys);
if (re.test(`${method}${path}`)) {
authCode = authAttr[prop];
break;
}
}
return !authCode || (resources || []).some(code => code === authCode);
};
function factory(app, opts) {
return async function auth(ctx, next) {
const { path, method, header, query } = ctx;
ctx.fs.logger.log('[AUTH] start', path, method);
ctx.fs.api = ctx.fs.api || {};
ctx.fs.port = opts.port;
ctx.redis = app.redis;
let error = null;
if (path) {
if (!isPathExcluded(opts, path, method)) {
const user = await authorizeToken(ctx, header.token || query.token);
if (user && user.authorized) {
// if (!isResourceAvailable(user.resources, { authAttr: app.fs.auth.authAttr, path, method })) {
// error = { status: 403, name: 'Forbidden' }
// } else {
// error = { status: 401, name: 'Unauthorized' }
// }
} else {
error = { status: 401, name: 'Unauthorized' }
}
function factory (app, opts) {
return async function auth (ctx, next) {
const { path, method, header, query } = ctx;
ctx.fs.logger.log('[AUTH] start', path, method);
ctx.fs.api = ctx.fs.api || {};
ctx.fs.port = opts.port;
ctx.redis = app.redis;
ctx.redisTools = app.redisTools;
let error = null;
if (path) {
if (!isPathExcluded(opts, path, method)) {
const user = await authorizeToken(ctx, header.token || query.token);
if (user && user.authorized) {
// if (!isResourceAvailable(user.resources, { authAttr: app.fs.auth.authAttr, path, method })) {
// error = { status: 403, name: 'Forbidden' }
// } else {
// error = { status: 401, name: 'Unauthorized' }
// }
} else {
error = { status: 401, name: 'Unauthorized' }
}
} else {
error = { status: 401, name: 'Unauthorized' };
}
if (error) {
ctx.fs.logger.log('[AUTH] failed', path, method);
ctx.status = error.status;
ctx.body = error.name;
} else {
ctx.fs.logger.log('[AUTH] passed', path, method);
await next();
}
}
}
} else {
error = { status: 401, name: 'Unauthorized' };
}
if (error) {
ctx.fs.logger.log('[AUTH] failed', path, method);
ctx.status = error.status;
ctx.body = error.name;
} else {
ctx.fs.logger.log('[AUTH] passed', path, method);
await next();
}
}
}
module.exports = factory;

50
code/VideoAccess-VCMP/api/app/lib/middlewares/business-rest.js

@ -1,50 +0,0 @@
'use strict';
const request = require('superagent');
const buildUrl = (url,token) => {
let connector = url.indexOf('?') === -1 ? '?' : '&';
return `${url}${connector}token=${token}`;
};
function factory(app, router, opts) {
return async function (ctx, next) {
const token = ctx.fs.api.token;
//console.log(username,password)
const req = {
get: (url, query) => {
return request
.get(buildUrl(url,token))
.query(query)
},
post: (url, data, query) => {
return request
.post(buildUrl(url,token))
.query(query)
//.set('Content-Type', 'application/json')
.send(data);
},
put: (url, data) => {
return request
.put(buildUrl(url,token))
//.set('Content-Type', 'application/json')
.send(data);
},
delete: (url) => {
return request
.del(buildUrl(url,token))
},
};
app.business = app.business || {};
app.business.request = req;
await next();
};
}
module.exports = factory;

72
code/VideoAccess-VCMP/api/app/lib/models/user.js → code/VideoAccess-VCMP/api/app/lib/models/application.js

@ -4,7 +4,7 @@
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const User = sequelize.define("user", {
const Application = sequelize.define("application", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
@ -13,7 +13,7 @@ module.exports = dc => {
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "user_id_uindex"
unique: "application_id_uindex"
},
name: {
type: DataTypes.STRING,
@ -24,85 +24,65 @@ module.exports = dc => {
field: "name",
autoIncrement: false
},
username: {
type: DataTypes.STRING,
allowNull: false,
type: {
type: DataTypes.ARRAY(DataTypes.STRING),
allowNull: true,
defaultValue: null,
comment: "用户名 账号",
comment: "web / app / wxapp / other",
primaryKey: false,
field: "username",
field: "type",
autoIncrement: false
},
password: {
appKey: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "password",
field: "app_key",
autoIncrement: false
},
departmentId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: "部门id",
primaryKey: false,
field: "department_id",
autoIncrement: false
},
email: {
appSecret: {
type: DataTypes.STRING,
allowNull: true,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "email",
field: "app_secret",
autoIncrement: false
},
enable: {
type: DataTypes.BOOLEAN,
createUserId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: "启用状态",
comment: null,
primaryKey: false,
field: "enable",
field: "create_user_id",
autoIncrement: false
},
delete: {
type: DataTypes.BOOLEAN,
createTime: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "delete",
field: "create_time",
autoIncrement: false
},
phone: {
type: DataTypes.STRING,
forbidden: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: null,
comment: "手机号(小程序使用手机号登录)",
primaryKey: false,
field: "phone",
autoIncrement: false
},
post: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "职位",
comment: null,
primaryKey: false,
field: "post",
field: "forbidden",
autoIncrement: false
}
}, {
tableName: "user",
tableName: "application",
comment: "",
indexes: []
});
dc.models.User = User;
return User;
dc.models.Application = Application;
return Application;
};

35
code/VideoAccess-VCMP/api/app/lib/models/ax_project.js

@ -0,0 +1,35 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const AxProject = sequelize.define("axProject", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: false,
unique: "ax_project_id_uindex"
},
name: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "name",
autoIncrement: false
}
}, {
tableName: "ax_project",
comment: "",
indexes: []
});
dc.models.AxProject = AxProject;
return AxProject;
};

294
code/VideoAccess-VCMP/api/app/lib/models/camera.js

@ -0,0 +1,294 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const Camera = sequelize.define("camera", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "camera_id_uindex"
},
type: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: "设备类型:yingshi - 萤石;nvr - NVR摄像头;ipc - IPC 网络摄像头;cascade - 级联摄像头",
primaryKey: false,
field: "type",
autoIncrement: false
},
name: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "设备名称/安装位置",
primaryKey: false,
field: "name",
autoIncrement: false
},
channelName: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "通道名称",
primaryKey: false,
field: "channel_name",
autoIncrement: false
},
externalDomain: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "外域名称",
primaryKey: false,
field: "external_domain",
autoIncrement: false
},
rtmp: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "rtmp",
autoIncrement: false
},
serialNo: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "设备编号",
primaryKey: false,
field: "serial_no",
autoIncrement: false
},
topSerialNo: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "gb设备 level=0 的 steamid ",
primaryKey: false,
field: "top_serial_no",
autoIncrement: false
},
cloudControl: {
type: DataTypes.BOOLEAN,
allowNull: true,
defaultValue: null,
comment: "云台控制",
primaryKey: false,
field: "cloud_control",
autoIncrement: false
},
definition: {
type: DataTypes.BOOLEAN,
allowNull: true,
defaultValue: null,
comment: "清晰度",
primaryKey: false,
field: "definition",
autoIncrement: false
},
highDefinition: {
type: DataTypes.BOOLEAN,
allowNull: true,
defaultValue: null,
comment: "高清支持",
primaryKey: false,
field: "high_definition",
autoIncrement: false
},
voice: {
type: DataTypes.BOOLEAN,
allowNull: true,
defaultValue: null,
comment: "语音对讲支持",
primaryKey: false,
field: "voice",
autoIncrement: false
},
memoryCard: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "内存卡容量",
primaryKey: false,
field: "memory_card",
autoIncrement: false
},
venderId: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: null,
comment: "设备厂商id",
primaryKey: false,
field: "vender_id",
autoIncrement: false,
references: {
key: "id",
model: "vender"
}
},
cascadeType: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "级联方式:up - 上级联;down - 下级联",
primaryKey: false,
field: "cascade_type",
autoIncrement: false
},
sip: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "sip",
autoIncrement: false
},
longitude: {
type: DataTypes.DOUBLE,
allowNull: true,
defaultValue: null,
comment: "经度",
primaryKey: false,
field: "longitude",
autoIncrement: false
},
latitude: {
type: DataTypes.DOUBLE,
allowNull: true,
defaultValue: null,
comment: "维度",
primaryKey: false,
field: "latitude",
autoIncrement: false
},
forbidden: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
comment: "是否禁用",
primaryKey: false,
field: "forbidden",
autoIncrement: false
},
createTime: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "create_time",
autoIncrement: false
},
recycleTime: {
type: DataTypes.DATE,
allowNull: true,
defaultValue: null,
comment: "放入回收站时间",
primaryKey: false,
field: "recycle_time",
autoIncrement: false
},
delete: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
comment: "是否彻底删除",
primaryKey: false,
field: "delete",
autoIncrement: false
},
createUserId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "create_user_id",
autoIncrement: false
},
nvrId: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "nvr_id",
autoIncrement: false,
references: {
key: "id",
model: "nvr"
}
},
model: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "型号",
primaryKey: false,
field: "model",
autoIncrement: false
},
kindId: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "kind_id",
autoIncrement: false,
references: {
key: "id",
model: "cameraKind"
}
},
yingshiSecretId: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "yingshi_secret_id",
autoIncrement: false,
references: {
key: "id",
model: "secretYingshi"
}
},
gbId: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "gb_id",
autoIncrement: false,
},
channelNo: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: '通道号',
primaryKey: false,
field: "channel_no",
autoIncrement: false
},
}, {
tableName: "camera",
comment: "",
indexes: []
});
dc.models.Camera = Camera;
return Camera;
};

34
code/VideoAccess-VCMP/api/app/lib/models/camera_ability.js

@ -0,0 +1,34 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const CameraAbility = sequelize.define("cameraAbility", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: false,
unique: "camera_ability_id_uindex"
},
ability: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "ability",
autoIncrement: false
}
}, {
tableName: "camera_ability",
comment: "",
indexes: []
});
dc.models.CameraAbility = CameraAbility;
return CameraAbility;
};

52
code/VideoAccess-VCMP/api/app/lib/models/camera_ability_bind.js

@ -0,0 +1,52 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const CameraAbilityBind = sequelize.define("cameraAbilityBind", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "camera_ability_bind_id_uindex"
},
cameraId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "camera_id",
autoIncrement: false,
references: {
key: "id",
model: "camera"
}
},
abilityId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "ability_id",
autoIncrement: false,
references: {
key: "id",
model: "cameraAbility"
}
}
}, {
tableName: "camera_ability_bind",
comment: "",
indexes: []
});
dc.models.CameraAbilityBind = CameraAbilityBind;
return CameraAbilityBind;
};

34
code/VideoAccess-VCMP/api/app/lib/models/camera_kind.js

@ -0,0 +1,34 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const CameraKind = sequelize.define("cameraKind", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: false,
unique: "camera_kind_id_uindex"
},
kind: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "kind",
autoIncrement: false
}
}, {
tableName: "camera_kind",
comment: "",
indexes: []
});
dc.models.CameraKind = CameraKind;
return CameraKind;
};

48
code/VideoAccess-VCMP/api/app/lib/models/camera_remark.js

@ -0,0 +1,48 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const CameraRemark = sequelize.define("cameraRemark", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "camera_remark_id_uindex"
},
cameraId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "camera_id",
autoIncrement: false,
references: {
key: "id",
model: "camera"
}
},
remark: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "remark",
autoIncrement: false
}
}, {
tableName: "camera_remark",
comment: "",
indexes: []
});
dc.models.CameraRemark = CameraRemark;
return CameraRemark;
};

79
code/VideoAccess-VCMP/api/app/lib/models/camera_status.js

@ -0,0 +1,79 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const CameraStatus = sequelize.define("cameraStatus", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "camera_status_id_uindex"
},
platform: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: "平台分类 yingshi gb",
primaryKey: false,
field: "platform",
autoIncrement: false
},
status: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "status",
autoIncrement: false
},
describe: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "错误描述",
primaryKey: false,
field: "describe",
autoIncrement: false
},
paraphrase: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "释义",
primaryKey: false,
field: "paraphrase",
autoIncrement: false
},
forbidden: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: null,
comment: "是否禁用",
primaryKey: false,
field: "forbidden",
autoIncrement: false
},
paraphraseCustom: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "自定义释义",
primaryKey: false,
field: "paraphrase_custom",
autoIncrement: false
}
}, {
tableName: "camera_status",
comment: "",
indexes: []
});
dc.models.CameraStatus = CameraStatus;
return CameraStatus;
};

119
code/VideoAccess-VCMP/api/app/lib/models/camera_status_alarm.js

@ -0,0 +1,119 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const CameraStatusAlarm = sequelize.define("cameraStatusAlarm", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "camera_status_alarm_id_uindex"
},
statusId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "status_id",
autoIncrement: false,
references: {
key: "id",
model: "cameraStatus"
}
},
description: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "描述",
primaryKey: false,
field: "description",
autoIncrement: false
},
confirm: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "确认信息",
primaryKey: false,
field: "confirm",
autoIncrement: false
},
confirmTime: {
type: DataTypes.DATE,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "confirm_time",
autoIncrement: false
},
createTime: {
type: DataTypes.DATE,
allowNull: true,
defaultValue: null,
comment: "生成时间",
primaryKey: false,
field: "create_time",
autoIncrement: false
},
updateTime: {
type: DataTypes.DATE,
allowNull: true,
defaultValue: null,
comment: "更新时间",
primaryKey: false,
field: "update_time",
autoIncrement: false
},
serialNo: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "序列号",
primaryKey: false,
field: "serial_no",
autoIncrement: false
},
channelNo: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "通道号",
primaryKey: false,
field: "channel_no",
autoIncrement: false
},
platform: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "platform",
autoIncrement: false
},
autoRestore: {
type: DataTypes.BOOLEAN,
allowNull: true,
defaultValue: false,
comment: "是否自动恢复的",
primaryKey: false,
field: "auto_restore",
autoIncrement: false
}
}, {
tableName: "camera_status_alarm",
comment: "",
indexes: []
});
dc.models.CameraStatusAlarm = CameraStatusAlarm;
return CameraStatusAlarm;
};

47
code/VideoAccess-VCMP/api/app/lib/models/camera_status_log.js

@ -0,0 +1,47 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const CameraStatusLog = sequelize.define("cameraStatusLog", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "camera_status_log_id_uindex_2"
},
statusId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "status_id",
autoIncrement: false,
references: {
key: "id",
model: "cameraStatus"
}
},
time: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "time",
autoIncrement: false
}
}, {
tableName: "camera_status_log",
comment: "",
indexes: []
});
dc.models.CameraStatusLog = CameraStatusLog;
return CameraStatusLog;
};

52
code/VideoAccess-VCMP/api/app/lib/models/camera_status_offline_log.js

@ -0,0 +1,52 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const CameraStatusOfflineLog = sequelize.define("cameraStatusOfflineLog", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "camera_status_offline_log_id_uindex"
},
cameraId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "camera_id",
autoIncrement: false
},
status: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "status",
autoIncrement: false
},
time: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "time",
autoIncrement: false
}
}, {
tableName: "camera_status_offline_log",
comment: "",
indexes: []
});
dc.models.CameraStatusOfflineLog = CameraStatusOfflineLog;
return CameraStatusOfflineLog;
};

79
code/VideoAccess-VCMP/api/app/lib/models/camera_status_push_config.js

@ -0,0 +1,79 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const CameraStatusPushConfig = sequelize.define("cameraStatusPushConfig", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "camera_online_status_push_config_id_uindex"
},
name: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "name",
autoIncrement: false
},
pushWay: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: "推送方式 email / phone",
primaryKey: false,
field: "push_way",
autoIncrement: false
},
noticeWay: {
type: DataTypes.ARRAY(DataTypes.STRING),
allowNull: false,
defaultValue: null,
comment: "通知方式 offline / online / timing",
primaryKey: false,
field: "notice_way",
autoIncrement: false
},
createUser: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "create_user",
autoIncrement: false
},
forbidden: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "forbidden",
autoIncrement: false
},
timing: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "定时推送时间",
primaryKey: false,
field: "timing",
autoIncrement: false
}
}, {
tableName: "camera_status_push_config",
comment: "",
indexes: []
});
dc.models.CameraStatusPushConfig = CameraStatusPushConfig;
return CameraStatusPushConfig;
};

88
code/VideoAccess-VCMP/api/app/lib/models/camera_status_push_log.js

@ -0,0 +1,88 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const CameraStatusPushLog = sequelize.define("cameraStatusPushLog", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "camera_status_push_log_id_uindex"
},
pushConfigId: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "push_config_id",
autoIncrement: false
},
receiver: {
type: DataTypes.ARRAY(DataTypes.STRING),
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "receiver",
autoIncrement: false
},
time: {
type: DataTypes.DATE,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "time",
autoIncrement: false
},
pushWay: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "push_way",
autoIncrement: false
},
camera: {
type: DataTypes.ARRAY(DataTypes.INTEGER),
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "camera",
autoIncrement: false
},
timing: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "定时推送时间",
primaryKey: false,
field: "timing",
autoIncrement: false
},
noticeWay: {
type: DataTypes.ARRAY(DataTypes.STRING),
allowNull: false,
defaultValue: null,
comment: "通知方式 offline / online / timing",
primaryKey: false,
field: "notice_way",
autoIncrement: false
},
}, {
tableName: "camera_status_push_log",
comment: "",
indexes: []
});
dc.models.CameraStatusPushLog = CameraStatusPushLog;
return CameraStatusPushLog;
};

51
code/VideoAccess-VCMP/api/app/lib/models/camera_status_push_monitor.js

@ -0,0 +1,51 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const CameraStatusPushMonitor = sequelize.define("cameraStatusPushMonitor", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "camera_status_push_monitor_id_uindex"
},
configId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "config_id",
autoIncrement: false,
references: {
key: "id",
model: "cameraStatusPushConfig"
}
},
cameraId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "camera_id",
autoIncrement: false,
references: {
key: "id",
model: "camera"
}
}
}, {
tableName: "camera_status_push_monitor",
comment: "",
indexes: []
});
dc.models.CameraStatusPushMonitor = CameraStatusPushMonitor;
return CameraStatusPushMonitor;
};

47
code/VideoAccess-VCMP/api/app/lib/models/camera_status_push_receiver.js

@ -0,0 +1,47 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const CameraStatusPushReceiver = sequelize.define("cameraStatusPushReceiver", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "camera_status_push_receiver_id_uindex"
},
configId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "config_id",
autoIncrement: false,
references: {
key: "id",
model: "cameraStatusPushConfig"
}
},
receiver: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: "接受者信息 邮箱或者电话号码",
primaryKey: false,
field: "receiver",
autoIncrement: false
}
}, {
tableName: "camera_status_push_receiver",
comment: "",
indexes: []
});
dc.models.CameraStatusPushReceiver = CameraStatusPushReceiver;
return CameraStatusPushReceiver;
};

47
code/VideoAccess-VCMP/api/app/lib/models/camera_status_resolve.js

@ -0,0 +1,47 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const CameraStatusResolve = sequelize.define("cameraStatusResolve", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "camera_status_resolve_id_uindex"
},
statusId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "status_id",
autoIncrement: false,
references: {
key: "id",
model: "cameraStatus"
}
},
resolve: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "resolve",
autoIncrement: false
}
}, {
tableName: "camera_status_resolve",
comment: "",
indexes: []
});
dc.models.CameraStatusResolve = CameraStatusResolve;
return CameraStatusResolve;
};

170
code/VideoAccess-VCMP/api/app/lib/models/gb_camera.js

@ -0,0 +1,170 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const GbCamera = sequelize.define("gbCamera", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "gbcamera_id_uindex"
},
level: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "level",
autoIncrement: false
},
parent: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "parent",
autoIncrement: false
},
streamid: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "streamid",
autoIncrement: false
},
registerTime: {
type: DataTypes.DATEONLY,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "registerTime",
autoIncrement: false
},
updateTime: {
type: DataTypes.DATEONLY,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "updateTime",
autoIncrement: false
},
online: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "online",
autoIncrement: false
},
manufactuer: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "manufactuer",
autoIncrement: false
},
model: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "model",
autoIncrement: false
},
civilCode: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "civilCode",
autoIncrement: false
},
adddress: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "adddress",
autoIncrement: false
},
name: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "name",
autoIncrement: false
},
addr: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "Addr",
autoIncrement: false
},
sipip: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "Sipip",
autoIncrement: false
},
ipctype: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "ipctype",
autoIncrement: false
},
playUrl: {
type: DataTypes.JSONB,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "playUrl",
autoIncrement: false
},
did: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "did",
autoIncrement: false
}
}, {
tableName: "gbCamera",
comment: "",
indexes: []
});
dc.models.GbCamera = GbCamera;
return GbCamera;
};

124
code/VideoAccess-VCMP/api/app/lib/models/mirror.js

@ -0,0 +1,124 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const Mirror = sequelize.define("mirror", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "mirror_id_uindex"
},
template: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: "模板标识",
primaryKey: false,
field: "template",
autoIncrement: false
},
createUser: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "create_user",
autoIncrement: false
},
createTime: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "create_time",
autoIncrement: false
},
updateTime: {
type: DataTypes.DATE,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "update_time",
autoIncrement: false
},
title: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "title",
autoIncrement: false
},
showHeader: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "show_header",
autoIncrement: false
},
listOpen: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "list_open",
autoIncrement: false
},
publish: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "publish",
autoIncrement: false
},
check: {
type: DataTypes.ARRAY(DataTypes.INTEGER),
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "check",
autoIncrement: false
},
mid: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "mid",
autoIncrement: false
},
publishTime: {
type: DataTypes.DATE,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "publish_time",
autoIncrement: false
}
}, {
tableName: "mirror",
comment: "",
indexes: []
});
dc.models.Mirror = Mirror;
return Mirror;
};

69
code/VideoAccess-VCMP/api/app/lib/models/mirror_camera.js

@ -0,0 +1,69 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const MirrorCamera = sequelize.define("mirrorCamera", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "mirror_camera_id_uindex"
},
cameraId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "camera_id",
autoIncrement: false,
references: {
key: "id",
model: "camera"
}
},
treeIds: {
type: DataTypes.ARRAY(DataTypes.INTEGER),
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "tree_ids",
autoIncrement: false
},
filterIds: {
type: DataTypes.ARRAY(DataTypes.INTEGER),
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "filter_ids",
autoIncrement: false
},
mirrorId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "mirror_id",
autoIncrement: false,
references: {
key: "id",
model: "mirror"
}
}
}, {
tableName: "mirror_camera",
comment: "",
indexes: []
});
dc.models.MirrorCamera = MirrorCamera;
return MirrorCamera;
};

47
code/VideoAccess-VCMP/api/app/lib/models/mirror_filter.js

@ -0,0 +1,47 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const MirrorFilter = sequelize.define("mirrorFilter", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "mirror_filter_id_uindex"
},
name: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "name",
autoIncrement: false
},
groupId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "group_id",
autoIncrement: false,
references: {
key: "id",
model: "mirrorFilterGroup"
}
}
}, {
tableName: "mirror_filter",
comment: "",
indexes: []
});
dc.models.MirrorFilter = MirrorFilter;
return MirrorFilter;
};

56
code/VideoAccess-VCMP/api/app/lib/models/mirror_filter_group.js

@ -0,0 +1,56 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const MirrorFilterGroup = sequelize.define("mirrorFilterGroup", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "mirror_filter_group_id_uindex"
},
name: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "name",
autoIncrement: false
},
forbidden: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "forbidden",
autoIncrement: false
},
mirrorId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "mirror_id",
autoIncrement: false,
references: {
key: "id",
model: "mirror"
}
}
}, {
tableName: "mirror_filter_group",
comment: "",
indexes: []
});
dc.models.MirrorFilterGroup = MirrorFilterGroup;
return MirrorFilterGroup;
};

65
code/VideoAccess-VCMP/api/app/lib/models/mirror_tree.js

@ -0,0 +1,65 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const MirrorTree = sequelize.define("mirrorTree", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "mirror_tree_id_uindex"
},
name: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "name",
autoIncrement: false
},
level: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: "层级标注",
primaryKey: false,
field: "level",
autoIncrement: false
},
dependence: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "dependence",
autoIncrement: false
},
mirrorId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "mirror_id",
autoIncrement: false,
references: {
key: "id",
model: "mirror"
}
}
}, {
tableName: "mirror_tree",
comment: "",
indexes: []
});
dc.models.MirrorTree = MirrorTree;
return MirrorTree;
};

128
code/VideoAccess-VCMP/api/app/lib/models/nvr.js

@ -0,0 +1,128 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const Nvr = sequelize.define("nvr", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "nvr_id_uindex"
},
name: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "name",
autoIncrement: false
},
venderId: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: null,
comment: "设备厂家id",
primaryKey: false,
field: "vender_id",
autoIncrement: false,
references: {
key: "id",
model: "vender"
}
},
serialNo: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: "设备编号",
primaryKey: false,
field: "serial_no",
autoIncrement: false
},
regionCode: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "行政区码",
primaryKey: false,
field: "region_code",
autoIncrement: false
},
longitude: {
type: DataTypes.DOUBLE,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "longitude",
autoIncrement: false
},
latitude: {
type: DataTypes.DOUBLE,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "latitude",
autoIncrement: false
},
createTime: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: sequelize.fn('now'),
comment: "创建时间",
primaryKey: false,
field: "create_time",
autoIncrement: false
},
channelCount: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: null,
comment: "通道数",
primaryKey: false,
field: "channel_count",
autoIncrement: false
},
port: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: "端口",
primaryKey: false,
field: "port",
autoIncrement: false
},
delete: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "delete",
autoIncrement: false
},
createUserId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "create_user_id",
autoIncrement: false
}
}, {
tableName: "nvr",
comment: "",
indexes: []
});
dc.models.Nvr = Nvr;
return Nvr;
};

63
code/VideoAccess-VCMP/api/app/lib/models/secret_yingshi.js

@ -0,0 +1,63 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const SecretYingshi = sequelize.define("secretYingshi", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "secret_yingshi_id_uindex"
},
key: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "key",
autoIncrement: false
},
secret: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "secret",
autoIncrement: false
},
token: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "token",
autoIncrement: false
},
expire: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "expire",
autoIncrement: false
}
}, {
tableName: "secret_yingshi",
comment: "",
indexes: []
});
dc.models.SecretYingshi = SecretYingshi;
return SecretYingshi;
};

36
code/VideoAccess-VCMP/api/app/lib/models/vender.js

@ -0,0 +1,36 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
const DataTypes = dc.ORM;
const sequelize = dc.orm;
const Vender = sequelize.define("vender", {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: true,
field: "id",
autoIncrement: true,
unique: "vender_id_uindex"
},
name: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "name",
autoIncrement: false
}
}, {
tableName: "vender",
comment: "",
indexes: []
});
dc.models.Vender = Vender;
return Vender;
};

26
code/VideoAccess-VCMP/api/app/lib/routes/application/index.js

@ -0,0 +1,26 @@
'use strict';
const application = require('../../controllers/application');
module.exports = function (app, router, opts) {
app.fs.api.logAttr['GET/application'] = { content: '获取应用信息', visible: false };
router.get('/application', application.get);
app.fs.api.logAttr['POST/application'] = { content: '创建/修改应用', visible: false };
router.post('/application', application.edit);
app.fs.api.logAttr['PUT/application'] = { content: '禁用应用', visible: false }
router.put('/application', application.put);
app.fs.api.logAttr['DEL/application/:appId'] = { content: '删除应用', visible: false };
router.del('/application/:appId', application.del);
app.fs.api.logAttr['GET/application/check'] = { content: '检查应用状态', visible: false };
router.get('/application/check', application.check);
app.fs.api.logAttr['POST/application'] = { content: '创建/修改应用', visible: false };
router.post('/application', application.edit);
};

32
code/VideoAccess-VCMP/api/app/lib/routes/auth/index.js

@ -1,32 +0,0 @@
'use strict';
const auth = require('../../controllers/auth');
module.exports = function (app, router, opts) {
/**
* @api {Post} login 登录.
* @apiVersion 1.0.0
* @apiGroup Auth
*/
app.fs.api.logAttr['POST/login'] = { content: '登录', visible: true };
router.post('/login', auth.login);
/**
* @api {POST} wxLogin 微信小程序登录.使用手机号密码登录
* @apiVersion 1.0.0
* @apiGroup Auth
*/
app.fs.api.logAttr['POST/wxLogin'] = { content: '微信小程序登录', visible: true };
router.post('/wxLogin', auth.wxLogin);
app.fs.api.logAttr['PUT/logout'] = { content: '登出', visible: false };
router.put('/logout', auth.logout);
/**
* @api {PUT} wxLogout 微信小程序登出
* @apiVersion 1.0.0
* @apiGroup Auth
*/
app.fs.api.logAttr['PUT/wxLogout'] = { content: '登出', visible: false };
router.put('/wxLogout', auth.wxLogout);
};

79
code/VideoAccess-VCMP/api/app/lib/routes/camera/index.js

@ -0,0 +1,79 @@
'use strict';
const camera = require('../../controllers/camera');
const cameraCreate = require('../../controllers/camera/create')
module.exports = function (app, router, opts) {
// 摄像头创建
app.fs.api.logAttr['POST/camera/verify/yingshi'] = { content: '验证萤石摄像头信息', visible: false };
router.post('/camera/verify/yingshi', cameraCreate.verifyYingshi);
app.fs.api.logAttr['POST/camera/create/yingshi'] = { content: '创建萤石摄像头', visible: false };
router.post('/camera/create/yingshi', cameraCreate.createYingshi);
app.fs.api.logAttr['GET/camera/nvr_stream'] = { content: '获取NVR视频流', visible: false };
router.get('/camera/nvr_stream', cameraCreate.getNvrSteam);
app.fs.api.logAttr['GET/nvr/:nvrId/nvr_stream'] = { content: '以 nvrId 获取NVR视频流', visible: false };
router.get('/nvr/:nvrId/nvr_stream', cameraCreate.getNvrSteamById);
app.fs.api.logAttr['POST/camera/create/nvr'] = { content: '记录NVR摄像头', visible: false };
router.post('/camera/create/nvr', cameraCreate.createNvrCamera);
app.fs.api.logAttr['POST/camera/verify/ipc'] = { content: '验证IPC摄像头信息', visible: false };
router.post('/camera/verify/ipc', cameraCreate.verifyIpcCamera);
app.fs.api.logAttr['POST/camera/create/ipc'] = { content: '创建IPC摄像头', visible: false };
router.post('/camera/create/ipc', cameraCreate.createIpcCamera);
app.fs.api.logAttr['GET/camera/sip_list/cascade'] = { content: '获取级联摄像头sip列表', visible: false };
router.get('/camera/sip_list/cascade', cameraCreate.getCascadeSipList);
app.fs.api.logAttr['POST/camera/verify/cascade'] = { content: '验证级联摄像头信息', visible: false };
router.post('/camera/verify/cascade', cameraCreate.verifyCascadeCamera);
app.fs.api.logAttr['GET/camera/cascade_stream'] = { content: '获取级联视频流', visible: false };
router.get('/camera/cascade_stream', cameraCreate.getCascadeSteam);
app.fs.api.logAttr['POST/camera/create/cascade'] = { content: '添加级联摄像头', visible: false };
router.post('/camera/create/cascade', cameraCreate.createCascadeCamera);
app.fs.api.logAttr['GET/camera/cascade_device'] = { content: '获取级联摄像头父级设备', visible: false };
router.get('/camera/cascade_device', cameraCreate.getCascadeCameraGrandParentSip);
// 摄像头创建 END
app.fs.api.logAttr['GET/camera/project'] = { content: '获取摄像头列表及项目绑定信息', visible: false };
router.get('/camera/project', camera.getCameraProject);
app.fs.api.logAttr['GET/camera'] = { content: '获取摄像头信息', visible: false };
router.get('/camera', camera.getCamera);
app.fs.api.logAttr['GET/camera/:cameraId/detail'] = { content: '获取摄像头详情', visible: false };
router.get('/camera/:cameraId/detail', camera.detail);
app.fs.api.logAttr['GET/camera/listAll'] = { content: '获取摄像头详情', visible: false };
router.get('/camera/listAll', camera.getCameraListAll);
app.fs.api.logAttr['PUT/camera/banned'] = { content: '禁用摄像头', visible: false };
router.put('/camera/banned', camera.banned);
app.fs.api.logAttr['DEL/camera/:cameraId'] = { content: '删除摄像头', visible: false };
router.delete('/camera/:cameraId', camera.del);
app.fs.api.logAttr['GET/camera/export'] = { content: '导出摄像头信息', visible: false };
router.get('/camera/export', camera.cameraExport);
app.fs.api.logAttr['GET/camera/ability'] = { content: '获取摄像头能力列表', visible: false };
router.get('/camera/ability', camera.getAbility);
app.fs.api.logAttr['GET/camera/kind'] = { content: '获取摄像头种类列表', visible: false };
router.get('/camera/kind', camera.getKind);
app.fs.api.logAttr['POST/camera/remark'] = { content: '编辑摄像头备注', visible: false };
router.post('/camera/remark', camera.remark);
app.fs.api.logAttr['GET/camera/unique/all'] = { content: '获取全部摄像头,序列号+通道号唯一', visible: false };
router.get('/camera/unique/all', camera.getCmaeraUniqueConfig);
};

23
code/VideoAccess-VCMP/api/app/lib/routes/index.js

@ -4,14 +4,19 @@ const path = require('path');
const fs = require('fs');
module.exports = function (app, router, opts) {
fs.readdirSync(__dirname).forEach((filename) => {
if (filename.indexOf('.') !== 0 &&fs.lstatSync(path.join(__dirname, filename)).isDirectory()) {
fs.readdirSync(path.join(__dirname, filename)).forEach((api) => {
if (api.indexOf('.') == 0 || api.indexOf('.js') == -1) return;
require(`./${filename}/${api}`)(app, router, opts);
});
}
});
fs.readdirSync(__dirname).forEach((filename) => {
if (filename.indexOf('.') !== 0 && fs.lstatSync(path.join(__dirname, filename)).isDirectory()) {
fs.readdirSync(path.join(__dirname, filename)).forEach((api) => {
console.log('加载路由文件:' + filename + '/' + api);
if (api.indexOf('.') == 0 || api.indexOf('.js') == -1) return;
try {
require(`./${filename}/${api}`)(app, router, opts);
} catch (e) {
console.error(e);
}
});
}
});
return router;
return router;
};

26
code/VideoAccess-VCMP/api/app/lib/routes/mirror/index.js

@ -0,0 +1,26 @@
'use strict';
const mirror = require('../../controllers/mirror');
module.exports = function (app, router, opts) {
app.fs.api.logAttr['PUT/mirror'] = { content: '编辑镜像信息', visible: false };
router.put('/mirror', mirror.edit);
app.fs.api.logAttr['PUT/mirror/:mirrorId/id'] = { content: '更新镜像服务ID', visible: false };
router.put('/mirror/:mirrorId/id', mirror.refreshId);
app.fs.api.logAttr['GET/mirror/list'] = { content: '获取镜像信息列表', visible: false };
router.get('/mirror/list', mirror.list);
app.fs.api.logAttr['GET/mirror/:mid'] = { content: '获取指定镜像信息', visible: false };
router.get('/mirror/:mid', mirror.get);
app.fs.api.logAttr['DEL/mirror/:mirrorId'] = { content: '删除镜像信息', visible: false };
router.del('/mirror/:mirrorId', mirror.del);
app.fs.api.logAttr['PUT/mirror/:mirrorId/publish'] = { content: '发布镜像信息', visible: false };
router.put('/mirror/:mirrorId/publish', mirror.publish);
app.fs.api.logAttr['PUT/mirror/:mirrorId/copy'] = { content: '复制镜像信息', visible: false };
router.put('/mirror/:mirrorId/copy', mirror.copy);
};

23
code/VideoAccess-VCMP/api/app/lib/routes/nvr/index.js

@ -0,0 +1,23 @@
'use strict';
const nvr = require('../../controllers/nvr');
module.exports = function (app, router, opts) {
app.fs.api.logAttr['POST/nvr'] = { content: '添加/修改nvr', visible: false };
router.post('/nvr', nvr.edit);
app.fs.api.logAttr['POST/nvr/verify'] = { content: '校验nvr信息', visible: false };
router.post('/nvr/verify', nvr.verify);
app.fs.api.logAttr['GET/nvr'] = { content: '获取nvr', visible: false };
router.get('/nvr', nvr.get);
app.fs.api.logAttr['GET/nvr/detail/:nvrId'] = { content: '获取nvr详情', visible: false };
router.get('/nvr/detail/:nvrId', nvr.detail);
app.fs.api.logAttr['DEL/nvr/:nvrId'] = { content: '删除nvr', visible: false };
router.del('/nvr/:nvrId', nvr.del);
app.fs.api.logAttr['GET/nvr/export'] = { content: '导出nvr信息', visible: false };
router.get('/nvr/export', nvr.nvrExport);
};

52
code/VideoAccess-VCMP/api/app/lib/routes/status/index.js

@ -0,0 +1,52 @@
'use strict';
const status = require('../../controllers/status');
const push = require('../../controllers/status/push');
const alarm = require('../../controllers/status/alarm');
module.exports = function (app, router, opts) {
app.fs.api.logAttr['GET/status'] = { content: '获取状态码', visible: false };
router.get('/status', status.get);
app.fs.api.logAttr['GET/status/simple_all'] = { content: '获取全部状态码简略信息', visible: false };
router.get('/status/simple_all', status.getSimpleAll);
app.fs.api.logAttr['PUT/status/banned'] = { content: '禁用状态码自定义', visible: false };
router.put('/status/banned', status.banned);
app.fs.api.logAttr['POST/status/custom'] = { content: '自定义状态码释义', visible: false };
router.post('/status/custom', status.paraphraseCustom);
app.fs.api.logAttr['POST/status/resolve'] = { content: '编辑解决方案', visible: false };
router.post('/status/resolve', status.resolveEdit);
app.fs.api.logAttr['GET/status/check'] = { content: '查取指定状态码信息', visible: false };
router.get('/status/check', status.statusCheck);
// 信鸽推送
app.fs.api.logAttr['PUT/status/push'] = { content: '编辑推送配置', visible: false };
router.put('/status/push', push.edit);
app.fs.api.logAttr['GET/status/push_list'] = { content: '获取推送配置', visible: false };
router.get('/status/push_list', push.getStatusPushList);
app.fs.api.logAttr['PUT/status/push/banned'] = { content: '禁用推送配置', visible: false };
router.put('/status/push/banned', push.banned);
app.fs.api.logAttr['DEL/status/push/:configId'] = { content: '删除推送配置', visible: false };
router.del('/status/push/:configId', push.del);
app.fs.api.logAttr['GET/status/push/:configId/copy'] = { content: '复制推送配置', visible: false };
router.get('/status/push/:configId/copy', push.copy);
app.fs.api.logAttr['GET/status/push/:configId/detail'] = { content: '获取推送记录', visible: false };
router.get('/status/push/:configId/log', push.pushLog);
// 信鸽推送 END
// 状态告警
app.fs.api.logAttr['POST/status/alarm'] = { content: '保存或更新告警信息', visible: false };
router.post('/status/alarm', alarm.record);
app.fs.api.logAttr['PUT/status/alarm/confirm'] = { content: '确认告警信息', visible: false };
router.put('/status/alarm/confirm', alarm.confirm);
};

8
code/VideoAccess-VCMP/api/app/lib/routes/vender/index.js

@ -0,0 +1,8 @@
'use strict';
const vender = require('../../controllers/vender');
module.exports = function (app, router, opts) {
app.fs.api.logAttr['GET/vender'] = { content: '获取设备厂商', visible: false };
router.get('/vender', vender.getVenderList);
};

377
code/VideoAccess-VCMP/api/app/lib/schedule/cameraStatePush.js

@ -0,0 +1,377 @@
const moment = require('moment')
module.exports = function (app, opts) {
const cameraOnlinePush = app.fs.scheduleInit(
{
interval: '0 */15 * * * *',
// interval: '* */1 * * * *',
// interval: '*/5 * * * * *',
immediate: false,
proRun: true,
},
async () => {
try {
const { models, ORM: sequelize } = app.fs.dc
const { pushBySms, pushByEmail } = app.fs.utils
const configRes = await models.CameraStatusPushConfig.findAll({
where: {
forbidden: false
},
include: [
{
model: models.CameraStatusPushMonitor,
attributes: ['cameraId'],
required: false,
duplicating: true
},
{
model: models.CameraStatusPushReceiver,
attributes: ['receiver'],
duplicating: false,
required: false,
},
],
})
const timeNow = moment().startOf('minute').format()
for (let c of configRes) {
console.log('上下线推送方式', c.pushWay,);
// 查配置信息所对应的摄像头15min内的在离线状态
const cameraIds = c.cameraStatusPushMonitors.map(m => m.cameraId)
const offlineStatusRes = await models.CameraStatusOfflineLog.findAll({
where: {
cameraId: { $in: cameraIds },
// !!! 時間限制
time: {
$between: [moment(timeNow).subtract(15, 'minutes').format(), timeNow]
}
},
include: [{
model: models.Camera,
attributes: ['name']
}],
order: [['time', 'ASC']],
})
console.log('上下线推送路线记录', offlineStatusRes);
if (offlineStatusRes.length) {
const cameraStatusMap = {}
// 当前逻辑
// 只要最后状态是离线 就做离线推送
// 只要出现一次上线 就做上线推送
for (let s of offlineStatusRes) {
if (cameraStatusMap[s.cameraId]) {
cameraStatusMap[s.cameraId].status.push({
status: s.status,
time: s.time,
})
} else {
cameraStatusMap[s.cameraId] = {
status: [{
status: s.status,
time: s.time,
}],
cameraId: s.cameraId,
name: s.camera.name,
}
}
}
let offArr = []
let onArr = []
for (let k of Object.keys(cameraStatusMap).sort()) {
const data = cameraStatusMap[k]
if (data.status[0].status == 'OFF') {
offArr.push({
cameraId: data.cameraId,
name: data.name,
time: data.status[0].time,
})
}
const onLineIndex = data.status.findIndex(s => s.status == 'ON')
if (onLineIndex >= 0) {
const onLineLastOffIndex = data.status.findIndex((s, i) => s.status == 'OFF' && i > onLineIndex)
// 当前在线记录的上一次离线记录
let onlineData = {
cameraId: data.cameraId,
name: data.name,
time: data.status[onLineIndex].time,
}
if (onLineLastOffIndex >= 0) {
onlineData.offTime = data.status[onLineLastOffIndex].time
}
onArr.push(onlineData)
}
}
// 查当前配置由谁配置
const corUser = await app.fs.authRequest.get(`user/${c.createUser}/message`, {
query: {
// TODO 这里拿不到 token 去鉴权 怎么能系统间鉴权呢
// 暂时取消了鉴权系统对这里的判断
token: ''
}
})
const receiver = c.cameraStatusPushReceivers.map(r => r.receiver)
const logData = {
pushConfigId: c.id,
receiver: receiver,
timing: c.timing,
time: moment(timeNow).format(),
pushWay: c.pushWay,
// camera: cameraIds,
}
// 离线推送
console.log('上下线推送数据', offArr, onArr);
console.log('上下线推送接收', receiver);
if (offArr.length && c.noticeWay && c.noticeWay.includes('offline') && receiver.length) {
if (c.pushWay == 'email') {
// 邮件
let text = `${corUser[0].username}】账号下的设备,截止【${moment(timeNow).format('MM月DD日 HH时mm分')}】,新增${offArr.length}个设备掉线:\n`
text += offArr.map(o => `${o.name}】于【${moment(o.time).format('MM月DD日 HH时mm分')}】掉线,`).join('\n')
text += `\n请及时处理!`
await pushByEmail({
email: receiver,
title: '尚视设备离线通知',
text,
})
await models.CameraStatusPushLog.create({ ...logData, pushWay: 'email', noticeWay: ['offline'], camera: offArr.map(o => o.cameraId) })
} else if (c.pushWay == 'phone') {
// 短信
let templateParam = {
name: `${corUser[0].username}`,
}
let useTempCode = 'SMS_248205074'
// let text = `【${corUser[0].username}】账号下的`
if (offArr.length == 1) {
// text += `【${offArr[0].name}】离线,请及时处理!【${moment(offArr[0].time).format('MM月DD日 HH时mm分')}】`
templateParam.deviceName = `${offArr[0].name}`
templateParam.timeRange = moment(offArr[0].time).format('MM月DD日 HH时mm分')
} else {
let text = ''
text += offArr.map(o => `${o.name}`).join('')
if (text.length > 35) {
text = text.substring(0, 35) + '...'
// text += `等${offArr.length}个摄像头离线`
templateParam.deviceCount = offArr.length
useTempCode = 'SMS_248250074'
}
templateParam.deviceName = text
// text += `,请及时处理!【${moment().format('MM月DD日HH时mm分')}-${moment(timeNow).subtract(15, 'minutes').format('MM月DD日HH时mm分')}】`
templateParam.timeRange = `${moment().format('MM月DD日HH时mm分')} -${moment(timeNow).subtract(15, 'minutes').format('MM月DD日HH时mm分')}`
}
await pushBySms({
phone: receiver,
templateCode: useTempCode,
templateParam: templateParam,
})
await models.CameraStatusPushLog.create({ ...logData, pushWay: 'phone', noticeWay: ['offline'], camera: offArr.map(o => o.cameraId) })
}
}
// 上线推送
if (onArr.length && c.noticeWay && c.noticeWay.includes('online') && receiver.length) {
if (c.pushWay == 'email') {
// 邮件
const outTimeCameraOff = onArr.filter(a => !a.offTime)
if (outTimeCameraOff.length) {
let cameraIds = outTimeCameraOff.map(a => a.cameraId)
const lastOfflineRes = await models.CameraStatusOfflineLog.findAll({
where: {
cameraId: { $in: cameraIds },
status: 'OFF',
time: {
$lt: moment(timeNow).subtract(15, 'minutes').format()
}
},
group: ['cameraId'],
attributes: ['cameraId', [sequelize.fn('max', sequelize.col('time')), 'time']],
})
for (let a of onArr) {
if (!a.offTime) {
const lastOffline = lastOfflineRes.find(l => l.cameraId == a.cameraId)
if (lastOffline) {
a.offTime = lastOffline.time
}
}
}
}
let text = `${corUser[0].username}】账号下的设备:\n`
text += onArr.map(o => `${o.name}】于【${moment(o.offTime).format('MM月DD日HH时mm分')}】掉线,【${moment(o.time).format('MM月DD日HH时mm分')}】已恢复`).join('\n')
await pushByEmail({
email: receiver,
title: '尚视设备上线通知',
text,
})
await models.CameraStatusPushLog.create({ ...logData, pushWay: 'email', noticeWay: ['online'], camera: onArr.map(o => o.cameraId) })
} else if (c.pushWay == 'phone') {
// 短信
// let text = `【${corUser[0].username}】账号下的`
let templateParam = {
name: `${corUser[0].username}`,
}
let useTempCode = 'SMS_248250073'
if (onArr.length == 1) {
// text += `【${onArr[0].name}】已恢复上线,请及时处理!【${moment(onArr[0].time).format('MM月DD日 HH时mm分')}】`
templateParam.deviceName = `${onArr[0].name}`
templateParam.date = moment(onArr[0].time).format('MM月DD日 HH时mm分')
} else {
let text = ''
text += onArr.map(o => `${o.name}`).join('')
let timeRange = `${moment().format('MM月DD日HH时mm分')}-${moment(timeNow).subtract(15, 'minutes').format('MM月DD日HH时mm分')}】!`
if (text.length > 35) {
text = text.substring(0, 35) + '...'
// text += `等${onArr.length}个摄像头已恢复上线!`
templateParam.deviceCount = onArr.length
useTempCode = 'SMS_248120080'
templateParam.timeRange = timeRange
} else {
templateParam.date = timeRange
}
templateParam.deviceName = text
}
await pushBySms({
phone: receiver,
templateCode: useTempCode,
templateParam: templateParam,
})
await models.CameraStatusPushLog.create({ ...logData, pushWay: 'phone', noticeWay: ['online'], camera: onArr.map(o => o.cameraId) })
}
}
}
}
} catch (error) {
console.error('15min 上下线推送错误:', error);
}
}
)
// 摄像头离线定时统计推送
const cameraOnlineTimingPush = app.fs.scheduleInit(
{
interval: '0 */5 * * * *',
// interval: '*/10 * * * * *', // dev
immediate: false,
// immediate: true, // dev
proRun: true,
},
async () => {
try {
const { models, ORM: sequelize } = app.fs.dc
const { pushBySms, pushByEmail } = app.fs.utils
const timeNow = moment().format()
const configRes = await models.CameraStatusPushConfig.findAll({
where: {
forbidden: false,
noticeWay: {
$contains: ['timing']
},
// !!! 此时此刻
timing: moment(timeNow).format('HH:mm')
},
include: [
{
model: models.CameraStatusPushMonitor,
attributes: ['cameraId'],
required: false,
duplicating: true
},
{
model: models.CameraStatusPushReceiver,
attributes: ['receiver'],
duplicating: false,
required: false,
},
],
})
for (let c of configRes) {
// 查配置信息所对应的摄像头在离线状态
const cameraIds = c.cameraStatusPushMonitors.map(m => m.cameraId)
const offlineRes = await models.Camera.findAll({
where: {
id: { $in: cameraIds },
},
attributes: ['id', 'name'],
include: [{
model: models.GbCamera,
attributes: ['id', 'online'],
required: true,
where: {
online: 'OFF'
}
}],
})
if (offlineRes.length) {
// 查当前配置由谁配置
const corUser = await app.fs.authRequest.get(`user/${c.createUser}/message`, {
query: {
token: ''
}
})
const receiver = c.cameraStatusPushReceivers.map(r => r.receiver)
if (receiver.length) {
const logData = {
pushConfigId: c.id,
receiver: receiver,
timing: c.timing,
time: moment(timeNow).format(),
pushWay: c.pushWay,
camera: offlineRes.map(o => o.id),
}
if (c.pushWay == 'email') {
// 邮件
const offlineTimeRes = await models.CameraStatusOfflineLog.findAll({
attributes: ['cameraId', [sequelize.fn('max', sequelize.col('time')), 'time']],
where: {
cameraId: { $in: offlineRes.map(oc => oc.id) },
status: 'OFF',
},
group: ['cameraId'],
})
if (offlineTimeRes.length) {
let text = `${corUser[0].username}】账号下的设备,截止${moment(timeNow).format('MM月DD日 HH时mm分')},新增${offlineRes.length}个设备掉线:\n`
text += offlineTimeRes.map(o => {
let corCamera = offlineRes.find(c => c.id == o.cameraId)
if (corCamera) {
return `${(corCamera || {}).name}】于【${moment(o.time).format('MM月DD日 HH时mm分')}】掉线,`
}
return ''
}).join('\n')
text += `\n请及时处理!`
await pushByEmail({
email: receiver,
title: '尚视设备离线定时统计通知',
text,
})
await models.CameraStatusPushLog.create({ ...logData, pushWay: 'email', noticeWay: ['timing'] })
}
} else if (c.pushWay == 'phone') {
// 短信
// let text = `【${corUser[0].username}】账号下截止${moment(timeNow).format('YYYY年MM月DD日 HH时')},有${offlineRes.length}个设备掉线,请及时处理!`
await pushBySms({
phone: receiver,
templateCode: 'SMS_248095009',
templateParam: {
name: corUser[0].username,
time: moment(timeNow).format('YYYY年MM月DD日 HH时'),
deviceCount: offlineRes.length,
},
})
await models.CameraStatusPushLog.create({ ...logData, pushWay: 'phone', noticeWay: ['timing'] })
}
}
}
}
} catch (error) {
console.error(error);
}
}
)
return {
cameraOnlinePush,
cameraOnlineTimingPush,
}
}

210
code/VideoAccess-VCMP/api/app/lib/schedule/freshYingshiMsg.js

@ -0,0 +1,210 @@
const schedule = require('node-schedule');
const moment = require('moment')
module.exports = function (app, opts) {
const freshYingshiState = app.fs.scheduleInit(
{
interval: '50 */4 * * * *',
// interval: '*/3 * * * *',
// immediate: true,
proRun: true,
},
async () => {
console.log('萤石状态查询 ', moment().format('YYYY-MM-DD HH:mm:ss'));
try {
const startTime = moment()
const { models } = app.fs.dc
const { token4yingshi, getYingshiPlayUrl, cameraStatePush } = app.fs.utils
const secretRes = await models.SecretYingshi.findAll()
let deviceList = []
for (let s of secretRes) {
const tokenYingshi = await token4yingshi(s.dataValues)
// 查询所有设备
let pageStart = 0
while (pageStart >= 0) {
const deviceRes = await app.fs.yingshiRequest.post('lapp/device/list', {
query: {
accessToken: tokenYingshi,
pageStart,
pageSize: 50
}
})
if (deviceRes.code == 200) {
deviceList = deviceList.concat.apply(deviceList, deviceRes.data)
for (let d of deviceRes.data) {
// if(d.deviceSerial = 'J29900896'){
// console.log(d);
// }
const existD = await models.GbCamera.findOne({
where: {
streamid: d.deviceSerial
}
})
let storageD = {
level: 0,
ipctype: 'yingshi',
streamid: d.deviceSerial,
online: d.status == 1 ? 'ON' : 'OFF',
name: d.deviceName,
}
if (existD) {
// 创建过但是没有赋予did
if (!existD.did) {
const yingshiCount = await models.GbCamera.count({
where: {
ipctype: 'yingshi',
id: { $lt: existD.id }
}
})
let random2place = Math.floor(Math.random() * 99)
if (random2place < 10) {
random2place = '0' + random2place
}
storageD.did = 'SE' + 'Dvs' + 'Y02' + 'T' + moment().format('YYMMDD') + (yingshiCount + 1) + random2place
await models.GbCamera.update(storageD, {
where: {
id: existD.id
}
})
}
// 状态改变
if (existD.online != storageD.online) {
// 状态更新
if (storageD.online == 'ON' && !existD.playUrl) {
// 播放地址更新
const playUrlRes = await getYingshiPlayUrl({ deviceSerial: d.deviceSerial, token: tokenYingshi })
storageD.playUrl = playUrlRes
}
// 在离线状态更新
await models.GbCamera.update(storageD, {
where: {
id: existD.id,
updateTime: moment().format()
}
})
// 状态向前端页面推送
cameraStatePush({
gbId: existD.id,
online: storageD.online,
ipctype: storageD.ipctype,
})
// 记录在离线日志
const cameraRes = await models.Camera.findAll({
where: {
gbId: existD.id
}
})
const nowTime = moment().format()
let bulkCreateData = cameraRes.map(c => {
return {
cameraId: c.id,
status: storageD.online,
time: nowTime
}
})
// console.log('上下线记录', bulkCreateData);
if (bulkCreateData.length) {
await models.CameraStatusOfflineLog.bulkCreate(bulkCreateData)
}
}
} else {
// 播放地址更新
const playUrlRes = await getYingshiPlayUrl({ deviceSerial: d.deviceSerial, token: tokenYingshi })
storageD.playUrl = playUrlRes
// 生成 did
const yingshiCount = await models.GbCamera.count({
where: {
ipctype: 'yingshi'
}
})
let random2place = Math.floor(Math.random() * 99)
if (random2place < 10) {
random2place = '0' + random2place
}
storageD.did = 'SE' + 'Dvs' + 'Y02' + 'T' + moment().format('YYMMDD') + (yingshiCount + 1) + random2place
const yingshiRes = await models.GbCamera.create(storageD)
await models.Camera.update({
gbId: yingshiRes.id
}, {
where: {
serialNo: d.deviceSerial
}
})
}
}
if (deviceRes.data.length == 50) {
pageStart++
} else {
pageStart = -1
}
}
}
}
// console.log(deviceList);
console.info(`萤石设备 ${deviceList.length} 状态查询用时 ${moment().diff(startTime, 'seconds')} s`)
} catch (error) {
app.fs.logger.error(`sechedule: freshYingshiState, error: ${error}`);
}
});
const freshYingshiPlayUrl = app.fs.scheduleInit(
{
// interval: '0 0 4 */1 *',
// interval: '*/30 * * * *',
interval: '0 34 5 1 * *',
immediate: true,
proRun: true,
},
async () => {
try {
const startTime = moment()
const { models } = app.fs.dc
const { token4yingshi, getYingshiPlayUrl } = app.fs.utils
const secretRes = await models.SecretYingshi.findAll()
for (let s of secretRes) {
const tokenYingshi = await token4yingshi(s.dataValues)
// 查询所有设备
let pageStart = 0
while (pageStart >= 0) {
const deviceRes = await app.fs.yingshiRequest.post('lapp/device/list', {
query: {
accessToken: tokenYingshi,
pageStart,
pageSize: 50
}
})
if (deviceRes.code == 200) {
for (let d of deviceRes.data) {
const playUrlRes = await getYingshiPlayUrl({ deviceSerial: d.deviceSerial, token: tokenYingshi })
await models.GbCamera.update({
playUrl: playUrlRes,
}, {
where: {
streamid: d.deviceSerial
}
})
}
if (deviceRes.data.length == 50) {
pageStart++
} else {
pageStart = -1
}
}
}
}
console.info(`萤石设备播放地址更新查询用时 ${moment().diff(startTime, 'seconds')} s`)
} catch (error) {
app.fs.logger.error(`sechedule: freshYingshiPlayUrl, error: ${error}`);
}
}
)
return {
freshYingshiState,
freshYingshiPlayUrl
}
}

36
code/VideoAccess-VCMP/api/app/lib/schedule/index.js

@ -0,0 +1,36 @@
'use strict';
const fs = require('fs');
const nodeSchedule = require('node-schedule');
// 将定时任务汇集未来可根据需要选取操作
module.exports = async function (app, opts) {
const scheduleInit = ({
interval, immediate, proRun,
}, callback) => {
if (proRun && opts.dev) {
return;
}
const j = nodeSchedule.scheduleJob(interval, callback);
if (immediate && (!proRun || (proRun && !opts.dev))) {
setTimeout(callback, 0)
}
return j;
}
app.fs.scheduleInit = scheduleInit
fs.readdirSync(__dirname).forEach((filename) => {
if (!['index.js'].some(f => filename == f)) {
const scheduleList = require(`./${filename}`)(app, opts)
for (let k of Object.keys(scheduleList)) {
console.info(`定时任务 ${k} 启动`);
}
app.fs.schedule = {
...app.fs.schedule,
...scheduleList,
}
}
});
};

40
code/VideoAccess-VCMP/api/app/lib/service/mqttVideoServer.js

@ -0,0 +1,40 @@
'use strict';
const mqtt = require('mqtt');
module.exports = async function factory (app, opts) {
console.info(`mqtt connecting ${opts.mqtt.mqttVideoServer}`);
const client = mqtt.connect(opts.mqtt.mqttVideoServer);
client.on('connect', function () {
console.info(`mqtt connect success ${opts.mqtt.mqttVideoServer}`);
client.subscribe('topic/test', { qos: 0 });//订阅主题为test的消息
})
client.on('error', function (e) {
console.error(`mqtt connect failed ${opts.mqtt.mqttVideoServer}`);
app.fs.logger.error('info', '[FS-AUTH-MQTT]', `mqtt connect failed ${opts.mqtt.mqttVideoServer}`);
})
client.on('message', async (top, message) => {
let msgStr = message.toString();
let msg = JSON.parse(msgStr.replace(/\\/g, ''));
if (msg.id && msg.online) {
const { cameraStatePush } = app.fs.utils
const { models } = app.fs.dc
const gbCameraRes = await models.GbCamera.findOne({
where: {
id: msg.id
}
})
if (gbCameraRes) {
cameraStatePush({
gbId: msg.id,
online: msg.online,
ipctype: gbCameraRes.ipctype,
})
}
}
});
app.mqttVideoServer = client
}

67
code/VideoAccess-VCMP/api/app/lib/service/paasRequest.js

@ -0,0 +1,67 @@
'use strict';
const request = require('superagent')
class paasRequest {
constructor(root, { query = {} } = {}, option) {
this.root = root;
this.query = query
this.option = option
}
#buildUrl = (url) => {
return `${this.root}/${url}`;
}
#resultHandler = (resolve, reject) => {
return (err, res) => {
if (err) {
reject(err);
} else {
resolve(res[this.option.dataWord]);
}
};
}
get = (url, { query = {}, header = {} } = {}) => {
return new Promise((resolve, reject) => {
request.get(this.#buildUrl(url)).set(header).query(Object.assign(query, this.query)).end(this.#resultHandler(resolve, reject));
})
}
post = (url, { data = {}, query = {}, header = {} } = {}) => {
return new Promise((resolve, reject) => {
request.post(this.#buildUrl(url)).set(header).query(Object.assign(query, this.query)).send(data).end(this.#resultHandler(resolve, reject));
})
}
put = (url, { data = {}, header = {}, query = {}, } = {}) => {
return new Promise((resolve, reject) => {
request.put(this.#buildUrl(url)).set(header).query(Object.assign(query, this.query)).send(data).end(this.#resultHandler(resolve, reject));
})
}
delete = (url, { header = {}, query = {} } = {}) => {
return new Promise((resolve, reject) => {
request.delete(this.#buildUrl(url)).set(header).query(Object.assign(query, this.query)).end(this.#resultHandler(resolve, reject));
})
}
}
function factory (app, opts) {
if (opts.pssaRequest) {
try {
for (let r of opts.pssaRequest) {
if (r.name && r.root) {
app.fs[r.name] = new paasRequest(r.root, { ...(r.params || {}) }, { dataWord: r.dataWord || 'body' })
} else {
throw 'opts.pssaRequest 参数错误!'
}
}
} catch (error) {
console.error(error)
process.exit(-1);
}
}
}
module.exports = factory;

41
code/VideoAccess-VCMP/api/app/lib/service/redis.js

@ -0,0 +1,41 @@
'use strict';
// https://github.com/luin/ioredis
const redis = require("ioredis")
module.exports = async function factory (app, opts) {
let client = opts.redis.pwd ?
new redis.Cluster([
{
host: opts.redis.host,
port: opts.redis.port
}
], {
redisOptions: {
password: opts.redis.pwd,
},
})
: new redis(opts.redis.port, opts.redis.host, {
password: opts.redis.pwd,
});
client.on("error", function (err) {
app.fs.logger.error('info', '[FS-AUTH-REDIS]', `redis connect error. ${opts.redis.host + ':' + opts.redis.port}`);
// console.error("Error :", err);
// process.exit(-1);
});
client.on('connect', function () {
console.info(`redis connect success ${opts.redis.host + ':' + opts.redis.port}`);
})
// 自定义方法
async function hdelall (key) {
const obj = await client.hgetall(key);
await client.hdel(key, Object.keys(obj))
}
app.redis = client
app.redisTools = {
hdelall,
}
}

33
code/VideoAccess-VCMP/api/app/lib/service/socket.js

@ -0,0 +1,33 @@
'use strict';
module.exports = async function factory (app, opts) {
app.socket.on('connection', async (socket) => {
console.info('WEB_SOCKET ' + socket.handshake.query.token + ' 已连接:' + socket.id);
socket.on('disconnecting', async (reason) => {
console.info('WEB_SOCKET ' + socket.handshake.query.token + ' 已断开连接:' + reason);
})
})
// 使用测试 保持链接
setInterval(async () => {
const { connected } = app.socket.sockets
const roomId = 'ROOM_' + Math.random()
// if (connected) {
// for (let c in connected) {
// connected[c].join(roomId)
// }
// app.socket.to(roomId).emit('TEST', { someProperty: `【星域 ROOM:${roomId}】呼叫自然选择号!!!`, })
// }
app.socket.emit('TEST', { someProperty: '【广播】呼叫青铜时代号!!!', })
// app.socket.emit('CAMERA_ONLINE', {
// ipctype: 'yingshi',
// online: Math.random() > 0.5 ? 'ON' : 'OFF',
// gbId: Math.floor(Math.random() * 100),
// name: 'cameraName'
// })
}, 3000)
}

171
code/VideoAccess-VCMP/api/app/lib/utils/camera.js

@ -0,0 +1,171 @@
module.exports = function (app, opts) {
async function getGbCameraLevel3ByStreamId ({ streamId }) {
const { models } = app.fs.dc
if (!streamId) {
let errMsg = '参数错误'
throw errMsg
}
const streamIdArr = [streamId]
const findChild = async (streamIdArr) => {
const childRes = await models.GbCamera.findAll({
where: {
parent: { $in: streamIdArr },
}
})
if (!childRes.length || childRes.some(c => c.level == 2)) {
return childRes
} else {
const nextLevelStreamIds = childRes.map(level => level.streamid)
return findChild(nextLevelStreamIds)
}
}
const cameraRes = await findChild(streamIdArr)
return cameraRes
}
async function getGbCameraLevel1ByStreamId ({ streamId, where = {} }) {
const { models } = app.fs.dc
if (!streamId) {
let errMsg = '参数错误'
throw errMsg
}
const findParent = async (streamId) => {
const parentRes = await models.GbCamera.findOne({
where: {
streamid: streamId,
...where
}
})
if (!parentRes || parentRes.level == 0) {
return parentRes
} if (!parentRes.parent) {
return
} else {
const lastLevelStreamId = parentRes.parent
return findParent(lastLevelStreamId)
}
}
const deviceRes = await findParent(streamId)
return deviceRes
}
async function verifyYingshiInfo ({ serialNo } = {}) {
const { varifyYingshiBelongSecretBySerialNo } = app.fs.utils
const beloneSecret = await varifyYingshiBelongSecretBySerialNo(serialNo)
if (!beloneSecret) {
let errMsg = '请联系管理员核验或新增萤石云权限'
throw errMsg
}
return beloneSecret
}
async function verifyIpcInfo ({ serialNo } = {}) {
const { models } = app.fs.dc
const gbCameraRes = await models.GbCamera.findOne({
where: {
streamid: serialNo,
// ipctype: 'ipc'
}
})
if (!gbCameraRes) {
let errMsg = '没有找到已接入的 IPC 服务信息'
throw errMsg
}
return gbCameraRes.dataValues
}
async function verifyCascadeInfo ({ streamId } = {}) {
const { models } = app.fs.dc
const gbCameraRes = await models.GbCamera.findOne({
where: {
streamid: streamId,
level: 0,
ipctype: '级联'
}
})
if (!gbCameraRes) {
let errMsg = '没有找到已接入的级联摄像头服务信息'
throw errMsg
}
return gbCameraRes.dataValues
}
async function getPlayUrl ({ topSerialNo, serialNo }) {
const { cameraPlayHost } = opts
if (!topSerialNo || !serialNo) {
return null
}
return {
liveUrl: {
sd: {
'WS-RAW': `${cameraPlayHost.ws}/jessica/${topSerialNo}/${serialNo}`,
'WS-FLV': `${cameraPlayHost.ws}/jessica/${topSerialNo}/${serialNo}.flv`,
'HTTP-FLV': `${cameraPlayHost.httpFlv}/hdl/${topSerialNo}/${serialNo}.flv`,
'HLS': `${cameraPlayHost.httpFlv}/hls/${topSerialNo}/${serialNo}.m3u8`,
'RTMP': `${cameraPlayHost.rtmp}/${topSerialNo}/${serialNo}`,
'RTSP': `${cameraPlayHost.rtsp}/${topSerialNo}/${serialNo}`,
}
}
}
}
async function cameraStatePush ({ gbId, online, ipctype }) {
try {
const { models } = app.fs.dc
const { connected } = app.socket.sockets
const roomId = 'ROOM_' + Math.random() + '_' + gbId
let cameraName = ''
if (connected) {
// TODO 摄像头绑定关系查询
for (let c in connected) {
const { client: { conn: { request: { _query } } } } = connected[c]
if (_query && _query.token) {
let userInfo = await app.redis.hget(_query.token, 'userInfo');
if (userInfo) {
userInfo = JSON.parse(userInfo)
const corCameraRes = await models.Camera.findOne({
where: {
gbId: gbId,
createUserId: userInfo.id
}
})
// TODO 管理员判断
if (corCameraRes) {
cameraName = corCameraRes.name
connected[c].join(roomId)
}
}
}
}
app.socket.to(roomId).emit('CAMERA_ONLINE', {
ipctype: ipctype,
online: online,
gbId: gbId,
name: cameraName
})
}
} catch (error) {
app.fs.logger.error(`utils: cameraStatePush, error: ${error}`);
}
}
return {
getGbCameraLevel1ByStreamId,
getGbCameraLevel3ByStreamId,
verifyYingshiInfo,
verifyIpcInfo,
verifyCascadeInfo,
getPlayUrl,
cameraStatePush,
}
}

16
code/VideoAccess-VCMP/api/app/lib/utils/index.js

@ -0,0 +1,16 @@
'use strict';
const path = require('path');
const fs = require('fs');
module.exports = async function (app, opts) {
fs.readdirSync(__dirname).forEach((filename) => {
if (!['index.js'].some(f => filename == f)) {
const utils = require(`./${filename}`)(app, opts)
app.fs.utils = {
...app.fs.utils,
...utils,
}
}
});
};

54
code/VideoAccess-VCMP/api/app/lib/utils/oauth2.js

@ -0,0 +1,54 @@
const fs = require('fs');
module.exports = function (app, opts) {
async function oauthParseAuthHeader (auth) {
if (!auth) {
throw new Error('参数无效: 未包含Authorization头');
}
const authSplit = auth.split('Basic');
if (authSplit.length != 2) {
throw new Error('参数无效: Authorization头格式无效,请检查是否包含了"Basic "');
}
const authCode = authSplit[1];
const apikey = Buffer.from(authCode, 'base64').toString();
const keySplit = apikey.split(':');
if (keySplit.length != 2) {
throw new Error('参数无效:请检查Authorization头内容是否经过正确Base64编码');
}
return keySplit;
}
async function oauthParseBody (body, type) {
let checked = true, token = '';
if (type == 'apply' && body['grant_type'] != 'client_credentials') {
checked = false;
} else if (type == 'refresh') {
if (body['grant_type'] != 'refresh_token' || body['token'] == null) {
checked = false;
} else {
token = body['token'];
}
} else if (type == 'invalidate') {
if (body['token'] == null) {
checked = false;
} else {
token = body['token'];
}
}
if (!checked) {
throw new Error('参数无效:请求正文中未包含正确的信息');
}
return token;
}
return {
oauthParseAuthHeader,
oauthParseBody
}
}

62
code/VideoAccess-VCMP/api/app/lib/utils/push.js

@ -0,0 +1,62 @@
'use strict';
const moment = require('moment')
const Core = require('@alicloud/pop-core');
const nodemailer = require('nodemailer')
module.exports = function (app, opts) {
const pushBySms = async ({ phone = [], templateCode, templateParam } = {}) => {
try {
if (phone.length) {
const client = new Core({
accessKeyId: opts.sms.accessKey,
accessKeySecret: opts.sms.accessSecret,
endpoint: 'http://dysmsapi.aliyuncs.com',//固定
apiVersion: '2017-05-25'//固定
});
const SendSmsRes = await client.request('SendSms', {
"PhoneNumbers": phone.join(','),//接收短信的手机号码。
"SignName": "飞尚尚视",//短信签名名称。必须是已添加、并通过审核的短信签名。
"TemplateCode": templateCode,//短信模板ID。必须是已添加、并通过审核的短信签名;且发送国际/港澳台消息时,请使用国际/港澳台短信模版。
"TemplateParam": JSON.stringify(templateParam)//短信模板变量对应的实际值,JSON格式。
}, {
method: 'POST'
});
return SendSmsRes
}
} catch (error) {
throw error
}
}
const pushByEmail = async ({ email = [], title, text = '', html = '', attachments = undefined } = {}) => {
try {
let transporter = nodemailer.createTransport({
host: opts.email.host,
port: opts.email.port,
secure: true,
auth: {
user: opts.email.sender.address,
pass: opts.email.sender.password,
}
});
// send mail with defined transport object
await transporter.sendMail({
from: `${opts.email.sender.name}<${opts.email.sender.address}>`, // sender address
to: email.join(','), // list of receivers 逗号分隔字符串
subject: title, // Subject line
text: text, // plain text body
html: html, // html body
attachments: attachments
});
} catch (error) {
throw error
}
}
return {
pushByEmail,
pushBySms,
}
}

158
code/VideoAccess-VCMP/api/app/lib/utils/token4yingshi.js

@ -0,0 +1,158 @@
'use strict';
const moment = require('moment')
module.exports = function (app, opts) {
async function token4yingshi ({ key, secret, token, expire } = {}) {
const { models } = app.fs.dc
if (!key || !secret) {
throw '参数 { key, secret } 缺一不可'
}
if (token && expire && moment().isBefore(moment(expire))) {
return token
} else {
const secretRes = await models.SecretYingshi.findOne({
where: { key, secret }
})
if (secretRes && secretRes.expire && secretRes.token && moment().isBefore(moment(secretRes.expire))) {
return secretRes.token
}
}
// 也可以做基于 redis 的缓存
const tokenRes = await app.fs.yingshiRequest.post(`lapp/token/get`, {
query: {
appKey: key,
appSecret: secret
}
})
if (tokenRes.code == 200 && tokenRes.data) {
const { accessToken, expireTime } = tokenRes.data
await models.SecretYingshi.update({
token: accessToken,
expire: expireTime
}, {
where: {
key, secret
}
})
return accessToken
} else {
throw {
msg: '未能获取萤石token',
key, secret,
tokenRes
}
}
}
async function varifyYingshiBelongSecretBySerialNo (serialNo) {
const { models } = app.fs.dc
const serialNo_ = String(serialNo).toUpperCase()
const secretRes = await models.SecretYingshi.findAll()
let beloneSecret = null
for (let s of secretRes) {
const tokenYingshi = await token4yingshi(s.dataValues)
// 检测设备所属
const cameraState = await app.fs.yingshiRequest.post('lapp/device/info', {
query: {
accessToken: tokenYingshi,
deviceSerial: serialNo_
}
})
if (cameraState.code == 200) {
beloneSecret = {
...s.dataValues,
token: tokenYingshi
}
break
}
}
return beloneSecret
}
const getYingshiPlayUrl = async ({ deviceSerial, token }) => {
const protocolMap = {
ezopen: 1,
hls: 2,
rtmp: 3,
flv: 4,
}
const qualityMap = {
hd: 1,
sd: 2,
}
const typeMap = {
// live: 1,
local: 2,
cloud: 3
}
let playUrl = {
liveUrl: {// 直播
hd: {// 高清
rtmp: '',
hls: '',
flv: '',
ezopen: '',
},
sd: {// 标清
rtmp: '',
hls: '',
flv: '',
ezopen: '',
}
},
replayUrl: {// 回放
cloud: '',
local: '',
}
}
for (let protocol in protocolMap) {
for (let quality in qualityMap) {
const playUrlRes = await app.fs.yingshiRequest.post('lapp/v2/live/address/get', {
query: {
accessToken: token,
deviceSerial: deviceSerial,
protocol: protocolMap[protocol],
quality: qualityMap[quality],
}
})
if (playUrlRes.code == 200) {
playUrl.liveUrl[quality][protocol] = playUrlRes.data.url
} else {
// return null
}
}
}
for (let type in typeMap) {
try {
const playUrlRes = await app.fs.yingshiRequest.post('lapp/v2/live/address/get', {
query: {
accessToken: token,
deviceSerial: deviceSerial,
type: typeMap[type],
}
})
if (playUrlRes.code == 200) {
playUrl.replayUrl[type] = playUrlRes.data.url
} else {
// return null
}
} catch (error) {
app.fs.logger.error(`sechedule: freshYingshiPlayUrl, error: ${error}`);
}
}
return playUrl
}
return {
token4yingshi,
varifyYingshiBelongSecretBySerialNo,
getYingshiPlayUrl,
}
}

82
code/VideoAccess-VCMP/api/app/lib/utils/xlsxDownload.js

@ -0,0 +1,82 @@
'use strict';
const fs = require('fs');
const xlsx = require('better-xlsx');
const path = require('path')
const moment = require('moment')
module.exports = function (app, opts) {
//递归创建目录 同步方法
async function makeDir (dir) {
if (!fs.existsSync(dir)) {
makeDir(path.dirname(dir))
fs.mkdirSync(dir, function (err) {
if (err) {
throw err
}
});
}
}
async function simpleExcelDown ({ data = [], header = [], fileName = moment().format('YYYY-MM-DD HH:mm:ss') } = {}) {
const fileDirPath = path.join(__dirname, `../../downloadFiles`)
makeDir(fileDirPath)
const file = new xlsx.File();
const sheet_1 = file.addSheet('sheet_1');
// header
const headerStyle = new xlsx.Style();
headerStyle.align.h = 'center';
headerStyle.align.v = 'center';
headerStyle.border.right = 'thin';
headerStyle.border.rightColor = '#000000';
headerStyle.border.bottom = 'thin';
headerStyle.border.bottomColor = '#000000';
const headerRow = sheet_1.addRow();
const indexCell = headerRow.addCell();
indexCell.value = '序号'
indexCell.style = headerStyle
for (let h of header) {
const cell = headerRow.addCell();
cell.value = h.title;
cell.style = headerStyle
}
// data
const style = new xlsx.Style();
style.align.h = 'left';
style.align.v = 'center';
style.border.right = 'thin';
style.border.rightColor = '#000000';
style.border.bottom = 'thin';
style.border.bottomColor = '#000000';
for (let i = 0; i < data.length; i++) {
const row = sheet_1.addRow();
const indexCell = row.addCell();
indexCell.value = i + 1
indexCell.style = headerStyle
for (let h of header) {
const cell = row.addCell();
cell.value = data[i][h.key];
cell.style = style
}
}
const savePath = path.join(fileDirPath, fileName)
await new Promise(function (resolve, reject) {
file.saveAs()
.pipe(fs.createWriteStream(savePath))
.on('finish', () => {
resolve()
});
})
return savePath
}
return {
simpleExcelDown,
makeDir
}
}

265
code/VideoAccess-VCMP/api/config.js

@ -12,92 +12,217 @@ args.option(['p', 'port'], '启动端口');
args.option(['g', 'pg'], 'postgre服务URL');
args.option(['f', 'fileHost'], '文件中心本地化存储: WebApi 服务器地址(必填), 该服务器提供文件上传Web服务');
args.option('redisHost', 'redisHost');
args.option('redisPort', 'redisPort');
args.option('redisPswd', 'redisPassword');
args.option('axyApiUrl', '安心云 api');
args.option('iotAuthApi', 'IOT 鉴权 api');
args.option('pomsApiUrl', '运维平台 api')
args.option('godUrl', '高德地图API请求地址');
args.option('godKey', '高德地图API key');
args.option('iotVideoServerUrl', '视频后端服务地址');
args.option('mqttVideoServer', '视频后台 mqtt 服务 URL');
args.option('cameraPlayWsHost', '视频播放地址 ws://xxx:xxx');
args.option('cameraPlayHttpFlvHost', '视频播放地址 httpFlv');
args.option('cameraPlayHlsHost', '视频播放地址 hls');
args.option('cameraPlayRtmpHost', '视频播放地址 rtmp');
args.option('cameraPlayRtspHost', '视频播放地址 rtsp');
const flags = args.parse(process.argv);
const IOT_VIDEO_ACCESS_DB = process.env.IOT_VIDEO_ACCESS_DB || flags.pg;
const IOT_VIDEO_ACCESS_LOCAL_SVR_ORIGIN = process.env.IOT_VIDEO_ACCESS_LOCAL_SVR_ORIGIN || flags.fileHost;
if (!IOT_VIDEO_ACCESS_DB) {
console.log('缺少启动参数,异常退出');
args.showHelp();
process.exit(-1);
// Redis 参数
const IOTA_REDIS_SERVER_HOST = process.env.IOTA_REDIS_SERVER_HOST || flags.redisHost || "localhost";//redis IP
const IOTA_REDIS_SERVER_PORT = process.env.IOTA_REDIS_SERVER_PORT || flags.redisPort || "6379";//redis 端口
const IOTA_REDIS_SERVER_PWD = process.env.IOTA_REDIS_SERVER_PWD || flags.redisPswd || "";//redis 密码
// 鉴权 api
const IOT_AUTH_API = process.env.IOT_AUTH_API || flags.iotAuthApi;
// 安心云api
const AXY_API_URL = process.env.AXY_API_URL || flags.axyApiUrl;
// 运维平台 api
const POMS_API_URL = process.env.POMS_API_URL || flags.pomsApiUrl;
// 高德地图的参数
const GOD_URL = process.env.GOD_URL || flags.godUrl || 'https://restapi.amap.com/v3';
const GOD_KEY = process.env.GOD_KEY || flags.godKey;
// 萤石服务的地址
const YINGSHI_URL = process.env.YINGSHI_URL || flags.yingshiUrl || 'https://open.ys7.com/api';
// 视频后台服务的地址
const IOT_VIDEO_SERVER_URL = process.env.IOT_VIDEO_SERVER_URL || flags.iotVideoServerUrl
// 视频后台 mqtt 信息推送地址
const MQTT_VIDEO_SERVER = process.env.MQTT_VIDEO_SERVER || flags.mqttVideoServer;
// 几种国标摄像头播放地址前缀
const CAMERA_PLAY_WS_HOST = process.env.CAMERA_PLAY_WS_HOST || flags.cameraPlayWsHost;
const CAMERA_PLAY_HTTP_FLV_HOST = process.env.CAMERA_PLAY_HTTP_FLV_HOST || flags.cameraPlayHttpFlvHost;
const CAMERA_PLAY_HLS_HOST = process.env.CAMERA_PLAY_HLS_HOST || flags.cameraPlayHlsHost;
const CAMERA_PLAY_RTMP_HOST = process.env.CAMERA_PLAY_RTMP_HOST || flags.cameraPlayRtmpHost;
const CAMERA_PLAY_RTSP_HOST = process.env.CAMERA_PLAY_RTSP_HOST || flags.cameraPlayRtspHost;
if (
!IOT_VIDEO_ACCESS_DB || !IOTA_REDIS_SERVER_HOST || !IOTA_REDIS_SERVER_PORT || !GOD_KEY || !MQTT_VIDEO_SERVER ||
!AXY_API_URL || !IOT_VIDEO_SERVER_URL || !IOT_AUTH_API || !POMS_API_URL ||
!CAMERA_PLAY_WS_HOST || !CAMERA_PLAY_HTTP_FLV_HOST || !CAMERA_PLAY_HLS_HOST || !CAMERA_PLAY_RTMP_HOST || !CAMERA_PLAY_RTSP_HOST
) {
console.log('缺少启动参数,异常退出');
args.showHelp();
process.exit(-1);
}
const product = {
port: flags.port || 8080,
staticDirs: ['static'],
mws: [
{
entry: require('@fs/attachment').entry,
opts: {
local: {
origin: IOT_VIDEO_ACCESS_LOCAL_SVR_ORIGIN || `http://localhost:${flags.port || 8080}`,
rootPath: 'static',
childPath: 'upload',
},
maxSize: 104857600, // 100M
}
}, {
entry: require('./app').entry,
opts: {
exclude: [], // 不做认证的路由,也可以使用 exclude: ["*"] 跳过所有路由
}
}
],
dc: {
url: IOT_VIDEO_ACCESS_DB,
opts: {
pool: {
max: 80,
min: 10,
idle: 10000
port: flags.port || 8080,
staticDirs: ['static'],
mws: [
{
entry: require('@fs/attachment').entry,
opts: {
local: {
origin: IOT_VIDEO_ACCESS_LOCAL_SVR_ORIGIN || `http://localhost:${flags.port || 8080}`,
rootPath: 'static',
childPath: 'upload',
},
maxSize: 104857600, // 100M
}
}, {
entry: require('./app').entry,
opts: {
dev,
exclude: [
{ p: '/camera', o: 'GET' }, // 暂时滴
{ p: '/application/check', o: 'GET' }, // 暂时滴
{ p: '/status/alarm', o: 'POST' },
{ p: '/camera/unique/all', o: 'GET' },
{ p: '/status/alarm/confirm', o: 'PUT' },
{ p: '/status/check', o: 'GET' },
{ p: '/mirror/:mirrorId', o: 'GET' },
], // 不做认证的路由,也可以使用 exclude: ["*"] 跳过所有路由
redis: {
host: IOTA_REDIS_SERVER_HOST,
port: IOTA_REDIS_SERVER_PORT,
pwd: IOTA_REDIS_SERVER_PWD
},
mqtt: {
mqttVideoServer: MQTT_VIDEO_SERVER,
},
cameraPlayHost: {
ws: CAMERA_PLAY_WS_HOST,
httpFlv: CAMERA_PLAY_HTTP_FLV_HOST,
hls: CAMERA_PLAY_HLS_HOST,
rtmp: CAMERA_PLAY_RTMP_HOST,
rtsp: CAMERA_PLAY_RTSP_HOST,
},
sms: {
///阿里云-安心云
accessKey: 'LTAI5tAFdjz7j38aNF2C9Qe8',
accessSecret: '1trYkmiqfBtvZL6BxkNH2uQcQQPs0S'
},
define: {
freezeTableName: true, // 固定表名
timestamps: false // 不含列 "createAt"/"updateAt"/"DeleteAt"
email: {
enabled: true,
host: 'smtp.exmail.qq.com',
port: 465,
sender: {
name: '尚视',
address: 'fsiot@free-sun.com.cn',
password: 'Fs2689'
}
},
timezone: '+08:00',
logging: false
},
models: [require('./app').models]
},
logger: {
level: 'info',
json: false,
filename: path.join(__dirname, 'log', 'runtime.log'),
colorize: false,
maxsize: 1024 * 1024 * 5,
rotationFormat: false,
zippedArchive: true,
maxFiles: 10,
prettyPrint: true,
label: '',
timestamp: () => moment().format('YYYY-MM-DD HH:mm:ss.SSS'),
eol: os.EOL,
tailable: true,
depth: null,
showLevel: true,
maxRetries: 1
}
pssaRequest: [
{// name 会作为一个 request 出现在 ctx.app.fs
name: 'authRequest',
root: IOT_AUTH_API
}, {
name: 'axyRequest',
root: AXY_API_URL
}, {
name: 'pomsRequest',
root: POMS_API_URL
}, {
name: 'godRequest',
root: GOD_URL,
params: {
query: {
key: GOD_KEY
}
}
}, {
name: 'yingshiRequest',
root: YINGSHI_URL,
params: {
query: {
key: GOD_KEY
}
}
}, {
name: 'videoServerRequest',
root: IOT_VIDEO_SERVER_URL + '/api',
dataWord: 'text'
},
]
}
}
],
dc: {
url: IOT_VIDEO_ACCESS_DB,
opts: {
pool: {
max: 80,
min: 10,
idle: 10000
},
define: {
freezeTableName: true, // 固定表名
timestamps: false // 不含列 "createAt"/"updateAt"/"DeleteAt"
},
timezone: '+08:00',
logging: false
},
models: [require('./app').models]
},
logger: {
level: 'info',
json: false,
filename: path.join(__dirname, 'log', 'runtime.log'),
colorize: false,
maxsize: 1024 * 1024 * 5,
rotationFormat: false,
zippedArchive: true,
maxFiles: 10,
prettyPrint: true,
label: '',
timestamp: () => moment().format('YYYY-MM-DD HH:mm:ss.SSS'),
eol: os.EOL,
tailable: true,
depth: null,
showLevel: true,
maxRetries: 1
}
};
const development = {
port: product.port,
staticDirs: product.staticDirs,
mws: product.mws,
dc: product.dc,
logger: product.logger
port: product.port,
staticDirs: product.staticDirs,
mws: product.mws,
dc: product.dc,
logger: product.logger
};
if (dev) {
// mws
for (let mw of development.mws) {
// if (mw.opts.exclude) mw.opts.exclude = ['*']; // 使用 ['*'] 跳过所有路由
}
// logger
development.logger.filename = path.join(__dirname, 'log', 'development.log');
development.logger.level = 'debug';
development.dc.opts.logging = console.log;
// mws
for (let mw of development.mws) {
// if (mw.opts.exclude) mw.opts.exclude = ['*']; // 使用 ['*'] 跳过所有路由
}
// logger
development.logger.filename = path.join(__dirname, 'log', 'development.log');
development.logger.level = 'debug';
development.dc.opts.logging = console.log;
}
module.exports = dev ? development : product;

9
code/VideoAccess-VCMP/api/package.json

@ -5,7 +5,7 @@
"main": "server.js",
"scripts": {
"test": "set DEBUG=true&&\"node_modules/.bin/mocha\" --harmony --reporter spec app/test/*.test.js",
"start": "set NODE_ENV=development&&node server -p 14000 -g postgres://postgres:123@10.8.30.32:5432/yinjiguanli -f http://localhost:14000",
"start": "set NODE_ENV=development&&node server -p 4000 -g postgres://postgres:123@10.8.30.32:5432/video_access -f http://localhost:4000",
"start:linux": "export NODE_ENV=development&&node server -p 4000 -g postgres://FashionAdmin:123456@10.8.30.39:5432/pm1",
"automate": "sequelize-automate -c sequelize-automate.config.js"
},
@ -13,15 +13,20 @@
"license": "MIT",
"repository": {},
"dependencies": {
"@alicloud/pop-core": "^1.7.12",
"@fs/attachment": "^1.0.0",
"args": "^3.0.7",
"better-xlsx": "^0.7.6",
"crypto-js": "^4.0.0",
"file-saver": "^2.0.2",
"fs-web-server-scaffold": "^2.0.2",
"ioredis": "^4.19.4",
"ioredis": "^5.0.4",
"koa-convert": "^1.2.0",
"koa-proxy": "^0.9.0",
"moment": "^2.24.0",
"mqtt": "^4.3.7",
"node-schedule": "^2.1.0",
"nodemailer": "^6.7.7",
"path": "^0.12.7",
"path-to-regexp": "^3.0.0",
"pg": "^7.9.0",

66
code/VideoAccess-VCMP/api/sequelize-automate.config.js

@ -1,35 +1,35 @@
module.exports = {
// 数据库配置 与 sequelize 相同
dbOptions: {
database: 'yinjiguanli',
username: 'postgres',
password: '123',
dialect: 'postgres',
host: '10.8.30.32',
port: 5432,
define: {
underscored: false,
freezeTableName: false,
charset: 'utf8mb4',
timezone: '+00: 00',
dialectOptions: {
collate: 'utf8_general_ci',
},
timestamps: false,
},
},
options: {
type: 'freesun', // 指定 models 代码风格
camelCase: true, // Models 文件中代码是否使用驼峰命名
modalNameSuffix: false, // 模型名称是否带 ‘Model’ 后缀
fileNameCamelCase: false, // Model 文件名是否使用驼峰法命名,默认文件名会使用表名,如 `user_post.js`;如果为 true,则文件名为 `userPost.js`
dir: './app/lib/models', // 指定输出 models 文件的目录
typesDir: 'models', // 指定输出 TypeScript 类型定义的文件目录,只有 TypeScript / Midway 等会有类型定义
emptyDir: false, // !!! 谨慎操作 生成 models 之前是否清空 `dir` 以及 `typesDir`
tables: ['user_placeSecurityRecord', 'places'], // 指定生成哪些表的 models,如 ['user', 'user_post'];如果为 null,则忽略改属性
skipTables: ['user'], // 指定跳过哪些表的 models,如 ['user'];如果为 null,则忽略改属性
tsNoCheck: false, // 是否添加 `@ts-nocheck` 注释到 models 文件中
ignorePrefix: [], // 生成的模型名称忽略的前缀,因为 项目中有以下表名是以 t_ 开头的,在实际模型中不需要, 可以添加多个 [ 't_data_', 't_',] ,长度较长的 前缀放前面
attrLength: false, // 在生成模型的字段中 是否生成 如 var(128)这种格式,公司一般使用 String ,则配置为 false
},
// 数据库配置 与 sequelize 相同
dbOptions: {
database: 'video_access-dev',
username: 'postgres',
password: '123',
dialect: 'postgres',
host: '10.8.30.166',
port: 5432,
define: {
underscored: false,
freezeTableName: false,
charset: 'utf8mb4',
timezone: '+00: 00',
dialectOptions: {
collate: 'utf8_general_ci',
},
timestamps: false,
},
},
options: {
type: 'freesun', // 指定 models 代码风格
camelCase: true, // Models 文件中代码是否使用驼峰命名
modalNameSuffix: false, // 模型名称是否带 ‘Model’ 后缀
fileNameCamelCase: false, // Model 文件名是否使用驼峰法命名,默认文件名会使用表名,如 `user_post.js`;如果为 true,则文件名为 `userPost.js`
dir: './app/lib/models', // 指定输出 models 文件的目录
typesDir: 'models', // 指定输出 TypeScript 类型定义的文件目录,只有 TypeScript / Midway 等会有类型定义
emptyDir: false, // !!! 谨慎操作 生成 models 之前是否清空 `dir` 以及 `typesDir`
tables: ['camera_status_alarm',], // 指定生成哪些表的 models,如 ['user', 'user_post'];如果为 null,则忽略改属性
skipTables: [], // 指定跳过哪些表的 models,如 ['user'];如果为 null,则忽略改属性
tsNoCheck: false, // 是否添加 `@ts-nocheck` 注释到 models 文件中
ignorePrefix: [], // 生成的模型名称忽略的前缀,因为 项目中有以下表名是以 t_ 开头的,在实际模型中不需要, 可以添加多个 [ 't_data_', 't_',] ,长度较长的 前缀放前面
attrLength: false, // 在生成模型的字段中 是否生成 如 var(128)这种格式,公司一般使用 String ,则配置为 false
},
}

15
code/VideoAccess-VCMP/api/utils/forward-api.js

@ -1,15 +0,0 @@
'use strict';
const proxy = require('koa-proxy');
const convert = require('koa-convert');
module.exports = {
entry: function (app, router, opts) {
app.use(convert(proxy({
host: opts.host,
match: opts.match,
map: function (path) {
return path.replace(opts.match, '');
}
})));
}
};

3
code/VideoAccess-VCMP/script/.vscode/settings.json

@ -0,0 +1,3 @@
{
"editor.wordWrap": "on"
}

543
code/VideoAccess-VCMP/script/0.0.1/0_init_db.sql

@ -0,0 +1,543 @@
/*
Navicat Premium Data Transfer
Source Server : 10.8.30.32
Source Server Type : PostgreSQL
Source Server Version : 90515
Source Host : 10.8.30.32:5432
Source Catalog : video_access
Source Schema : public
Target Server Type : PostgreSQL
Target Server Version : 90515
File Encoding : 65001
Date: 06/07/2022 11:45:25
*/
-- ----------------------------
-- Sequence structure for camera_ability_bind_id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."camera_ability_bind_id_seq";
CREATE SEQUENCE "public"."camera_ability_bind_id_seq"
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
-- ----------------------------
-- Sequence structure for camera_id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."camera_id_seq";
CREATE SEQUENCE "public"."camera_id_seq"
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
-- ----------------------------
-- Sequence structure for camera_remark_id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."camera_remark_id_seq";
CREATE SEQUENCE "public"."camera_remark_id_seq"
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
-- ----------------------------
-- Sequence structure for gbCamera_id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."gbCamera_id_seq";
CREATE SEQUENCE "public"."gbCamera_id_seq"
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
-- ----------------------------
-- Sequence structure for gb_id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."gb_id_seq";
CREATE SEQUENCE "public"."gb_id_seq"
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
-- ----------------------------
-- Sequence structure for nvr_id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."nvr_id_seq";
CREATE SEQUENCE "public"."nvr_id_seq"
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
-- ----------------------------
-- Sequence structure for secret_yingshi_id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."secret_yingshi_id_seq";
CREATE SEQUENCE "public"."secret_yingshi_id_seq"
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
-- ----------------------------
-- Sequence structure for t_upload_comm_http_id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."t_upload_comm_http_id_seq";
CREATE SEQUENCE "public"."t_upload_comm_http_id_seq"
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
-- ----------------------------
-- Sequence structure for vender_id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."vender_id_seq";
CREATE SEQUENCE "public"."vender_id_seq"
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
-- ----------------------------
-- Table structure for ax_project
-- ----------------------------
DROP TABLE IF EXISTS "public"."ax_project";
CREATE TABLE "public"."ax_project" (
"id" int4 NOT NULL,
"name" varchar(64) COLLATE "pg_catalog"."default" NOT NULL
)
;
COMMENT ON TABLE "public"."ax_project" IS '安心云项目副表,主要用于和camera等进行联合查询
';
-- ----------------------------
-- Records of ax_project
-- ----------------------------
INSERT INTO "public"."ax_project" VALUES (1, '安心云项目');
-- ----------------------------
-- Table structure for camera
-- ----------------------------
DROP TABLE IF EXISTS "public"."camera";
CREATE TABLE "public"."camera" (
"id" int4 NOT NULL DEFAULT nextval('camera_id_seq'::regclass),
"type" varchar(16) COLLATE "pg_catalog"."default" NOT NULL,
"name" varchar(128) COLLATE "pg_catalog"."default",
"channel_name" varchar(64) COLLATE "pg_catalog"."default",
"external_domain" varchar(64) COLLATE "pg_catalog"."default",
"rtmp" varchar(1024) COLLATE "pg_catalog"."default",
"serial_no" varchar(128) COLLATE "pg_catalog"."default",
"cloud_control" bool,
"high_definition" bool,
"voice" bool,
"memory_card" varchar(32) COLLATE "pg_catalog"."default",
"vender_id" int4,
"cascade_type" varchar(32) COLLATE "pg_catalog"."default",
"sip" varchar(1024) COLLATE "pg_catalog"."default",
"longitude" numeric(16,12),
"latitude" numeric(16,12),
"forbidden" bool NOT NULL DEFAULT false,
"create_time" timestamptz(6) NOT NULL,
"recycle_time" timestamptz(6),
"delete" bool NOT NULL DEFAULT false,
"create_user_id" int4 NOT NULL,
"nvr_id" int4,
"model" varchar(128) COLLATE "pg_catalog"."default",
"kind_id" int4,
"yingshi_secret_id" int4,
"gb_id" int4,
"top_serial_no" varchar(128) COLLATE "pg_catalog"."default"
)
;
COMMENT ON COLUMN "public"."camera"."type" IS '设备类型:yingshi - 萤石;nvr - NVR摄像头;ipc - IPC 网络摄像头;cascade - 级联摄像头';
COMMENT ON COLUMN "public"."camera"."name" IS '设备名称/安装位置';
COMMENT ON COLUMN "public"."camera"."channel_name" IS '通道名称';
COMMENT ON COLUMN "public"."camera"."external_domain" IS '外域名称';
COMMENT ON COLUMN "public"."camera"."serial_no" IS '设备编号';
COMMENT ON COLUMN "public"."camera"."cloud_control" IS '云台控制';
COMMENT ON COLUMN "public"."camera"."high_definition" IS '高清支持';
COMMENT ON COLUMN "public"."camera"."voice" IS '语音对讲支持';
COMMENT ON COLUMN "public"."camera"."memory_card" IS '内存卡容量';
COMMENT ON COLUMN "public"."camera"."vender_id" IS '设备厂商id';
COMMENT ON COLUMN "public"."camera"."cascade_type" IS '级联方式:up - 上级联;down - 下级联';
COMMENT ON COLUMN "public"."camera"."longitude" IS '经度';
COMMENT ON COLUMN "public"."camera"."latitude" IS '维度';
COMMENT ON COLUMN "public"."camera"."forbidden" IS '是否禁用';
COMMENT ON COLUMN "public"."camera"."recycle_time" IS '放入回收站时间';
COMMENT ON COLUMN "public"."camera"."delete" IS '是否彻底删除';
COMMENT ON COLUMN "public"."camera"."model" IS '型号';
COMMENT ON COLUMN "public"."camera"."top_serial_no" IS 'gb设备 level=0 的 steamid ';
-- ----------------------------
-- Table structure for camera_ability
-- ----------------------------
DROP TABLE IF EXISTS "public"."camera_ability";
CREATE TABLE "public"."camera_ability" (
"id" int4 NOT NULL,
"ability" varchar(64) COLLATE "pg_catalog"."default" NOT NULL
)
;
COMMENT ON TABLE "public"."camera_ability" IS '摄像机能力';
-- ----------------------------
-- Records of camera_ability
-- ----------------------------
INSERT INTO "public"."camera_ability" VALUES (1, '普通摄像头');
INSERT INTO "public"."camera_ability" VALUES (2, '人流量计数');
INSERT INTO "public"."camera_ability" VALUES (3, '热成像');
INSERT INTO "public"."camera_ability" VALUES (4, 'AI摄像头');
INSERT INTO "public"."camera_ability" VALUES (1314, '其他');
-- ----------------------------
-- Table structure for camera_ability_bind
-- ----------------------------
DROP TABLE IF EXISTS "public"."camera_ability_bind";
CREATE TABLE "public"."camera_ability_bind" (
"id" int4 NOT NULL DEFAULT nextval('camera_ability_bind_id_seq'::regclass),
"camera_id" int4 NOT NULL,
"ability_id" int4 NOT NULL
)
;
-- ----------------------------
-- Table structure for camera_kind
-- ----------------------------
DROP TABLE IF EXISTS "public"."camera_kind";
CREATE TABLE "public"."camera_kind" (
"id" int4 NOT NULL,
"kind" varchar(64) COLLATE "pg_catalog"."default" NOT NULL
)
;
COMMENT ON TABLE "public"."camera_kind" IS '摄像机类型';
-- ----------------------------
-- Records of camera_kind
-- ----------------------------
INSERT INTO "public"."camera_kind" VALUES (1, '枪机');
INSERT INTO "public"."camera_kind" VALUES (2, '球机');
INSERT INTO "public"."camera_kind" VALUES (1314, '其他');
-- ----------------------------
-- Table structure for camera_remark
-- ----------------------------
DROP TABLE IF EXISTS "public"."camera_remark";
CREATE TABLE "public"."camera_remark" (
"id" int4 NOT NULL DEFAULT nextval('camera_remark_id_seq'::regclass),
"camera_id" int4 NOT NULL,
"remark" varchar(256) COLLATE "pg_catalog"."default" NOT NULL
)
;
-- ----------------------------
-- Table structure for gbCamera
-- ----------------------------
DROP TABLE IF EXISTS "public"."gbCamera";
CREATE TABLE "public"."gbCamera" (
"id" int4 NOT NULL DEFAULT nextval('gb_id_seq'::regclass),
"level" int4,
"parent" varchar(32) COLLATE "pg_catalog"."default",
"streamid" varchar(255) COLLATE "pg_catalog"."default",
"online" varchar(255) COLLATE "pg_catalog"."default",
"manufactuer" varchar(255) COLLATE "pg_catalog"."default",
"model" varchar(255) COLLATE "pg_catalog"."default",
"civilCode" varchar(255) COLLATE "pg_catalog"."default",
"adddress" varchar(255) COLLATE "pg_catalog"."default",
"name" varchar(255) COLLATE "pg_catalog"."default",
"Addr" varchar(255) COLLATE "pg_catalog"."default",
"Sipip" varchar(255) COLLATE "pg_catalog"."default",
"ipctype" varchar(255) COLLATE "pg_catalog"."default",
"registerTime" varchar(255) COLLATE "pg_catalog"."default" DEFAULT ''::character varying,
"updateTime" varchar(255) COLLATE "pg_catalog"."default",
"playUrl" jsonb
)
;
COMMENT ON COLUMN "public"."gbCamera"."playUrl" IS '播放地址集合';
-- ----------------------------
-- Table structure for nvr
-- ----------------------------
DROP TABLE IF EXISTS "public"."nvr";
CREATE TABLE "public"."nvr" (
"id" int4 NOT NULL DEFAULT nextval('nvr_id_seq'::regclass),
"name" varchar(64) COLLATE "pg_catalog"."default" NOT NULL,
"vender_id" int4,
"serial_no" varchar(64) COLLATE "pg_catalog"."default" NOT NULL,
"region_code" varchar(64) COLLATE "pg_catalog"."default",
"longitude" numeric(16,12) NOT NULL,
"latitude" numeric(16,12) NOT NULL,
"create_time" timestamptz(6) NOT NULL DEFAULT now(),
"channel_count" int4,
"port" varchar(32) COLLATE "pg_catalog"."default",
"delete" bool NOT NULL DEFAULT false,
"create_user_id" int4 NOT NULL
)
;
COMMENT ON COLUMN "public"."nvr"."vender_id" IS '设备厂家id';
COMMENT ON COLUMN "public"."nvr"."serial_no" IS '设备编号';
COMMENT ON COLUMN "public"."nvr"."region_code" IS '行政区码';
COMMENT ON COLUMN "public"."nvr"."create_time" IS '创建时间';
COMMENT ON COLUMN "public"."nvr"."channel_count" IS '通道数';
COMMENT ON COLUMN "public"."nvr"."port" IS '端口';
-- ----------------------------
-- Table structure for secret_yingshi
-- ----------------------------
DROP TABLE IF EXISTS "public"."secret_yingshi";
CREATE TABLE "public"."secret_yingshi" (
"id" int4 NOT NULL DEFAULT nextval('secret_yingshi_id_seq'::regclass),
"key" varchar(512) COLLATE "pg_catalog"."default" NOT NULL,
"secret" varchar(512) COLLATE "pg_catalog"."default" NOT NULL,
"token" varchar(512) COLLATE "pg_catalog"."default",
"expire" varchar(512) COLLATE "pg_catalog"."default"
)
;
-- ----------------------------
-- Records of secret_yingshi
-- ----------------------------
INSERT INTO "public"."secret_yingshi" VALUES (2, '3ea2b502f6804d64b43e4cb3d135665c', '331c85c5b7ce76179f6eb7dccb8aeb27', 'at.culo424j9drz8atx9uikeq5e2mzkhnhx-490csubqrh-1o3hcaz-szuvfax6f', '1657681218109');
INSERT INTO "public"."secret_yingshi" VALUES (3, 'd0704fb9d5d14a6682c1c1d592c12512', '93d023269495b86be62cdfdcf34a6cd1', 'at.1y2mk5fh2myswbkp017pmvdi0v1zbdrw-5j39z78wsp-0x4vi2j-a3mxjlt32', '1657683606281');
INSERT INTO "public"."secret_yingshi" VALUES (1, '5d16a667e1c2423d9d0d634f781810b4', '0cc4e1ec4e6a53ea3dabeb09cd5f468b', 'at.9gq3xwwbazkk33y177ucqtk936bmd0sz-41x4xf24sh-1cn7x82-4lf7davve', '1657681803201');
-- ----------------------------
-- Table structure for t_upload_comm_http
-- ----------------------------
DROP TABLE IF EXISTS "public"."t_upload_comm_http";
CREATE TABLE "public"."t_upload_comm_http" (
"id" int4 NOT NULL DEFAULT nextval('t_upload_comm_http_id_seq'::regclass),
"content" json NOT NULL,
"enable" bool NOT NULL DEFAULT true,
"description" varchar(255) COLLATE "pg_catalog"."default"
)
;
-- ----------------------------
-- Table structure for vender
-- ----------------------------
DROP TABLE IF EXISTS "public"."vender";
CREATE TABLE "public"."vender" (
"id" int4 NOT NULL DEFAULT nextval('vender_id_seq'::regclass),
"name" varchar(64) COLLATE "pg_catalog"."default" NOT NULL
)
;
COMMENT ON TABLE "public"."vender" IS '设备厂商';
-- ----------------------------
-- Records of vender
-- ----------------------------
INSERT INTO "public"."vender" VALUES (2, '海康威视');
INSERT INTO "public"."vender" VALUES (3, '大华');
INSERT INTO "public"."vender" VALUES (1, '飞尚科技');
INSERT INTO "public"."vender" VALUES (1314, '其他');
-- ----------------------------
-- Alter sequences owned by
-- ----------------------------
ALTER SEQUENCE "public"."camera_ability_bind_id_seq"
OWNED BY "public"."camera_ability_bind"."id";
-- ----------------------------
-- Alter sequences owned by
-- ----------------------------
ALTER SEQUENCE "public"."camera_id_seq"
OWNED BY "public"."camera"."id";
-- ----------------------------
-- Alter sequences owned by
-- ----------------------------
ALTER SEQUENCE "public"."camera_remark_id_seq"
OWNED BY "public"."camera_remark"."id";
-- ----------------------------
-- Alter sequences owned by
-- ----------------------------
SELECT setval('"public"."gbCamera_id_seq"', 2, false);
-- ----------------------------
-- Alter sequences owned by
-- ----------------------------
-- ----------------------------
-- Alter sequences owned by
-- ----------------------------
ALTER SEQUENCE "public"."nvr_id_seq"
OWNED BY "public"."nvr"."id";
-- ----------------------------
-- Alter sequences owned by
-- ----------------------------
ALTER SEQUENCE "public"."secret_yingshi_id_seq"
OWNED BY "public"."secret_yingshi"."id";
SELECT setval('"public"."secret_yingshi_id_seq"', 4, true);
-- ----------------------------
-- Alter sequences owned by
-- ----------------------------
SELECT setval('"public"."t_upload_comm_http_id_seq"', 2, false);
-- ----------------------------
-- Alter sequences owned by
-- ----------------------------
ALTER SEQUENCE "public"."vender_id_seq"
OWNED BY "public"."vender"."id";
SELECT setval('"public"."vender_id_seq"', 4, true);
-- ----------------------------
-- Indexes structure for table ax_project
-- ----------------------------
CREATE UNIQUE INDEX "ax_project_id_uindex" ON "public"."ax_project" USING btree (
"id" "pg_catalog"."int4_ops" ASC NULLS LAST
);
-- ----------------------------
-- Primary Key structure for table ax_project
-- ----------------------------
ALTER TABLE "public"."ax_project" ADD CONSTRAINT "ax_project_pk" PRIMARY KEY ("id");
-- ----------------------------
-- Indexes structure for table camera
-- ----------------------------
CREATE UNIQUE INDEX "camera_id_uindex" ON "public"."camera" USING btree (
"id" "pg_catalog"."int4_ops" ASC NULLS LAST
);
-- ----------------------------
-- Primary Key structure for table camera
-- ----------------------------
ALTER TABLE "public"."camera" ADD CONSTRAINT "camera_pk" PRIMARY KEY ("id");
-- ----------------------------
-- Indexes structure for table camera_ability
-- ----------------------------
CREATE UNIQUE INDEX "camera_ability_id_uindex" ON "public"."camera_ability" USING btree (
"id" "pg_catalog"."int4_ops" ASC NULLS LAST
);
-- ----------------------------
-- Primary Key structure for table camera_ability
-- ----------------------------
ALTER TABLE "public"."camera_ability" ADD CONSTRAINT "camera_ability_pk" PRIMARY KEY ("id");
-- ----------------------------
-- Indexes structure for table camera_ability_bind
-- ----------------------------
CREATE UNIQUE INDEX "camera_ability_bind_id_uindex" ON "public"."camera_ability_bind" USING btree (
"id" "pg_catalog"."int4_ops" ASC NULLS LAST
);
-- ----------------------------
-- Primary Key structure for table camera_ability_bind
-- ----------------------------
ALTER TABLE "public"."camera_ability_bind" ADD CONSTRAINT "camera_ability_bind_pk" PRIMARY KEY ("id");
-- ----------------------------
-- Indexes structure for table camera_kind
-- ----------------------------
CREATE UNIQUE INDEX "camera_kind_id_uindex" ON "public"."camera_kind" USING btree (
"id" "pg_catalog"."int4_ops" ASC NULLS LAST
);
-- ----------------------------
-- Primary Key structure for table camera_kind
-- ----------------------------
ALTER TABLE "public"."camera_kind" ADD CONSTRAINT "camera_kind_pk" PRIMARY KEY ("id");
-- ----------------------------
-- Indexes structure for table camera_remark
-- ----------------------------
CREATE UNIQUE INDEX "camera_remark_id_uindex" ON "public"."camera_remark" USING btree (
"id" "pg_catalog"."int4_ops" ASC NULLS LAST
);
-- ----------------------------
-- Primary Key structure for table camera_remark
-- ----------------------------
ALTER TABLE "public"."camera_remark" ADD CONSTRAINT "camera_remark_pk" PRIMARY KEY ("id");
-- ----------------------------
-- Primary Key structure for table gbCamera
-- ----------------------------
ALTER TABLE "public"."gbCamera" ADD CONSTRAINT "gbCamera1_copy1_pkey" PRIMARY KEY ("id");
-- ----------------------------
-- Indexes structure for table nvr
-- ----------------------------
CREATE UNIQUE INDEX "nvr_id_uindex" ON "public"."nvr" USING btree (
"id" "pg_catalog"."int4_ops" ASC NULLS LAST
);
-- ----------------------------
-- Primary Key structure for table nvr
-- ----------------------------
ALTER TABLE "public"."nvr" ADD CONSTRAINT "nvr_pk" PRIMARY KEY ("id");
-- ----------------------------
-- Indexes structure for table secret_yingshi
-- ----------------------------
CREATE UNIQUE INDEX "secret_yingshi_id_uindex" ON "public"."secret_yingshi" USING btree (
"id" "pg_catalog"."int4_ops" ASC NULLS LAST
);
-- ----------------------------
-- Primary Key structure for table secret_yingshi
-- ----------------------------
ALTER TABLE "public"."secret_yingshi" ADD CONSTRAINT "secret_yingshi_pk" PRIMARY KEY ("id");
-- ----------------------------
-- Primary Key structure for table t_upload_comm_http
-- ----------------------------
ALTER TABLE "public"."t_upload_comm_http" ADD CONSTRAINT "t_upload_comm_http_pkey" PRIMARY KEY ("id");
-- ----------------------------
-- Indexes structure for table vender
-- ----------------------------
CREATE UNIQUE INDEX "vender_id_uindex" ON "public"."vender" USING btree (
"id" "pg_catalog"."int4_ops" ASC NULLS LAST
);
-- ----------------------------
-- Primary Key structure for table vender
-- ----------------------------
ALTER TABLE "public"."vender" ADD CONSTRAINT "vender_pk" PRIMARY KEY ("id");
-- ----------------------------
-- Foreign Keys structure for table camera
-- ----------------------------
ALTER TABLE "public"."camera" ADD CONSTRAINT "camera_camera_kind_id_fk" FOREIGN KEY ("kind_id") REFERENCES "public"."camera_kind" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
ALTER TABLE "public"."camera" ADD CONSTRAINT "camera_nvr_id_fk" FOREIGN KEY ("nvr_id") REFERENCES "public"."nvr" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
ALTER TABLE "public"."camera" ADD CONSTRAINT "camera_secret_yingshi_id_fk" FOREIGN KEY ("yingshi_secret_id") REFERENCES "public"."secret_yingshi" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
ALTER TABLE "public"."camera" ADD CONSTRAINT "camera_vender_id_fk" FOREIGN KEY ("vender_id") REFERENCES "public"."vender" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
-- ----------------------------
-- Foreign Keys structure for table camera_ability_bind
-- ----------------------------
ALTER TABLE "public"."camera_ability_bind" ADD CONSTRAINT "camera_ability_bind_camera_ability_id_fk" FOREIGN KEY ("ability_id") REFERENCES "public"."camera_ability" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
ALTER TABLE "public"."camera_ability_bind" ADD CONSTRAINT "camera_ability_bind_camera_id_fk" FOREIGN KEY ("camera_id") REFERENCES "public"."camera" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
-- ----------------------------
-- Foreign Keys structure for table camera_remark
-- ----------------------------
ALTER TABLE "public"."camera_remark" ADD CONSTRAINT "camera_remark_camera_id_fk" FOREIGN KEY ("camera_id") REFERENCES "public"."camera" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
-- ----------------------------
-- Foreign Keys structure for table nvr
-- ----------------------------
ALTER TABLE "public"."nvr" ADD CONSTRAINT "nvr_vender_id_fk" FOREIGN KEY ("vender_id") REFERENCES "public"."vender" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;

14
code/VideoAccess-VCMP/script/1.1.0/1.camera_remark.sql

@ -0,0 +1,14 @@
create table if not exists camera_remark
(
id serial not null,
camera_id integer not null,
remark varchar(256) not null,
constraint camera_remark_pk
primary key (id),
constraint camera_remark_camera_id_fk
foreign key (camera_id) references camera
);
create unique index if not exists camera_remark_id_uindex
on camera_remark (id);

17
code/VideoAccess-VCMP/script/1.1.1/data/1_update_status_code_data/.vscode/launch.json

@ -0,0 +1,17 @@
{
// 使 IntelliSense
//
// 访: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "启动程序",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}\\index.js"
}
]
}

69
code/VideoAccess-VCMP/script/1.1.1/data/1_update_status_code_data/index.js

@ -0,0 +1,69 @@
try {
const { Pool, Client } = require('pg')
const XLSX = require('xlsx')
const path = require('path')
// 连接数据库
const pool = new Pool({
user: 'postgres',
host: '10.8.30.32',
database: 'video_access',
password: '123',
port: 5432,
})
const fun = async () => {
// note: we don't try/catch this because if connecting throws an exception
// we don't need to dispose of the client (it will be undefined)
const client = await pool.connect()
try {
await client.query('BEGIN')
// 读取数据文件
let workbook = XLSX.readFile(path.join(__dirname, '云录制错误码.xlsx'))
let firstSheetName = workbook.SheetNames[0];
let worksheet = workbook.Sheets[firstSheetName];
let res = XLSX.utils.sheet_to_json(worksheet);
// console.log(res);
for (let d of res) {
let statusRes = await client.query(`SELECT * FROM camera_status WHERE status=$1`, [d['错误码']]);
let statusRows = statusRes.rows
if (statusRows.length) {
} else {
console.log(`增加${d['错误码']}`);
const statusInQuery = `INSERT INTO "camera_status" (platform, status, describe, paraphrase) VALUES($1, $2, $3, $4) RETURNING id;`
const statusRows = (await client.query(statusInQuery, ['yingshi', d['错误码'], d['错误描述'], d['释义']])).rows
// console.log(statusRows);
if (d['解决方案']) {
let resolveArr = d['解决方案'].split(';');
// await client.query(`DELETE FROM "camera_status_solution" WHERE status_id=$1`, [statusRows[0].id]);
for (let r of resolveArr) {
await client.query(
`INSERT INTO "camera_status_resolve" (status_id, resolve) VALUES($1, $2) RETURNING id;`,
[statusRows[0].id, r]
)
}
}
}
}
// await client.query('ROLLBACK')
await client.query('COMMIT')
console.log('执行完毕~')
} catch (e) {
await client.query('ROLLBACK')
console.log('执行错误~')
throw e
} finally {
client.release();
}
}
fun()
} catch (error) {
console.error(error)
}

16
code/VideoAccess-VCMP/script/1.1.1/data/1_update_status_code_data/package.json

@ -0,0 +1,16 @@
{
"name": "appkey-generator",
"version": "1.0.0",
"description": "tool",
"main": "index.js",
"scripts": {
"test": "mocha",
"start": "set NODE_ENV=development&&node index"
},
"author": "liu",
"license": "ISC",
"dependencies": {
"pg": "^7.18.2",
"xlsx": "^0.17.1"
}
}

BIN
code/VideoAccess-VCMP/script/1.1.1/data/1_update_status_code_data/云录制错误码.xlsx

Binary file not shown.

141
code/VideoAccess-VCMP/script/1.1.1/data/2.insert_camera_status.sql

@ -0,0 +1,141 @@
-- ----------------------------
-- Records of camera_status
-- ----------------------------
INSERT INTO "public"."camera_status" VALUES (2, 'yingshi', '5000', '服务端内部处理异常', '服务端内部错误码', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (3, 'yingshi', '5400', '私有化协议vtm检测私有化协议中码流类型小于0或者设备序列号为空等非法参数场景返回(app不重试取流)', '客户端参数出错', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (4, 'yingshi', '5402', '回放找不到录像文件', '设备回放找不到录像文件', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (5, 'yingshi', '5403', '操作码或信令密钥与设备不匹配', '操作码或信令密钥与设备不匹配', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (6, 'yingshi', '5404', '设备不在线', '设备不在线', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (7, 'yingshi', '5405', '流媒体向设备发送或接受信令超时/cas响应超时', '设备回应信令10秒超时', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (8, 'yingshi', '5406', 'token失效', 'token失效', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (9, 'yingshi', '5407', '客户端的URL格式错误', '客户端的URL格式错误', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (10, 'yingshi', '5409', '预览开启隐私保护', '预览开启隐私保护', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (11, 'yingshi', '5411', 'token无权限', 'token无权限、用户无权限', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (12, 'yingshi', '5412', 'session不存在', 'session不存在', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (13, 'yingshi', '5413', '验证token的他异常(不具体)', 'token验证失败', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (14, 'yingshi', '5415', '设备通道错', '设备判断请求通道不存在', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (15, 'yingshi', '5416', '设备资源受限', '设备资源受限', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (16, 'yingshi', '5451', '设备不支持的码流类型', '设备不支持的码流类型', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (17, 'yingshi', '5452', '设备链接流媒体服务器失败', '设备链接流媒体服务器失败', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (18, 'yingshi', '5454', '流媒体中关于设备取流会话不存在', '流媒体中关于设备取流会话不存在', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (19, 'yingshi', '5455', '设备通道未关联', '设备通道未关联', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (20, 'yingshi', '5456', '设备通道关联设备不在线', '设备通道关联设备不在线', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (21, 'yingshi', '5457', '客户端不支持端到端加密', '客户端不支持端到端加密', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (22, 'yingshi', '5458', '设备不支持当前并发ECDH密', '设备不支持当前并发ECDH密', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (23, 'yingshi', '5459', 'VTDU 处理ECDH 加密失败', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (24, 'yingshi', '5492', '设备不支持的命令', '设备不支持的命令', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (25, 'yingshi', '5500', '服务器处理失败', '服务器处理失败', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (26, 'yingshi', '5503', 'vtm返回分配vtdu失败', 'vtm返回分配vtdu失败', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (27, 'yingshi', '5504', '流媒体vtdu达到最大负载', '流媒体vtdu达到最大负载', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (28, 'yingshi', '5544', '设备返回无视频源', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (29, 'yingshi', '5545', '视频分享时间已经结束', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (30, 'yingshi', '5546', 'vtdu返回达到取流并发路数限制', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (31, 'yingshi', '5547', 'vtdu返回开放平台用户并发限制', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (32, 'yingshi', '5556', 'ticket校验失败', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (33, 'yingshi', '5557', '回放服务器等待流头超时', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (34, 'yingshi', '5558', '查找录像开始时间错误', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (35, 'yingshi', '5560', '群组分享取流二次验证失败', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (36, 'yingshi', '5561', '分享群组用户被锁住', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (37, 'yingshi', '5562', '群组分享用户权限变更', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (38, 'yingshi', '5563', '认证服务连接失败', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (39, 'yingshi', '5564', '认证超时', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (40, 'yingshi', '5565', '缓存无效', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (41, 'yingshi', '5566', '不在分享时间内预览', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (42, 'yingshi', '5567', '分享通道被锁定', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (43, 'yingshi', '5568', '未找到认证类型', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (44, 'yingshi', '5569', '认证返回的参数异常', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (45, 'yingshi', '5600', '分享设备不在分享时间内', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (46, 'yingshi', '5601', '群组分享用户没权限', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (47, 'yingshi', '5602', '群组分享权限变更', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (48, 'yingshi', '5530', '机房故障不可用', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (49, 'yingshi', '5701', 'cas信令返回格式错误', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (50, 'yingshi', '5702', 'SPGW请求Cas、Status透传超时', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (51, 'yingshi', '5703', 'SPGW请求http不通', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (52, 'yingshi', '6001', '客户端参数出错', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (53, 'yingshi', '6099', '客户端默认错误', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (54, 'yingshi', '6101', '不支持的命令', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (55, 'yingshi', '6102', '设备流头发送失败', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (56, 'yingshi', '6103', 'cas/设备返回错误1', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (57, 'yingshi', '6104', 'cas/设备返回错误-1', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (58, 'yingshi', '6105', '设备返回错误码3', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (59, 'yingshi', '6106', '设备返回错误码4', '一般常见于多通道设 备预览 1、通道不存在 2、通道子码流不存在 3、通道不在线', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (60, 'yingshi', '6107', '设备返回错误码5', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (61, 'yingshi', '6108', 'cas信令回应重复', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (62, 'yingshi', '6109', '视频广场取消分享', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (63, 'yingshi', '6110', '设备信令默认错误', '设备错误返回的错误码,不具体', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (64, 'yingshi', '6501', '设备数据链路和实际链路不匹配', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (65, 'yingshi', '6502', '设备数据链路重复建立连接', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (66, 'yingshi', '6503', '设备数据链路端口不匹配', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (67, 'yingshi', '6504', '缓存设备数据链路失败(内存块不足)', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (68, 'yingshi', '6505', '设备发送确认头消息重复', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (69, 'yingshi', '6506', '设备数据先于确定头部到达', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (70, 'yingshi', '6508', '设备数据头部长度非法', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (71, 'yingshi', '6509', '索引找不到设备数据管理块', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (72, 'yingshi', '6510', '设备数据链路vtdu内存块协议状态不匹配', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (73, 'yingshi', '6511', '设备数据头部没有streamkey错误', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (74, 'yingshi', '6512', '设备数据头部非法(较笼统)', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (75, 'yingshi', '6513', '设备数据长度过小', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (76, 'yingshi', '6514', '设备老协议推流头部没有streamkey错误', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (77, 'yingshi', '6515', '设备老协议推流数据非法', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (78, 'yingshi', '6516', '设备老协议索引找不到内存管理块', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (79, 'yingshi', '6517', '设备老协议推流数据非法', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (80, 'yingshi', '6518', '设备数据包过大', NULL, 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (81, 'yingshi', '6519', '设备推流链路网络不稳定', '设备长时间未推流超时', 'f', NULL);
INSERT INTO "public"."camera_status" VALUES (82, 'yingshi', '6520', '设备推流链路网络不稳定(默认)', '设备网络异常', 'f', NULL);
-- ----------------------------
-- Records of camera_status_resolve
-- ----------------------------
INSERT INTO "public"."camera_status_resolve" VALUES (2, 2, '检测服务端是否正常');
INSERT INTO "public"."camera_status_resolve" VALUES (3, 3, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (4, 4, '检查是否有存储卡并且接触良好');
INSERT INTO "public"."camera_status_resolve" VALUES (5, 6, '检查设备网络');
INSERT INTO "public"."camera_status_resolve" VALUES (6, 6, '重启设备接入萤石云');
INSERT INTO "public"."camera_status_resolve" VALUES (7, 7, '检查设备网络');
INSERT INTO "public"."camera_status_resolve" VALUES (8, 7, '重启设备');
INSERT INTO "public"."camera_status_resolve" VALUES (9, 8, '刷新重试或者重启设备');
INSERT INTO "public"."camera_status_resolve" VALUES (10, 9, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (11, 13, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (12, 14, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (13, 15, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (14, 16, '刷新重试或者切换到高清模式');
INSERT INTO "public"."camera_status_resolve" VALUES (15, 17, '检查设备网络,重启设备,刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (16, 19, '检查设备通道是否关联');
INSERT INTO "public"."camera_status_resolve" VALUES (17, 20, '检查设备通道是否上线');
INSERT INTO "public"."camera_status_resolve" VALUES (18, 25, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (19, 26, 'vtdu服务异常,请请稍后重试');
INSERT INTO "public"."camera_status_resolve" VALUES (20, 27, '服务器负载达到上限,请稍后重试');
INSERT INTO "public"."camera_status_resolve" VALUES (21, 28, '设备是否接触良好');
INSERT INTO "public"."camera_status_resolve" VALUES (22, 28, '如果一直无法解决,请联系技术支持');
INSERT INTO "public"."camera_status_resolve" VALUES (23, 30, '请升级为企业版,放开并发限制');
INSERT INTO "public"."camera_status_resolve" VALUES (24, 31, '请确定开放平台用户预览是否超过用户并发数量限制');
INSERT INTO "public"."camera_status_resolve" VALUES (25, 33, '刷新重试,检测设备网络,重启设备');
INSERT INTO "public"."camera_status_resolve" VALUES (26, 48, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (27, 49, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (28, 50, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (29, 51, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (30, 52, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (31, 54, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (32, 55, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (33, 56, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (34, 57, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (35, 58, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (36, 59, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (37, 60, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (38, 61, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (39, 63, '刷新重试,或者重启设备');
INSERT INTO "public"."camera_status_resolve" VALUES (40, 64, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (41, 65, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (42, 66, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (43, 67, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (44, 68, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (45, 69, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (46, 70, '刷新重试,或者重启设备');
INSERT INTO "public"."camera_status_resolve" VALUES (47, 71, '刷新重试');
INSERT INTO "public"."camera_status_resolve" VALUES (48, 80, '刷新重试,或者重启设备');

140
code/VideoAccess-VCMP/script/1.1.1/schema/1.create_camera_status_table.sql

@ -0,0 +1,140 @@
create table if not exists camera_status
(
id serial not null,
platform varchar(32) not null,
status varchar(32) not null,
describe varchar(1024),
paraphrase varchar(1024),
forbidden boolean default false not null,
paraphrase_custom varchar(1024),
constraint camera_status_pk
primary key (id)
);
comment on column camera_status.platform is '平台分类 yingshi gb';
comment on column camera_status.describe is '错误描述';
comment on column camera_status.paraphrase is '释义';
comment on column camera_status.forbidden is '是否禁用';
comment on column camera_status.paraphrase_custom is '自定义释义';
create unique index if not exists camera_status_id_uindex
on camera_status (id);
create table if not exists camera_status_log
(
id serial not null,
status_id integer not null,
time timestamp not null,
constraint camera_status_log_pk
primary key (id),
constraint camera_status_log_camera_status_id_fk
foreign key (status_id) references camera_status
);
create unique index if not exists camera_status_log_id_uindex
on camera_status_log (id);
create unique index if not exists camera_status_log_id_uindex_2
on camera_status_log (id);
create table if not exists camera_status_push_config
(
id serial not null,
name varchar(64) not null,
push_way varchar(32) not null,
notice_way varchar(32) not null,
create_user integer not null,
forbidden boolean default false not null,
timing varchar(32),
constraint camera_online_status_push_config_pk
primary key (id)
);
comment on column camera_status_push_config.push_way is '推送方式 email / phone';
comment on column camera_status_push_config.notice_way is '通知方式 offline / online / timing';
comment on column camera_status_push_config.timing is '定时推送时间';
create unique index if not exists camera_online_status_push_config_id_uindex
on camera_status_push_config (id);
create table if not exists camera_status_push_log
(
id serial not null,
push_config_id integer,
receiver jsonb not null,
time timestamp,
push_way varchar(128) not null,
constraint camera_status_push_log_pk
primary key (id)
);
comment on table camera_status_push_log is '上下线推送日志';
create unique index if not exists camera_status_push_log_id_uindex
on camera_status_push_log (id);
create table if not exists camera_status_push_monitor
(
id serial not null,
config_id integer not null,
camera_id integer not null,
constraint camera_status_push_monitor_pk
primary key (id),
constraint camera_status_push_monitor_camera_id_fk
foreign key (camera_id) references camera,
constraint camera_status_push_monitor_camera_status_push_config_id_fk
foreign key (config_id) references camera_status_push_config
);
create unique index if not exists camera_status_push_monitor_id_uindex
on camera_status_push_monitor (id);
create table if not exists camera_status_push_receiver
(
id serial not null,
config_id integer not null,
receiver varchar(64) not null,
constraint camera_status_push_receiver_pk
primary key (id),
constraint camera_status_push_receiver_camera_status_push_config_id_fk
foreign key (config_id) references camera_status_push_config
);
comment on column camera_status_push_receiver.receiver is '接受者信息 邮箱或者电话号码';
create unique index if not exists camera_status_push_receiver_id_uindex
on camera_status_push_receiver (id);
create table if not exists camera_status_resolve
(
id serial not null,
status_id integer not null,
resolve varchar(1024) not null,
constraint camera_status_resolve_pk
primary key (id),
constraint camera_status_resolve_camera_status_id_fk
foreign key (status_id) references camera_status
);
comment on table camera_status_resolve is '错误码解决方案';
create unique index if not exists camera_status_resolve_id_uindex
on camera_status_resolve (id);

21
code/VideoAccess-VCMP/script/1.1.2/schema/1.update_camera_status_config.sql

@ -0,0 +1,21 @@
alter table camera_status_push_config alter column notice_way type varchar[32] using notice_way::varchar[32];
DROP TABLE if exists camera_status_push_log;
create table if not exists camera_status_push_log
(
id serial not null,
push_config_id integer,
time timestamp,
push_way varchar(128) not null,
camera integer[] not null,
receiver character varying[] not null,
constraint camera_status_push_log_pk
primary key (id)
);
comment on table camera_status_push_log is '上下线推送日志';
create unique index if not exists camera_status_push_log_id_uindex
on camera_status_push_log (id);

5
code/VideoAccess-VCMP/script/1.1.2/schema/2.update_push_log.sql

@ -0,0 +1,5 @@
alter table camera_status_push_log
add timing varchar(64);
alter table camera_status_push_log
add notice_way varchar[];

4
code/VideoAccess-VCMP/script/1.1.2/schema/3.update_camera_channel_no.sql

@ -0,0 +1,4 @@
alter table camera
add channel_no varchar(128);
comment on column camera.channel_no is '通道号';

13
code/VideoAccess-VCMP/script/1.1.2/schema/4.create_camera_status_offline_log.sql

@ -0,0 +1,13 @@
create table if not exists camera_status_offline_log
(
id serial not null,
camera_id integer not null,
status varchar(32) not null,
time timestamp not null,
constraint camera_status_offline_log_pk
primary key (id)
);
create unique index if not exists camera_status_offline_log_id_uindex
on camera_status_offline_log (id);

19
code/VideoAccess-VCMP/script/1.2.1/schema/1.create_application.sql

@ -0,0 +1,19 @@
create table if not exists application
(
id serial not null,
name varchar(32) not null,
type character varying[],
app_key varchar(64) not null,
app_secret varchar(64) not null,
create_user_id integer not null,
create_time timestamp not null,
forbidden boolean default false not null,
constraint application_pk
primary key (id)
);
comment on column application.type is 'web / app / wxapp / other';
create unique index if not exists application_id_uindex
on application (id);

4
code/VideoAccess-VCMP/script/1.3.0/schema/1.alert_gbcamera_did.sql

@ -0,0 +1,4 @@
alter table "gbCamera"
add did varchar(128);
comment on column "gbCamera".did is '设备自定义id';

90
code/VideoAccess-VCMP/script/1.3.0/schema/2.create_mirror_table.sql

@ -0,0 +1,90 @@
create table if not exists mirror
(
id serial not null,
template varchar(63) not null,
create_user integer not null,
create_time timestamp with time zone not null,
update_time timestamp with time zone,
title varchar(128),
show_header boolean not null,
publish boolean default false not null,
mid varchar(32) not null,
publish_time timestamp with time zone,
constraint mirror_pk
primary key (id)
);
comment on column mirror.template is '模板标识';
create unique index if not exists mirror_id_uindex
on mirror (id);
create table if not exists mirror_tree
(
id serial not null,
name varchar(64) not null,
level integer not null,
dependence integer,
mirror_id integer not null,
constraint mirror_tree_pk
primary key (id),
constraint mirror_tree_mirror_id_fk
foreign key (mirror_id) references mirror
);
comment on table mirror_tree is '镜像服务的树节点';
comment on column mirror_tree.level is '层级标注';
create unique index if not exists mirror_tree_id_uindex
on mirror_tree (id);
create table if not exists mirror_filter_group
(
id serial not null,
name varchar(64) not null,
forbidden boolean default false not null,
mirror_id integer not null,
constraint mirror_filter_group_pk
primary key (id),
constraint mirror_filter_group_mirror_id_fk
foreign key (mirror_id) references mirror
);
comment on table mirror_filter_group is '筛选分组';
create unique index if not exists mirror_filter_group_id_uindex
on mirror_filter_group (id);
create table if not exists mirror_filter
(
id serial not null,
name varchar(64) not null,
group_id integer not null,
constraint mirror_filter_pk
primary key (id),
constraint mirror_filter_mirror_filter_group_id_fk
foreign key (group_id) references mirror_filter_group
);
create unique index if not exists mirror_filter_id_uindex
on mirror_filter (id);
create table if not exists mirror_camera
(
id serial not null,
camera_id integer not null,
tree_ids integer[] not null,
filter_ids integer[],
mirror_id integer not null,
constraint mirror_camera_pk
primary key (id),
constraint mirror_camera_camera_id_fk
foreign key (camera_id) references camera,
constraint mirror_camera_mirror_id_fk
foreign key (mirror_id) references mirror
);
create unique index if not exists mirror_camera_id_uindex
on mirror_camera (id);

17
code/VideoAccess-VCMP/script/1.3.1/data/1_sync_camera_data/.vscode/launch.json

@ -0,0 +1,17 @@
{
// 使 IntelliSense
//
// 访: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "启动程序",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}\\index.js"
}
]
}

8
code/VideoAccess-VCMP/script/1.3.1/data/1_sync_camera_data/Dockerfile

@ -0,0 +1,8 @@
FROM repository.anxinyun.cn/base-images/nodejs12:20.10.12.2
COPY ./code/VideoAccess-VCMP/script/1.3.1/data/1_sync_camera_data/ /var/app
WORKDIR /var/app
RUN npm cache clean -f
RUN rm -rf package-lock.json
RUN npm install --registry https://nexus.ngaiot.com/repository/fs-npm/
CMD ["node", "index.js"]

156
code/VideoAccess-VCMP/script/1.3.1/data/1_sync_camera_data/index.js

@ -0,0 +1,156 @@
try {
const { Pool, Client } = require('pg')
const XLSX = require('xlsx')
const path = require('path')
const request = require('superagent')
const moment = require('moment')
// 连接数据库
const vcmpPool = new Pool({
user: 'FashionAdmin',
host: '10.8.40.223',
database: 'video-access',
password: 'Fas123_',
port: 5432,
})
const anxinPool = new Pool({
user: 'postgres',
host: '10.8.40.210',
database: 'AnxinCloud',
password: 'postgres',
port: 5432,
})
const fun = async () => {
// note: we don't try/catch this because if connecting throws an exception
// we don't need to dispose of the client (it will be undefined)
const vcmpClient = await vcmpPool.connect()
const anxinClient = await anxinPool.connect()
try {
await vcmpClient.query('BEGIN')
const yingshiHost = 'https://open.ys7.com/api/'
// 获取全部萤石摄像头信息
const anxinYSRes = await anxinClient.query(`SELECT * FROM t_video_ipc WHERE type=$1`, ['yingshi']);
// console.log(anxinYSRes);
// 获取所有萤石账号信息
const secretYSRes = await vcmpClient.query(`SELECT * FROM secret_yingshi`)
const secretRes = secretYSRes.rows
// console.log('secretRes', secretRes);
let addSuccessCount = 0
let addRepeatCount = 0
let addUnlegalCount = 0
let addNoAuthCount = 0
for (let c of anxinYSRes.rows) {
console.log(`处理序列号:${c.serial_no}`)
if (!c.serial_no) {
addUnlegalCount += 1
continue
}
let vcmpExistRes = await vcmpClient.query(
`SELECT * FROM "gbCamera" WHERE streamid=$1`, [c.serial_no]
)
let vcmpExistRows = vcmpExistRes.rows
let cameraExistRes = await vcmpClient.query(`SELECT * FROM camera WHERE serial_no=$1`, [c.serial_no])
let cameraRes = cameraExistRes.rows || []
let repeatCamera = cameraRes.find(cr => {
return (
!cr.channel_no && c.channel_no == 1
) || (cr.channel_no == c.channel_no)
})
if (repeatCamera) {
console.log(`当前设备序列号 ${c.serial_no} 通道号 ${c.channel_no} 已存在`);
console.log(`已存在 id=${repeatCamera.id} 通道号 ${repeatCamera.channel_no}`);
addRepeatCount++
continue
}
if (vcmpExistRows.length) {
let beloneSecretId = null
let serialUnlegal = false
for (let s of secretRes) {
let start = (new Date()).getTime();
console.log(`当前查询账号key ${s.key}`);
if (!s.newToken) {
const tokenRes = await request.post(`${yingshiHost}lapp/token/get`).query({
appKey: s.key,
appSecret: s.secret
})
console.log(`查询 token 结果`, tokenRes.body);
if (tokenRes.body.code == 200 && tokenRes.body.data) {
const { accessToken, expireTime } = tokenRes.body.data
s.newToken = accessToken
} else {
throw `未能获取萤石token ${s.key} ${tokenRes.body.code}`
}
}
while (((new Date()).getTime() - start) < 3000) {//限制频率
continue;
}
// 检测设备所属
const cameraState = await request.post(`${yingshiHost}lapp/device/info`).query({
accessToken: s.newToken,
deviceSerial: c.serial_no
})
console.log(`查询设备所属结果`, cameraState.body.code, cameraState.body.msg);
if (cameraState.body.code == 200) {
console.log(`所属萤石账号 ${s.key}`);
beloneSecretId = s.id
break
} else if (cameraState.body.code == 20018) {
} else if (cameraState.body.code == 20014) {
serialUnlegal = true
break
}
}
if (serialUnlegal) {
addUnlegalCount++
continue
}
if (!beloneSecretId) {
console.error('没有查询到所属账号')
console.log(vcmpExistRows);
addNoAuthCount++
continue
}
const cameraInQuery = `INSERT INTO "camera" (type, name, serial_no, cloud_control,longitude,latitude,create_time,create_user_id,yingshi_secret_id,gb_id,channel_no) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING id;`
await vcmpClient.query(cameraInQuery, ['yingshi', c.name, c.serial_no, c.has_ptz, c.longitude, c.latitude, moment().format(), 1, beloneSecretId, vcmpExistRows[0].id, c.channel_no])
addSuccessCount++
} else {
console.error('当前序列号不存在,应在 vcmp 添加相应萤石账号');
addNoAuthCount++
}
}
console.log(`
${anxinYSRes.rows.length}
添加 ${addSuccessCount}
已有 ${addRepeatCount}
序列号不合法 ${addUnlegalCount}
无所属 ${addNoAuthCount}
`);
// await client.query('ROLLBACK')
await vcmpClient.query('COMMIT')
console.log('执行完毕~')
} catch (e) {
await vcmpClient.query('ROLLBACK')
console.log('执行错误~')
throw e
} finally {
vcmpClient.release();
}
}
fun()
} catch (error) {
console.error(error)
}

18
code/VideoAccess-VCMP/script/1.3.1/data/1_sync_camera_data/package.json

@ -0,0 +1,18 @@
{
"name": "appkey-generator",
"version": "1.0.0",
"description": "tool",
"main": "index.js",
"scripts": {
"test": "mocha",
"start": "set NODE_ENV=development&&node index"
},
"author": "liu",
"license": "ISC",
"dependencies": {
"moment": "^2.29.4",
"pg": "^7.18.2",
"superagent": "3.5.2",
"xlsx": "^0.17.1"
}
}

5
code/VideoAccess-VCMP/script/1.3.2/schema/1.collect_all_camera_to_one_user.sql

@ -0,0 +1,5 @@
-- 将所有现有摄像头归为同一账号下
UPDATE camera
SET create_user_id = 2149
WHERE create_time <= make_timestamptz(2022, 9, 17, 22, 22, 22);

33
code/VideoAccess-VCMP/script/1.3.3/schema/1.create_camera_status_alarm.sql

@ -0,0 +1,33 @@
create table if not exists camera_status_alarm
(
id serial not null,
status_id integer not null,
description varchar(1024),
confirm varchar(1024),
confirm_time timestamp with time zone,
create_time timestamp with time zone,
update_time timestamp with time zone,
serial_no varchar(64),
channel_no varchar(64),
platform varchar(32),
constraint camera_status_alarm_pk
primary key (id),
constraint camera_status_alarm_camera_status_id_fk
foreign key (status_id) references camera_status
);
comment on column camera_status_alarm.description is '描述';
comment on column camera_status_alarm.confirm is '确认信息';
comment on column camera_status_alarm.create_time is '生成时间';
comment on column camera_status_alarm.update_time is '更新时间';
comment on column camera_status_alarm.serial_no is '序列号';
comment on column camera_status_alarm.channel_no is '通道号';
create unique index if not exists camera_status_alarm_id_uindex
on camera_status_alarm (id);

10
code/VideoAccess-VCMP/script/1.3.4/schema/1.alert_tables.sql

@ -0,0 +1,10 @@
alter table camera_status_alarm
add auto_restore bool default false;
comment on column camera_status_alarm.auto_restore is '是否自动恢复的';
alter table camera_status_alarm alter column confirm_time type timestamp(6) using confirm_time::timestamp(6);
alter table camera_status_alarm alter column create_time type timestamp(6) using create_time::timestamp(6);
alter table camera_status_alarm alter column update_time type timestamp(6) using update_time::timestamp(6);

1
code/VideoAccess-VCMP/script/1.3.5.1/data/1.update_secret_yingshi.sql

@ -0,0 +1 @@
INSERT INTO secret_yingshi (key, secret, token, expire) VALUES ('88c43faadfd545baaaadbb1a84a060d5', 'ac6da04021c4d410c7033ccff991d981', null, null)

1
code/VideoAccess-VCMP/script/1.3.5/data/1.camera_kindId_update.sql

@ -0,0 +1 @@
UPDATE camera SET kind_id = 1314 WHERE kind_id IS null

17
code/VideoAccess-VCMP/script/1.3.6/data/1_batch_entry_camera/.vscode/launch.json

@ -0,0 +1,17 @@
{
// 使 IntelliSense
//
// 访: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "启动程序",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}\\index.js"
}
]
}

21
code/VideoAccess-VCMP/script/1.3.6/data/1_batch_entry_camera/Dockerfile

@ -0,0 +1,21 @@
FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node:12-dev as builder
COPY . /var/app
WORKDIR /var/app
EXPOSE 8080
RUN npm config set registry=http://10.8.30.22:7000
RUN echo "{\"time\":\"$BUILD_TIMESTAMP\",\"build\": \"$BUILD_NUMBER\",\"revision\": \"$SVN_REVISION_1\",\"URL\":\"$SVN_URL_1\"}" > version.json
RUN npm cache clean -f
RUN rm -rf package-lock.json
RUN npm install --registry http://10.8.30.22:7000
FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node:12
COPY --from=builder --chown=node /var/app /home/node/app
WORKDIR /home/node/app
CMD ["node", "index.js"]

78
code/VideoAccess-VCMP/script/1.3.6/data/1_batch_entry_camera/index.js

@ -0,0 +1,78 @@
try {
const { Pool, Client } = require('pg')
const XLSX = require('xlsx')
const path = require('path')
const moment = require('moment')
// 连接数据库
const pool = new Pool({
user: 'FashionAdmin',
host: '10.8.40.223',
database: 'video-access',
password: 'Fas123_',
port: 5432,
})
const fun = async () => {
// note: we don't try/catch this because if connecting throws an exception
// we don't need to dispose of the client (it will be undefined)
const client = await pool.connect()
try {
await client.query('BEGIN')
// 读取数据文件
let workbook = XLSX.readFile(path.join(__dirname, '摄像头信息对接.xlsx'))
let firstSheetName = workbook.SheetNames[0];
let worksheet = workbook.Sheets[firstSheetName];
let res = XLSX.utils.sheet_to_json(worksheet);
// console.log(res);
const yingshiSecretRes = await client.query(`SELECT * FROM secret_yingshi WHERE key='88c43faadfd545baaaadbb1a84a060d5'`)
console.log(yingshiSecretRes);
let secretRes = null
if (yingshiSecretRes && yingshiSecretRes.rows && yingshiSecretRes.rows.length) {
secretRes = yingshiSecretRes.rows[0]
} else {
throw '没有目标 SECRET'
}
for (let d of res) {
console.log(`处理${d['设备序列号']} ${d['通道号']} USER ${d['userid']}`);
let gbRes = await client.query(`SELECT * FROM "gbCamera" WHERE ipctype=$1 AND streamid=$2`, ['yingshi', d['设备序列号']])
let gb = null
if (gbRes.rows.length) {
gb = gbRes.rows[0]
} else {
console.log(`GB 里没查到`)
continue
}
let cameraRes = await client.query(`SELECT * FROM camera WHERE type=$1 AND serial_no=$2 AND create_user_id=$3 AND channel_no=$4`, ['yingshi', d['设备序列号'], d['userid'], d['通道号']]);
let cameraRows = cameraRes.rows
if (cameraRows.length) {
console.log(`添加过了`);
} else {
await client.query(`INSERT INTO "camera" (type, name, serial_no, cloud_control, high_definition, voice, longitude,latitude, forbidden, create_time, delete, create_user_id, yingshi_secret_id, gb_id, channel_no, kind_id) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)`, ['yingshi', gb.name || null, d['设备序列号'], false, true, false, 115.88, 28.54, false, moment().format('YYYY-MM-DD HH:mm:ss'), false, d['userid'], secretRes.id, gb.id, d['通道号'], 1]);
}
}
// await client.query('ROLLBACK')
await client.query('COMMIT')
console.log('执行完毕~')
} catch (e) {
await client.query('ROLLBACK')
console.log('执行错误~')
throw e
} finally {
client.release();
}
}
fun()
} catch (error) {
console.error(error)
}

17
code/VideoAccess-VCMP/script/1.3.6/data/1_batch_entry_camera/package.json

@ -0,0 +1,17 @@
{
"name": "appkey-generator",
"version": "1.0.0",
"description": "tool",
"main": "index.js",
"scripts": {
"test": "mocha",
"start": "set NODE_ENV=development&&node index"
},
"author": "liu",
"license": "ISC",
"dependencies": {
"moment": "^2.29.4",
"pg": "^7.18.2",
"xlsx": "^0.17.1"
}
}

BIN
code/VideoAccess-VCMP/script/1.3.6/data/1_batch_entry_camera/摄像头信息对接.xlsx

Binary file not shown.

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save