Browse Source

(*) 接入泵站开关状态

master
liujiangyong 1 year ago
parent
commit
855f83ffd4
  1. 2
      api/.vscode/launch.json
  2. 55
      api/app/lib/controllers/superScreen/pump.js
  3. 1
      api/app/lib/middlewares/authenticator.js
  4. 9
      api/app/lib/routes/superScreen/pump.js
  5. 12
      api/config.js
  6. 10
      super-screen/client/src/sections/water-prevention/actions/waterconservancy.js
  7. 10
      super-screen/client/src/sections/water-prevention/constants/water.js
  8. 35
      super-screen/client/src/sections/water-prevention/containers/gis.js
  9. 36
      super-screen/client/src/sections/water-prevention/containers/gis.less
  10. 8
      super-screen/client/src/sections/water-prevention/containers/homePage.js
  11. 2
      super-screen/client/src/utils/webapi.js

2
api/.vscode/launch.json

@ -23,6 +23,8 @@
"-w https://smartwater.anxinyun.cn",
"-a https://smartworksafety.anxinyun.cn",
"--tf http://91mogo.com/onecity/v5",
"--axyApi https://openapi.anxinyun.cn/api/v1",
"--axyPumpProject 1a271f12-52f2-4d16-8dad-ec0c92d3e0cc/03bzzdh/123456", //
]
},
{

55
api/app/lib/controllers/superScreen/pump.js

@ -0,0 +1,55 @@
'use strict';
const moment = require('moment');
let axyTokenCache = {
token: null,
orgId: null,
expireTime: null // 过期时间
}
const getAnxinyunToken = async function (ctx, opts) {
try {
if (!axyTokenCache.token || moment() > moment(axyTokenCache.expireTime)) {
if (opts.axyPumpProject.split('/').length === 3) {
const dataToAxy = {
p: opts.axyPumpProject.split('/')[0],
username: opts.axyPumpProject.split('/')[1],
password: opts.axyPumpProject.split('/')[2],
};
const axyResponse = await ctx.app.fs.anxinyun.post('project/login', { data: dataToAxy });
if (axyResponse.authorized) {
axyTokenCache.token = axyResponse.token;
axyTokenCache.orgId = axyResponse.orgId;
axyTokenCache.expireTime = moment().add(20, 'hour').format('YYYY-MM-DD HH:mm:ss');
}
}
}
return axyTokenCache;
} catch (error) {
ctx.fs.logger.error(`sechedule: laborAttendance, error: ${error}`);
}
}
function getPumpStatus(opts) {
return async function (ctx, next) {
try {
const { structId } = ctx.params;
let authData = await getAnxinyunToken(ctx, opts);
const factors = await ctx.app.fs.anxinyun.get(`structures/${structId}/factors?token=${authData.token}`);
const pumpFactorId = factors.find(f => f.name === '泵站水泵').id;
const stationsRes = await ctx.app.fs.anxinyun.get(`structures/${structId}/stations?factorId=${pumpFactorId}&token=${authData.token}`);
const stations = stationsRes[0].groups[0].stations.map(s => s.id).join();
const statusList = await ctx.app.fs.anxinyun.get(`stations/theme/data?stations=${stations}&startTime=${moment().startOf('day').format('YYYY-MM-DD HH:mm:ss')}&endTime=${moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')}&limit=1&token=${authData.token}`);
ctx.status = 200;
ctx.body = statusList;
} catch (err) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${err}`);
ctx.status = 400;
ctx.body = { name: 'FindError', message: '获取安心云数据失败' };
}
}
}
module.exports = {
getPumpStatus,
}

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

@ -66,6 +66,7 @@ let isPathExcluded = function (opts, path, method) {
excludeOpts.push({ p: '/fire/alarm/:id', o: 'PUT' });
excludeOpts.push({ p: '/fire/device', o: 'GET' });
excludeOpts.push({ p: '/fire/trend', o: 'GET' });
excludeOpts.push({ p: '/pumpStatus/:structId', o: 'GET' });
excludes = new ExcludesUrls(excludeOpts);
}

9
api/app/lib/routes/superScreen/pump.js

@ -0,0 +1,9 @@
'use strict';
const pump = require('../../controllers/superScreen/pump');
module.exports = function (app, router, opts, AuthCode) {
// 获取水泵状态
app.fs.api.logAttr['GET/pumpStatus/:structId'] = { content: '获取水泵状态', visible: true };
router.get('/pumpStatus/:structId', pump.getPumpStatus(opts));
};

12
api/config.js

@ -16,6 +16,8 @@ args.option(['d', 'dbconfig'], '后台同步数据库host示例:postgres/example
args.option(['w', 'water'], '水环境api地址');
args.option(['a', 'worksafety'], '安监api地址');
args.option('tf', '消防第三方接口 THIRD_FIRECONTROL');
args.option('axyApi', "安心云api");
args.option('axyPumpProject', '安心云泵站项目信息');
const flags = args.parse(process.argv);
@ -33,10 +35,11 @@ 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 THIRD_FIRECONTROL = process.env.THIRD_FIRECONTROL || flags.tf;
const AXY_API_URL = process.env.AXY_API_URL || flags.axyApi;
const AXY_PUMP_PROJECT = process.env.AXY_PUMP_PROJECT || flags.axyPumpProject;
if (!DB || !BACKUPS_URL || !KUBESPHERE_URL || !DATABASE_CONFIG || !WATER_URL || !WORKSAFETY_URL || !THIRD_FIRECONTROL) {
if (!DB || !BACKUPS_URL || !KUBESPHERE_URL || !DATABASE_CONFIG || !WATER_URL || !WORKSAFETY_URL || !THIRD_FIRECONTROL || !AXY_API_URL || !AXY_PUMP_PROJECT) {
console.log('缺少启动参数,异常退出');
args.showHelp();
process.exit(-1);
@ -85,6 +88,11 @@ const product = {
k8s: KUBESPHERE_URL,
dbConfig: DATABASE_CONFIG,
tfApi: THIRD_FIRECONTROL,
axyPumpProject: AXY_PUMP_PROJECT,
pssaRequest: [{// name 会作为一个 request 出现在 ctx.app.fs
name: 'anxinyun',
root: AXY_API_URL
}],
}
}, {
entry: require('./app/lib/middlewares/proxy').entry,

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

@ -81,3 +81,13 @@ export function getWaterAlarms(query) {
msg: { error: '获取告警失败' },
});
}
export function getPumpStatus(structId) {
return dispatch => basicAction({
type: 'get',
dispatch: dispatch,
actionType: 'GET_PUMP_STATUS',
url: `${ApiTable.getPumpStatus.replace('{structId}', structId)}`,
msg: { error: '获取水泵状态失败' },
});
}

10
super-screen/client/src/sections/water-prevention/constants/water.js

@ -1,22 +1,22 @@
export const SHUI_ZHAN = [
{ name: '莲塘渡槽', location: [115.95219, 28.5429711], },
{ name: '雄溪站', location: [115.908888, 28.5337351], structId: 2945 },
{ name: '雄溪站', location: [115.908888, 28.5337351], },
{ name: '塔田站', location: [115.916979, 28.5319411], },
{ name: '万寿湖站', location: [115.929167, 28.5222881], },
{ name: '张坊站', location: [115.9092, 28.5049421], },
{ name: '东山站', location: [115.887528, 28.4872531], },
{ name: '东山站', location: [115.887528, 28.4872531], structId: 3592 },
{ name: '河外泵站', location: [115.889888, 28.4856311], },
{ name: '三山站', location: [115.888521, 28.4726391], },
{ name: '三山站', location: [115.888521, 28.4726391], structId: 3599 },
{ name: '内湖电排站', location: [115.891311, 28.4692441], },
{ name: '沥山站', location: [115.897692, 28.5616881], },
{ name: '象湖站', location: [115.894774, 28.5789311], },
{ name: '姚塘站', location: [115.863709, 28.579954], },
{ name: '河下站', location: [115.844769, 28.5602231], },
{ name: '霞山站', location: [115.841465, 28.5508371], },
{ name: '石岐站', location: [115.838675, 28.5507611], },
{ name: '石岐站', location: [115.838675, 28.5507611], structId: 3598 },
{ name: '清湖站', location: [115.838418, 28.5378311], },
{ name: '虎山站', location: [115.843673, 28.5366861], },
{ name: '新八月湖站', location: [115.880322, 28.6076911], },
{ name: '新八月湖站', location: [115.880322, 28.6076911], structId: 3569 },
// { name: '八月湖站', location: [115.868392, 28.6091981], },
{ name: '河口电排站', location: [115.924659, 28.52865] },
]

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

@ -17,7 +17,7 @@ const MARKER_IMG_NAME = {
markeryellow: '廉租房',
}
function Map(props) {
const { trendData, waterLevelAlarms, emergencyList } = props;
const { trendData, waterLevelAlarms, emergencyList, getPumpStatusData } = props;
const [delay, setDelay] = useState(true)
const [tab, setTab] = useState('overview')
@ -128,10 +128,17 @@ function Map(props) {
offset: new AMap.Pixel(153, 260)
});
marker.on('click', () => {
marker.on('click', async () => {
let position = marker.getPosition ? marker.getPosition() : marker.getCenter();
infowindow.open(map, position);
map.setCenter(position)
map.setCenter(position);
let pumpStatus = [];
if (x.structId) {
const res = await getPumpStatusData(x.structId);
if (res?.payload?.data?.stations) {
pumpStatus = res.payload.data.stations;
}
}
setTimeout(() => {
if (document.getElementById(`contentid${x.name}`)) {
render(<div>
@ -145,20 +152,14 @@ function Map(props) {
<span className='gis_title'>泵站名称</span>
<span className='gis_text'>{x.name}</span>
</div>
<div className='gis_item'>
<span className='gis_title'>1#提升泵</span>
<div className='gis_text_on'>
</div>
</div>
<div className='gis_item'>
<span className='gis_title'>2#提升泵</span>
<div className='gis_text_on'>
</div>
</div>
<div className='gis_item'>
<span className='gis_title'>3#提升泵</span>
<div className='gis_text_off'>
</div>
<div className='gis_item_box'>
{
pumpStatus?.map(s => <div className='gis_item' key={s.id}>
<span className='gis_title'>{s.name}</span>
<div className={[2, 4, 6].includes(s.data[0]?.sMotor_State) ? 'gis_text_on' : 'gis_text_off'}>
</div>
</div>)
}
</div>
</div>,
document.getElementById(`contentid${x.name}`));

36
super-screen/client/src/sections/water-prevention/containers/gis.less

@ -97,7 +97,6 @@
background: url('/assets/images/homepage/water/waterinfowindow.png') no-repeat;
background-size: 100% 100%;
opacity: 0.8;
padding-left: 69px;
padding-left: 22px;
padding-top: 197px;
color: #fff;
@ -113,6 +112,41 @@
background-size: 100% 100%;
}
.gis_item_box {
height: 105px;
width: 93%;
overflow-x: hidden;
overflow-y: auto;
}
/* 滚动条整体 */
.gis_item_box::-webkit-scrollbar {
height: 10px;
width: 10px;
}
/* 两个滚动条交接处 -- x轴和y轴 */
.gis_item_box::-webkit-scrollbar-corner {
background-color: transparent;
}
/* 滚动条滑块 */
.gis_item_box::-webkit-scrollbar-thumb {
border-radius: 5px;
-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
background: #053676;
}
/* 滚动条轨道 */
.gis_item_box::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
border-radius: 5px;
background: #ededed;
}
/* 滚动条两端按钮 */
.gis_item_box::-webkit-scrollbar-button {}
.gis_item {
height: 35px;
background-image: linear-gradient(180deg, #0555a791 0%, #022a6f91 100%);

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

@ -20,7 +20,8 @@ function homePage(props) {
const { dispatch, actions } = props;
const {
waterLogin, getWaterLevelTrend, getWaterStructures, getWaterVideoList, getYsAccessToken, getWaterAlarms,
worksafetyLogin, getEmerOrgList, getEmerTeamList, getEmerExpertList, getEmerMedicalList, getEmerRefugeList
worksafetyLogin, getEmerOrgList, getEmerTeamList, getEmerExpertList, getEmerMedicalList, getEmerRefugeList,
getPumpStatus,
} = actions.waterprevention;
const childStyle = { height: '49%', color: '#fff', marginBottom: 17 }
const cardHeight = document.body.clientHeight * 0.896 * 0.32
@ -139,6 +140,10 @@ function homePage(props) {
})
}
const getPumpStatusData = async (structId) => {
return await dispatch(getPumpStatus(structId));
}
const getEmerResource = (type, token) => {
if (type && token) {
const handleRequestComplete = (res) => {
@ -200,6 +205,7 @@ function homePage(props) {
waterLevelAlarms={waterLevelAlarms}
emerResource={emerResource}
emergencyList={emergencyList}
getPumpStatusData={getPumpStatusData}
/>
</div>
<div className='homepage-left homepage-left-right'>

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

@ -123,6 +123,8 @@ export const ApiTable = {
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}',
//安监
worksafetyLogin: '_worksafety/project/login',
getEmerOrgList: '_worksafety/emergency/resource-org-list', // 应急机构

Loading…
Cancel
Save