Browse Source

摄像头验证接口

release_0.0.2
yuan_yi 2 years ago
parent
commit
c8e54329a7
  1. 201
      code/VideoAccess-VCMP/api/app/lib/controllers/camera/create.js
  2. 22
      code/VideoAccess-VCMP/api/app/lib/controllers/camera/index.js
  3. 64
      code/VideoAccess-VCMP/api/app/lib/controllers/nvr/index.js
  4. 2
      code/VideoAccess-VCMP/api/app/lib/index.js
  5. 4
      code/VideoAccess-VCMP/api/app/lib/models/camera.js
  6. 15
      code/VideoAccess-VCMP/api/app/lib/routes/camera/index.js
  7. 3
      code/VideoAccess-VCMP/api/app/lib/routes/nvr/index.js
  8. 77
      code/VideoAccess-VCMP/api/app/lib/utils/camera.js
  9. 33
      code/VideoAccess-VCMP/api/app/lib/utils/gbCamera.js
  10. 28
      code/VideoAccess-VCMP/api/app/lib/utils/token4yingshi.js

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

@ -2,48 +2,46 @@
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 = '添加萤石摄像头失败'
let errMsg = '萤石摄像头失败'
const transaction = await ctx.fs.dc.orm.transaction();
try {
const { models } = ctx.fs.dc
const { userId, token } = ctx.fs.api
const { utils: { token4yingshi } } = ctx.app.fs
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 serialNo_ = String(serialNo).toUpperCase()
const secretRes = await models.SecretYingshi.findAll()
let cameraBeloneSecretId = null
for (let s of secretRes) {
const tokenYingshi = await token4yingshi(s.dataValues)
// 检测设备所属
const cameraState = await ctx.app.fs.yingshiRequest.post('lapp/device/info', {
query: {
accessToken: tokenYingshi,
deviceSerial: serialNo_
}
})
if (cameraState.code == 200) {
cameraBeloneSecretId = s.dataValues.id
break
}
}
if (!cameraBeloneSecretId) {
errMsg = '请联系管理员核验或新增萤石云权限'
throw errMsg
}
const beloneSecret = await verifyYingshiInfo({ serialNo })
let storageData = {
type: 'yingshi', name, cloudControl, highDefinition, memoryCard,
voice, longitude, latitude, kindId, rtmp,
serialNo: serialNo_,
yingshiSecretId: cameraBeloneSecretId
serialNo: String(serialNo).toUpperCase(),
yingshiSecretId: beloneSecret.id
}
if (handleCameraId) {
@ -90,7 +88,7 @@ async function createYingshi (ctx) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: errMsg
message: typeof error == 'string' ? error : errMsg
}
}
}
@ -99,9 +97,19 @@ async function getNvrSteam (ctx) {
let errMsg = '获取 NVR 视频流失败'
try {
const { streamId } = ctx.query
const { utils: { getCameraLevel3ByStreamId } } = ctx.app.fs
const { utils: { getGbCameraLevel3ByStreamId } } = ctx.app.fs
const cameraRes = await getCameraLevel3ByStreamId({ streamId, errMsg })
const nvrRes = await models.Nvr.findOne({
where: {
serialNo: streamId,
}
})
if (!nvrRes) {
errMsg = '没有找到已配置的 NVR 信息'
throw errMsg
}
const cameraRes = await getGbCameraLevel3ByStreamId({ streamId })
ctx.status = 200;
ctx.body = cameraRes
@ -109,18 +117,42 @@ async function getNvrSteam (ctx) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: errMsg
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 = '添加 NVR 摄像头失败'
let errMsg = ''
const transaction = await ctx.fs.dc.orm.transaction();
try {
const { models } = ctx.fs.dc
const { userId, token } = ctx.fs.api
const { utils: { getCameraLevel3ByStreamId } } = ctx.app.fs
const { utils: { getGbCameraLevel3ByStreamId } } = ctx.app.fs
const data = ctx.request.body
const { data: camera, serialNo } = data
if (!serialNo || !camera) {
@ -143,7 +175,7 @@ async function createNvrCamera (ctx) {
nvrId: nvrRes.id
}
})
const allCameraRes = await getCameraLevel3ByStreamId({ streamId: serialNo })
const allCameraRes = await getGbCameraLevel3ByStreamId({ streamId: serialNo })
let createData = []
let updateData = []
@ -196,16 +228,33 @@ async function createNvrCamera (ctx) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: errMsg
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,
@ -213,6 +262,7 @@ async function createIpcCamera (ctx) {
serialNo, kindId, abilityId,
} = ctx.request.body;
let handleCameraId = id
errMsg = (handleCameraId ? '修改' : '添加') + errMsg
let storageData = {
type: 'ipc', name, cloudControl, memoryCard,
@ -220,6 +270,10 @@ async function createIpcCamera (ctx) {
serialNo, kindId,
}
const gbCameraRes = await verifyIpcInfo({ serialNo })
storageData.sip = gbCameraRes.dataValues.sipip
if (handleCameraId) {
await models.Camera.update(storageData, {
where: {
@ -237,6 +291,7 @@ async function createIpcCamera (ctx) {
handleCameraId = createRes.id
}
// 保存设备能力
await models.CameraAbilityBind.destroy({
where: {
cameraId: handleCameraId
@ -263,13 +318,89 @@ async function createIpcCamera (ctx) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
ctx.body = {
message: typeof error == 'string' ? error : errMsg
}
}
}
async function verifyCascadeCamera (ctx) {
let errMsg = '校验级联摄像头信息失败'
try {
const { utils: { verifyCascadeInfo } } = ctx.app.fs
const { sip } = ctx.request.body
await verifyCascadeInfo({ sip })
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 createCascadeCamera (ctx) {
let errMsg = '添加级联摄像头信息失败'
try {
const { userId, token } = ctx.fs.api
const { sip, externalDomain, cascadeType } = ctx.request.body
const { utils: { getGbCameraLevel3ByStreamId, verifyCascadeInfo } } = ctx.app.fs
const cameraParentRes = await verifyCascadeInfo({ sip })
const allCameraRes = await getGbCameraLevel3ByStreamId({ streamId: cameraParentRes.streamid })
const allCameraIds = allCameraRes.map(c => c.streamid)
const addedCmeraRes = allCameraIds.length ?
await models.Camera.findAll({
where: {
type: 'cascade',
serialNo: { $in: allCameraIds }
}
}) : []
let addData = []
let updateData = []
for (let { dataValues: c } of allCameraRes) {
let storageData = {
externalDomain,
cascadeType,
sip: c.sipip,
name: c.name
}
const added = addedCmeraRes.some(ac => ac.streamid == c.streamid)
if (added) {
updateData.push({
...storageData,
id: added.id,
})
} else {
addData.push({
...storageData,
serialNo: c.streamid,
createTime: moment().format(),
createUserId: userId,
forbidden: false
})
}
}
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
}
}
}
module.exports = {
verifyYingshi,
createYingshi,
getNvrSteam,
getNvrSteamById,
createNvrCamera,
verifyIpcCamera,
createIpcCamera,
verifyCascadeCamera,
createCascadeCamera,
};

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

@ -5,7 +5,7 @@ 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 } = ctx.query
const { limit, page, orderBy, orderDirection, keyword, abilityId, type, venderId, nvrId } = ctx.query
const { userId, token } = ctx.fs.api
let findOption = {
@ -20,6 +20,10 @@ async function getCameraProject (ctx, next) {
],
include: [{
model: models.CameraKind
}, {
model: models.Nvr,
required: Boolean(nvrId),
attributes: ['id', 'name', 'serialNo']
}]
}
let abilityFind = {
@ -68,7 +72,12 @@ async function getCameraProject (ctx, next) {
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 } })
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.find(b => b.cameraId == camera.id)
@ -78,12 +87,9 @@ async function getCameraProject (ctx, next) {
camera.station = []
}
const corUser = corUsers.find(u => u.id == camera.createUserId)
if (corUser) {
camera.createUser = {
namePresent: corUser.namePresent
}
} else {
camera.createUser = {}
camera.createUser = {
namePresent: corUser ? corUser.namePresent : ''
}
}

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

@ -6,7 +6,7 @@ async function edit (ctx, next) {
let errMsg = '添加 NVR 设备失败'
const transaction = await ctx.fs.dc.orm.transaction();
try {
const { utils: { getCameraLevel3ByStreamId } } = ctx.app.fs
const { utils: { getGbCameraLevel3ByStreamId } } = ctx.app.fs
const { models } = ctx.fs.dc;
const { userId } = ctx.fs.api
const data = ctx.request.body;
@ -15,7 +15,8 @@ async function edit (ctx, next) {
const nvrGbRes = await models.GbCamera.findOne({
where: {
streamid: serialNo,
level: 0
level: 0,
ipctype: 'nvr'
}
})
@ -24,7 +25,7 @@ async function edit (ctx, next) {
throw errMsg
}
const channelRes = await getCameraLevel3ByStreamId(serialNo)
const channelRes = await getGbCameraLevel3ByStreamId({ streamId: serialNo, errMsg })
// 或取其他服务信息
const nvrData = {
@ -58,7 +59,40 @@ async function edit (ctx, next) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {}
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
}
}
}
@ -66,7 +100,7 @@ async function get (ctx) {
try {
const models = ctx.fs.dc.models;
const { userId, token } = ctx.fs.api
const { limit, page, orderBy, orderDirection, keyword, venderId } = ctx.query
const { limit, page, orderBy, orderDirection, keyword, venderId, state } = ctx.query
let findOption = {
attributes: { exclude: ['delete'] },
where: {
@ -76,13 +110,15 @@ async function get (ctx) {
order: [
[orderBy || 'id', orderDirection || 'DESC']
],
include: [{
model: models.GbCamera,
as: 'gbNvr',
// attributes: ['id', 'address', 'name', 'online'],
required: false
}]
include: []
}
let gbNvrOption = {
model: models.GbCamera,
as: 'gbNvr',
// attributes: ['id', 'address', 'name', 'online'],
required: false
}
if (limit) {
findOption.limit = limit
}
@ -95,6 +131,11 @@ async function get (ctx) {
if (venderId) {
findOption.where.venderId = venderId
}
if (state) {
}
findOption.include.push(gbNvrOption)
const nvrRes = await models.Nvr.findAll(findOption)
const total = await models.Nvr.count({
@ -398,6 +439,7 @@ async function nvrExport (ctx) {
module.exports = {
edit,
verify,
get,
del,
detail,

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

@ -36,11 +36,11 @@ module.exports.entry = function (app, router, opts) {
};
module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Sequelize, models: {} }
require('./models/nvr')(dc);
require('./models/camera_ability')(dc);
require('./models/camera_kind')(dc);
require('./models/camera')(dc);
require('./models/camera_ability_bind')(dc);
require('./models/nvr')(dc);
require('./models/vender')(dc);
require('./models/secret_yingshi')(dc);
require('./models/gb_camera')(dc);

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

@ -258,5 +258,9 @@ module.exports = dc => {
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;
};

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

@ -6,18 +6,33 @@ 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['POST/camera/verify/cascade'] = { content: '验证级联摄像头信息', visible: false };
router.post('/camera/verify/cascade', cameraCreate.verifyCascadeCamera);
app.fs.api.logAttr['POST/camera/create/cascade'] = { content: '添加级联摄像头', visible: false };
router.post('/camera/create/cascade', cameraCreate.createCascadeCamera);
// 摄像头创建 END
app.fs.api.logAttr['GET/camera/project'] = { content: '获取摄像头列表及项目绑定信息', visible: false };

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

@ -6,6 +6,9 @@ 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);

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

@ -0,0 +1,77 @@
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 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 ({ sip } = {}) {
const { models } = app.fs.dc
const gbCameraRes = await models.GbCamera.findOne({
where: {
sipip: sip,
level: 0,
ipctype: '级联'
}
})
if (!gbCameraRes) {
let errMsg = '没有找到已接入的级联摄像头服务信息'
throw errMsg
}
return gbCameraRes.dataValues
}
return {
getGbCameraLevel3ByStreamId,
verifyYingshiInfo,
verifyIpcInfo,
verifyCascadeInfo,
}
}

33
code/VideoAccess-VCMP/api/app/lib/utils/gbCamera.js

@ -1,33 +0,0 @@
module.exports = function (app, opts) {
async function getCameraLevel3ByStreamId ({ streamId, errMsg = '' }) {
const { models } = app.fs.dc
if (!streamId) {
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
}
return {
getCameraLevel3ByStreamId
}
}

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

@ -43,7 +43,33 @@ module.exports = function (app, opts) {
}
}
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
}
return {
token4yingshi
token4yingshi,
varifyYingshiBelongSecretBySerialNo,
}
}
Loading…
Cancel
Save