After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 1.6 MiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 347 B |
After Width: | Height: | Size: 325 B |
After Width: | Height: | Size: 411 B |
After Width: | Height: | Size: 321 B |
After Width: | Height: | Size: 27 KiB |
@ -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) |
@ -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) |
@ -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) |
|||
|
@ -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; |
|||
} |
|||
} |