Browse Source

(*)水利平台增加数据缓存

master
peng.peng 12 months ago
parent
commit
33372daa62
  1. 2
      api/.vscode/launch.json
  2. 23
      api/app/lib/controllers/superScreen/water.js
  3. 2
      api/app/lib/middlewares/authenticator.js
  4. 38
      api/app/lib/middlewares/water.js
  5. 4
      api/app/lib/routes/superScreen/water.js
  6. 69
      api/app/lib/utils/waterCache.js
  7. 33
      api/app/lib/utils/waterReq.js
  8. 7
      api/config.js
  9. 52
      super-screen/client/src/sections/water-prevention/actions/waterconservancy.js
  10. 5
      super-screen/client/src/sections/water-prevention/components/right-bottom.js
  11. 31
      super-screen/client/src/sections/water-prevention/containers/gis.js
  12. 24
      super-screen/client/src/sections/water-prevention/containers/homePage.js
  13. 15
      super-screen/client/src/utils/webapi.js

2
api/.vscode/launch.json

@ -20,7 +20,7 @@
"-b http://10.8.30.161:31420",
"-s http://10.8.30.161:32258",
"-d postgres/example/10.8.30.160/30432",
"-w https://smartwater.anxinyun.cn",
"-w https://smartwater.anxinyun.cn/api",
"-a https://smartworksafety.anxinyun.cn",
"--yingshiKey 5d16a667e1c2423d9d0d634f781810b4",
"--yingshiSecret 0cc4e1ec4e6a53ea3dabeb09cd5f468b",

23
api/app/lib/controllers/superScreen/water.js

@ -51,8 +51,29 @@ function getEmergencyList(opts) {
}
}
function waterReq(opts) {
return async function (ctx, next) {
let errMsg = { message: '获取水务平台数据失败' }
const body = ctx.request.body;
try {
let ache = body.url == 'login' ? await opts.fs.utils.getAnxinyunToken() :
await opts.fs.utils.getDataFromAxy(body.url, body.method || 'get', body.data)
ctx.status = 200;
ctx.body = ache.body ? ache.body : ache;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = errMsg
}
}
}
module.exports = {
getRealStateData,
getEmergencyList
getEmergencyList,
waterReq
}

2
api/app/lib/middlewares/authenticator.js

@ -75,6 +75,8 @@ let isPathExcluded = function (opts, path, method) {
excludeOpts.push({ p: '/community/info', o: 'GET' });
excludeOpts.push({ p: '/community/fgjv/notice', o: 'GET' });
excludeOpts.push({ p: '/affordable/housing/add', o: 'POST' });
excludeOpts.push({ p: '/waterReq', o: 'POST' });
excludes = new ExcludesUrls(excludeOpts);
}

38
api/app/lib/middlewares/water.js

@ -0,0 +1,38 @@
/**
* Created by PengLing on 2017/7/3.
*/
'use strict';
const request = require('superagent');
module.exports = {
entry: (app, router, opts) => {
const apiRoot = `${opts.host}${opts.match}`;
const req = {
get: (url) => {
return request.get(`${apiRoot}${url}`);
},
post: (url, data) => {
return request
.post(`${apiRoot}${url}`)
.set('Content-Type', 'application/json')
.send(data);
},
put: (url, data) => {
return request
.put(`${apiRoot}${url}`)
.set('Content-Type', 'application/json')
.send(data);
},
delete: (url) => {
return request.del(`${apiRoot}${url}`);
}
};
app.iota = app.iota || {};
app.iota.request = req;
}
};

4
api/app/lib/routes/superScreen/water.js

@ -11,4 +11,8 @@ module.exports = function (app, router, opts, AuthCode) {
//获取水利应急抢险数据
app.fs.api.logAttr['GET/water/emergency'] = { content: '获取水利应急抢险数据', visible: true };
router.get('/water/emergency', water.getEmergencyList(opts));
//获取水利应急抢险数据
app.fs.api.logAttr['GET/waterReq'] = { content: '获取智慧水务平台数据', visible: true };
router.post('/waterReq', water.waterReq(app));
};

69
api/app/lib/utils/waterCache.js

@ -0,0 +1,69 @@
'use strict';
const moment = require('moment')
module.exports = function (app, opts) {
let axyTokenCache = {
userId: null,
orgId: null,
token: null,
expireTime: null //过期时间
}
let getAnxinyunToken = async function () {
try {
if (!axyTokenCache.token || moment() > moment(axyTokenCache.expireTime)) {
const dataToAxy = {
pcode: 'fce4afe2-5b6a-408a-ab18-a2afa7fa027c',
username: '123456',
password: '123456',
}
const axyResponse = await app.fs.waterReq.post('/login', dataToAxy)
const axyData = axyResponse.body
if (axyData.authorized) {
axyTokenCache.userId = axyData.id //放进缓存
axyTokenCache.orgId = axyData.orgId //放进缓存
axyTokenCache.token = axyData.token //放进缓存
axyTokenCache.expireTime = moment().add(23, 'hour').format('YYYY-MM-DD HH:mm:ss')
}
}
return axyTokenCache
} catch (err) {
app.fs.logger.error(`utils: fetch anxinyun token, error: ${err}`);
}
}
let rslt = {};
async function getDataFromAxy(url, method, data) {
try {
if (rslt[url]) {
getData(url, method, data)
return rslt[url]
} else {
let res = await getData(url, method, data)
return res
}
} catch (err) {
app.fs.logger.error(`utils: fetch axy sensors Data, error: ${err}`);
}
}
async function getData(url, method = 'get', data) {
try {
let ache = await getAnxinyunToken()
if (ache) {
const connector = url.indexOf('?') > -1 ? '&' : '?'
const res = await app.fs.waterReq[method](`${url}`, { ...data })
rslt[url] = res
return rslt[url]
}
} catch (err) {
app.fs.logger.error(`utils: fetch axy sensors Data, error: ${err}`);
}
}
return {
getAnxinyunToken,
getDataFromAxy
}
}

33
api/app/lib/utils/waterReq.js

@ -0,0 +1,33 @@
/**
* Created by PengLing on 2017/7/3.
*/
'use strict'
const request = require('superagent');
class AxyReq {
constructor(root) {
this.apiRoot = root
}
get(url) {
return request.get(`${this.apiRoot}${url}`);
}
post(url, data) {
return request.post(`${this.apiRoot}${url}`).set('Content-Type', 'application/json').send(data)
}
put(url, data) {
return request.put(`${this.apiRoot}${url}`).set('Content-Type', 'application/json').send(data)
}
delete(url) {
return request.del(`${this.apiRoot}${url}`)
}
}
module.exports = function (app, opts) {
const req = new AxyReq(opts.waterUrl)
app.fs.waterReq = req
}

7
api/config.js

@ -66,6 +66,12 @@ const product = {
port: flags.port || 8080,
staticDirs: ['static'],
mws: [
{
entry: require('./app/lib/utils/waterReq').entry,
opts: {
host: WATER_URL,
}
},
{
entry: require('@fs/attachment').entry,
opts: {
@ -110,6 +116,7 @@ const product = {
tfApi: THIRD_FIRECONTROL,
axyPumpProject: AXY_PUMP_PROJECT,
statistics: AXY_STATISTICS,
waterUrl: WATER_URL,
pssaRequest: [{// name 会作为一个 request 出现在 ctx.app.fs
name: 'anxinyun',
root: AXY_API_URL

52
super-screen/client/src/sections/water-prevention/actions/waterconservancy.js

@ -16,10 +16,10 @@ export function getPcode(orgId) {
export function waterLogin(data) {
return dispatch => basicAction({
type: 'post',
data,
data: { url: 'login', method: 'post' },
dispatch: dispatch,
actionType: 'POST_WATER_LOGIN',
url: `${ApiTable.waterLogin}`,
url: `${ApiTable.getSmartWaterData}`,
msg: { error: '登录水环境失败' },
// reducer: { name: 'members' }
});
@ -27,44 +27,52 @@ export function waterLogin(data) {
export function getWaterLevelTrend(query) {
return dispatch => basicAction({
type: 'get',
query,
type: 'post',
data: {
url: `${ApiTable.getWaterLevelTrend}?token=${query?.token}&orgId=${query?.orgId}&keyword=`,
},
dispatch: dispatch,
actionType: 'GET_WATER_LEVEL_TREND',
url: `${ApiTable.getWaterLevelTrend}`,
url: `${ApiTable.getSmartWaterData}`,
msg: { error: '获取水位趋势失败' },
});
}
export function getWaterStructures(query) {
return dispatch => basicAction({
type: 'get',
query,
type: 'post',
data: {
url: `${ApiTable.getWaterStructures}?token=${query?.token}`,
},
dispatch: dispatch,
actionType: 'GET_WATER_STRUCTURES',
url: `${ApiTable.getWaterStructures}`,
url: `${ApiTable.getSmartWaterData}`,
msg: { error: '获取水务结构物失败' },
});
}
export function getWaterVideoList(struIds, query) {
return dispatch => basicAction({
type: 'get',
query,
type: 'post',
data: {
url: `${ApiTable.getWaterVideoList.replace('{struIds}', struIds)}&token=${query?.token}`,
},
dispatch: dispatch,
actionType: 'GET_WATER_VIDEO_LIST',
url: `${ApiTable.getWaterVideoList.replace('{struIds}', struIds)}`,
url: `${ApiTable.getSmartWaterData.replace('{struIds}', struIds)}`,
msg: { error: '获取水务视频失败' },
});
}
export function getYsAccessToken(query) {
return dispatch => basicAction({
type: 'get',
query,
type: 'post',
data: {
url: `${ApiTable.getYsAccessToken}?token=${query?.token}`,
},
dispatch: dispatch,
actionType: 'GET_YS_ACCESS_TOKEN',
url: `${ApiTable.getYsAccessToken}`,
url: `${ApiTable.getSmartWaterData}`,
msg: { error: '获取萤石授权失败' },
});
}
@ -72,22 +80,28 @@ export function getYsAccessToken(query) {
export function getWaterAlarms(query) {
return dispatch => basicAction({
type: 'post',
query,
data: { "keywords": "", "status": "new", "levels": [1, 2, 3], "orderBy": "endTime", "orderDirection": "desc", "limit": 10, "offset": 0, "structures": null, "types": [1] },
data: {
url: `${ApiTable.getWaterAlarms}&token=${query?.token}`,
method: 'post',
data: { "keywords": "", "status": "new", "levels": [1, 2, 3], "orderBy": "endTime", "orderDirection": "desc", "limit": 10, "offset": 0, "structures": null, "types": [1] }
},
// data: { "structures": null, "orderBy": "endTime", "endTime": "2022-06-30 23:59:59", "keywords": "", "levels": [1, 2, 3], "startTime": "2022-06-01 00:00:00", "orderDirection": "desc", "status": "history", "offset": 0, "types": [1], "limit": 10 },
dispatch: dispatch,
actionType: 'GET_WATER_ALARMS',
url: `${ApiTable.getWaterAlarms}`,
url: `${ApiTable.getSmartWaterData}`,
msg: { error: '获取告警失败' },
});
}
export function getPumpStatus(structId) {
return dispatch => basicAction({
type: 'get',
type: 'post',
data: {
url: `${ApiTable.getPumpStatus.replace('{structId}', structId)}`,
},
dispatch: dispatch,
actionType: 'GET_PUMP_STATUS',
url: `${ApiTable.getPumpStatus.replace('{structId}', structId)}`,
url: `${ApiTable.getSmartWaterData}`,
msg: { error: '获取水泵状态失败' },
});
}

5
super-screen/client/src/sections/water-prevention/components/right-bottom.js

@ -10,13 +10,12 @@ function DataTop5(props) {
const [showVideoList, setShowVideoList] = useState();
useEffect(() => {
if (videoList.length && structures.length) {
setShowVideoList(videoList.filter(v => v.structId === structures[0].id));
if (videoList.length && structures.length && accessToken) {
if (!showVideoList) {
setShowVideoList(recUrlToLiveUrl(videoList[0]?.url))
}
}
}, [videoList])
}, [videoList, accessToken])
const renderSubtitle = () => (
videoList?.length > 0 && <Select

31
super-screen/client/src/sections/water-prevention/containers/gis.js

@ -10,12 +10,7 @@ let map = null;
let heatmap = null;
let loca = null;
let gridLayer = null;
let interval = null;
const MARKER_IMG_NAME = {
markergreen: '回迁房',
markerblue: '城中村',
markeryellow: '廉租房',
}
function Map(props) {
const { trendData, waterLevelAlarms, emergencyList, getPumpStatusData } = props;
const [delay, setDelay] = useState(true)
@ -51,10 +46,7 @@ function Map(props) {
});
map.on('complete', () => {
setTimeout(() => {
setDelay(false)
}, 1500);
map && renderMarkers()
map && renderAlarms()
setTimeout(() => {
@ -90,9 +82,28 @@ function Map(props) {
// 初始化GIS 组件销毁清空定时器
useEffect(() => {
loadMap();
if (!map) loadMap();
return () => {
map = null;
heatmap = null;
loca = null;
gridLayer = null;
}
}, []);
useEffect(() => {
if (map) {
setTimeout(() => {
renderLayer()
createText()
renderAlarms()
}, 500);
}
}, [trendData, waterLevelAlarms]);
const renderMarkers = () => {
map.clearMap();
// map.setZoom(10.3)

24
super-screen/client/src/sections/water-prevention/containers/homePage.js

@ -113,16 +113,26 @@ function homePage(props) {
dispatch(getWaterVideoList(structRes.payload.data?.map(s => s.id).join(), { token })),
dispatch(getYsAccessToken({ token }))
];
Promise.all(promiseArr).then(resArr => {
if (resArr[0].success && resArr[1].success) {
const at = resArr[1].payload.data.accessToken;
const list = resArr[0].payload.data?.map(v => ({ url: v.yingshi.hlsAddress, name: v.name, structId: v.structId }));
setAccessToken(at)
// Promise.all(promiseArr).then(resArr => {
// if (resArr[0].success && resArr[1].success) {
// const at = resArr[1].payload.data.accessToken;
// const list = resArr[0].payload.data?.map(v => ({ url: v.yingshi.hlsAddress, name: v.name, structId: v.structId }));
// setAccessToken(at)
// let videoTop = list?.find(x => x.name == '玉湖公园')
// setVideoList([videoTop].concat(list?.filter(v => v.name != '玉湖公园')));
// // setVideoList(list);
// }
// })
dispatch(getWaterVideoList(structRes.payload.data?.map(s => s.id).join(), { token })).then(resArr => {
const list = resArr.payload.data?.map(v => ({ url: v.yingshi.hlsAddress, name: v.name, structId: v.structId }));
let videoTop = list?.find(x => x.name == '玉湖公园')
setVideoList([videoTop].concat(list?.filter(v => v.name != '玉湖公园')));
// setVideoList(list);
}
})
dispatch(getYsAccessToken({ token })).then(resArr => {
const at = resArr.payload.data.accessToken;
setAccessToken(at)
})
// 告警
dispatch(getWaterAlarms({ token })).then(alarmRes => {
if (alarmRes.success) {

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

@ -117,13 +117,14 @@ export const ApiTable = {
lookField: 'lookField',
//大屏-水务
waterLogin: '_water/login',
getWaterLevelTrend: '_water/overview/monitoring-station',
getWaterStructures: '_water/organizations/84/structures',
getWaterVideoList: '_water/structures/{struIds}/ipcs?stationIds=undefined',
getYsAccessToken: '_water/yingshi/accessToken',
getWaterAlarms: '_water/axy/alarm?userId=1134&orderBy=endTime&orderDirection=desc&limit=10&offset=0',
getPumpStatus: 'pumpStatus/{structId}',
waterLogin: '_water/_api/login',
getWaterLevelTrend: '/overview/monitoring-station',
getWaterStructures: '/organizations/84/structures',
getWaterVideoList: '/structures/{struIds}/ipcs?stationIds=undefined',
getYsAccessToken: '/yingshi/accessToken',
getWaterAlarms: '/axy/alarm?userId=1134&orderBy=endTime&orderDirection=desc&limit=10&offset=0',
getPumpStatus: '/pumpStatus/{structId}',
getSmartWaterData: 'waterReq',
//安监
worksafetyLogin: '_worksafety/project/login',

Loading…
Cancel
Save