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