'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, };