From a77e22a3ea1f748dbbcae47a7a01d4b6ffc3e7fd Mon Sep 17 00:00:00 2001 From: CrescentLeaf Date: Sat, 4 Oct 2025 15:49:19 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BB=8E=E5=AF=B9=E8=AF=9D=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E6=89=93=E5=BC=80=E7=94=A8=E6=88=B7=E8=AF=A6=E6=83=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/api/ApiDeclare.ts | 3 ++ client/ui/App.tsx | 11 ++++--- client/ui/AppMobile.tsx | 17 ++++++----- client/ui/dialog/ChatInfoDialog.tsx | 22 +++++++++++--- server/api/ApiDeclare.ts | 3 ++ server/api/ChatApi.ts | 47 +++++++++++++++++++++++++++-- 6 files changed, 84 insertions(+), 19 deletions(-) diff --git a/client/api/ApiDeclare.ts b/client/api/ApiDeclare.ts index 7b59b92..761aeb0 100644 --- a/client/api/ApiDeclare.ts +++ b/client/api/ApiDeclare.ts @@ -16,7 +16,10 @@ export type CallMethod = "User.getMyRecentChats" | "Chat.getInfo" | + "Chat.getIdForPrivate" | + "Chat.getAnotherUserIdFromPrivate" | + "Chat.sendMessage" | "Chat.getMessageHistory" | diff --git a/client/ui/App.tsx b/client/ui/App.tsx index d15416d..cd2f7ae 100644 --- a/client/ui/App.tsx +++ b/client/ui/App.tsx @@ -135,6 +135,12 @@ export default function App() { loginInputAccountRef={loginInputAccountRef} loginInputPasswordRef={loginInputPasswordRef} /> + + @@ -143,11 +149,6 @@ export default function App() { openChatFragment={openChatFragment} user={userInfo} /> - - diff --git a/client/ui/AppMobile.tsx b/client/ui/AppMobile.tsx index f7bf11e..bff55d8 100644 --- a/client/ui/AppMobile.tsx +++ b/client/ui/AppMobile.tsx @@ -156,6 +156,15 @@ export default function AppMobile() { loginInputAccountRef={loginInputAccountRef} loginInputPasswordRef={loginInputPasswordRef} /> + { + setCurrentChatId(id) + setIsShowChatFragment(true) + }} + chat={chatInfo} /> + @@ -164,14 +173,6 @@ export default function AppMobile() { openChatFragment={openChatFragment} user={userInfo} /> - { - setCurrentChatId(id) - setIsShowChatFragment(true) - }} - chat={chatInfo} /> - diff --git a/client/ui/dialog/ChatInfoDialog.tsx b/client/ui/dialog/ChatInfoDialog.tsx index e83ae59..f3bdaa9 100644 --- a/client/ui/dialog/ChatInfoDialog.tsx +++ b/client/ui/dialog/ChatInfoDialog.tsx @@ -4,16 +4,18 @@ import useAsyncEffect from "../useAsyncEffect.ts" import Client from "../../api/Client.ts" import data from "../../Data.ts" import { Dialog } from "mdui" -import Avatar from "../Avatar.tsx"; +import Avatar from "../Avatar.tsx" import { checkApiSuccessOrSncakbar } from "../snackbar.ts" +import User from "../../api/client_data/User.ts" interface Args extends React.HTMLAttributes { chat: Chat openChatFragment: (id: string) => void chatInfoDialogRef: React.MutableRefObject + openUserInfoDialog: (user: User | string) => void } -export default function ChatInfoDialog({ chat, chatInfoDialogRef, openChatFragment }: Args) { +export default function ChatInfoDialog({ chat, chatInfoDialogRef, openChatFragment, openUserInfoDialog }: Args) { const [chatInfo, setChatInfo] = React.useState(null as unknown as Chat) const isMySelf = Client.myUserProfile?.id == chatInfo?.user_a_id && Client.myUserProfile?.id == chatInfo?.user_b_id @@ -45,14 +47,26 @@ export default function ChatInfoDialog({ chat, chatInfoDialogRef, openChatFragme + { + chat?.type == 'private' && + { + const re = await Client.invoke("Chat.getAnotherUserIdFromPrivate", { + token: data.access_token, + target: chat.id, + }) + if (re.code != 200) + return checkApiSuccessOrSncakbar(re, '获取用户失败') + + openUserInfoDialog(re.data!.user_id as string) + }}>用户详情 + } { chatInfoDialogRef.current!.open = false openChatFragment(chat.id) - }}>對話 + }}>打开此对话 ) diff --git a/server/api/ApiDeclare.ts b/server/api/ApiDeclare.ts index 2e818fb..a9aba2c 100644 --- a/server/api/ApiDeclare.ts +++ b/server/api/ApiDeclare.ts @@ -16,7 +16,10 @@ export type CallMethod = "User.getMyRecentChats" | "Chat.getInfo" | + "Chat.getIdForPrivate" | + "Chat.getAnotherUserIdFromPrivate" | + "Chat.sendMessage" | "Chat.getMessageHistory" | diff --git a/server/api/ChatApi.ts b/server/api/ChatApi.ts index 6dd3402..980b57a 100644 --- a/server/api/ChatApi.ts +++ b/server/api/ChatApi.ts @@ -197,9 +197,9 @@ export default class ChatApi extends BaseApi { } }) /** - * 獲取對話訊息 + * 获取私聊的 ChatId * @param token 令牌 - * @param target 目標對用户 + * @param target 目標用户 */ this.registerEvent("Chat.getIdForPrivate", (args, { deviceId }) => { if (this.checkArgsMissing(args, ['token', 'target'])) return { @@ -230,5 +230,48 @@ export default class ChatApi extends BaseApi { } } }) + /** + * 从私聊获取对方的 UserId + * @param token 令牌 + * @param target 目標对话 + */ + this.registerEvent("Chat.getAnotherUserIdFromPrivate", (args, { deviceId }) => { + if (this.checkArgsMissing(args, ['token', 'target'])) return { + msg: "參數缺失", + code: 400, + } + + const token = TokenManager.decode(args.token as string) + if (!this.checkToken(token, deviceId)) return { + code: 401, + msg: "令牌無效", + } + + const user = User.findById(token.author) as User + + const chat = Chat.findById(args.target as string) + if (chat == null) return { + code: 404, + msg: "對話不存在", + } + if (!UserChatLinker.checkUserIsLinkedToChat(token.author, chat!.bean.id)) return { + code: 400, + msg: "用戶無權訪問該對話", + } + + if (chat.bean.type == 'private') + return { + code: 200, + msg: '成功', + data: { + user_id: chat.getAnotherUserForPrivate(user)?.bean.id + } + } + + return { + code: 403, + msg: "非私聊对话", + } + }) } } \ No newline at end of file