From 0fd34a564415a6a33e862bc425230a9984187ef0 Mon Sep 17 00:00:00 2001 From: john Date: Sat, 11 Jul 2026 08:51:30 +0800 Subject: [PATCH] feat(miniapp): improve session navigation and auth guard --- miniapp/pages/chat/index.js | 52 ++++++++++++++++++++++++++++++--- miniapp/pages/chat/index.wxml | 14 +++++++++ miniapp/pages/chat/index.wxss | 51 ++++++++++++++++++++++++++++++++ miniapp/pages/login/index.js | 12 ++++++++ miniapp/pages/sessions/index.js | 19 ++++++++++-- miniapp/pages/space/index.js | 17 +++++++++-- miniapp/utils/config.js | 1 + 7 files changed, 158 insertions(+), 8 deletions(-) diff --git a/miniapp/pages/chat/index.js b/miniapp/pages/chat/index.js index 825d821..c6c0fed 100644 --- a/miniapp/pages/chat/index.js +++ b/miniapp/pages/chat/index.js @@ -2,9 +2,14 @@ const { checkAuth, createAgentRun, getAgentRun, - loadSession + loadSession, + logout } = require('../../utils/api'); -const { AGENT_RUN_MAX_POLLS, AGENT_RUN_POLL_MS } = require('../../utils/config'); +const { + AGENT_RUN_MAX_POLLS, + AGENT_RUN_POLL_MS, + SELECTED_SESSION_KEY +} = require('../../utils/config'); const { createUserMessage, normalizeMessages } = require('../../utils/messages'); function delay(ms) { @@ -17,6 +22,7 @@ Page({ messages: [], draft: '', loading: false, + error: '', scrollIntoView: '' }, @@ -25,6 +31,14 @@ Page({ const status = await checkAuth(); if (!status?.authenticated) { wx.redirectTo({ url: '/pages/login/index' }); + return; + } + const selectedSessionId = wx.getStorageSync(SELECTED_SESSION_KEY); + if (selectedSessionId) { + wx.removeStorageSync(SELECTED_SESSION_KEY); + if (selectedSessionId !== this.data.sessionId) { + await this.openSession(selectedSessionId); + } } } catch { wx.redirectTo({ url: '/pages/login/index' }); @@ -49,7 +63,7 @@ Page({ ...this.data.messages, { id: userMessage.id, role: 'user', text } ]; - this.setData({ messages: nextMessages, draft: '', loading: true }); + this.setData({ messages: nextMessages, draft: '', loading: true, error: '' }); this.scrollToBottom(); try { @@ -61,6 +75,7 @@ Page({ const run = await createAgentRun(payload); await this.waitForRun(run?.id || run?.runId); } catch (error) { + this.setData({ error: error?.message || '发送失败' }); wx.showToast({ title: error?.message || '发送失败', icon: 'none' }); } finally { this.setData({ loading: false }); @@ -92,6 +107,35 @@ Page({ async refreshSession(sessionId) { const detail = await loadSession(sessionId); const messages = normalizeMessages(detail?.messages || detail?.data?.messages || []); - this.setData({ messages }); + this.setData({ sessionId, messages, error: '' }); + }, + + async openSession(sessionId) { + this.setData({ loading: true, error: '' }); + try { + await this.refreshSession(sessionId); + } catch (error) { + this.setData({ error: error?.message || '会话加载失败' }); + } finally { + this.setData({ loading: false }); + this.scrollToBottom(); + } + }, + + startNewChat() { + wx.removeStorageSync(SELECTED_SESSION_KEY); + this.setData({ sessionId: '', messages: [], draft: '', error: '' }); + }, + + async handleLogout() { + this.setData({ loading: true, error: '' }); + try { + await logout(); + wx.redirectTo({ url: '/pages/login/index' }); + } catch (error) { + this.setData({ error: error?.message || '退出失败' }); + } finally { + this.setData({ loading: false }); + } } }); diff --git a/miniapp/pages/chat/index.wxml b/miniapp/pages/chat/index.wxml index db88ba3..f40fd7b 100644 --- a/miniapp/pages/chat/index.wxml +++ b/miniapp/pages/chat/index.wxml @@ -1,5 +1,19 @@ + + + {{sessionId ? '继续会话' : '新会话'}} + {{error}} + + + + + + + + + 发一条消息开始使用 TKMind。 + {{item.text}} diff --git a/miniapp/pages/chat/index.wxss b/miniapp/pages/chat/index.wxss index baa3513..3e12b05 100644 --- a/miniapp/pages/chat/index.wxss +++ b/miniapp/pages/chat/index.wxss @@ -5,12 +5,63 @@ padding: 0; } +.chat-header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 16rpx; + padding: 20rpx 24rpx; + background: #ffffff; + border-bottom: 1rpx solid #dbe3eb; +} + +.chat-title { + display: flex; + flex-direction: column; + gap: 4rpx; + min-width: 0; + font-size: 30rpx; + font-weight: 800; +} + +.header-error { + max-width: 420rpx; + color: #b42318; + font-size: 22rpx; + font-weight: 500; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.header-actions { + display: flex; + gap: 12rpx; +} + +.header-button { + width: 112rpx; + height: 58rpx; + line-height: 58rpx; + border-radius: 10rpx; + background: #eef6f5; + color: #0f766e; + font-size: 24rpx; +} + .messages { flex: 1; box-sizing: border-box; padding: 28rpx; } +.empty-state { + margin: 160rpx auto 0; + color: #64748b; + font-size: 28rpx; + text-align: center; +} + .message { max-width: 84%; margin-bottom: 20rpx; diff --git a/miniapp/pages/login/index.js b/miniapp/pages/login/index.js index 48dbb42..76d7c01 100644 --- a/miniapp/pages/login/index.js +++ b/miniapp/pages/login/index.js @@ -1,4 +1,5 @@ const { + checkAuth, loginWithPassword, loginWithWechatCode } = require('../../utils/api'); @@ -13,6 +14,17 @@ Page({ passwordLoading: false }, + async onLoad() { + try { + const status = await checkAuth(); + if (status?.authenticated) { + wx.switchTab({ url: '/pages/chat/index' }); + } + } catch { + // Stay on the login page when the existing session cannot be verified. + } + }, + handleUsername(event) { this.setData({ username: event.detail.value, error: '' }); }, diff --git a/miniapp/pages/sessions/index.js b/miniapp/pages/sessions/index.js index aff2b27..f498ad8 100644 --- a/miniapp/pages/sessions/index.js +++ b/miniapp/pages/sessions/index.js @@ -1,4 +1,5 @@ -const { listSessions } = require('../../utils/api'); +const { checkAuth, listSessions } = require('../../utils/api'); +const { SELECTED_SESSION_KEY } = require('../../utils/config'); function formatTime(value) { const timestamp = Number(value || 0); @@ -15,7 +16,20 @@ Page({ }, onShow() { - this.loadSessions(); + this.ensureAndLoad(); + }, + + async ensureAndLoad() { + try { + const status = await checkAuth(); + if (!status?.authenticated) { + wx.redirectTo({ url: '/pages/login/index' }); + return; + } + await this.loadSessions(); + } catch { + wx.redirectTo({ url: '/pages/login/index' }); + } }, async loadSessions() { @@ -40,6 +54,7 @@ Page({ openSession(event) { const id = event.currentTarget.dataset.id; if (!id) return; + wx.setStorageSync(SELECTED_SESSION_KEY, id); wx.switchTab({ url: '/pages/chat/index' }); } }); diff --git a/miniapp/pages/space/index.js b/miniapp/pages/space/index.js index 1eb66b4..bc70dfd 100644 --- a/miniapp/pages/space/index.js +++ b/miniapp/pages/space/index.js @@ -1,4 +1,4 @@ -const { listMindSpacePages } = require('../../utils/api'); +const { checkAuth, listMindSpacePages } = require('../../utils/api'); Page({ data: { @@ -8,7 +8,20 @@ Page({ }, onShow() { - this.loadPages(); + this.ensureAndLoad(); + }, + + async ensureAndLoad() { + try { + const status = await checkAuth(); + if (!status?.authenticated) { + wx.redirectTo({ url: '/pages/login/index' }); + return; + } + await this.loadPages(); + } catch { + wx.redirectTo({ url: '/pages/login/index' }); + } }, async loadPages() { diff --git a/miniapp/utils/config.js b/miniapp/utils/config.js index 6e9a6f9..061f535 100644 --- a/miniapp/utils/config.js +++ b/miniapp/utils/config.js @@ -1,6 +1,7 @@ module.exports = { API_BASE_URL: 'https://h5.tkmind.cn', MINIAPP_LOGIN_PATH: '/auth/wechat-miniapp/login', + SELECTED_SESSION_KEY: 'tkmind_selected_session_id', AGENT_RUN_POLL_MS: 1200, AGENT_RUN_MAX_POLLS: 120 };