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 { 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 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 = [{ |
const api = useRef(); |
||||
label: '全部', |
|
||||
value: '全部', |
useEffect(() => { |
||||
key: '0', |
let query = [] |
||||
children: [{ |
treeData?.map(v => [ |
||||
label: '公司', |
query.push({ label: v.label, value: v.value, key: v.key }) |
||||
value: '公司', |
]) |
||||
key: '0-1', |
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: [ |
children: [ |
||||
{ |
{ |
||||
label: '大门', |
label: '房子', |
||||
value: '大门', |
value: '房子', |
||||
key: '0-1-1', |
key: '0-2-1-1', |
||||
}, { |
videoData: { |
||||
label: '机房', |
channelNo: 1, |
||||
value: '机房', |
content: ['5442542542', '452345', '234524525'], |
||||
key: '0-1-2', |
serialNo: "F61504020", |
||||
}, { |
type: "yingshi", |
||||
label: '后门', |
yingshiToken: "at.7pl4c5orb9fpndtlbjpsn5m11szujnf7-1laxxre0ob-010o8fw-kqeuwthva" |
||||
value: '后门', |
} |
||||
key: '0-1-3', |
}, |
||||
}, |
|
||||
] |
] |
||||
}, { |
}, |
||||
label: '外部', |
] |
||||
value: '外部', |
}, { |
||||
key: '0-2', |
label: '外', |
||||
|
value: '外', |
||||
|
key: '0-3', |
||||
|
children: [ |
||||
|
{ |
||||
|
label: '库', |
||||
|
value: '库', |
||||
|
key: '0-3-1', |
||||
children: [ |
children: [ |
||||
{ |
{ |
||||
label: '门口', |
label: '子', |
||||
value: '门口', |
value: '子', |
||||
key: '0-2-1', |
key: '0-3-1-1', |
||||
}, |
}, |
||||
] |
] |
||||
}] |
}, |
||||
}] |
] |
||||
|
}] |
||||
|
|
||||
|
//搜索条件赛选样式 |
||||
return ( |
const screen = { width: 193, marginRight: 20, marginBottom: 16, color: "#fff", }; |
||||
<> |
|
||||
{/* 头部标题及搜索 */} |
//宫格设置点击 |
||||
<div>智慧小蓝视频融合监管中心</div> |
const flipScreens = (data) => { |
||||
<div> |
console.log(data); |
||||
<div style={{ width: 200, }}> |
switch (data) { |
||||
<div>查询: |
case "单屏": |
||||
<TreeSelect |
setPageSize(1) |
||||
style={{ width: 150 }} |
break; |
||||
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }} |
case "4分屏": |
||||
treeData={treeData} |
setPageSize(4) |
||||
placeholder="请选择" |
break; |
||||
multiple={true} |
case "6分屏": |
||||
defaultValue={['全部']} |
setPageSize(6) |
||||
maxTagCount={1} |
break; |
||||
onChange={(e) => { |
case "12分屏": |
||||
console.log(e) |
setPageSize(12) |
||||
}} |
break; |
||||
/> |
default: |
||||
</div> |
break |
||||
|
} |
||||
<Tree |
} |
||||
treeData={treeData} |
|
||||
defaultExpandAll |
|
||||
style={{ width: 150 }} |
return ( |
||||
/> |
<> |
||||
</div> |
<div |
||||
<div style={{flex: 1}}> |
className='KJBlue' |
||||
|
style={{ |
||||
</div> |
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> |
||||
|
</div > |
||||
|
</> |
||||
|
|
||||
</> |
) |
||||
) |
|
||||
} |
} |
||||
|
|
||||
function mapStateToProps (state) { |
function mapStateToProps (state) { |
||||
const { auth } = state; |
const { auth } = state; |
||||
return { |
return { |
||||
user: auth.user, |
user: auth.user, |
||||
}; |
}; |
||||
} |
} |
||||
|
|
||||
export default connect(mapStateToProps)(VideoScreen) |
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; |
||||
|
} |
||||
|
} |