1 line
44 KiB
Plaintext
1 line
44 KiB
Plaintext
{"version":3,"sources":["pages/mall/consumer/chat.uvue","pages/user/profile.uvue","pages/main/index.uvue","pages/user/change-password.uvue","pages/user/terms.uvue","pages/user/login.uvue","pages/mall/consumer/product-detail.uvue","pages/main/profile.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 <!-- 图片消息 -->\r\n <image \r\n v-if=\"message.msgType == 'image'\" \r\n class=\"message-image\" \r\n :src=\"message.content\" \r\n mode=\"widthFix\"\r\n @click=\"previewImage(message.content)\"\r\n />\r\n <!-- 文本消息 -->\r\n <text v-if=\"message.msgType != 'image'\" 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 <!-- 图片消息 -->\r\n <image \r\n v-if=\"message.msgType == 'image'\" \r\n class=\"message-image\" \r\n :src=\"message.content\" \r\n mode=\"widthFix\"\r\n @click=\"previewImage(message.content)\"\r\n />\r\n <!-- 文本消息 -->\r\n <text v-if=\"message.msgType != 'image'\" 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\tmsgType: string // 'text' | 'image'\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\tconst msgType = newMsg.getString('msg_type') ?? 'text'\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\t\t\tconsole.log('消息类型 msgType:', msgType)\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\tmsgType: msgType\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 msgType: m.msg_type ?? 'text'\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 showEmoji.value = false\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 showEmoji.value = false // 选中表情后收起表情列表\r\n inputFocus.value = true\r\n}\r\n\r\n// 显示表情选择器\r\nfunction showEmojiPicker(): void {\r\n showEmoji.value = !showEmoji.value\r\n if (showEmoji.value) {\r\n // 如果打开表情,通常需要收起键盘\r\n uni.hideKeyboard()\r\n }\r\n}\r\n\r\n// 执行图片上传\r\nasync function doUploadImage(filePath: string): Promise<void> {\r\n console.log('[doUploadImage] 开始上传图片:', filePath)\r\n \r\n // 显示加载提示\r\n uni.showLoading({\r\n title: '发送中...',\r\n mask: true\r\n })\r\n \r\n try {\r\n // 上传图片\r\n const imageUrl = await supabaseService.uploadChatImage(filePath)\r\n \r\n uni.hideLoading()\r\n \r\n if (imageUrl == '') {\r\n uni.showToast({\r\n title: '图片上传失败',\r\n icon: 'none'\r\n })\r\n return\r\n }\r\n \r\n console.log('[doUploadImage] 图片上传成功:', imageUrl)\r\n \r\n // 发送图片消息\r\n const success = await supabaseService.sendMessage(merchantId.value, imageUrl, 'image')\r\n if (!success) {\r\n uni.showToast({\r\n title: '发送失败',\r\n icon: 'none'\r\n })\r\n }\r\n } catch (e) {\r\n uni.hideLoading()\r\n console.error('[doUploadImage] 上传异常:', e)\r\n uni.showToast({\r\n title: '上传失败',\r\n icon: 'none'\r\n })\r\n }\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('选择图片成功:', JSON.stringify(res))\r\n \r\n // 处理 tempFilePaths,兼容不同平台\r\n let filePath: string = ''\r\n const tempFilePaths = res.tempFilePaths\r\n if (tempFilePaths != null) {\r\n if (Array.isArray(tempFilePaths)) {\r\n const arr = tempFilePaths as string[]\r\n if (arr.length > 0) {\r\n filePath = arr[0]\r\n }\r\n } else if (tempFilePaths instanceof UTSJSONObject) {\r\n const keys = UTSJSONObject.keys(tempFilePaths as UTSJSONObject)\r\n if (keys.length > 0) {\r\n filePath = (tempFilePaths as UTSJSONObject).getString(keys[0]) ?? ''\r\n }\r\n } else if (typeof tempFilePaths === 'string') {\r\n filePath = tempFilePaths as string\r\n }\r\n }\r\n \r\n // 尝试从 tempFiles 获取\r\n if (filePath == '' && res.tempFiles != null) {\r\n const tempFiles = res.tempFiles\r\n if (Array.isArray(tempFiles)) {\r\n const files = tempFiles as any[]\r\n if (files.length > 0) {\r\n const firstFile = files[0]\r\n if (firstFile instanceof UTSJSONObject) {\r\n filePath = firstFile.getString('path') ?? ''\r\n } else if (typeof firstFile === 'object' && firstFile != null) {\r\n const fileObj = JSON.parse(JSON.stringify(firstFile)) as UTSJSONObject\r\n filePath = fileObj.getString('path') ?? ''\r\n }\r\n }\r\n }\r\n }\r\n \r\n console.log('[showImagePicker] 文件路径:', filePath)\r\n \r\n if (filePath == '') {\r\n uni.showToast({\r\n title: '获取图片路径失败',\r\n icon: 'none'\r\n })\r\n return\r\n }\r\n \r\n // 执行上传\r\n doUploadImage(filePath)\r\n },\r\n fail: (err) => {\r\n console.log('选择图片失败:', err)\r\n uni.showToast({\r\n title: '选择图片失败',\r\n icon: 'none'\r\n })\r\n }\r\n })\r\n}\r\n\r\n// 预览图片\r\nfunction previewImage(url: string): void {\r\n uni.previewImage({\r\n urls: [url],\r\n current: url\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: 20px;\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-image {\r\n max-width: 200px;\r\n min-width: 100px;\r\n border-radius: 8px;\r\n margin-bottom: 5px;\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,null,null],"names":[],"mappings":"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"} |