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

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

@@ -0,0 +1,135 @@
// pages/basics/progress/RoomTypeControlLog/RoomTypeControlLog.js
const app = getApp()
Page({
/**
* 页面的初始数据
*/
data: {
Hotelinfo: null,
HotelId: null,
RoomNumber: null,
sectionsList: [
{
id: 1,
name: '刷卡记录',
icon: 'card',
color: '#4CAF50',
count: 0
},
{
id: 2,
name: '回路状态记录',
icon: 'circuit',
color: '#2196F3',
count: 0
},
{
id: 3,
name: '回路异常记录',
icon: 'warning',
color: '#FF9800',
count: 0
},
{
id: 4,
name: '外设异常记录',
icon: 'device',
color: '#F44336',
count: 0
},
{
id: 5,
name: '语音上报记录',
icon: 'voice',
color: '#9C27B0',
count: 0
}
]
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
console.log('RoomTypeControlLog onLoad options:', options);
if (options.HotelId && options.RoomNumber && options.HotelName) {
this.setData({
HotelId: options.HotelId,
RoomNumber: options.RoomNumber,
Hotelinfo: {
HotelName: options.HotelName,
Code: ''
}
});
}
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
},
/**
* 返回上一页
*/
back() {
wx.navigateBack({
delta: 1
});
},
/**
* 点击板块列表项
*/
tap板块列表项(e) {
const { id, name } = e.currentTarget.dataset;
console.log('点击了板块:', name, 'ID:', id);
// 这里可以添加点击事件的处理逻辑,比如跳转到对应记录的详细页面
}
})

View File

@@ -0,0 +1,3 @@
{
"usingComponents": {}
}

View File

@@ -0,0 +1,34 @@
<cu-custom bgColor="bg-gradual-blue"
isBack="true">
<block bindtap="back" slot="backText" >返回</block>
<view slot="content">{{Hotelinfo.HotelName}}({{Hotelinfo.Code}})</view>
</cu-custom>
<!-- 房间信息 -->
<view class="bg-white padding-sm margin-top-xs" style="border-bottom: 1px solid #f0f0f0;">
<view class="flex justify-between align-center">
<view class="text-df font-bold">房间号:{{RoomNumber}}</view>
<view class="text-sm text-gray">房间控制日志</view>
</view>
</view>
<!-- 板块列表 -->
<view class="margin-top-xs" >
<view class="nav-list1 bg-white" style="margin-top: 0;">
<view
bindtap="tap板块列表项"
data-id="{{item.id}}"
data-name="{{item.name}}"
hover-class="navigator-hover"
class="nav-li4"
style="background-color: {{item.color}}; margin: 10rpx; width: calc(50% - 20rpx);"
wx:for="{{sectionsList}}"
wx:key="id">
<view class="flex flex-column align-center" style="width: 100%; height: 100%;">
<view class="text-white" style="font-size: 32rpx; margin-bottom: 10rpx;">{{item.name}}</view>
<view class="text-white" style="font-size: 24rpx; opacity: 0.8;">共 {{item.count}} 条记录</view>
</view>
</view>
</view>
</view>

View File

@@ -0,0 +1 @@
/* pages/basics/progress/RoomTypeControlLog/RoomTypeControlLog.wxss */

View File

@@ -0,0 +1,293 @@
// pages/basics/progress/progress.js
const app = getApp()
import {
GetHostsInfo,
GetMAC,
GetFaceSN,
ErrorInfo,
CheckFaceSN,
OpenDoorTest,
GetRoomType,
GetRoomTypeAndModalsListLog,
WebChatUpgrade,
QueryUpdateHostStatus,
ForwardQueryUpdateHostProgressBar,
GetRoomTypeNode,
SetRCULight,
SetRCUAir,
SetRCUCurtain,
GetRoomAddressStatus
} from '../../../lib/RequestingCenter.js'
Page({
/**
* 页面的初始数据
*/
data: {
RoomIndex:0,
//权限信息
autho: null,
//酒店信息
Hotelinfo: null,
HostsData:null,
HostsDataFilters:[],
isback:null,
HotelId:null,
statusdata:null,
onlineNumber:0,
inputValue:"",
toView:"",
scrollHeight: 0
},
/**
* 生命周期函数--监听页面加载
*/
onLoad:async function(options) {
if (!options.HotelId || app.globalData.autho == null) {
app.toast(2, "无酒店信息~")
return;
}
this.setData({
autho: app.globalData.autho
})
try {
this.data.autho.forEach((element, index) => {
element.Hotels.forEach((elements, indexs) => {
if (elements.HotelId == options.HotelId) {
this.setData({
Hotelinfo: elements
})
throw new Error();
}
})
});
} catch (error) {
console.log("已经找到,无需循环~")
}
let that = this
await GetHostsInfo({
HotelID: this.data.Hotelinfo.HotelId
}).then(res => {
if (res.Status == 200) {
let onlineNumber=0
for (let index = 0; index < res.Data.length; index++) {
const element = res.Data[index];
if (element.Status===1) {
onlineNumber=onlineNumber+1
}
}
that.setData({
onlineNumber:onlineNumber,
HostsData: res.Data,
HostsDataFilters: res.Data,
isback: (app.globalData.autho.length > 1 || app.globalData.autho[0].Hotels.length > 1),
HotelId: options.HotelId,
statusdata: [0, 0, 0, res.Data.length]
})
console.log(this.data.HostsDataFilters)
} else {
app.toast(2, res.Message || "网络繁忙")
}
}, err => {
console.log(err)
app.toast(2, "网络繁忙")
}).catch(err => {
console.log(err)
app.toast(2, "网络繁忙")
});
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
this.calcScrollHeight();
},
calcScrollHeight() {
// 1. 拿到屏幕可用高度px
const sys = wx.getSystemInfoSync();
const screenHeight = sys.windowHeight; // px
// 2. 拿到 scroll-view 的 toppx
wx.createSelectorQuery()
.in(this)
.select('#myScroll')
.boundingClientRect(rect => {
if (rect) {
const topPx = rect.top; // px
const bottomPx = 10 / 2; // 10rpx → 5px2倍屏
const heightPx = screenHeight - topPx - bottomPx;
// 3. 转 rpx 并写入
this.setData({
scrollHeight: heightPx * 2 // px→rpx
});
}
})
.exec();
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
},
inputSearchForHotels(e){
this.setData({
inputValue: e.detail.value
})
},
SearchForHotels(e){
//debugger
let myarry =this.data.HostsDataFilters
let inputValue =this.data.inputValue.trim()
const CNaelement =this.sortHotelsByFuzzyMatch(myarry,inputValue)
this.setData({
HostsDataFilters:CNaelement
})
},
goProcess(e) {
let indexstr = e.currentTarget.id.replace("msg-","")
let index= Number(indexstr)
const { room, hotel, status } = e.currentTarget.dataset;
this.setData({
RoomIndex:index
} )
let HostsDataFilters= this.data.HostsDataFilters
console.log(HostsDataFilters[index].RoomNumber)
// 取消状态检查,无论状态如何都允许跳转
wx.navigateTo({
url: `/pages/basics/progress/RoomTypeControlLog/RoomTypeControlLog?RoomNumber=${room}&HotelName=${hotel}&HotelId=${this.data.Hotelinfo.HotelId }`
});
},
RefreshTheRoom:async function(e){
let that = this
await GetHostsInfo({
HotelID: this.data.Hotelinfo.HotelId
}).then(res => {
if (res.Status == 200) {
let onlineNumber=0
for (let index = 0; index < res.Data.length; index++) {
const element = res.Data[index];
if (element.Status===1) {
onlineNumber=onlineNumber+1
}
}
that.setData({
RoomIndex:0,
onlineNumber:onlineNumber,
HostsData: res.Data,
HostsDataFilters: res.Data,
isback: (app.globalData.autho.length > 1 || app.globalData.autho[0].Hotels.length > 1),
statusdata: [0, 0, 0, res.Data.length]
})
console.log(this.data.HostsDataFilters)
} else {
app.toast(2, res.Message || "网络繁忙")
}
}, err => {
console.log(err)
app.toast(2, "网络繁忙")
}).catch(err => {
console.log(err)
app.toast(2, "网络繁忙")
});
},
sortHotelsByFuzzyMatch:function(hotels, keyword) {
// 1. 参数验证
if (!Array.isArray(hotels)) {
console.warn('第一个参数必须是数组');
return [];
}
if (typeof keyword !== 'string') {
console.warn('第二个参数必须是字符串');
return hotels.slice();
}
// 2. 处理空数组或空关键字的情况
const trimmedKeyword = keyword.trim();
if (hotels.length === 0 || trimmedKeyword === '') {
return hotels.slice();
}
const lowerKeyword = trimmedKeyword.toLowerCase();
// 3. 分离匹配和不匹配的酒店
const matchedHotels = [];
const unmatchedHotels = [];
hotels.forEach(hotel => {
// 检查是否为有效酒店对象
if (!hotel || typeof hotel !== 'object' || !hotel.RoomNumber) {
unmatchedHotels.push(hotel);
return;
}
const hotelName = String(hotel.RoomNumber).toLowerCase();
const isMatch = hotelName.includes(lowerKeyword);
if (isMatch) {
matchedHotels.push(hotel);
} else {
unmatchedHotels.push(hotel);
}
});
// 4. 合并数组并返回
return [...matchedHotels, ...unmatchedHotels];
},
})

View File

@@ -0,0 +1,3 @@
{
"usingComponents": {}
}

View File

@@ -0,0 +1,46 @@
<cu-custom bgColor="bg-gradual-blue"
isBack="true">
<block bindtap="back" slot="backText" >返回</block>
<view slot="content">{{Hotelinfo.HotelName}}({{Hotelinfo.Code}})</view>
</cu-custom>
<view class=" solids bg-white" style="height:70px ;width: 100%;font-weight: bold; ">
<view class="flex text-xl" style=" height:45% ;width: 100%;">
<view class="solids" wx:if="{{RoomIndex>=0}}" style="height:100% ;width: 50%;">
<text class="text-black">房号:{{HostsDataFilters[RoomIndex].RoomNumber}}</text>
</view>
<view class="solids" wx:if="{{RoomIndex>=0}}" style="height:100% ;width: 50%;">
<text class="text-black">房间在线:</text>
<text class="text-blue">{{onlineNumber}}/</text>
<text class="text-black">{{HostsDataFilters.length}} </text>
</view>
</view>
<view class="cu-bar1 bg-white " style="height:50% ;width: 100%;" >
<view class="solids" style="width: 60%;">
<input class="solids cu-btn1" focus="true" bindinput="inputSearchForHotels" confirm-type="search" style="width: 100%;"/>
</view>
<view class="flex"style="width: 40%;">
<button class="cu-btn1 line-green margin-left " style="width: 100%; margin:5rpx;" bindtap="SearchForHotels">搜索</button>
<button class="cu-btn1 line-green margin-left " style="width: 100%; margin:5rpx;" bindtap="RefreshTheRoom">刷新</button>
</view>
</view>
</view>
<scroll-view scroll-y scroll-into-view="{{toView}}" id="myScroll" style="height:{{scrollHeight}}rpx;" >
<view class='nav-list1 bg-white' style="margin-top: 20rpx;">
<view bindtap="goProcess" data-room="{{item.RoomNumber}}" data-hotel="{{Hotelinfo.HotelName}}"
data-status="{{item.Status}}" hover-class="navigator-hover" class="nav-li4 bg-{{item.Status===1? 'cyan':'gray'}}" wx:for="{{HostsDataFilters}}" id="msg-{{index}}" wx:key>
<view style="font-size: 32rpx;justify-content:start" >{{item.RoomNumber}}</view>
<view style="font-size: 20rpx;justify-content:start" >{{item.MAC}}</view>
</view>
</view>
</scroll-view>

View File

@@ -0,0 +1,102 @@
/* pages/basics/progress/progress.wxss */
.aside{
width:8rem;
border-right: 1px solid #ddd;
font-size: .85rem;
}
.type-nav{
width:8rem;
position: relative;
padding:.7rem .3rem;
text-align: center;
border-bottom: 1px solid #ddd;
z-index: 10;
}
.flex-wrap{
display: flex;
}
.type-nav.selected{
margin-right: -1px;
padding-left:0,-1px;
color: #333;
background-color: #fff;
}
/* .content{
background-color: #fff;
} */
.dish{
margin-left: 1rem;
padding: 1rem;
border-bottom: 1px solid #ddd;
}
.dish .title{
display: block;
font-size: 1rem;
}
.dish p{
color: orange;
font-size: .75rem;
}
.dish .add-btn{
width: 8rem;
text-align: right;
}
.cu-bar1 {
display: flex;
align-items: center;
justify-content: space-between;
}
.cart{
display: block;
position: fixed;
left: 0;
right: 0;
bottom: 0;
padding: 1rem;
background: #ddd;
}
.container {
height: 50%;
box-sizing: border-box;
background-color: #f4f4f4;
}
.cu1-btn {
position: relative;
border: 0rpx;
display: inline-flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
padding: 5rpx 5rpx;
font-size: 26rpx;
height: 70rpx;
line-height: 1;
text-align: center;
text-decoration: none;
overflow: visible;
margin-left: initial;
transform: translate(0rpx, 0rpx);
margin-right: initial;
}
.cu-btn1 {
position: relative;
border: 0rpx;
display: inline-flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
padding: 0 5rpx;
font-size: 26rpx;
height: 64rpx;
line-height: 1;
text-align: center;
text-decoration: none;
overflow: visible;
margin-left: initial;
transform: translate(0rpx, 0rpx);
margin-right: initial;
}