agri-app/pages/news/subpages/deviceCenter/index.vue

281 lines
7.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="message-page">
<!-- 消息列表 -->
<scroll-view
v-if="messageList.length > 0"
:scroll-y="true"
class="message-list"
:refresher-enabled="true"
refresher-background="#f5f5f5"
:refresher-triggered="refreshing"
:scroll-into-view="scrollId"
:scroll-with-animation="false"
@refresherrefresh="getList"
@scrolltolower="onLoadMore"
>
<view
v-for="(item, index) in messageList"
:key="index"
:id="`item${item.id}`"
class="message-item"
>
<!-- 时间标签:如果是第一条或者与上一条时间不同才显示 -->
<view class="time-label" v-if="index === 0 || !isSameMinute(item.createTime, messageList[index - 1].createTime)">
{{ formatTime(item.createTime) }}
</view>
<view class="champion-card">
<view class="sender-info" @click="gotoDevice(item)">
<image class="avatar" :src="avatar" mode="aspectFill"></image>
<text class="sender-text">{{ item.content }}</text>
</view>
</view>
</view>
<uni-load-more iconType="auto" v-if="messageList.length >=10"
:status="status" :content-text="contentText" />
</scroll-view>
<view class="empty__item tn-margin-top empty__view" v-else>
<tn-empty icon="https://resource.tuniaokj.com/images/empty/alien/2.png"
text="近7天暂无消息" :imgWidth="200"
:imgHeight="200"></tn-empty>
</view>
</view>
</template>
<script>
import {listMessage, updateRead} from "@/api/warn/message";
import * as mqttUtil from "@/utils/mqtt";
import {formatTime} from "@/utils/agri";
export default {
data() {
return {
refreshing: false, // 下拉刷新状态
avatar: 'https://img.xiaoces.com/photos/logo.png',
messageList: [],
isHaveOldData: true,
scrollId: null,
msgList:[],
pageNum: 0,
status: 'more',
contentText: {
contentdown: '查看更多',
contentrefresh: '加载中.....',
contentnomore: '没有更多数据了'
},
sortNewId: null,
sortOldId: null,
}
},
onLoad() {
// 只允许查询七天以内消息默认展示今天
// this.getSortDate();
this.getList();
},
onShow() {
console.info("消息日志监听")
mqttUtil.setOnMessageCallback(this.ackAlarm);
},
onHide() {
console.info("消息日志取消监听")
mqttUtil.removeOnMessageCallback();
},
onUnload() {
console.info("消息日志取消监听")
mqttUtil.removeOnMessageCallback();
},
beforeDestroy() {
console.info("消息日志取消监听")
mqttUtil.removeOnMessageCallback();
},
methods: {
formatTime,
// 判断两个时间是否是同一天同一分钟
isSameMinute(time1, time2) {
const date1 = new Date(time1);
const date2 = new Date(time2);
return date1.getFullYear() === date2.getFullYear() &&
date1.getMonth() === date2.getMonth() &&
date1.getDate() === date2.getDate() &&
date1.getHours() === date2.getHours() &&
date1.getMinutes() === date2.getMinutes();
},
getSortDate(messageList) {
return messageList.sort((a, b) => new Date(a.createTime) - new Date(b.createTime));
},
getList() {
this.refreshing = true;
if (!this.isHaveOldData) {
setTimeout(() => {
this.$modal.msg("没有更早数据!");
// 结束刷新状态
this.refreshing = false;
}, 800);
return;
}
var query = {
msgType: "status",
pageSize: 10,
sortOldId: this.sortOldId
}
listMessage(query).then(response => {
if (response.code === 200) {
if (response.rows.length > 0) {
var newData = this.getSortDate(response.rows);
this.sortOldId = response.rows[0].id
this.messageList = [...newData, ...this.msgList];
this.msgList = [...newData, ...this.msgList]
console.info("时间最早的数据id",this.sortOldId)
return;
}
this.isHaveOldData = false;
}
}).finally(()=>{
this.updateRead();
if (this.messageList.length>10) {
// 在数据更新后设置 scrollId
this.$nextTick(() => {
// 更新数据的长度
this.scrollId = "item"+this.messageList[9].id;
});
}
// 结束刷新状态
this.refreshing = false;
})
},
updateRead() {
if (this.msgList.length === 0) return;
var unReadList = this.messageList.filter(item => item.readStatus === 0);
if (unReadList.length === 0) return;
updateRead({msgType: "status"}).then(response => {
if (response.code === 200) {
console.info("更新已读成功")
}
})
},
onLoadMore() {
if (!this.sortNewId) {
this.sortNewId = this.msgList[this.msgList.length - 1].id;
}
this.status = 'loading'
var query = {
msgType: "status",
sortNewId: this.sortNewId
}
listMessage(query).then(response => {
if (response.code === 200) {
if (response.rows.length > 0) {
var newData = this.getSortDate(response.rows);
this.messageList = [...this.msgList, ...newData]
this.msgList = [...this.msgList, ...newData]
this.sortNewId = response.rows[response.rows.length-1].id
return;
}
this.$modal.msg("已是最新数据了!");
// 结束刷新状态
this.status = 'nomore'
}
}).finally(()=>{
// 在数据更新后设置 scrollId
this.$nextTick(() => {
// 更新数据的长度
this.scrollId = "item"+this.messageList[this.messageList.length-1].id;
});
// 结束刷新状态
this.status = 'more'
})
},
gotoDevice(item) {
const agriList = uni.getStorageSync('agri_list')
if (agriList.length === 0 || !agriList.includes(item.imei)) {
return
}
this.$tab.navigateTo(item.linkUrl)
},
ackAlarm(topic, payload) {
const regex = /^device\/\d+\/alarm$/;
if (!regex.test(topic)) return;
let msgData = {};
// 优化捕获JSON解析异常
try {
msgData = JSON.parse(payload);
var msg = msgData.msgType
this.messageList.push(msg)
} catch (e) {
console.error("MQTT消息解析失败", e, payload);
} finally {
this.$nextTick(() => {
this.scrollId
= "item"+this.messageList[this.messageList.length-1].id;
})
}
}
}
}
</script>
<style lang="scss">
@import '@/tuniao-ui/index.scss';
@import '@/colorui/main.css';
@import '@/colorui/icon.css';
</style>
<style scoped>
/* 页面容器 */
.message-page {
height: 100vh;
background-color: #f5f5f5;
}
/* 消息列表 */
.message-list {
padding: 20rpx;
height: 100vh; /* 修复scroll-view高度问题 */
}
.message-item {
margin: 30rpx 20rpx;
}
/* 时间标签 */
.time-label {
text-align: center;
font-size: 26rpx;
color: #999;
margin: 50rpx 20rpx 20rpx;
}
.message-item:first-child .time-label {
margin-top: 0;
}
/* 通用卡片样式 */
.like-card, .champion-card {
background-color: #fff;
border-radius: 12rpx;
padding: 24rpx;
display: flex;
align-items: center;
justify-content: space-between;
}
/* 发送者信息(点赞/冠军) */
.sender-info {
display: flex;
align-items: center;
}
.avatar {
width: 48rpx;
height: 48rpx;
border-radius: 50%;
margin-right: 16rpx;
}
.sender-text {
font-size: 30rpx;
color: #333;
}
.arrow {
font-size: 32rpx;
color: #ccc;
}
</style>