Browse Source

feat:故障风险管理数据计算、接入

master
liujiangyong 1 year ago
parent
commit
d8b646cbed
  1. 161
      api/app/lib/controllers/patrolManage/patrolRecord.js
  2. 4
      api/app/lib/routes/patrolManage/patrolRecord.js
  3. 61
      weapp/package/riskManagement/riskManagement.js
  4. 26
      weapp/package/riskManagement/riskManagement.wxml
  5. 5
      weapp/utils/getApiUrl.js

161
api/app/lib/controllers/patrolManage/patrolRecord.js

@ -2,6 +2,7 @@
const moment = require("moment");
async function findPatrolRecord(ctx, next) {
let rslt = [];
let error = { name: 'FindError', message: '获取巡检记录失败' };
@ -414,15 +415,15 @@ function editPatrolRecordIssueHandle(opts) {
}
//查询子系统的当月的巡检和维修
function getSubSystemPatrolAbout(opts) {
return async function (ctx, next){
try{
let rslt=[]
return async function (ctx, next) {
try {
let rslt = []
const models = ctx.fs.dc.models;
const {STime,ETime,keywords}=ctx.query
let generalInclude = [{model: models.PatrolRecordIssueHandle},{model:models.Project,where:{subType :{$like: `%${keywords}%`}}}]
rslt=await models.PatrolRecord.findAll({
where:{inspectionTime: { $between: [STime, ETime] }},
include:generalInclude
const { STime, ETime, keywords } = ctx.query
let generalInclude = [{ model: models.PatrolRecordIssueHandle }, { model: models.Project, where: { subType: { $like: `%${keywords}%` } } }]
rslt = await models.PatrolRecord.findAll({
where: { inspectionTime: { $between: [STime, ETime] } },
include: generalInclude
})
let userInfo = ctx.fs.api.userInfo;
rslt = rslt.filter(f => f)
@ -435,14 +436,151 @@ function getSubSystemPatrolAbout(opts) {
}
ctx.status = 200;
ctx.body = rslt
}catch(error){
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = { message: '子系统查询巡检记录失败' }
}
}
}
//
/**
* 查询故障风险统计
* @param structures {String} 结构物id, example: 1,2,3
*/
function getPatrolRecordStatistic(opts) {
return async function (ctx, next) {
try {
let rslt = {
monthAlarmCount: 0, // 本月上报风险
monthHandleCount: 0, // 本月处理风险
historyTrend: [], // 历史风险趋势
monthDeviceAlarm: [], // 设备故障统计
};
const models = ctx.fs.dc.models;
const sequelize = ctx.fs.dc.orm;
const { structures } = ctx.query;
const monthStartTime = moment().startOf("month").format('YYYY-MM-DD HH:mm:ss');
const historyStartTime = moment().startOf("month").subtract(11, 'months').format('YYYY-MM-DD HH:mm:ss');
const endTime = moment().endOf("month").format('YYYY-MM-DD HH:mm:ss');
const monthAlarm = await models.PatrolRecord.findAndCountAll({
where: {
inspectionTime: { $between: [monthStartTime, endTime] },
projectId: { $in: structures.split(',') },
alarm: true
},
include: [{
model: models.Project,
where: { type: '管廊' }
}],
})
rslt.monthAlarmCount = monthAlarm.count;
let abnormalDevice = [];
for (const r of monthAlarm.rows) {
if (Array.isArray(r.points.inspectContent)) {
for (const d of r.points.inspectContent) {
if (d.deviceName && d.alarm) {
let abnormalCount = 0, abnormalScore = 0, slight = 0, middle = 0, severity = 0, itemsCount = [];
const index = abnormalDevice.findIndex(e => e.deviceId === d.deviceId);
if (index !== -1) {
itemsCount = abnormalDevice[index].itemsCount;
slight = abnormalDevice[index].slight;
middle = abnormalDevice[index].middle;
severity = abnormalDevice[index].severity;
}
for (const item of d.checkItems) {
if (item.isNormal === false) {
abnormalCount += 1;
switch (item.level) {
case '轻微':
slight += 1;
abnormalScore += 1;
break;
case '中度':
middle += 1;
abnormalScore += 3;
break;
case '严重':
severity += 1;
abnormalScore += 5;
break;
default:
break;
}
const itemIndex = itemsCount.findIndex(i => i.name === item.name);
if (itemIndex === -1) {
itemsCount.push({ name: item.name, count: 1 });
} else {
itemsCount[itemIndex].count += 1;
}
}
}
if (index !== -1) {
abnormalDevice[index].abnormalCount += abnormalCount;
abnormalDevice[index].abnormalScore += abnormalScore;
abnormalDevice[index].itemsCount = itemsCount;
abnormalDevice[index].slight = slight;
abnormalDevice[index].middle = middle;
abnormalDevice[index].severity = severity;
} else {
abnormalDevice.push({
deviceId: d.deviceId, deviceName: d.deviceName, project: r.points.project.name,
abnormalCount, abnormalScore, itemsCount, slight, middle, severity,
})
}
}
}
}
}
rslt.monthDeviceAlarm = abnormalDevice;
rslt.monthHandleCount = await models.PatrolRecord.count({
where: {
inspectionTime: { $between: [monthStartTime, endTime] },
projectId: { $in: structures.split(',') },
alarm: true
},
include: [{
model: models.PatrolRecordIssueHandle,
where: { state: 6 } // 验收通过
}, {
model: models.Project,
where: { type: '管廊' }
}],
})
// rslt.historyTrend = await sequelize.query(
// `select to_char(inspection_time::DATE, 'YYYY-MM') as month, COUNT(*) as num from patrol_record INNER JOIN "project" ON "patrol_record"."project_id" = "project"."id" AND "project"."type" = '管廊' where inspection_time >= '${historyStartTime}' and inspection_time <= '${endTime}' group by month order by month;`
// );
const monthFn = sequelize.fn('to_char', sequelize.col('inspection_time'), 'YYYY-MM');
rslt.historyTrend = await models.PatrolRecord.findAll({
attributes: [
[monthFn, 'month'],
[sequelize.fn('COUNT', sequelize.col('*')), 'count'],
],
group: [monthFn],
order: [monthFn],
where: {
inspectionTime: { $between: [historyStartTime, endTime] },
projectId: { $in: structures.split(',') },
alarm: true
},
include: [{
attributes: [],
model: models.Project,
where: { type: '管廊' }
}],
})
ctx.status = 200;
ctx.body = rslt
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = { message: '查询故障风险统计失败' }
}
}
}
Array.prototype.group = function (callback, thisArg = null) {
// 参数合法性判断
@ -473,5 +611,6 @@ module.exports = {
getPatrolRecordIssueHandleById,
addPatrolRecordIssueHandle,
editPatrolRecordIssueHandle,
getSubSystemPatrolAbout
getSubSystemPatrolAbout,
getPatrolRecordStatistic
}

4
api/app/lib/routes/patrolManage/patrolRecord.js

@ -34,4 +34,8 @@ module.exports = function (app, router, opts) {
//子系统巡检记录
app.fs.api.logAttr['GET/patrolRecord/subSystemPatrolAbout'] = { content: '子系统查询巡检记录', visible: true };
router.get('/patrolRecord/subSystemPatrolAbout', patrolRecord.getSubSystemPatrolAbout(opts))
//故障风险管理-统计接口
app.fs.api.logAttr['GET/patrolRecord/statistic'] = { content: '故障风险统计', visible: true };
router.get('/patrolRecord/statistic', patrolRecord.getPatrolRecordStatistic(opts))
};

61
weapp/package/riskManagement/riskManagement.js

@ -1,5 +1,8 @@
// package/riskManagement/riskManagement.js
import * as echarts from '../components/ec-canvas/echarts';
import { Request } from "../../common";
import { getPatrolRecordStatistic } from '../../utils/getApiUrl';
import moment from '../../utils/moment';
function setOption(chart, data) {
const option = {
@ -10,17 +13,37 @@ function setOption(chart, data) {
bottom: '3%',
containLabel: true
},
tooltip: {
trigger: 'axis',
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
data: data.map(d => d.month),
boundaryGap: false,
axisLabel: {
formatter: (value) => {
const temp = value.split('-');
return + temp[1] + '月' + '\n ' + temp[0];
}
},
},
yAxis: {
type: 'value'
},
series: [
{
data: data,
type: 'line'
data: data.map(d => d.count),
type: 'line',
symbol: 'circle',
symbolSize: 5,
itemStyle: {
normal: {
color: '#008AFF',
lineStyle: {
color: '#008AFF',
}
}
},
}
]
};
@ -39,6 +62,11 @@ Page({
},
isLoaded: false,
list: [1, 2, 3, 4],
monthAlarmCount: 0,
monthHandleCount: 0,
historyTrend: [],
monthDeviceRank: [],
monthDeviceScoreRank: [],
},
// 初始化图表
@ -75,10 +103,31 @@ Page({
* 生命周期函数--监听页面加载
*/
onLoad(options) {
const userInfo = wx.getStorageSync("userInfo");
// 请求数据
setTimeout(() => {
this.initChart([250, 300, 100, 147, 260, 123, 311])
}, 1000)
wx.showLoading()
Request.get(getPatrolRecordStatistic(userInfo.structure.join())).then(res => {
wx.hideLoading()
let historyTrend = new Array(12)
for (let i = 11; i >= 0; i--) {
const month = moment().subtract(i, 'month').format('YYYY-MM')
historyTrend[11 - i] = {
month: month,
count: res.historyTrend?.find(h => h.month === month)?.count || 0,
}
}
const monthDeviceRank = [...res.monthDeviceAlarm]
.sort((a, b) => b.abnormalCount - a.abnormalCount)
.map(d => ({ ...d, itemsCount: d.itemsCount.sort((a, b) => b.count - a.count) }))
this.setData({
monthAlarmCount: res.monthAlarmCount,
monthHandleCount: res.monthHandleCount,
historyTrend,
monthDeviceRank: monthDeviceRank,
monthDeviceScoreRank: [...res.monthDeviceAlarm].sort((a, b) => b.abnormalScore - a.abnormalScore),
})
this.initChart(historyTrend)
})
},
/**

26
weapp/package/riskManagement/riskManagement.wxml

@ -7,11 +7,11 @@
<view class="flex flex-between">
<view class="title-item flex flex-col">
<view>本月上报风险</view>
<view><text class="title-num">{{86}}</text><text class="title-unit">个</text></view>
<view><text class="title-num">{{monthAlarmCount}}</text><text class="title-unit">个</text></view>
</view>
<view class="title-item flex flex-col">
<view>故障风险管理</view>
<view><text class="title-num">{{300}}</text><text class="title-unit">个</text></view>
<view>本月处理风险</view>
<view><text class="title-num">{{monthHandleCount}}</text><text class="title-unit">个</text></view>
</view>
</view>
@ -34,8 +34,8 @@
<view class="card-link" bindtap="toCalendar">查看详情 ></view>
</view>
<view style="margin-top: 10px">【故障次数统计】</view>
<view class="list" wx:for="{{list}}">
<view class="list-title">设备{{item}}</view>
<view class="list" wx:for="{{monthDeviceRank}}">
<view class="list-title">{{item.deviceName}}</view>
<view class="list-line" />
<view class="list-content flex flex-between">
<view class="content-item content-left">
@ -44,15 +44,15 @@
<view>问题概述</view>
</view>
<view class="content-item content-right">
<view>管廊{{item}}</view>
<view>{{10}}次</view>
<view>{{'设备损坏' + item}}</view>
<view>{{item.project}}</view>
<view>{{item.abnormalCount}}次</view>
<view>{{item.itemsCount[0].name}}</view>
</view>
</view>
</view>
<view style="margin-top: 10px">【故障评分统计】</view>
<view class="list" wx:for="{{list}}">
<view class="list-title">设备{{item}}</view>
<view class="list" wx:for="{{monthDeviceScoreRank}}">
<view class="list-title">{{item.deviceName}}</view>
<view class="list-line" />
<view class="list-content flex flex-between">
<view class="content-item content-left">
@ -61,9 +61,9 @@
<view>等级分布</view>
</view>
<view class="content-item content-right">
<view>管廊{{item}}</view>
<view>{{15 - item}}</view>
<view>严重:{{5-item}}次,中等{{2}}次,轻微{{1}}次</view>
<view>{{item.project}}</view>
<view>{{item.abnormalScore}}</view>
<view>严重:{{item.severity}}次,中度{{item.middle}}次,轻微{{item.slight}}次</view>
</view>
</view>
</view>

5
weapp/utils/getApiUrl.js

@ -79,4 +79,9 @@ exports.getStructuresList = () => {
exports.getPatrolReport = (query) => {
const { projectId, startTime, endTime } = query;
return `/patrolReport?projectId=${projectId}&startTime=${startTime}&endTime=${endTime}`
}
// 故障风险管理统计
exports.getPatrolRecordStatistic = (structures) => {
return `/patrolRecord/statistic?structures=${structures}`
}
Loading…
Cancel
Save