diff --git a/api/app/lib/controllers/patrolManage/patrolRecord.js b/api/app/lib/controllers/patrolManage/patrolRecord.js index 2b5ac30..db7eeaf 100644 --- a/api/app/lib/controllers/patrolManage/patrolRecord.js +++ b/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 } \ No newline at end of file diff --git a/api/app/lib/routes/patrolManage/patrolRecord.js b/api/app/lib/routes/patrolManage/patrolRecord.js index 82facc5..ce1baea 100644 --- a/api/app/lib/routes/patrolManage/patrolRecord.js +++ b/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)) }; \ No newline at end of file diff --git a/weapp/package/riskManagement/riskManagement.js b/weapp/package/riskManagement/riskManagement.js index ffa65f0..dd94f6f 100644 --- a/weapp/package/riskManagement/riskManagement.js +++ b/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) + }) }, /** diff --git a/weapp/package/riskManagement/riskManagement.wxml b/weapp/package/riskManagement/riskManagement.wxml index 5e32908..9a6456c 100644 --- a/weapp/package/riskManagement/riskManagement.wxml +++ b/weapp/package/riskManagement/riskManagement.wxml @@ -7,11 +7,11 @@ 本月上报风险 - {{86}} + {{monthAlarmCount}} - 故障风险管理 - {{300}} + 本月处理风险 + {{monthHandleCount}} @@ -34,8 +34,8 @@ 查看详情 > 【故障次数统计】 - - 设备{{item}} + + {{item.deviceName}} @@ -44,15 +44,15 @@ 问题概述 - 管廊{{item}} - {{10}}次 - {{'设备损坏' + item}} + {{item.project}} + {{item.abnormalCount}}次 + {{item.itemsCount[0].name}} 【故障评分统计】 - - 设备{{item}} + + {{item.deviceName}} @@ -61,9 +61,9 @@ 等级分布 - 管廊{{item}} - {{15 - item}} - 严重:{{5-item}}次,中等{{2}}次,轻微{{1}}次 + {{item.project}} + {{item.abnormalScore}} + 严重:{{item.severity}}次,中度{{item.middle}}次,轻微{{item.slight}}次 diff --git a/weapp/utils/getApiUrl.js b/weapp/utils/getApiUrl.js index 5634298..f1f241a 100644 --- a/weapp/utils/getApiUrl.js +++ b/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}` } \ No newline at end of file