wenlele
1 year ago
23 changed files with 1387 additions and 846 deletions
@ -1,63 +1,190 @@ |
|||||
'use strict'; |
'use strict'; |
||||
|
const request = require('superagent'); |
||||
|
|
||||
function getFireAlarmList(opts) { |
function getFireAlarmList (opts) { |
||||
return async function (ctx, next) { |
return async function (ctx, next) { |
||||
const models = ctx.fs.dc.models; |
const models = ctx.fs.dc.models; |
||||
let errMsg = { message: '获取消防告警失败' } |
let errMsg = { message: '获取消防告警失败' } |
||||
try { |
try { |
||||
const res = await models.FireAlarm.findAll(); |
const res = await models.FireAlarm.findAll(); |
||||
ctx.status = 200; |
ctx.status = 200; |
||||
ctx.body = res; |
ctx.body = res; |
||||
} catch (error) { |
} catch (error) { |
||||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
||||
ctx.status = 400; |
ctx.status = 400; |
||||
ctx.body = errMsg |
ctx.body = errMsg |
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
// 新增消防告警
|
// 新增消防告警
|
||||
function addAlarm(opts) { |
function addAlarm (opts) { |
||||
return async function (ctx, next) { |
return async function (ctx, next) { |
||||
const models = ctx.fs.dc.models; |
const models = ctx.fs.dc.models; |
||||
try { |
try { |
||||
const body = ctx.request.body |
const body = ctx.request.body |
||||
await models.FireAlarm.create(body) |
await models.FireAlarm.create(body) |
||||
|
|
||||
ctx.status = 204; |
ctx.status = 204; |
||||
ctx.body = { message: '新建消防告警成功' } |
ctx.body = { message: '新建消防告警成功' } |
||||
} catch (error) { |
} catch (error) { |
||||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
||||
ctx.status = 400; |
ctx.status = 400; |
||||
ctx.body = { message: '新建消防告警失败' } |
ctx.body = { message: '新建消防告警失败' } |
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
// 修改消防告警
|
// 修改消防告警
|
||||
function updateAlarm(opts) { |
function updateAlarm (opts) { |
||||
return async function (ctx, next) { |
return async function (ctx, next) { |
||||
try { |
try { |
||||
const models = ctx.fs.dc.models; |
const models = ctx.fs.dc.models; |
||||
const { id } = ctx.params; |
const { id } = ctx.params; |
||||
const body = ctx.request.body; |
const body = ctx.request.body; |
||||
await models.FireAlarm.update( |
await models.FireAlarm.update( |
||||
body, |
body, |
||||
{ where: { id: id, } } |
{ where: { id: id, } } |
||||
) |
) |
||||
ctx.status = 204; |
ctx.status = 204; |
||||
ctx.body = { message: '修改消防告警成功' } |
ctx.body = { message: '修改消防告警成功' } |
||||
|
|
||||
} catch (error) { |
} catch (error) { |
||||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
||||
ctx.status = 400; |
ctx.status = 400; |
||||
ctx.body = { message: '修改消防告警失败' } |
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 = { |
module.exports = { |
||||
addAlarm, |
addAlarm, |
||||
updateAlarm, |
updateAlarm, |
||||
getFireAlarmList |
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 { |
.opcityBackground { |
||||
background-color: rgba(8, 27, 55, 0.6); |
background-color: rgba(8, 27, 55, 0.6); |
||||
} |
} |
||||
|
|
||||
.card-title { |
.card-title { |
||||
height: 31px; |
height: 31px; |
||||
font-family: YouSheBiaoTiHei; |
font-family: YouSheBiaoTiHei; |
||||
font-size: 24px; |
font-size: 24px; |
||||
color: #FFFFFF; |
color: #ffffff; |
||||
letter-spacing: 2px; |
letter-spacing: 2px; |
||||
padding-left: 15px; |
padding-left: 15px; |
||||
} |
} |
||||
|
|
||||
/* 滚动列表 */ |
/* 滚动列表 */ |
||||
.scroll-board { |
.scroll-board { |
||||
width: 533px; |
width: 533px; |
||||
height: 220px; |
height: 220px; |
||||
margin-top: 10px; |
margin-top: 10px; |
||||
margin-left: 6px; |
margin-left: 6px; |
||||
|
|
||||
.header { |
.header { |
||||
height: 30px; |
height: 30px; |
||||
border-top: 1px solid #0047ba; |
border-top: 1px solid #0047ba; |
||||
border-bottom: 1px solid #0047ba; |
border-bottom: 1px solid #0047ba; |
||||
|
|
||||
.header-item { |
.header-item { |
||||
// background: rgba(12, 49, 110, 0.3); |
// background: rgba(12, 49, 110, 0.3); |
||||
margin-right: 10px; |
margin-right: 10px; |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
.rows { |
.rows { |
||||
.row-item { |
.row-item { |
||||
font-size: 16px; |
font-size: 16px; |
||||
} |
} |
||||
|
|
||||
.row-item:hover { |
.row-item:hover { |
||||
background: linear-gradient(270deg, rgba(17, 183, 247, 0) 0%, rgba(17, 183, 247, 0.85) 100%); |
background: linear-gradient( |
||||
color: #9ac8fc; |
270deg, |
||||
} |
rgba(17, 183, 247, 0) 0%, |
||||
} |
rgba(17, 183, 247, 0.85) 100% |
||||
|
); |
||||
|
color: #9ac8fc; |
||||
|
} |
||||
|
} |
||||
} |
} |
||||
|
|
||||
.scroll-board-multi { |
.scroll-board-multi { |
||||
padding: 5px 0px 5px; |
padding: 5px 0px 5px; |
||||
color: rgba(204, 228, 255, 1) !important; |
color: rgba(204, 228, 255, 1) !important; |
||||
|
|
||||
.header { |
.header { |
||||
display: flex; |
display: flex; |
||||
flex-direction: row; |
flex-direction: row; |
||||
font-size: 12px !important; |
font-size: 12px !important; |
||||
color: rgba(204, 228, 255, 1) !important; |
color: rgba(204, 228, 255, 1) !important; |
||||
// border-bottom: 1px solid #124C79 !important; |
// border-bottom: 1px solid #124C79 !important; |
||||
} |
} |
||||
|
|
||||
.rows { |
.rows { |
||||
color: rgba(204, 228, 255, 1) !important; |
color: rgba(204, 228, 255, 1) !important; |
||||
|
|
||||
.row-item { |
.row-item { |
||||
border-bottom: 1px solid #124C79 !important; |
border-bottom: 1px solid #124c79 !important; |
||||
} |
} |
||||
|
|
||||
.row-item:hover { |
.row-item:hover { |
||||
background: linear-gradient(270deg, rgba(17, 183, 247, 0) 0%, rgba(17, 183, 247, 0.85) 100%); |
background: linear-gradient( |
||||
color: #9ac8fc; |
270deg, |
||||
} |
rgba(17, 183, 247, 0) 0%, |
||||
} |
rgba(17, 183, 247, 0.85) 100% |
||||
|
); |
||||
|
color: #9ac8fc; |
||||
|
} |
||||
|
} |
||||
} |
} |
||||
|
|
||||
._sorrow { |
._sorrow { |
||||
display: inline-block; |
display: inline-block; |
||||
width: 15px; |
width: 15px; |
||||
height: 15px; |
height: 15px; |
||||
background: url('/assets/images/homepage/bigscreen/sorrow.png'); |
background: url("/assets/images/homepage/bigscreen/sorrow.png"); |
||||
background-repeat: no-repeat; |
background-repeat: no-repeat; |
||||
background-size: 100% 100%; |
background-size: 100% 100%; |
||||
margin-left: 13px; |
margin-left: 13px; |
||||
} |
} |
||||
|
|
||||
.subtitle_ { |
.subtitle_ { |
||||
float: right; |
float: right; |
||||
margin-top: 12px; |
margin-top: 12px; |
||||
margin-right: 20px; |
margin-right: 20px; |
||||
width: 200px; |
width: 200px; |
||||
text-align: center; |
text-align: center; |
||||
|
|
||||
._item_select { |
._item_select { |
||||
width: 60px; |
width: 60px; |
||||
height: 20px; |
height: 20px; |
||||
display: inline-block; |
display: inline-block; |
||||
font-size: 14px; |
font-size: 14px; |
||||
color: #24DCF7; |
color: #24dcf7; |
||||
border: 1px solid #12B2E5; |
border: 1px solid #12b2e5; |
||||
background-color: rgba(91, 193, 255, 0.2); |
background-color: rgba(91, 193, 255, 0.2); |
||||
margin-right: 3px; |
margin-right: 3px; |
||||
cursor: pointer; |
cursor: pointer; |
||||
} |
} |
||||
|
|
||||
._item { |
._item { |
||||
width: 60px; |
width: 60px; |
||||
height: 20px; |
height: 20px; |
||||
display: inline-block; |
display: inline-block; |
||||
font-size: 14px; |
font-size: 14px; |
||||
color: #4C9FFF; |
color: #4c9fff; |
||||
border: 1px solid #0B6AEA; |
border: 1px solid #0b6aea; |
||||
background-color: rgba(35, 108, 254, 0.3); |
background-color: rgba(35, 108, 254, 0.3); |
||||
margin-right: 3px; |
margin-right: 3px; |
||||
cursor: pointer; |
cursor: pointer; |
||||
} |
} |
||||
} |
} |
||||
|
|
||||
.children-container { |
.children-container { |
||||
height: calc(100% - 42px); |
height: calc(100% - 42px); |
||||
background-image: linear-gradient(180deg, #04377ecc 1%, #001241 100%); |
// background-image: linear-gradient(180deg, #04377ecc 1%, #001241 100%); |
||||
|
background-image: linear-gradient(180deg, #04377ecc 1%, #001241 100%); |
||||
} |
} |
||||
|
|
||||
.box_header_bg { |
.box_header_bg { |
||||
background: url(/assets/images/homepage/bigscreen/headertitlebg.png) no-repeat; |
background: url(/assets/images/homepage/bigscreen/headertitlebg.png) no-repeat; |
||||
background-size: 100% 100%; |
background-size: 100% 100%; |
||||
height: 42px; |
height: 42px; |
||||
padding-top: 4px; |
padding-top: 4px; |
||||
word-break: keep-all; |
word-break: keep-all; |
||||
white-space: nowrap; |
white-space: nowrap; |
||||
width: 100%; |
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 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'; |
import './style.less'; |
||||
|
|
||||
|
|
||||
function DataTop5(props) { |
const DataTop5 = ({ dispatch, actions }) => { |
||||
|
const [videoList, setVideoList] = useState([]) |
||||
|
const [options, setOptions] = useState([]) |
||||
return <Box title={"视频监控"} bodyPaddingTop={1} > |
const [videoData, setVideoData] = useState({}) |
||||
<div className='video_container'> |
|
||||
<div className='_item'> |
|
||||
<div className='video_bottom'><span>南昌大道</span><span>14:12:32</span></div> |
useEffect(() => { |
||||
</div> |
dispatch(actions.firecontrol.getVideoCenterList()).then(res => { |
||||
<div className='_item'> |
if (res.success) { |
||||
<div className='video_bottom'><span>南昌大道</span><span>11:34:12</span></div> |
setVideoList(res.payload.data || []) |
||||
</div> |
setOptions(res.payload.data?.map(v => ({ value: v.deviceSerial, label: v.deviceName })) || []) |
||||
<div className='_item'> |
setVideoData(res.payload.data[0] || {}) |
||||
<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> |
|
||||
} |
|
||||
|
|
||||
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