Browse Source

级联添加接口

release_0.0.2
巴林闲侠 2 years ago
parent
commit
b3caa8a43a
  1. 68
      code/VideoAccess-VCMP/api/app/lib/controllers/camera/create.js
  2. 38
      code/VideoAccess-VCMP/api/app/lib/controllers/camera/index.js
  3. 3
      code/VideoAccess-VCMP/api/app/lib/routes/camera/index.js
  4. 196
      code/VideoAccess-VCMP/api/app/lib/schedule/freshYingshiState.js
  5. 6
      code/VideoAccess-VCMP/api/app/lib/service/socket.js
  6. 2
      code/VideoAccess-VCMP/web/client/index.html
  7. 2
      code/VideoAccess-VCMP/web/client/src/components/videoPlayer/videoOperation.jsx
  8. 27
      code/VideoAccess-VCMP/web/client/src/layout/actions/webSocket.js
  9. 27
      code/VideoAccess-VCMP/web/client/src/layout/containers/layout/index.jsx
  10. 2
      code/VideoAccess-VCMP/web/client/src/layout/index.jsx
  11. 89
      code/VideoAccess-VCMP/web/client/src/sections/example/containers/example.jsx
  12. 2
      code/VideoAccess-VCMP/web/package.json

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

@ -391,6 +391,52 @@ async function verifyCascadeCamera (ctx) {
} }
} }
async function getCascadeSteam (ctx) {
let errMsg = '获取级联摄像头视频流失败'
try {
const { models } = ctx.fs.dc
const { sip } = ctx.query
const { utils: { getGbCameraLevel3ByStreamId } } = ctx.app.fs
const cascadeRes = await models.GbCamera.findOne({
where: {
sipip: sip,
}
})
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 }
}
})
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
}
}
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) { async function getCascadeCameraGrandParentSip (ctx) {
let errMsg = '查询级联设备失败' let errMsg = '查询级联设备失败'
try { try {
@ -423,32 +469,38 @@ async function createCascadeCamera (ctx) {
try { try {
const { models } = ctx.fs.dc const { models } = ctx.fs.dc
const { userId, token } = ctx.fs.api const { userId, token } = ctx.fs.api
const { sip, externalDomain, cascadeType } = ctx.request.body const { sip, camera = [], externalDomain, cascadeType } = ctx.request.body
const { utils: { getGbCameraLevel3ByStreamId, verifyCascadeInfo } } = ctx.app.fs const { utils: { getGbCameraLevel3ByStreamId, verifyCascadeInfo } } = ctx.app.fs
const cameraParentRes = await verifyCascadeInfo({ sip }) const cameraParentRes = await verifyCascadeInfo({ sip })
const allCameraRes = await getGbCameraLevel3ByStreamId({ streamId: cameraParentRes.streamid }) const allCameraRes = await getGbCameraLevel3ByStreamId({ streamId: cameraParentRes.streamid })
const allCameraIds = allCameraRes.map(c => c.streamid) const allCameraIds = allCameraRes.map(c => c.id)
const addedCmeraRes = allCameraIds.length ? const addedCmeraRes = allCameraIds.length ?
await models.Camera.findAll({ await models.Camera.findAll({
where: { where: {
type: 'cascade', type: 'cascade',
serialNo: { $in: allCameraIds }, gbId: { $in: allCameraIds },
delete: false delete: false
} }
}) : [] }) : []
let addData = [] let addData = []
let updateData = [] let updateData = []
for (let { dataValues: c } of allCameraRes) { for (let c of camera) {
const corGbCamera = allCameraRes.find(ac => ac.id == c.id)
if (!corGbCamera) {
errMsg = '数据信息错误'
throw errMsg
}
let storageData = { let storageData = {
externalDomain, externalDomain,
cascadeType, cascadeType,
sip: c.sipip, serialNo: corGbCamera.streamid,
sip: corGbCamera.sipip,
name: c.name, name: c.name,
gbId: c.id, gbId: corGbCamera.id,
} }
const added = addedCmeraRes.find(ac => ac.serialNo == c.streamid) const added = addedCmeraRes.find(ac => ac.gbId == corGbCamera.id)
if (added) { if (added) {
let data = { let data = {
...storageData, ...storageData,
@ -463,7 +515,6 @@ async function createCascadeCamera (ctx) {
addData.push({ addData.push({
...storageData, ...storageData,
type: 'cascade', type: 'cascade',
serialNo: c.streamid,
createTime: moment().format(), createTime: moment().format(),
createUserId: userId, createUserId: userId,
forbidden: false forbidden: false
@ -495,6 +546,7 @@ module.exports = {
createIpcCamera, createIpcCamera,
getCascadeSipList, getCascadeSipList,
verifyCascadeCamera, verifyCascadeCamera,
getCascadeSteam,
getCascadeCameraGrandParentSip, getCascadeCameraGrandParentSip,
createCascadeCamera, createCascadeCamera,
}; };

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

@ -5,7 +5,7 @@ const moment = require('moment')
async function getCameraProject (ctx, next) { async function getCameraProject (ctx, next) {
try { try {
const models = ctx.fs.dc.models; const models = ctx.fs.dc.models;
const { limit, page, orderBy, orderDirection, keyword, abilityId, type, venderId, nvrId, externalDomain } = ctx.query const { limit, page, orderBy, orderDirection, keyword, abilityId, type, venderId, nvrId, externalDomain, state } = ctx.query
const { userId, token } = ctx.fs.api const { userId, token } = ctx.fs.api
let findOption = { let findOption = {
@ -27,15 +27,17 @@ async function getCameraProject (ctx, next) {
} : {}, } : {},
required: Boolean(nvrId), required: Boolean(nvrId),
attributes: ['id', 'name', 'serialNo'] attributes: ['id', 'name', 'serialNo']
}, { },],
model: models.GbCamera,
attributes: ['id', 'online']
}],
distinct: true distinct: true
} }
let abilityFind = { let abilityFind = {
model: models.CameraAbility model: models.CameraAbility
} }
let gbCameraOption = {
model: models.GbCamera,
attributes: ['id', 'online'],
required: false
}
if (limit) { if (limit) {
findOption.limit = limit findOption.limit = limit
} }
@ -67,7 +69,33 @@ async function getCameraProject (ctx, next) {
if (externalDomain) { if (externalDomain) {
findOption.where.externalDomain = 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) findOption.include.push(abilityFind)
const cameraRes = await models.Camera.findAll(findOption) const cameraRes = await models.Camera.findAll(findOption)
// const cameraRes = await models.Camera.findAndCountAll(findOption) // const cameraRes = await models.Camera.findAndCountAll(findOption)

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

@ -33,6 +33,9 @@ module.exports = function (app, router, opts) {
app.fs.api.logAttr['POST/camera/verify/cascade'] = { content: '验证级联摄像头信息', visible: false }; app.fs.api.logAttr['POST/camera/verify/cascade'] = { content: '验证级联摄像头信息', visible: false };
router.post('/camera/verify/cascade', cameraCreate.verifyCascadeCamera); 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 }; app.fs.api.logAttr['POST/camera/create/cascade'] = { content: '添加级联摄像头', visible: false };
router.post('/camera/create/cascade', cameraCreate.createCascadeCamera); router.post('/camera/create/cascade', cameraCreate.createCascadeCamera);

196
code/VideoAccess-VCMP/api/app/lib/schedule/freshYingshiState.js

@ -7,107 +7,107 @@ module.exports = function (app, opts) {
'*/1 * * * *', '*/1 * * * *',
async () => { async () => {
try { // try {
const startTime = moment() // const startTime = moment()
const { models } = app.fs.dc // const { models } = app.fs.dc
const { token4yingshi } = app.fs.utils // const { token4yingshi } = app.fs.utils
const secretRes = await models.SecretYingshi.findAll() // const secretRes = await models.SecretYingshi.findAll()
let deviceList = [] // let deviceList = []
for (let s of secretRes) { // for (let s of secretRes) {
const tokenYingshi = await token4yingshi(s.dataValues) // const tokenYingshi = await token4yingshi(s.dataValues)
// 查询所有设备 // // 查询所有设备
let pageStart = 0 // let pageStart = 0
while (pageStart >= 0) { // while (pageStart >= 0) {
const deviceRes = await app.fs.yingshiRequest.post('lapp/device/list', { // const deviceRes = await app.fs.yingshiRequest.post('lapp/device/list', {
query: { // query: {
accessToken: tokenYingshi, // accessToken: tokenYingshi,
pageStart, // pageStart,
pageSize: 50 // pageSize: 50
} // }
}) // })
if (deviceRes.code == 200) { // if (deviceRes.code == 200) {
if (deviceRes.data.length) { // if (deviceRes.data.length) {
deviceList = deviceList.concat.apply(deviceList, deviceRes.data) // deviceList = deviceList.concat.apply(deviceList, deviceRes.data)
for (let d of deviceRes.data) { // for (let d of deviceRes.data) {
const existD = await models.GbCamera.findOne({ // const existD = await models.GbCamera.findOne({
where: { // where: {
streamid: d.deviceSerial // streamid: d.deviceSerial
} // }
}) // })
let storageD = { // let storageD = {
level: 0, // level: 0,
ipctype: 'yingshi', // ipctype: 'yingshi',
streamid: d.deviceSerial, // streamid: d.deviceSerial,
online: d.status ? 'ON' : 'OFF', // online: d.status ? 'ON' : 'OFF',
name: d.deviceName, // name: d.deviceName,
} // }
if (existD) { // if (existD) {
if (existD.online != storageD.online) { // if (existD.online != storageD.online) {
// 状态更新 // // 状态更新
await models.GbCamera.update(storageD, { // await models.GbCamera.update(storageD, {
where: { // where: {
id: existD.id // id: existD.id
} // }
}) // })
// 状态推送 // // 状态推送
const { connected } = app.socket.sockets // // const { connected } = app.socket.sockets
const roomId = 'ROOM_' + Math.random() + '_' + d.deviceSerial // // const roomId = 'ROOM_' + Math.random() + '_' + d.deviceSerial
let cameraName = '' // // let cameraName = ''
if (connected) { // // if (connected) {
for (let c in connected) { // // for (let c in connected) {
const { client: { conn: { request: { _query } } } } = connected[c] // // const { client: { conn: { request: { _query } } } } = connected[c]
if (_query && _query.token) { // // if (_query && _query.token) {
let userInfo = await app.redis.hget(_query.token, 'userInfo'); // // let userInfo = await app.redis.hget(_query.token, 'userInfo');
if (userInfo) { // // if (userInfo) {
userInfo = JSON.parse(userInfo) // // userInfo = JSON.parse(userInfo)
const corCameraRes = await models.Camera.findOne({ // // const corCameraRes = await models.Camera.findOne({
where: { // // where: {
gbId: existD.id, // // gbId: existD.id,
createUserId: userInfo.id // // createUserId: userInfo.id
} // // }
}) // // })
// TODO 管理员判断 // // // TODO 管理员判断
if (corCameraRes) { // // if (corCameraRes) {
cameraName = corCameraRes.name // // cameraName = corCameraRes.name
connected[c].join(roomId) // // connected[c].join(roomId)
} // // }
} // // }
} // // }
} // // }
app.socket.to(roomId).emit('CAMERA_ONLINE', { // // app.socket.to(roomId).emit('CAMERA_ONLINE', {
ipctype: 'yingshi', // // ipctype: 'yingshi',
online: storageD.online, // // online: storageD.online,
gbId: existD.id, // // gbId: existD.id,
name: cameraName // // name: cameraName
}) // // })
} // // }
} // }
} else { // } else {
const yingshiRes = await models.GbCamera.create(storageD) // const yingshiRes = await models.GbCamera.create(storageD)
await models.Camera.update({ // await models.Camera.update({
gbId: yingshiRes.id // gbId: yingshiRes.id
}, { // }, {
where: { // where: {
serialNo: d.deviceSerial // serialNo: d.deviceSerial
} // }
}) // })
} // }
} // }
pageStart++ // pageStart++
} else { // } else {
pageStart = -1 // pageStart = -1
} // }
} // }
} // }
} // }
// console.log(deviceList); // // console.log(deviceList);
console.info(`萤石状态查询用时 ${moment().diff(startTime, 'seconds')} s`) // console.info(`萤石状态查询用时 ${moment().diff(startTime, 'seconds')} s`)
} catch (error) { // } catch (error) {
app.fs.logger.error(`sechedule: freshYingshiState, error: ${error}`); // app.fs.logger.error(`sechedule: freshYingshiState, error: ${error}`);
} // }
}); });
return { return {

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

@ -3,9 +3,9 @@
module.exports = async function factory (app, opts) { module.exports = async function factory (app, opts) {
app.socket.on('connection', async (socket) => { app.socket.on('connection', async (socket) => {
// console.info('WEB_SOCKET ' + socket.handshake.query.token + ' 已连接:' + socket.id); console.info('WEB_SOCKET ' + socket.handshake.query.token + ' 已连接:' + socket.id);
socket.on('disconnecting', async (reason) => { socket.on('disconnecting', async (reason) => {
// console.info('WEB_SOCKET ' + socket.handshake.query.token + ' 已断开连接:' + reason); console.info('WEB_SOCKET ' + socket.handshake.query.token + ' 已断开连接:' + reason);
}) })
}) })
@ -22,5 +22,5 @@ module.exports = async function factory (app, opts) {
} }
app.socket.emit('TEST', { someProperty: '【广播】呼叫青铜时代号!!!', }) app.socket.emit('TEST', { someProperty: '【广播】呼叫青铜时代号!!!', })
}, 1000) }, 500)
} }

2
code/VideoAccess-VCMP/web/client/index.html

@ -18,7 +18,7 @@
import RefreshRuntime from "http://localhost:5002/@react-refresh" import RefreshRuntime from "http://localhost:5002/@react-refresh"
RefreshRuntime.injectIntoGlobalHook(window) RefreshRuntime.injectIntoGlobalHook(window)
window.$RefreshReg$ = () => { } window.$RefreshReg$ = () => { }
window.$RefreshSig$ = () => (type) => type window.$RefreshSig$ = () => (type) => type
window.__vite_plugin_react_preamble_installed__ = true window.__vite_plugin_react_preamble_installed__ = true
const global = window const global = window
</script> </script>

2
code/VideoAccess-VCMP/web/client/src/components/videoPlayer/videoOperation.jsx

@ -16,7 +16,7 @@ const VideoOperation = ({
const [showTimeSelect, setShowTimeSelect] = useState(false) const [showTimeSelect, setShowTimeSelect] = useState(false)
const butStyle = { const butStyle = {
border: '1px solid #fff', display: 'inline-block', color: '#fff', padding: '0 10px', border: '1px solid #fff', color: '#fff', padding: '0 10px',
display: 'flex', alignItems: 'center', height: '64%', marginLeft: 12, cursor: 'pointer', display: 'flex', alignItems: 'center', height: '64%', marginLeft: 12, cursor: 'pointer',
position: 'relative' position: 'relative'
} }

27
code/VideoAccess-VCMP/web/client/src/layout/actions/webSocket.js

@ -20,10 +20,29 @@ export function initWebSocket ({ ioUrl, token }) {
} }
return dispatch => { return dispatch => {
const socket = io(ioUrl, { const socket = io(
query: { ioUrl
token: token // 'http://127.0.0.1:4000'
}, // '_api/'
, {
query: {
token: token
},
});
socket.on("connect", () => {
console.log('connect');
});
socket.io.on("error", (error) => {
console.error(error);
});
socket.io.on("reconnect_error", (error) => {
console.error(error);
});
socket.io.on("reconnect_failed", () => {
console.error(error);
});
socket.on('TEST', function (msg) {
console.info(msg);
}); });
dispatch({ dispatch({
type: INIT_WEB_SOCKET, type: INIT_WEB_SOCKET,

27
code/VideoAccess-VCMP/web/client/src/layout/containers/layout/index.jsx

@ -26,7 +26,7 @@ let scrollbar
const LayoutContainer = props => { const LayoutContainer = props => {
const { const {
dispatch, msg, user, copyright, children, sections, clientWidth, clientHeight, dispatch, msg, user, copyright, children, sections, clientWidth, clientHeight,
location, match, routes, history, authCrossLoading,socket location, match, routes, history, authCrossLoading, socket
} = props } = props
const [collapsed, setCollapsed] = useState(false) const [collapsed, setCollapsed] = useState(false)
@ -80,18 +80,21 @@ const LayoutContainer = props => {
}) })
// websocket 使 // websocket 使
useEffect(() => { useEffect(() => {
console.log(socket) console.log(socket)
if (socket) { if (socket) {
socket.on('CAMERA_ONLINE', function (msg) { socket.on('CAMERA_ONLINE', function (msg) {
console.info(msg);
});
socket.on('TEST', function (msg) {
console.info(msg); console.info(msg);
}); });
return () => { return () => {
socket.off("CAMERA_ONLINE"); socket.off("CAMERA_ONLINE");
} }
} }
}, [socket]) }, [socket])
return ( return (
<Layout id="layout"> <Layout id="layout">
@ -163,7 +166,7 @@ const LayoutContainer = props => {
} }
function mapStateToProps (state) { function mapStateToProps (state) {
const { global, auth, ajaxResponse , webSocket} = state; const { global, auth, ajaxResponse, webSocket } = state;
return { return {
title: global.title, title: global.title,
copyright: global.copyright, copyright: global.copyright,

2
code/VideoAccess-VCMP/web/client/src/layout/index.jsx

@ -130,9 +130,9 @@ const Root = props => {
store.dispatch(initLayout(title, copyright, sections, actions)); store.dispatch(initLayout(title, copyright, sections, actions));
store.dispatch(resize(document.body.clientHeight, document.body.clientWidth)); store.dispatch(resize(document.body.clientHeight, document.body.clientWidth));
store.dispatch(actions.auth.initAuth()); store.dispatch(actions.auth.initAuth());
store.dispatch(initWebSocket({}))
const resourceRoot = await store.dispatch(initApiRoot()) const resourceRoot = await store.dispatch(initApiRoot())
setResourceRoot(resourceRoot.payload) setResourceRoot(resourceRoot.payload)
store.dispatch(initWebSocket({}))
const combineRoutes = flatRoutes(innerRoutes); const combineRoutes = flatRoutes(innerRoutes);
setInnerRoutes(combineRoutes) setInnerRoutes(combineRoutes)

89
code/VideoAccess-VCMP/web/client/src/sections/example/containers/example.jsx

@ -5,56 +5,57 @@ import '../style.less'
const { Meta } = Card; const { Meta } = Card;
const Example = (props) => { const Example = (props) => {
const { dispatch, actions, user, loading, socket } = props const { dispatch, actions, user, loading, socket } = props
console.log(props) console.log(props)
useEffect(() => { useEffect(() => {
// ACTION // ACTION
dispatch(actions.example.getMembers(user.orgId)) dispatch(actions.example.getMembers(user.orgId))
}, []) }, [])
// websocket 使 // websocket 使
useEffect(() => { useEffect(() => {
console.log(socket) console.log(socket)
if (socket) { if (socket) {
socket.on('TEST', function (msg) { socket.on('TEST', function (msg) {
console.info(msg); console.info(msg);
}); });
return () => { return () => {
socket.off("TEST"); socket.off("TEST");
} }
} }
}, [socket])
}, [socket])
return ( return (
<Spin tip="biubiubiu~" spinning={loading}> <Spin tip="biubiubiu~" spinning={loading}>
<div id='example'> <div id='example'>
<p>STYLE EXAMPLE</p> <p>STYLE EXAMPLE</p>
</div> </div>
<Card <Card
style={{ maxWidth: 300 }} style={{ maxWidth: 300 }}
cover={ cover={
<img <img
alt="example" alt="example"
src="https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/card-cover-docs-demo2.jpeg" src="https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/card-cover-docs-demo2.jpeg"
/> />
} }
> >
<Meta title="组件示例" /> <Meta title="组件示例" />
</Card> </Card>
</Spin> </Spin>
) )
} }
function mapStateToProps (state) { function mapStateToProps (state) {
const { auth, global, members, webSocket } = state; const { auth, global, members, webSocket } = state;
return { return {
loading: members.isRequesting, loading: members.isRequesting,
user: auth.user, user: auth.user,
actions: global.actions, actions: global.actions,
members: members.data, members: members.data,
socket: webSocket.socket socket: webSocket.socket
}; };
} }
export default connect(mapStateToProps)(Example); export default connect(mapStateToProps)(Example);

2
code/VideoAccess-VCMP/web/package.json

@ -7,7 +7,7 @@
"test": "mocha", "test": "mocha",
"start-vite": "cross-env NODE_ENV=developmentVite npm run start-params", "start-vite": "cross-env NODE_ENV=developmentVite npm run start-params",
"start": "cross-env NODE_ENV=development npm run start-params", "start": "cross-env NODE_ENV=development npm run start-params",
"start-params": "node server -p 5000 -u http://10.8.30.7:4000 --apiAuthUrl http://10.8.30.7:4200 --apiAnxinyunUrl http://10.8.30.7:4100 --iotAuthWeb http://localhost:5200", "start-params": "node server -p 5000 -u http://localhost:4000 --apiAuthUrl http://10.8.30.7:4200 --apiAnxinyunUrl http://10.8.30.7:4100 --iotAuthWeb http://localhost:5200",
"deploy": "export NODE_ENV=production&& npm run build && node server", "deploy": "export NODE_ENV=production&& npm run build && node server",
"build-dev": "cross-env NODE_ENV=development&&webpack --config webpack.config.js", "build-dev": "cross-env NODE_ENV=development&&webpack --config webpack.config.js",
"build": "export NODE_ENV=production&&webpack --config webpack.config.prod.js" "build": "export NODE_ENV=production&&webpack --config webpack.config.prod.js"

Loading…
Cancel
Save