feat(chat): 添加私信功能和WebSocket实时通信
- 集成WebSocket管理器,支持心跳、自动重连、消息队列 - 实现私信相关API接口,包括会话列表、历史消息、已读标记等 - 添加聊天页面和会话列表页面,支持实时消息收发 - 配置地图权限和腾讯地图SDK用于酒局定位功能 - 修改应用名称为"喝酒了么"并更新应用描述 - 在App.vue中初始化WebSocket连接和私信功能 - 添加详细的私信模块接口文档和Mock数据 - 优化单图片动态高度计算和预加载逻辑
This commit is contained in:
+80
-6
@@ -2,7 +2,15 @@
|
||||
<view :class="themeClass" class="page-container circle-page">
|
||||
<!-- 顶部导航 -->
|
||||
<view class="circle-header" :style="{ paddingTop: headerPaddingTop }">
|
||||
<text class="circle-title">酒友圈</text>
|
||||
<view class="circle-title-row" :style="{ paddingRight: headerPaddingRight }">
|
||||
<text class="circle-title">酒友圈</text>
|
||||
<view class="msg-entry" @click="goChatList">
|
||||
<text class="msg-entry-icon">💬</text>
|
||||
<view v-if="unreadTotal > 0" class="msg-badge">
|
||||
<text class="msg-badge-text">{{ unreadTotal > 99 ? '99+' : unreadTotal }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- Tab 切换 -->
|
||||
<view class="circle-tabs">
|
||||
<view
|
||||
@@ -67,7 +75,7 @@
|
||||
v-for="f in friends"
|
||||
:key="f.id"
|
||||
:friend="f"
|
||||
@tap="goFriends"
|
||||
@tap="goChat(f)"
|
||||
/>
|
||||
<EmptyState
|
||||
v-if="!friends.length"
|
||||
@@ -112,7 +120,7 @@ import FeedCard from '../../components/FeedCard.vue'
|
||||
import FriendItem from '../../components/FriendItem.vue'
|
||||
import EventCard from '../../components/EventCard.vue'
|
||||
import EmptyState from '../../components/EmptyState.vue'
|
||||
import { GetCircleFeeds, LikeFeed, UnlikeFeed, GetFriends, GetFriendRequests, GetEvents } from '../../common/api'
|
||||
import { GetCircleFeeds, LikeFeed, UnlikeFeed, GetFriends, GetFriendRequests, GetEvents, GetUnreadCount } from '../../common/api'
|
||||
import themeMixin from '../../common/theme-mixin'
|
||||
|
||||
export default {
|
||||
@@ -120,10 +128,12 @@ export default {
|
||||
components: { FeedCard, FriendItem, EventCard, EmptyState },
|
||||
data() {
|
||||
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
||||
const sysInfo = uni.getSystemInfoSync()
|
||||
return {
|
||||
tabs: ['动态', '酒友', '酒局'],
|
||||
currentTab: 0,
|
||||
headerPaddingTop: (menuBtn.top + 8) + 'px',
|
||||
headerPaddingRight: (sysInfo.windowWidth - menuBtn.left + 8) + 'px',
|
||||
// 动态
|
||||
feeds: [],
|
||||
page: 1,
|
||||
@@ -134,13 +144,16 @@ export default {
|
||||
friends: [],
|
||||
friendRequests: [],
|
||||
// 酒局
|
||||
events: []
|
||||
events: [],
|
||||
// 私信未读
|
||||
unreadTotal: 0
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.loadFeeds(true)
|
||||
this.loadFriends()
|
||||
this.loadEvents()
|
||||
this.loadUnread()
|
||||
},
|
||||
methods: {
|
||||
switchTab(i) {
|
||||
@@ -212,6 +225,22 @@ export default {
|
||||
goFriends() {
|
||||
uni.navigateTo({ url: '/pages/friends/friends' })
|
||||
},
|
||||
goChat(friend) {
|
||||
// 根据 friendId 查找对应会话 (f001 -> conv_001)
|
||||
const convId = 'conv_' + friend.id.replace('f', '')
|
||||
uni.navigateTo({
|
||||
url: `/pages/chat/chat?friendId=${friend.id}&nickname=${encodeURIComponent(friend.nickname)}&conversationId=${convId}`
|
||||
})
|
||||
},
|
||||
goChatList() {
|
||||
uni.navigateTo({ url: '/pages/chat-list/chat-list' })
|
||||
},
|
||||
async loadUnread() {
|
||||
try {
|
||||
const res = await GetUnreadCount()
|
||||
this.unreadTotal = res.data.total
|
||||
} catch (e) { /* ignore */ }
|
||||
},
|
||||
// === 酒局 ===
|
||||
async loadEvents() {
|
||||
try {
|
||||
@@ -256,12 +285,57 @@ export default {
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.circle-title-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: $sp-lg;
|
||||
}
|
||||
|
||||
.circle-title {
|
||||
display: block;
|
||||
font-size: $fs-2xl;
|
||||
font-weight: $fw-black;
|
||||
color: $text-primary;
|
||||
margin-bottom: $sp-lg;
|
||||
}
|
||||
|
||||
.msg-entry {
|
||||
position: relative;
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
background: $bg-card;
|
||||
|
||||
&:active {
|
||||
background: $bg-card-alt;
|
||||
}
|
||||
}
|
||||
|
||||
.msg-entry-icon {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
|
||||
.msg-badge {
|
||||
position: absolute;
|
||||
top: -4rpx;
|
||||
right: -4rpx;
|
||||
min-width: 32rpx;
|
||||
height: 32rpx;
|
||||
padding: 0 8rpx;
|
||||
border-radius: 16rpx;
|
||||
background: $coral;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.msg-badge-text {
|
||||
font-size: 18rpx;
|
||||
color: #fff;
|
||||
font-weight: $fw-bold;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.circle-tabs {
|
||||
|
||||
Reference in New Issue
Block a user