Browse Source

周边路况信息

master
wenlele 1 year ago
parent
commit
460afa8c21
  1. 2
      api/.vscode/launch.json
  2. 229
      api/app/lib/controllers/superScreen/fire.js
  3. 2
      api/app/lib/middlewares/authenticator.js
  4. 6
      api/app/lib/routes/superScreen/fire.js
  5. 228
      api/config.js
  6. BIN
      super-screen/client/assets/images/homepage/bigscreen/background_n.png
  7. BIN
      super-screen/client/assets/images/homepage/bigscreen/blue.png
  8. BIN
      super-screen/client/assets/images/homepage/bigscreen/dateDook.png
  9. BIN
      super-screen/client/assets/images/homepage/bigscreen/green.png
  10. BIN
      super-screen/client/assets/images/homepage/bigscreen/red.png
  11. BIN
      super-screen/client/assets/images/homepage/bigscreen/seniority.png
  12. 2
      super-screen/client/src/components/index.js
  13. 211
      super-screen/client/src/components/public/index.less
  14. 52
      super-screen/client/src/components/ysPlayerIframe.js
  15. 24
      super-screen/client/src/sections/fire-control/actions/fire.js
  16. 209
      super-screen/client/src/sections/fire-control/components/Right-top2.js
  17. 86
      super-screen/client/src/sections/fire-control/components/right-bottom.js
  18. 36
      super-screen/client/src/sections/fire-control/components/style.less
  19. 755
      super-screen/client/src/sections/fire-control/containers/gis.js
  20. 189
      super-screen/client/src/sections/fire-control/containers/homePage.js
  21. 5
      super-screen/client/src/utils/webapi.js
  22. 192
      super-screen/config.js
  23. 1
      super-screen/routes/attachment/index.js

2
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",
]
},
{

229
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
}

2
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' });

6
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));
};

228
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;

BIN
super-screen/client/assets/images/homepage/bigscreen/background_n.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
super-screen/client/assets/images/homepage/bigscreen/blue.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

BIN
super-screen/client/assets/images/homepage/bigscreen/dateDook.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
super-screen/client/assets/images/homepage/bigscreen/green.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

BIN
super-screen/client/assets/images/homepage/bigscreen/red.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
super-screen/client/assets/images/homepage/bigscreen/seniority.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

2
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,

211
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%;
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%;
}

52
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 (
<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);

24
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' }
});
}

209
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 <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);

86
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 <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);

36
super-screen/client/src/sections/fire-control/components/style.less

@ -455,3 +455,39 @@
}
}
}
.bigscreen-select {
.ant-select-selector {
background-color: #24dcf74d !important;
height: 18px !important;
}
.ant-select-focused {
border: 0px;
}
.ant-select-selection-item {
color: #fff;
font-family: YouSheBiaoTiHei;
height: 16px !important;
line-height: 17px !important;
text-align: right;
}
.ant-select-selection-search {
color: #fff;
}
.ant-select-arrow {
color: #fff;
}
.ant-select-selection-item {
background: transparent;
border: 0;
}
.ant-select-multiple,
.ant-select-selection-item-remove {
color: #fff;
}
}

755
super-screen/client/src/sections/fire-control/containers/gis.js

@ -10,394 +10,395 @@ const MAPDOMID = 'fs-amap-container-fire';
let map = null;
const tabs = [
{ name: '应急物资', tab: 'xfyjwz', className: 'emergency_button' },
{ name: '消防救援', tab: 'xfjy', className: 'emergency_button' },
{ name: '人民武装部', tab: 'rmwzb', className: 'emergency_button' },
{ name: '医疗救援', tab: 'yljy', className: 'emergency_button' },
{ name: '应急避难场所', tab: 'yjbns', className: 'emergency_button' },
{ name: '应急物资', tab: 'xfyjwz', className: 'emergency_button' },
{ name: '消防救援', tab: 'xfjy', className: 'emergency_button' },
{ name: '人民武装部', tab: 'rmwzb', className: 'emergency_button' },
{ name: '医疗救援', tab: 'yljy', className: 'emergency_button' },
{ name: '应急避难场所', tab: 'yjbns', className: 'emergency_button' },
]
function Map(props) {
const { dispatch, actions, emergencyList, propTab } = props;
const [delay, setDelay] = useState(true)
const [tab, setTab] = useState('xfyjwz')
const [visible, setVisible] = useState(false)
const [level, setLevel] = useState('I')
const [alarmData, setAlarmData] = useState()
const [locationVisible, setLocationVisible] = useState(false)
const [location, setLocation] = useState({})
const [alarmList, setAlarmList] = useState()
//查询告警列表数据
const getData = () => {
dispatch(actions?.firecontrol?.getFireAlarmList()).then(res => {
if (res?.payload?.data) {
setAlarmList(res?.payload?.data)
}
})
}
// 初始化GIS 组件销毁清空定时器
useEffect(() => {
loadMap();
getData()
}, []);
useEffect(() => {
if (alarmData) renderAlarmInfowindow(alarmData)
}, [level])
useEffect(() => {
if (propTab == 'overview') getData()
}, [propTab])
const setMapInitFit = () => {
map.setZoom(10.3)
map.setCenter([116.054664, 28.538966])
map.setPitch(22.9)
map.setRotation(0)
}
useEffect(() => {
if (!delay && alarmList?.length > 0 && emergencyList['xfjy']) {
map.clearMap()
map && renderMarkers()
map && renderAlarms()
setMapInitFit()
}
}, [delay, alarmList, emergencyList])
const renderMarkers = () => {
const data = emergencyList['xfjy']
data.map((x, index) => {
function Map (props) {
const { dispatch, actions, emergencyList, propTab,setLongitudeLatitude } = props;
const [delay, setDelay] = useState(true)
const [tab, setTab] = useState('xfyjwz')
const [visible, setVisible] = useState(false)
const [level, setLevel] = useState('I')
const [alarmData, setAlarmData] = useState()
const [locationVisible, setLocationVisible] = useState(false)
const [location, setLocation] = useState({})
const [alarmList, setAlarmList] = useState()
//查询告警列表数据
const getData = () => {
dispatch(actions?.firecontrol?.getFireAlarmList()).then(res => {
if (res?.payload?.data) {
setAlarmList(res?.payload?.data)
}
})
}
// 初始化GIS 组件销毁清空定时器
useEffect(() => {
loadMap();
getData()
}, []);
useEffect(() => {
if (alarmData) renderAlarmInfowindow(alarmData)
}, [level])
useEffect(() => {
if (propTab == 'overview') getData()
}, [propTab])
const setMapInitFit = () => {
map.setZoom(10.3)
map.setCenter([116.054664, 28.538966])
map.setPitch(22.9)
map.setRotation(0)
}
useEffect(() => {
if (!delay && alarmList?.length > 0 && emergencyList['xfjy']) {
map.clearMap()
map && renderMarkers()
map && renderAlarms()
setMapInitFit()
}
}, [delay, alarmList, emergencyList])
const renderMarkers = () => {
const data = emergencyList['xfjy']
data.map((x, index) => {
var marker = new AMap.Marker({
position: new AMap.LngLat(x.location?.split(',')[0], x.location?.split(',')[1]),
// 将一张图片的地址设置为 icon
icon: '/assets/images/homepage/fire/rescue_icon.png',
// 设置了 icon 以后,设置 icon 的偏移量,以 icon 的 [center bottom] 为原点
offset: new AMap.Pixel(-13, -30),
zooms: [3, 19],
zIndex: 12,
});
marker.setTitle(x.teamName);
map.add(marker);
marker.setLabel({
zIndex: 13,
direction: 'right',
offset: new AMap.Pixel(-90, -40), //设置文本标注偏移量
content: "<div class='rescu_team_marker'>" + x.teamName + "</div>", //设置文本标注内容
});
})
}
// 地图初始化
const loadMap = () => {
// 图片图层 实现瓦片地图中国地图样式 bounds 第一个点为左下角 第二个点为右上角
const imageLayer = new AMap.ImageLayer({
url: '/assets/images/map.svg',
bounds: new AMap.Bounds(
[115.800221, 28.265659],
[116.334849, 28.973298],
),
zooms: [3, 14],
});
map = new AMap.Map(MAPDOMID, {
center: [116.054664, 28.538966],
zoomEnable: true,
dragEnable: true,
viewMode: '3D',
pitch: 22.9,
labelzIndex: 130,
zoom: 10.3,
cursor: 'pointer',
mapStyle: 'amap://styles/4eb48d1ef0a024c73376fd2256d0b5a5',
layers: [
AMap.createDefaultLayer(),
imageLayer,
],
});
map.on('complete', () => {
// map.setZoom(17.4)
// map.setCenter([115.922069, 28.554867])
// map.setPitch(47.30)
// map.setRotation(1.7000)
setTimeout(() => {
setDelay(false)
}, 1000);
});
map.on('click', (e) => {
if (!e && !e.lnglat) {
return
}
const zoom = map.getZoom();
const pitch = map.getPitch();
const center = map.getCenter();
const Rotation = map.getRotation();
console.log('zoom' + zoom)
console.log('pitch' + pitch)
console.log('center' + center)
console.log('Rotation' + Rotation)
console.log('e.lnglat' + e.lnglat)
})
};
const renderAlarms = () => {
alarmList
?.filter(s => s.state == 1)
?.map((x, index) => {
var marker = new AMap.Marker({
position: new AMap.LngLat(x.location?.split(',')[0], x.location?.split(',')[1]),
// 将一张图片的地址设置为 icon
icon: '/assets/images/homepage/fire/rescue_icon.png',
// 设置了 icon 以后,设置 icon 的偏移量,以 icon 的 [center bottom] 为原点
offset: new AMap.Pixel(-13, -30),
zooms: [3, 19],
zIndex: 12,
position: new AMap.LngLat(x.longitude, x.latitude),
// 将一张图片的地址设置为 icon
icon: '/assets/images/homepage/communtity/markeralarm.png',
// 设置了 icon 以后,设置 icon 的偏移量,以 icon 的 [center bottom] 为原点
offset: new AMap.Pixel(-13, -30),
zooms: [3, 19],
zIndex: 14,
});
marker.setTitle(x.teamName);
marker.setTitle(x.location);
map.add(marker);
marker.setLabel({
zIndex: 13,
direction: 'right',
offset: new AMap.Pixel(-90, -40), //设置文本标注偏移量
content: "<div class='rescu_team_marker'>" + x.teamName + "</div>", //设置文本标注内容
});
})
}
// 地图初始化
const loadMap = () => {
// 图片图层 实现瓦片地图中国地图样式 bounds 第一个点为左下角 第二个点为右上角
const imageLayer = new AMap.ImageLayer({
url: '/assets/images/map.svg',
bounds: new AMap.Bounds(
[115.800221, 28.265659],
[116.334849, 28.973298],
),
zooms: [3, 14],
});
map = new AMap.Map(MAPDOMID, {
center: [116.054664, 28.538966],
zoomEnable: true,
dragEnable: true,
viewMode: '3D',
pitch: 22.9,
labelzIndex: 130,
zoom: 10.3,
cursor: 'pointer',
mapStyle: 'amap://styles/4eb48d1ef0a024c73376fd2256d0b5a5',
layers: [
AMap.createDefaultLayer(),
imageLayer,
],
});
map.on('complete', () => {
// map.setZoom(17.4)
// map.setCenter([115.922069, 28.554867])
// map.setPitch(47.30)
// map.setRotation(1.7000)
setTimeout(() => {
setDelay(false)
}, 1000);
});
map.on('click', (e) => {
if (!e && !e.lnglat) {
return
}
const zoom = map.getZoom();
const pitch = map.getPitch();
const center = map.getCenter();
const Rotation = map.getRotation();
console.log('zoom' + zoom)
console.log('pitch' + pitch)
console.log('center' + center)
console.log('Rotation' + Rotation)
console.log('e.lnglat' + e.lnglat)
})
};
const renderAlarms = () => {
alarmList
?.filter(s => s.state == 1)
?.map((x, index) => {
var marker = new AMap.Marker({
position: new AMap.LngLat(x.longitude, x.latitude),
// 将一张图片的地址设置为 icon
icon: '/assets/images/homepage/communtity/markeralarm.png',
// 设置了 icon 以后,设置 icon 的偏移量,以 icon 的 [center bottom] 为原点
offset: new AMap.Pixel(-13, -30),
zooms: [3, 19],
zIndex: 14,
});
marker.setTitle(x.location);
map.add(marker);
// var circle = new AMap.Circle({
// center: [x.longitude, x.latitude],
// radius: 5000, //半径
// borderWeight: 3,
// strokeColor: "#AE0000",
// strokeOpacity: 1,
// strokeWeight: 6,
// strokeOpacity: 0.8,
// fillOpacity: 0.2,
// // strokeStyle: 'dashed',
// strokeDasharray: [10, 10],
// // 线样式还支持 'dashed'
// fillColor: 'rgba(243, 0, 0, 0.15)',
// zIndex: 50,
// })
// map.add(circle);
let infowindow = new AMap.InfoWindow({
isCustom: true, //使用自定义窗体
content: `<div id="map-content" class="fire-gis-infowindow fire-gis-infowindow-alarm">
// var circle = new AMap.Circle({
// center: [x.longitude, x.latitude],
// radius: 5000, //半径
// borderWeight: 3,
// strokeColor: "#AE0000",
// strokeOpacity: 1,
// strokeWeight: 6,
// strokeOpacity: 0.8,
// fillOpacity: 0.2,
// // strokeStyle: 'dashed',
// strokeDasharray: [10, 10],
// // 线样式还支持 'dashed'
// fillColor: 'rgba(243, 0, 0, 0.15)',
// zIndex: 50,
// })
// map.add(circle);
let infowindow = new AMap.InfoWindow({
isCustom: true, //使用自定义窗体
content: `<div id="map-content" class="fire-gis-infowindow fire-gis-infowindow-alarm">
<div style="height:${360}px;" id="alarmcontentid${x.location}"></div></div>`,
offset: new AMap.Pixel(233, 260)
});
marker.on('click', () => {
let position = marker.getPosition ? marker.getPosition() : marker.getCenter();
infowindow.open(map, position);
map.setCenter(position)
// map.setZoom(17.4)
// map.setPitch(47.30)
// map.setRotation(1.7000)
setAlarmData(x)
setTimeout(() => {
if (document.getElementById(`alarmcontentid${x.location}`)) {
renderAlarmInfowindow(x)
}
}, 50)
})
offset: new AMap.Pixel(233, 260)
});
marker.on('click', () => {
let position = marker.getPosition ? marker.getPosition() : marker.getCenter();
infowindow.open(map, position);
map.setCenter(position)
// map.setZoom(17.4)
// map.setPitch(47.30)
// map.setRotation(1.7000)
setAlarmData(x)
setTimeout(() => {
if (document.getElementById(`alarmcontentid${x.location}`)) {
renderAlarmInfowindow(x)
}
}, 50)
setLongitudeLatitude({ longitude: x.longitude, latitude: x.latitude })
})
}
//驾车路线规划
const drawDrivings = (location1, location2, alarmInfo, rescueInfo) => {
var driving = new AMap.Driving({});
// 根据起终点经纬度规划驾车导航路线
driving.search(new AMap.LngLat(location1[0], location1[1]), new AMap.LngLat(location2[0], location2[1]), function (status, result) {
// result 即是对应的驾车导航信息,相关数据结构文档请参考 https://lbs.amap.com/api/javascript-api/reference/route-search#m_DrivingResult
if (status === 'complete') {
if (result.routes && result.routes.length) {
// 绘制第一条路线,也可以按需求绘制其它几条路线
drawRoute(result.routes[0])
props.alarmOk({
alarmInfo: { ...alarmInfo, routes: result.routes[0] },
rescueInfo: rescueInfo
})
}
} else {
})
}
//驾车路线规划
const drawDrivings = (location1, location2, alarmInfo, rescueInfo) => {
var driving = new AMap.Driving({});
// 根据起终点经纬度规划驾车导航路线
driving.search(new AMap.LngLat(location1[0], location1[1]), new AMap.LngLat(location2[0], location2[1]), function (status, result) {
// result 即是对应的驾车导航信息,相关数据结构文档请参考 https://lbs.amap.com/api/javascript-api/reference/route-search#m_DrivingResult
if (status === 'complete') {
if (result.routes && result.routes.length) {
// 绘制第一条路线,也可以按需求绘制其它几条路线
drawRoute(result.routes[0])
props.alarmOk({
alarmInfo: { ...alarmInfo, routes: result.routes[0] },
rescueInfo: rescueInfo
})
}
});
// driving.clear() //清除路线
}
function drawRoute(route) {
var path = parseRouteToPath(route)
var routeLine = new AMap.Polyline({
path: path,
isOutline: true,
outlineColor: 'rgba(118, 38, 63, 1)',
borderWeight: 2,
strokeWeight: 5,
strokeOpacity: 0.9,
strokeColor: 'rgba(118, 38, 63, 1)',
lineJoin: 'round'
})
map.add(routeLine);
// 调整视野达到最佳显示区域
map.setFitView([routeLine], false, [150, 150, 400, 400])
// setTimeout(() => {
// map.setZoom(map.getZoom() - 1)
// }, 1000);
}
//计算两点距离
function computeDis(p1, p2) {
return Math.round(p1.distance(p2));
}
// 解析DrivingRoute对象,构造成AMap.Polyline的path参数需要的格式
// DrivingResult对象结构参考文档 https://lbs.amap.com/api/javascript-api/reference/route-search#m_DriveRoute
function parseRouteToPath(route) {
var path = []
for (var i = 0, l = route.steps.length; i < l; i++) {
var step = route.steps[i]
for (var j = 0, n = step.path.length; j < n; j++) {
path.push(step.path[j])
}
}
return path
}
const renderAlarmInfowindow = (x) => {
return x && render(<div>
<div className='gis_exit' onClick={() => {
map.setCenter([116.054664, 28.538966])
map.setZoom(10.3)
map.setPitch(22.9)
map.setRotation(0)
map.clearInfoWindow();
}} />
<div style={{ marginTop: 50 }}>
<div className='gis_item'>
<div className='gis_title'>事件时间</div><div className='gis_text'>{moment(x?.createTime).format('YYYY-MM-DD HH:mm:ss')}</div>
</div>
<div className='gis_item'>
<div className='gis_title'>地址信息</div><div className='gis_text'>
<Tooltip placement="top" title={x?.location}>
<span style={{ color: '#FFF' }}>{x?.location?.length > 20 ? x?.location?.substring(0, 20) + '...' : x?.location}</span>
</Tooltip>
</div>
</div>
<div className='gis_item'>
<div className='gis_title'>警情类型</div><div className='gis_text'>{x?.type}</div>
</div>
} else {
}
});
// driving.clear() //清除路线
}
function drawRoute (route) {
var path = parseRouteToPath(route)
var routeLine = new AMap.Polyline({
path: path,
isOutline: true,
outlineColor: 'rgba(118, 38, 63, 1)',
borderWeight: 2,
strokeWeight: 5,
strokeOpacity: 0.9,
strokeColor: 'rgba(118, 38, 63, 1)',
lineJoin: 'round'
})
map.add(routeLine);
// 调整视野达到最佳显示区域
map.setFitView([routeLine], false, [150, 150, 400, 400])
// setTimeout(() => {
// map.setZoom(map.getZoom() - 1)
// }, 1000);
}
//计算两点距离
function computeDis (p1, p2) {
return Math.round(p1.distance(p2));
}
// 解析DrivingRoute对象,构造成AMap.Polyline的path参数需要的格式
// DrivingResult对象结构参考文档 https://lbs.amap.com/api/javascript-api/reference/route-search#m_DriveRoute
function parseRouteToPath (route) {
var path = []
for (var i = 0, l = route.steps.length; i < l; i++) {
var step = route.steps[i]
for (var j = 0, n = step.path.length; j < n; j++) {
path.push(step.path[j])
}
}
return path
}
const renderAlarmInfowindow = (x) => {
return x && render(<div>
<div className='gis_exit' onClick={() => {
map.setCenter([116.054664, 28.538966])
map.setZoom(10.3)
map.setPitch(22.9)
map.setRotation(0)
map.clearInfoWindow();
}} />
<div style={{ marginTop: 50 }}>
<div className='gis_item'>
<div className='gis_title'>事件时间</div><div className='gis_text'>{moment(x?.createTime).format('YYYY-MM-DD HH:mm:ss')}</div>
</div>
<div className='alarm_confirm'>
<div className='hande_button'
onClick={() => {
map.clearInfoWindow();
if (emergencyList['xfjy']?.length > 0) {
const list = emergencyList['xfjy'].sort((b, a) => computeDis(
new AMap.LngLat(x.longitude, x.latitude),
new AMap.LngLat(b.location?.split(',')[0], b.location?.split(',')[1])
) - computeDis(
new AMap.LngLat(x.longitude, x.latitude),
new AMap.LngLat(a.location?.split(',')[0], a.location?.split(',')[1])
))
const location = list[0]?.location
drawDrivings([x.longitude, x.latitude], location.split(','), x, list[0])
}
}}
>一键护航</div>
<div className='gis_item'>
<div className='gis_title'>地址信息</div><div className='gis_text'>
<Tooltip placement="top" title={x?.location}>
<span style={{ color: '#FFF' }}>{x?.location?.length > 20 ? x?.location?.substring(0, 20) + '...' : x?.location}</span>
</Tooltip>
</div>
</div>
</div>,
document.getElementById(`alarmcontentid${x.location}`));
}
const renderLeftTop = () => {
return <div className='home_left_add' onClick={() => { setVisible(true) }} />
}
const onFinish = (values) => {
setLocation({})
dispatch(actions.firecontrol.addFireAlarm(
{
...values,
state: 1,
location: location?.location,
longitude: location?.lnglat?.split(',')[0],
latitude: location?.lnglat?.split(',')[1],
}
)).then(res => {
getData()
message.success('新增上报信息成功')
setVisible(false)
})
}
return (
<>
{/* 延缓加载遮罩 */}
{delay && <div className='map_delay'><div className='delay_img' /></div>}
{/* 地图容器 */}
<div className="gis" id={MAPDOMID} />
{/* 底部按钮 */}
{props.propTab == 'item' && tabs.map((s, index) => {
return <>
<div className={s.className ? `${s.className} ${s.className}${index + 1}` : 'water-gis-button' + (index + 1)}
onClick={() => {
setTab(s.tab)
s.className ? props.changeEmengencyTab(s.tab) : props.changeTab(s.tab)
if (s.tab == 'emergency') {
setTab('yjwz')
props.changeEmengencyTab('yjwz')
}
}}
>
<div className={
s.className ? `button_img_${(index + 1)} ${tab == s.tab ? 'button_img_' + (index + 1) + '_select' : ''}` :
`button_img ${tab == s.tab ? 'button_img_select' : ''}`} />
<div>{s.name}</div>
{s.className && <div className='dotbg'>{emergencyList[s.tab]?.length}</div>}
</div>
</>
})}
{/* 左上角图例 */}
{props.propTab == 'overview' && renderLeftTop()}
{/* 四周遮罩 */}
<div className='gis-left'></div>
<div className='gis-right'></div>
<div className='gis-top'></div>
<div className='gis-bottom'></div>
{/* 新增告警 */}
<FireAddForm
visible={visible}
onCancel={() => setVisible(false)}
locationClick={() => setLocationVisible(true)}
location={location}
onFinish={onFinish}
/>
{/* 位置选点 */}
<LoacationSelect
locationVisible={locationVisible}
onCancel={() => setLocationVisible(false)}
locationSelect={(location) => {
setLocation(location)
setLocationVisible(false)
}}
/>
</>
);
<div className='gis_item'>
<div className='gis_title'>警情类型</div><div className='gis_text'>{x?.type}</div>
</div>
</div>
<div className='alarm_confirm'>
<div className='hande_button'
onClick={() => {
map.clearInfoWindow();
if (emergencyList['xfjy']?.length > 0) {
const list = emergencyList['xfjy'].sort((b, a) => computeDis(
new AMap.LngLat(x.longitude, x.latitude),
new AMap.LngLat(b.location?.split(',')[0], b.location?.split(',')[1])
) - computeDis(
new AMap.LngLat(x.longitude, x.latitude),
new AMap.LngLat(a.location?.split(',')[0], a.location?.split(',')[1])
))
const location = list[0]?.location
drawDrivings([x.longitude, x.latitude], location.split(','), x, list[0])
}
}}
>一键护航</div>
</div>
</div>,
document.getElementById(`alarmcontentid${x.location}`));
}
const renderLeftTop = () => {
return <div className='home_left_add' onClick={() => { setVisible(true) }} />
}
const onFinish = (values) => {
setLocation({})
dispatch(actions.firecontrol.addFireAlarm(
{
...values,
state: 1,
location: location?.location,
longitude: location?.lnglat?.split(',')[0],
latitude: location?.lnglat?.split(',')[1],
}
)).then(res => {
getData()
message.success('新增上报信息成功')
setVisible(false)
})
}
return (
<>
{/* 延缓加载遮罩 */}
{delay && <div className='map_delay'><div className='delay_img' /></div>}
{/* 地图容器 */}
<div className="gis" id={MAPDOMID} />
{/* 底部按钮 */}
{props.propTab == 'item' && tabs.map((s, index) => {
return <>
<div className={s.className ? `${s.className} ${s.className}${index + 1}` : 'water-gis-button' + (index + 1)}
onClick={() => {
setTab(s.tab)
s.className ? props.changeEmengencyTab(s.tab) : props.changeTab(s.tab)
if (s.tab == 'emergency') {
setTab('yjwz')
props.changeEmengencyTab('yjwz')
}
}}
>
<div className={
s.className ? `button_img_${(index + 1)} ${tab == s.tab ? 'button_img_' + (index + 1) + '_select' : ''}` :
`button_img ${tab == s.tab ? 'button_img_select' : ''}`} />
<div>{s.name}</div>
{s.className && <div className='dotbg'>{emergencyList[s.tab]?.length}</div>}
</div>
</>
})}
{/* 左上角图例 */}
{props.propTab == 'overview' && renderLeftTop()}
{/* 四周遮罩 */}
<div className='gis-left'></div>
<div className='gis-right'></div>
<div className='gis-top'></div>
<div className='gis-bottom'></div>
{/* 新增告警 */}
<FireAddForm
visible={visible}
onCancel={() => setVisible(false)}
locationClick={() => setLocationVisible(true)}
location={location}
onFinish={onFinish}
/>
{/* 位置选点 */}
<LoacationSelect
locationVisible={locationVisible}
onCancel={() => setLocationVisible(false)}
locationSelect={(location) => {
setLocation(location)
setLocationVisible(false)
}}
/>
</>
);
}
export default connect()(Map);

189
super-screen/client/src/sections/fire-control/containers/homePage.js

@ -8,6 +8,7 @@ import LeftMiddle from '../components/left-middle'
import LeftBottom from '../components/left-bottom'
import RightTop from '../components/right-top'
import RightMiddle from '../components/right-middle'
import RightTop2 from '../components/Right-top2'
import RightBottom from '../components/right-bottom'
import Gis from './gis';
import './style.less'
@ -15,110 +16,116 @@ import Weather from '../../water-prevention/components/weather';
import { FullScreenContainer } from '$components'
import { useFsRequest } from '$utils';
function homePage(props) {
const { dispatch, actions } = props;
const childStyle = { height: '32%', color: '#fff', marginBottom: 17 }
const cardHeight = document.body.clientHeight * 0.896 * 0.32
const cardContentHeight = cardHeight - 42 - 13
const [tab, setTab] = useState('overview')
const [emengencyTab, setEmengencyTab] = useState('xfyjwz');
const [alarmInfo, setAlarmInfo] = useState({})
function homePage (props) {
const { dispatch, actions } = props;
const childStyle = { height: '32%', color: '#fff', marginBottom: 17 }
const cardHeight = document.body.clientHeight * 0.896 * 0.32
const cardContentHeight = cardHeight - 42 - 13
const [tab, setTab] = useState('overview')
const [emengencyTab, setEmengencyTab] = useState('xfyjwz');
const [alarmInfo, setAlarmInfo] = useState({})
const [longitudeLatitude, setLongitudeLatitude] = useState({})
const { data: emergencyList = {} } = useFsRequest({ url: 'water/emergency' });
const endEvent = () => {
dispatch(actions.firecontrol.modifyFireAlarm(
alarmInfo?.alarmInfo?.id, { state: 2 }
)).then(res => {
setTab('overview')
})
}
return <>
<FullScreenContainer>
<div className='homepage'>
<div className='_title'>
<div className='_title_text'>
<span>智慧消防</span>
<div className='_title_dot'></div>
<span>一键护航</span>
</div>
<Weather />
<div onClick={() => { dispatch(push('/homepage')) }} className='_exit' >返回平台</div>
</div>
<div className='homepage-left homepage-left-left'>
<div div className="list">
{tab == 'overview' ?
<>
<div className='child' style={childStyle}>
<LeftTop emergencyList={emergencyList} />
</div>
<div className='child' style={childStyle}>
<LeftMiddle />
</div>
<div className='child' style={childStyle}>
<LeftBottom cardContentHeight={cardContentHeight} />
</div>
</>
:
<div className='child' style={{ height: '100%' }} >
<Left
info={alarmInfo}
endEvent={() => { endEvent() }}
cardContentHeight={document.body.clientHeight * 0.896} />
</div>
}
</div>
</div>
<div className='homepage-center'>
<Gis
emergencyList={emergencyList}
dispatch={dispatch}
actions={actions}
propTab={tab}
alarmOk={(info) => {
setTab('item')
setAlarmInfo(info);
}}
changeEmengencyTab={(e) => {
setEmengencyTab(e)
}}
/>
</div>
<div className='homepage-left homepage-left-right'>
{tab == 'overview' ? <div className="list">
<div className='child-right' style={childStyle}>
<RightTop />
const { data: emergencyList = {} } = useFsRequest({ url: 'water/emergency' });
const endEvent = () => {
dispatch(actions.firecontrol.modifyFireAlarm(
alarmInfo?.alarmInfo?.id, { state: 2 }
)).then(res => {
setTab('overview')
})
}
return <>
<FullScreenContainer>
<div className='homepage'>
<div className='_title'>
<div className='_title_text'>
<span>智慧消防</span>
<div className='_title_dot'></div>
<span>一键护航</span>
</div>
<Weather />
<div onClick={() => { dispatch(push('/homepage')) }} className='_exit' >返回平台</div>
</div>
<div className='homepage-left homepage-left-left'>
<div div className="list">
{tab == 'overview' ?
<>
<div className='child' style={childStyle}>
<LeftTop emergencyList={emergencyList} />
</div>
<div className='child-right' style={childStyle}>
<RightMiddle cardContentHeight={cardContentHeight} />
<div className='child' style={childStyle}>
<LeftMiddle />
</div>
<div className='child-right' style={childStyle}>
<RightBottom />
<div className='child' style={childStyle}>
<LeftBottom cardContentHeight={cardContentHeight} />
</div>
</div> :
<div className='child' style={{ height: '100%' }} >
<Right emergencyList={emergencyList} emengencyTab={emengencyTab} cardContentHeight={document.body.clientHeight * 0.896} />
</>
:
<div className='child' style={{ height: '100%' }} >
<Left
info={alarmInfo}
endEvent={() => { endEvent() }}
cardContentHeight={document.body.clientHeight * 0.896} />
</div>
}
</div>
</div>
<div className='homepage-center'>
<Gis
emergencyList={emergencyList}
dispatch={dispatch}
actions={actions}
setLongitudeLatitude={setLongitudeLatitude}
propTab={tab}
alarmOk={(info) => {
setTab('item')
setAlarmInfo(info);
}}
changeEmengencyTab={(e) => {
setEmengencyTab(e)
}}
/>
</div>
<div className='homepage-left homepage-left-right'>
{tab == 'overview' ? <div className="list">
{/* <div className='child-right' style={childStyle}>
<RightTop />
</div>
}
</div>
<div className='child-right' style={childStyle}>
<RightMiddle cardContentHeight={cardContentHeight} />
</div> */}
<div className='child-right' style={{ height: 'calc(64% + 17px)', color: '#fff', marginBottom: 17 }}>
<RightTop2 longitudeLatitude={longitudeLatitude} />
</div>
<div className='child-right' style={childStyle}>
<RightBottom />
</div>
</div> :
<div className='child' style={{ height: '100%' }} >
<Right emergencyList={emergencyList} emengencyTab={emengencyTab} cardContentHeight={document.body.clientHeight * 0.896} />
</div>
}
</div>
</div >
</FullScreenContainer>
</div >
</FullScreenContainer>
</>
</>
}
function mapStateToProps(state) {
const {
auth, global
} = state;
return {
clientHeight: global.clientHeight,
actions: global.actions,
function mapStateToProps (state) {
const {
auth, global
} = state;
return {
clientHeight: global.clientHeight,
actions: global.actions,
};
};
}
export default connect(mapStateToProps)(homePage);

5
super-screen/client/src/utils/webapi.js

@ -134,6 +134,11 @@ export const ApiTable = {
//消防
getFireAlarmList: 'fire/alarm',
modifyFireAlarm: 'fire/alarm/{id}',
//获取摄像头数据
videoCenterList:'videoCenter/list',
details: '/trafficindex/city/details'
};
export const RouteTable = {

192
super-screen/config.js

@ -27,6 +27,7 @@ const ANXINCLOUD_QINIU_SECRETKEY = process.env.ANXINCLOUD_QINIU_SECRETKEY || fla
const ANXINCLOUD_QINIU_BUCKET_RESOURCE = process.env.ANXINCLOUD_QINIU_BUCKET_RESOURCE || flags.qnbkt;
const ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE = process.env.ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE || flags.qndmn;
const weatherUrl = process.env.ANXINCLOUD_WEATHERAPP_API || "https://weatherssj.anxinyun.cn/weatherApp/weather/getImmeData"
const BAIDU_API = process.env.BAIDU_API || "https://jiaotong.baidu.com"
//阿里OSS
const ALI_OSS_ACCESSKEY = process.env.ALI_OSS_ACCESSKEY || flags.aliOssAccessKey;
@ -35,113 +36,114 @@ const ALI_OSS_BUCKET = process.env.ALI_OSS_BUCKET || flags.aliOssBucket;
const ALI_OSS_REGION = process.env.ALI_OSS_REGION || flags.aliOssRegion;
if (
!FS_UNIAPP_API
// || !ANXINCLOUD_QINIU_ACCESSKEY
// || !ANXINCLOUD_QINIU_SECRETKEY
// || !ANXINCLOUD_QINIU_BUCKET_RESOURCE
// || !ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE
!FS_UNIAPP_API
// || !ANXINCLOUD_QINIU_ACCESSKEY
// || !ANXINCLOUD_QINIU_SECRETKEY
// || !ANXINCLOUD_QINIU_BUCKET_RESOURCE
// || !ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE
) {
console.log('缺少启动参数,异常退出');
args.showHelp();
process.exit(-1);
console.log('缺少启动参数,异常退出');
args.showHelp();
process.exit(-1);
}
const product = {
port: flags.port || 8080,
staticDirs: [path.join(__dirname, './client')],
mws: [
{
entry: require('./middlewares/proxy').entry,
opts: {
host: FS_UNIAPP_API,
match: /^\/_api\//,
}
},
// {
// entry: require('./middlewares/attachment').entry,
// opts: {
// qiniu: {
// accessKey: ANXINCLOUD_QINIU_ACCESSKEY,
// secretKey: ANXINCLOUD_QINIU_SECRETKEY,
// bucket: ANXINCLOUD_QINIU_BUCKET_RESOURCE,
// domain: ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE
// },
// maxSize: 104857600, // 100M
// uploadPath: 'other'
// }
// },
{
entry: require('./routes').entry,
opts: {
apiUrl: FS_UNIAPP_API,
staticRoot: './client',
qiniu: {
fetchUrl: '/_file-server',
domain: ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE
},
aliOss: {
fetchUrl: '/_file-ali-server',
accessKey: ALI_OSS_ACCESSKEY,
secretKey: ALI_OSS_SECRETKET,
bucket: ALI_OSS_BUCKET,
region: ALI_OSS_REGION
},
weatherUrl,
}
},
{
entry: require('./client').entry,// 静态信息
opts: {}
}
],
logger: {
level: 'debug',
json: false,
filename: path.join(__dirname, 'log', 'runtime.txt'),
colorize: true,
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
}
port: flags.port || 8080,
staticDirs: [path.join(__dirname, './client')],
mws: [
{
entry: require('./middlewares/proxy').entry,
opts: {
host: FS_UNIAPP_API,
match: /^\/_api\//,
}
},
// {
// entry: require('./middlewares/attachment').entry,
// opts: {
// qiniu: {
// accessKey: ANXINCLOUD_QINIU_ACCESSKEY,
// secretKey: ANXINCLOUD_QINIU_SECRETKEY,
// bucket: ANXINCLOUD_QINIU_BUCKET_RESOURCE,
// domain: ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE
// },
// maxSize: 104857600, // 100M
// uploadPath: 'other'
// }
// },
{
entry: require('./routes').entry,
opts: {
apiUrl: FS_UNIAPP_API,
staticRoot: './client',
qiniu: {
fetchUrl: '/_file-server',
domain: ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE
},
aliOss: {
fetchUrl: '/_file-ali-server',
accessKey: ALI_OSS_ACCESSKEY,
secretKey: ALI_OSS_SECRETKET,
bucket: ALI_OSS_BUCKET,
region: ALI_OSS_REGION
},
weatherUrl,
baiDuAPi: BAIDU_API
}
},
{
entry: require('./client').entry,// 静态信息
opts: {}
}
],
logger: {
level: 'debug',
json: false,
filename: path.join(__dirname, 'log', 'runtime.txt'),
colorize: true,
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
}
};
if (product.frontParams) {
const patt = /[^A-Z|_]+/
for (let k in product.frontParams) {
if (!k.startsWith('FS_') || patt.test(k)) {
console.warn(`参数 ${k} 当以大写字母和下划线组成 且以 FS_ 开头`);
process.exit(-1);
}
}
const patt = /[^A-Z|_]+/
for (let k in product.frontParams) {
if (!k.startsWith('FS_') || patt.test(k)) {
console.warn(`参数 ${k} 当以大写字母和下划线组成 且以 FS_ 开头`);
process.exit(-1);
}
}
}
let config;
if (dev) {
config = {
port: product.port,
staticDirs: product.staticDirs,
frontParams: product.frontParams,
mws: product.mws.concat([
{
entry: require('./middlewares/webpack-dev').entry,
opts: {
frontParams: product.frontParams,
}
config = {
port: product.port,
staticDirs: product.staticDirs,
frontParams: product.frontParams,
mws: product.mws.concat([
{
entry: require('./middlewares/webpack-dev').entry,
opts: {
frontParams: product.frontParams,
}
]),
logger: product.logger
}
config.logger.filename = path.join(__dirname, 'log', 'development.txt');
}
]),
logger: product.logger
}
config.logger.filename = path.join(__dirname, 'log', 'development.txt');
} else {
config = product;
config = product;
}
module.exports = config;//区分开发和发布

1
super-screen/routes/attachment/index.js

@ -229,7 +229,6 @@ module.exports = {
}
}
router.use(download_);
router.post('/_upload/new', upload);
router.delete('/_upload/cleanup', remove);

Loading…
Cancel
Save