Files
medical-mall/unpackage/cache/.app-android/sourcemap/pages/mall/consumer/chat.kt.map

1 line
36 KiB
Plaintext
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.
{"version":3,"sources":["pages/mall/consumer/chat.uvue","pages/user/profile.uvue","pages/mall/consumer/index.uvue","pages/user/terms.uvue","pages/user/login.uvue","pages/mall/consumer/settings.uvue","pages/user/center.uvue","uni_modules/ak-req/ak-req.uts"],"sourcesContent":["<!-- pages/mall/consumer/chat.uvue -->\r\n<template>\r\n <view class=\"chat-page\">\r\n <!-- 聊天头部 -->\r\n <view class=\"chat-header\" :style=\"{ paddingTop: navPaddingTop }\">\r\n <view class=\"header-back\" @click=\"goBack\">\r\n <text class=\"back-icon\"></text>\r\n </view>\r\n <view class=\"header-info\">\r\n <view class=\"header-info-text-wrapper\">\r\n <text class=\"chat-title\">{{ headerTitle }}</text>\r\n <text class=\"chat-status\">在线</text>\r\n </view>\r\n </view>\r\n <view class=\"header-actions\">\r\n <view class=\"action-icon\" @click=\"showMoreActions\">\r\n <text class=\"action-icon-text\">⋯</text>\r\n </view>\r\n </view>\r\n </view>\r\n \r\n <!-- 聊天内容 -->\r\n <scroll-view \r\n scroll-y=\"true\"\r\n class=\"chat-content\"\r\n :scroll-into-view=\"scrollToView\"\r\n :scroll-with-animation=\"true\"\r\n :show-scrollbar=\"false\"\r\n upper-threshold=\"100\"\r\n @scrolltoupper=\"onScrollToUpper\"\r\n >\r\n <!-- 聊天消息列表 -->\r\n <view class=\"chat-messages\">\r\n <!-- 系统消息 -->\r\n <view class=\"message-item system\">\r\n <text class=\"system-text\">客服 小美 已接入,请描述您的问题</text>\r\n </view>\r\n \r\n <!-- 时间分割线 -->\r\n <view class=\"time-divider\">\r\n <text class=\"time-text\">今天 14:30</text>\r\n </view>\r\n \r\n <!-- 消息项 -->\r\n <view \r\n v-for=\"message in messages\" \r\n :key=\"message.id\"\r\n :class=\"['message-item', message.type]\"\r\n :id=\"message.viewId\"\r\n >\r\n <!-- 对方消息 -->\r\n <view v-if=\"message.type === 'received'\" class=\"message-wrapper\">\r\n <image \r\n class=\"avatar\" \r\n :src=\"merchantAvatar\" \r\n mode=\"aspectFill\"\r\n />\r\n <view class=\"message-content-wrapper\">\r\n <text class=\"sender-name\">{{ headerTitle }}</text>\r\n <view class=\"message-bubble received-bubble\">\r\n <text class=\"message-text\">{{ message.content }}</text>\r\n <text class=\"message-time\">{{ message.time }}</text>\r\n </view>\r\n </view>\r\n </view>\r\n \r\n <!-- 我的消息 -->\r\n <view v-else class=\"message-wrapper me\">\r\n <view class=\"message-content-wrapper\">\r\n <view class=\"message-bubble me\">\r\n <text class=\"message-text\">{{ message.content }}</text>\r\n <text class=\"message-time\">{{ message.time }}</text>\r\n </view>\r\n </view>\r\n <image \r\n class=\"avatar me\" \r\n src=\"/static/default-avatar.png\" \r\n mode=\"aspectFill\"\r\n />\r\n </view>\r\n </view>\r\n </view>\r\n </scroll-view>\r\n \r\n <!-- 聊天输入区 -->\r\n <view class=\"chat-input\">\r\n <view class=\"input-tools\">\r\n <text class=\"tool-icon\" @click=\"showEmojiPicker\">😊</text>\r\n <text class=\"tool-icon\" @click=\"showImagePicker\">📷</text>\r\n <text class=\"tool-icon\" @click=\"showMoreTools\"></text>\r\n </view>\r\n \r\n <view class=\"input-wrapper\">\r\n <input \r\n class=\"message-input\" \r\n v-model=\"inputMessage\"\r\n placeholder=\"请输入消息...\"\r\n :focus=\"inputFocus\"\r\n @confirm=\"sendMessage\"\r\n confirm-type=\"send\"\r\n />\r\n <button \r\n class=\"send-button\" \r\n :class=\"{ active: inputMessage.trim() }\" \r\n @click=\"sendMessage\"\r\n >\r\n 发送\r\n </button>\r\n </view>\r\n </view>\r\n \r\n <!-- 表情选择器 -->\r\n <scroll-view v-if=\"showEmoji\" class=\"emoji-picker\" direction=\"vertical\">\r\n <view class=\"emoji-category\">\r\n <text \r\n v-for=\"emoji in emojiList\" \r\n :key=\"emoji\"\r\n class=\"emoji-item\"\r\n @click=\"insertEmoji(emoji)\"\r\n >\r\n {{ emoji }}\r\n </text>\r\n </view>\r\n </scroll-view>\r\n </view>\r\n</template>\r\n\r\n<script setup lang=\"uts\">\r\nimport { ref, reactive, onMounted, onUnmounted, nextTick } from 'vue'\r\nimport { supabaseService, type ChatMessage } from '@/utils/supabaseService.uts'\r\nimport supa from '@/components/supadb/aksupainstance.uts'\r\nimport type { AkSupaRealtimeChannel } from '@/components/supadb/aksupa.uts'\r\nimport { getCurrentUser } from '@/utils/store.uts'\r\n\r\ntype UiChatMessage = {\r\n\tid: string\r\n\tviewId: string\r\n\ttype: string\r\n\tcontent: string\r\n\ttime: string\r\n}\r\n\r\n// 响应式数据\r\nconst messages = ref<UiChatMessage[]>([])\r\nconst inputMessage = ref<string>('')\r\nconst inputFocus = ref<boolean>(false)\r\nconst showEmoji = ref<boolean>(false)\r\nconst scrollToView = ref<string>('')\r\nconst currentUserId = ref<string>('')\r\nconst merchantId = ref<string>('') // 商家ID\r\nconst headerTitle = ref<string>('在线客服')\r\nconst merchantAvatar = ref<string>('/static/default-shop.png') // 商家头像\r\nconst navPaddingTop = ref<string>('30px') // 默认值,包含状态栏高度+原有内边距\r\nconst isInitialLoading = ref<boolean>(true)\r\nlet realtimeChannel: AkSupaRealtimeChannel | null = null\r\n\r\n// 模拟表情列表\r\nconst emojiList = ['😊', '😂', '🤣', '😍', '😘', '🥰', '😭', '😡', '👍', '👏', '🙏', '🎉', '❤️', '🔥', '⭐']\r\n\r\nfunction scrollToBottom() : void {\r\n if (messages.value.length === 0) return\r\n\r\n // 获取最后一条消息的 ID\r\n const lastMsg = messages.value[messages.value.length - 1]\r\n const targetId = lastMsg.viewId\r\n\r\n // 关键点:在 UVue 安卓端,直接连续赋值可能被合并。\r\n // 我们先清空 ID然后在下一帧赋值确保 scroll-view 监听到变化。\r\n scrollToView.value = ''\r\n\r\n // 延迟更久一点,确保安卓端列表排版彻底完成\r\n setTimeout(() => {\r\n scrollToView.value = targetId\r\n console.log('[scrollToBottom] 发起滚动定位:', targetId)\r\n \r\n // 分级校准:针对长消息或渲染抖动导致的高度变化\r\n setTimeout(() => {\r\n scrollToView.value = ''\r\n setTimeout(() => {\r\n scrollToView.value = targetId\r\n console.log('[scrollToBottom] 第一阶段校准:', targetId)\r\n }, 50)\r\n }, 500)\r\n\r\n // 最终深度校准(针对首屏数据较多时)\r\n setTimeout(() => {\r\n scrollToView.value = ''\r\n setTimeout(() => {\r\n scrollToView.value = targetId\r\n console.log('[scrollToBottom] 最终校准:', targetId)\r\n }, 50)\r\n }, 1200)\r\n }, 300)\r\n}\r\n\r\nfunction getCurrentTime(): string {\r\n const now = new Date()\r\n const hours = now.getHours().toString().padStart(2, '0')\r\n const minutes = now.getMinutes().toString().padStart(2, '0')\r\n return `${hours}:${minutes}`\r\n}\r\n\r\nfunction setupRealtimeSubscription(): void {\r\n\tconsole.log('开始建立聊天实时订阅...')\r\n\tconsole.log('当前用户ID:', currentUserId.value, '商家ID:', merchantId.value)\r\n\t\r\n\trealtimeChannel = supa.channel('chat-messages-' + Date.now().toString())\r\n\t\t.on('postgres_changes', {\r\n\t\t\tevent: 'INSERT',\r\n\t\t\tschema: 'public',\r\n\t\t\ttable: 'ml_chat_messages'\r\n\t\t}, (payload: any) => {\r\n\t\t\tconsole.log('=== 收到实时订阅回调 ===')\r\n\t\t\tconst payloadObj = (payload instanceof UTSJSONObject) ? (payload as UTSJSONObject) : (JSON.parse(JSON.stringify(payload ?? {})) as UTSJSONObject)\r\n\t\t\tconst newMsgAny = payloadObj.get('new')\r\n\t\t\tif (newMsgAny == null) {\r\n\t\t\t\tconsole.log('newMsgAny 为空,跳过')\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t\tconst newMsg = (newMsgAny instanceof UTSJSONObject) ? (newMsgAny as UTSJSONObject) : (JSON.parse(JSON.stringify(newMsgAny)) as UTSJSONObject)\r\n\t\t\tconsole.log('收到新消息:', newMsg)\r\n\r\n\t\t\tconst senderId = newMsg.getString('sender_id') ?? ''\r\n\t\t\tconst receiverId = newMsg.getString('receiver_id') ?? ''\r\n\t\t\tconst msgId = newMsg.getString('id') ?? ''\r\n\t\t\tconst content = newMsg.getString('content') ?? ''\r\n\t\t\t\r\n\t\t\tconsole.log('=== 消息详情 ===')\r\n\t\t\tconsole.log('消息ID:', msgId)\r\n\t\t\tconsole.log('发送者ID:', senderId)\r\n\t\t\tconsole.log('接收者ID:', receiverId)\r\n\t\t\tconsole.log('当前用户ID:', currentUserId.value)\r\n\t\t\tconsole.log('商家ID:', merchantId.value)\r\n\t\t\tconsole.log('消息内容:', content)\r\n\r\n\t\t\t// 检查消息是否已经在列表中(避免重复)\r\n\t\t\tfor (let i = 0; i < messages.value.length; i++) {\r\n\t\t\t\tif (messages.value[i].id == msgId) {\r\n\t\t\t\t\tconsole.log('消息已存在,跳过')\r\n\t\t\t\t\treturn\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// 判断消息类型\r\n\t\t\tconst isMyMessage = (senderId == currentUserId.value)\r\n\t\t\tconst isForMe = (receiverId == currentUserId.value)\r\n\t\t\tconst isRelatedToCurrentChat = (senderId == merchantId.value || receiverId == merchantId.value)\r\n\t\t\t\r\n\t\t\tconsole.log('=== 条件判断 ===')\r\n\t\t\tconsole.log('isMyMessage:', isMyMessage)\r\n\t\t\tconsole.log('isForMe:', isForMe)\r\n\t\t\tconsole.log('isRelatedToCurrentChat:', isRelatedToCurrentChat)\r\n\r\n\t\t\t// 如果消息与当前聊天无关,跳过\r\n\t\t\tif (!isRelatedToCurrentChat) {\r\n\t\t\t\tconsole.log('消息与当前聊天无关,跳过')\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\r\n\t\t\t// 如果是自己发送的消息,或者是发给自己的消息,都显示\r\n\t\t\tif (isMyMessage || isForMe) {\r\n\t\t\t\tconst createdAt = newMsg.getString('created_at') ?? new Date().toISOString()\r\n\t\t\t\tconst date = new Date(createdAt)\r\n\t\t\t\tconst timeStr = `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`\r\n\r\n\t\t\t\t// 生成安全的 viewId\r\n\t\t\t\tconst safeViewId = 'msg_' + msgId.replace(/[^a-zA-Z0-9]/g, '_')\r\n\r\n\t\t\t\tconst incomingMsg: UiChatMessage = {\r\n\t\t\t\t\tid: msgId,\r\n\t\t\t\t\tviewId: safeViewId,\r\n\t\t\t\t\ttype: isMyMessage ? 'sent' : 'received',\r\n\t\t\t\t\tcontent: content,\r\n\t\t\t\t\ttime: timeStr\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconsole.log('=== 添加新消息到列表 ===')\r\n\t\t\t\tconsole.log('消息类型:', incomingMsg.type)\r\n\t\t\t\tconsole.log('消息内容:', incomingMsg.content)\r\n\t\t\t\tmessages.value.push(incomingMsg)\r\n\t\t\t\tscrollToBottom()\r\n\t\t\t} else {\r\n\t\t\t\tconsole.log('条件不满足,不添加消息')\r\n\t\t\t}\r\n\t\t})\r\n\t\t.subscribe((status: string, err: any | null) => {\r\n\t\t\tconsole.log('订阅状态:', status)\r\n\t\t\tif (err != null) {\r\n\t\t\t\tconsole.log('订阅错误:', err)\r\n\t\t\t}\r\n\t\t})\r\n}\r\n\r\nasync function loadChatHistory(): Promise<void> {\r\n let rawMsgs : ChatMessage[] = []\r\n\r\n if (merchantId.value != '') {\r\n rawMsgs = await supabaseService.getChatMessages(merchantId.value)\r\n } else {\r\n console.warn(\"No merchant ID provided for chat\")\r\n return\r\n }\r\n\r\n // 确保时间顺序是升序(旧的在前,新的在后)\r\n // Supabase 返回的消息如果是降序,我们需要 reverse 过来显示\r\n const sortedRawMsgs = rawMsgs.sort((a, b) => {\r\n const timeA = new Date(a.created_at ?? '').getTime()\r\n const timeB = new Date(b.created_at ?? '').getTime()\r\n return timeA - timeB\r\n })\r\n\r\n const uiMessages : UiChatMessage[] = []\r\n for (let i = 0; i < sortedRawMsgs.length; i++) {\r\n const m = sortedRawMsgs[i]\r\n const date = new Date(m.created_at ?? new Date().toISOString())\r\n const timeStr = `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`\r\n\r\n const sender = m.sender_id ?? ''\r\n const msgType = (currentUserId.value != '' && sender == currentUserId.value) ? 'sent' : 'received'\r\n const rawId = (m.id ?? '').toString()\r\n const msgId = rawId != '' ? rawId : Date.now().toString() + i.toString()\r\n const safeViewId = 'msg_' + msgId.replace(/[^a-zA-Z0-9]/g, '_')\r\n \r\n const uiMsg : UiChatMessage = {\r\n id: msgId,\r\n viewId: safeViewId,\r\n type: msgType,\r\n content: m.content ?? '',\r\n time: timeStr\r\n }\r\n uiMessages.push(uiMsg)\r\n }\r\n messages.value = uiMessages\r\n \r\n if (isInitialLoading.value) {\r\n // 增加一点初始化延迟,等待 scroll-view 渲染就绪\r\n setTimeout(() => {\r\n scrollToBottom()\r\n isInitialLoading.value = false\r\n }, 500)\r\n }\r\n}\r\n\r\nfunction onScrollToUpper(e: any): void {\r\n console.log('[onScrollToUpper] 触发加载历史记录')\r\n}\r\n\r\nasync function loadMerchantInfo(): Promise<void> {\r\n\tif (merchantId.value == '') return\r\n\t\r\n\ttry {\r\n\t\tconst response = await supa\r\n\t\t\t.from('ml_shops')\r\n\t\t\t.select('shop_logo, shop_name')\r\n\t\t\t.eq('merchant_id', merchantId.value)\r\n\t\t\t.limit(1)\r\n\t\t\t.execute()\r\n\t\t\r\n\t\tif (response.error != null) {\r\n\t\t\tconsole.error('[loadMerchantInfo] 获取商家信息失败:', response.error)\r\n\t\t\treturn\r\n\t\t}\r\n\t\t\r\n\t\tconst rawData = response.data\r\n\t\tif (rawData == null) return\r\n\t\t\r\n\t\tconst rawList = rawData as any[]\r\n\t\tif (rawList.length == 0) return\r\n\t\t\r\n\t\tconst shopData = rawList[0]\r\n\t\tconst shopObj = JSON.parse(JSON.stringify(shopData)) as UTSJSONObject\r\n\t\t\r\n\t\tconst logo = shopObj.getString('shop_logo')\r\n\t\tif (logo != null && logo != '') {\r\n\t\t\tmerchantAvatar.value = logo\r\n\t\t}\r\n\t\t\r\n\t\tconst name = shopObj.getString('shop_name')\r\n\t\tif (name != null && name != '' && headerTitle.value == '在线客服') {\r\n\t\t\theaderTitle.value = name\r\n\t\t}\r\n\t} catch (e) {\r\n\t\tconsole.error('[loadMerchantInfo] 获取商家信息异常:', e)\r\n\t}\r\n}\r\n\r\n// 生命周期\r\nonLoad((options: any) => {\r\n // 动态获取状态栏高度\r\n const sysInfo = uni.getSystemInfoSync()\r\n const statusBarH = sysInfo.statusBarHeight\r\n // 状态栏高度 + 10px 原有顶部内边距\r\n navPaddingTop.value = (statusBarH + 10) + 'px'\r\n\r\n\tconst optObj = (options instanceof UTSJSONObject) ? (options as UTSJSONObject) : (JSON.parse(JSON.stringify(options ?? {})) as UTSJSONObject)\r\n\tconst mid = optObj.getString('merchantId') ?? ''\r\n\tif (mid !== '') {\r\n\t\tmerchantId.value = mid\r\n\t}\r\n\tconst mname = optObj.getString('merchantName') ?? ''\r\n\tif (mname !== '') {\r\n\t\theaderTitle.value = mname\r\n\t}\r\n})\r\n\r\nonMounted(() => {\r\n\tsupabaseService.ensureSession().then((uid) => {\r\n\t\tif (uid != null) {\r\n\t\t\tcurrentUserId.value = uid\r\n\t\t} else {\r\n\t\t\tgetCurrentUser().then((user) => {\r\n\t\t\t\tif (user != null) {\r\n\t\t\t\t\tcurrentUserId.value = user.id ?? ''\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\tloadMerchantInfo()\r\n\t\tloadChatHistory()\r\n\t\tsetupRealtimeSubscription()\r\n\t})\r\n})\r\n\r\nonUnmounted(() => {\r\n if (realtimeChannel != null) {\r\n supa.removeChannel(realtimeChannel!!)\r\n }\r\n})\r\n\r\nconst sendMessage = async () => {\r\n const content = inputMessage.value.trim()\r\n if (content == '') return\r\n \r\n // 清空输入框\r\n inputMessage.value = ''\r\n \r\n // 发送到 Supabase\r\n if (merchantId.value != '') {\r\n console.log('[sendMessage] 开始发送消息到:', merchantId.value)\r\n const success = await supabaseService.sendMessage(merchantId.value, content)\r\n console.log('[sendMessage] 发送结果:', success)\r\n if (!success) {\r\n uni.showToast({\r\n title: '发送失败',\r\n icon: 'none'\r\n })\r\n }\r\n // 不需要手动添加消息,等待实时订阅推送\r\n }\r\n}\r\n\r\n// 模拟客服回复 (已禁用,改用 Realtime)\r\n/*\r\nconst simulateCustomerReply = async () => {\r\n // ...\r\n}\r\n*/\r\n\r\n/* 移除不再使用的 simulateCustomerReply 和 addReceivedMessage */\r\n\r\n// 插入表情\r\nfunction insertEmoji(emoji: string): void {\r\n inputMessage.value += emoji\r\n inputFocus.value = true\r\n}\r\n\r\n// 显示表情选择器\r\nfunction showEmojiPicker(): void {\r\n showEmoji.value = !showEmoji.value\r\n}\r\n\r\n// 显示图片选择器\r\nfunction showImagePicker(): void {\r\n uni.chooseImage({\r\n count: 1,\r\n success: (res) => {\r\n console.log('选择图片:', res.tempFilePaths)\r\n // 这里可以处理图片上传\r\n }\r\n })\r\n}\r\n\r\n// 显示更多工具\r\nfunction showMoreTools(): void {\r\n uni.showActionSheet({\r\n itemList: ['发送位置', '发送文件', '发送语音'],\r\n success: (res) => {\r\n console.log('选择工具:', res.tapIndex)\r\n }\r\n })\r\n}\r\n\r\n// 显示更多操作\r\nfunction showMoreActions(): void {\r\n uni.showActionSheet({\r\n itemList: ['投诉客服', '结束对话', '清除记录'],\r\n success: (res) => {\r\n switch (res.tapIndex) {\r\n case 0:\r\n uni.navigateTo({ url: '/pages/mall/consumer/complaint' })\r\n break\r\n case 1:\r\n uni.showModal({\r\n title: '确认结束',\r\n content: '确定要结束本次对话吗?',\r\n success: (res) => {\r\n if (res.confirm) {\r\n uni.navigateBack()\r\n }\r\n }\r\n })\r\n break\r\n case 2:\r\n uni.showModal({\r\n title: '确认清除',\r\n content: '确定要清除聊天记录吗?',\r\n success: (res) => {\r\n if (res.confirm) {\r\n messages.value = []\r\n }\r\n }\r\n })\r\n break\r\n }\r\n }\r\n })\r\n}\r\n\r\n// 返回\r\nconst goBack = () => {\r\n uni.navigateBack()\r\n}\r\n</script>\r\n\r\n<style>\r\n.chat-page {\r\n width: 100%;\r\n flex: 1;\r\n background-color: #f5f5f5;\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n}\r\n\r\n/* 聊天头部 */\r\n.chat-header {\r\n background-color: white;\r\n padding: 10px 15px;\r\n display: flex;\r\n flex-direction: row;\r\n align-items: center;\r\n justify-content: space-between;\r\n border-bottom: 1px solid #eee;\r\n flex-shrink: 0;\r\n}\r\n\r\n.header-back {\r\n width: 40px;\r\n}\r\n\r\n.back-icon {\r\n font-size: 24px;\r\n color: #333;\r\n}\r\n\r\n.header-info {\r\n flex: 1;\r\n}\r\n\r\n.header-info-text-wrapper {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n}\r\n\r\n.chat-title {\r\n font-size: 16px;\r\n font-weight: bold;\r\n color: #333;\r\n margin-bottom: 2px;\r\n}\r\n\r\n.chat-status {\r\n font-size: 12px;\r\n color: #34c759;\r\n}\r\n\r\n.header-actions .action-icon {\r\n font-size: 20px;\r\n color: #333;\r\n width: 40px;\r\n}\r\n\r\n.action-icon-text {\r\n text-align: right;\r\n width: 100%;\r\n}\r\n\r\n/* 聊天内容区 */\r\n.chat-content {\r\n flex: 1;\r\n height: 0;\r\n padding: 10px;\r\n padding-bottom: 20px;\r\n box-sizing: border-box;\r\n}\r\n\r\n.chat-messages {\r\n display: flex;\r\n flex-direction: column;\r\n padding-bottom: 80px;\r\n}\r\n\r\n/* 系统消息 */\r\n.message-item.system {\r\n display: flex;\r\n flex-direction: row;\r\n justify-content: center;\r\n margin-bottom: 20px;\r\n}\r\n\r\n.system-text {\r\n font-size: 12px;\r\n color: #999;\r\n background-color: #f0f0f0;\r\n padding: 5px 15px;\r\n border-radius: 15px;\r\n text-align: center;\r\n}\r\n\r\n/* 时间分割线 */\r\n.time-divider {\r\n display: flex;\r\n flex-direction: row;\r\n justify-content: center;\r\n margin: 20px 0;\r\n}\r\n\r\n.time-text {\r\n font-size: 12px;\r\n color: #999;\r\n background-color: #f0f0f0;\r\n padding: 3px 10px;\r\n border-radius: 10px;\r\n text-align: center;\r\n}\r\n\r\n/* 消息项 */\r\n.message-wrapper {\r\n display: flex;\r\n flex-direction: row;\r\n margin-bottom: 15px;\r\n}\r\n\r\n.message-wrapper.me {\r\n justify-content: flex-end;\r\n}\r\n\r\n.avatar {\r\n width: 40px;\r\n height: 40px;\r\n border-radius: 20px;\r\n margin-right: 10px;\r\n flex-shrink: 0;\r\n}\r\n\r\n.avatar.me {\r\n margin-right: 0;\r\n margin-left: 10px;\r\n /* order: 2; removed for uni-app-x */\r\n}\r\n\r\n.message-content-wrapper {\r\n width: 260px;\r\n display: flex;\r\n flex-direction: column;\r\n}\r\n\r\n.message-bubble {\r\n background-color: white;\r\n padding: 10px 15px;\r\n border-radius: 12px;\r\n position: relative;\r\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\r\n}\r\n\r\n.received-bubble {\r\n align-self: flex-start;\r\n border-top-left-radius: 2px;\r\n}\r\n\r\n.message-bubble.me {\r\n background-color: #95ec69;\r\n align-self: flex-end; /* 关键:靠右对齐且宽度自适应 */\r\n border-top-right-radius: 2px;\r\n}\r\n\r\n.sender-name {\r\n font-size: 11px;\r\n color: #999;\r\n margin-bottom: 2px;\r\n align-self: flex-start;\r\n}\r\n\r\n.message-text {\r\n font-size: 15px;\r\n color: #333;\r\n line-height: 1.4;\r\n margin-bottom: 5px;\r\n white-space: pre-wrap;\r\n}\r\n\r\n.message-time {\r\n font-size: 11px;\r\n color: #999;\r\n text-align: right;\r\n}\r\n\r\n/* 聊天输入区 */\r\n.chat-input {\r\n background-color: white;\r\n border-top: 1px solid #eee;\r\n padding: 10px 15px;\r\n padding-bottom: 20px;\r\n position: fixed;\r\n bottom: 0;\r\n left: 0;\r\n right: 0;\r\n flex-shrink: 0;\r\n}\r\n\r\n.input-tools {\r\n display: flex;\r\n flex-direction: row;\r\n margin-bottom: 10px;\r\n}\r\n\r\n.tool-icon {\r\n font-size: 20px;\r\n margin-right: 15px;\r\n color: #666;\r\n}\r\n\r\n.input-wrapper {\r\n display: flex;\r\n flex-direction: row;\r\n align-items: center;\r\n}\r\n\r\n.message-input {\r\n flex: 1;\r\n background-color: #f5f5f5;\r\n border-radius: 20px;\r\n padding: 10px 15px;\r\n font-size: 15px;\r\n margin-right: 10px;\r\n min-height: 40px;\r\n max-height: 100px;\r\n}\r\n\r\n.send-button {\r\n background-color: #ccc;\r\n color: white;\r\n border: none;\r\n border-radius: 20px;\r\n padding: 8px 20px;\r\n font-size: 14px;\r\n min-width: 60px;\r\n transition: all 0.3s ease;\r\n}\r\n\r\n.send-button.active {\r\n background-color: #ff5000;\r\n}\r\n\r\n/* 表情选择器 */\r\n.emoji-picker {\r\n background-color: white;\r\n border-top: 1px solid #eee;\r\n padding: 10px;\r\n height: 200px;\r\n position: fixed;\r\n bottom: 80px;\r\n left: 0;\r\n right: 0;\r\n z-index: 99;\r\n}\r\n\r\n.emoji-category {\r\n display: flex;\r\n flex-direction: row;\r\n flex-wrap: wrap;\r\n}\r\n\r\n.emoji-item {\r\n font-size: 24px;\r\n padding: 8px;\r\n width: 45px;\r\n height: 45px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n\r\n/* 响应式适配 removed for strict uv-app-x compliance */\r\n</style>\r\n\r\n",null,null,null,null,null,null,null],"names":[],"mappings":"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"}