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", "-d postgres/example/10.8.30.160/30432",
"-w https://smartwater.anxinyun.cn", "-w https://smartwater.anxinyun.cn",
"-a https://smartworksafety.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'; '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
} }

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: '/logout', o: 'PUT' });
excludeOpts.push({ p: '/water/realstate', o: 'GET' }); excludeOpts.push({ p: '/water/realstate', o: 'GET' });
excludeOpts.push({ p: '/water/emergency', 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: 'GET' });
excludeOpts.push({ p: '/fire/alarm', o: 'POST' }); excludeOpts.push({ p: '/fire/alarm', o: 'POST' });
excludeOpts.push({ p: '/fire/alarm/:id', o: 'PUT' }); 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 }; app.fs.api.logAttr['PUT/fire/alarm/:id'] = { content: '修改消防告警状态', visible: true };
router.put('/fire/alarm/:id', fire.updateAlarm(opts)); 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(['w', 'water'], '水环境api地址');
args.option(['a', 'worksafety'], '安监api地址'); args.option(['a', 'worksafety'], '安监api地址');
args.option('yingshiKey', '萤石 KEY')
args.option('yingshiSecret', '萤石 SECRET')
const flags = args.parse(process.argv); const flags = args.parse(process.argv);
const DB = process.env.GDRC_DB || flags.pg; 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 WATER_URL = process.env.WATER_URL || flags.water;
const WORKSAFETY_URL = process.env.WORKSAFETY_URL || flags.worksafety; 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) { if (!DB || !BACKUPS_URL || !KUBESPHERE_URL || !DATABASE_CONFIG || !WATER_URL || !WORKSAFETY_URL) {
console.log('缺少启动参数,异常退出'); console.log('缺少启动参数,异常退出');
args.showHelp(); args.showHelp();
process.exit(-1); process.exit(-1);
} }
const product = { const product = {
port: flags.port || 8080, port: flags.port || 8080,
staticDirs: ['static'], staticDirs: ['static'],
mws: [ mws: [
{ {
entry: require('@fs/attachment').entry, entry: require('@fs/attachment').entry,
opts: { opts: {
qiniu: { qiniu: {
domain: QINIU_DOMAIN_QNDMN_RESOURCE, domain: QINIU_DOMAIN_QNDMN_RESOURCE,
bucket: QINIU_BUCKET_RESOURCE, bucket: QINIU_BUCKET_RESOURCE,
accessKey: QINIU_AK, accessKey: QINIU_AK,
secretKey: QINIU_SK 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
}, },
define: { maxSize: 104857600, // 100M
freezeTableName: true, // 固定表名 }
timestamps: false // 不含列 "createAt"/"updateAt"/"DeleteAt" }, {
entry: require('./app').entry,
opts: {
dev,
yingshiKey: YINGSHI_KEY,
yingshiSecret: YINGSHI_SECRET,
exclude: [
// "*"
], // 不做认证的路由,也可以使用 exclude: ["*"] 跳过所有路由
sms: {
///阿里云-安心云
accessKey: 'LTAI5tAFdjz7j38aNF2C9Qe8',
accessSecret: '1trYkmiqfBtvZL6BxkNH2uQcQQPs0S'
}, },
timezone: '+08:00', email: {
logging: false enabled: true,
}, host: 'smtp.exmail.qq.com',
models: [require('./app').models] port: 465,
}, sender: {
logger: { name: '政务数据资源中心',
level: 'info', address: 'fsiot@free-sun.com.cn',
json: false, password: 'Fs2689'
filename: path.join(__dirname, 'log', 'runtime.log'), }
colorize: false, },
maxsize: 1024 * 1024 * 5, pssaRequest: [
rotationFormat: false, {
zippedArchive: true, name: 'yingshiRequest',
maxFiles: 10, root: YINGSHI_URL,
prettyPrint: true, params: {}
label: '', },
timestamp: () => moment().format('YYYY-MM-DD HH:mm:ss.SSS'), ],
eol: os.EOL, backupsUrl: BACKUPS_URL,
tailable: true, k8s: KUBESPHERE_URL,
depth: null, dbConfig: DATABASE_CONFIG,
showLevel: true,
maxRetries: 1 }
} }, {
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 = { const development = {
port: product.port, port: product.port,
staticDirs: product.staticDirs, staticDirs: product.staticDirs,
mws: product.mws, mws: product.mws,
dc: product.dc, dc: product.dc,
logger: product.logger logger: product.logger
}; };
if (dev) { if (dev) {
// mws // mws
for (let mw of development.mws) { for (let mw of development.mws) {
// if (mw.opts.exclude) mw.opts.exclude = ['*']; // 使用 ['*'] 跳过所有路由 // if (mw.opts.exclude) mw.opts.exclude = ['*']; // 使用 ['*'] 跳过所有路由
} }
// logger // logger
development.logger.filename = path.join(__dirname, 'log', 'development.log'); development.logger.filename = path.join(__dirname, 'log', 'development.log');
development.logger.level = 'debug'; development.logger.level = 'debug';
development.dc.opts.logging = console.log; development.dc.opts.logging = console.log;
} }
module.exports = dev ? development : product; 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 NoResource from './no-resource';
import ExportAndImport from './export'; import ExportAndImport from './export';
import ButtonGroup from './buttonGroup'; import ButtonGroup from './buttonGroup';
import YSIframePlayer from './ysPlayerIframe';
import UploadLocal from './UploadLocal'; import UploadLocal from './UploadLocal';
import Box from './public/table-card'; import Box from './public/table-card';
import CarouselList from './public/carousel-list'; import CarouselList from './public/carousel-list';
@ -19,6 +20,7 @@ export {
ExportAndImport, ExportAndImport,
ButtonGroup, ButtonGroup,
UploadLocal, UploadLocal,
YSIframePlayer,
Box, Box,
CarouselList, CarouselList,
NoData, NoData,

211
super-screen/client/src/components/public/index.less

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

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

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; let map = null;
const tabs = [ const tabs = [
{ name: '应急物资', tab: 'xfyjwz', className: 'emergency_button' }, { name: '应急物资', tab: 'xfyjwz', className: 'emergency_button' },
{ name: '消防救援', tab: 'xfjy', className: 'emergency_button' }, { name: '消防救援', tab: 'xfjy', className: 'emergency_button' },
{ name: '人民武装部', tab: 'rmwzb', className: 'emergency_button' }, { name: '人民武装部', tab: 'rmwzb', className: 'emergency_button' },
{ name: '医疗救援', tab: 'yljy', className: 'emergency_button' }, { name: '医疗救援', tab: 'yljy', className: 'emergency_button' },
{ name: '应急避难场所', tab: 'yjbns', className: 'emergency_button' }, { name: '应急避难场所', tab: 'yjbns', className: 'emergency_button' },
] ]
function Map(props) { function Map (props) {
const { dispatch, actions, emergencyList, propTab } = props; const { dispatch, actions, emergencyList, propTab,setLongitudeLatitude } = props;
const [delay, setDelay] = useState(true) const [delay, setDelay] = useState(true)
const [tab, setTab] = useState('xfyjwz') const [tab, setTab] = useState('xfyjwz')
const [visible, setVisible] = useState(false) const [visible, setVisible] = useState(false)
const [level, setLevel] = useState('I') const [level, setLevel] = useState('I')
const [alarmData, setAlarmData] = useState() const [alarmData, setAlarmData] = useState()
const [locationVisible, setLocationVisible] = useState(false) const [locationVisible, setLocationVisible] = useState(false)
const [location, setLocation] = useState({}) const [location, setLocation] = useState({})
const [alarmList, setAlarmList] = useState() const [alarmList, setAlarmList] = useState()
//查询告警列表数据 //查询告警列表数据
const getData = () => { const getData = () => {
dispatch(actions?.firecontrol?.getFireAlarmList()).then(res => { dispatch(actions?.firecontrol?.getFireAlarmList()).then(res => {
if (res?.payload?.data) { if (res?.payload?.data) {
setAlarmList(res?.payload?.data) setAlarmList(res?.payload?.data)
} }
}) })
} }
// 初始化GIS 组件销毁清空定时器 // 初始化GIS 组件销毁清空定时器
useEffect(() => { useEffect(() => {
loadMap(); loadMap();
getData() getData()
}, []); }, []);
useEffect(() => { useEffect(() => {
if (alarmData) renderAlarmInfowindow(alarmData) if (alarmData) renderAlarmInfowindow(alarmData)
}, [level]) }, [level])
useEffect(() => { useEffect(() => {
if (propTab == 'overview') getData() if (propTab == 'overview') getData()
}, [propTab]) }, [propTab])
const setMapInitFit = () => { const setMapInitFit = () => {
map.setZoom(10.3) map.setZoom(10.3)
map.setCenter([116.054664, 28.538966]) map.setCenter([116.054664, 28.538966])
map.setPitch(22.9) map.setPitch(22.9)
map.setRotation(0) map.setRotation(0)
} }
useEffect(() => { useEffect(() => {
if (!delay && alarmList?.length > 0 && emergencyList['xfjy']) { if (!delay && alarmList?.length > 0 && emergencyList['xfjy']) {
map.clearMap() map.clearMap()
map && renderMarkers() map && renderMarkers()
map && renderAlarms() map && renderAlarms()
setMapInitFit() setMapInitFit()
} }
}, [delay, alarmList, emergencyList]) }, [delay, alarmList, emergencyList])
const renderMarkers = () => { const renderMarkers = () => {
const data = emergencyList['xfjy'] const data = emergencyList['xfjy']
data.map((x, index) => { 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({ var marker = new AMap.Marker({
position: new AMap.LngLat(x.location?.split(',')[0], x.location?.split(',')[1]), position: new AMap.LngLat(x.longitude, x.latitude),
// 将一张图片的地址设置为 icon // 将一张图片的地址设置为 icon
icon: '/assets/images/homepage/fire/rescue_icon.png', icon: '/assets/images/homepage/communtity/markeralarm.png',
// 设置了 icon 以后,设置 icon 的偏移量,以 icon 的 [center bottom] 为原点 // 设置了 icon 以后,设置 icon 的偏移量,以 icon 的 [center bottom] 为原点
offset: new AMap.Pixel(-13, -30), offset: new AMap.Pixel(-13, -30),
zooms: [3, 19], zooms: [3, 19],
zIndex: 12, zIndex: 14,
}); });
marker.setTitle(x.teamName); marker.setTitle(x.location);
map.add(marker); 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(); // var circle = new AMap.Circle({
const pitch = map.getPitch(); // center: [x.longitude, x.latitude],
const center = map.getCenter(); // radius: 5000, //半径
const Rotation = map.getRotation(); // borderWeight: 3,
console.log('zoom' + zoom) // strokeColor: "#AE0000",
console.log('pitch' + pitch) // strokeOpacity: 1,
console.log('center' + center) // strokeWeight: 6,
console.log('Rotation' + Rotation) // strokeOpacity: 0.8,
console.log('e.lnglat' + e.lnglat) // fillOpacity: 0.2,
}) // // strokeStyle: 'dashed',
}; // strokeDasharray: [10, 10],
// // 线样式还支持 'dashed'
const renderAlarms = () => { // fillColor: 'rgba(243, 0, 0, 0.15)',
alarmList // zIndex: 50,
?.filter(s => s.state == 1) // })
?.map((x, index) => {
var marker = new AMap.Marker({ // map.add(circle);
position: new AMap.LngLat(x.longitude, x.latitude),
// 将一张图片的地址设置为 icon let infowindow = new AMap.InfoWindow({
icon: '/assets/images/homepage/communtity/markeralarm.png', isCustom: true, //使用自定义窗体
// 设置了 icon 以后,设置 icon 的偏移量,以 icon 的 [center bottom] 为原点 content: `<div id="map-content" class="fire-gis-infowindow fire-gis-infowindow-alarm">
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">
<div style="height:${360}px;" id="alarmcontentid${x.location}"></div></div>`, <div style="height:${360}px;" id="alarmcontentid${x.location}"></div></div>`,
offset: new AMap.Pixel(233, 260) offset: new AMap.Pixel(233, 260)
}); });
marker.on('click', () => { marker.on('click', () => {
let position = marker.getPosition ? marker.getPosition() : marker.getCenter(); let position = marker.getPosition ? marker.getPosition() : marker.getCenter();
infowindow.open(map, position); infowindow.open(map, position);
map.setCenter(position) map.setCenter(position)
// map.setZoom(17.4) // map.setZoom(17.4)
// map.setPitch(47.30) // map.setPitch(47.30)
// map.setRotation(1.7000) // map.setRotation(1.7000)
setAlarmData(x) setAlarmData(x)
setTimeout(() => { setTimeout(() => {
if (document.getElementById(`alarmcontentid${x.location}`)) { if (document.getElementById(`alarmcontentid${x.location}`)) {
renderAlarmInfowindow(x) renderAlarmInfowindow(x)
} }
}, 50) }, 50)
}) setLongitudeLatitude({ longitude: x.longitude, latitude: x.latitude })
}) })
} })
}
//驾车路线规划
const drawDrivings = (location1, location2, alarmInfo, rescueInfo) => { //驾车路线规划
var driving = new AMap.Driving({}); 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 driving.search(new AMap.LngLat(location1[0], location1[1]), new AMap.LngLat(location2[0], location2[1]), function (status, result) {
if (status === 'complete') { // result 即是对应的驾车导航信息,相关数据结构文档请参考 https://lbs.amap.com/api/javascript-api/reference/route-search#m_DrivingResult
if (result.routes && result.routes.length) { if (status === 'complete') {
// 绘制第一条路线,也可以按需求绘制其它几条路线 if (result.routes && result.routes.length) {
drawRoute(result.routes[0]) // 绘制第一条路线,也可以按需求绘制其它几条路线
drawRoute(result.routes[0])
props.alarmOk({
alarmInfo: { ...alarmInfo, routes: result.routes[0] }, props.alarmOk({
rescueInfo: rescueInfo alarmInfo: { ...alarmInfo, routes: result.routes[0] },
}) rescueInfo: rescueInfo
} })
} else {
} }
}); } else {
// driving.clear() //清除路线 }
} });
// driving.clear() //清除路线
function drawRoute(route) { }
var path = parseRouteToPath(route)
function drawRoute (route) {
var routeLine = new AMap.Polyline({ var path = parseRouteToPath(route)
path: path,
isOutline: true, var routeLine = new AMap.Polyline({
outlineColor: 'rgba(118, 38, 63, 1)', path: path,
borderWeight: 2, isOutline: true,
strokeWeight: 5, outlineColor: 'rgba(118, 38, 63, 1)',
strokeOpacity: 0.9, borderWeight: 2,
strokeColor: 'rgba(118, 38, 63, 1)', strokeWeight: 5,
lineJoin: 'round' strokeOpacity: 0.9,
}) strokeColor: 'rgba(118, 38, 63, 1)',
lineJoin: 'round'
map.add(routeLine); })
// 调整视野达到最佳显示区域 map.add(routeLine);
map.setFitView([routeLine], false, [150, 150, 400, 400])
// setTimeout(() => { // 调整视野达到最佳显示区域
// map.setZoom(map.getZoom() - 1) map.setFitView([routeLine], false, [150, 150, 400, 400])
// }, 1000); // setTimeout(() => {
// map.setZoom(map.getZoom() - 1)
} // }, 1000);
//计算两点距离 }
function computeDis(p1, p2) {
return Math.round(p1.distance(p2)); //计算两点距离
} 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) { // 解析DrivingRoute对象,构造成AMap.Polyline的path参数需要的格式
var path = [] // DrivingResult对象结构参考文档 https://lbs.amap.com/api/javascript-api/reference/route-search#m_DriveRoute
for (var i = 0, l = route.steps.length; i < l; i++) { function parseRouteToPath (route) {
var step = route.steps[i] var path = []
for (var i = 0, l = route.steps.length; i < l; i++) {
for (var j = 0, n = step.path.length; j < n; j++) { var step = route.steps[i]
path.push(step.path[j])
} for (var j = 0, n = step.path.length; j < n; j++) {
} path.push(step.path[j])
return path }
} }
return path
const renderAlarmInfowindow = (x) => { }
return x && render(<div>
<div className='gis_exit' onClick={() => { const renderAlarmInfowindow = (x) => {
map.setCenter([116.054664, 28.538966]) return x && render(<div>
map.setZoom(10.3) <div className='gis_exit' onClick={() => {
map.setPitch(22.9) map.setCenter([116.054664, 28.538966])
map.setRotation(0) map.setZoom(10.3)
map.clearInfoWindow(); 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 style={{ marginTop: 50 }}>
</div> <div className='gis_item'>
<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 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>
</div> </div>
<div className='gis_item'>
<div className='alarm_confirm'> <div className='gis_title'>地址信息</div><div className='gis_text'>
<div className='hande_button' <Tooltip placement="top" title={x?.location}>
onClick={() => { <span style={{ color: '#FFF' }}>{x?.location?.length > 20 ? x?.location?.substring(0, 20) + '...' : x?.location}</span>
map.clearInfoWindow(); </Tooltip>
if (emergencyList['xfjy']?.length > 0) { </div>
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>
</div>, <div className='gis_item'>
document.getElementById(`alarmcontentid${x.location}`)); <div className='gis_title'>警情类型</div><div className='gis_text'>{x?.type}</div>
} </div>
</div>
const renderLeftTop = () => {
return <div className='home_left_add' onClick={() => { setVisible(true) }} /> <div className='alarm_confirm'>
} <div className='hande_button'
onClick={() => {
const onFinish = (values) => { map.clearInfoWindow();
setLocation({}) if (emergencyList['xfjy']?.length > 0) {
const list = emergencyList['xfjy'].sort((b, a) => computeDis(
dispatch(actions.firecontrol.addFireAlarm( new AMap.LngLat(x.longitude, x.latitude),
{ new AMap.LngLat(b.location?.split(',')[0], b.location?.split(',')[1])
...values, ) - computeDis(
state: 1, new AMap.LngLat(x.longitude, x.latitude),
location: location?.location, new AMap.LngLat(a.location?.split(',')[0], a.location?.split(',')[1])
longitude: location?.lnglat?.split(',')[0], ))
latitude: location?.lnglat?.split(',')[1], const location = list[0]?.location
} drawDrivings([x.longitude, x.latitude], location.split(','), x, list[0])
)).then(res => { }
getData() }}
message.success('新增上报信息成功') >一键护航</div>
setVisible(false) </div>
}) </div>,
} document.getElementById(`alarmcontentid${x.location}`));
}
return (
<> const renderLeftTop = () => {
{/* 延缓加载遮罩 */} return <div className='home_left_add' onClick={() => { setVisible(true) }} />
{delay && <div className='map_delay'><div className='delay_img' /></div>} }
{/* 地图容器 */}
<div className="gis" id={MAPDOMID} /> const onFinish = (values) => {
{/* 底部按钮 */} setLocation({})
{props.propTab == 'item' && tabs.map((s, index) => {
return <> dispatch(actions.firecontrol.addFireAlarm(
<div className={s.className ? `${s.className} ${s.className}${index + 1}` : 'water-gis-button' + (index + 1)} {
onClick={() => { ...values,
setTab(s.tab) state: 1,
s.className ? props.changeEmengencyTab(s.tab) : props.changeTab(s.tab) location: location?.location,
if (s.tab == 'emergency') { longitude: location?.lnglat?.split(',')[0],
setTab('yjwz') latitude: location?.lnglat?.split(',')[1],
props.changeEmengencyTab('yjwz') }
} )).then(res => {
}} getData()
> message.success('新增上报信息成功')
<div className={ setVisible(false)
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>} return (
</div> <>
</> {/* 延缓加载遮罩 */}
})} {delay && <div className='map_delay'><div className='delay_img' /></div>}
{/* 左上角图例 */} {/* 地图容器 */}
{props.propTab == 'overview' && renderLeftTop()} <div className="gis" id={MAPDOMID} />
{/* 四周遮罩 */} {/* 底部按钮 */}
<div className='gis-left'></div> {props.propTab == 'item' && tabs.map((s, index) => {
<div className='gis-right'></div> return <>
<div className='gis-top'></div> <div className={s.className ? `${s.className} ${s.className}${index + 1}` : 'water-gis-button' + (index + 1)}
<div className='gis-bottom'></div> onClick={() => {
setTab(s.tab)
{/* 新增告警 */} s.className ? props.changeEmengencyTab(s.tab) : props.changeTab(s.tab)
<FireAddForm if (s.tab == 'emergency') {
visible={visible} setTab('yjwz')
onCancel={() => setVisible(false)} props.changeEmengencyTab('yjwz')
locationClick={() => setLocationVisible(true)} }
location={location} }}
onFinish={onFinish} >
/> <div className={
s.className ? `button_img_${(index + 1)} ${tab == s.tab ? 'button_img_' + (index + 1) + '_select' : ''}` :
{/* 位置选点 */} `button_img ${tab == s.tab ? 'button_img_select' : ''}`} />
<LoacationSelect <div>{s.name}</div>
locationVisible={locationVisible} {s.className && <div className='dotbg'>{emergencyList[s.tab]?.length}</div>}
onCancel={() => setLocationVisible(false)} </div>
locationSelect={(location) => { </>
setLocation(location) })}
setLocationVisible(false) {/* 左上角图例 */}
}} {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); 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 LeftBottom from '../components/left-bottom'
import RightTop from '../components/right-top' import RightTop from '../components/right-top'
import RightMiddle from '../components/right-middle' import RightMiddle from '../components/right-middle'
import RightTop2 from '../components/Right-top2'
import RightBottom from '../components/right-bottom' import RightBottom from '../components/right-bottom'
import Gis from './gis'; import Gis from './gis';
import './style.less' import './style.less'
@ -15,110 +16,116 @@ import Weather from '../../water-prevention/components/weather';
import { FullScreenContainer } from '$components' import { FullScreenContainer } from '$components'
import { useFsRequest } from '$utils'; import { useFsRequest } from '$utils';
function homePage(props) { function homePage (props) {
const { dispatch, actions } = props; const { dispatch, actions } = props;
const childStyle = { height: '32%', color: '#fff', marginBottom: 17 } const childStyle = { height: '32%', color: '#fff', marginBottom: 17 }
const cardHeight = document.body.clientHeight * 0.896 * 0.32 const cardHeight = document.body.clientHeight * 0.896 * 0.32
const cardContentHeight = cardHeight - 42 - 13 const cardContentHeight = cardHeight - 42 - 13
const [tab, setTab] = useState('overview') const [tab, setTab] = useState('overview')
const [emengencyTab, setEmengencyTab] = useState('xfyjwz'); const [emengencyTab, setEmengencyTab] = useState('xfyjwz');
const [alarmInfo, setAlarmInfo] = useState({}) 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 <> const { data: emergencyList = {} } = useFsRequest({ url: 'water/emergency' });
<FullScreenContainer> const endEvent = () => {
<div className='homepage'> dispatch(actions.firecontrol.modifyFireAlarm(
<div className='_title'> alarmInfo?.alarmInfo?.id, { state: 2 }
<div className='_title_text'> )).then(res => {
<span>智慧消防</span> setTab('overview')
<div className='_title_dot'></div> })
<span>一键护航</span> }
</div>
<Weather /> return <>
<div onClick={() => { dispatch(push('/homepage')) }} className='_exit' >返回平台</div> <FullScreenContainer>
</div> <div className='homepage'>
<div className='homepage-left homepage-left-left'> <div className='_title'>
<div div className="list"> <div className='_title_text'>
{tab == 'overview' ? <span>智慧消防</span>
<> <div className='_title_dot'></div>
<div className='child' style={childStyle}> <span>一键护航</span>
<LeftTop emergencyList={emergencyList} /> </div>
</div> <Weather />
<div className='child' style={childStyle}> <div onClick={() => { dispatch(push('/homepage')) }} className='_exit' >返回平台</div>
<LeftMiddle /> </div>
</div> <div className='homepage-left homepage-left-left'>
<div className='child' style={childStyle}> <div div className="list">
<LeftBottom cardContentHeight={cardContentHeight} /> {tab == 'overview' ?
</div> <>
</> <div className='child' style={childStyle}>
: <LeftTop emergencyList={emergencyList} />
<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 />
</div> </div>
<div className='child-right' style={childStyle}> <div className='child' style={childStyle}>
<RightMiddle cardContentHeight={cardContentHeight} /> <LeftMiddle />
</div> </div>
<div className='child-right' style={childStyle}> <div className='child' style={childStyle}>
<RightBottom /> <LeftBottom cardContentHeight={cardContentHeight} />
</div> </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}>
</div> <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 > </div >
</FullScreenContainer> </FullScreenContainer>
</> </>
} }
function mapStateToProps(state) { function mapStateToProps (state) {
const { const {
auth, global auth, global
} = state; } = state;
return { return {
clientHeight: global.clientHeight, clientHeight: global.clientHeight,
actions: global.actions, actions: global.actions,
}; };
} }
export default connect(mapStateToProps)(homePage); export default connect(mapStateToProps)(homePage);

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

@ -134,6 +134,11 @@ export const ApiTable = {
//消防 //消防
getFireAlarmList: 'fire/alarm', getFireAlarmList: 'fire/alarm',
modifyFireAlarm: 'fire/alarm/{id}', modifyFireAlarm: 'fire/alarm/{id}',
//获取摄像头数据
videoCenterList:'videoCenter/list',
details: '/trafficindex/city/details'
}; };
export const RouteTable = { 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_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 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 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 //阿里OSS
const ALI_OSS_ACCESSKEY = process.env.ALI_OSS_ACCESSKEY || flags.aliOssAccessKey; 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; const ALI_OSS_REGION = process.env.ALI_OSS_REGION || flags.aliOssRegion;
if ( if (
!FS_UNIAPP_API !FS_UNIAPP_API
// || !ANXINCLOUD_QINIU_ACCESSKEY // || !ANXINCLOUD_QINIU_ACCESSKEY
// || !ANXINCLOUD_QINIU_SECRETKEY // || !ANXINCLOUD_QINIU_SECRETKEY
// || !ANXINCLOUD_QINIU_BUCKET_RESOURCE // || !ANXINCLOUD_QINIU_BUCKET_RESOURCE
// || !ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE // || !ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE
) { ) {
console.log('缺少启动参数,异常退出'); console.log('缺少启动参数,异常退出');
args.showHelp(); args.showHelp();
process.exit(-1); process.exit(-1);
} }
const product = { const product = {
port: flags.port || 8080, port: flags.port || 8080,
staticDirs: [path.join(__dirname, './client')], staticDirs: [path.join(__dirname, './client')],
mws: [ mws: [
{ {
entry: require('./middlewares/proxy').entry, entry: require('./middlewares/proxy').entry,
opts: { opts: {
host: FS_UNIAPP_API, host: FS_UNIAPP_API,
match: /^\/_api\//, match: /^\/_api\//,
} }
}, },
// { // {
// entry: require('./middlewares/attachment').entry, // entry: require('./middlewares/attachment').entry,
// opts: { // opts: {
// qiniu: { // qiniu: {
// accessKey: ANXINCLOUD_QINIU_ACCESSKEY, // accessKey: ANXINCLOUD_QINIU_ACCESSKEY,
// secretKey: ANXINCLOUD_QINIU_SECRETKEY, // secretKey: ANXINCLOUD_QINIU_SECRETKEY,
// bucket: ANXINCLOUD_QINIU_BUCKET_RESOURCE, // bucket: ANXINCLOUD_QINIU_BUCKET_RESOURCE,
// domain: ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE // domain: ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE
// }, // },
// maxSize: 104857600, // 100M // maxSize: 104857600, // 100M
// uploadPath: 'other' // uploadPath: 'other'
// } // }
// }, // },
{ {
entry: require('./routes').entry, entry: require('./routes').entry,
opts: { opts: {
apiUrl: FS_UNIAPP_API, apiUrl: FS_UNIAPP_API,
staticRoot: './client', staticRoot: './client',
qiniu: { qiniu: {
fetchUrl: '/_file-server', fetchUrl: '/_file-server',
domain: ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE domain: ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE
}, },
aliOss: { aliOss: {
fetchUrl: '/_file-ali-server', fetchUrl: '/_file-ali-server',
accessKey: ALI_OSS_ACCESSKEY, accessKey: ALI_OSS_ACCESSKEY,
secretKey: ALI_OSS_SECRETKET, secretKey: ALI_OSS_SECRETKET,
bucket: ALI_OSS_BUCKET, bucket: ALI_OSS_BUCKET,
region: ALI_OSS_REGION region: ALI_OSS_REGION
}, },
weatherUrl, weatherUrl,
} baiDuAPi: BAIDU_API
}, }
{ },
entry: require('./client').entry,// 静态信息 {
opts: {} entry: require('./client').entry,// 静态信息
} opts: {}
], }
logger: { ],
level: 'debug', logger: {
json: false, level: 'debug',
filename: path.join(__dirname, 'log', 'runtime.txt'), json: false,
colorize: true, filename: path.join(__dirname, 'log', 'runtime.txt'),
maxsize: 1024 * 1024 * 5, colorize: true,
rotationFormat: false, maxsize: 1024 * 1024 * 5,
zippedArchive: true, rotationFormat: false,
maxFiles: 10, zippedArchive: true,
prettyPrint: true, maxFiles: 10,
label: '', prettyPrint: true,
timestamp: () => moment().format('YYYY-MM-DD HH:mm:ss.SSS'), label: '',
eol: os.EOL, timestamp: () => moment().format('YYYY-MM-DD HH:mm:ss.SSS'),
tailable: true, eol: os.EOL,
depth: null, tailable: true,
showLevel: true, depth: null,
maxRetries: 1 showLevel: true,
} maxRetries: 1
}
}; };
if (product.frontParams) { if (product.frontParams) {
const patt = /[^A-Z|_]+/ const patt = /[^A-Z|_]+/
for (let k in product.frontParams) { for (let k in product.frontParams) {
if (!k.startsWith('FS_') || patt.test(k)) { if (!k.startsWith('FS_') || patt.test(k)) {
console.warn(`参数 ${k} 当以大写字母和下划线组成 且以 FS_ 开头`); console.warn(`参数 ${k} 当以大写字母和下划线组成 且以 FS_ 开头`);
process.exit(-1); process.exit(-1);
} }
} }
} }
let config; let config;
if (dev) { if (dev) {
config = { config = {
port: product.port, port: product.port,
staticDirs: product.staticDirs, staticDirs: product.staticDirs,
frontParams: product.frontParams, frontParams: product.frontParams,
mws: product.mws.concat([ mws: product.mws.concat([
{ {
entry: require('./middlewares/webpack-dev').entry, entry: require('./middlewares/webpack-dev').entry,
opts: { opts: {
frontParams: product.frontParams, frontParams: product.frontParams,
}
} }
]), }
logger: product.logger ]),
} logger: product.logger
config.logger.filename = path.join(__dirname, 'log', 'development.txt'); }
config.logger.filename = path.join(__dirname, 'log', 'development.txt');
} else { } else {
config = product; config = product;
} }
module.exports = config;//区分开发和发布 module.exports = config;//区分开发和发布

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

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

Loading…
Cancel
Save