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) {
let errMsg = '查询级联设备失败'
try {
@ -423,32 +469,38 @@ async function createCascadeCamera (ctx) {
try {
const { models } = ctx.fs.dc
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 cameraParentRes = await verifyCascadeInfo({ sip })
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 ?
await models.Camera.findAll({
where: {
type: 'cascade',
serialNo: { $in: allCameraIds },
gbId: { $in: allCameraIds },
delete: false
}
}) : []
let addData = []
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 = {
externalDomain,
cascadeType,
sip: c.sipip,
serialNo: corGbCamera.streamid,
sip: corGbCamera.sipip,
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) {
let data = {
...storageData,
@ -463,7 +515,6 @@ async function createCascadeCamera (ctx) {
addData.push({
...storageData,
type: 'cascade',
serialNo: c.streamid,
createTime: moment().format(),
createUserId: userId,
forbidden: false
@ -495,6 +546,7 @@ module.exports = {
createIpcCamera,
getCascadeSipList,
verifyCascadeCamera,
getCascadeSteam,
getCascadeCameraGrandParentSip,
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) {
try {
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
let findOption = {
@ -27,15 +27,17 @@ async function getCameraProject (ctx, next) {
} : {},
required: Boolean(nvrId),
attributes: ['id', 'name', 'serialNo']
}, {
model: models.GbCamera,
attributes: ['id', 'online']
}],
},],
distinct: true
}
let abilityFind = {
model: models.CameraAbility
}
let gbCameraOption = {
model: models.GbCamera,
attributes: ['id', 'online'],
required: false
}
if (limit) {
findOption.limit = limit
}
@ -67,7 +69,33 @@ async function getCameraProject (ctx, next) {
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)

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 };
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);

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

@ -7,107 +7,107 @@ module.exports = function (app, opts) {
'*/1 * * * *',
async () => {
try {
const startTime = moment()
const { models } = app.fs.dc
const { token4yingshi } = 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) {
if (deviceRes.data.length) {
deviceList = deviceList.concat.apply(deviceList, deviceRes.data)
for (let d of deviceRes.data) {
const existD = await models.GbCamera.findOne({
where: {
streamid: d.deviceSerial
}
})
// try {
// const startTime = moment()
// const { models } = app.fs.dc
// const { token4yingshi } = 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) {
// if (deviceRes.data.length) {
// 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) {
// 状态更新
await models.GbCamera.update(storageD, {
where: {
id: existD.id
}
})
// let storageD = {
// level: 0,
// ipctype: 'yingshi',
// streamid: d.deviceSerial,
// online: d.status ? 'ON' : 'OFF',
// name: d.deviceName,
// }
// if (existD) {
// if (existD.online != storageD.online) {
// // 状态更新
// await models.GbCamera.update(storageD, {
// where: {
// id: existD.id
// }
// })
// 状态推送
const { connected } = app.socket.sockets
const roomId = 'ROOM_' + Math.random() + '_' + d.deviceSerial
let cameraName = ''
if (connected) {
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: existD.id,
createUserId: userInfo.id
}
})
// TODO 管理员判断
if (corCameraRes) {
cameraName = corCameraRes.name
connected[c].join(roomId)
}
}
}
}
// // 状态推送
// // const { connected } = app.socket.sockets
// // const roomId = 'ROOM_' + Math.random() + '_' + d.deviceSerial
// // let cameraName = ''
// // if (connected) {
// // 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: existD.id,
// // createUserId: userInfo.id
// // }
// // })
// // // TODO 管理员判断
// // if (corCameraRes) {
// // cameraName = corCameraRes.name
// // connected[c].join(roomId)
// // }
// // }
// // }
// // }
app.socket.to(roomId).emit('CAMERA_ONLINE', {
ipctype: 'yingshi',
online: storageD.online,
gbId: existD.id,
name: cameraName
})
}
}
} else {
const yingshiRes = await models.GbCamera.create(storageD)
await models.Camera.update({
gbId: yingshiRes.id
}, {
where: {
serialNo: d.deviceSerial
}
})
}
}
pageStart++
} else {
pageStart = -1
}
}
}
}
// console.log(deviceList);
console.info(`萤石状态查询用时 ${moment().diff(startTime, 'seconds')} s`)
} catch (error) {
app.fs.logger.error(`sechedule: freshYingshiState, error: ${error}`);
}
// // app.socket.to(roomId).emit('CAMERA_ONLINE', {
// // ipctype: 'yingshi',
// // online: storageD.online,
// // gbId: existD.id,
// // name: cameraName
// // })
// // }
// }
// } else {
// const yingshiRes = await models.GbCamera.create(storageD)
// await models.Camera.update({
// gbId: yingshiRes.id
// }, {
// where: {
// serialNo: d.deviceSerial
// }
// })
// }
// }
// pageStart++
// } else {
// pageStart = -1
// }
// }
// }
// }
// // console.log(deviceList);
// console.info(`萤石状态查询用时 ${moment().diff(startTime, 'seconds')} s`)
// } catch (error) {
// app.fs.logger.error(`sechedule: freshYingshiState, error: ${error}`);
// }
});
return {

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

@ -3,9 +3,9 @@
module.exports = async function factory (app, opts) {
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) => {
// 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: '【广播】呼叫青铜时代号!!!', })
}, 1000)
}, 500)
}

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

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

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

@ -16,7 +16,7 @@ const VideoOperation = ({
const [showTimeSelect, setShowTimeSelect] = useState(false)
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',
position: 'relative'
}

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

@ -20,10 +20,29 @@ export function initWebSocket ({ ioUrl, token }) {
}
return dispatch => {
const socket = io(ioUrl, {
query: {
token: token
},
const socket = io(
ioUrl
// '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({
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 {
dispatch, msg, user, copyright, children, sections, clientWidth, clientHeight,
location, match, routes, history, authCrossLoading,socket
location, match, routes, history, authCrossLoading, socket
} = props
const [collapsed, setCollapsed] = useState(false)
@ -80,18 +80,21 @@ const LayoutContainer = props => {
})
// websocket 使
useEffect(() => {
console.log(socket)
if (socket) {
socket.on('CAMERA_ONLINE', function (msg) {
// websocket 使
useEffect(() => {
console.log(socket)
if (socket) {
socket.on('CAMERA_ONLINE', function (msg) {
console.info(msg);
});
socket.on('TEST', function (msg) {
console.info(msg);
});
return () => {
});
return () => {
socket.off("CAMERA_ONLINE");
}
}
}, [socket])
}
}
}, [socket])
return (
<Layout id="layout">
@ -163,7 +166,7 @@ const LayoutContainer = props => {
}
function mapStateToProps (state) {
const { global, auth, ajaxResponse , webSocket} = state;
const { global, auth, ajaxResponse, webSocket } = state;
return {
title: global.title,
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(resize(document.body.clientHeight, document.body.clientWidth));
store.dispatch(actions.auth.initAuth());
store.dispatch(initWebSocket({}))
const resourceRoot = await store.dispatch(initApiRoot())
setResourceRoot(resourceRoot.payload)
store.dispatch(initWebSocket({}))
const combineRoutes = flatRoutes(innerRoutes);
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 Example = (props) => {
const { dispatch, actions, user, loading, socket } = props
console.log(props)
const { dispatch, actions, user, loading, socket } = props
console.log(props)
useEffect(() => {
// ACTION
dispatch(actions.example.getMembers(user.orgId))
}, [])
useEffect(() => {
// ACTION
dispatch(actions.example.getMembers(user.orgId))
}, [])
// websocket 使
useEffect(() => {
console.log(socket)
if (socket) {
socket.on('TEST', function (msg) {
console.info(msg);
});
return () => {
socket.off("TEST");
}
}
}, [socket])
// websocket 使
useEffect(() => {
console.log(socket)
if (socket) {
socket.on('TEST', function (msg) {
console.info(msg);
});
return () => {
socket.off("TEST");
}
}
}, [socket])
return (
<Spin tip="biubiubiu~" spinning={loading}>
<div id='example'>
<p>STYLE EXAMPLE</p>
</div>
<Card
style={{ maxWidth: 300 }}
cover={
<img
alt="example"
src="https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/card-cover-docs-demo2.jpeg"
/>
}
>
<Meta title="组件示例" />
</Card>
</Spin>
)
return (
<Spin tip="biubiubiu~" spinning={loading}>
<div id='example'>
<p>STYLE EXAMPLE</p>
</div>
<Card
style={{ maxWidth: 300 }}
cover={
<img
alt="example"
src="https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/card-cover-docs-demo2.jpeg"
/>
}
>
<Meta title="组件示例" />
</Card>
</Spin>
)
}
function mapStateToProps (state) {
const { auth, global, members, webSocket } = state;
return {
loading: members.isRequesting,
user: auth.user,
actions: global.actions,
members: members.data,
socket: webSocket.socket
};
const { auth, global, members, webSocket } = state;
return {
loading: members.isRequesting,
user: auth.user,
actions: global.actions,
members: members.data,
socket: webSocket.socket
};
}
export default connect(mapStateToProps)(Example);

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

@ -7,7 +7,7 @@
"test": "mocha",
"start-vite": "cross-env NODE_ENV=developmentVite 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",
"build-dev": "cross-env NODE_ENV=development&&webpack --config webpack.config.js",
"build": "export NODE_ENV=production&&webpack --config webpack.config.prod.js"

Loading…
Cancel
Save