Browse Source

feat:寿命预警数据接入+fix bugs

master
zhaobing’ 1 year ago
parent
commit
9a07c139e2
  1. 53
      api/app/lib/controllers/device/index.js
  2. 32
      api/app/lib/controllers/patrolManage/patrolRecord.js
  3. 3
      api/app/lib/routes/device/index.js
  4. 4
      api/app/lib/routes/patrolManage/patrolRecord.js
  5. 50
      weapp/package/deviceBigdataGraph/deviceBigdataGraph.js
  6. 8
      weapp/package/deviceBigdataGraph/deviceBigdataGraph.wxml
  7. 321
      weapp/package/deviceBigdataGraph/lifeWarning/lifeWarning.js
  8. 36
      weapp/package/deviceBigdataGraph/lifeWarning/lifeWarning.wxml
  9. 2
      weapp/package/report/report.js
  10. 3
      weapp/pages/home/home.js
  11. 10
      weapp/utils/getApiUrl.js

53
api/app/lib/controllers/device/index.js

@ -148,10 +148,61 @@ function deleteDevice(opts) {
} }
} }
} }
//获取相应设备信息
function getDevices(opts) {
return async function (ctx, next) {
const models = ctx.fs.dc.models;
const { page, limit } = ctx.query;
const Op = ctx.fs.dc.ORM.Op;
let errMsg = { message: '获取设备失败' }
try {
let rslt=[]
let searchWhere = {}
let option = {
where: searchWhere,
order: [["id", "desc"]],
include: [{ model: models.PointDevice,include:{model:models.Point} }]
}
option.where = searchWhere
let limit_ = limit || 10;
let page_ = page || 1;
let offset = (page_ - 1) * limit_;
if (limit && page) {
option.limit = limit_
option.offset = offset
}
let userInfo = ctx.fs.api.userInfo;
rslt = await models.Device.findAll(option);
rslt = rslt.filter(f => f)
if (userInfo.username != 'SuperAdmin') {
if (userInfo.structure) {
rslt = rslt.filter(s =>
{
if(s.pointDevices){
return s.pointDevices.some((item) =>
userInfo.structure.find((x) => x === item.point.projectId))
}
}
)
} else {
rslt = []
}
}
ctx.status = 200;
ctx.body = rslt;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = errMsg
}
}
}
module.exports = { module.exports = {
getDeviceList, getDeviceList,
addDevice, addDevice,
editDevice, editDevice,
deleteDevice deleteDevice,
getDevices
} }

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

@ -596,7 +596,7 @@ function getPointInfo(opts) {
rslt = rslt.filter(f => f) rslt = rslt.filter(f => f)
if (userInfo.username != 'SuperAdmin') { if (userInfo.username != 'SuperAdmin') {
if (userInfo.structure) { if (userInfo.structure) {
rslt = rslt.filter(s => userInfo.structure.find(x => x == s.project.userId)) rslt = rslt.filter(s => userInfo.structure.find(x => x == s.projectId))
} else { } else {
rslt = [] rslt = []
} }
@ -628,7 +628,7 @@ function getTemplate(opts){
rslt = rslt.filter(f => f) rslt = rslt.filter(f => f)
if (userInfo.username != 'SuperAdmin') { if (userInfo.username != 'SuperAdmin') {
if (userInfo.structure) { if (userInfo.structure) {
rslt = rslt.filter(s => userInfo.structure.find(x => x == s.project.userId)) rslt = rslt.filter(s => userInfo.structure.find(x => x == s.project.id))
} else { } else {
rslt = [] rslt = []
} }
@ -732,6 +732,31 @@ function getSubSystemPatrol(opts) {
// } // }
// } // }
//查询用户所有的巡检记录
function getAllPatrol(opts) {
return async function (ctx, next) {
try{
let rslt=[]
const models = ctx.fs.dc.models;
let userInfo = ctx.fs.api.userInfo;
rslt=await models.PatrolRecord.findAll()
rslt = rslt.filter(f => f)
if (userInfo.username != 'SuperAdmin') {
if (userInfo.structure) {
rslt = rslt.filter(s => userInfo.structure.find(x => x == s.projectId))
} else {
rslt = []
}
}
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) { Array.prototype.group = function (callback, thisArg = null) {
// 参数合法性判断 // 参数合法性判断
@ -767,5 +792,6 @@ module.exports = {
getPointInfo, getPointInfo,
getTemplate, getTemplate,
reportQuest, reportQuest,
getSubSystemPatrol getSubSystemPatrol,
getAllPatrol
} }

3
api/app/lib/routes/device/index.js

@ -19,5 +19,8 @@ module.exports = function (app, router, opts, AuthCode) {
app.fs.api.logAttr['GET/device'] = { content: '获取设备信息列表', visible: true }; app.fs.api.logAttr['GET/device'] = { content: '获取设备信息列表', visible: true };
router.get('/device', device.getDeviceList(opts)); router.get('/device', device.getDeviceList(opts));
// 获取设备信息
app.fs.api.logAttr['GET/devices'] = { content: '获取设备信息', visible: true };
router.get('/devices', device.getDevices(opts));
}; };

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

@ -53,4 +53,8 @@ module.exports = function (app, router, opts) {
// 查询子系统每日巡检 // 查询子系统每日巡检
app.fs.api.logAttr['GET/subSystemPatrol/day'] = { content: '查询子系统每日巡检', visible: true }; app.fs.api.logAttr['GET/subSystemPatrol/day'] = { content: '查询子系统每日巡检', visible: true };
router.get('/subSystemPatrol/day', patrolRecord.getSubSystemPatrol(opts)) router.get('/subSystemPatrol/day', patrolRecord.getSubSystemPatrol(opts))
// 查询所有的巡检记录
app.fs.api.logAttr['GET/allPatrol'] = { content: '查询所有的巡检记录', visible: true };
router.get('/allPatrol', patrolRecord.getAllPatrol(opts))
}; };

50
weapp/package/deviceBigdataGraph/deviceBigdataGraph.js

@ -1,5 +1,10 @@
// package/riskManagement/riskCalendar/riskCalendar.js // package/riskManagement/riskCalendar/riskCalendar.js
import * as echarts from '../components/ec-canvas/echarts'; import * as echarts from '../components/ec-canvas/echarts';
import {
getAllPatrol,getDevices,getProjectList
} from "../../utils/getApiUrl";
import { Request } from "../../common";
const moment = require("../../utils/moment");
Page({ Page({
initECharts(option) { initECharts(option) {
@ -30,7 +35,11 @@ Page({
* 页面的初始数据 * 页面的初始数据
*/ */
data: { data: {
ec:{} ec:{},
dataList:[],//巡检记录的列表
guaranteedRate:0,//过保率
warrantyPeriod:0,//质保期
projectList:[],//结构物列表
}, },
navigator(e) { navigator(e) {
wx.navigateTo({ wx.navigateTo({
@ -38,8 +47,9 @@ Page({
}) })
}, },
navigatorToLifeWarning(e) { navigatorToLifeWarning(e) {
const res=JSON.stringify(this.data.projectList.rows)
wx.navigateTo({ wx.navigateTo({
url: '/package/deviceBigdataGraph/lifeWarning/lifeWarning', url: `/package/deviceBigdataGraph/lifeWarning/lifeWarning?arrayData=${encodeURIComponent(res)}`,
}) })
}, },
/** /**
@ -119,6 +129,42 @@ Page({
}; };
that.initECharts(option); that.initECharts(option);
that.initDeviceECharts(optionDevice); that.initDeviceECharts(optionDevice);
Request.get(getAllPatrol()).then(res=>{
if(res){
that.setData({dataList:res})
const rslt=res.filter(item=>{
console.log('dsadasda',item)
})
console.log('resss',rslt)
}else{
wx.hideLoading()
}
})
Request.get(getProjectList()).then(res=>{
if(res){
that.setData({
projectList:res
})
}else{
}
})
Request.get(getDevices()).then(res=>{
if(res&&res.length){
//总的
const count=res.length
//过期的
const guaranteedRate=res.filter(item=>moment(item.dateGuarantee).isBefore(moment()))?.length||0
//没过期的
const warrantyPeriod=res.filter(item=>moment(item.dateGuarantee).isAfter(moment()))?.length||0
that.setData({
guaranteedRate: Math.round((guaranteedRate/count)*100),
warrantyPeriod: Math.round((warrantyPeriod/count)*100),
})
}else{
}
})
}, },
/** /**

8
weapp/package/deviceBigdataGraph/deviceBigdataGraph.wxml

@ -16,15 +16,15 @@
<view class="progress-container"> <view class="progress-container">
<text class="label">过保比率:</text> <text class="label">过保比率:</text>
<view class="progress-wrapper"> <view class="progress-wrapper">
<progress class="progress" percent="50" color="#4E87FF"></progress> <progress class="progress" percent="{{guaranteedRate}}" color="#4E87FF"></progress>
<text>50%</text> <text>{{guaranteedRate}}%</text>
</view> </view>
</view> </view>
<view class="progress-container"> <view class="progress-container">
<text class="label">质保期比例:</text> <text class="label">质保期比例:</text>
<view class="progress-wrapper"> <view class="progress-wrapper">
<progress class="progress" percent="50"></progress> <progress class="progress" percent="{{warrantyPeriod}}"></progress>
<text>50%</text> <text>{{warrantyPeriod?0:0}}%</text>
</view> </view>
</view> </view>

321
weapp/package/deviceBigdataGraph/lifeWarning/lifeWarning.js

@ -1,123 +1,216 @@
// package/deviceBigdataGraph/lifeWarning/lifeWarning.js // package/deviceBigdataGraph/lifeWarning/lifeWarning.js
import * as echarts from '../../components/ec-canvas/echarts'; import * as echarts from '../../components/ec-canvas/echarts';
function setOption(chart, data) { import {
getAllPatrol,
getDevices,getProjectList
} from "../../../utils/getApiUrl";
import {
Request
} from "../../../common";
const moment = require("../../../utils/moment");
function setOption(chart, seriesData, xData) {
const option = { const option = {
grid: { grid: {
top: '5%', top: '5%',
left: '3%', left: '3%',
right: '4%', right: '4%',
bottom: '3%', bottom: '3%',
containLabel: true containLabel: true
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value',
},
series: [
{
data: data,
type: 'line'
}, },
] xAxis: {
type: 'category',
data: xData
},
yAxis: {
type: 'value',
},
series: [{
data: seriesData,
type: 'line'
}, ]
}; };
chart.setOption(option); chart.setOption(option);
} }
Page({ Page({
/** /**
* 页面的初始数据 * 页面的初始数据
*/ */
data: { data: {
ec: { ec: {
// onInit: initChart, // onInit: initChart,
lazyLoad: true, // 将 lazyLoad 设为 true 后,需要手动初始化图表 lazyLoad: true, // 将 lazyLoad 设为 true 后,需要手动初始化图表
}, },
isLoaded: false, isLoaded: false,
list: [1,2,3] list: [1, 2, 3],
}, count: 0, //总设备数
initChart: function (data) { guaranteedRate: 0, //过保率
this.ecComponent = this.selectComponent('#device-status-chart'); warrantyPeriod: 0, //质保期
this.ecComponent.init((canvas, width, height, dpr) => { next30days: [], //未来30天过期的设备列表
const chart = echarts.init(canvas, null, { },
width: width, initChart: function (seriesData, xData) {
height: height, this.ecComponent = this.selectComponent('#device-status-chart');
devicePixelRatio: dpr // new this.ecComponent.init((canvas, width, height, dpr) => {
}); const chart = echarts.init(canvas, null, {
setOption(chart, data); width: width,
height: height,
// 将图表实例绑定到 this 上,可以在其他成员函数中访问 devicePixelRatio: dpr // new
this.chart = chart; });
setOption(chart, seriesData, xData);
this.setData({
isLoaded: true, // 将图表实例绑定到 this 上,可以在其他成员函数中访问
}); this.chart = chart;
// 注意这里一定要返回 chart 实例,否则会影响事件处理等 this.setData({
return chart; isLoaded: true,
}); });
},
/** // 注意这里一定要返回 chart 实例,否则会影响事件处理等
* 生命周期函数--监听页面加载 return chart;
*/ });
onLoad(options) { },
const {windowHeight}=wx.getSystemInfoSync() /**
const pageHeight=windowHeight - 48 * 生命周期函数--监听页面加载
setTimeout(() => { */
this.initChart([1,2,3,4,5,6]) onLoad(options) {
}, 1000) const projectList=decodeURIComponent(options.arrayData)
const that = this const complexArray = JSON.parse(projectList);
that.setData({pageHeight:pageHeight+'px'}) const {
}, windowHeight
} = wx.getSystemInfoSync()
/** const pageHeight = windowHeight - 48
* 生命周期函数--监听页面初次渲染完成 const that = this
*/ that.setData({
onReady() { pageHeight: pageHeight + 'px'
})
}, Request.get(getDevices()).then(res => {
if (res && res.length) {
/** // 获取当前日期
* 生命周期函数--监听页面显示 const currentDate = new Date();
*/ // 计算 30 天后的日期
onShow() { const thirtyDaysLater = new Date(currentDate);
thirtyDaysLater.setDate(thirtyDaysLater.getDate() + 30);
}, // 计算半年后的日期
const sixMonthsLater = new Date();
/** sixMonthsLater.setMonth(sixMonthsLater.getMonth() + 6);
* 生命周期函数--监听页面隐藏 // 初始化每个月的设备计数数组
*/ const monthlyCounts = new Array(6).fill(0);
onHide() { // 创建日期范围
const dateRange = [];
}, //30天内过期设备列表
const expiringDevices = [];
/** for (let i = 0; i < 6; i++) {
* 生命周期函数--监听页面卸载 const startOfMonth = new Date(currentDate.getFullYear(), currentDate.getMonth() + i, 1);
*/ dateRange.push({
onUnload() { start: startOfMonth,
end: new Date(startOfMonth.getFullYear(), startOfMonth.getMonth() + 1, 0)
}, });
}
/** // 遍历设备列表
* 页面相关事件处理函数--监听用户下拉动作 res.forEach((device) => {
*/ const guaranteeDate = new Date(device.dateGuarantee);
onPullDownRefresh() { if (guaranteeDate >= currentDate && guaranteeDate <= thirtyDaysLater) {
const pointDevices = device.pointDevices;
}, pointDevices.forEach((pointDevice) => {
const point = pointDevice.point;
/** // 查找匹配项目
* 页面上拉触底事件的处理函数 const project = complexArray.find((project) => project.id === point.projectId);
*/ if (project) {
onReachBottom() { device.project = project;
}
}, });
expiringDevices.push(device);
/** }
* 用户点击右上角分享 // 检查设备的 dateGuarantee 是否在日期范围内
*/ for (let i = 0; i < dateRange.length; i++) {
onShareAppMessage() { if (guaranteeDate >= dateRange[i].start && guaranteeDate <= dateRange[i].end) {
// 设备在当前月内到期
} monthlyCounts[i]++;
break; // 结束循环,不需要继续检查其他月份
}
}
});
const xAxisLabels = [];
// 生成未来六个月的月份
for (let i = 0; i < 6; i++) {
// const nextMonth = new Date(currentDate.getFullYear(), currentDate.getMonth() + i, 1);
// const year = nextMonth.getFullYear();
// const month = String(nextMonth.getMonth() + 1).padStart(2, '0'); // 月份格式化为两位数
// const label = `${year}-${month}`;
// xAxisLabels.push(label);
const nextMonth = new Date(currentDate.getFullYear(), currentDate.getMonth() + i, 1);
const month = nextMonth.toLocaleDateString('en-US', {
month: 'short'
}); // 获取月份的缩写
xAxisLabels.push(month);
}
//过期的
const guaranteedRate = res.filter(item => moment(item.dateGuarantee).isBefore(moment()))?.length || 0
//没过期的
const warrantyPeriod = res.filter(item => moment(item.dateGuarantee).isAfter(moment()))?.length || 0
that.setData({
count: res.length,
guaranteedRate: guaranteedRate,
warrantyPeriod: warrantyPeriod,
next30days:expiringDevices
})
setTimeout(() => {
this.initChart(monthlyCounts, xAxisLabels)
}, 1000)
} else {
}
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
}) })

36
weapp/package/deviceBigdataGraph/lifeWarning/lifeWarning.wxml

@ -8,18 +8,18 @@
<image src='/images/rectangle.png' class="backStyle"></image> <image src='/images/rectangle.png' class="backStyle"></image>
<view class="icon-text">设备总数</view> <view class="icon-text">设备总数</view>
</view> </view>
<view class="fontStyle">300个</view> <view class="fontStyle">{{count}}个</view>
</view> </view>
<image src="/images/shield.png" class="deviceImgStyle"></image> <image src="/images/shield.png" class="deviceImgStyle"></image>
</view> </view>
<view class="secondRow"> <view class="secondRow">
<view class="title-item flex flex-col"> <view class="title-item flex flex-col">
<view>过保个数</view> <view>过保个数</view>
<view><text class="title-num">{{86}}</text></view> <view><text class="title-num">{{guaranteedRate}}</text></view>
</view> </view>
<view class="title-item flex flex-col"> <view class="title-item flex flex-col">
<view>质保个数</view> <view>质保个数</view>
<view><text class="title-num">{{300}}</text></view> <view><text class="title-num">{{warrantyPeriod}}</text></view>
</view> </view>
</view> </view>
</view> </view>
@ -46,43 +46,25 @@
</view> </view>
<view class="describeStyle"> <view class="describeStyle">
<view class="center-content"> <view class="center-content">
<text class="font">30天内你有1000个设备即将过保,请及时更换设备</text> <text class="font">30天内你有{{next30days.length}}个设备即将过保,请及时更换设备</text>
</view> </view>
</view> </view>
<!--设备列表--> <!--设备列表-->
<view> <view wx:for="{{next30days}}" wx:key='*this'>
<view class="detail"> <view class="detail">
<view style="position: relative; top: 8px;"> <text class="deviceStyle">设备A</text></view> <view style="position: relative; top: 8px;"> <text class="deviceStyle">{{item.name}}</text></view>
<van-divider class="van-divider-custom" /> <van-divider class="van-divider-custom" />
<view class="flex flex-between" style="margin-top: -10px;"> <view class="flex flex-between" style="margin-top: -10px;">
<view style="margin: 5px 5px;"><text class="chineseStyle">所属结构物</text></view> <view style="margin: 5px 5px;"><text class="chineseStyle">所属结构物</text></view>
<view style="margin: 5px 5px;"><text class="chineseStyle">管廊A</text></view> <view style="margin: 5px 5px;"><text class="chineseStyle">{{item.project.name}}</text></view>
</view> </view>
<view class="flex flex-between"> <view class="flex flex-between">
<view style="margin: 5px 5px;"><text class="chineseStyle">安装时间</text></view> <view style="margin: 5px 5px;"><text class="chineseStyle">安装时间</text></view>
<view style="margin: 5px 5px;"> <text class="chineseStyle">2022-02-11</text></view> <view style="margin: 5px 5px;"> <text class="chineseStyle">{{item.dateInstall}}</text></view>
</view> </view>
<view class="flex flex-between"> <view class="flex flex-between">
<view style="margin: 5px 5px;"><text class="chineseStyle">质保期</text></view> <view style="margin: 5px 5px;"><text class="chineseStyle">质保期</text></view>
<view style="margin: 5px 5px;"><text class="chineseStyle">2022-02-11</text></view> <view style="margin: 5px 5px;"><text class="chineseStyle">{{item.dateGuarantee}}</text></view>
</view>
</view>
</view>
<view>
<view class="detail">
<view style="position: relative; top: 8px;"> <text class="deviceStyle">设备A</text></view>
<van-divider class="van-divider-custom" />
<view class="flex flex-between" style="margin-top: -10px;">
<view style="margin: 5px 5px;"><text class="chineseStyle">所属结构物</text></view>
<view style="margin: 5px 5px;"><text class="chineseStyle">管廊A</text></view>
</view>
<view class="flex flex-between">
<view style="margin: 5px 5px;"><text class="chineseStyle">安装时间</text></view>
<view style="margin: 5px 5px;"> <text class="chineseStyle">2022-02-11</text></view>
</view>
<view class="flex flex-between">
<view style="margin: 5px 5px;"><text class="chineseStyle">质保期</text></view>
<view style="margin: 5px 5px;"><text class="chineseStyle">2022-02-11</text></view>
</view> </view>
</view> </view>
</view> </view>

2
weapp/package/report/report.js

@ -245,7 +245,7 @@ Page({
} }
} }
const { id, name, departmentId, deptName } = wx.getStorageSync('userInfo'); const { id, name, departmentId, deptName } = wx.getStorageSync('userInfo');
const curPlan = that.data.planList.find(item=>item.id=patrolTemplate[patrolTemplateIndex].id) const curPlan = that.data.planList.find(item=>item.id==patrolTemplate[patrolTemplateIndex].id)
const nextItemData = curPlan.points.find(p => p.id == this.data.scenePointId) const nextItemData = curPlan.points.find(p => p.id == this.data.scenePointId)
const aboutSend=templateData.find(item=>item.patrolTemplate.id===patrolTemplate[patrolTemplateIndex].id) const aboutSend=templateData.find(item=>item.patrolTemplate.id===patrolTemplate[patrolTemplateIndex].id)
let datas = { let datas = {

3
weapp/pages/home/home.js

@ -90,7 +90,8 @@ Page({
] ]
}; };
wx.showLoading({ title: '加载中' }) wx.showLoading({ title: '加载中' })
promiseArr.push(Request.get(getPatrolRecord('all', moment('1970-1-1').format('YYYY-MM-DD') + ' 00:00:00', moment('2099-12-31').format('YYYY-MM-DD') + ' 23:59:59', 'null', 'null'))); const date1 = new Date('1970-01-01 00:00:00');
promiseArr.push(Request.get(getPatrolRecord('all', moment(date1).format('YYYY-MM-DD') + ' 00:00:00', moment('2099-12-31').format('YYYY-MM-DD') + ' 23:59:59', 'null', 'null')));
Promise.all(promiseArr).then(res => { Promise.all(promiseArr).then(res => {
wx.hideLoading() wx.hideLoading()
//与自己相关的所有巡检记录 //与自己相关的所有巡检记录

10
weapp/utils/getApiUrl.js

@ -43,10 +43,18 @@ exports.reportQuest = () => {
exports.getPatrolRecord = (patrolPlanId, startTime, endTime, alarm, pointId) => { exports.getPatrolRecord = (patrolPlanId, startTime, endTime, alarm, pointId) => {
return `/patrolRecord/${patrolPlanId}/${startTime}/${endTime}/${alarm}/${pointId}` return `/patrolRecord/${patrolPlanId}/${startTime}/${endTime}/${alarm}/${pointId}`
} }
exports.getAllPatrol = () => {
return `/allPatrol`
}
//设备
exports.getDevices = () => {
return `/devices`
}
//获取子系统的巡检记录 //获取子系统的巡检记录
exports.getSubSystemPatrolAbout = (query) => { exports.getSubSystemPatrolAbout = (query) => {
const { STime, ETime,keywords } = query; const { STime, ETime,keywords } = query;
return `/patrolRecord/subSystemPatrolAbout?STime=${STime}&ETime=${ETime}&keywords=${keywords}` return `/patrolRecord/subSystemPatrolAbout?STime=${STime}&ETime=${ETime}&keywords=${keywords}`
} }

Loading…
Cancel
Save