Files
cashier_app/pageChat/index.vue
2025-12-05 11:10:50 +08:00

277 lines
6.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="min-page bg-f7 color-333 u-font-28">
<up-sticky>
<view class="top u-flex u-row-between u-col-center">
<view style="width: 420rpx">
<up-search
v-model="query.key"
placeholder="搜索群名称"
:showAction="false"
@clear="throttleSearch"
@change="throttleSearch"
></up-search>
</view>
<view class="u-flex u-col-center" @click="clearAllmsg">
<text class="color-666 u-m-r-12">清空未读</text>
<image src="/pageChat/static/clear.png" class="clear"></image>
</view>
</view>
</up-sticky>
<view class="list">
<up-swipe-action>
<up-swipe-action-item
:options="options1"
v-for="(item, index) in list"
v-model:show="item.showOptions"
@click="optionsClick($event, item, index)"
:key="item.id"
>
<view class="item u-flex" @click="toDetail(item)">
<view class="u-flex avatar">
<up-avatar
size="118rpx"
:src="item.avatar"
shape="square"
round="8rpx"
></up-avatar>
<view class="bandage" v-if="item.unread_count > 0">{{
item.unread_count >= 99 ? "99" : item.unread_count
}}</view>
</view>
<view class="u-flex-1 u-flex u-row-between u-p-l-14">
<view style="max-width: 364rpx">
<view class="color-000 u-line-1">{{ item.name }}</view>
<view class="u-m-t-28 u-line-1 u-font-24 color-999">{{
item.msg
}}</view>
</view>
<view class="color-333 u-font-24">{{ item.send_time }}</view>
</view>
</view>
</up-swipe-action-item>
</up-swipe-action>
</view>
</view>
</template>
<script setup>
import * as chatApi from "@/http/php/chat";
import { ref, reactive, inject, onMounted,onUnmounted } from "vue";
import { onShow } from "@dcloudio/uni-app";
import { useChatStore } from "@/store/chat";
const chatStore = useChatStore();
onMounted(() => {
chatStore.connectSocket();
// 确保状态监听已初始化
if (!chatStore._listenersInitialized) {
chatStore.initStateListeners();
chatStore._listenersInitialized = true;
}
});
const startReciveMsg=ref(true)
onUnmounted(() => {
startReciveMsg.value=false
})
chatStore.onReceiveMsg = (msg) => {
if(!startReciveMsg.value){
return
}
if (msg.operate_type == "receive_msg" && msg.chat_type == 2) {
const index = allList.value.findIndex((v) => v.group_id == msg.group_id);
if (index != -1) {
allList.value[index].unread_count += 1;
allList.value[index].msg = returnMsg(msg);
allList.value[index].send_time = msg.send_time;
}
const index1 = list.value.findIndex((v) => v.group_id == msg.group_id);
if (index1 != -1) {
list.value[index1].unread_count += 1;
list.value[index1].msg = returnMsg(msg);
list.value[index1].send_time = msg.send_time;
}
}
};
function returnMsg(msg) {
if (msg.msg_type == 1) {
return msg.nick + "" + msg.content;
}
if (msg.msg_type == 2) {
return msg.nick + "" + "[图片]";
}
if (msg.msg_type == 5) {
return msg.nick + "" + "[视频]";
}
if (msg.msg_type == 4) {
return msg.nick + "" + "[优惠券]";
}
}
chatStore.connectSocket();
// 使用 reactive 创建响应式对象
const options1 = reactive([
{
text: "删除",
style: {
backgroundColor: "#f56c6c",
color: "#fff",
},
},
]);
function optionsClick(e, item, index) {
if (e.index == 0) {
//删除
chatApi
.sessionlistdel({
session_id: item.session_id,
})
.then((res) => {
if (res) {
uni.showToast({
title: "删除成功",
icon: "none",
duration: 1000,
});
list.value.splice(index, 1);
setTimeout(() => {
getList();
}, 1000);
}
});
}
}
const list = ref([]);
let allList = ref([]);
const query = reactive({
key: "",
});
function throttle(fn, delay) {
let timer = null;
return function (...args) {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
//使用节流函数
const throttleSearch = throttle(search, 500);
function search() {
list.value = allList.value
.filter((v) => v.name.includes(query.key.trim()))
.map((v) => {
return {
...v,
showOptions: false,
};
});
}
async function getList() {
const res = await chatApi.messageSessionList({});
allList.value = (res.list || []).filter((v) => !v.is_del);
search();
}
async function clearAllmsg() {
uni.showModal({
title: "提示",
content: "确定要清空所有未读消息吗?",
success: async (res) => {
if (res.confirm) {
const res = await chatApi.messageMarkReadAll({
session_ids: list.value.map((v) => v.session_id).join(","),
});
if (res) {
uni.showToast({
title: "清空成功",
icon: "none",
duration: 2000,
});
setTimeout(() => {
getList();
}, 1000);
}
}
},
});
}
function toDetail(item) {
if (!item.is_th) {
return uni.showToast({
title: "你已不在该群内",
icon: "none",
duration: 1500,
});
}
uni.navigateTo({
url:
"/pageChat/chat" +
`?group_id=${item.group_id}&session_id=${item.session_id}`,
});
}
const messageUnreadCount = ref(0);
onShow(() => {
startReciveMsg.value=true
getList();
// 获取未读消息总数
chatApi.messageUnreadCount({}).then((res) => {
console.log(res);
messageUnreadCount.value = res.total;
});
});
</script>
<style lang="scss" scoped>
.top {
padding: 32rpx 28rpx;
background-color: #fff;
}
.clear {
width: 38rpx;
height: 38rpx;
}
.list {
padding: 36rpx 28rpx;
.item {
padding: 32rpx 28rpx;
background-color: #fff;
border-radius: 16rpx;
display: flex;
flex-direction: column;
gap: 16rpx;
.avatar {
position: relative;
.bandage {
position: absolute;
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 50%;
background: #ff1c1c;
font-size: 24rpx;
color: #ffffff;
width: 38rpx;
height: 38rpx;
text-align: center;
line-height: 38rpx;
right: -10rpx;
top: -10rpx;
}
}
}
}
</style>