287 lines
7.9 KiB
Vue
287 lines
7.9 KiB
Vue
<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 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;
|
||
var words = topic.split("/");
|
||
const agriList = uni.getStorageSync('agri_list')
|
||
if (agriList.length === 0 || !agriList.includes(words[1])) {
|
||
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>
|
||
page {
|
||
background-color: #f5f5f5;
|
||
}
|
||
/* 页面容器 */
|
||
.message-page {
|
||
height: 100vh;
|
||
}
|
||
|
||
/* 消息列表 */
|
||
.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> |