标消息开发页msgindex.vue
一、来消息的数量自加
1.消息数量实时更新的部分有四个:协同消息数量、应用消息数量、公告消息数量、消息总数。
2.问题研究:每当后台发送一条消息过来,消息页对应部分显示数字徽标。涉及到实时更新的问题,因为uniapp框架的页面不可能周期的调用后端接口实现实时更新。那么使用Websocket组件被动的使数量的实时更新。(你喜欢被动吗?)消息页面的不涉及到触发条件的更新,需要使用websocket,当然后端不可能把数量的变量直接推给咱们,顶多把表单分三类通过websocket发给咱们。咱们要进一步的对数量的加加减减进行处理。
逻辑实现
3.圈1、圈2、圈3,都是正常现象,websocket发过来的值直接用在<view>里就可以。如下:
4.但是圈4-tabBar,这个傻逼东西做的就很狗,它他妈的用
if(this.$store.state.wsAllnum>0){
uni.setTabBarBadge({
index: 0,
text:this.$store.state.wsAllnum.toString(),
})
}
else if(this.$store.state.wsAllnum==0){
uni.removeTabBarBadge({
index: 0,
})
};
这个来写,这个需要触发条件,但是消息数量实时更新在.vue界面是不会有触发条件的,来了就能显示。还好这个东西可以全局使用,我把它放在了websocket组件的.js文件里的来消息函数进行触发。如上图逻辑实现的圈4。注:在使用uni.setTabBarBadge的时候,注意textd的数据类型是字符串,要将数字转换成字符串的格式。(太傻逼了)
5.同时为了防止前端数据丢失以及接下来两个页面的数据交换打基础,使用了uniapp的数据缓存函数。
uni.setStorage({
key: 'msgSynergykey',
data: state.wsSynergynum,
success: function () {
}
});
console.log("皆",state.wsSynergyDate);
uni.getStorage({
key:'msgSynergykey',
success:(res)=>{
if(res.data){
state.wsSynergynum = res.data //定义全局变量供页面使用
}
}
})
方便全局数据拿去。
二、点击某一消息类型,该类型的数量全部消失,对应的总数也相应减少。
1.由第一节可知,总数量写在了.js文件里,并通过来消息函数触发,在.vue界面点击部分消息窗口时整体的消息数量会改变并放在缓存里,但是这时无法触发来消息函数
2.解决办法:回想一下,消息总数一开始为什么放在了websocket所在的.js文件里?因为最开始是来消息时总数自动更新,并且不需要页面内的任何条件出发,所以写在了那里。但是这次有触发条件了,就是点击时间。那么在点击事件下边在写一遍tabbar数量的函数就实现了。
.js代码
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import user from '@/store/modules/user'
//import websocket from '@/store/modules/websocket';
import getters from './getters'
const store = new Vuex.Store({
state: {
socketTask: null,
websocketData: {}, // 存放从后端接收到的websocket数据
wsSynergyDate:{},//cunchu
wsAppliedDate:{},
wsAnnouncedDate:{},
wsSynergynum:0,
wsAppliednum:0,
wsAnnouncednum:0,
wsAllnum:0,
wsUrl:"",
},
mutations: {
setWebsocketData (state, data) {
state.websocketData = data
if(state.websocketData.msgCategory==1){
state.wsSynergyDate=state.websocketData;
state.wsSynergynum+=1;
uni.setStorage({
key: 'msgSynergykey',
data: state.wsSynergynum,
success: function () {
}
});
console.log("皆",state.wsSynergyDate);
uni.getStorage({
key:'msgSynergykey',
success:(res)=>{
if(res.data){
state.wsSynergynum = res.data //定义全局变量供页面使用
}
}
})
};
if(state.websocketData.msgCategory==2){
state.wsAppliedDate=state.websocketData;
state.wsAppliednum+=1;
uni.setStorage({
key: 'msgAppliedkey',
data: state.wsAppliednum,
success: function () {
}
});
console.log("阵",state.wsAppliedDate);
uni.getStorage({
key:'msgAppliedkey',
success:(res)=>{
if(res.data){
state.wsAppliednum = res.data //定义全局变量供页面使用
}
}
})
};
if(state.websocketData.msgCategory==3){
state.wsAnnouncedDate=state.websocketData;
state.wsAnnouncednum+=1;
uni.setStorage({
key: 'msgAnnouncedkey',
data: state.wsAnnouncednum,
success: function () {
}
});
console.log("列",state.wsAnnouncedDate);
uni.getStorage({
key:'msgAnnouncedkey',
success:(res)=>{
if(res.data){
state.wsAnnouncednum = res.data //定义全局变量供页面使用
}
}
})
};
state.wsAllnum=state.wsSynergynum+state.wsAppliednum+state.wsAnnouncednum;
uni.setStorage({
key: 'msgAllkey',
data: state.wsAllnum,
success: function () {
}
});
uni.getStorage({
key:'msgAllkey',
success:(res)=>{
if(res.data){
state.wsAllnum = res.data //定义全局变量供页面使用
}
}
});
if(state.wsAllnum>0){
uni.setTabBarBadge({
index: 0,
text:state.wsAllnum.toString(),
})
}else if(state.wsAllnum==0){
uni.removeTabBarBadge({
index: 0,
})
};
}
},
actions: {
websocketInit ({ state, dispatch }, url) {
state.socketTast = uni.connectSocket({
url, // url是websocket连接ip
success: () => {
console.log('websocket连接成功!')
},
fail: e => {
console.log('连接失败' + e)
}
})
state.socketTast.onOpen(() => dispatch('websocketOnOpen'))
state.socketTast.onMessage(res => dispatch('websocketOnMessage', res))
state.socketTast.onClose(e => dispatch('websocketOnClose'))
state.socketTast.onError(e => dispatch('websocketOnError'))
},
websocketOnOpen ({ commit }) {
console.log('WebSocket连接正常打开中...!')
},
// 收到数据
websocketOnMessage ({ commit }, res) {
console.log('收到服务器内容啦!!!:' + res.data)
if (res.data !== 'success') {
commit('setWebsocketData', (res && JSON.parse(res.data) || null))
}
},
websocketOnClose ({ commit, dispatch }) {
console.log('WebSocket连接关闭')
},
websocketOnError ({ commit, dispatch }) {
console.log('WebSocket连接错误')
},
websocketClose ({ state }) {
if (!state.socketTast) return
state.socketTast.close({
success (res) {
console.log('关闭成功', res)
},
fail (err) {
console.log('关闭失败', err)
}
})
},
// 发送数据
websocketSend ({ state }, data) {
uni.sendSocketMessage({
data,
success: res => {
console.log('发送成功', res)
},
fail: e => {
console.log('发送失败', e)
}
})
}
},
modules: {
user,
//websocket,
},
getters
})
export default store
.vue代码
<template>
<view class="pagecolor" >
<view class="navbar">
<uni-nav-bar>
<block slot="left">
<view class="bartext">
<h2>消息</h2>
</view>
</block>
</uni-nav-bar>
</view>
<!-- 协同消息通知 -->
<view>
<view v-if="this.$store.state.wsSynergyDate.msgCategory!=1">
<uni-card class="todo_first"
@click="handlemesSynergy">
<view style="border-bottom: 0.5px solid #d0d0d0;padding: 5rpx 10rpx;">
<uni-badge size="small" :text="this.$store.state.wsSynergynum" absolute="rightTop" >
<uni-icons type="staff-filled" size="30" color="#2c5a42" style="margin-left: -1%;"></uni-icons>
</uni-badge>
<text style="font-size:33rpx;color: #3d3d3d;margin-left: 2%;">新协同消息</text>
<text style="font-size: 24rpx;color: #838383;float: right;margin-top: 15rpx;">{{this.firstsynergy.createTime|MerchantsNumber}}</text>
</view>
<view style="margin-top: 4%;">
<h5 class="todo_0">
<view > <text>{{this.firstsynergy.creatorName}}</text> </view>
<view class="flex">
<text>{{this.firstsynergy.msgTitle}}:</text>
<text>{{this.firstsynergy.msgContent}}</text>
</view>
</h5>
</view>
</uni-card>
</view>
<view v-else>
<uni-card class="todo_first"
@click="handlemesSynergy">
<view style="border-bottom: 0.5px solid #d0d0d0;padding: 5rpx 10rpx;">
<uni-badge size="small" :text="this.$store.state.wsSynergynum" absolute="rightTop" >
<uni-icons type="staff-filled" size="30" color="#2c5a42" style="margin-left: -1%;"></uni-icons>
</uni-badge>
<text style="font-size:33rpx;color: #3d3d3d;margin-left: 2%;">新协同消息</text>
<text style="font-size: 24rpx;color: #838383;float: right;margin-top: 15rpx;">{{this.$store.state.wsSynergyDate.createTime|MerchantsNumber}}</text>
</view>
<view style="margin-top: 4%;">
<h5 class="todo_0">
<view > <text>{{this.$store.state.wsSynergyDate.creatorName}}</text> </view>
<view class="flex">
<text>{{this.$store.state.wsSynergyDate.msgTitle}}:</text>
<text>{{this.$store.state.wsSynergyDate.msgContent}}</text>
</view>
</h5>
</view>
</uni-card>
</view>
</view>
<!-- 应用消息通知 -->
<view>
<view v-if="this.$store.state.wsAppliedDate.msgCategory!=2">
<uni-card class="todo_first"
@click="handlemesApplied">
<view style="border-bottom: 0.5px solid #d0d0d0;padding: 5rpx 10rpx;">
<uni-badge size="small" :text="this.$store.state.wsAppliednum" absolute="rightTop" >
<uni-icons type="shop-filled" size="30" color="#32669a" style="margin-left: -1%;"></uni-icons>
</uni-badge>
<text style="font-size:33rpx;color: #3d3d3d;margin-left: 2%;">新应用消息</text>
<text style="font-size: 24rpx;color: #838383;float: right;margin-top: 15rpx;">{{this.firstapplied.createTime|MerchantsNumber}}</text>
</view>
<view style="margin-top: 4%;">
<h5 class="todo_0">
<view><text>{{this.firstapplied.creatorName}}</text></view>
<view class="flex">
<text>{{this.firstapplied.msgTitle}}:</text>
<text>{{this.firstapplied.msgContent}}</text>
</view>
</h5>
</view>
</uni-card>
</view>
<view v-else>
<uni-card class="todo_first"
@click="handlemesApplied">
<view style="border-bottom: 0.5px solid #d0d0d0;padding: 5rpx 10rpx;">
<uni-badge size="small" :text="this.$store.state.wsAppliednum" absolute="rightTop" >
<uni-icons type="shop-filled" size="30" color="#32669a" style="margin-left: -1%;"></uni-icons>
</uni-badge>
<text style="font-size:33rpx;color: #3d3d3d;margin-left: 2%;">新应用消息</text>
<text style="font-size: 24rpx;color: #838383;float: right;margin-top: 15rpx;">{{this.$store.state.wsAppliedDate.createTime|MerchantsNumber}}</text>
</view>
<view style="margin-top: 4%;">
<h5 class="todo_0">
<view><text>{{this.$store.state.wsAppliedDate.creatorName}}</text></view>
<view class="flex">
<text>{{this.$store.state.wsAppliedDate.msgTitle}}:</text>
<text>{{this.$store.state.wsAppliedDate.msgContent}}</text>
</view>
</h5>
</view>
</uni-card>
</view>
</view>
<!-- 公告消息通知 -->
<view>
<view v-if="this.$store.state.wsAnnouncedDate.msgCategory!=3">
<uni-card class="todo_first"
@click="handlemesAnnounce">
<view style="border-bottom: 0.5px solid #d0d0d0;padding: 5rpx 10rpx;">
<uni-badge size="small" :text="this.$store.state.wsAnnouncednum" absolute="rightTop" >
<uni-icons type="sound-filled" size="30" color="#ecec00" style="margin-left: -1%;"></uni-icons>
</uni-badge>
<text style="font-size:33rpx;color: #3d3d3d;margin-left: 2%;">新公告消息</text>
<text style="font-size: 24rpx;color: #838383;float: right;margin-top: 15rpx;">{{this.firstannounce.createTime|MerchantsNumber}}</text>
</view>
<view style="margin-top: 4%;">
<h5 class="todo_0">
<view><text>{{this.firstannounce.creatorName}}</text></view>
<view class="flex">
<text>{{this.firstannounce.msgTitle}}:</text>
<text>{{this.firstannounce.msgContent}}</text>
</view>
</h5>
</view>
</uni-card>
</view>
<view v-else>
<uni-card class="todo_first"
@click="handlemesAnnounce">
<view style="border-bottom: 0.5px solid #d0d0d0;padding: 5rpx 10rpx;">
<uni-badge size="small" :text="this.$store.state.wsAnnouncednum" absolute="rightTop" >
<uni-icons type="sound-filled" size="30" color="#ecec00" style="margin-left: -1%;"></uni-icons>
</uni-badge>
<text style="font-size:33rpx;color: #3d3d3d;margin-left: 2%;">新公告消息</text>
<text style="font-size: 24rpx;color: #838383;float: right;margin-top: 15rpx;">{{this.$store.state.wsAnnouncedDate.createTime|MerchantsNumber}}</text>
</view>
<view style="margin-top: 4%;">
<h5 class="todo_0">
<view><text>{{this.$store.state.wsAnnouncedDate.creatorName}}</text></view>
<view class="flex">
<text>{{this.$store.state.wsAnnouncedDate.msgTitle}}:</text>
<text>{{this.$store.state.wsAnnouncedDate.msgContent}}</text>
</view>
</h5>
</view>
</uni-card>
</view>
</view>
</view>
</template>
<script>
import {listtop,read}from "@/api/system/message";
import index from "@/store/index";
import { created } from "../uview-ui/libs/mixin/mixin";
export default{
data() {
return {
flag:1,
synergylist:[],
appliedlist:[],
announcelist:[],
firstsynergy:[],
firstapplied:[],
firstannounce:[],
queryParams:{
pageNum: 1,
pageSize:this.mestodototal,
},
}
},
created() {
this.getlistone();
this.getlistwo();
this.getlistthree();
},
onLoad: function (options) {
uni.startPullDownRefresh();
},
onPullDownRefresh() {
this.getlistone();
this.getlistwo();
this.getlistthree();
setTimeout(function () {
uni.stopPullDownRefresh();
}, 500);
},
//过滤器显示时间
filters: {
MerchantsNumber(value) {
if(value!=null){
let start = value.slice(0,16);
return `${start}`;
}
}
},
methods: {
getlistone(){
listtop(this.queryParams).then(Response=>{
for(let i=0;i<Response.total;i++){
if(Response.rows[i].msgCategory==1){
this.synergylist.push(Response.rows[i])
};
}
this.firstsynergy=this.synergylist[0];
})
},
getlistwo(){
listtop(this.queryParams).then(Response=>{
for(let i=0;i<Response.total;i++){
if(Response.rows[i].msgCategory==2){
this.appliedlist.push(Response.rows[i])
};
}
this.firstapplied=this.appliedlist[0];
})
},
getlistthree(){
listtop(this.queryParams).then(Response=>{
for(let i=0;i<Response.total;i++){
if(Response.rows[i].msgCategory==3){
this.announcelist.push(Response.rows[i])
};
}
this.firstannounce=this.announcelist[0];
})
},
handlemesApplied(){
this.$tab.navigateTo('/pages/message/mesApplied/mesApplied');
this.$store.state.wsAppliednum=0
uni.setStorage({
key: 'msgAppliedkey',
data: 0,
success: function (res) {
}
});
this.$store.state.wsAllnum=this.$store.state.wsSynergynum+this.$store.state.wsAnnouncednum;
uni.setStorage({
key: 'msgAllkey',
data: this.$store.state.wsAllnum,
success: function (res) {
}
});
if(this.$store.state.wsAllnum>0){
uni.setTabBarBadge({
index: 0,
text:this.$store.state.wsAllnum.toString(),
})
}else if(this.$store.state.wsAllnum==0){
uni.removeTabBarBadge({
index: 0,
})
};
},
handlemesAnnounce(){
this.$tab.navigateTo('/pages/message/mesAnnounce/mesAnnounce')
this.$store.state.wsAnnouncednum=0
uni.setStorage({
key: 'msgAnnouncedkey',
data: 0,
success: function (res) {
}
});
this.$store.state.wsAllnum=this.$store.state.wsSynergynum+this.$store.state.wsAppliednum;
uni.setStorage({
key: 'msgAllkey',
data: this.$store.state.wsAllnum,
success: function (res) {
}
});
if(this.$store.state.wsAllnum>0){
uni.setTabBarBadge({
index: 0,
text:this.$store.state.wsAllnum.toString(),
})
}
else if(this.$store.state.wsAllnum==0){
uni.removeTabBarBadge({
index: 0,
})
};
},
handlemesSynergy(){
this.$tab.navigateTo('/pages/message/mesSynergy/mesSynergy')
this.$store.state.wsSynergynum=0
uni.setStorage({
key: 'msgSynergykey',
data: 0,
success: function (res) {
}
});
this.$store.state.wsAllnum=this.$store.state.wsAnnouncednum+this.$store.state.wsAppliednum;
uni.setStorage({
key: 'msgAllkey',
data: this.$store.state.wsAllnum,
success: function (res) {
}
});
if(this.$store.state.wsAllnum>0){
uni.setTabBarBadge({
index: 0,
text:this.$store.state.wsAllnum.toString(),
})
}
else if(this.$store.state.wsAllnum==0){
uni.removeTabBarBadge({
index: 0,
})
};
},
}
}
</script>
<style lang="scss">
.todo_first{
height: 220rpx;
}
.todo_0{
margin-top: -10rpx;
font-size: 30rpx;
color: #828282;
padding-left:0rpx;
}
.todo_1{
margin-top: -10rpx;
font-size: 20rpx;
color: #828282;
padding-left:0rpx;
}
.pagecolor{
background-color: #f3f3f3;
}
.navbar{
padding-top: 10%;
background-color: #ffffff;
width:100%;
height:20%;
}
.flex{
display: flex;
font-weight: bold;
color:#828282;
display: -webkit-box; /** 对象作为伸缩盒子模型显示 **/
overflow: hidden;
word-break: break-all; /* break-all(允许在单词内换行。) https://www.w3school.com.cn/cssref/pr_word-break.asp*/
text-overflow: ellipsis; /* 超出部分省略号 */
-webkit-box-orient: vertical; /** 设置或检索伸缩盒对象的子元素的排列方式 **/
-webkit-line-clamp: 1; /** 显示的行数 **/
}
</style>