diff --git a/pages/Chat/Chat.css b/pages/Chat/Chat.css index ee07b11..2157f1b 100644 --- a/pages/Chat/Chat.css +++ b/pages/Chat/Chat.css @@ -1066,3 +1066,172 @@ white-space: pre-wrap; word-break: break-all; } + +/* ===== 调试按钮(顶部Header) ===== */ +.debug-top-btn { + flex-shrink: 0; + background: rgba(108, 99, 255, 0.15); +} + +.debug-top-btn:active { + background: rgba(108, 99, 255, 0.3); +} + +.debug-top-text { + font-size: 18rpx; + font-weight: 700; + color: #6c63ff; +} + +/* ===== 调试面板(居中弹窗) ===== */ +.debug-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.5); + z-index: 9999; + display: flex; + align-items: center; + justify-content: center; + padding: 40rpx; + box-sizing: border-box; +} + +.debug-panel { + width: 100%; + max-height: 80vh; + background: #1e1e2e; + border-radius: 24rpx; + display: flex; + flex-direction: column; + overflow: hidden; +} + +.debug-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 28rpx 32rpx 20rpx; + border-bottom: 1rpx solid rgba(255, 255, 255, 0.08); +} + +.debug-title { + font-size: 30rpx; + font-weight: 600; + color: #cdd6f4; +} + +.debug-actions { + display: flex; + align-items: center; + gap: 28rpx; +} + +.debug-clear-btn { + font-size: 24rpx; + color: #f38ba8; + padding: 6rpx 16rpx; + border-radius: 12rpx; + background: rgba(243, 139, 168, 0.12); +} + +.debug-close-btn { + font-size: 32rpx; + color: #a6adc8; + font-weight: 700; +} + +.debug-section { + padding: 20rpx 24rpx; + border-bottom: 1rpx solid rgba(255, 255, 255, 0.05); +} + +.debug-label { + font-size: 24rpx; + color: #89b4fa; + font-weight: 600; + margin-bottom: 12rpx; +} + +/* 状态网格 */ +.debug-state-grid { + display: flex; + flex-wrap: wrap; + gap: 12rpx 28rpx; +} + +.debug-state-item { + font-size: 24rpx; + color: #cdd6f4; +} + +.state-key { + color: #a6adc8; +} + +.state-val { + color: #cdd6f4; +} + +.state-val-ok { + color: #a6e3a1; +} + +.state-val-err { + color: #f38ba8; +} + +.state-val-warn { + color: #f9e2af; +} + +/* 原始消息展示 */ +.debug-raw-box { + max-height: 400rpx; + background: rgba(0, 0, 0, 0.25); + border-radius: 12rpx; + padding: 16rpx; + overflow-y: auto; +} + +.debug-json { + font-size: 20rpx; + color: #bac2de; + font-family: 'Courier New', monospace; + white-space: pre-wrap; + word-break: break-all; + line-height: 1.5; +} + +.debug-empty { + font-size: 22rpx; + color: #585b70; + font-style: italic; + padding: 12rpx 0; +} + +/* 本轮消息列表项 */ +.debug-round-item { + padding: 12rpx 0; + border-bottom: 1rpx solid rgba(255, 255, 255, 0.04); +} + +.debug-round-item:last-child { + border-bottom: none; +} + +.debug-round-index { + font-size: 22rpx; + color: #f5c2e7; + font-weight: 600; + margin-bottom: 6rpx; +} + +.debug-round-time { + font-size: 20rpx; + color: #585b70; + font-weight: 400; + margin-left: 12rpx; +} diff --git a/pages/Chat/Chat.vue b/pages/Chat/Chat.vue index 50cd630..2a33ced 100644 --- a/pages/Chat/Chat.vue +++ b/pages/Chat/Chat.vue @@ -108,6 +108,9 @@ + + {{ showDebugPanel ? '✕' : 'LOG' }} + @@ -340,6 +343,62 @@ + + + + + Socket 调试日志 + + 清空 + + + + + + + 当前状态 + + + 连接: + {{ socketStore.connectionStatus }} + + + AI思考: + {{ socketStore.isThinking ? '是' : '否' }} + + + 流式ID: + {{ streamingMessageId || '-' }} + + + SessionID: + {{ (currentSessionId || '').slice(-8) || '-' }} + + + + + + + 最后一帧接收 + + {{ formatDebugJson(socketStore.lastReceiveRaw.data) }} + + 暂无接收数据 + + + + + 本轮消息 ({{ socketStore.questionRoundMessages.length }}条) + + + #{{ i + 1 }} {{ formatDebugTime(msg.time) }} + {{ formatDebugJson(msg.data) }} + + 暂无本轮消息 + + + + @@ -1010,6 +1069,9 @@ import { openFile as openFileNative, downloadAndOpen } from '@/utils/fileOpener. const showMessageModal = ref(false) const detailLinks = ref([]) + // 调试面板 + const showDebugPanel = ref(false) + // 点击气泡内容:拦截链接点击,否则 AI 对话弹出详情 const handleChatContentClick = (e, message) => { // 在事件路径中向上查找 .chat-inline-link 元素 @@ -1353,6 +1415,8 @@ import { openFile as openFileNative, downloadAndOpen } from '@/utils/fileOpener. // 发送AI消息 const sendAIMessage = async () => { try { + // 调试:开始新的提问轮次,记录本轮所有 socket 消息 + socketStore.startNewRound() let messageContent = textMessage.value // 立即添加用户消息到列表(使用完整的 messageContent,包含文件信息) allmessages.value = [...allmessages.value, { @@ -2019,6 +2083,35 @@ import { openFile as openFileNative, downloadAndOpen } from '@/utils/fileOpener. }) // 离开 AI 对话页面时断开 socket + // ===== 调试面板相关 ===== + const toggleDebugPanel = () => { + showDebugPanel.value = !showDebugPanel.value + } + + const clearDebugRound = () => { + socketStore.clearRoundMessages() + } + + const formatDebugJson = (data) => { + try { + return JSON.stringify(data, null, 2) + } catch { + return String(data) + } + } + + const formatDebugTime = (isoStr) => { + try { + const t = new Date(isoStr) + const h = t.getHours().toString().padStart(2, '0') + const m = t.getMinutes().toString().padStart(2, '0') + const s = t.getSeconds().toString().padStart(2, '0') + return `${h}:${m}:${s}` + } catch { + return isoStr + } + } + onUnload(() => { socketStore.disconnect() }) diff --git a/stores/socket.js b/stores/socket.js index 941bfe0..16d2963 100644 --- a/stores/socket.js +++ b/stores/socket.js @@ -29,6 +29,10 @@ export const useSocketStore = defineStore('socket', () => { const logs = ref([]) const maxLogCount = ref(20) + // 调试:记录上一次收到的原始消息和当前提问轮次的所有消息 + const lastReceiveRaw = ref(null) + const questionRoundMessages = ref([]) + const authFailReason = ref('') const pcOffline = ref(false) @@ -59,6 +63,17 @@ export const useSocketStore = defineStore('socket', () => { logs.value = [] } + // 调试:开始新的提问轮次 + function startNewRound() { + questionRoundMessages.value = [] + } + + // 调试:清除轮次记录 + function clearRoundMessages() { + questionRoundMessages.value = [] + lastReceiveRaw.value = null + } + // ==================== 连接相关方法 ==================== function connect(options = {}) { messages.value = [] @@ -153,6 +168,20 @@ export const useSocketStore = defineStore('socket', () => { function handleMessage(messageData) { addLog('receive', `收到: ${JSON.stringify(messageData)}`) + // 调试:记录上一次收到的原始消息 + lastReceiveRaw.value = { + time: new Date().toISOString(), + data: messageData + } + // 调试:记录当前提问轮次的所有消息 + questionRoundMessages.value.push({ + time: new Date().toISOString(), + data: messageData + }) + if (questionRoundMessages.value.length > 200) { + questionRoundMessages.value = questionRoundMessages.value.slice(-50) + } + const { type, conversation_id, @@ -291,6 +320,8 @@ export const useSocketStore = defineStore('socket', () => { config, authFailReason, pcOffline, + lastReceiveRaw, + questionRoundMessages, // 计算属性 isConnected, @@ -305,6 +336,8 @@ export const useSocketStore = defineStore('socket', () => { send, addLog, clearLogs, + startNewRound, + clearRoundMessages, getStatusText } }) \ No newline at end of file diff --git a/unpackage/dist/dev/app-plus/app-service.js b/unpackage/dist/dev/app-plus/app-service.js index fee9613..f3c0209 100644 --- a/unpackage/dist/dev/app-plus/app-service.js +++ b/unpackage/dist/dev/app-plus/app-service.js @@ -4761,6 +4761,8 @@ This will fail in production.`); vue.ref(""); const logs = vue.ref([]); const maxLogCount = vue.ref(20); + const lastReceiveRaw = vue.ref(null); + const questionRoundMessages = vue.ref([]); const authFailReason = vue.ref(""); const pcOffline = vue.ref(false); const isConnected = vue.computed(() => connectionStatus.value === "connected"); @@ -4779,11 +4781,18 @@ This will fail in production.`); if (logs.value.length > maxLogCount.value) { logs.value = logs.value.slice(-maxLogCount.value); } - formatAppLog("log", "at stores/socket.js:55", `[${type.toUpperCase()}] ${connect2}`); + formatAppLog("log", "at stores/socket.js:59", `[${type.toUpperCase()}] ${connect2}`); } function clearLogs() { logs.value = []; } + function startNewRound() { + questionRoundMessages.value = []; + } + function clearRoundMessages() { + questionRoundMessages.value = []; + lastReceiveRaw.value = null; + } function connect(options = {}) { messages.value = []; messageString.value = ""; @@ -4818,7 +4827,7 @@ This will fail in production.`); addLog("warn", "已主动断开连接"); } async function send(message) { - formatAppLog("log", "at stores/socket.js:100", "检查到要发生消息为:", message); + formatAppLog("log", "at stores/socket.js:115", "检查到要发生消息为:", message); if (!isConnected.value) { addLog("error", "发送失败: 连接未建立"); throw new Error("连接未建立"); @@ -4835,7 +4844,7 @@ This will fail in production.`); function handleOpen() { connectionStatus.value = "connected"; addLog("success", "连接成功!发送auth"); - formatAppLog("log", "at stores/socket.js:119", "连接成功!发送auth"); + formatAppLog("log", "at stores/socket.js:134", "连接成功!发送auth"); sendAuth(); } function handleClose() { @@ -4863,13 +4872,24 @@ This will fail in production.`); } function handleMessage(messageData) { addLog("receive", `收到: ${JSON.stringify(messageData)}`); + lastReceiveRaw.value = { + time: (/* @__PURE__ */ new Date()).toISOString(), + data: messageData + }; + questionRoundMessages.value.push({ + time: (/* @__PURE__ */ new Date()).toISOString(), + data: messageData + }); + if (questionRoundMessages.value.length > 200) { + questionRoundMessages.value = questionRoundMessages.value.slice(-50); + } const { type, conversation_id, message_id, data } = messageData || {}; - formatAppLog("log", "at stores/socket.js:164", `[handleMessage] type = ${type}, data = ${JSON.stringify(data)}`); + formatAppLog("log", "at stores/socket.js:193", `[handleMessage] type = ${type}, data = ${JSON.stringify(data)}`); switch (type) { case "auth_ok": addLog("success", "连接成功"); @@ -4903,14 +4923,14 @@ This will fail in production.`); } function handleBusinessMessage(data) { if (data === "exit") { - formatAppLog("log", "at stores/socket.js:227", "ai结束思考"); + formatAppLog("log", "at stores/socket.js:256", "ai结束思考"); isThinking.value = false; return; } if (!data || typeof data !== "object") return; if (data.cmd === "event_callback" && data.info === "中断成功") { - formatAppLog("log", "at stores/socket.js:237", "后端确认中断成功"); + formatAppLog("log", "at stores/socket.js:266", "后端确认中断成功"); addLog("warn", `中断确认: ${data.info}`); isThinking.value = false; return; @@ -4924,14 +4944,14 @@ This will fail in production.`); task_call_id } = data; if (!isThinking.value && (chunk || message_role === "assistant")) { - formatAppLog("log", "at stores/socket.js:254", "ai开始思考"); + formatAppLog("log", "at stores/socket.js:283", "ai开始思考"); messageString.value = ""; isThinking.value = true; } if (chunk) { messageString.value += chunk; if (!isThinking.value) { - formatAppLog("log", "at stores/socket.js:263", "修改状态为开始思考"); + formatAppLog("log", "at stores/socket.js:292", "修改状态为开始思考"); isThinking.value = true; } } @@ -4954,6 +4974,8 @@ This will fail in production.`); config, authFailReason, pcOffline, + lastReceiveRaw, + questionRoundMessages, // 计算属性 isConnected, isConnecting, @@ -4966,6 +4988,8 @@ This will fail in production.`); send, addLog, clearLogs, + startNewRound, + clearRoundMessages, getStatusText }; }); @@ -5811,7 +5835,7 @@ This will fail in production.`); if (friendSocketStore.isConnected) return; if (!userToken.value || !UserId.value) { - formatAppLog("warn", "at pages/Chat/Chat.vue:409", "Token或UserId未准备好"); + formatAppLog("warn", "at pages/Chat/Chat.vue:468", "Token或UserId未准备好"); return; } friendSocketStore.connect({ @@ -6008,7 +6032,7 @@ This will fail in production.`); }); return html; } catch (e2) { - formatAppLog("error", "at pages/Chat/Chat.vue:617", "解析失败", e2); + formatAppLog("error", "at pages/Chat/Chat.vue:676", "解析失败", e2); return content; } }; @@ -6059,7 +6083,7 @@ This will fail in production.`); files }; } catch (e2) { - formatAppLog("error", "at pages/Chat/Chat.vue:686", "解析文件信息失败:", e2); + formatAppLog("error", "at pages/Chat/Chat.vue:745", "解析文件信息失败:", e2); return { textContent: content, files: [] @@ -6099,7 +6123,7 @@ This will fail in production.`); currentSessionId.value = conversationId; uni.setStorageSync("currentSessionId", conversationId); } catch (error) { - formatAppLog("error", "at pages/Chat/Chat.vue:735", "新建普通会话失败:", error); + formatAppLog("error", "at pages/Chat/Chat.vue:794", "新建普通会话失败:", error); uni.showToast({ title: "创建会话失败,请重试", icon: "none" @@ -6126,7 +6150,7 @@ This will fail in production.`); uni.showToast({ title: "获取智能体列表失败", icon: "none" }); } } catch (error) { - formatAppLog("error", "at pages/Chat/Chat.vue:767", "获取智能体列表失败:", error); + formatAppLog("error", "at pages/Chat/Chat.vue:826", "获取智能体列表失败:", error); uni.showToast({ title: "获取智能体列表失败,请重试", icon: "none" }); } finally { agentLoading.value = false; @@ -6153,7 +6177,7 @@ This will fail in production.`); uni.showToast({ title: `已创建「${result.title || agent.title}」会话`, icon: "success" }); } catch (error) { uni.hideLoading(); - formatAppLog("error", "at pages/Chat/Chat.vue:798", "创建智能体会话失败:", error); + formatAppLog("error", "at pages/Chat/Chat.vue:857", "创建智能体会话失败:", error); uni.showToast({ title: typeof error === "string" ? error : "创建失败,请重试", icon: "none" }); } }; @@ -6242,7 +6266,7 @@ This will fail in production.`); }; const previewFileArray = vue.ref([]); const uploadPhoto = () => { - formatAppLog("log", "at pages/Chat/Chat.vue:915", "点击了拍照上传"); + formatAppLog("log", "at pages/Chat/Chat.vue:974", "点击了拍照上传"); uni.chooseImage({ count: 1, sourceType: ["camera", "album"], @@ -6265,7 +6289,7 @@ This will fail in production.`); }); }, fail: (err) => { - formatAppLog("error", "at pages/Chat/Chat.vue:933", "选择图片失败", err); + formatAppLog("error", "at pages/Chat/Chat.vue:992", "选择图片失败", err); } }); }; @@ -6274,12 +6298,12 @@ This will fail in production.`); }; const fileList = vue.ref([]); const uploadFile = () => { - formatAppLog("log", "at pages/Chat/Chat.vue:944", "点击了上传文件"); + formatAppLog("log", "at pages/Chat/Chat.vue:1003", "点击了上传文件"); chooseFile({ count: 5, type: "all", success: (res) => { - formatAppLog("log", "at pages/Chat/Chat.vue:949", "成功了"); + formatAppLog("log", "at pages/Chat/Chat.vue:1008", "成功了"); fileList.value = res.tempFiles; previewFileArray.value.push(...res.tempFiles); uni.showToast({ @@ -6288,7 +6312,7 @@ This will fail in production.`); }); }, fail: (err) => { - formatAppLog("error", "at pages/Chat/Chat.vue:960", "选择失败:", err); + formatAppLog("error", "at pages/Chat/Chat.vue:1019", "选择失败:", err); uni.showToast({ title: "选择失败", icon: "error" @@ -6327,6 +6351,7 @@ This will fail in production.`); const streamingMessageId = vue.ref(null); const showMessageModal = vue.ref(false); const detailLinks = vue.ref([]); + const showDebugPanel = vue.ref(false); const handleChatContentClick = (e2, message) => { let el = e2.target; while (el && el.classList) { @@ -6527,7 +6552,7 @@ This will fail in production.`); previewFileArray.value = []; } catch (err) { uni.hideLoading(); - formatAppLog("error", "at pages/Chat/Chat.vue:1235", "文件上传失败:", err); + formatAppLog("error", "at pages/Chat/Chat.vue:1297", "文件上传失败:", err); uni.showToast({ title: "文件上传失败,请重试", icon: "error" @@ -6623,6 +6648,7 @@ This will fail in production.`); }; const sendAIMessage = async () => { try { + socketStore.startNewRound(); let messageContent = textMessage.value; allmessages.value = [...allmessages.value, { role: "user", @@ -6661,15 +6687,15 @@ This will fail in production.`); } }; const stopConversation = async () => { - formatAppLog("log", "at pages/Chat/Chat.vue:1405", "中断对话 - 当前会话ID:", currentSessionId.value); + formatAppLog("log", "at pages/Chat/Chat.vue:1469", "中断对话 - 当前会话ID:", currentSessionId.value); try { await socketStore.send({ type: "stop", conversation_id: currentSessionId.value }); - formatAppLog("log", "at pages/Chat/Chat.vue:1411", "中断指令已发送成功"); + formatAppLog("log", "at pages/Chat/Chat.vue:1475", "中断指令已发送成功"); } catch (err) { - formatAppLog("error", "at pages/Chat/Chat.vue:1413", "中断指令发送失败:", err); + formatAppLog("error", "at pages/Chat/Chat.vue:1477", "中断指令发送失败:", err); } if (streamingMessageId.value) { allmessages.value = allmessages.value.filter((m) => m._id !== streamingMessageId.value); @@ -6688,9 +6714,9 @@ This will fail in production.`); }); }; vue.watch(() => socketStore.isThinking, async (newVal, oldVal) => { - formatAppLog("log", "at pages/Chat/Chat.vue:1438", "isThinking 变化:", oldVal, "→", newVal, "messageString:", socketStore.messageString); + formatAppLog("log", "at pages/Chat/Chat.vue:1502", "isThinking 变化:", oldVal, "→", newVal, "messageString:", socketStore.messageString); if (!oldVal && newVal) { - formatAppLog("log", "at pages/Chat/Chat.vue:1441", "AI开始回复(跨设备同步),锁定输入框"); + formatAppLog("log", "at pages/Chat/Chat.vue:1505", "AI开始回复(跨设备同步),锁定输入框"); isThinking.value = true; if (!isSelfSent.value) { await takeConversationMessages(); @@ -6707,7 +6733,7 @@ This will fail in production.`); return; } if (oldVal && !newVal) { - formatAppLog("log", "at pages/Chat/Chat.vue:1460", "AI回复结束(正常/中断),解锁并刷新消息列表"); + formatAppLog("log", "at pages/Chat/Chat.vue:1524", "AI回复结束(正常/中断),解锁并刷新消息列表"); await takeConversationMessages(); if (streamingMessageId.value) { allmessages.value = allmessages.value.filter((m) => m._id !== streamingMessageId.value); @@ -6778,15 +6804,15 @@ This will fail in production.`); UserData.value = await getUserInfo(userToken.value); UserId.value = UserData.value._id; UserAvatar.value = UserData.value.avatar || ""; - formatAppLog("log", "at pages/Chat/Chat.vue:1547", "用户信息已加载:", UserId.value, UserAvatar.value); + formatAppLog("log", "at pages/Chat/Chat.vue:1611", "用户信息已加载:", UserId.value, UserAvatar.value); } catch (error) { - formatAppLog("error", "at pages/Chat/Chat.vue:1549", "获取用户信息失败:", error); + formatAppLog("error", "at pages/Chat/Chat.vue:1613", "获取用户信息失败:", error); } }; const takeUserConversations = async () => { try { userToken.value = getToken(); - formatAppLog("log", "at pages/Chat/Chat.vue:1557", "token:", userToken.value); + formatAppLog("log", "at pages/Chat/Chat.vue:1621", "token:", userToken.value); UserConversations.value = await getUserConversations(userToken.value) || []; const savedSessionId = getCurrentSessionId(); if (savedSessionId && UserConversations.value.some((c) => c._id === savedSessionId)) { @@ -6796,7 +6822,7 @@ This will fail in production.`); } else { currentSessionId.value = ""; } - formatAppLog("log", "at pages/Chat/Chat.vue:1569", "保存会话id:", currentSessionId.value); + formatAppLog("log", "at pages/Chat/Chat.vue:1633", "保存会话id:", currentSessionId.value); uni.setStorageSync("currentSessionId", currentSessionId.value); } catch (error) { uni.showToast({ @@ -6808,17 +6834,17 @@ This will fail in production.`); const FriendInfoList = vue.ref([]); const takeFriendList = async () => { try { - formatAppLog("log", "at pages/Chat/Chat.vue:1584", "开始获取好友列表"); + formatAppLog("log", "at pages/Chat/Chat.vue:1648", "开始获取好友列表"); const friendList = await getChatFriend(UserId.value); - formatAppLog("log", "at pages/Chat/Chat.vue:1587", "friendList:", friendList); + formatAppLog("log", "at pages/Chat/Chat.vue:1651", "friendList:", friendList); if (friendList && friendList.length) { FriendInfoList.value = await takeUserAvatar(friendList); } else { FriendInfoList.value = []; - formatAppLog("log", "at pages/Chat/Chat.vue:1592", "好友列表为空"); + formatAppLog("log", "at pages/Chat/Chat.vue:1656", "好友列表为空"); } } catch (error) { - formatAppLog("error", "at pages/Chat/Chat.vue:1595", "获取好友列表失败:", error); + formatAppLog("error", "at pages/Chat/Chat.vue:1659", "获取好友列表失败:", error); FriendInfoList.value = []; } finally { UserConversations.value = FriendInfoList.value; @@ -6845,17 +6871,17 @@ This will fail in production.`); }; }); } catch (err) { - formatAppLog("error", "at pages/Chat/Chat.vue:1625", "获取好友头像失败", err); + formatAppLog("error", "at pages/Chat/Chat.vue:1689", "获取好友头像失败", err); return friendList; } }; const GroupList = vue.ref([]); const takeGroupList = async () => { try { - formatAppLog("log", "at pages/Chat/Chat.vue:1635", "开始获取群聊列表"); + formatAppLog("log", "at pages/Chat/Chat.vue:1699", "开始获取群聊列表"); GroupList.value = await getGroup(UserId.value); } catch (error) { - formatAppLog("error", "at pages/Chat/Chat.vue:1640", "获取群聊列表失败:", error); + formatAppLog("error", "at pages/Chat/Chat.vue:1704", "获取群聊列表失败:", error); GroupList.value = []; } finally { UserConversations.value = GroupList.value; @@ -6867,22 +6893,22 @@ This will fail in production.`); return []; try { const memberIds = memberList.map((item) => item.groupContactId); - formatAppLog("log", "at pages/Chat/Chat.vue:1654", "请求头像的ID列表:", memberIds); + formatAppLog("log", "at pages/Chat/Chat.vue:1718", "请求头像的ID列表:", memberIds); const memberAvatarList = await getUserAvatar(userToken.value, memberIds); - formatAppLog("log", "at pages/Chat/Chat.vue:1656", "头像接口返回数据:", memberAvatarList); + formatAppLog("log", "at pages/Chat/Chat.vue:1720", "头像接口返回数据:", memberAvatarList); const userMap = new Map(memberAvatarList.map((user) => [user.user_id, user]) || []); - formatAppLog("log", "at pages/Chat/Chat.vue:1659", "userMap的keys:", Array.from(userMap.keys())); + formatAppLog("log", "at pages/Chat/Chat.vue:1723", "userMap的keys:", Array.from(userMap.keys())); return memberList.map((member) => { const memberId = member.groupContactId; const userInfo = userMap.get(memberId); - formatAppLog("log", "at pages/Chat/Chat.vue:1664", `查找 ${memberId} 的头像:`, userInfo); + formatAppLog("log", "at pages/Chat/Chat.vue:1728", `查找 ${memberId} 的头像:`, userInfo); return { ...member, avatar: (userInfo == null ? void 0 : userInfo.avatar) || null }; }); } catch (err) { - formatAppLog("error", "at pages/Chat/Chat.vue:1671", "获取群成员头像失败", err); + formatAppLog("error", "at pages/Chat/Chat.vue:1735", "获取群成员头像失败", err); return memberList; } }; @@ -6947,12 +6973,12 @@ This will fail in production.`); hasMoreGroupMessages.value = true; const rawMessages = await getGroupMessages(currentSessionId.value, pageSize$1, 0) || []; allmessages.value = rawMessages; - formatAppLog("log", "at pages/Chat/Chat.vue:1760", "群聊消息:", allmessages.value); + formatAppLog("log", "at pages/Chat/Chat.vue:1824", "群聊消息:", allmessages.value); const memberList = await getGroupMemberList(currentSessionId.value); - formatAppLog("log", "at pages/Chat/Chat.vue:1763", "获取到的群成员列表:", memberList); + formatAppLog("log", "at pages/Chat/Chat.vue:1827", "获取到的群成员列表:", memberList); if (memberList && memberList.length) { groupMemberList.value = await takeGroupMemberAvatar(memberList); - formatAppLog("log", "at pages/Chat/Chat.vue:1766", "群成员列表(带头像):", groupMemberList.value); + formatAppLog("log", "at pages/Chat/Chat.vue:1830", "群成员列表(带头像):", groupMemberList.value); } else { groupMemberList.value = []; } @@ -6991,7 +7017,7 @@ This will fail in production.`); hasMoreAIMessages.value = false; } } catch (e2) { - formatAppLog("error", "at pages/Chat/Chat.vue:1828", "加载更多消息失败:", e2); + formatAppLog("error", "at pages/Chat/Chat.vue:1892", "加载更多消息失败:", e2); uni.showToast({ title: "加载更多失败", icon: "none" }); } finally { isAILoadingMore.value = false; @@ -7013,7 +7039,7 @@ This will fail in production.`); hasMoreFriendMessages.value = false; } } catch (e2) { - formatAppLog("error", "at pages/Chat/Chat.vue:1853", "加载更多好友消息失败:", e2); + formatAppLog("error", "at pages/Chat/Chat.vue:1917", "加载更多好友消息失败:", e2); uni.showToast({ title: "加载更多失败", icon: "none" }); } finally { isFriendLoadingMore.value = false; @@ -7035,7 +7061,7 @@ This will fail in production.`); hasMoreGroupMessages.value = false; } } catch (e2) { - formatAppLog("error", "at pages/Chat/Chat.vue:1878", "加载更多群聊消息失败:", e2); + formatAppLog("error", "at pages/Chat/Chat.vue:1942", "加载更多群聊消息失败:", e2); uni.showToast({ title: "加载更多失败", icon: "none" }); } finally { isGroupLoadingMore.value = false; @@ -7051,9 +7077,9 @@ This will fail in production.`); } }; vue.watch(() => friendSocketStore.MessageReceived, (newId) => { - formatAppLog("log", "at pages/Chat/Chat.vue:1899", "收到了好友消息"); + formatAppLog("log", "at pages/Chat/Chat.vue:1963", "收到了好友消息"); if (newId) { - formatAppLog("log", "at pages/Chat/Chat.vue:1901", "ChatType:", ChatType.value); + formatAppLog("log", "at pages/Chat/Chat.vue:1965", "ChatType:", ChatType.value); switch (ChatType.value) { case 0: takeConversationMessages(); @@ -7068,7 +7094,7 @@ This will fail in production.`); friendSocketStore.MessageReceived = false; break; default: - formatAppLog("log", "at pages/Chat/Chat.vue:1917", "default 分支"); + formatAppLog("log", "at pages/Chat/Chat.vue:1981", "default 分支"); friendSocketStore.MessageReceived = false; break; } @@ -7155,14 +7181,38 @@ This will fail in production.`); await takeGroupMessages(); } }); + const toggleDebugPanel = () => { + showDebugPanel.value = !showDebugPanel.value; + }; + const clearDebugRound = () => { + socketStore.clearRoundMessages(); + }; + const formatDebugJson = (data) => { + try { + return JSON.stringify(data, null, 2); + } catch { + return String(data); + } + }; + const formatDebugTime = (isoStr) => { + try { + const t2 = new Date(isoStr); + const h = t2.getHours().toString().padStart(2, "0"); + const m = t2.getMinutes().toString().padStart(2, "0"); + const s = t2.getSeconds().toString().padStart(2, "0"); + return `${h}:${m}:${s}`; + } catch { + return isoStr; + } + }; onUnload(() => { socketStore.disconnect(); }); - const __returned__ = { friendSocketStore, handleFriendConnect, socketStore, ChatType, wyxdWorkspaceId, wyxdFilePath, wyxdFileName, wyxdUserToken, hasWyxdFile, convertMarkdownTable, renderTable, escapeLoneUnderscores, isDownloadLink, renderDownloadBtn, supportedExtensions, extPattern, pareseMarkdown, sanitizeContent, previewImage, openFile: openFile$1, formatFileSize: formatFileSize2, parseFileInfo, selectNormalChat, showNewChatModal, closeNewChatModal, showAgentModal, agentList, agentLoading, selectAgentChat, closeAgentModal, handleAgentSelect, isChatSidebar, handleChatSidebar, goWorkSpace, goWyxdViewer, goCloudDatabase, logOut, handleRefresh, previewFileArray, uploadPhoto, deleteImage, fileList, uploadFile, handleConnect, isThinking, isSelfSent, isUploading, isLoadingMessages, uploadedFiles, streamingMessageId, showMessageModal, detailLinks, handleChatContentClick, extractLinks, extractFileNameFromUrl, getFileTypeInfo, showMessageDetail, closeMessageDetail, downloadToast, get downloadToastTimer() { + const __returned__ = { friendSocketStore, handleFriendConnect, socketStore, ChatType, wyxdWorkspaceId, wyxdFilePath, wyxdFileName, wyxdUserToken, hasWyxdFile, convertMarkdownTable, renderTable, escapeLoneUnderscores, isDownloadLink, renderDownloadBtn, supportedExtensions, extPattern, pareseMarkdown, sanitizeContent, previewImage, openFile: openFile$1, formatFileSize: formatFileSize2, parseFileInfo, selectNormalChat, showNewChatModal, closeNewChatModal, showAgentModal, agentList, agentLoading, selectAgentChat, closeAgentModal, handleAgentSelect, isChatSidebar, handleChatSidebar, goWorkSpace, goWyxdViewer, goCloudDatabase, logOut, handleRefresh, previewFileArray, uploadPhoto, deleteImage, fileList, uploadFile, handleConnect, isThinking, isSelfSent, isUploading, isLoadingMessages, uploadedFiles, streamingMessageId, showMessageModal, detailLinks, showDebugPanel, handleChatContentClick, extractLinks, extractFileNameFromUrl, getFileTypeInfo, showMessageDetail, closeMessageDetail, downloadToast, get downloadToastTimer() { return downloadToastTimer; }, set downloadToastTimer(v) { downloadToastTimer = v; - }, showDownloadToast, hideDownloadToast, openLink, downloadAndHandle, sendMessage, sendFriendMessage, sendGroupMessage, sendAIMessage, stopConversation, textMessage, UserConversations, currentSessionId, userToken, UserId, UserAvatar, UserData, takeUserInfo, takeUserConversations, FriendInfoList, takeFriendList, takeTalkUserAvatar, takeUserAvatar, GroupList, takeGroupList, groupMemberList, takeGroupMemberAvatar, getGroupMemberAvatarById, allmessages, scrollToView, bottomToggle, isLoadingMore, isAILoadingMore, aiPageNumber, hasMoreAIMessages, currentPage, pageSize: pageSize$1, isFriendLoadingMore, friendPageNumber, hasMoreFriendMessages, isGroupLoadingMore, groupPageNumber, hasMoreGroupMessages, groupSize, currentMessages, takeConversationMessages, takeFriendMessages, takeGroupMessages, onScrollToUpper, loadMoreAIMessages, loadMoreFriendMessages, loadMoreGroupMessages, onScroll, scrollToBottom, computed: vue.computed, getCurrentInstance: vue.getCurrentInstance, nextTick: vue.nextTick, onMounted: vue.onMounted, ref: vue.ref, watch: vue.watch, get onLoad() { + }, showDownloadToast, hideDownloadToast, openLink, downloadAndHandle, sendMessage, sendFriendMessage, sendGroupMessage, sendAIMessage, stopConversation, textMessage, UserConversations, currentSessionId, userToken, UserId, UserAvatar, UserData, takeUserInfo, takeUserConversations, FriendInfoList, takeFriendList, takeTalkUserAvatar, takeUserAvatar, GroupList, takeGroupList, groupMemberList, takeGroupMemberAvatar, getGroupMemberAvatarById, allmessages, scrollToView, bottomToggle, isLoadingMore, isAILoadingMore, aiPageNumber, hasMoreAIMessages, currentPage, pageSize: pageSize$1, isFriendLoadingMore, friendPageNumber, hasMoreFriendMessages, isGroupLoadingMore, groupPageNumber, hasMoreGroupMessages, groupSize, currentMessages, takeConversationMessages, takeFriendMessages, takeGroupMessages, onScrollToUpper, loadMoreAIMessages, loadMoreFriendMessages, loadMoreGroupMessages, onScroll, scrollToBottom, toggleDebugPanel, clearDebugRound, formatDebugJson, formatDebugTime, computed: vue.computed, getCurrentInstance: vue.getCurrentInstance, nextTick: vue.nextTick, onMounted: vue.onMounted, ref: vue.ref, watch: vue.watch, get onLoad() { return onLoad; }, get onShow() { return onShow; @@ -7458,6 +7508,18 @@ This will fail in production.`); onClick: $setup.logOut }, [ vue.createElementVNode("view", { class: "iconfont icon-tuichu" }) + ]), + vue.createElementVNode("view", { + class: "head-btn debug-top-btn", + onClick: $setup.toggleDebugPanel + }, [ + vue.createElementVNode( + "text", + { class: "debug-top-text" }, + vue.toDisplayString($setup.showDebugPanel ? "✕" : "LOG"), + 1 + /* TEXT */ + ) ]) ]) ]), @@ -8022,7 +8084,152 @@ This will fail in production.`); ], 2 /* CLASS */ - )) : vue.createCommentVNode("v-if", true) + )) : vue.createCommentVNode("v-if", true), + $setup.showDebugPanel ? (vue.openBlock(), vue.createElementBlock("view", { + key: 4, + class: "debug-overlay", + onClick: _cache[14] || (_cache[14] = ($event) => $setup.showDebugPanel = false) + }, [ + vue.createElementVNode("view", { + class: "debug-panel", + onClick: _cache[13] || (_cache[13] = vue.withModifiers(() => { + }, ["stop"])) + }, [ + vue.createElementVNode("view", { class: "debug-header" }, [ + vue.createElementVNode("text", { class: "debug-title" }, "Socket 调试日志"), + vue.createElementVNode("view", { class: "debug-actions" }, [ + vue.createElementVNode("text", { + class: "debug-clear-btn", + onClick: $setup.clearDebugRound + }, "清空"), + vue.createElementVNode("text", { + class: "debug-close-btn", + onClick: _cache[12] || (_cache[12] = ($event) => $setup.showDebugPanel = false) + }, "✕") + ]) + ]), + vue.createElementVNode("view", { class: "debug-section" }, [ + vue.createElementVNode("view", { class: "debug-label" }, "当前状态"), + vue.createElementVNode("view", { class: "debug-state-grid" }, [ + vue.createElementVNode("view", { class: "debug-state-item" }, [ + vue.createElementVNode("text", { class: "state-key" }, "连接:"), + vue.createElementVNode( + "text", + { + class: vue.normalizeClass($setup.socketStore.isConnected ? "state-val-ok" : "state-val-err") + }, + vue.toDisplayString($setup.socketStore.connectionStatus), + 3 + /* TEXT, CLASS */ + ) + ]), + vue.createElementVNode("view", { class: "debug-state-item" }, [ + vue.createElementVNode("text", { class: "state-key" }, "AI思考:"), + vue.createElementVNode( + "text", + { + class: vue.normalizeClass($setup.socketStore.isThinking ? "state-val-warn" : "state-val-ok") + }, + vue.toDisplayString($setup.socketStore.isThinking ? "是" : "否"), + 3 + /* TEXT, CLASS */ + ) + ]), + vue.createElementVNode("view", { class: "debug-state-item" }, [ + vue.createElementVNode("text", { class: "state-key" }, "流式ID:"), + vue.createElementVNode( + "text", + { class: "state-val" }, + vue.toDisplayString($setup.streamingMessageId || "-"), + 1 + /* TEXT */ + ) + ]), + vue.createElementVNode("view", { class: "debug-state-item" }, [ + vue.createElementVNode("text", { class: "state-key" }, "SessionID:"), + vue.createElementVNode( + "text", + { class: "state-val" }, + vue.toDisplayString(($setup.currentSessionId || "").slice(-8) || "-"), + 1 + /* TEXT */ + ) + ]) + ]) + ]), + vue.createElementVNode("view", { class: "debug-section" }, [ + vue.createElementVNode("view", { class: "debug-label" }, "最后一帧接收"), + $setup.socketStore.lastReceiveRaw ? (vue.openBlock(), vue.createElementBlock("scroll-view", { + key: 0, + class: "debug-raw-box", + "scroll-y": "" + }, [ + vue.createElementVNode( + "text", + { class: "debug-json" }, + vue.toDisplayString($setup.formatDebugJson($setup.socketStore.lastReceiveRaw.data)), + 1 + /* TEXT */ + ) + ])) : (vue.openBlock(), vue.createElementBlock("text", { + key: 1, + class: "debug-empty" + }, "暂无接收数据")) + ]), + vue.createElementVNode("view", { class: "debug-section" }, [ + vue.createElementVNode( + "view", + { class: "debug-label" }, + "本轮消息 (" + vue.toDisplayString($setup.socketStore.questionRoundMessages.length) + "条)", + 1 + /* TEXT */ + ), + vue.createElementVNode("scroll-view", { + class: "debug-raw-box", + "scroll-y": "" + }, [ + (vue.openBlock(true), vue.createElementBlock( + vue.Fragment, + null, + vue.renderList($setup.socketStore.questionRoundMessages, (msg, i) => { + return vue.openBlock(), vue.createElementBlock("view", { + key: i, + class: "debug-round-item" + }, [ + vue.createElementVNode("view", { class: "debug-round-index" }, [ + vue.createTextVNode( + "#" + vue.toDisplayString(i + 1) + " ", + 1 + /* TEXT */ + ), + vue.createElementVNode( + "text", + { class: "debug-round-time" }, + vue.toDisplayString($setup.formatDebugTime(msg.time)), + 1 + /* TEXT */ + ) + ]), + vue.createElementVNode( + "text", + { class: "debug-json" }, + vue.toDisplayString($setup.formatDebugJson(msg.data)), + 1 + /* TEXT */ + ) + ]); + }), + 128 + /* KEYED_FRAGMENT */ + )), + !$setup.socketStore.questionRoundMessages.length ? (vue.openBlock(), vue.createElementBlock("text", { + key: 0, + class: "debug-empty" + }, "暂无本轮消息")) : vue.createCommentVNode("v-if", true) + ]) + ]) + ]) + ])) : vue.createCommentVNode("v-if", true) ], 64 /* STABLE_FRAGMENT */ diff --git a/unpackage/dist/dev/app-plus/pages/Chat/Chat.css b/unpackage/dist/dev/app-plus/pages/Chat/Chat.css index ef21904..1ac2759 100644 --- a/unpackage/dist/dev/app-plus/pages/Chat/Chat.css +++ b/unpackage/dist/dev/app-plus/pages/Chat/Chat.css @@ -1849,6 +1849,149 @@ to { opacity: 1; transform: translateY(0); white-space: pre-wrap; word-break: break-all; } +/* ===== 调试按钮(顶部Header) ===== */ +.debug-top-btn[data-v-5eb7b895] { + flex-shrink: 0; + background: rgba(108, 99, 255, 0.15); +} +.debug-top-btn[data-v-5eb7b895]:active { + background: rgba(108, 99, 255, 0.3); +} +.debug-top-text[data-v-5eb7b895] { + font-size: 0.5625rem; + font-weight: 700; + color: #6c63ff; +} +/* ===== 调试面板(居中弹窗) ===== */ +.debug-overlay[data-v-5eb7b895] { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.5); + z-index: 9999; + display: flex; + align-items: center; + justify-content: center; + padding: 1.25rem; + box-sizing: border-box; +} +.debug-panel[data-v-5eb7b895] { + width: 100%; + max-height: 80vh; + background: #1e1e2e; + border-radius: 0.75rem; + display: flex; + flex-direction: column; + overflow: hidden; +} +.debug-header[data-v-5eb7b895] { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0.875rem 1rem 0.625rem; + border-bottom: 0.03125rem solid rgba(255, 255, 255, 0.08); +} +.debug-title[data-v-5eb7b895] { + font-size: 0.9375rem; + font-weight: 600; + color: #cdd6f4; +} +.debug-actions[data-v-5eb7b895] { + display: flex; + align-items: center; + gap: 0.875rem; +} +.debug-clear-btn[data-v-5eb7b895] { + font-size: 0.75rem; + color: #f38ba8; + padding: 0.1875rem 0.5rem; + border-radius: 0.375rem; + background: rgba(243, 139, 168, 0.12); +} +.debug-close-btn[data-v-5eb7b895] { + font-size: 1rem; + color: #a6adc8; + font-weight: 700; +} +.debug-section[data-v-5eb7b895] { + padding: 0.625rem 0.75rem; + border-bottom: 0.03125rem solid rgba(255, 255, 255, 0.05); +} +.debug-label[data-v-5eb7b895] { + font-size: 0.75rem; + color: #89b4fa; + font-weight: 600; + margin-bottom: 0.375rem; +} +/* 状态网格 */ +.debug-state-grid[data-v-5eb7b895] { + display: flex; + flex-wrap: wrap; + gap: 0.375rem 0.875rem; +} +.debug-state-item[data-v-5eb7b895] { + font-size: 0.75rem; + color: #cdd6f4; +} +.state-key[data-v-5eb7b895] { + color: #a6adc8; +} +.state-val[data-v-5eb7b895] { + color: #cdd6f4; +} +.state-val-ok[data-v-5eb7b895] { + color: #a6e3a1; +} +.state-val-err[data-v-5eb7b895] { + color: #f38ba8; +} +.state-val-warn[data-v-5eb7b895] { + color: #f9e2af; +} +/* 原始消息展示 */ +.debug-raw-box[data-v-5eb7b895] { + max-height: 12.5rem; + background: rgba(0, 0, 0, 0.25); + border-radius: 0.375rem; + padding: 0.5rem; + overflow-y: auto; +} +.debug-json[data-v-5eb7b895] { + font-size: 0.625rem; + color: #bac2de; + font-family: 'Courier New', monospace; + white-space: pre-wrap; + word-break: break-all; + line-height: 1.5; +} +.debug-empty[data-v-5eb7b895] { + font-size: 0.6875rem; + color: #585b70; + font-style: italic; + padding: 0.375rem 0; +} +/* 本轮消息列表项 */ +.debug-round-item[data-v-5eb7b895] { + padding: 0.375rem 0; + border-bottom: 0.03125rem solid rgba(255, 255, 255, 0.04); +} +.debug-round-item[data-v-5eb7b895]:last-child { + border-bottom: none; +} +.debug-round-index[data-v-5eb7b895] { + font-size: 0.6875rem; + color: #f5c2e7; + font-weight: 600; + margin-bottom: 0.1875rem; +} +.debug-round-time[data-v-5eb7b895] { + font-size: 0.625rem; + color: #585b70; + font-weight: 400; + margin-left: 0.375rem; +} /** * 这里是uni-app内置的常用样式变量 * diff --git a/unpackage/dist/dev/app-plus/pages/text/text.css b/unpackage/dist/dev/app-plus/pages/text/text.css index e25df84..0611f21 100644 --- a/unpackage/dist/dev/app-plus/pages/text/text.css +++ b/unpackage/dist/dev/app-plus/pages/text/text.css @@ -1849,6 +1849,149 @@ to { opacity: 1; transform: translateY(0); white-space: pre-wrap; word-break: break-all; } +/* ===== 调试按钮(顶部Header) ===== */ +.debug-top-btn[data-v-fdf84df1] { + flex-shrink: 0; + background: rgba(108, 99, 255, 0.15); +} +.debug-top-btn[data-v-fdf84df1]:active { + background: rgba(108, 99, 255, 0.3); +} +.debug-top-text[data-v-fdf84df1] { + font-size: 0.5625rem; + font-weight: 700; + color: #6c63ff; +} +/* ===== 调试面板(居中弹窗) ===== */ +.debug-overlay[data-v-fdf84df1] { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.5); + z-index: 9999; + display: flex; + align-items: center; + justify-content: center; + padding: 1.25rem; + box-sizing: border-box; +} +.debug-panel[data-v-fdf84df1] { + width: 100%; + max-height: 80vh; + background: #1e1e2e; + border-radius: 0.75rem; + display: flex; + flex-direction: column; + overflow: hidden; +} +.debug-header[data-v-fdf84df1] { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0.875rem 1rem 0.625rem; + border-bottom: 0.03125rem solid rgba(255, 255, 255, 0.08); +} +.debug-title[data-v-fdf84df1] { + font-size: 0.9375rem; + font-weight: 600; + color: #cdd6f4; +} +.debug-actions[data-v-fdf84df1] { + display: flex; + align-items: center; + gap: 0.875rem; +} +.debug-clear-btn[data-v-fdf84df1] { + font-size: 0.75rem; + color: #f38ba8; + padding: 0.1875rem 0.5rem; + border-radius: 0.375rem; + background: rgba(243, 139, 168, 0.12); +} +.debug-close-btn[data-v-fdf84df1] { + font-size: 1rem; + color: #a6adc8; + font-weight: 700; +} +.debug-section[data-v-fdf84df1] { + padding: 0.625rem 0.75rem; + border-bottom: 0.03125rem solid rgba(255, 255, 255, 0.05); +} +.debug-label[data-v-fdf84df1] { + font-size: 0.75rem; + color: #89b4fa; + font-weight: 600; + margin-bottom: 0.375rem; +} +/* 状态网格 */ +.debug-state-grid[data-v-fdf84df1] { + display: flex; + flex-wrap: wrap; + gap: 0.375rem 0.875rem; +} +.debug-state-item[data-v-fdf84df1] { + font-size: 0.75rem; + color: #cdd6f4; +} +.state-key[data-v-fdf84df1] { + color: #a6adc8; +} +.state-val[data-v-fdf84df1] { + color: #cdd6f4; +} +.state-val-ok[data-v-fdf84df1] { + color: #a6e3a1; +} +.state-val-err[data-v-fdf84df1] { + color: #f38ba8; +} +.state-val-warn[data-v-fdf84df1] { + color: #f9e2af; +} +/* 原始消息展示 */ +.debug-raw-box[data-v-fdf84df1] { + max-height: 12.5rem; + background: rgba(0, 0, 0, 0.25); + border-radius: 0.375rem; + padding: 0.5rem; + overflow-y: auto; +} +.debug-json[data-v-fdf84df1] { + font-size: 0.625rem; + color: #bac2de; + font-family: 'Courier New', monospace; + white-space: pre-wrap; + word-break: break-all; + line-height: 1.5; +} +.debug-empty[data-v-fdf84df1] { + font-size: 0.6875rem; + color: #585b70; + font-style: italic; + padding: 0.375rem 0; +} +/* 本轮消息列表项 */ +.debug-round-item[data-v-fdf84df1] { + padding: 0.375rem 0; + border-bottom: 0.03125rem solid rgba(255, 255, 255, 0.04); +} +.debug-round-item[data-v-fdf84df1]:last-child { + border-bottom: none; +} +.debug-round-index[data-v-fdf84df1] { + font-size: 0.6875rem; + color: #f5c2e7; + font-weight: 600; + margin-bottom: 0.1875rem; +} +.debug-round-time[data-v-fdf84df1] { + font-size: 0.625rem; + color: #585b70; + font-weight: 400; + margin-left: 0.375rem; +} /** * 这里是uni-app内置的常用样式变量 *