Compare commits
274 Commits
main
...
release_0.
Author | SHA1 | Date |
---|---|---|
wenlele | 1453d187c4 | 2 years ago |
巴林闲侠 | ce3e1c932d | 2 years ago |
巴林闲侠 | df40d3d9df | 2 years ago |
巴林闲侠 | 4e192fe454 | 2 years ago |
巴林闲侠 | a9ced94fc7 | 2 years ago |
巴林闲侠 | a31d4c04d3 | 2 years ago |
巴林闲侠 | f0760bd0e5 | 2 years ago |
deartibers | d588ac9661 | 2 years ago |
deartibers | 56e277b099 | 2 years ago |
巴林闲侠 | 13524a5cf1 | 2 years ago |
巴林闲侠 | 04663f3cbf | 2 years ago |
deartibers | 405c723228 | 2 years ago |
巴林闲侠 | 1ae93b7676 | 2 years ago |
巴林闲侠 | ffc064fcb0 | 2 years ago |
deartibers | bb385d7536 | 2 years ago |
巴林闲侠 | 55928225d5 | 2 years ago |
巴林闲侠 | d372ce14fc | 2 years ago |
巴林闲侠 | c079740238 | 2 years ago |
wenlele | e6c365494d | 2 years ago |
wenlele | 766935ed75 | 2 years ago |
deartibers | c15990cd60 | 2 years ago |
deartibers | 761c829c0e | 2 years ago |
巴林闲侠 | a9ce108e9d | 2 years ago |
wenlele | 29244b7288 | 2 years ago |
wenlele | cb6d752abc | 2 years ago |
deartibers | c38fb8cbf9 | 2 years ago |
巴林闲侠 | f05ade2b91 | 2 years ago |
巴林闲侠 | bfdf962443 | 2 years ago |
巴林闲侠 | f0a380d64d | 2 years ago |
deartibers | 36052b634c | 2 years ago |
deartibers | d067752179 | 2 years ago |
wenlele | 06fc355304 | 2 years ago |
wenlele | 0c08d9e55d | 2 years ago |
巴林闲侠 | c8a00261a0 | 2 years ago |
巴林闲侠 | 9131be6873 | 2 years ago |
wenlele | 17de5056e4 | 2 years ago |
wenlele | 37b84265a1 | 2 years ago |
巴林闲侠 | ed1423141f | 2 years ago |
巴林闲侠 | ccaa56c1ea | 2 years ago |
deartibers | c9bd721035 | 2 years ago |
巴林闲侠 | 9d2420130b | 2 years ago |
巴林闲侠 | e3a6dc6e85 | 2 years ago |
wenlele | 8cb1cfcf8b | 2 years ago |
巴林闲侠 | 8e74408c87 | 2 years ago |
巴林闲侠 | efdde52111 | 2 years ago |
deartibers | c6b6345116 | 2 years ago |
巴林闲侠 | f72a28c30b | 2 years ago |
巴林闲侠 | 707f8437fe | 2 years ago |
巴林闲侠 | f6a7c66c68 | 2 years ago |
巴林闲侠 | b6a763e3c8 | 2 years ago |
wenlele | feb1824eed | 2 years ago |
deartibers | 623fae136e | 2 years ago |
deartibers | 73ee59529f | 2 years ago |
巴林闲侠 | 30ccd213a7 | 2 years ago |
巴林闲侠 | 13a97ea076 | 2 years ago |
巴林闲侠 | b0d21b367c | 2 years ago |
wenlele | 885c69d4d6 | 2 years ago |
deartibers | 97d8d0337e | 2 years ago |
deartibers | 769ff49451 | 2 years ago |
巴林闲侠 | 09f72f5c9d | 2 years ago |
巴林闲侠 | faf23bb4f6 | 2 years ago |
巴林闲侠 | 6c646018a6 | 2 years ago |
deartibers | bccf70dec1 | 2 years ago |
wenlele | 96e04ea0db | 2 years ago |
wenlele | ab2e4dc81a | 2 years ago |
巴林闲侠 | 09af37576b | 2 years ago |
巴林闲侠 | 32ded7ec5a | 2 years ago |
wenlele | 3d1242fa31 | 2 years ago |
巴林闲侠 | 1bbcd0c6a5 | 2 years ago |
巴林闲侠 | 517929e1ce | 2 years ago |
wenlele | a6c4ac075f | 2 years ago |
wenlele | d255cb4ef6 | 2 years ago |
巴林闲侠 | 39fa23c823 | 2 years ago |
巴林闲侠 | 263c79d246 | 2 years ago |
巴林闲侠 | ee1dee9f84 | 2 years ago |
wenlele | 7ed76c4208 | 2 years ago |
wenlele | 8d29279fd9 | 2 years ago |
wenlele | bb9974c8b2 | 2 years ago |
巴林闲侠 | 4a3946d4cc | 2 years ago |
巴林闲侠 | 756231efa7 | 2 years ago |
巴林闲侠 | eb9789e6c0 | 2 years ago |
巴林闲侠 | 1b16c8a05b | 2 years ago |
wenlele | 35ab0b2fa6 | 2 years ago |
巴林闲侠 | e9e4b42060 | 2 years ago |
巴林闲侠 | b3caa8a43a | 2 years ago |
wenlele | 26aa1c6ae8 | 2 years ago |
巴林闲侠 | a7d98ddcfc | 2 years ago |
巴林闲侠 | 8deb57ba1f | 2 years ago |
巴林闲侠 | fa513c5e8e | 2 years ago |
wenlele | 5a0da83039 | 2 years ago |
wenlele | f69525056b | 2 years ago |
巴林闲侠 | 57e99c139a | 2 years ago |
巴林闲侠 | 7279365a62 | 2 years ago |
wenlele | e8d0d7c2d7 | 2 years ago |
巴林闲侠 | 1f3dc736fb | 2 years ago |
巴林闲侠 | cfc281eddc | 2 years ago |
wenlele | d171c80b5a | 2 years ago |
巴林闲侠 | 28756bee04 | 2 years ago |
巴林闲侠 | eb5bbc2758 | 2 years ago |
wenlele | 03fc11ead2 | 2 years ago |
巴林闲侠 | de5d8f4283 | 2 years ago |
巴林闲侠 | 06f310034e | 2 years ago |
巴林闲侠 | 7826cbc581 | 2 years ago |
wenlele | af10506c47 | 2 years ago |
巴林闲侠 | b288d2156e | 2 years ago |
巴林闲侠 | b712b36be8 | 2 years ago |
巴林闲侠 | 7db8194212 | 2 years ago |
巴林闲侠 | a421a1671e | 2 years ago |
巴林闲侠 | 5ad052f205 | 2 years ago |
巴林闲侠 | 6553443e41 | 2 years ago |
巴林闲侠 | ee23345513 | 2 years ago |
巴林闲侠 | 89749c7dc2 | 2 years ago |
wenlele | d1dbeeccae | 2 years ago |
wenlele | 26a9ff2b1f | 2 years ago |
wenlele | 45761dd89b | 2 years ago |
wenlele | 9958510f5c | 2 years ago |
巴林闲侠 | 4d6398b7e5 | 2 years ago |
巴林闲侠 | 25902d6f22 | 2 years ago |
巴林闲侠 | e1dd11c50e | 2 years ago |
巴林闲侠 | aff86a6820 | 2 years ago |
巴林闲侠 | 54d4227b59 | 2 years ago |
巴林闲侠 | 65f427a12d | 2 years ago |
巴林闲侠 | 1cd95e5ad3 | 2 years ago |
巴林闲侠 | 0debdb7c1d | 2 years ago |
wenlele | 3430ecb5e2 | 2 years ago |
wenlele | 2d9f850a9f | 2 years ago |
巴林闲侠 | 0594201af5 | 2 years ago |
wenlele | 4cb212cbcf | 2 years ago |
巴林闲侠 | acc1f98e13 | 2 years ago |
巴林闲侠 | c0ec917f01 | 2 years ago |
巴林闲侠 | 5cc1e758ef | 2 years ago |
巴林闲侠 | e3d08b97f0 | 2 years ago |
wenlele | ab8b7bc8d1 | 2 years ago |
wenlele | 6369ae4c5e | 2 years ago |
wenlele | 53515f4a3d | 2 years ago |
巴林闲侠 | a15fb7be51 | 2 years ago |
巴林闲侠 | b86cbbd98e | 2 years ago |
巴林闲侠 | 2c64beb088 | 2 years ago |
wenlele | fa9cabdef0 | 2 years ago |
wenlele | 68a7d60fa0 | 2 years ago |
巴林闲侠 | 3b23a41e80 | 2 years ago |
巴林闲侠 | 93b4754159 | 2 years ago |
wenlele | 0a210e2729 | 2 years ago |
wenlele | 4b87887396 | 2 years ago |
wenlele | ec2b6fd849 | 2 years ago |
巴林闲侠 | f0842505d1 | 2 years ago |
yuan_yi | b75fee46ea | 2 years ago |
yuan_yi | 0956159fc8 | 2 years ago |
yuan_yi | 12815a3cee | 2 years ago |
wenlele | f468021def | 2 years ago |
yuan_yi | dfcac5c2fb | 2 years ago |
yuan_yi | c8e54329a7 | 2 years ago |
yuan_yi | d9739eed96 | 2 years ago |
yuan_yi | 720f3e29ef | 2 years ago |
yuan_yi | a0e55f01e7 | 2 years ago |
yuan_yi | 51c2f84976 | 2 years ago |
wenlele | 7dea13915d | 2 years ago |
wenlele | 8fd9b56cc7 | 2 years ago |
wenlele | b31d5a8c1d | 2 years ago |
yuan_yi | 63e8968c10 | 2 years ago |
yuan_yi | f8e5e30e57 | 2 years ago |
yuan_yi | 538fb4630a | 2 years ago |
wenlele | 205f8f177e | 2 years ago |
yuan_yi | 4794d63ffe | 2 years ago |
yuan_yi | f7bd48bfaa | 2 years ago |
yuan_yi | ce47dbadcf | 2 years ago |
yuan_yi | 77efe48d7c | 2 years ago |
yuan_yi | 377503cbcb | 2 years ago |
yuan_yi | 33e9e9b42a | 2 years ago |
yuan_yi | 9d1096583e | 2 years ago |
yuan_yi | cffc4e95be | 2 years ago |
yuan_yi | 44606dfd4c | 2 years ago |
yuan_yi | 8c5407347d | 2 years ago |
wenlele | 345a2014db | 2 years ago |
yuan_yi | 8589ead102 | 2 years ago |
yuan_yi | 6dbcca3fa9 | 2 years ago |
yuan_yi | e175e6ade5 | 2 years ago |
wenlele | 1fd486536b | 2 years ago |
yuan_yi | b009f18bc2 | 2 years ago |
yuan_yi | 24c1294aad | 2 years ago |
wenlele | e632b74387 | 2 years ago |
wenlele | 6efe633899 | 2 years ago |
deartibers | 5a86abc520 | 2 years ago |
yuan_yi | 8a9b814ea6 | 2 years ago |
wenlele | 28e2133a7c | 2 years ago |
wenlele | 3f3d357f1e | 2 years ago |
yuan_yi | efab54dbdc | 2 years ago |
yuan_yi | 5919ec2850 | 2 years ago |
wenlele | 5c5334ff72 | 2 years ago |
wenlele | cf93351a5a | 2 years ago |
yuan_yi | 5750c3872e | 2 years ago |
yuan_yi | 96954a8a6e | 2 years ago |
yuan_yi | f638047ae7 | 2 years ago |
yuan_yi | 7801359f73 | 2 years ago |
yuan_yi | fff6d76346 | 2 years ago |
yuan_yi | a033e13a2e | 2 years ago |
yuan_yi | ddc013104d | 2 years ago |
yuan_yi | c61d69a720 | 2 years ago |
yuan_yi | 79d4f26ec1 | 2 years ago |
deartibers | a1c20552b1 | 2 years ago |
deartibers | 38f9bf91da | 2 years ago |
wenlele | 70080015d7 | 2 years ago |
yuan_yi | 64fa1bc28c | 2 years ago |
yuan_yi | 1efb405f19 | 2 years ago |
yuan_yi | 974455267e | 2 years ago |
deartibers | 20daa99a47 | 2 years ago |
yuan_yi | 54737dba51 | 2 years ago |
yuan_yi | 9dc3554c7d | 2 years ago |
wenlele | 99b8aca186 | 3 years ago |
wenlele | dc0136a212 | 3 years ago |
wenlele | 70d75b164a | 3 years ago |
wenlele | 1d6877ce2d | 3 years ago |
wenlele | 068ccda661 | 3 years ago |
deartibers | 47a80141b0 | 3 years ago |
deartibers | b4f2dc62e3 | 3 years ago |
yuan_yi | 224bc45174 | 3 years ago |
yuan_yi | 9e8de3ff47 | 3 years ago |
yuan_yi | caa85094bd | 3 years ago |
yuan_yi | d1be1ce22d | 3 years ago |
yuan_yi | 0c1b8f8d99 | 3 years ago |
deartibers | 25c88dea6b | 3 years ago |
wenlele | f1f3a17be3 | 3 years ago |
wenlele | 870afbcd47 | 3 years ago |
deartibers | ee8881a661 | 3 years ago |
wenlele | b9ac39955c | 3 years ago |
wenlele | c23c764238 | 3 years ago |
deartibers | 981dc894c4 | 3 years ago |
yuan_yi | 37779c29b9 | 3 years ago |
yuan_yi | 255466ef39 | 3 years ago |
yuan_yi | 12be6e0ba6 | 3 years ago |
yuan_yi | 29de0083a4 | 3 years ago |
yuan_yi | 685f65affd | 3 years ago |
wenlele | 2bee6dc9a3 | 3 years ago |
wenlele | 7113aaf672 | 3 years ago |
deartibers | a45a0a9a50 | 3 years ago |
deartibers | c3a82d8979 | 3 years ago |
yuan_yi | 4168be60d7 | 3 years ago |
yuan_yi | 8c4cffa8b5 | 3 years ago |
yuan_yi | 068c0a6e50 | 3 years ago |
deartibers | bdbd43ef73 | 3 years ago |
deartibers | b1d1b4bfb5 | 3 years ago |
wenlele | 525d99c736 | 3 years ago |
yuan_yi | 90b6c11a3f | 3 years ago |
yuan_yi | 6f23175395 | 3 years ago |
yuan_yi | 3e898f7a3e | 3 years ago |
yuan_yi | 85b64e95c4 | 3 years ago |
yuan_yi | d18dfa9c30 | 3 years ago |
deartibers | 27594bada8 | 3 years ago |
wenlele | 5744fe52b8 | 3 years ago |
wenlele | 6c712920c8 | 3 years ago |
wenlele | b6ed892275 | 3 years ago |
deartibers | 1aad3c3bef | 3 years ago |
wenlele | 3f5742570b | 3 years ago |
deartibers | 00610e8c2a | 3 years ago |
deartibers | 1ebc1f15ae | 3 years ago |
yuan_yi | f1c3748571 | 3 years ago |
yuan_yi | c494dce09e | 3 years ago |
deartibers | 72f2e341b4 | 3 years ago |
yuan_yi | 07f13a617f | 3 years ago |
yuan_yi | d192b64407 | 3 years ago |
yuan_yi | 333330d9c3 | 3 years ago |
yuan_yi | b122c1e11c | 3 years ago |
yuan_yi | 06648ff786 | 3 years ago |
deartibers | 33b42ed889 | 3 years ago |
wenlele | a8f7b63cac | 3 years ago |
wenlele | 29a904dce8 | 3 years ago |
wenlele | 911e502bf4 | 3 years ago |
wenlele | 6e92a71354 | 3 years ago |
deartibers | 67c41bd4d9 | 3 years ago |
deartibers | 15420f0c96 | 3 years ago |
deartibers | 26390a2a81 | 3 years ago |
yuan_yi | 40a022484b | 3 years ago |
yuan_yi | 05e60fb524 | 3 years ago |
yuan_yi | 052d73e231 | 3 years ago |
@ -1,41 +1,52 @@ |
|||||
{ |
{ |
||||
// 使用 IntelliSense 了解相关属性。 |
// 使用 IntelliSense 了解相关属性。 |
||||
// 悬停以查看现有属性的描述。 |
// 悬停以查看现有属性的描述。 |
||||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 |
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 |
||||
"version": "0.2.0", |
"version": "0.2.0", |
||||
"configurations": [ |
"configurations": [ |
||||
{ |
{ |
||||
"type": "node", |
"type": "node", |
||||
"request": "launch", |
"request": "launch", |
||||
"name": "启动API", |
"name": "启动API", |
||||
"program": "${workspaceRoot}/server.js", |
"program": "${workspaceRoot}/server.js", |
||||
"env": { |
"env": { |
||||
"NODE_ENV": "development" |
"NODE_ENV": "development" |
||||
}, |
}, |
||||
"args": [ |
"args": [ |
||||
"-p 14000", |
"-p 4000", |
||||
"-f http://localhost:14000", |
"-f http://localhost:4000", |
||||
// "-g postgres://postgres:123@10.8.30.32:5432/yinjiguanli", |
"-g postgres://postgres:123@10.8.30.32:5432/video_access", |
||||
// "-g postgres://postgres:123456@221.230.55.27:5432/yinjiguanli", |
"--redisHost 127.0.0.1", |
||||
// "-g postgres://FashionAdmin:123456@10.8.30.156:5432/SmartEmergency", |
"--redisPort 6379", |
||||
"-g postgres://postgres:Mantis1921@116.63.50.139:54327/smartYingji" |
"--axyApiUrl http://127.0.0.1:4100", |
||||
] |
"--iotAuthApi http://127.0.0.1:4200", |
||||
}, |
"--godUrl https://restapi.amap.com/v3", |
||||
{ |
"--godKey 21c2d970e1646bb9a795900dd00093ce", |
||||
"type": "node", |
"--mqttVideoServer mqtt://10.8.30.71:30883", |
||||
"request": "launch", |
"--iotVideoServerUrl http://221.230.55.27:8081", |
||||
"name": "run mocha", |
// "--iotVideoServerUrl http://10.8.30.59:8080", |
||||
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha", |
"--cameraPlayWsHost ws://221.230.55.27:8081", |
||||
"stopOnEntry": false, |
"--cameraPlayHttpFlvHost http://221.230.55.27:2020", |
||||
"args": [ |
"--cameraPlayHlsHost http://221.230.55.27:8081", |
||||
"app/test/*.test.js", |
"--cameraPlayRtmpHost rtmp://221.230.55.27:1935", |
||||
"--no-timeouts" |
"--cameraPlayRtspHost rtsp://221.230.55.27:554" |
||||
], |
] |
||||
"cwd": "${workspaceRoot}", |
}, |
||||
"runtimeExecutable": null, |
{ |
||||
"env": { |
"type": "node", |
||||
"NODE_ENV": "development" |
"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" |
||||
|
} |
||||
|
} |
||||
|
] |
||||
} |
} |
@ -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 |
|
||||
}; |
|
@ -0,0 +1,571 @@ |
|||||
|
'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, |
||||
|
} = 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 |
||||
|
} |
||||
|
|
||||
|
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, |
||||
|
}; |
@ -0,0 +1,565 @@ |
|||||
|
'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 } = 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'], |
||||
|
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 (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'] |
||||
|
}, { |
||||
|
model: models.GbCamera, |
||||
|
attributes: ['id', 'online', 'playUrl'], |
||||
|
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[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 cameraRes = await models.Camera.findAll({ |
||||
|
attributes: ['id', 'name', 'type'], |
||||
|
where: { |
||||
|
delete: false, |
||||
|
recycleTime: null, |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
ctx.status = 200; |
||||
|
ctx.body = cameraRes |
||||
|
} 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.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.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, |
||||
|
detail, |
||||
|
banned, |
||||
|
del, |
||||
|
cameraExport, |
||||
|
getAbility, |
||||
|
getKind, |
||||
|
remark, |
||||
|
}; |
@ -0,0 +1,463 @@ |
|||||
|
'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}/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[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, |
||||
|
}; |
@ -0,0 +1,23 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
async function get (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 = { |
||||
|
get, |
||||
|
}; |
@ -1,36 +1,62 @@ |
|||||
'use strict'; |
'use strict'; |
||||
|
|
||||
|
const fs = require('fs'); |
||||
|
const path = require('path'); |
||||
|
const utils = require('./utils') |
||||
const routes = require('./routes'); |
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 authenticator = require('./middlewares/authenticator'); |
||||
|
const schedule = require('./schedule') |
||||
// const apiLog = require('./middlewares/api-log');
|
// const apiLog = require('./middlewares/api-log');
|
||||
const businessRest = require('./middlewares/business-rest'); |
|
||||
|
|
||||
module.exports.entry = function (app, router, opts) { |
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 = app.fs.api || {}; |
||||
app.fs.api.authAttr = app.fs.api.authAttr || {}; |
app.fs.utils = app.fs.utils || {}; |
||||
app.fs.api.logAttr = app.fs.api.logAttr || {}; |
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)); |
redisConnect(app, opts) |
||||
// router.use(apiLog(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: {} }
|
module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Sequelize, models: {} }
|
||||
require('./models/user')(dc); |
require('./models/nvr')(dc); |
||||
require('./models/user_token')(dc); |
require('./models/camera_ability')(dc); |
||||
require('./models/department')(dc); |
require('./models/camera_kind')(dc); |
||||
require('./models/resource')(dc); |
require('./models/camera')(dc); |
||||
require('./models/user_resource')(dc); |
require('./models/camera_ability_bind')(dc); |
||||
require('./models/places')(dc); |
require('./models/vender')(dc); |
||||
require('./models/user_placeSecurityRecord')(dc); |
require('./models/secret_yingshi')(dc); |
||||
require('./models/report_type')(dc); |
require('./models/gb_camera')(dc); |
||||
require('./models/report_downManage')(dc); |
require('./models/ax_project')(dc); |
||||
require('./models/department')(dc); |
require('./models/camera_remark')(dc); |
||||
require('./models/report_configition')(dc); |
|
||||
require('./models/report_collection')(dc); |
// TODO 模型关系摘出来 初始化之后再定义关系才行
|
||||
require('./models/report_rectify')(dc); |
// fs.readdirSync(path.join(__dirname, '/models')).forEach((filename) => {
|
||||
|
// require(`./models/${filename}`)(dc)
|
||||
|
// });
|
||||
}; |
}; |
||||
|
@ -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; |
|
||||
|
|
@ -0,0 +1,40 @@ |
|||||
|
/* 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: [] |
||||
|
}); |
||||
|
|
||||
|
const Nvr = dc.models.Nvr; |
||||
|
|
||||
|
// Nvr.belongsTo(User, { foreignKey: 'userId', targetKey: 'id' });
|
||||
|
// User.hasMany(Nvr, { foreignKey: 'userId', sourceKey: 'id' });
|
||||
|
|
||||
|
dc.models.AxProject = AxProject; |
||||
|
return AxProject; |
||||
|
}; |
@ -0,0 +1,284 @@ |
|||||
|
/* 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 |
||||
|
}, |
||||
|
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, |
||||
|
}, |
||||
|
}, { |
||||
|
tableName: "camera", |
||||
|
comment: "", |
||||
|
indexes: [] |
||||
|
}); |
||||
|
dc.models.Camera = Camera; |
||||
|
|
||||
|
const CameraKind = dc.models.CameraKind; |
||||
|
Camera.belongsTo(CameraKind, { foreignKey: 'kindId', targetKey: 'id' }); |
||||
|
CameraKind.hasMany(Camera, { foreignKey: 'kindId', sourceKey: 'id' }); |
||||
|
|
||||
|
const Nvr = dc.models.Nvr; |
||||
|
Camera.belongsTo(Nvr, { foreignKey: 'nvrId', targetKey: 'id' }); |
||||
|
Nvr.hasMany(Camera, { foreignKey: 'nvrId', sourceKey: 'id' }); |
||||
|
|
||||
|
return Camera; |
||||
|
}; |
@ -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; |
||||
|
}; |
@ -0,0 +1,56 @@ |
|||||
|
/* 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; |
||||
|
|
||||
|
const Camera = dc.models.Camera; |
||||
|
const CameraAbility = dc.models.CameraAbility; |
||||
|
Camera.belongsToMany(CameraAbility, { through: CameraAbilityBind, foreignKey: 'cameraId', otherKey: 'abilityId' }); |
||||
|
|
||||
|
return CameraAbilityBind; |
||||
|
}; |
@ -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; |
||||
|
}; |
@ -0,0 +1,52 @@ |
|||||
|
/* 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; |
||||
|
|
||||
|
const Camera = dc.models.Camera; |
||||
|
CameraRemark.belongsTo(Camera, { foreignKey: 'cameraId', targetKey: 'id' }); |
||||
|
Camera.hasMany(CameraRemark, { foreignKey: 'cameraId', sourceKey: 'id' }); |
||||
|
|
||||
|
return CameraRemark; |
||||
|
}; |
@ -0,0 +1,169 @@ |
|||||
|
/* 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 |
||||
|
} |
||||
|
}, { |
||||
|
tableName: "gbCamera", |
||||
|
comment: "", |
||||
|
indexes: [] |
||||
|
}); |
||||
|
|
||||
|
const Nvr = dc.models.Nvr; |
||||
|
Nvr.belongsTo(GbCamera, { foreignKey: 'serialNo', targetKey: 'streamid', as: 'gbNvr' }); |
||||
|
GbCamera.hasMany(Nvr, { foreignKey: 'serialNo', sourceKey: 'streamid', as: 'gbNvr' }); |
||||
|
|
||||
|
const Camera = dc.models.Camera; |
||||
|
Camera.belongsTo(GbCamera, { foreignKey: 'gbId', targetKey: 'id' }); |
||||
|
GbCamera.hasMany(Camera, { foreignKey: 'gbId', sourceKey: 'id' }); |
||||
|
|
||||
|
dc.models.GbCamera = GbCamera; |
||||
|
return GbCamera; |
||||
|
}; |
@ -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; |
||||
|
}; |
@ -0,0 +1,67 @@ |
|||||
|
/* 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: [] |
||||
|
}); |
||||
|
|
||||
|
const Camera = dc.models.Camera; |
||||
|
Camera.belongsTo(SecretYingshi, { foreignKey: 'yingshiSecretId', targetKey: 'id' }); |
||||
|
SecretYingshi.hasMany(Camera, { foreignKey: 'yingshiSecretId', sourceKey: 'id' }); |
||||
|
|
||||
|
dc.models.SecretYingshi = SecretYingshi; |
||||
|
|
||||
|
return SecretYingshi; |
||||
|
}; |
@ -1,108 +0,0 @@ |
|||||
/* eslint-disable*/ |
|
||||
'use strict'; |
|
||||
|
|
||||
module.exports = dc => { |
|
||||
const DataTypes = dc.ORM; |
|
||||
const sequelize = dc.orm; |
|
||||
const User = sequelize.define("user", { |
|
||||
id: { |
|
||||
type: DataTypes.INTEGER, |
|
||||
allowNull: false, |
|
||||
defaultValue: null, |
|
||||
comment: null, |
|
||||
primaryKey: true, |
|
||||
field: "id", |
|
||||
autoIncrement: true, |
|
||||
unique: "user_id_uindex" |
|
||||
}, |
|
||||
name: { |
|
||||
type: DataTypes.STRING, |
|
||||
allowNull: false, |
|
||||
defaultValue: null, |
|
||||
comment: null, |
|
||||
primaryKey: false, |
|
||||
field: "name", |
|
||||
autoIncrement: false |
|
||||
}, |
|
||||
username: { |
|
||||
type: DataTypes.STRING, |
|
||||
allowNull: false, |
|
||||
defaultValue: null, |
|
||||
comment: "用户名 账号", |
|
||||
primaryKey: false, |
|
||||
field: "username", |
|
||||
autoIncrement: false |
|
||||
}, |
|
||||
password: { |
|
||||
type: DataTypes.STRING, |
|
||||
allowNull: false, |
|
||||
defaultValue: null, |
|
||||
comment: null, |
|
||||
primaryKey: false, |
|
||||
field: "password", |
|
||||
autoIncrement: false |
|
||||
}, |
|
||||
departmentId: { |
|
||||
type: DataTypes.INTEGER, |
|
||||
allowNull: false, |
|
||||
defaultValue: null, |
|
||||
comment: "部门id", |
|
||||
primaryKey: false, |
|
||||
field: "department_id", |
|
||||
autoIncrement: false |
|
||||
}, |
|
||||
email: { |
|
||||
type: DataTypes.STRING, |
|
||||
allowNull: true, |
|
||||
defaultValue: null, |
|
||||
comment: null, |
|
||||
primaryKey: false, |
|
||||
field: "email", |
|
||||
autoIncrement: false |
|
||||
}, |
|
||||
enable: { |
|
||||
type: DataTypes.BOOLEAN, |
|
||||
allowNull: false, |
|
||||
defaultValue: null, |
|
||||
comment: "启用状态", |
|
||||
primaryKey: false, |
|
||||
field: "enable", |
|
||||
autoIncrement: false |
|
||||
}, |
|
||||
delete: { |
|
||||
type: DataTypes.BOOLEAN, |
|
||||
allowNull: false, |
|
||||
defaultValue: null, |
|
||||
comment: null, |
|
||||
primaryKey: false, |
|
||||
field: "delete", |
|
||||
autoIncrement: false |
|
||||
}, |
|
||||
phone: { |
|
||||
type: DataTypes.STRING, |
|
||||
allowNull: false, |
|
||||
defaultValue: null, |
|
||||
comment: "手机号(小程序使用手机号登录)", |
|
||||
primaryKey: false, |
|
||||
field: "phone", |
|
||||
autoIncrement: false |
|
||||
}, |
|
||||
post: { |
|
||||
type: DataTypes.STRING, |
|
||||
allowNull: true, |
|
||||
defaultValue: null, |
|
||||
comment: "职位", |
|
||||
primaryKey: false, |
|
||||
field: "post", |
|
||||
autoIncrement: false |
|
||||
} |
|
||||
}, { |
|
||||
tableName: "user", |
|
||||
comment: "", |
|
||||
indexes: [] |
|
||||
}); |
|
||||
dc.models.User = User; |
|
||||
|
|
||||
|
|
||||
return User; |
|
||||
}; |
|
@ -0,0 +1,44 @@ |
|||||
|
/* 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: [] |
||||
|
}); |
||||
|
|
||||
|
const Camera = dc.models.Camera; |
||||
|
Camera.belongsTo(Vender, { foreignKey: 'venderId', targetKey: 'id' }); |
||||
|
Vender.hasMany(Camera, { foreignKey: 'venderId', sourceKey: 'id' }); |
||||
|
|
||||
|
const Nvr = dc.models.Nvr; |
||||
|
Nvr.belongsTo(Vender, { foreignKey: 'venderId', targetKey: 'id' }); |
||||
|
Vender.hasMany(Nvr, { foreignKey: 'venderId', sourceKey: 'id' }); |
||||
|
|
||||
|
dc.models.Vender = Vender; |
||||
|
|
||||
|
return Vender; |
||||
|
}; |
@ -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); |
|
||||
}; |
|
@ -0,0 +1,76 @@ |
|||||
|
'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); |
||||
|
}; |
@ -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); |
||||
|
}; |
@ -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.get); |
||||
|
}; |
@ -0,0 +1,151 @@ |
|||||
|
const schedule = require('node-schedule'); |
||||
|
const moment = require('moment') |
||||
|
|
||||
|
module.exports = function (app, opts) { |
||||
|
const freshYingshiState = app.fs.scheduleInit( |
||||
|
{ |
||||
|
// interval: '* * 4 * * *',
|
||||
|
interval: '*/10 * * * *', |
||||
|
immediate: false, |
||||
|
}, |
||||
|
async () => { |
||||
|
|
||||
|
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) { |
||||
|
const existD = await models.GbCamera.findOne({ |
||||
|
where: { |
||||
|
streamid: d.deviceSerial |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
let storageD = { |
||||
|
level: 0, |
||||
|
ipctype: 'yingshi', |
||||
|
streamid: d.deviceSerial, |
||||
|
online: d.status ? 'ON' : 'OFF', |
||||
|
name: d.deviceName, |
||||
|
} |
||||
|
if (existD) { |
||||
|
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 |
||||
|
} |
||||
|
}) |
||||
|
// 状态更新 END
|
||||
|
|
||||
|
// 状态推送
|
||||
|
cameraStatePush({ |
||||
|
gbId: existD.id, |
||||
|
online: storageD.online, |
||||
|
ipctype: storageD.ipctype, |
||||
|
}) |
||||
|
} |
||||
|
} else { |
||||
|
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, |
||||
|
}, |
||||
|
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 |
||||
|
} |
||||
|
} |
@ -0,0 +1,33 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
const fs = require('fs'); |
||||
|
const nodeSchedule = require('node-schedule'); |
||||
|
|
||||
|
// 将定时任务汇集未来可根据需要选取操作
|
||||
|
module.exports = async function (app, opts) { |
||||
|
|
||||
|
const scheduleInit = ({ |
||||
|
interval, immediate |
||||
|
}, callback) => { |
||||
|
const j = nodeSchedule.scheduleJob(interval, callback); |
||||
|
if (immediate && !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, |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}; |
@ -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 |
||||
|
} |
@ -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; |
@ -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, |
||||
|
} |
||||
|
} |
@ -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) |
||||
|
} |
@ -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, |
||||
|
} |
||||
|
} |
@ -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, |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}; |
@ -0,0 +1,154 @@ |
|||||
|
'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) { |
||||
|
const { accessToken, expireTime } = tokenRes.data |
||||
|
await models.SecretYingshi.update({ |
||||
|
token: accessToken, |
||||
|
expire: expireTime |
||||
|
}, { |
||||
|
where: { |
||||
|
key, secret |
||||
|
} |
||||
|
}) |
||||
|
return accessToken |
||||
|
} else { |
||||
|
throw 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, |
||||
|
} |
||||
|
} |
@ -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 |
||||
|
} |
||||
|
} |
@ -1,35 +1,35 @@ |
|||||
module.exports = { |
module.exports = { |
||||
// 数据库配置 与 sequelize 相同
|
// 数据库配置 与 sequelize 相同
|
||||
dbOptions: { |
dbOptions: { |
||||
database: 'yinjiguanli', |
database: 'video_access', |
||||
username: 'postgres', |
username: 'postgres', |
||||
password: '123', |
password: '123', |
||||
dialect: 'postgres', |
dialect: 'postgres', |
||||
host: '10.8.30.32', |
host: '10.8.30.32', |
||||
port: 5432, |
port: 5432, |
||||
define: { |
define: { |
||||
underscored: false, |
underscored: false, |
||||
freezeTableName: false, |
freezeTableName: false, |
||||
charset: 'utf8mb4', |
charset: 'utf8mb4', |
||||
timezone: '+00: 00', |
timezone: '+00: 00', |
||||
dialectOptions: { |
dialectOptions: { |
||||
collate: 'utf8_general_ci', |
collate: 'utf8_general_ci', |
||||
}, |
}, |
||||
timestamps: false, |
timestamps: false, |
||||
}, |
}, |
||||
}, |
}, |
||||
options: { |
options: { |
||||
type: 'freesun', // 指定 models 代码风格
|
type: 'freesun', // 指定 models 代码风格
|
||||
camelCase: true, // Models 文件中代码是否使用驼峰命名
|
camelCase: true, // Models 文件中代码是否使用驼峰命名
|
||||
modalNameSuffix: false, // 模型名称是否带 ‘Model’ 后缀
|
modalNameSuffix: false, // 模型名称是否带 ‘Model’ 后缀
|
||||
fileNameCamelCase: false, // Model 文件名是否使用驼峰法命名,默认文件名会使用表名,如 `user_post.js`;如果为 true,则文件名为 `userPost.js`
|
fileNameCamelCase: false, // Model 文件名是否使用驼峰法命名,默认文件名会使用表名,如 `user_post.js`;如果为 true,则文件名为 `userPost.js`
|
||||
dir: './app/lib/models', // 指定输出 models 文件的目录
|
dir: './app/lib/models', // 指定输出 models 文件的目录
|
||||
typesDir: 'models', // 指定输出 TypeScript 类型定义的文件目录,只有 TypeScript / Midway 等会有类型定义
|
typesDir: 'models', // 指定输出 TypeScript 类型定义的文件目录,只有 TypeScript / Midway 等会有类型定义
|
||||
emptyDir: false, // !!! 谨慎操作 生成 models 之前是否清空 `dir` 以及 `typesDir`
|
emptyDir: false, // !!! 谨慎操作 生成 models 之前是否清空 `dir` 以及 `typesDir`
|
||||
tables: ['user_placeSecurityRecord', 'places'], // 指定生成哪些表的 models,如 ['user', 'user_post'];如果为 null,则忽略改属性
|
tables: ['camera_remark'], // 指定生成哪些表的 models,如 ['user', 'user_post'];如果为 null,则忽略改属性
|
||||
skipTables: ['user'], // 指定跳过哪些表的 models,如 ['user'];如果为 null,则忽略改属性
|
skipTables: [], // 指定跳过哪些表的 models,如 ['user'];如果为 null,则忽略改属性
|
||||
tsNoCheck: false, // 是否添加 `@ts-nocheck` 注释到 models 文件中
|
tsNoCheck: false, // 是否添加 `@ts-nocheck` 注释到 models 文件中
|
||||
ignorePrefix: [], // 生成的模型名称忽略的前缀,因为 项目中有以下表名是以 t_ 开头的,在实际模型中不需要, 可以添加多个 [ 't_data_', 't_',] ,长度较长的 前缀放前面
|
ignorePrefix: [], // 生成的模型名称忽略的前缀,因为 项目中有以下表名是以 t_ 开头的,在实际模型中不需要, 可以添加多个 [ 't_data_', 't_',] ,长度较长的 前缀放前面
|
||||
attrLength: false, // 在生成模型的字段中 是否生成 如 var(128)这种格式,公司一般使用 String ,则配置为 false
|
attrLength: false, // 在生成模型的字段中 是否生成 如 var(128)这种格式,公司一般使用 String ,则配置为 false
|
||||
}, |
}, |
||||
} |
} |
@ -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, ''); |
|
||||
} |
|
||||
}))); |
|
||||
} |
|
||||
}; |
|
@ -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; |
@ -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); |
||||
|
|
@ -0,0 +1,5 @@ |
|||||
|
{ |
||||
|
"recommendations": [ |
||||
|
"formulahendry.code-runner" |
||||
|
] |
||||
|
} |
After Width: | Height: | Size: 350 B |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 87 KiB |
After Width: | Height: | Size: 712 B |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 173 B |
After Width: | Height: | Size: 169 B |
After Width: | Height: | Size: 354 B |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 226 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 481 B |
After Width: | Height: | Size: 791 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 6.0 KiB |
After Width: | Height: | Size: 283 KiB |
After Width: | Height: | Size: 538 B |
After Width: | Height: | Size: 434 B |
After Width: | Height: | Size: 258 B |
After Width: | Height: | Size: 453 B |
After Width: | Height: | Size: 300 B |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 945 B |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 853 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 412 KiB |
After Width: | Height: | Size: 125 B |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 860 B |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 549 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 906 B |
After Width: | Height: | Size: 671 B |
After Width: | Height: | Size: 632 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1012 B |
After Width: | Height: | Size: 722 B |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 377 KiB |