hookehuyr

feat(消息页面): 添加消息详情弹框功能

实现点击对话显示消息详情的功能,包含头部信息、消息内容和关闭按钮
...@@ -169,6 +169,55 @@ ...@@ -169,6 +169,55 @@
169 169
170 <!-- 自定义TabBar --> 170 <!-- 自定义TabBar -->
171 <TabBar /> 171 <TabBar />
172 +
173 + <!-- 消息详情弹框 -->
174 + <nut-popup
175 + v-model:visible="showMessageDetail"
176 + position="right"
177 + :style="{ width: '100%', height: '100%' }"
178 + closeable
179 + close-icon-position="top-right"
180 + @close="closeMessageDetail"
181 + >
182 + <view class="message-detail-container">
183 + <!-- 详情页头部 -->
184 + <view class="detail-header">
185 + <view class="flex items-center">
186 + <image v-if="selectedConversation?.avatar"
187 + :src="selectedConversation.avatar"
188 + class="w-12 h-12 rounded-full object-cover mr-3"
189 + mode="aspectFill"
190 + />
191 + <view v-else class="w-12 h-12 rounded-full bg-gray-100 flex items-center justify-center mr-3">
192 + <component :is="selectedConversation?.icon" />
193 + </view>
194 + <view class="flex-1">
195 + <text class="text-lg font-medium">{{ selectedConversation?.name }}</text>
196 + <text class="text-sm text-gray-500 block">{{ selectedConversation?.time }}</text>
197 + </view>
198 + </view>
199 + </view>
200 +
201 + <!-- 消息内容 -->
202 + <view class="detail-content">
203 + <view class="message-content">
204 + <text class="text-base">{{ selectedConversation?.lastMessage }}</text>
205 + </view>
206 + </view>
207 +
208 + <!-- 底部关闭按钮 -->
209 + <view class="detail-footer">
210 + <nut-button
211 + type="primary"
212 + size="large"
213 + block
214 + @click="closeMessageDetail"
215 + >
216 + 关闭
217 + </nut-button>
218 + </view>
219 + </view>
220 + </nut-popup>
172 </view> 221 </view>
173 </template> 222 </template>
174 223
...@@ -199,6 +248,13 @@ const hasMore = ref(true) ...@@ -199,6 +248,13 @@ const hasMore = ref(true)
199 // 模拟对话数据 248 // 模拟对话数据
200 const conversations = ref([]) 249 const conversations = ref([])
201 250
251 +// 消息详情弹框相关
252 +const showMessageDetail = ref(false)
253 +const selectedConversation = ref(null)
254 +
255 +// 模拟消息历史记录
256 +const mockMessages = ref([])
257 +
202 // 初始化数据 258 // 初始化数据
203 const initData = () => { 259 const initData = () => {
204 const mockData = [] 260 const mockData = []
...@@ -301,12 +357,31 @@ const generateMockData = (pageNum) => { ...@@ -301,12 +357,31 @@ const generateMockData = (pageNum) => {
301 return mockData 357 return mockData
302 } 358 }
303 359
304 -// 点击对话 360 +// 点击对话 - 显示消息详情弹框
305 const onConversationClick = (conversation) => { 361 const onConversationClick = (conversation) => {
306 - // 跳转到聊天页面 362 + selectedConversation.value = conversation
307 - Taro.navigateTo({ 363 +
308 - url: `/pages/chat/index?id=${conversation.id}&name=${conversation.name}` 364 + // 显示弹框
309 - }) 365 + showMessageDetail.value = true
366 +
367 + // 标记为已读
368 + markAsRead(conversation.id)
369 +}
370 +
371 +
372 +// 关闭消息详情弹框
373 +const closeMessageDetail = () => {
374 + showMessageDetail.value = false
375 + selectedConversation.value = null
376 + mockMessages.value = []
377 +}
378 +
379 +// 标记消息为已读
380 +const markAsRead = (conversationId) => {
381 + const conversation = conversations.value.find(conv => conv.id === conversationId)
382 + if (conversation && conversation.unread) {
383 + conversation.unread = false
384 + }
310 } 385 }
311 386
312 // 页面加载时初始化数据 387 // 页面加载时初始化数据
...@@ -527,6 +602,70 @@ onMounted(() => { ...@@ -527,6 +602,70 @@ onMounted(() => {
527 position: relative; 602 position: relative;
528 } 603 }
529 604
605 + /* 消息详情弹框样式 */
606 + .message-detail-container {
607 + height: 100%;
608 + display: flex;
609 + flex-direction: column;
610 + background: #ffffff;
611 + }
612 +
613 + .detail-header {
614 + padding: 32rpx 24rpx;
615 + border-bottom: 1rpx solid #f0f0f0;
616 + background: #ffffff;
617 + flex-shrink: 0;
618 + }
619 +
620 + .detail-content {
621 + flex: 1;
622 + padding: 24rpx;
623 + overflow-y: auto;
624 + background: #f8f9fa;
625 + }
626 +
627 + .message-content {
628 + background: #ffffff;
629 + padding: 24rpx;
630 + border-radius: 16rpx;
631 + margin-bottom: 24rpx;
632 + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
633 + }
634 +
635 + .message-history {
636 + .message-item {
637 + background: #ffffff;
638 + padding: 20rpx;
639 + border-radius: 12rpx;
640 + margin-bottom: 16rpx;
641 + box-shadow: 0 1rpx 4rpx rgba(0, 0, 0, 0.05);
642 + }
643 + }
644 +
645 + .detail-footer {
646 + padding: 24rpx;
647 + background: #ffffff;
648 + border-top: 1rpx solid #f0f0f0;
649 + flex-shrink: 0;
650 + }
651 +
652 + .text-lg {
653 + font-size: 36rpx;
654 + }
655 +
656 + .text-base {
657 + font-size: 32rpx;
658 + line-height: 1.5;
659 + }
660 +
661 + .mr-3 {
662 + margin-right: 24rpx;
663 + }
664 +
665 + .mt-1 {
666 + margin-top: 8rpx;
667 + }
668 +
530 } 669 }
531 /* NutUI 组件样式覆盖 */ 670 /* NutUI 组件样式覆盖 */
532 :deep(.nut-searchbar) { 671 :deep(.nut-searchbar) {
......