wenlele
1 year ago
23 changed files with 1387 additions and 846 deletions
@ -1,63 +1,190 @@ |
|||
'use strict'; |
|||
const request = require('superagent'); |
|||
|
|||
function getFireAlarmList(opts) { |
|||
return async function (ctx, next) { |
|||
const models = ctx.fs.dc.models; |
|||
let errMsg = { message: '获取消防告警失败' } |
|||
try { |
|||
const res = await models.FireAlarm.findAll(); |
|||
ctx.status = 200; |
|||
ctx.body = res; |
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = errMsg |
|||
} |
|||
} |
|||
function getFireAlarmList (opts) { |
|||
return async function (ctx, next) { |
|||
const models = ctx.fs.dc.models; |
|||
let errMsg = { message: '获取消防告警失败' } |
|||
try { |
|||
const res = await models.FireAlarm.findAll(); |
|||
ctx.status = 200; |
|||
ctx.body = res; |
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = errMsg |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 新增消防告警
|
|||
function addAlarm(opts) { |
|||
return async function (ctx, next) { |
|||
const models = ctx.fs.dc.models; |
|||
try { |
|||
const body = ctx.request.body |
|||
await models.FireAlarm.create(body) |
|||
|
|||
ctx.status = 204; |
|||
ctx.body = { message: '新建消防告警成功' } |
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = { message: '新建消防告警失败' } |
|||
} |
|||
} |
|||
function addAlarm (opts) { |
|||
return async function (ctx, next) { |
|||
const models = ctx.fs.dc.models; |
|||
try { |
|||
const body = ctx.request.body |
|||
await models.FireAlarm.create(body) |
|||
|
|||
ctx.status = 204; |
|||
ctx.body = { message: '新建消防告警成功' } |
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = { message: '新建消防告警失败' } |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 修改消防告警
|
|||
function updateAlarm(opts) { |
|||
return async function (ctx, next) { |
|||
try { |
|||
const models = ctx.fs.dc.models; |
|||
const { id } = ctx.params; |
|||
const body = ctx.request.body; |
|||
await models.FireAlarm.update( |
|||
body, |
|||
{ where: { id: id, } } |
|||
) |
|||
ctx.status = 204; |
|||
ctx.body = { message: '修改消防告警成功' } |
|||
|
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = { message: '修改消防告警失败' } |
|||
} |
|||
} |
|||
function updateAlarm (opts) { |
|||
return async function (ctx, next) { |
|||
try { |
|||
const models = ctx.fs.dc.models; |
|||
const { id } = ctx.params; |
|||
const body = ctx.request.body; |
|||
await models.FireAlarm.update( |
|||
body, |
|||
{ where: { id: id, } } |
|||
) |
|||
ctx.status = 204; |
|||
ctx.body = { message: '修改消防告警成功' } |
|||
|
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = { message: '修改消防告警失败' } |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
function videoList (opts) { |
|||
return async function (ctx) { |
|||
try { |
|||
const { models, } = ctx.fs.dc; |
|||
const { app, yingshiTokenRes } = ctx |
|||
|
|||
let yingshiToken = '' |
|||
if (yingshiTokenRes && yingshiTokenRes.token && yingshiTokenRes.expire && moment().isBefore(moment(yingshiTokenRes.expire))) { |
|||
yingshiToken = yingshiTokenRes.token |
|||
} else { |
|||
const tokenRes = await app.fs.yingshiRequest.post(`lapp/token/get`, { |
|||
query: { |
|||
appKey: opts.yingshiKey, |
|||
appSecret: opts.yingshiSecret |
|||
} |
|||
}) |
|||
if (tokenRes.code == 200 && tokenRes.data) { |
|||
const { accessToken, expireTime } = tokenRes.data |
|||
|
|||
ctx.yingshiTokenRes = { |
|||
token: accessToken, |
|||
expire: expireTime |
|||
} |
|||
yingshiToken = accessToken |
|||
} else { |
|||
throw '未能获取进行萤石鉴权' |
|||
} |
|||
} |
|||
|
|||
// const deviceRes = await app.fs.yingshiRequest.post(`lapp/device/list`, {
|
|||
// query: {
|
|||
// accessToken: yingshiToken,
|
|||
// }
|
|||
// })
|
|||
|
|||
ctx.status = 200; |
|||
|
|||
let deviceRes_ = [{ |
|||
deviceName: '楼前大桥', |
|||
deviceSerial: 'L48947105', |
|||
}, { |
|||
deviceName: '滁北大桥', |
|||
deviceSerial: 'L48947108', |
|||
}, { |
|||
deviceName: '新联桥', |
|||
deviceSerial: 'L48947110', |
|||
}, { |
|||
deviceName: '湾庄线', |
|||
deviceSerial: 'L48947112', |
|||
}, { |
|||
deviceName: '新土线', |
|||
deviceSerial: 'AA9943808', |
|||
}, { |
|||
deviceName: '东文大桥', |
|||
deviceSerial: 'L48947087', |
|||
}, { |
|||
deviceName: '莲姚线', |
|||
deviceSerial: 'L48947082', |
|||
}, { |
|||
deviceName: '荷漳公路', |
|||
deviceSerial: 'L48947109', |
|||
}, { |
|||
deviceName: '新武大桥', |
|||
deviceSerial: 'L48947086', |
|||
},] |
|||
|
|||
const deviceState = await Promise.all(deviceRes_.map(d => { |
|||
return app.fs.yingshiRequest.post(`lapp/device/info`, { |
|||
query: { |
|||
accessToken: yingshiToken, |
|||
deviceSerial: d.deviceSerial |
|||
} |
|||
}) |
|||
})) |
|||
|
|||
for (let d of deviceRes_) { |
|||
let corState = deviceState.find(item => item.code == 200 && item.data && item.data.deviceSerial == d.deviceSerial) |
|||
if (corState) { |
|||
d.status = corState.data.status |
|||
} else { |
|||
d.status = 0 |
|||
} |
|||
d.token = yingshiToken |
|||
} |
|||
|
|||
ctx.body = deviceRes_ |
|||
// ||
|
|||
// (deviceRes.data || []).map(item => {
|
|||
// return {
|
|||
// ...item,
|
|||
// token: yingshiToken,
|
|||
// }
|
|||
// })
|
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: error`); |
|||
ctx.status = 400; |
|||
ctx.body = { |
|||
message: typeof error == 'string' ? error : undefined |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
function getDetails (opts) { |
|||
return async function (ctx) { |
|||
try { |
|||
const res = await request.get('https://jiaotong.baidu.com/trafficindex/city/details/?cityCode=163') |
|||
|
|||
ctx.status = 200 |
|||
ctx.body = res.body || {} |
|||
|
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: error`); |
|||
ctx.status = 400; |
|||
ctx.body = { |
|||
message: '获取南昌市道路数据失败' |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
module.exports = { |
|||
addAlarm, |
|||
updateAlarm, |
|||
getFireAlarmList |
|||
addAlarm, |
|||
updateAlarm, |
|||
getFireAlarmList, |
|||
videoList, |
|||
getDetails |
|||
} |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 8.1 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 8.1 KiB |
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 38 KiB |
@ -1,125 +1,134 @@ |
|||
.opcityBackground { |
|||
background-color: rgba(8, 27, 55, 0.6); |
|||
background-color: rgba(8, 27, 55, 0.6); |
|||
} |
|||
|
|||
.card-title { |
|||
height: 31px; |
|||
font-family: YouSheBiaoTiHei; |
|||
font-size: 24px; |
|||
color: #FFFFFF; |
|||
letter-spacing: 2px; |
|||
padding-left: 15px; |
|||
height: 31px; |
|||
font-family: YouSheBiaoTiHei; |
|||
font-size: 24px; |
|||
color: #ffffff; |
|||
letter-spacing: 2px; |
|||
padding-left: 15px; |
|||
} |
|||
|
|||
/* 滚动列表 */ |
|||
.scroll-board { |
|||
width: 533px; |
|||
height: 220px; |
|||
margin-top: 10px; |
|||
margin-left: 6px; |
|||
|
|||
.header { |
|||
height: 30px; |
|||
border-top: 1px solid #0047ba; |
|||
border-bottom: 1px solid #0047ba; |
|||
|
|||
.header-item { |
|||
// background: rgba(12, 49, 110, 0.3); |
|||
margin-right: 10px; |
|||
} |
|||
} |
|||
|
|||
.rows { |
|||
.row-item { |
|||
font-size: 16px; |
|||
} |
|||
|
|||
.row-item:hover { |
|||
background: linear-gradient(270deg, rgba(17, 183, 247, 0) 0%, rgba(17, 183, 247, 0.85) 100%); |
|||
color: #9ac8fc; |
|||
} |
|||
} |
|||
width: 533px; |
|||
height: 220px; |
|||
margin-top: 10px; |
|||
margin-left: 6px; |
|||
|
|||
.header { |
|||
height: 30px; |
|||
border-top: 1px solid #0047ba; |
|||
border-bottom: 1px solid #0047ba; |
|||
|
|||
.header-item { |
|||
// background: rgba(12, 49, 110, 0.3); |
|||
margin-right: 10px; |
|||
} |
|||
} |
|||
|
|||
.rows { |
|||
.row-item { |
|||
font-size: 16px; |
|||
} |
|||
|
|||
.row-item:hover { |
|||
background: linear-gradient( |
|||
270deg, |
|||
rgba(17, 183, 247, 0) 0%, |
|||
rgba(17, 183, 247, 0.85) 100% |
|||
); |
|||
color: #9ac8fc; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.scroll-board-multi { |
|||
padding: 5px 0px 5px; |
|||
color: rgba(204, 228, 255, 1) !important; |
|||
|
|||
.header { |
|||
display: flex; |
|||
flex-direction: row; |
|||
font-size: 12px !important; |
|||
color: rgba(204, 228, 255, 1) !important; |
|||
// border-bottom: 1px solid #124C79 !important; |
|||
} |
|||
|
|||
.rows { |
|||
color: rgba(204, 228, 255, 1) !important; |
|||
|
|||
.row-item { |
|||
border-bottom: 1px solid #124C79 !important; |
|||
} |
|||
|
|||
.row-item:hover { |
|||
background: linear-gradient(270deg, rgba(17, 183, 247, 0) 0%, rgba(17, 183, 247, 0.85) 100%); |
|||
color: #9ac8fc; |
|||
} |
|||
} |
|||
padding: 5px 0px 5px; |
|||
color: rgba(204, 228, 255, 1) !important; |
|||
|
|||
.header { |
|||
display: flex; |
|||
flex-direction: row; |
|||
font-size: 12px !important; |
|||
color: rgba(204, 228, 255, 1) !important; |
|||
// border-bottom: 1px solid #124C79 !important; |
|||
} |
|||
|
|||
.rows { |
|||
color: rgba(204, 228, 255, 1) !important; |
|||
|
|||
.row-item { |
|||
border-bottom: 1px solid #124c79 !important; |
|||
} |
|||
|
|||
.row-item:hover { |
|||
background: linear-gradient( |
|||
270deg, |
|||
rgba(17, 183, 247, 0) 0%, |
|||
rgba(17, 183, 247, 0.85) 100% |
|||
); |
|||
color: #9ac8fc; |
|||
} |
|||
} |
|||
} |
|||
|
|||
._sorrow { |
|||
display: inline-block; |
|||
width: 15px; |
|||
height: 15px; |
|||
background: url('/assets/images/homepage/bigscreen/sorrow.png'); |
|||
background-repeat: no-repeat; |
|||
background-size: 100% 100%; |
|||
margin-left: 13px; |
|||
display: inline-block; |
|||
width: 15px; |
|||
height: 15px; |
|||
background: url("/assets/images/homepage/bigscreen/sorrow.png"); |
|||
background-repeat: no-repeat; |
|||
background-size: 100% 100%; |
|||
margin-left: 13px; |
|||
} |
|||
|
|||
.subtitle_ { |
|||
float: right; |
|||
margin-top: 12px; |
|||
margin-right: 20px; |
|||
width: 200px; |
|||
text-align: center; |
|||
|
|||
._item_select { |
|||
width: 60px; |
|||
height: 20px; |
|||
display: inline-block; |
|||
font-size: 14px; |
|||
color: #24DCF7; |
|||
border: 1px solid #12B2E5; |
|||
background-color: rgba(91, 193, 255, 0.2); |
|||
margin-right: 3px; |
|||
cursor: pointer; |
|||
} |
|||
|
|||
._item { |
|||
width: 60px; |
|||
height: 20px; |
|||
display: inline-block; |
|||
font-size: 14px; |
|||
color: #4C9FFF; |
|||
border: 1px solid #0B6AEA; |
|||
background-color: rgba(35, 108, 254, 0.3); |
|||
margin-right: 3px; |
|||
cursor: pointer; |
|||
} |
|||
float: right; |
|||
margin-top: 12px; |
|||
margin-right: 20px; |
|||
width: 200px; |
|||
text-align: center; |
|||
|
|||
._item_select { |
|||
width: 60px; |
|||
height: 20px; |
|||
display: inline-block; |
|||
font-size: 14px; |
|||
color: #24dcf7; |
|||
border: 1px solid #12b2e5; |
|||
background-color: rgba(91, 193, 255, 0.2); |
|||
margin-right: 3px; |
|||
cursor: pointer; |
|||
} |
|||
|
|||
._item { |
|||
width: 60px; |
|||
height: 20px; |
|||
display: inline-block; |
|||
font-size: 14px; |
|||
color: #4c9fff; |
|||
border: 1px solid #0b6aea; |
|||
background-color: rgba(35, 108, 254, 0.3); |
|||
margin-right: 3px; |
|||
cursor: pointer; |
|||
} |
|||
} |
|||
|
|||
.children-container { |
|||
height: calc(100% - 42px); |
|||
background-image: linear-gradient(180deg, #04377ecc 1%, #001241 100%); |
|||
height: calc(100% - 42px); |
|||
// background-image: linear-gradient(180deg, #04377ecc 1%, #001241 100%); |
|||
background-image: linear-gradient(180deg, #04377ecc 1%, #001241 100%); |
|||
} |
|||
|
|||
.box_header_bg { |
|||
background: url(/assets/images/homepage/bigscreen/headertitlebg.png) no-repeat; |
|||
background-size: 100% 100%; |
|||
height: 42px; |
|||
padding-top: 4px; |
|||
word-break: keep-all; |
|||
white-space: nowrap; |
|||
width: 100%; |
|||
background: url(/assets/images/homepage/bigscreen/headertitlebg.png) no-repeat; |
|||
background-size: 100% 100%; |
|||
height: 42px; |
|||
padding-top: 4px; |
|||
word-break: keep-all; |
|||
white-space: nowrap; |
|||
width: 100%; |
|||
} |
@ -0,0 +1,52 @@ |
|||
/** |
|||
* 萤石视频直播(基于萤石云iframe模式,使用方式简单) |
|||
* 官方参考:https://open.ys7.com/console/ezopenIframe.html
|
|||
*/ |
|||
'use strict'; |
|||
|
|||
import React from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
|
|||
const YSIframePlayer = props => { |
|||
|
|||
const { containerId, height, width, url, autoplay, audio, videoState, ysToken } = props; |
|||
const at = ysToken |
|||
if (!url || !at) return null; |
|||
const src = `https://open.ys7.com/ezopen/h5/iframe?audio=${audio ? '1' : '0'}&url=${url}&autoplay=${autoplay || 1}&accessToken=${at}` |
|||
// const src = `https://open.ys7.com/ezopen/h5/iframe?audio=1&url=${url}&autoplay=${autoplay || 1}&accessToken=${at}`
|
|||
return ( |
|||
<div |
|||
style={{ position: 'relative', height: '100%', width: '100%' }}> |
|||
<iframe |
|||
frameBorder="0" |
|||
id={containerId || 'myPlayer'} |
|||
src={src} |
|||
// https://open.ys7.com/doc/zh/book/index/live_proto.html 单个播放器的长宽比例限制最小为{width: 400px;height: 300px;}
|
|||
width={width || 400} |
|||
height={height || 300} |
|||
allowFullScreen |
|||
wmode="transparent" |
|||
> |
|||
</iframe> |
|||
{ |
|||
videoState && videoState.status == 0 ? |
|||
<div style={{ |
|||
height: width || 300, width: width || 400, position: 'absolute', top: 0, background: '#000', |
|||
display: 'flex', justifyContent: 'center', alignItems: 'center', color: '#fff' |
|||
}}> |
|||
设备中断,正在处理中... |
|||
</div> |
|||
: '' |
|||
} |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps (state) { |
|||
const { auth, } = state; |
|||
return { |
|||
user: auth.user, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(YSIframePlayer); |
@ -0,0 +1,209 @@ |
|||
import React, { useEffect, useState } from 'react' |
|||
import { connect } from 'react-redux'; |
|||
import { Box, YSIframePlayer } from '$components'; |
|||
import { Select } from 'antd'; |
|||
import { ArrowDownOutlined, ArrowUpOutlined } from '@ant-design/icons'; |
|||
import './style.less'; |
|||
|
|||
|
|||
const DataTop5 = ({ dispatch, actions, longitudeLatitude }) => { |
|||
const [videoList, setVideoList] = useState([]) |
|||
const [options, setOptions] = useState([]) |
|||
const [traffic, setTraffic] = useState({}) |
|||
let weeks = { 1: '周一', 2: '周二', 3: '周三', 4: '周四', 5: '周五', 6: '周六', 7: '周日' } |
|||
|
|||
useEffect(() => { |
|||
dispatch(actions.firecontrol.getDetails()).then(res => { |
|||
if (res.success) { |
|||
setTraffic(res.payload.data?.data?.detail || {}); |
|||
} |
|||
}) |
|||
}, []) |
|||
|
|||
useEffect(() => { |
|||
dispatch(actions.firecontrol.getDetails()).then(res => { |
|||
if (res.success) { |
|||
setTraffic(res.payload.data?.data?.detail || {}); |
|||
} |
|||
}) |
|||
}, [longitudeLatitude]) |
|||
|
|||
console.log(longitudeLatitude); |
|||
|
|||
return <div style={{ height: '100%', width: '100%', margin: "0px 0px 28px" }}> |
|||
<div style={{ |
|||
height: "100%", listStyle: 'none', |
|||
|
|||
}}> |
|||
<div className='box_header_bg' > |
|||
<span className='card-title'>周边路况实时数据</span> |
|||
</div> |
|||
<div className='children-container' style={{ padding: '20px' }}> |
|||
{longitudeLatitude?.longitude ? |
|||
<> |
|||
{/* <div style={{ |
|||
height: "23%", display: "flex", |
|||
background: 'linear-gradient(180deg, #04377ecc 1%, #001241 100%)' |
|||
}}> |
|||
<div style={{ width: "34%", display: 'flex', flexDirection: "column", justifyContent: "center", alignItems: "center" }}> |
|||
<div style={{ |
|||
fontFamily: "YouSheBiaoTiHei", fontSize: 28, letterSpacing: 2, |
|||
color: (traffic?.index >= 1 && traffic?.index < 1.5) ? |
|||
"#00FF87" : (traffic?.index >= 1.5 && traffic?.index < 1.8) ? |
|||
"#FFCC00;" : (traffic?.index >= 1.8 && traffic?.index < 2) ? |
|||
"#DE0102;" : (traffic?.index >= 2) ? "#8E0E0B;" : "" |
|||
}}>畅通</div> |
|||
<div style={{ fontSize: 14, color: "#C0E2FF;" }}>路况整体评价</div> |
|||
</div> |
|||
<div style={{ width: "62%", display: 'flex', }}> |
|||
<div style={{ width: "50%", display: 'flex', flexDirection: "column", justifyContent: "space-evenly", alignItems: "center" }}> |
|||
<div style={{ height: 22, background: "rgb(0 88 204 / 50%)", width: '90%', textAlign: 'center' }}>平均通行速度</div> |
|||
<div ><div style={{ display: 'inline-block', transform: 'skewX(-8deg)', fontSize: 20, fontFamily: "D-DINExp-Italic", }}>{traffic?.road_network_speed || '--'}</div> <span style={{ color: '#00FF87', marginLeft: 6 }}>km/h</span></div> |
|||
</div> |
|||
<div style={{ width: "50%", display: 'flex', flexDirection: "column", justifyContent: "space-evenly", alignItems: "center" }}> |
|||
<div style={{ height: 22, background: "rgb(0 88 204 / 50%)", width: '90%', textAlign: 'center' }}>拥堵距离</div> |
|||
<div ><div style={{ display: 'inline-block', transform: 'skewX(-8deg)', fontSize: 20, fontFamily: "D-DINExp-Italic", }}>{traffic?.yongdu_length_4 || '--'}</div><span style={{ color: '#00FF87', marginLeft: 6 }}>km</span> </div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div style={{ display: 'flex' }}> |
|||
<div style={{ fontFamily: 'SourceHanSansCN-Bold', fontWeight: 700, fontSize: 18, width: 190 }}>较10分钟前拥堵趋势:</div> |
|||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start', width: "calc(100% - 200px)" }}> |
|||
<div style={{ |
|||
display: 'flex', alignItems: 'center', justifyContent: 'space-around' |
|||
}}> |
|||
<div style={{ fontSize: 28, transform: 'skewX(-8deg)', color: '#00FF87', fontFamily: "YouSheBiaoTiHei", }}> |
|||
持平 |
|||
</div> |
|||
<img src="/assets/images/homepage/bigscreen/red.png" style={{ width: 30, height: 30 }} /> |
|||
</div> |
|||
<div>与1设法厕任务v</div> |
|||
|
|||
</div> |
|||
</div> |
|||
<div style={{}}> |
|||
<div style={{ fontFamily: 'SourceHanSansCN-Bold', fontWeight: 700, fontSize: 18, }}>路况描述:</div> |
|||
<div>dewbfdhuihseacf dsjhcf ewdcjaiopsdc op sadc jwe dcfp weopdcf ujew fdc </div> |
|||
|
|||
</div> */} |
|||
|
|||
|
|||
</> |
|||
: <> |
|||
<div style={{ |
|||
background: 'url(/assets/images/homepage/bigscreen/background_n.png)', |
|||
backgroundSize: '100% 20px', backgroundPosition: '0 14px', backgroundRepeat: 'no-repeat', |
|||
display: 'flex', alignItems: 'center', justifyContent: "space-between", padding: '0 6px', |
|||
}}> |
|||
<div style={{ |
|||
fontFamily: 'YouSheBiaoTiHei', fontSize: 20 |
|||
}} |
|||
> |
|||
南昌市</div> |
|||
<div style={{ |
|||
fontFamily: 'YouSheBiaoTiHei', fontSize: 14 |
|||
}} |
|||
>NANCHANG CITY</div> |
|||
</div> |
|||
<div style={{ |
|||
height: "calc(100% - 38px)", marginTop: 20, display: 'flex', flexDirection: 'column', justifyContent: 'space-around', |
|||
|
|||
}}> |
|||
<div style={{ |
|||
height: "23%", display: "flex", |
|||
background: 'linear-gradient(180deg, #04377ecc 1%, #001241 100%)' |
|||
}}> |
|||
<div style={{ width: "34%", display: 'flex', flexDirection: "column", justifyContent: "center", alignItems: "center" }}> |
|||
<div style={{ |
|||
fontFamily: "YouSheBiaoTiHei", fontSize: 28, letterSpacing: 2, |
|||
color: (traffic?.index >= 1 && traffic?.index < 1.5) ? |
|||
"#00FF87" : (traffic?.index >= 1.5 && traffic?.index < 1.8) ? |
|||
"#FFCC00;" : (traffic?.index >= 1.8 && traffic?.index < 2) ? |
|||
"#DE0102;" : (traffic?.index >= 2) ? "#8E0E0B;" : "" |
|||
}}>{ |
|||
(traffic?.index >= 1 && traffic?.index < 1.5) ? |
|||
"畅通" : (traffic?.index >= 1.5 && traffic?.index < 1.8) ? |
|||
"缓行" : (traffic?.index >= 1.8 && traffic?.index < 2) ? |
|||
"拥堵" : (traffic?.index >= 2) ? "严重拥堵" : "" |
|||
}</div> |
|||
<div style={{ fontSize: 14, color: "#C0E2FF;" }}>路况整体评价</div> |
|||
</div> |
|||
<div style={{ width: "62%", display: 'flex', flexDirection: "column", justifyContent: "space-evenly", }}> |
|||
<div style={{ height: 22, background: "rgb(0 88 204 / 50%)", textIndent: 20 }}>实时拥堵指数</div> |
|||
<div style={{ display: "flex", alignItems: 'center' }}> |
|||
<div style={{ fontSize: 28, transform: 'skewX(-8deg)', fontFamily: "D-DINExp-Italic", fontWeight: 'Italic', color: '#ECF7FF', marginRight: 4 }}>{traffic?.index || '--'}</div> |
|||
<div style={{ color: '#C3E6FF' }}> |
|||
较上周同期{traffic?.last_index > traffic?.index ? "下降" : '上升'} |
|||
{((traffic?.last_index > traffic?.index ? (traffic?.last_index - traffic?.index) / traffic?.last_index : (traffic?.index - traffic?.last_index) / traffic?.last_index) * 100).toFixed(2)}% |
|||
</div> |
|||
{traffic?.last_index > traffic?.index ? |
|||
<ArrowDownOutlined style={{ color: '#06FF07', fontSize: 18 }} /> |
|||
: <ArrowUpOutlined style={{ color: '#06FF07', fontSize: 18 }} />} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div style={{ |
|||
height: "23%", display: "flex", |
|||
background: 'linear-gradient(180deg, #04377ecc 1%, #001241 100%)' |
|||
}}> |
|||
<div style={{ width: "34%", display: 'flex', flexDirection: "column", justifyContent: "center", alignItems: "center" }}> |
|||
<img src='/assets/images/homepage/bigscreen/seniority.png' style={{ width: "80%" }} /> |
|||
</div> |
|||
<div style={{ width: "62%", display: 'flex', flexDirection: "column", justifyContent: "space-evenly", }}> |
|||
<div style={{ height: 22, background: "rgb(0 88 204 / 50%)", textIndent: 20 }}>实时拥堵排行</div> |
|||
<div style={{ display: "flex", alignItems: 'center' }}> |
|||
<div style={{ fontSize: 28, fontFamily: "D-DINExp-Italic", transform: 'skewX(-8deg)', fontWeight: 'Italic', color: '#ECF7FF', marginRight: 4 }}>{traffic?.rank || '--'}</div> |
|||
<div style={{ marginRight: 16, fontSize: 20, transform: 'skewX(-8deg)' }}>/{traffic?.count || '--'}</div> |
|||
<div style={{ color: '#C3E6FF' }}>全国重点城市拥堵排行</div> |
|||
|
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div style={{ |
|||
height: "23%", display: "flex", |
|||
background: 'linear-gradient(180deg, #04377ecc 1%, #001241 100%)' |
|||
}}> |
|||
<div style={{ width: "50%", display: 'flex', flexDirection: "column", justifyContent: "space-evenly", alignItems: "center" }}> |
|||
<div style={{ height: 22, background: "rgb(0 88 204 / 50%)", width: '90%', textAlign: 'center' }}>实时平均速度</div> |
|||
<div ><div style={{ display: 'inline-block', transform: 'skewX(-8deg)', fontSize: 28, fontFamily: "D-DINExp-Italic", }}>{traffic?.road_network_speed || '--'}</div> <span style={{ color: '#00FF87', marginLeft: 20 }}>km/h</span></div> |
|||
</div> |
|||
<div style={{ width: "50%", display: 'flex', flexDirection: "column", justifyContent: "space-evenly", alignItems: "center" }}> |
|||
<div style={{ height: 22, background: "rgb(0 88 204 / 50%)", width: '90%', textAlign: 'center' }}>实时严重拥堵里程</div> |
|||
<div ><div style={{ display: 'inline-block', transform: 'skewX(-8deg)', fontSize: 28, fontFamily: "D-DINExp-Italic", }}>{traffic?.yongdu_length_4 || '--'}</div><span style={{ color: '#00FF87', marginLeft: 20 }}>km</span> </div> |
|||
</div> |
|||
</div> |
|||
|
|||
<div style={{ |
|||
height: "23%", display: "flex", |
|||
background: 'linear-gradient(180deg, #04377ecc 1%, #001241 100%)' |
|||
}}> |
|||
<div style={{ width: "34%", display: 'flex', flexDirection: "column", justifyContent: "center", alignItems: "center" }}> |
|||
<img src='/assets/images/homepage/bigscreen/dateDook.png' style={{ width: "80%" }} /> |
|||
</div> |
|||
<div style={{ width: "62%", display: 'flex', flexDirection: "column", justifyContent: "space-evenly", }}> |
|||
<div style={{ height: 22, background: "rgb(0 88 204 / 50%)", textIndent: 20 }}>近30日最高拥堵指数</div> |
|||
<div style={{ display: "flex", alignItems: 'center' }}> |
|||
<div style={{ fontSize: 28, fontFamily: "D-DINExp-Italic", fontWeight: 'Italic', color: '#ECF7FF', marginRight: 38 }}>{traffic?.month_max_yongdu_index || '--'}</div> |
|||
<div style={{ color: '#C3E6FF' }}>{traffic?.month_max_congest_time} {weeks[traffic?.month_max_week_day]}</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div></> |
|||
|
|||
} |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
</div > |
|||
} |
|||
function mapStateToProps (state) { |
|||
const { auth, global } = state |
|||
return { |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
} |
|||
} |
|||
export default connect(mapStateToProps)(DataTop5); |
|||
|
|||
|
@ -1,29 +1,71 @@ |
|||
import React, { useEffect, useState } from 'react' |
|||
import { Box } from '$components'; |
|||
import { connect } from 'react-redux'; |
|||
import { Box, YSIframePlayer } from '$components'; |
|||
import { Select } from 'antd'; |
|||
import './style.less'; |
|||
|
|||
|
|||
function DataTop5(props) { |
|||
|
|||
|
|||
return <Box title={"视频监控"} bodyPaddingTop={1} > |
|||
<div className='video_container'> |
|||
<div className='_item'> |
|||
<div className='video_bottom'><span>南昌大道</span><span>14:12:32</span></div> |
|||
</div> |
|||
<div className='_item'> |
|||
<div className='video_bottom'><span>南昌大道</span><span>11:34:12</span></div> |
|||
</div> |
|||
<div className='_item'> |
|||
<div className='video_bottom'><span>南昌大道</span><span>08:34:12</span></div> |
|||
</div> |
|||
<div className='_item'> |
|||
<div className='video_bottom'><span>南昌大道</span><span>09:12:34</span></div> |
|||
</div> |
|||
</div> |
|||
</Box> |
|||
} |
|||
const DataTop5 = ({ dispatch, actions }) => { |
|||
const [videoList, setVideoList] = useState([]) |
|||
const [options, setOptions] = useState([]) |
|||
const [videoData, setVideoData] = useState({}) |
|||
|
|||
|
|||
useEffect(() => { |
|||
dispatch(actions.firecontrol.getVideoCenterList()).then(res => { |
|||
if (res.success) { |
|||
setVideoList(res.payload.data || []) |
|||
setOptions(res.payload.data?.map(v => ({ value: v.deviceSerial, label: v.deviceName })) || []) |
|||
setVideoData(res.payload.data[0] || {}) |
|||
} |
|||
}) |
|||
}, []) |
|||
|
|||
|
|||
export default DataTop5; |
|||
return <div style={{ height: '100%', width: '100%', margin: "0px 0px 28px" }}> |
|||
<div style={{ |
|||
height: "100%", listStyle: 'none', |
|||
|
|||
}}> |
|||
<div className='box_header_bg' > |
|||
<span className='card-title'>视频监控</span> |
|||
<Select |
|||
className='bigscreen-select' |
|||
style={{ |
|||
width: 100, |
|||
float: 'right', |
|||
margin: '18px 20px 0 0 ' |
|||
}} |
|||
value={videoData?.deviceSerial} |
|||
onChange={v => { |
|||
setVideoData(videoList?.find(s => s.deviceSerial == v) ||{}) |
|||
}} |
|||
options={options} |
|||
/> |
|||
</div> |
|||
<div className='children-container'> |
|||
<YSIframePlayer |
|||
containerId={`yingshiPlay_lu_${videoData?.deviceSerial}`} |
|||
height='100%' |
|||
width="100%" |
|||
url={`ezopen://open.ys7.com/${videoData?.deviceSerial}/${'1'}.hd.live`} |
|||
audio="0" |
|||
ysToken={videoData?.token} |
|||
videoState={{ |
|||
status: videoData?.status |
|||
}} |
|||
/> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
} |
|||
function mapStateToProps (state) { |
|||
const { auth, global } = state |
|||
return { |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
} |
|||
} |
|||
export default connect(mapStateToProps)(DataTop5); |
|||
|
|||
|
|||
|
Loading…
Reference in new issue