From 34c02b98324068133d6529d0455ef7fff496c34e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E5=8B=A4=E6=B0=91?= Date: Mon, 27 Apr 2026 19:00:54 +0800 Subject: [PATCH] =?UTF-8?q?feat(sample):=20=E6=B7=BB=E5=8A=A0=E7=A4=BA?= =?UTF-8?q?=E4=BE=8B=E5=BA=94=E7=94=A8=E7=9A=84=E6=A0=B8=E5=BF=83=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 集成依赖管理配置文件 libs.versions.toml,统一管理项目依赖版本 - 实现演示 API 接口定义,包含登录、注册、用户管理等 RESTful 端点 - 创建认证仓库 AuthRepository,处理用户会话管理和加密存储 - 开发登录和注册界面,实现用户身份验证流程 - 构建聊天界面 ChatScreen,支持消息收发和历史记录显示 - 实现联系人管理功能,包含好友搜索和添加删除操作 - 添加会话列表界面,展示最近聊天记录和未读消息提示 --- docs/README.md | 4 ++++ scripts/publish-demo-assets.sh | 2 +- src/api/demo.ts | 1 + src/context/AuthContext.tsx | 17 +++++++++++------ .../conversation/ConversationListScreen.tsx | 5 +++-- src/screens/group/GroupMembersScreen.tsx | 3 ++- 6 files changed, 22 insertions(+), 10 deletions(-) diff --git a/docs/README.md b/docs/README.md index 6af8641..242b28b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,6 +16,7 @@ | 配置项 | 值 | |--------|-----| | API 域名 | `https://dev.xuqinmin.com` | +| 登录服务 | `demo-service`(`/api/demo/auth/*`) | | IM WebSocket | `wss://dev.xuqinmin.com/ws/im` | | 演示 AppId | `ak_demo_chat` | | 演示用户 | `demo_alice`(Alice)、`demo_bob`(Bob) | @@ -136,6 +137,7 @@ cd XuqmGroup-RNChatDemo | 路径前缀 | 对应服务 | 端口 | |----------|---------|-----| +| `/api/demo/` | demo-service | 8085 | | `/api/im/` | im-service | 8082 | | `/ws/im` | im-service (WebSocket) | 8082 | | `/api/v1/updates/` | update-service | 8084 | @@ -144,6 +146,8 @@ cd XuqmGroup-RNChatDemo 所有接口通过 Nginx 反代至 `https://dev.xuqinmin.com`。 +`demo-service` 负责 demo 账号体系的注册、登录、找回密码和资料更新;登录成功后会返回 `demoToken`、`imToken` 和 `profile`。其中 `profile.appId` 用于后续初始化 IM 和更新能力,不走租户服务登录链路。 + --- ## 注意事项 diff --git a/scripts/publish-demo-assets.sh b/scripts/publish-demo-assets.sh index d9359df..e39d0b9 100755 --- a/scripts/publish-demo-assets.sh +++ b/scripts/publish-demo-assets.sh @@ -2,7 +2,7 @@ set -euo pipefail -BASE_URL="${BASE_URL:-https://sentry.xuqinmin.com}" +BASE_URL="${BASE_URL:-https://dev.xuqinmin.com}" APP_ID="${APP_ID:-ak_demo_chat}" MODULE_ID="${MODULE_ID:-chat-home}" diff --git a/src/api/demo.ts b/src/api/demo.ts index 50edd4f..f60bf8c 100644 --- a/src/api/demo.ts +++ b/src/api/demo.ts @@ -33,6 +33,7 @@ async function request( } export interface UserProfile { + appId: string userId: string nickname: string avatar: string diff --git a/src/context/AuthContext.tsx b/src/context/AuthContext.tsx index 025be3a..804bacd 100644 --- a/src/context/AuthContext.tsx +++ b/src/context/AuthContext.tsx @@ -8,6 +8,10 @@ import pluginMeta from '../../plugin.json' const APP_ID = 'ak_demo_chat' const SERVER_URL = 'https://dev.xuqinmin.com' +function buildImDbName(appId: string, userId: string): string { + return `xuqm_im_${appId}_${userId}` +} + interface AuthState { ready: boolean userId: string | null @@ -27,10 +31,11 @@ const AuthContext = createContext(null) export function AuthProvider({ children }: { children: React.ReactNode }) { const [state, setState] = useState({ ready: false, userId: null, profile: null }) - const initSDK = useCallback(async (userId: string, imToken: string, profile: UserProfile) => { - await XuqmSDK.initialize({ appId: APP_ID, serverUrl: SERVER_URL }) - await ImSDK.loginWithToken(userId, imToken, 'xuqm_im') - setState({ ready: true, userId, profile }) + const initSDK = useCallback(async (profile: UserProfile, imToken: string) => { + const appId = profile.appId || APP_ID + await XuqmSDK.initialize({ appId, serverUrl: SERVER_URL }) + await ImSDK.loginWithToken(profile.userId, imToken, buildImDbName(appId, profile.userId)) + setState({ ready: true, userId: profile.userId, profile }) UpdateSDK.checkAppUpdate() .then(update => { @@ -57,7 +62,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) { const imToken = await load(K.IM_TOKEN) const profile = await load(K.PROFILE) if (demoToken && imToken && profile) { - await initSDK(profile.userId, imToken, profile) + await initSDK(profile, imToken) return } } catch { @@ -72,7 +77,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) { await save(K.DEMO_TOKEN, result.demoToken) await save(K.IM_TOKEN, result.imToken) await save(K.PROFILE, result.profile) - await initSDK(result.profile.userId, result.imToken, result.profile) + await initSDK(result.profile, result.imToken) }, [initSDK]) const login = useCallback(async (userId: string, password: string) => { diff --git a/src/screens/conversation/ConversationListScreen.tsx b/src/screens/conversation/ConversationListScreen.tsx index 974aafa..4b72a15 100644 --- a/src/screens/conversation/ConversationListScreen.tsx +++ b/src/screens/conversation/ConversationListScreen.tsx @@ -18,6 +18,7 @@ interface ConvWithMeta extends ConversationData { } export default function ConversationListScreen() { + const appId = 'ak_demo_chat' const navigation = useNavigation