diff --git a/api/app/lib/controllers/patrolManage/patrolRecord.js b/api/app/lib/controllers/patrolManage/patrolRecord.js index db7eeaf..5f5e6c0 100644 --- a/api/app/lib/controllers/patrolManage/patrolRecord.js +++ b/api/app/lib/controllers/patrolManage/patrolRecord.js @@ -581,6 +581,107 @@ function getPatrolRecordStatistic(opts) { } } } +//根据子系统查询点位信息 +function getPointInfo(opts) { + return async function (ctx, next){ + try{ + let rslt=[] + const models = ctx.fs.dc.models; + const {keywords}=ctx.query + let generalInclude = [{model:models.Project,where:{subType :{$like: `%${keywords}%`}}},{model:models.Device}] + rslt=await models.Point.findAll({ + include:generalInclude + }) + let userInfo = ctx.fs.api.userInfo; + rslt = rslt.filter(f => f) + if (userInfo.username != 'SuperAdmin') { + if (userInfo.structure) { + rslt = rslt.filter(s => userInfo.structure.find(x => x == s.project.userId)) + } 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: '根据子系统查询点位信息失败' } + } + } + +} +//根据结构物查询对应巡检计划的模板 +function getTemplate(opts){ + return async function (ctx, next){ + try{ + let rslt=[] + const models = ctx.fs.dc.models; + const {keywords}=ctx.query + rslt=await models.PatrolPlan.findAll({ + include:[ + {model:models.Project, + where:{subType:{$like: `%${keywords}%`}}}, + {model:models.PatrolTemplate}] + }) + let userInfo = ctx.fs.api.userInfo; + rslt = rslt.filter(f => f) + if (userInfo.username != 'SuperAdmin') { + if (userInfo.structure) { + rslt = rslt.filter(s => userInfo.structure.find(x => x == s.project.userId)) + } 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: '根据结构物查询对应巡检计划的模板失败' } + } + } +} +//上报问题和发现问题接口 +function reportQuest(opts){ + return async function (ctx, next){ + try{ + const models = ctx.fs.dc.models; + const data = ctx.request.body; + let { patrolPlanId, inspectionTime, points, alarm, pointId, projectId } = data + const pointRecord = await models.PatrolRecord.findAll({ + where: { pointId: pointId }, + order: [['inspectionTime', 'desc']], + attributes: ['inspectionTime'], + }); + const lastInspectionTime = pointRecord.length ? pointRecord[0].dataValues.inspectionTime : null; + const recordRes = await models.PatrolRecord.create( + // record + { + patrolPlanId: patrolPlanId, + lastInspectionTime, + inspectionTime, + points, + alarm, + pointId: pointId, + projectId + } + ); + ctx.status = 204; + }catch(error){ + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { message: '上报问题失败' } + } + } +} + +//根据子系统查询点位信息 +// function getPointInfo(opts) { +// return async function (ctx, next){ + +// } +// } Array.prototype.group = function (callback, thisArg = null) { // 参数合法性判断 @@ -612,5 +713,8 @@ module.exports = { addPatrolRecordIssueHandle, editPatrolRecordIssueHandle, getSubSystemPatrolAbout, - getPatrolRecordStatistic + getPatrolRecordStatistic, + getPointInfo, + getTemplate, + reportQuest } \ No newline at end of file diff --git a/api/app/lib/controllers/patrolManage/patrolTemplate.js b/api/app/lib/controllers/patrolManage/patrolTemplate.js index 37ff08b..cebc30a 100644 --- a/api/app/lib/controllers/patrolManage/patrolTemplate.js +++ b/api/app/lib/controllers/patrolManage/patrolTemplate.js @@ -16,7 +16,7 @@ async function getPatrolTemplate (ctx, next) { model: models.CheckItems, }, { model: models.PatrolPlan, - attributes: ['name'], + attributes: ['structure_id','name'], }] }; if (id) { diff --git a/api/app/lib/index.js b/api/app/lib/index.js index 7a63112..7d02a88 100644 --- a/api/app/lib/index.js +++ b/api/app/lib/index.js @@ -111,4 +111,10 @@ module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Seq PointDevice.belongsTo(Device, { foreignKey: 'deviceId', targetKey: 'id' }); Device.hasMany(PointDevice, { foreignKey: 'deviceId', sourceKey: 'id' }); + + Device.belongsToMany(Point,{ through: PointDevice, foreignKey: 'deviceId', otherKey: 'pointId' }) + Point.belongsToMany(Device,{ through: PointDevice, foreignKey: 'pointId', otherKey: 'deviceId' }) + + + }; diff --git a/api/app/lib/routes/patrolManage/patrolRecord.js b/api/app/lib/routes/patrolManage/patrolRecord.js index ce1baea..efffabd 100644 --- a/api/app/lib/routes/patrolManage/patrolRecord.js +++ b/api/app/lib/routes/patrolManage/patrolRecord.js @@ -38,4 +38,15 @@ module.exports = function (app, router, opts) { //故障风险管理-统计接口 app.fs.api.logAttr['GET/patrolRecord/statistic'] = { content: '故障风险统计', visible: true }; router.get('/patrolRecord/statistic', patrolRecord.getPatrolRecordStatistic(opts)) + //点位信息 + app.fs.api.logAttr['GET/patrolRecord/pointInfo'] = { content: '点位信息', visible: true }; + router.get('/patrolRecord/pointInfo', patrolRecord.getPointInfo(opts)) + + //查询模板 + app.fs.api.logAttr['GET/patrolRecord/getTemplate'] = { content: '查询模板', visible: true }; + router.get('/patrolRecord/getTemplate', patrolRecord.getTemplate(opts)) + + //查询模板 + app.fs.api.logAttr['POST/patrolRecord/reportQuest'] = { content: '上报问题', visible: true }; + router.post('/patrolRecord/reportQuest', patrolRecord.reportQuest(opts)) }; \ No newline at end of file diff --git a/weapp/app.json b/weapp/app.json index 2323d4d..25c523a 100644 --- a/weapp/app.json +++ b/weapp/app.json @@ -23,7 +23,10 @@ "pointsStatus/pointsStatus", "subSystem/subSystem", "riskManagement/riskManagement", - "riskManagement/riskCalendar/riskCalendar" + "riskManagement/riskCalendar/riskCalendar", + "deviceBigdataGraph/deviceBigdataGraph", + "deviceBigdataGraph/statusDetail/statusDetail", + "report/report" ] } ], diff --git a/weapp/custom-tab-bar/index.js b/weapp/custom-tab-bar/index.js index 6fa7319..96ddf2c 100644 --- a/weapp/custom-tab-bar/index.js +++ b/weapp/custom-tab-bar/index.js @@ -9,7 +9,7 @@ Component({ let userRole = wx.getStorageSync('userRole'); // 0 表示普通用户 1表示管理员 console.log('userRole', userRole); - if (userRole && userRole.includes('管理')) { + if (userRole && userRole.includes('巡检')) { this.setData({ list: getApp().globalData.managerList }) diff --git a/weapp/images/calendar.png b/weapp/images/calendar.png new file mode 100644 index 0000000..798e6ec Binary files /dev/null and b/weapp/images/calendar.png differ diff --git a/weapp/images/device.png b/weapp/images/device.png new file mode 100644 index 0000000..4e14a39 Binary files /dev/null and b/weapp/images/device.png differ diff --git a/weapp/images/down1.png b/weapp/images/down1.png new file mode 100644 index 0000000..28bc27a Binary files /dev/null and b/weapp/images/down1.png differ diff --git a/weapp/images/edit.png b/weapp/images/edit.png new file mode 100644 index 0000000..a4c5467 Binary files /dev/null and b/weapp/images/edit.png differ diff --git a/weapp/images/shape1.png b/weapp/images/shape1.png new file mode 100644 index 0000000..e86c222 Binary files /dev/null and b/weapp/images/shape1.png differ diff --git a/weapp/images/shape2.png b/weapp/images/shape2.png new file mode 100644 index 0000000..d8eef34 Binary files /dev/null and b/weapp/images/shape2.png differ diff --git a/weapp/images/shape3.png b/weapp/images/shape3.png new file mode 100644 index 0000000..e9a3cac Binary files /dev/null and b/weapp/images/shape3.png differ diff --git a/weapp/package/deviceBigdataGraph/deviceBigdataGraph.js b/weapp/package/deviceBigdataGraph/deviceBigdataGraph.js new file mode 100644 index 0000000..579c700 --- /dev/null +++ b/weapp/package/deviceBigdataGraph/deviceBigdataGraph.js @@ -0,0 +1,168 @@ +// package/riskManagement/riskCalendar/riskCalendar.js +import * as echarts from '../components/ec-canvas/echarts'; + +Page({ + initECharts(option) { + this.ecComponent.init((canvas, width, height, dpr) => { + const chart = echarts.init(canvas, null, { + width: width, + height: height, + devicePixelRatio: dpr, + }); + chart.setOption(option); + this.chart = chart; + return chart; + }); + }, + initDeviceECharts(option) { + this.ecDeviceComponent.init((canvas, width, height, dpr) => { + const chart = echarts.init(canvas, null, { + width: width, + height: height, + devicePixelRatio: dpr, + }); + chart.setOption(option); + this.chart = chart; + return chart; + }); + }, + /** + * 页面的初始数据 + */ + data: { + ec:{} + }, + navigator(e) { + wx.navigateTo({ + url: '/package/deviceBigdataGraph/statusDetail/statusDetail', + }) + console.log('xxxxxx',e) + }, + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + const that = this + that.ecComponent = that.selectComponent('#mychart-dom-pie'); + that.ecDeviceComponent=that.selectComponent('#mychart-device-pie'); + var option = { + backgroundColor: "#ffffff", + legend: { + bottom: 10, + left: 'center', + }, + series: [{ + label: { + normal: { + fontSize: 14 + } + }, + type: 'pie', + center: ['50%', '50%'], + radius: ['20%', '40%'], + data: [{ + name: '类型一', + value: 1 + }, + { + name: '类型二', + value: 2 + }, + { + name: '类型三', + value: 3 + }, + { + name: '类型四', + value: 4 + } + ] + + }] + }; + var optionDevice = { + backgroundColor: "#ffffff", + legend: { + bottom: 10, + left: 'center', + }, + series: [{ + label: { + normal: { + fontSize: 14 + } + }, + type: 'pie', + center: ['50%', '50%'], + radius: ['20%', '40%'], + + data: [{ + name: '正常', + value: 1 + }, + { + name: '未知', + value: 2 + }, + { + name: '异常', + value: 3 + }, + + ] + + }] + }; + that.initECharts(option); + that.initDeviceECharts(optionDevice); + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + + } +}) \ No newline at end of file diff --git a/weapp/package/deviceBigdataGraph/deviceBigdataGraph.json b/weapp/package/deviceBigdataGraph/deviceBigdataGraph.json new file mode 100644 index 0000000..2d686f4 --- /dev/null +++ b/weapp/package/deviceBigdataGraph/deviceBigdataGraph.json @@ -0,0 +1,11 @@ +{ + "navigationBarBackgroundColor": "#1979ff", + "navigationBarTextStyle": "white", + "navigationBarTitleText": "设备大数据图谱", + "enablePullDownRefresh": false, + "usingComponents": { + "ec-canvas": "../components/ec-canvas/ec-canvas", + "van-button": "@vant/weapp/button/index", + "van-progress": "@vant/weapp/progress/index" + } + } \ No newline at end of file diff --git a/weapp/package/deviceBigdataGraph/deviceBigdataGraph.wxml b/weapp/package/deviceBigdataGraph/deviceBigdataGraph.wxml new file mode 100644 index 0000000..e932950 --- /dev/null +++ b/weapp/package/deviceBigdataGraph/deviceBigdataGraph.wxml @@ -0,0 +1,63 @@ + + + + + + + + + 质保图谱 + + + 查看详情 + + + + 过保比率: + + + 50% + + + + 质保期比例: + + + 50% + + + + + + + + + + + 设备状态 + + + 查看详情 + + + + + + + + + + + + + 设备类型 + + + 总数: + + + + + + + \ No newline at end of file diff --git a/weapp/package/deviceBigdataGraph/deviceBigdataGraph.wxss b/weapp/package/deviceBigdataGraph/deviceBigdataGraph.wxss new file mode 100644 index 0000000..73a1649 --- /dev/null +++ b/weapp/package/deviceBigdataGraph/deviceBigdataGraph.wxss @@ -0,0 +1,91 @@ +/* package/riskManagement/riskCalendar/riskCalendar.wxss */ +.container { + background-image: linear-gradient(179deg, #006BE3 0%, #4E87FF 16%, #4e87ff00 93%); + padding: 0 15px; +} + +.card { + position: relative; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 8px; + /* padding: 10px; */ + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); + margin-top: 12px; + width: 100%; + background-image: linear-gradient(0deg, #F3F7FF 84%, #DBE6FF 100%); + +} + +.top { + display: flex; + justify-content: space-between; + padding: 10px; + + /* background-position: bottom; */ +} + +.fontStyle { + width: 64px; + height: 22px; + font-family: PingFangSC-Medium; + font-weight: 500; + font-size: 16px; + color: #000000d9; + letter-spacing: 0; + margin-left: 5px; +} + +.imgStyle { + position: absolute; + width: 115px; + height: 67px; + right: 0; + +} + +.detailStyle { + z-index: 1; +} + +.progress-container { + display: flex; + align-items: center; + width: 100%; + margin: 0px 0px 10px 10px; +} + +.label { + margin-right: 10px; + width: 50%; + height: 20px; + font-family: PingFangSC-Regular; + font-weight: 400; + font-size: 14px; + color: #383A3B; +} + +.progress-wrapper { + display: flex; + align-items: center; + width: 100%; + +} + +.percentage { + margin-right: 10px; +} + +.progress { + width: 75%; +} + +.countStyle { + width: 89px; + height: 24px; + font-family: PingFangSC-Medium; + font-weight: 500; + font-size: 17px; + color: #1684FF; + letter-spacing: 0; +} \ No newline at end of file diff --git a/weapp/package/deviceBigdataGraph/statusDetail/statusDetail.js b/weapp/package/deviceBigdataGraph/statusDetail/statusDetail.js new file mode 100644 index 0000000..ca20416 --- /dev/null +++ b/weapp/package/deviceBigdataGraph/statusDetail/statusDetail.js @@ -0,0 +1,120 @@ +// package/deviceBigdataGraph/detail/detail.js +import * as echarts from '../../components/ec-canvas/echarts'; +function setOption(chart, data) { + const option = { + grid: { + top: '5%', + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true + }, + xAxis: { + type: 'category', + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + }, + yAxis: { + type: 'value' + }, + series: [ + { + data: data, + type: 'line' + } + ] + }; + chart.setOption(option); +} + +Page({ + + /** + * 页面的初始数据 + */ + data: { + ec: { + // onInit: initChart, + lazyLoad: true, // 将 lazyLoad 设为 true 后,需要手动初始化图表 + }, + isLoaded: false, + list: [1,2,3] + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + setTimeout(() => { + this.initChart([250, 300, 100, 147, 260, 123, 311]) + }, 1000) + }, + initChart: function (data) { + this.ecComponent.init((canvas, width, height, dpr) => { + const chart = echarts.init(canvas, null, { + width: width, + height: height, + devicePixelRatio: dpr // new + }); + setOption(chart, data); + + // 将图表实例绑定到 this 上,可以在其他成员函数中访问 + this.chart = chart; + + this.setData({ + isLoaded: true, + }); + + // 注意这里一定要返回 chart 实例,否则会影响事件处理等 + return chart; + }); + }, + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + this.ecComponent = this.selectComponent('#device-status-chart'); + + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + + } +}) \ No newline at end of file diff --git a/weapp/package/deviceBigdataGraph/statusDetail/statusDetail.json b/weapp/package/deviceBigdataGraph/statusDetail/statusDetail.json new file mode 100644 index 0000000..a4a2a67 --- /dev/null +++ b/weapp/package/deviceBigdataGraph/statusDetail/statusDetail.json @@ -0,0 +1,10 @@ +{ + "navigationBarBackgroundColor": "#1979ff", + "navigationBarTextStyle": "white", + "navigationBarTitleText": "设备状态", + "enablePullDownRefresh": false, + "usingComponents": { + "ec-canvas": "../../components/ec-canvas/ec-canvas" + + } +} \ No newline at end of file diff --git a/weapp/package/deviceBigdataGraph/statusDetail/statusDetail.wxml b/weapp/package/deviceBigdataGraph/statusDetail/statusDetail.wxml new file mode 100644 index 0000000..6f3320e --- /dev/null +++ b/weapp/package/deviceBigdataGraph/statusDetail/statusDetail.wxml @@ -0,0 +1,26 @@ + + + 设备总数 + 300 + + + 设备故障率 + {{86}}% + + + 完好率 + {{300}}% + + + + + + + + 历史风险趋势 + + + + + + diff --git a/weapp/package/deviceBigdataGraph/statusDetail/statusDetail.wxss b/weapp/package/deviceBigdataGraph/statusDetail/statusDetail.wxss new file mode 100644 index 0000000..241dadd --- /dev/null +++ b/weapp/package/deviceBigdataGraph/statusDetail/statusDetail.wxss @@ -0,0 +1,76 @@ +/* package/deviceBigdataGraph/detail/detail.wxss */ +.status-detail { + height: 100vh; + background-image: linear-gradient(179deg, #006BE3 0%, #4E87FF 16%, #4e87ff00 93%); + padding: 0 15px; + } + + .icon { + width: 61px; + height: 31.86px; + background-image: linear-gradient(0deg, #EAF2FF 5%, #2578F0 100%); + box-shadow: 0 3px 4px 1px #bfdbfa4f; + } + + .icon-text { + width: 48px; + height: 17px; + font-family: PingFangSC-Medium; + font-weight: 500; + font-size: 12px; + color: #FFFFFF; + } + + .title-item { + width: 150px; + color: #ffffffd9; + } + + .title-num { + font-size: 20px; + color: #FFFFFF; + } + + .title-unit { + font-size: 10px; + color: #FFFFFE; + margin-left: 10px; + } + + .card { + background: #FFFFFF; + box-shadow: 2px 2px 11px 0 #00000008, 0 0 4px 0 #00000012; + border-radius: 4px; + padding: 12px; + margin-top: 12px; + } + + .card-img { + width: 18px; + height: 18px; + margin-right: 13px; + } + + .card-title { + font-weight: 500; + font-size: 16px; + color: #383A3B; + } + + .card-link { + font-weight: 500; + font-size: 14px; + color: #1684FF; + } + + .chart { + width: 100%; + height: 195px; + margin-top: 20px; + } + + .list { + margin-top: 10px; + padding: 10px 7px; + background-color: #F1F7FF; + } \ No newline at end of file diff --git a/weapp/package/polling/polling.js b/weapp/package/polling/polling.js index f6626ac..207f511 100644 --- a/weapp/package/polling/polling.js +++ b/weapp/package/polling/polling.js @@ -48,7 +48,12 @@ Page({ }, recordHidden: true, }, - + jumpToReport (options) { + const key='巡检录入' + wx.navigateTo({ + url: `/package/report/report?key=${key}`, + }) + }, // 顶部tab切换 onChange(event) { this.setData({ diff --git a/weapp/package/polling/polling.json b/weapp/package/polling/polling.json index b7423fa..81cd545 100644 --- a/weapp/package/polling/polling.json +++ b/weapp/package/polling/polling.json @@ -9,6 +9,8 @@ "van-tabs": "@vant/weapp/tabs/index", "van-dropdown-menu": "@vant/weapp/dropdown-menu/index", "van-dropdown-item": "@vant/weapp/dropdown-item/index", - "van-datetime-picker": "@vant/weapp/datetime-picker/index" + "van-datetime-picker": "@vant/weapp/datetime-picker/index", + "van-icon": "@vant/weapp/icon/index" + } } \ No newline at end of file diff --git a/weapp/package/polling/polling.wxml b/weapp/package/polling/polling.wxml index 0707fbe..b28b249 100644 --- a/weapp/package/polling/polling.wxml +++ b/weapp/package/polling/polling.wxml @@ -79,5 +79,10 @@ + + + + + \ No newline at end of file diff --git a/weapp/package/report/report.js b/weapp/package/report/report.js new file mode 100644 index 0000000..d004296 --- /dev/null +++ b/weapp/package/report/report.js @@ -0,0 +1,543 @@ +// package/report/report.js + +import { getPointList,getPatrolTemplate,getTemplates,reportQuest,getPatrolPlan } from "../../utils/getApiUrl"; +import {Request} from "../../common"; +const moment = require("../../utils/moment"); + +Page({ + data: { + isPlanState: false, + structList: [{ + id: 0, + name: '指挥中心' + }, { + id: 1, + name: '管廊' + }, + { + id: 2, + name: '电梯系统' + }, { + id: 3, + name: '供配电系统' + }, { + id: 4, + name: '燃气仓' + }, + { + id: 5, + name: '给水仓' + }, { + id: 6, + name: '防雷与接地系统' + }, { + id: 7, + name: '电气仓' + }, + { + id: 8, + name: '高压电力仓' + }, { + id: 9, + name: '安防系统' + } + ], + data:[],//巡检计划的数据(包括点位,设备等等) + structListIndex: undefined,//结构物id + pointList:[],//点位列表 + pointIndex:undefined,//点位索引 + devicesList:[],//设备列表 + dataList: '', // 当前巡检计划 + patrolTemplate:[],//巡检模板 + templateData:[],//巡检模板总数居 + // curPlanTemplateId:0,//当前巡检计划的模板id + patrolTemplateIndex:undefined,//巡检模板索引 + itemData: '', // 点位 + address: '', // 当前位置 + imgUrl: getApp().globalData.imgUrl, + checkItems: [], // 检查项 + inspectContentArr: [], // 巡检内容 + isCommitting: false, + planList: null, // 巡检计划列表 + structListVisible: true, + scenePointId: null, // 当前点位id + }, + //巡检计划 + getPatrolPlan: function (scenePointId) { + let that = this; + wx.showLoading({ + title: '加载中', + }) + Request.get(getPatrolPlan()).then(res => { + wx.hideLoading(); + let pointPlan = res.rows.filter(plan => { + for (const point of plan.points) { + if (point.id == scenePointId) { + return true; + } + } + return false; + }).map(p => ({ + label: p.name, + value: p.name, + ...p + })) + that.setData({ + planList: pointPlan + }) + }) + }, + //点位改变函数 + pointChange(e){ + const that = this + that.getPatrolPlan(that.data.data[e.detail.value].id) + that.setData({ + inspectContentArr:[], + pointIndex:e.detail.value, + devicesList:that.data.data[e.detail.value].devices, + scenePointId:that.data.data[e.detail.value].id + }) + }, + // 预览图片 + previewImg: function (e) { + const { deviceidx, itemidx, index } = e.currentTarget.dataset; + // 所有图片 + const imgs = this.data.inspectContentArr[deviceidx].checkItems[itemidx].imgs; + const newImgs = imgs.map(i => this.data.imgUrl + i); + wx.previewImage({ + // 当前显示图片 + current: newImgs[index], + // 所有图片 + urls: newImgs + }) + }, + //结构物改变函数 + structChange(event) { + const that = this + that.setData({ + structListIndex: event.detail.value, + // isPlanState: true, + pointList:[],//选择结构物后先置空先前的点位列表 + }) + + const keywords=that.data?.structList[event.detail.value]?.name + const query={keywords} + + Request.get(getTemplates(query)).then(res=>{ + if(res){ + const rlst=res.map(item=>item.patrolTemplate) + that.setData({patrolTemplate:rlst,templateData:res}) + }else{ + + } + }) + Request.get(getPointList(query)).then(res => { + if(res){ + const pointList=res.map(item=>{ + return { + id:item.id, + name:item.name + } + }) + that.setData({pointList:pointList,data:res}) + }else { + wx.hideLoading(); + } + }) + + }, + //整理设备和检查项 + getPatrolTemplate(templateId,pointDevices=[]) { + const that=this + Request.get(getPatrolTemplate(templateId)).then(res => { + const checkItems = res.rows[0].checkItems; + let inspectContentArr = []; + // 有绑定设备的点位,每个设备都要检查各个检查项 + if (pointDevices.length) { + pointDevices.forEach(device => { + inspectContentArr.push({ + deviceName: device.name, + deviceId: device.id, + checkItems: checkItems.map(c => ({ + id: `${device.id}-${c.id}`, + name: c.name, + isNormal: null, + msgInp: null, + level: null, + imgs: [], + })) + }) + }); + } else { + inspectContentArr.push({ + checkItems: checkItems.map(c => ({ + id: c.id, + name: c.name, + isNormal: null, + msgInp: null, + level: null, + imgs: [], + })) + }) + } + this.setData({ + checkItems, + inspectContentArr: inspectContentArr, + }) + }) + }, + //选择异常或者正常 + handleChangeTwo(e) { + const isNormal = e.detail === 'normal'; + const { deviceidx, itemidx } = e.currentTarget.dataset; + let nextInspectContentArr = this.data.inspectContentArr; + + nextInspectContentArr[deviceidx].checkItems[itemidx].isNormal = isNormal; + if (isNormal) { // 清除异常数据 + nextInspectContentArr[deviceidx].checkItems[itemidx].msgInp = null; + nextInspectContentArr[deviceidx].checkItems[itemidx].level = null; + nextInspectContentArr[deviceidx].checkItems[itemidx].imgs = []; + } + this.setData({ inspectContentArr: nextInspectContentArr }) + }, + //返回前一页 + bindCancel() { + wx.navigateBack(); + }, + // 开始巡检录入 + addPatrolRecord: function () { + const that = this; + if (that.data.isCommitting) { return } + let { + patrolTemplate, + patrolTemplateIndex, + structListIndex, + pointIndex, + pointList, + inspectContentArr, + dataList, + address, + data, + templateData + } = that.data; + let alarm = false; + if (!address) { + wx.showToast({ + title: '请获取当前位置', + icon: 'none', + duration: 1500 + }) + return; + } + if (!structListIndex) { + wx.showToast({ + title: '请选择结构物', + icon: 'none', + duration: 1500 + }) + return; + } + if (!patrolTemplateIndex) { + wx.showToast({ + title: '请选择模板', + icon: 'none', + duration: 1500 + }) + return; + } + if (!pointIndex) { + wx.showToast({ + title: '请选择点位', + icon: 'none', + duration: 1500 + }) + return; + } + let reportArr = inspectContentArr.map(d => ({ ...d, alarm: false })); + for (const [index, device] of inspectContentArr.entries()) { + for (const item of device.checkItems) { + if (item.isNormal === null) { + wx.showToast({ + title: '请填写完整', + icon: 'none', + duration: 1500 + }) + return; + } + if ((!item.isNormal) && (!item.level || !item.msgInp)) { + wx.showToast({ + title: '异常项必须输入巡查详情和选择严重等级', + icon: 'none', + duration: 2000 + }) + return; + } + if (item.isNormal === false) { + alarm = true; // 巡检记录异常 + reportArr[index].alarm = true; // 设备异常 + } + } + } + const { id, name, departmentId, deptName } = wx.getStorageSync('userInfo'); + const curPlan = that.data.planList.find(item=>item.id=patrolTemplate[patrolTemplateIndex].id) + const nextItemData = curPlan.points.find(p => p.id == this.data.scenePointId) + const aboutSend=templateData.find(item=>item.patrolTemplate.id===patrolTemplate[patrolTemplateIndex].id) + let datas = { + patrolPlanId: -1, + pointId: pointList[pointIndex].id, + inspectionTime: moment().format('YYYY-MM-DD HH:mm:ss'), + points: { + user: { id, name, department: { id: departmentId, name: deptName } }, + project: aboutSend.project, + frequency: aboutSend.frequency, + itemData:nextItemData, + inspectContent: reportArr, + address: address + }, + alarm, + projectId: aboutSend.project.id + } + wx.showLoading({ title: '提交中...' }); + that.setData({ isCommitting: true }); + Request.post(reportQuest(), datas).then(res => { + wx.hideLoading(); + that.setData({ isCommitting: false }); + wx.showToast({ + title: '提交成功', + icon: 'success' + }) + setTimeout(() => { + that.bindCancel(); + }, 1500) + }) + }, + //多张图片上传 + uploadImg: function (data, deviceidx, itemidx) { + wx.showLoading({ + title: '上传中...', + mask: true, + }) + let that = this, + i = data.i ? data.i : 0, + success = data.success ? data.success : 0, + fail = data.fail ? data.fail : 0; + let imgs = that.data.inspectContentArr[deviceidx].checkItems[itemidx].imgs; + wx.uploadFile({ + url: data.url, + filePath: data.path[i], + name: 'file', + success: (resp) => { + wx.hideLoading(); + success++; + let str = JSON.parse(resp.data) // 返回的结果,可能不同项目结果不一样 + str = str.uploaded + if (imgs.length >= 20) { + let nextInspectContentArr = that.data.inspectContentArr; + nextInspectContentArr[deviceidx].checkItems[itemidx].imgs = imgs; + that.setData({ inspectContentArr: nextInspectContentArr }); + return false; + } else { + imgs.push(str); + let nextInspectContentArr = that.data.inspectContentArr; + nextInspectContentArr[deviceidx].checkItems[itemidx].imgs = imgs; + that.setData({ inspectContentArr: nextInspectContentArr }); + } + }, + fail: (res) => { + fail++; + console.log('fail:' + i + "fail:" + fail); + }, + complete: () => { + i++; + if (i == data.path.length) { // 当图片传完时,停止调用 + console.log('执行完毕'); + console.log('成功:' + success + " 失败:" + fail); + } else { // 若图片还没有传完,则继续调用函数 + data.i = i; + data.success = success; + data.fail = fail; + that.uploadImg(data, deviceidx, itemidx); // 递归,回调自己 + } + } + }); + }, + // 上传图片 + chooseImg: function (e) { // 这里是选取图片的方法 + const { deviceidx, itemidx } = e.currentTarget.dataset; + const that = this; + let pics = []; + const detailPics = that.data.inspectContentArr[deviceidx].checkItems[itemidx].imgs; + if (detailPics.length >= 20) { + wx.showToast({ + title: '最多选择20张图片上传', + icon: 'none' + }); + return; + } + wx.chooseMedia({ + count: 20, // 基础库2.25.0前,最多可支持9个文件,2.25.0及以后最多可支持20个文件 + mediaType: ['image'], // 文件类型 + sizeType: ['original', 'compressed'], // original 原图,compressed 压缩图,默认二者都有 + sourceType: ['album', 'camera'], // album 从相册选图,camera 使用相机,默认二者都有 + success: function (res) { + const imgs = res.tempFiles; + for (let i = 0; i < imgs.length; i++) { + if (res.tempFiles[i].size > 15728640) { + wx.showToast({ title: '图片大于15M,不可上传', icon: 'none' }); + return; + } + const fileNameArr = res.tempFiles[i].tempFilePath.split('.'); + const extension = res.tempFiles[i].tempFilePath.split('.')[fileNameArr.length - 1]; + if (extension !== 'jpg' && extension !== 'png' && extension !== 'jpeg') { + wx.showToast({ title: '只能上传jpg、jpeg、png格式的图片', icon: 'none' }); + return; + } + pics.push(imgs[i].tempFilePath) + } + that.uploadImg({ + url: getApp().globalData.webUrl + '_upload/attachments/project', // 图片上传的接口 + path: pics, // 选取的图片的地址数组 + }, deviceidx, itemidx); + }, + }) + }, + // 巡查详情 + bindInput: function (e) { + const { deviceidx, itemidx } = e.currentTarget.dataset; + let nextInspectContentArr = this.data.inspectContentArr; + + nextInspectContentArr[deviceidx].checkItems[itemidx].msgInp = e.detail.value; + this.setData({ inspectContentArr: nextInspectContentArr }) + }, + + handleChangeThree(e) { + const { deviceidx, itemidx } = e.currentTarget.dataset; + let nextInspectContentArr = this.data.inspectContentArr; + nextInspectContentArr[deviceidx].checkItems[itemidx].level = e.detail; + this.setData({ inspectContentArr: nextInspectContentArr }) + }, + + + //巡检模板改变 + patrolTemplateChange(e){ + const that=this + that.getPatrolTemplate(that.data.patrolTemplate[e.detail.value].id,that.data.devicesList) + that.setData({ + patrolTemplateIndex:e.detail.value + }) + }, + bindShowMsg() { + this.setData({ + select: !this.data.select + }) + }, + + mySelect(e) { + var name = e.currentTarget.dataset.name + this.setData({ + tihuoWay: name, + select: false + }) + }, + /** + * 页面的初始数据 + */ + // data: { + + // }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad(options) { + const that=this + wx.setNavigationBarTitle({ + title: options.key, + }); + + }, + onStructListPicker() { + this.setData({ + structListVisible: true + }); + }, + // 获取当前位置 + selfLocation() { + const that = this + wx.showLoading({ + title: '定位中', + mask: true, + }); + wx.getLocation({ + type: 'wgs84', + success: (res) => { + wx.request({ + url: `https://apis.map.qq.com/ws/geocoder/v1/?location=${res.latitude},${res.longitude}&key=${getApp().globalData.key}`, + success: function (res) { + wx.hideLoading(); + // 根据自己项目需求获取res内容 + that.setData({ + address: res.data.result.address + }) + } + }) + }, + fail: (res) => { + wx.hideLoading(); + wx.showToast({ + title: res.errMsg, + icon: 'none', + duration: 1000 + }); + } + }); + }, + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady() { + + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow() { + + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide() { + + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload() { + + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh() { + + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom() { + + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage() { + + } +}) \ No newline at end of file diff --git a/weapp/package/report/report.json b/weapp/package/report/report.json new file mode 100644 index 0000000..425beee --- /dev/null +++ b/weapp/package/report/report.json @@ -0,0 +1,25 @@ +{ + "navigationBarBackgroundColor": "#1979ff", + "navigationBarTextStyle": "white", + "navigationBarTitleText": "发现问题", + "enablePullDownRefresh": false, + "componentFramework": "glass-easel", + "usingComponents": { + "van-button": "@vant/weapp/button/index", + "van-field": "@vant/weapp/field/index", + "van-cell": "@vant/weapp/cell/index", + "van-cell-group": "@vant/weapp/cell-group/index", + "van-picker": "@vant/weapp/picker/index", + "van-popup": "@vant/weapp/popup/index", + "van-icon": "@vant/weapp/icon/index", + "van-collapse": "@vant/weapp/collapse/index", + "van-collapse-item": "@vant/weapp/collapse-item/index", + "van-divider": "@vant/weapp/divider/index", + "t-cell-group": "tdesign-miniprogram/cell-group/cell-group", + "t-cell": "tdesign-miniprogram/cell/cell", + "t-picker": "tdesign-miniprogram/picker/picker", + "t-picker-item": "tdesign-miniprogram/picker-item/picker-item", + "van-radio": "@vant/weapp/radio/index", + "van-radio-group": "@vant/weapp/radio-group/index" + } +} \ No newline at end of file diff --git a/weapp/package/report/report.wxml b/weapp/package/report/report.wxml new file mode 100644 index 0000000..b60b5ad --- /dev/null +++ b/weapp/package/report/report.wxml @@ -0,0 +1,96 @@ + + + + + + 结构物: + + + {{structListIndex||structListIndex==0?structList[structListIndex].name:'请选择'}} + + + + + + + + 当前点位: + + + {{pointIndex||pointIndex==0?pointList[pointIndex].name:'请选择'}} + + + + + + + + 当前位置: + + {{address}} + + + + + 点击获取 + + + + + + + 巡检模板: + + + {{patrolTemplateIndex||patrolTemplateIndex==0?patrolTemplate[patrolTemplateIndex].name:'请选择'}} + + + + + + + + + + + + + + {{device.deviceName}} + + + {{item.name}}: + + 正常 + 异常 + + + + + 轻微 + 中度 + 严重 + +