重构第一版 智控助手小程序

This commit is contained in:
2025-12-30 15:21:19 +08:00
parent c25e282398
commit 3852e6ac20
32 changed files with 3584 additions and 123 deletions

View File

@@ -1,4 +1,10 @@
// pages/basics/MakingRounds/process/process.js
const app = getApp()
import {
GetRoomAddressStatus,
QueryDeviceList,
WriteRoomVisitLog,
SetRCUService
} from '../../../../lib/RequestingCenter.js'
Page({
/**
@@ -7,23 +13,7 @@ Page({
data: {
RoomNumber:"",
HotelName:"",
deviceList:[
{id:1, name:'取电面板通讯', status:'在线',note:'在线',isnote:"0"},
{id:2, name:'温控面板通讯', status:'在线',note:'在线',isnote:0},
{id:3, name:'红外转发通讯', status:'离线',note:'在线',isnote:0},
{id:4, name:'485窗帘电机通讯',status:'在线',note:'在线',isnote:0},
{id:5, name:'门口传感器测试', status:'显示',note:'在线',isnote:0},
{id:6, name:'卫生间传感器测试',status:'显示',note:'在线',isnote:0},
{id:7, name:'淋浴间传感器测试',status:'不显示',note:'在线',isnote:0},
{id:8, name:'床尾传感器测试', status:'不显示',note:'在线',isnote:0},
{id:9, name:'镜前传感器测试', status:'不显示',note:'在线',isnote:0},
{id:10,name:'休闲区传感器测试',status:'不显示',note:'在线',isnote:0},
{id:11,name:'客厅传感器测试', status:'不显示',note:'在线',isnote:0},
{id:12,name:'厅卫传感器测试', status:'不显示',note:'在线',isnote:0},
{id:13,name:'浴缸传感器测试', status:'不显示',note:'在线',isnote:0},
{id:14,name:'门磁测试', status:'不显示',note:'在线',isnote:0},
{id:15,name:'干接点窗帘测试', status:'正常',note:'在线',isnote:0} // 最后一条你自行改状态
],
deviceList:[],
deviceListindex:0,
inputValue:"",
toView:"",
@@ -32,15 +22,22 @@ Page({
note:"",
noteok:"",
errorsNumber:0,
HotelId:""
HotelId:"",
RoomTypeID:"",
showErrorReasonInput: false, // 控制异常原因输入框显示/隐藏
errorReason: "", // 异常原因内容
},
// 定时器ID
timer5s: null,
timer1min: null,
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
onLoad:async function(options) {
if (!options.RoomNumber || !options.HotelName ||!options.HotelId) {
if (!options.RoomNumber || !options.HotelName ||!options.HotelId ||!options.RoomTypeID) {
app.toast(2, "无酒店信息~")
return;
}
@@ -48,15 +45,95 @@ Page({
this.setData ({
RoomNumber:options.RoomNumber,
HotelName:options.HotelName,
HotelId:options.HotelId
HotelId:options.HotelId,
RoomTypeID:options.RoomTypeID
})
console.log(app.globalData.HotelCode)
// let HotelId =parseInt(app.globalData.HotelCode);
// await GetRoomAddressStatus({
// Code: HotelId,
// RoomNum:options.RoomNumber
// }).then(res => {
// if (res.Status == 200) {
// } else {
// app.toast(2, res.Message || "网络繁忙")
// }
// }, err => {
// console.log(err)
// app.toast(2, "网络繁忙")
// }).catch(err => {
// console.log(err)
// app.toast(2, "网络繁忙")
// });
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
onReady:async function() {
//debugger
this.calcScrollHeight();
// 页面加载完毕时调用QueryDeviceList获取设备列表
await this.getDeviceList();
},
/**
* 获取设备列表
*/
getDeviceList:async function() {
try {
const res = await QueryDeviceList({
HotelID: app.globalData.HotelCode,
RoomTypeID: this.data.RoomTypeID
});
if (res.Status == 1) {
console.log('设备列表获取成功:', res.Data);
// 更新设备列表数据
let deviceList = [];
for (let index = 0; index < res.Data.length; index++) {
const element = res.Data[index];
// 检查是否已存在相同名称的设备
const isExist = deviceList.some(item => item.name === element.DevName);
if (!isExist) {
deviceList.push({
id: deviceList.length + 1,
name: element.DevName,
status: "在线",
note: element.Process,
isnote: 0,
Addrlist: [element.DevAddr]
});
} else {
// 如果设备已存在将新地址添加到Addrlist中
const existingDevice = deviceList.find(item => item.name === element.DevName);
if (existingDevice) {
// 检查Addrlist中是否已存在该地址避免重复添加
if (!existingDevice.Addrlist.includes(element.DevAddr)) {
existingDevice.Addrlist.push(element.DevAddr);
}
}
}
}
this.setData({
deviceList: deviceList
});
} else {
console.log('设备列表获取失败:', res.Message);
app.toast(2, res.Message || "获取设备列表失败");
}
} catch (error) {
console.log('获取设备列表出错:', error);
app.toast(2, "获取设备列表失败");
}
},
calcScrollHeight() {
// 1. 拿到屏幕可用高度px
@@ -66,7 +143,7 @@ Page({
// 2. 拿到 scroll-view 的 toppx
wx.createSelectorQuery()
.in(this)
.select('#myScroll')
.select('#NmyScroll')
.boundingClientRect(rect => {
if (rect) {
const topPx = rect.top; // px
@@ -85,21 +162,172 @@ Page({
* 生命周期函数--监听页面显示
*/
onShow() {
// 启动定时器
this.startTimers();
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
// 停止定时器
this.stopTimers();
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
// 停止定时器
this.stopTimers();
},
/**
* 启动定时器
*/
startTimers() {
// 先调用一次SetRCUService
this.callSetRCUService();
// 再调用一次GetRoomAddressStatus
this.callGetRoomAddressStatus();
// 设置5秒定时器查询设备离在线状态
this.timer5s = setInterval(() => {
this.callGetRoomAddressStatus();
}, 5000);
// 设置1分钟定时器启动设备巡检
this.timer1min = setInterval(() => {
this.callSetRCUService();
}, 60000);
},
/**
* 停止定时器
*/
stopTimers() {
if (this.timer5s) {
clearInterval(this.timer5s);
this.timer5s = null;
}
if (this.timer1min) {
clearInterval(this.timer1min);
this.timer1min = null;
}
},
/**
* 调用SetRCUService接口
*/
async callSetRCUService() {
// 解析.NET风格的日期格式 "/Date(1473004800000)/"
let dotNetDate = app.globalData.CreatDate
let timestamp, pageCreateTime
try {
timestamp = parseInt(dotNetDate.match(/\d+/)[0])
pageCreateTime = new Date(timestamp)
} catch (error) {
console.error('日期解析错误:', error)
// 如果解析失败,使用当前日期作为备选
pageCreateTime = new Date()
}
let year = pageCreateTime.getFullYear()
let month = (pageCreateTime.getMonth() + 1).toString().padStart(2, '0')
let day = pageCreateTime.getDate().toString().padStart(2, '0')
let CreateTime = `${year}-${month}-${day}`
try {
const params = {
code: app.globalData.HotelCode,
creatDate:CreateTime,
roomNumber: this.data.RoomNumber,
modalAddress:"004000029",
status: "1"
};
const res = await SetRCUService(params);
console.log('SetRCUService调用成功:', res);
} catch (error) {
console.error('SetRCUService调用失败:', error);
}
},
/**
* 调用GetRoomAddressStatus接口
*/
async callGetRoomAddressStatus() {
//debugger
try {
const params = {
Code: parseInt(app.globalData.HotelCode),
RoomNum: this.data.RoomNumber
};
const res = await GetRoomAddressStatus(params);
//console.log('GetRoomAddressStatus调用成功:', res);
// 更新设备状态
if (res.Status === 1 && res.Data) {
this.updateDeviceStatus(res.Data);
}
} catch (error) {
console.error('GetRoomAddressStatus调用失败:', error);
}
},
/**
* 更新设备状态
*/
updateDeviceStatus(data) {
let deviceList = this.data.deviceList;
// 检测data和deviceList是否有数据若无数据则退出函数
if (!data || !deviceList || deviceList.length === 0) return;
// 先将所有设备标记为在线
deviceList = deviceList.map(device => ({
...device,
status: '在线'
}));
// 遍历设备异常数据集合data
for (const exceptionAddr in data) {
if (data.hasOwnProperty(exceptionAddr)) {
// 取异常地址的前6个字符
const exceptionAddrPrefix = exceptionAddr.toString().substring(0, 6);
// 遍历设备列表
for (let index = 0; index < deviceList.length; index++) {
const device = deviceList[index];
let isMatched = false;
// 遍历设备的地址集合
for (let addrIndex = 0; addrIndex < device.Addrlist.length; addrIndex++) {
const deviceAddr = device.Addrlist[addrIndex];
// 取设备地址的前6个字符
const deviceAddrPrefix = deviceAddr.toString().substring(0, 6);
// 比较地址前缀
if (deviceAddrPrefix === exceptionAddrPrefix) {
// 地址匹配,将设备标记为离线
deviceList[index].status = '离线';
isMatched = true;
break; // 退出当前设备的地址循环
}
}
if (isMatched) {
continue; // 匹配成功,遍历下一个设备
}
}
}
}
// 更新设备列表
this.setData({
deviceList: deviceList
});
console.log('设备状态更新完成:', deviceList);
},
/**
@@ -131,29 +359,52 @@ Page({
DialogModal1(e){
let deviceList = this.data.deviceList
let deviceListindex=this.data.deviceListindex
deviceList[deviceListindex].equipmentstatus=e.currentTarget.dataset.id
const status = e.currentTarget.dataset.id
this.setData({
modalName: null,
deviceList:deviceList
})
console.log(this.data.deviceList)
},
DialogModal2(e){
let deviceList = this.data.deviceList
let deviceListindex=this.data.deviceListindex
if (e.currentTarget.dataset.id==="hideModal_1") {
deviceList[deviceListindex].isnote=1
}else{
deviceList[deviceListindex].isnote=0
// 如果选择异常,显示异常原因弹窗
if (status === 'hideModal_0') {
// 先设置设备状态为异常
deviceList[deviceListindex].equipmentstatus = status
// 重新计算异常数量
const errorsNumber = deviceList.filter(device => device.equipmentstatus === 'hideModal_0').length;
this.setData({
errorReason: deviceList[deviceListindex].errorReason || "", // 显示已有的异常原因
modalName: "DialogModal4",
deviceList: deviceList,
errorsNumber: errorsNumber
})
} else {
// 选择正常,直接保存状态并关闭弹窗
deviceList[deviceListindex].equipmentstatus = status
// 清除异常原因
deviceList[deviceListindex].errorReason = undefined
// 重新计算异常数量
const errorsNumber = deviceList.filter(device => device.equipmentstatus === 'hideModal_0').length;
this.setData({
modalName: null,
deviceList: deviceList,
errorsNumber: errorsNumber
})
}
this.setData({
deviceList:deviceList
console.log(this.data.deviceList)
},
DialogModal2(e){
this.setData({
modalName: "DialogModal3"
})
console.log(this.data.deviceList)
},
DialogModal3(e){
this.setData({
modalName:""
})
},
inputSearchForHotels(e){
this.setData({
note: e.detail.value
@@ -171,12 +422,106 @@ Page({
let deviceListindex=this.data.deviceListindex
let note=this.data.note
let noteok=e.currentTarget.dataset.id
deviceList[deviceListindex].isnote= 0
if (noteok==="ok") {
deviceList[deviceListindex].note= note
}
this.setData({
deviceList:deviceList
this.setData({
deviceList:deviceList,
modalName: "DialogModal1"
})
},
// 处理异常原因输入
inputErrorReason(e){
this.setData({
errorReason: e.detail.value
})
},
// 确认异常原因弹窗
confirmErrorReasonModal(){
let deviceList = this.data.deviceList
let deviceListindex=this.data.deviceListindex
// 保存异常原因到设备节点
deviceList[deviceListindex].errorReason = this.data.errorReason
this.setData({
deviceList: deviceList,
modalName: null, // 退出所有弹窗
errorReason: ""
})
console.log("异常原因已保存:", deviceList[deviceListindex])
},
// 取消异常原因弹窗
cancelErrorReasonModal(){
let deviceList = this.data.deviceList
let deviceListindex=this.data.deviceListindex
// 如果还没有保存过异常原因,将设备状态改回未检测
if (!deviceList[deviceListindex].errorReason) {
deviceList[deviceListindex].equipmentstatus = undefined
// 重新计算异常数量
const errorsNumber = deviceList.filter(device => device.equipmentstatus === 'hideModal_0').length;
this.setData({
deviceList: deviceList,
errorsNumber: errorsNumber
})
}
this.setData({
modalName: "DialogModal1", // 返回之前的弹窗
errorReason: ""
})
},
/**
* 上传查房状态
*/
async uploadWardRoundStatus() {
const deviceList = this.data.deviceList
// 检查所有设备是否已设置equipmentstatus状态
const allSet = deviceList.every(device => device.equipmentstatus !== undefined && device.equipmentstatus !== null)
if (!allSet) {
app.toast(2, "请先完成所有设备的状态检测")
return
}
try {
// 构造请求参数
const params = {
HotelID: this.data.HotelId,
RoomNumber: this.data.RoomNumber,
EquipmentList: deviceList.map(device => ({
EquipmentStatus: device.equipmentstatus === 'hideModal_1' ? '正常' : device.equipmentstatus === 'hideModal_0' ? '故障' : '',
FaultDescription: device.errorReason || '',
DevName: device.name,
EquipmentStatusType: device.equipmentstatus === 'hideModal_1' ? '1' : device.equipmentstatus === 'hideModal_0' ? '2' : '',
EquipmentOnlineStatus: device.status === '在线' ? '1' : '2'
}))
}
// 调用接口上传数据
const res = await WriteRoomVisitLog(params)
// 处理返回结果
if (res.Status === 1) {
app.toast(1, res.Message || "上传成功")
console.log("上传成功", res)
} else {
app.toast(2, res.Message || "上传失败")
console.log("上传失败", res)
}
} catch (error) {
app.toast(2, "上传失败,请检查网络连接")
console.error("上传出错", error)
}
},
/**
* 刷新设备列表
*/
refreshDeviceList() {
// 调用getDeviceList函数刷新设备列表
this.getDeviceList()
},
})

View File

@@ -4,24 +4,24 @@
<view slot="content">({{HotelName}})_{{RoomNumber}}</view>
</cu-custom>
<view class="flex solid-bottom justify-between ">
<view class=" padding-xs margin-sm radius">
<view class=" padding-5 margin-5 radius">
<text class="text-black">异常数量:</text>
<text class="text-red">1</text>
<text class="text-red">{{errorsNumber}}</text>
<text class="text-black">/{{deviceList.length}}</text>
</view>
<view class="bg-grey padding-xs margin-sm radius" hover-class="navigator-hover" bindtap="checkWardRoundRecords" >查看查房记录</view>
<view class="bg-grey padding-xs margin-sm radius" hover-class="navigator-hover">上传查房状态</view>
<view class="bg-grey padding-5 margin-5 radius" hover-class="navigator-hover" bindtap="checkWardRoundRecords" >查看查房记录</view>
<view class="bg-grey padding-5 margin-5 radius" hover-class="navigator-hover" bindtap="uploadWardRoundStatus">上传查房状态</view>
<view class="bg-grey padding-5 margin-5 radius" hover-class="navigator-hover" bindtap="refreshDeviceList">刷新设备</view>
</view>
<!-- 设备状态表格 -->
<!-- 设备状态表格 -->
<view class="th">
<text class="th-item">设备名称</text>
<text class="th-item">状态</text>
<text class="th-item">设备检测</text>
<text class="th-item td ">状态</text>
<text class="th-item td2">设备检测</text>
</view>
<scroll-view scroll-y scroll-into-view="{{toView}}" id="myScroll" style="height:{{scrollHeight}}rpx;">
<scroll-view scroll-y scroll-into-view="{{toView}}" id="NmyScroll" style="height:{{scrollHeight}}rpx;">
<view class="device-table">
<block wx:for="{{deviceList}}" wx:key="id">
<view class="tr">
@@ -29,14 +29,12 @@
<text class="th-item {{item.equipmentstatus==='hideModal_1'? 'bg-green':item.equipmentstatus==='hideModal_0'? 'bg-red':'textbcolor'}} ">{{item.name}}</text>
<!-- 状态 -->
<view class="td status">
<text class="status-text {{item.status==='在线'||item.status==='显示'?'on':'off'}}">
{{item.status}}
</text>
<view class="td status" style="margin-left: 10rpx;" >
<text class="status-text {{item.status==='在线'||item.status==='显示'?'on':'off'}}">{{item.status}}</text>
</view>
<!-- 按钮 -->
<view class="td btn-group">
<view class="td2 btn-group">
<button class="btn green" data-id="{{item.id}}" data-st="正常" data-target="DialogModal1" bindtap="showModal">设备检测</button>
</view>
@@ -59,25 +57,51 @@
</view>
<view class="cu-bar bg-white justify-end">
<view class="action">
<button class="cu-btn bg-gray text-xl text-blue" data-id="hideModal_1" bindtap="DialogModal2">修改检测流程</button>
<button class="cu-btn bg-red text-xl text-black margin-left" data-id="hideModal_0" bindtap="DialogModal1">异常</button>
<button class="cu-btn bg-green text-xl text-black margin-left" data-id="hideModal_1" bindtap="DialogModal1">正常</button>
<button class="cu-btn bg-gray text-xl text-blue" data-id="hideModal_1" bindtap="DialogModal2" disabled="{{modalName=='DialogModal3'}}" >修改检测流程</button>
<button class="cu-btn bg-red text-xl text-black margin-left" data-id="hideModal_0" bindtap="DialogModal1" disabled="{{modalName=='DialogModal3'}}" >异常</button>
<button class="cu-btn bg-green text-xl text-black margin-left" data-id="hideModal_1" bindtap="DialogModal1" disabled="{{modalName=='DialogModal3'}}" >正常</button>
</view>
</view>
</view>
</view>
<view wx:if="{{deviceList[deviceListindex].isnote === 1 }}" >
<view class=" text-left" > 检测流程:</view>
<textarea auto-height maxlength="-1" class="solids " focus="true" bindinput="inputSearchForHotels" confirm-type="return" style="width: 100%;font-size: 32rpx;text-align: left;white-space: pre-wrap; word-break: break-all; line-height: 1.5;" value=" {{deviceList[deviceListindex].note}}"/>
<view class="cu-bar bg-white justify-end">
<view class="action">
<button class="cu-btn bg-red text-xl text-black margin-left" data-id="cancel" bindtap="saveTheText">取消</button>
<button class="cu-btn bg-green text-xl text-black margin-left" data-id="ok" bindtap="saveTheText">保存</button>
<!-- 修改检测流程弹窗 -->
<view class="cu-modal {{modalName=='DialogModal3'?'show':''}}">
<view class="cu-dialog">
<view class="cu-bar bg-white justify-end">
<view class="content">修改检测流程 - {{deviceList[deviceListindex].name}}</view>
</view>
<view >
<view class=" text-left" > 检测流程:</view>
<textarea auto-height maxlength="-1" class="solids " focus="true" bindinput="inputSearchForHotels" confirm-type="return" style="width: 95%;font-size: 32rpx;text-align: left;white-space: pre-wrap; word-break: break-all; line-height: 1.5;" value=" {{deviceList[deviceListindex].note}}"/>
</view>
<view class="cu-bar bg-white justify-end">
<view class="action">
<button class="cu-btn bg-red text-xl text-black margin-left" data-id="cancel" bindtap="saveTheText">取消</button>
<button class="cu-btn bg-green text-xl text-black margin-left" data-id="ok" bindtap="saveTheText">保存</button>
</view>
</view>
</view>
</view>
<!-- 异常原因输入弹窗 -->
<view class="cu-modal {{modalName=='DialogModal4'?'show':''}}">
<view class="cu-dialog">
<view class="cu-bar bg-white justify-end">
<view class="content">异常原因 - {{deviceList[deviceListindex].name}}</view>
</view>
<view >
<view class=" text-left" > 请输入异常原因:</view>
<textarea auto-height maxlength="-1" class="solids " focus="true" bindinput="inputErrorReason" confirm-type="return" style="width: 95%;font-size: 32rpx;text-align: left;white-space: pre-wrap; word-break: break-all; line-height: 1.5;" value=" {{errorReason}}"/>
</view>
<view class="cu-bar bg-white justify-end">
<view class="action">
<button class="cu-btn bg-red text-xl text-black margin-left" bindtap="cancelErrorReasonModal">取消</button>
<button class="cu-btn bg-green text-xl text-black margin-left" bindtap="confirmErrorReasonModal">确定</button>
</view>
</view>
</view>
</view>

View File

@@ -5,9 +5,10 @@
.textbcolor{ background-color: #f0f0f0;}
.device-table{ margin: 20rpx; font-size: 28rpx; }
.th{ display: flex; border-bottom: 2rpx solid #e0e0e0; padding: 15rpx 0; }
.th-item{ flex: 1; text-align: center; font-weight: bold; }
.th-item{ flex: 6; text-align: center; font-weight: bold; }
.tr{ display: flex; align-items: center; padding: 15rpx 0; border-bottom: 1rpx solid #f0f0f0; }
.td{ flex: 1; text-align: center; }
.td2{ flex: 3; text-align: center; }
.name{ text-align: left; padding-left: 10rpx; }
.status-text{ padding: 4rpx 12rpx; border-radius: 6rpx; color: #fff; font-size: 24rpx; }
.on{ background: #07c160; }