diff --git a/api/.vscode/launch.json b/api/.vscode/launch.json index 5433cf2..f675800 100644 --- a/api/.vscode/launch.json +++ b/api/.vscode/launch.json @@ -22,6 +22,8 @@ "-d postgres/example/10.8.30.160/30432", "-w https://smartwater.anxinyun.cn", "-a https://smartworksafety.anxinyun.cn", + "--yingshiKey 5d16a667e1c2423d9d0d634f781810b4", + "--yingshiSecret 0cc4e1ec4e6a53ea3dabeb09cd5f468b", ] }, { diff --git a/api/app/lib/controllers/superScreen/fire.js b/api/app/lib/controllers/superScreen/fire.js index 8bc189a..b9c685a 100644 --- a/api/app/lib/controllers/superScreen/fire.js +++ b/api/app/lib/controllers/superScreen/fire.js @@ -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 } \ No newline at end of file diff --git a/api/app/lib/middlewares/authenticator.js b/api/app/lib/middlewares/authenticator.js index 07df3ec..34f71d4 100644 --- a/api/app/lib/middlewares/authenticator.js +++ b/api/app/lib/middlewares/authenticator.js @@ -61,6 +61,8 @@ let isPathExcluded = function (opts, path, method) { excludeOpts.push({ p: '/logout', o: 'PUT' }); excludeOpts.push({ p: '/water/realstate', o: 'GET' }); excludeOpts.push({ p: '/water/emergency', o: 'GET' }); + excludeOpts.push({ p: '/videoCenter/list', o: 'GET' }); + excludeOpts.push({ p: '/trafficindex/city/details', o: 'GET' }); excludeOpts.push({ p: '/fire/alarm', o: 'GET' }); excludeOpts.push({ p: '/fire/alarm', o: 'POST' }); excludeOpts.push({ p: '/fire/alarm/:id', o: 'PUT' }); diff --git a/api/app/lib/routes/superScreen/fire.js b/api/app/lib/routes/superScreen/fire.js index b134d95..d5dc113 100644 --- a/api/app/lib/routes/superScreen/fire.js +++ b/api/app/lib/routes/superScreen/fire.js @@ -15,4 +15,10 @@ module.exports = function (app, router, opts, AuthCode) { //修改消防告警状态 app.fs.api.logAttr['PUT/fire/alarm/:id'] = { content: '修改消防告警状态', visible: true }; router.put('/fire/alarm/:id', fire.updateAlarm(opts)); + + app.fs.api.logAttr['GET/videoCenter/list'] = { content: '获取萤石设备列表', visible: true }; + router.get('/videoCenter/list', fire.videoList(opts)); + + app.fs.api.logAttr['GET/trafficindex/city/detailst'] = { content: '获取南昌市道路数据', visible: true }; + router.get('/trafficindex/city/details', fire.getDetails(opts)); }; diff --git a/api/config.js b/api/config.js index 155f150..6558ac0 100644 --- a/api/config.js +++ b/api/config.js @@ -16,6 +16,9 @@ args.option(['d', 'dbconfig'], '后台同步数据库host示例:postgres/example args.option(['w', 'water'], '水环境api地址'); args.option(['a', 'worksafety'], '安监api地址'); +args.option('yingshiKey', '萤石 KEY') +args.option('yingshiSecret', '萤石 SECRET') + const flags = args.parse(process.argv); const DB = process.env.GDRC_DB || flags.pg; @@ -33,124 +36,137 @@ const DATABASE_CONFIG = process.env.DATABASE_HOST || flags.dbconfig;//同步数 const WATER_URL = process.env.WATER_URL || flags.water; const WORKSAFETY_URL = process.env.WORKSAFETY_URL || flags.worksafety; +const YINGSHI_KEY = process.env.YINGSHI_KEY || flags.yingshiKey; +const YINGSHI_SECRET = process.env.YINGSHI_SECRET || flags.yingshiSecret; +// 萤石服务的地址 +const YINGSHI_URL = process.env.YINGSHI_URL || flags.yingshiUrl || 'https://open.ys7.com/api'; + if (!DB || !BACKUPS_URL || !KUBESPHERE_URL || !DATABASE_CONFIG || !WATER_URL || !WORKSAFETY_URL) { - console.log('缺少启动参数,异常退出'); - args.showHelp(); - process.exit(-1); + console.log('缺少启动参数,异常退出'); + args.showHelp(); + process.exit(-1); } const product = { - port: flags.port || 8080, - staticDirs: ['static'], - mws: [ - { - entry: require('@fs/attachment').entry, - opts: { - qiniu: { - domain: QINIU_DOMAIN_QNDMN_RESOURCE, - bucket: QINIU_BUCKET_RESOURCE, - accessKey: QINIU_AK, - secretKey: QINIU_SK - }, - maxSize: 104857600, // 100M - } - }, { - entry: require('./app').entry, - opts: { - dev, - exclude: [ - // "*" - ], // 不做认证的路由,也可以使用 exclude: ["*"] 跳过所有路由 - - sms: { - ///阿里云-安心云 - accessKey: 'LTAI5tAFdjz7j38aNF2C9Qe8', - accessSecret: '1trYkmiqfBtvZL6BxkNH2uQcQQPs0S' - }, - email: { - enabled: true, - host: 'smtp.exmail.qq.com', - port: 465, - sender: { - name: '政务数据资源中心', - address: 'fsiot@free-sun.com.cn', - password: 'Fs2689' - } - }, - pssaRequest: [], - backupsUrl: BACKUPS_URL, - k8s: KUBESPHERE_URL, - dbConfig: DATABASE_CONFIG, - - } - }, { - entry: require('./app/lib/middlewares/proxy').entry, - opts: { - host: WATER_URL, - match: /\/_water\//, - } - }, { - entry: require('./app/lib/middlewares/proxy').entry, - opts: { - host: WORKSAFETY_URL, - match: /\/_worksafety\//, - } - } - ], - dc: { - url: DB, - opts: { - pool: { - max: 80, - min: 10, - idle: 10000 + port: flags.port || 8080, + staticDirs: ['static'], + mws: [ + { + entry: require('@fs/attachment').entry, + opts: { + qiniu: { + domain: QINIU_DOMAIN_QNDMN_RESOURCE, + bucket: QINIU_BUCKET_RESOURCE, + accessKey: QINIU_AK, + secretKey: QINIU_SK }, - define: { - freezeTableName: true, // 固定表名 - timestamps: false // 不含列 "createAt"/"updateAt"/"DeleteAt" + maxSize: 104857600, // 100M + } + }, { + entry: require('./app').entry, + opts: { + dev, + yingshiKey: YINGSHI_KEY, + yingshiSecret: YINGSHI_SECRET, + exclude: [ + // "*" + ], // 不做认证的路由,也可以使用 exclude: ["*"] 跳过所有路由 + + sms: { + ///阿里云-安心云 + accessKey: 'LTAI5tAFdjz7j38aNF2C9Qe8', + accessSecret: '1trYkmiqfBtvZL6BxkNH2uQcQQPs0S' }, - timezone: '+08:00', - logging: false - }, - models: [require('./app').models] - }, - logger: { - level: 'info', - json: false, - filename: path.join(__dirname, 'log', 'runtime.log'), - colorize: false, - maxsize: 1024 * 1024 * 5, - rotationFormat: false, - zippedArchive: true, - maxFiles: 10, - prettyPrint: true, - label: '', - timestamp: () => moment().format('YYYY-MM-DD HH:mm:ss.SSS'), - eol: os.EOL, - tailable: true, - depth: null, - showLevel: true, - maxRetries: 1 - } + email: { + enabled: true, + host: 'smtp.exmail.qq.com', + port: 465, + sender: { + name: '政务数据资源中心', + address: 'fsiot@free-sun.com.cn', + password: 'Fs2689' + } + }, + pssaRequest: [ + { + name: 'yingshiRequest', + root: YINGSHI_URL, + params: {} + }, + ], + backupsUrl: BACKUPS_URL, + k8s: KUBESPHERE_URL, + dbConfig: DATABASE_CONFIG, + + } + }, { + entry: require('./app/lib/middlewares/proxy').entry, + opts: { + host: WATER_URL, + match: /\/_water\//, + } + }, { + entry: require('./app/lib/middlewares/proxy').entry, + opts: { + host: WORKSAFETY_URL, + match: /\/_worksafety\//, + } + } + ], + dc: { + url: DB, + opts: { + pool: { + max: 80, + min: 10, + idle: 10000 + }, + define: { + freezeTableName: true, // 固定表名 + timestamps: false // 不含列 "createAt"/"updateAt"/"DeleteAt" + }, + timezone: '+08:00', + logging: false + }, + models: [require('./app').models] + }, + logger: { + level: 'info', + json: false, + filename: path.join(__dirname, 'log', 'runtime.log'), + colorize: false, + maxsize: 1024 * 1024 * 5, + rotationFormat: false, + zippedArchive: true, + maxFiles: 10, + prettyPrint: true, + label: '', + timestamp: () => moment().format('YYYY-MM-DD HH:mm:ss.SSS'), + eol: os.EOL, + tailable: true, + depth: null, + showLevel: true, + maxRetries: 1 + } }; const development = { - port: product.port, - staticDirs: product.staticDirs, - mws: product.mws, - dc: product.dc, - logger: product.logger + port: product.port, + staticDirs: product.staticDirs, + mws: product.mws, + dc: product.dc, + logger: product.logger }; if (dev) { - // mws - for (let mw of development.mws) { - // if (mw.opts.exclude) mw.opts.exclude = ['*']; // 使用 ['*'] 跳过所有路由 - } - // logger - development.logger.filename = path.join(__dirname, 'log', 'development.log'); - development.logger.level = 'debug'; - development.dc.opts.logging = console.log; + // mws + for (let mw of development.mws) { + // if (mw.opts.exclude) mw.opts.exclude = ['*']; // 使用 ['*'] 跳过所有路由 + } + // logger + development.logger.filename = path.join(__dirname, 'log', 'development.log'); + development.logger.level = 'debug'; + development.dc.opts.logging = console.log; } module.exports = dev ? development : product; diff --git a/super-screen/client/assets/images/homepage/bigscreen/background_n.png b/super-screen/client/assets/images/homepage/bigscreen/background_n.png new file mode 100644 index 0000000..0834818 Binary files /dev/null and b/super-screen/client/assets/images/homepage/bigscreen/background_n.png differ diff --git a/super-screen/client/assets/images/homepage/bigscreen/blue.png b/super-screen/client/assets/images/homepage/bigscreen/blue.png new file mode 100644 index 0000000..d9cc7cd Binary files /dev/null and b/super-screen/client/assets/images/homepage/bigscreen/blue.png differ diff --git a/super-screen/client/assets/images/homepage/bigscreen/dateDook.png b/super-screen/client/assets/images/homepage/bigscreen/dateDook.png new file mode 100644 index 0000000..e49d725 Binary files /dev/null and b/super-screen/client/assets/images/homepage/bigscreen/dateDook.png differ diff --git a/super-screen/client/assets/images/homepage/bigscreen/green.png b/super-screen/client/assets/images/homepage/bigscreen/green.png new file mode 100644 index 0000000..d6953f6 Binary files /dev/null and b/super-screen/client/assets/images/homepage/bigscreen/green.png differ diff --git a/super-screen/client/assets/images/homepage/bigscreen/red.png b/super-screen/client/assets/images/homepage/bigscreen/red.png new file mode 100644 index 0000000..e938cbb Binary files /dev/null and b/super-screen/client/assets/images/homepage/bigscreen/red.png differ diff --git a/super-screen/client/assets/images/homepage/bigscreen/seniority.png b/super-screen/client/assets/images/homepage/bigscreen/seniority.png new file mode 100644 index 0000000..3914201 Binary files /dev/null and b/super-screen/client/assets/images/homepage/bigscreen/seniority.png differ diff --git a/super-screen/client/src/components/index.js b/super-screen/client/src/components/index.js index a326c9d..25cfd96 100644 --- a/super-screen/client/src/components/index.js +++ b/super-screen/client/src/components/index.js @@ -6,6 +6,7 @@ import Uploads from './Uploads'; import NoResource from './no-resource'; import ExportAndImport from './export'; import ButtonGroup from './buttonGroup'; +import YSIframePlayer from './ysPlayerIframe'; import UploadLocal from './UploadLocal'; import Box from './public/table-card'; import CarouselList from './public/carousel-list'; @@ -19,6 +20,7 @@ export { ExportAndImport, ButtonGroup, UploadLocal, + YSIframePlayer, Box, CarouselList, NoData, diff --git a/super-screen/client/src/components/public/index.less b/super-screen/client/src/components/public/index.less index 0ebd58b..c71a66e 100644 --- a/super-screen/client/src/components/public/index.less +++ b/super-screen/client/src/components/public/index.less @@ -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%; -} \ No newline at end of file + 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%; +} diff --git a/super-screen/client/src/components/ysPlayerIframe.js b/super-screen/client/src/components/ysPlayerIframe.js new file mode 100644 index 0000000..3d708e0 --- /dev/null +++ b/super-screen/client/src/components/ysPlayerIframe.js @@ -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 ( +
+ + { + videoState && videoState.status == 0 ? +
+ 设备中断,正在处理中... +
+ : '' + } +
+ ) +} + +function mapStateToProps (state) { + const { auth, } = state; + return { + user: auth.user, + }; +} + +export default connect(mapStateToProps)(YSIframePlayer); \ No newline at end of file diff --git a/super-screen/client/src/sections/fire-control/actions/fire.js b/super-screen/client/src/sections/fire-control/actions/fire.js index 3b5b12c..a1296d0 100644 --- a/super-screen/client/src/sections/fire-control/actions/fire.js +++ b/super-screen/client/src/sections/fire-control/actions/fire.js @@ -40,3 +40,27 @@ export function modifyFireAlarm(id, params) { }, }); } + + +export function getVideoCenterList () { + return dispatch => basicAction({ + type: 'get', + dispatch: dispatch, + actionType: 'GET_VIDEO_CENTER_LIST', + url: ApiTable.videoCenterList, + msg: { error: '获取视频中心列表失败' }, + reducer: { name: 'videoCenterList' } + }); +} + +export function getDetails () { + return dispatch => basicAction({ + type: 'get', + dispatch: dispatch, + actionType: 'GET_DETAILS', + url: ApiTable.details, + msg: { error: '获取南昌市道路数据失败' }, + // reducer: { name: 'videoCenterList' } + }); +} + diff --git a/super-screen/client/src/sections/fire-control/components/Right-top2.js b/super-screen/client/src/sections/fire-control/components/Right-top2.js new file mode 100644 index 0000000..7a1adc4 --- /dev/null +++ b/super-screen/client/src/sections/fire-control/components/Right-top2.js @@ -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
+
+
+ 周边路况实时数据 +
+
+ {longitudeLatitude?.longitude ? + <> + {/*
+
+
= 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?.road_network_speed || '--'}
km/h
+
+
+
拥堵距离
+
{traffic?.yongdu_length_4 || '--'}
km
+
+
+
+
+
较10分钟前拥堵趋势:
+
+
+
+ 持平 +
+ +
+
与1设法厕任务v
+ +
+
+
+
路况描述:
+
dewbfdhuihseacf dsjhcf ewdcjaiopsdc op sadc jwe dcfp weopdcf ujew fdc
+ +
*/} + + + + : <> +
+
+ 南昌市
+
NANCHANG CITY
+
+
+
+
+
= 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) ? "严重拥堵" : "" + }
+
路况整体评价
+
+
+
实时拥堵指数
+
+
{traffic?.index || '--'}
+
+ 较上周同期{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)}% +
+ {traffic?.last_index > traffic?.index ? + + : } +
+
+
+
+
+ +
+
+
实时拥堵排行
+
+
{traffic?.rank || '--'}
+
/{traffic?.count || '--'}
+
全国重点城市拥堵排行
+ +
+
+
+
+
+
实时平均速度
+
{traffic?.road_network_speed || '--'}
km/h
+
+
+
实时严重拥堵里程
+
{traffic?.yongdu_length_4 || '--'}
km
+
+
+ +
+
+ +
+
+
近30日最高拥堵指数
+
+
{traffic?.month_max_yongdu_index || '--'}
+
{traffic?.month_max_congest_time} {weeks[traffic?.month_max_week_day]}
+
+
+
+
+ + } + +
+ +
+
+} +function mapStateToProps (state) { + const { auth, global } = state + return { + user: auth.user, + actions: global.actions, + } +} +export default connect(mapStateToProps)(DataTop5); + + diff --git a/super-screen/client/src/sections/fire-control/components/right-bottom.js b/super-screen/client/src/sections/fire-control/components/right-bottom.js index e63c64b..fd753c8 100644 --- a/super-screen/client/src/sections/fire-control/components/right-bottom.js +++ b/super-screen/client/src/sections/fire-control/components/right-bottom.js @@ -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 -
-
-
南昌大道14:12:32
-
-
-
南昌大道11:34:12
-
-
-
南昌大道08:34:12
-
-
-
南昌大道09:12:34
-
-
-
-} +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
+
+
+ 视频监控 +