Browse Source

Merge branch 'dev_trial' of https://gitea.anxinyun.cn/free-sun/FS-IOT into dev_trial

release_1.3.0
巴林闲侠 2 years ago
parent
commit
8ab00cfd25
  1. 4
      code/VideoAccess-VCMP/api/app/lib/controllers/camera/index.js
  2. 9
      code/VideoAccess-VCMP/api/app/lib/models/gb_camera.js
  3. BIN
      code/VideoAccess-VCMP/web/client/assets/images/application/back.png
  4. BIN
      code/VideoAccess-VCMP/web/client/assets/images/application/background.png
  5. BIN
      code/VideoAccess-VCMP/web/client/assets/images/application/gongge.png
  6. BIN
      code/VideoAccess-VCMP/web/client/assets/images/application/monitor.png
  7. BIN
      code/VideoAccess-VCMP/web/client/assets/images/application/polling.png
  8. BIN
      code/VideoAccess-VCMP/web/client/assets/images/application/screen1.png
  9. BIN
      code/VideoAccess-VCMP/web/client/assets/images/application/screen12.png
  10. BIN
      code/VideoAccess-VCMP/web/client/assets/images/application/screen4.png
  11. BIN
      code/VideoAccess-VCMP/web/client/assets/images/application/screen6.png
  12. BIN
      code/VideoAccess-VCMP/web/client/assets/images/application/titleBottom.png
  13. 3
      code/VideoAccess-VCMP/web/client/src/components/textScroll.jsx
  14. 3
      code/VideoAccess-VCMP/web/client/src/components/videoPlayer/videoPlay.jsx
  15. 2
      code/VideoAccess-VCMP/web/client/src/components/videoPlayer/voiceHeader.jsx
  16. 2
      code/VideoAccess-VCMP/web/client/src/sections/application/containers/applicationCenter.jsx
  17. 52
      code/VideoAccess-VCMP/web/client/src/sections/journaling/components/container.jsx
  18. 52
      code/VideoAccess-VCMP/web/client/src/sections/journaling/components/videoCard.jsx
  19. 414
      code/VideoAccess-VCMP/web/client/src/sections/journaling/components/videoScreen.jsx
  20. 18
      code/VideoAccess-VCMP/web/client/src/sections/journaling/components/videoScreen.less
  21. 1
      code/VideoAccess-VCMP/web/client/src/sections/monitor/containers/videoPlayCross.jsx
  22. 10
      code/VideoAccess-VCMP/web/client/src/utils/webapi.js
  23. 2
      code/VideoAccess-VCMP/web/package.json

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

@ -43,7 +43,7 @@ async function getCameraProject (ctx, next) {
}
let gbCameraOption = {
model: models.GbCamera,
attributes: ['id', 'online', 'playUrl'],
attributes: ['id', 'online', 'playUrl','did'],
required: false
}
if (limit) {
@ -183,7 +183,7 @@ async function getCamera (ctx) {
attributes: ['token']
}, {
model: models.GbCamera,
attributes: ['id', 'online', 'playUrl'],
attributes: ['id', 'online', 'playUrl',],
required: false
}, {
model: models.CameraRemark,

9
code/VideoAccess-VCMP/api/app/lib/models/gb_camera.js

@ -149,6 +149,15 @@ module.exports = dc => {
primaryKey: false,
field: "playUrl",
autoIncrement: false
},
did: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "did",
autoIncrement: false
}
}, {
tableName: "gbCamera",

BIN
code/VideoAccess-VCMP/web/client/assets/images/application/back.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
code/VideoAccess-VCMP/web/client/assets/images/application/background.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

BIN
code/VideoAccess-VCMP/web/client/assets/images/application/gongge.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
code/VideoAccess-VCMP/web/client/assets/images/application/monitor.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
code/VideoAccess-VCMP/web/client/assets/images/application/polling.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
code/VideoAccess-VCMP/web/client/assets/images/application/screen1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

BIN
code/VideoAccess-VCMP/web/client/assets/images/application/screen12.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 B

BIN
code/VideoAccess-VCMP/web/client/assets/images/application/screen4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

BIN
code/VideoAccess-VCMP/web/client/assets/images/application/screen6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

BIN
code/VideoAccess-VCMP/web/client/assets/images/application/titleBottom.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

3
code/VideoAccess-VCMP/web/client/src/components/textScroll.jsx

@ -4,7 +4,6 @@ import './textScroll.less'
function TextScroll (props) {
const { content, duration, roll } = props
console.log(content, roll);
const [showContent, setShowContent] = useState('')
const showIndex = useRef(0)
const initialization = useRef(false)
@ -13,7 +12,6 @@ function TextScroll (props) {
if (content.length) {
if (roll) {
let contentParent = document.getElementById('marquee_box')
console.log(document.getElementById('contentPMakeUp'));
document.getElementById('contentPMakeUp').style.width = contentParent.clientWidth + 'px'
const contentP = document.getElementById('contentP')
contentP.style.visibility = 'visible'
@ -28,7 +26,6 @@ function TextScroll (props) {
let refreshTime = moment()
const scroll = () => {
let contentParent = document.getElementById('marquee_box')
console.log(document.getElementById('contentPMakeUp'));
document.getElementById('contentPMakeUp').style.width = contentParent.clientWidth + 'px'
//
// if(!showContent&&!initialization.current){

3
code/VideoAccess-VCMP/web/client/src/components/videoPlayer/videoPlay.jsx

@ -65,6 +65,7 @@ const VideoPlay = ({
iotVideoServer,
local, //
}) => {
console.log(videoObj);
if (videoObj.type == 'yingshi') {
videoObj = {
...videoObj,
@ -386,7 +387,6 @@ const VideoPlay = ({
const setupSize = (data) => {
if (!operationRef.current?.fullScreen.select) {
console.log(sizeWh);
let containerWidth = sizeWh?.parentWidth //
let containerHeight = sizeWh?.parentHeight
let videoWidth = width || sizeWh?.width
@ -500,7 +500,6 @@ const VideoPlay = ({
function mapStateToProps (state) {
const { auth, global } = state;
console.log(global);
return {
user: auth.user,
iotVideoServer: global.iotVideoServer,

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

@ -14,8 +14,6 @@ const VideoHeader = ({ operationState, changeSelectState, setProcessDisX, name,
const upTimeInterval = useRef(null)
const [showTime_, setShowTime] = useState(' ')
console.log(11212111313131);
const updateTime = () => {
if (!showTime) {
setShowTime('')

2
code/VideoAccess-VCMP/web/client/src/sections/application/containers/applicationCenter.jsx

@ -196,7 +196,7 @@ const ApplicationCenter = (props) => {
const details = (data) => {
pageLimit.current = query
dispatch(applicationCenter.getApplication(pageLimit.current)).then((res) => {
limits.current = res.payload.data.data.length
limits.current = res.payload?.data?.data.length
});
}
useEffect(() => {

52
code/VideoAccess-VCMP/web/client/src/sections/journaling/components/container.jsx

@ -0,0 +1,52 @@
import React, { useEffect, useRef } from 'react';
import { connect } from 'react-redux';
import { TreeSelect, Tree, Form, Button, Popover, Tag, Switch, Input, Row, Col } from '@douyinfe/semi-ui';
import { VideoPlay } from "$components";
import { useState } from 'react';
const Container = ({ videoObj, pageSize }) => {
const [videoWidth, setVideoWidth] = useState()
const [videoHeight, setVideoHeight] = useState()
useEffect(() => {
const resize_ = () => {
setVideoWidth(document.getElementById('videoo').clientWidth)
setVideoHeight(document.getElementById('videoo').clientHeight)
}
resize_()
window.addEventListener('resize', resize_); //
return () => {
window.removeEventListener('resize', resize_);
}
}, [])
useEffect(() => {
setVideoWidth(document.getElementById('videoo').clientWidth)
setVideoHeight(document.getElementById('videoo').clientHeight)
}, [pageSize])
console.log(videoWidth, videoHeight);
return (
<div style={{ width: videoWidth || '100%', height: videoHeight || '100%', padding: 5 }}>
<VideoPlay sizeWh={{
width: videoWidth - 10,
height: videoHeight - 10,
parentWidth: videoWidth - 10,
parentHeight: videoHeight - 10,
}}
videoObj={videoObj}
videoStyle='true'
containerId={videoObj.name}
local={true} />
</div>
)
}
function mapStateToProps (state) {
const { auth } = state;
return {
user: auth.user,
};
}
export default connect(mapStateToProps)(Container)

52
code/VideoAccess-VCMP/web/client/src/sections/journaling/components/videoCard.jsx

@ -0,0 +1,52 @@
import React, { useEffect, useRef,useState } from 'react';
import { connect } from 'react-redux';
import { TreeSelect, Tree, Form, Button, Popover, Tag, Switch, Input, Row, Col } from '@douyinfe/semi-ui';
import Container from "./container";
const VideoCard = ({ data, pageSize }) => {
let span = 8
let rowsCount = 2
if (pageSize === 1) {
span = 24
rowsCount = 1
}
if (pageSize === 4) {
span = 12
rowsCount = 2
}
if (pageSize == 6) {
span = 8
rowsCount = 2
}
if (pageSize == 12) {
span = 6
rowsCount = 3
}
let cheight = Math.floor(100 / rowsCount) + "%"
console.log(pageSize,span,cheight);
return (
<>
<Col id="videoo" span={span} style={{ height: cheight, }}>
<Container
videoObj={data}
pageSize={pageSize}
/>
</Col>
</>
)
}
function mapStateToProps (state) {
const { auth } = state;
return {
user: auth.user,
};
}
export default connect(mapStateToProps)(VideoCard)

414
code/VideoAccess-VCMP/web/client/src/sections/journaling/components/videoScreen.jsx

@ -1,91 +1,359 @@
import React, { useEffect } from 'react';
import React, { useEffect, useRef, useState } from 'react';
import { connect } from 'react-redux';
import { TreeSelect, Tree } from '@douyinfe/semi-ui';
import { TreeSelect, Tree, Form, Button, Popover, Tag, Switch, Input, Row } from '@douyinfe/semi-ui';
import './videoScreen.less'
import VideoCard from './videoCard'
const VideoScreen = (props) => {
const [pageSize, setPageSize] = useState(4) //
const [queryData, setQueryData] = useState([{ label: '全部', value: '全部', key: '0' }]) //
const [leftTree, setLefTtree] = useState([{ label: '全部', value: '全部', key: '0' }]) //
const [playData, setPlayData] = useState([]) //
const [queryValue, setQueryValue] = useState(['全部']) //
const [leftValue, setLeftValue] = useState() //
const treeData = [{
label: '全部',
value: '全部',
key: '0',
children: [{
label: '公司',
value: '公司',
key: '0-1',
const api = useRef();
useEffect(() => {
let query = []
treeData?.map(v => [
query.push({ label: v.label, value: v.value, key: v.key })
])
setQueryData([{ label: '全部', value: '全部', key: '0', children: query }])
}, [])
useEffect(() => {
if (treeData && queryValue.includes('全部')) {
setLefTtree(treeData)
} else {
let leftData = []
queryValue.map(item => leftData.push(treeData?.find(({ value }) => item == value))) //
setLefTtree([{ label: '全部', value: '全部', key: '0', children: leftData }])
}
}, [queryData, queryValue])
useEffect(() => {
setLeftValue()
}, [])
const treeData = [{
label: '公司',
value: '公司',
key: '0-1',
children: [
{
label: '大门',
value: '大门',
key: '0-1-1',
videoData: {
channelNo: 1,
content: ['5442542542', '452345', '234524525'],
serialNo: "F61504020",
type: "yingshi",
yingshiToken: "at.7pl4c5orb9fpndtlbjpsn5m11szujnf7-1laxxre0ob-010o8fw-kqeuwthva"
}
}, {
label: '机房',
value: '机房',
key: '0-1-2',
videoData: {
channelNo: 3,
content: ['5442542542', '452345', '234524525'],
serialNo: "F61504020",
type: "yingshi",
yingshiToken: "at.7pl4c5orb9fpndtlbjpsn5m11szujnf7-1laxxre0ob-010o8fw-kqeuwthva"
}
}, {
label: '后门',
value: '后门',
key: '0-1-3',
videoData: {
channelNo: 1,
content: ['5442542542', '452345', '234524525'],
serialNo: "F61504020",
type: "yingshi",
yingshiToken: "at.7pl4c5orb9fpndtlbjpsn5m11szujnf7-1laxxre0ob-010o8fw-kqeuwthva"
}
},
]
}, {
label: '外部',
value: '外部',
key: '0-2',
children: [
{
label: '水库',
value: '水库',
key: '0-2-1',
children: [
{
label: '大门',
value: '大门',
key: '0-1-1',
}, {
label: '机房',
value: '机房',
key: '0-1-2',
}, {
label: '后门',
value: '后门',
key: '0-1-3',
},
{
label: '房子',
value: '房子',
key: '0-2-1-1',
videoData: {
channelNo: 1,
content: ['5442542542', '452345', '234524525'],
serialNo: "F61504020",
type: "yingshi",
yingshiToken: "at.7pl4c5orb9fpndtlbjpsn5m11szujnf7-1laxxre0ob-010o8fw-kqeuwthva"
}
},
]
}, {
label: '外部',
value: '外部',
key: '0-2',
},
]
}, {
label: '外',
value: '外',
key: '0-3',
children: [
{
label: '库',
value: '库',
key: '0-3-1',
children: [
{
label: '门口',
value: '门口',
key: '0-2-1',
},
{
label: '',
value: '',
key: '0-3-1-1',
},
]
}]
}]
return (
<>
{/* 头部标题及搜索 */}
<div>智慧小蓝视频融合监管中心</div>
<div>
<div style={{ width: 200, }}>
<div>查询
<TreeSelect
style={{ width: 150 }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
placeholder="请选择"
multiple={true}
defaultValue={['全部']}
maxTagCount={1}
onChange={(e) => {
console.log(e)
}}
/>
</div>
<Tree
treeData={treeData}
defaultExpandAll
style={{ width: 150 }}
/>
</div>
<div style={{flex: 1}}>
</div>
},
]
}]
//
const screen = { width: 193, marginRight: 20, marginBottom: 16, color: "#fff", };
//
const flipScreens = (data) => {
console.log(data);
switch (data) {
case "单屏":
setPageSize(1)
break;
case "4分屏":
setPageSize(4)
break;
case "6分屏":
setPageSize(6)
break;
case "12分屏":
setPageSize(12)
break;
default:
break
}
}
return (
<>
<div
className='KJBlue'
style={{
width: '100%', height: '100%',
background: 'url(/assets/images/application/background.png) 100% 100%',
backgroundSize: '100% 100%',
color: '#FFFFFF',
position: 'absolute', minWidth: 1000,
}}>
{/* 头部标题 */}
<div style={{
width: '100%', height: 80,
textAlign: 'center',
}}>
<div style={{
height: 80,
padding: '0 10px',
display: 'inline-block',
fontSize: '36px',
fontFamily: 'SourceHanSansCN - Heavy, SourceHanSansCN',
fontWeight: 800,
color: '#FFFFFF',
lineHeight: '70px',
letterSpacing: '5px',
background: 'url(/assets/images/application/titleBottom.png) 100% 100%',
backgroundSize: '100% 100%',
}} > 智慧小蓝视频融合监管中心</div>
</div>
<div style={{
height: "calc(100% - 112px)", margin: '16px', display: 'flex',
}}>
<div style={{ width: 300, height: "100%", border: '2px solid #003D9E', }}>
<div>查询
<TreeSelect
style={{ width: 150, }}
dropdownStyle={{ maxHeight: 300, overflow: 'auto', color: '#FFFFFF', }}
treeData={queryData}
placeholder="请选择"
multiple={true}
defaultValue={['全部']}
maxTagCount={1}
onChange={(e) => {
console.log(e)
setQueryValue(e)
}}
/>
</div>
<Tree
multiple
treeData={leftTree}
defaultExpandAll
defaultValue={['公司','外部']}
blockNode={false}
onChange={(e) => {
console.log(e);
setLeftValue(e)
}}
style={{ width: 150, color: '#FFFFFF' }}
/>
</div>
<div style={{
flex: 1, marginLeft: '10px', border: '2px solid #003D9E',
}}>
<div style={{ display: 'flex', }}>
<div style={{ flex: 1, marginTop: '10px', }}>
<Form
onSubmit={(values) => console.log(values)}
// onValueChange={values=>console.log(values)}
getFormApi={(formApi) => (api.current = formApi)}
layout="horizontal"
style={{ position: "relative", width: "100%", flex: 1 }}
>
<Form.Input label="设备搜索:" field="keyword" maxLength="36" placeholder="请输入设备名称" labelPosition="left" style={screen} />
{/* <Form.Select
label="状态查询:"
labelPosition="left"
field="state"
style={screen}
placeholder="全部"
showClear
>
<Form.Select.Option value="ON">在线</Form.Select.Option>
<Form.Select.Option value="OFF">离线</Form.Select.Option>
<Form.Select.Option value="UNKONW">未知</Form.Select.Option>
<Form.Select.Option value="DISABLED">禁用</Form.Select.Option>
</Form.Select>
*/}
</Form>
</div>
<div
style={{
marginTop: '10px',
// width: 150,
// display: "flex",
// justifyContent: "flex-end",
// alignItems: "flex-end",
}}
>
<Button
theme="solid"
type="primary"
style={{ width: 65, height: 30, borderRadius: 3, marginRight: 16, }}
onClick={() => {
// api.current.validate().then((v) => {
// setSearch(v);
// setQuery({ limit: 10, page: 0 })
// });
}}
>
搜索
</Button>
{/* <Button
theme="light"
type="primary"
style={{
width: 65,
height: 30,
backGround: "#FFFFFF",
borderRadius: 3,
border: "1px solid #D9D9D9",
marginBottom: 20,
}}
onClick={() => {
api.current.reset();
// setSearch({});
// setQuery({ limit: 10, page: 0 })
}}
>
重置
</Button> */}
</div>
</div>
<div style={{ display: 'flex', height: `calc( 100% - 160px )` }}>
{/* 视频 */}
<div style={{ flex: 1, height: '100%' }}>
<Row style={{ height: '100%' }}>
{/* {data.map((v, index) => {
console.log(v);
return <VideoCard key={'VideoCard' + index} data={v} pageSize={pageSize} />
})} */}
</Row>
</div>
{/* 视频设置 */}
<div style={{
width: 64, height: 476, background: ' #01185F', boxShadow: 'inset 0px 0px 5px 1px rgba(28,96,254,0.4000)', borderRadius: ' 1px', textAlign: 'center',
}}>
{[{ img: 'gongge', value: '宫格设置', screen: [{ img: 'screen1', value: '单屏' }, { img: 'screen4', value: '4分屏' }, { img: 'screen6', value: '6分屏' }, { img: 'screen12', value: '12分屏' },] },
{ img: 'polling', value: '轮询设置' },
{ img: 'back', value: '背投' },
{ img: 'monitor', value: '监控地图' },].map((v, index) => {
return <div key={index}>
<Popover
position='left'
trigger='click'
content={() => {
switch (v.value) {
case '宫格设置':
return <div style={{ height: 69, background: '#01185F', boxShadow: ' inset 0px 0px 5px 1px rgba(28,96,254,0.2500)', display: 'flex', justifyContent: 'space-evenly', alignItems: 'center' }}>
{v.screen.map((item) => {
return <div key={item.img} onClick={() => flipScreens(item.value)}>
<img src={`/assets/images/application/${item.img}.png`} alt="" style={{ width: 40, height: 40, }} />
<div style={{ width: 40, fontWeight: 400, color: ' #D9D9D9', fontSize: 12, textAlign: 'center' }}>{item.value}</div>
</div>
})}
</div>
case '轮询设置':
return <div style={{ height: 48, background: '#01185F', boxShadow: ' inset 0px 0px 5px 1px rgba(28,96,254,0.2500)', color: ' #D9D9D9', display: 'flex', justifyContent: 'space-evenly', alignItems: 'center' }}>
<Switch onChange={(v, e) => console.log(v)} aria-label="a switch for demo" style={{ border: ' 1px solid #D9D9D9', }} />
轮询间隔
<Input style={{ width: 80, color: ' #D9D9D9', border: ' 1px solid #D9D9D9', }} defaultValue='1' />
分钟
</div>
default:
break;
}
}}
>
<img src={`/assets/images/application/${v.img}.png`} alt="" style={{ width: 54, height: 54, margin: '20px 0 0px 10px' }} />
</Popover>
<div style={{ width: 32, marginLeft: 16 }}>{v.value}</div>
</div>
})}
</div>
</div>
</div>
</div>
</div >
</>
</>
)
)
}
function mapStateToProps (state) {
const { auth } = state;
return {
user: auth.user,
};
const { auth } = state;
return {
user: auth.user,
};
}
export default connect(mapStateToProps)(VideoScreen)

18
code/VideoAccess-VCMP/web/client/src/sections/journaling/components/videoScreen.less

@ -0,0 +1,18 @@
.KJBlue {
.semi-tree-option,
.semi-icon,
.semi-form-field-label-text {
color: #fff;
}
.semi-checkbox-inner-display {
//树状多选框
border: 1px solid #fff;
}
input {
background: #01185f;
box-shadow: inset 0px 0px 5px 1px rgba(28, 96, 254, 0.4);
}
input::placeholder {
color: #fff;
}
}

1
code/VideoAccess-VCMP/web/client/src/sections/monitor/containers/videoPlayCross.jsx

@ -47,7 +47,6 @@ const VideoPlayCross = (props) => {
window.removeEventListener('resize', resize_);
}
}, [])
console.log(videoParams);
return (
<>
{

10
code/VideoAccess-VCMP/web/client/src/utils/webapi.js

@ -60,14 +60,14 @@ export const ApiTable = {
delPush: 'status/push/{configId}',//删除推送配置
putPushBanned: 'status/push/banned',//禁用推送配置
getPushCopy: 'status/push/{configId}/copy',//复制推送配置
getPushLog: '/status/push/{configId}/log',//获取推送记录
getPushLog: 'status/push/{configId}/log',//获取推送记录
//应用管理
getApplication: '/application', //获取应用信息
putApplication: '/application', //禁用应用
delApplication: '/application/{appId}', //删除应用
postApplication: '/application', //创建/修改应用
getApplication: 'application', //获取应用信息
putApplication: 'application', //禁用应用
delApplication: 'application/{appId}', //删除应用
postApplication: 'application', //创建/修改应用
};
export const VideoServeApi = {

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.112:4000 --apiVcmpUrl http://localhost:4000 --apiAuthUrl http://10.8.30.112:4200 --apiAnxinyunUrl http://10.8.30.112:4100 --iotAuthWeb http://localhost:5200 --iotVideoServer http://221.230.55.27:8081",
"start-params": "node server -p 5000 -u http://localhost:4000 --apiVcmpUrl http://localhost:4000 --apiAuthUrl http://localhost:4200 --apiAnxinyunUrl http://localhost:4100 --iotAuthWeb http://localhost:5200 --iotVideoServer http://221.230.55.27:8081",
"deploy": "export NODE_ENV=production&& npm run build && node server",
"build-dev": "cross-env NODE_ENV=development&&webpack --config webpack.config.js",
"build": "cross-env NODE_ENV=production&&webpack --config webpack.config.prod.js"

Loading…
Cancel
Save