From 0df114961868d07dabba0a1bea7fd3e3c285d664 Mon Sep 17 00:00:00 2001 From: CrescentLeaf Date: Wed, 8 Oct 2025 02:51:58 +0800 Subject: [PATCH] =?UTF-8?q?FEAT(=E7=81=B5=E8=BD=A6=20WIP):=20CHAT=20SETTIN?= =?UTF-8?q?GS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/api/client_data/GroupSettings.ts | 10 +++++++ server/api/ChatApi.ts | 40 +++++++++++++++++++++++-- server/data/ChatGroup.ts | 33 ++++++++++++++++++++ server/data/GroupSettingsBean.ts | 10 +++++++ 4 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 client/api/client_data/GroupSettings.ts create mode 100644 server/data/GroupSettingsBean.ts diff --git a/client/api/client_data/GroupSettings.ts b/client/api/client_data/GroupSettings.ts new file mode 100644 index 0000000..14a007e --- /dev/null +++ b/client/api/client_data/GroupSettings.ts @@ -0,0 +1,10 @@ +interface GroupSettings { + allow_new_member_join?: boolean + allow_new_member_from_invitation?: boolean + new_member_join_method?: 'disabled' | 'allowed_by_admin' | 'answered_and_allowed_by_admin' + answered_and_allowed_by_admin_question?: string + + [key: string]: unknown +} + +export default GroupSettings diff --git a/server/api/ChatApi.ts b/server/api/ChatApi.ts index c2a1751..8b344a1 100644 --- a/server/api/ChatApi.ts +++ b/server/api/ChatApi.ts @@ -9,6 +9,7 @@ import BaseApi from "./BaseApi.ts" import TokenManager from "./TokenManager.ts" import ChatPrivate from "../data/ChatPrivate.ts" import ChatGroup from "../data/ChatGroup.ts" +import GroupSettingsBean from "../data/GroupSettingsBean.ts" export default class ChatApi extends BaseApi { override getName(): string { @@ -53,7 +54,8 @@ export default class ChatApi extends BaseApi { id: args.target as string, type: chat.bean.type, title: chat.getTitle(mine), - avatar: chat.getAvatarFileHash(mine) ? "uploaded_files/" + chat.getAvatarFileHash(mine) : undefined + avatar: chat.getAvatarFileHash(mine) ? "uploaded_files/" + chat.getAvatarFileHash(mine) : undefined, + settings: JSON.parse(chat.bean.settings), } } } @@ -65,7 +67,8 @@ export default class ChatApi extends BaseApi { id: args.target as string, type: chat.bean.type, title: chat.getTitle(), - avatar: chat.getAvatarFileHash() ? "uploaded_files/" + chat.getAvatarFileHash() : undefined + avatar: chat.getAvatarFileHash() ? "uploaded_files/" + chat.getAvatarFileHash() : undefined, + settings: JSON.parse(chat.bean.settings), } } } @@ -287,6 +290,39 @@ export default class ChatApi extends BaseApi { } } }) + /** + * 更新设定 + * @param token 令牌 + * @param title 名称 + * @param [id] 群组 ID + */ + this.registerEvent("Chat.updateSettings", (args, { deviceId }) => { + if (this.checkArgsMissing(args, ['token', 'target', 'settings'])) 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 (chat.bean.type == 'group') + ChatGroup.fromChat(chat).getSettings().update(args.settings as GroupSettingsBean) + + return { + code: 200, + msg: '成功', + } + }) /** * 从私聊获取对方的 UserId * @param token 令牌 diff --git a/server/data/ChatGroup.ts b/server/data/ChatGroup.ts index e09260b..25cc66b 100644 --- a/server/data/ChatGroup.ts +++ b/server/data/ChatGroup.ts @@ -1,8 +1,41 @@ import chalk from "chalk" import Chat from "./Chat.ts" import User from "./User.ts" +import GroupSettingsBean from "./GroupSettingsBean.ts" + +class GroupSettings { + declare chat: ChatGroup + declare settings: GroupSettingsBean + constructor(chat: ChatGroup) { + this.chat = chat + this.settings = JSON.parse(chat.bean.settings) + } + + update(bean: GroupSettingsBean) { + const updateValue = (key: string) => { + if (key in bean) + this.settings[key] = bean[key] + } + for (const k of [ + 'allow_new_member_join', + 'allow_new_member_from_invitation', + 'new_member_join_method', + 'answered_and_allowed_by_admin_question', + ]) + updateValue(k) + + this.apply() + } + apply() { + this.chat.setAttr('settings', JSON.stringify(this.settings)) + } +} export default class ChatGroup extends Chat { + getSettings() { + return new GroupSettings(this) + } + static fromChat(chat: Chat) { return new ChatGroup(chat.bean) } diff --git a/server/data/GroupSettingsBean.ts b/server/data/GroupSettingsBean.ts new file mode 100644 index 0000000..5bad577 --- /dev/null +++ b/server/data/GroupSettingsBean.ts @@ -0,0 +1,10 @@ +interface GroupSettingsBean { + allow_new_member_join?: boolean + allow_new_member_from_invitation?: boolean + new_member_join_method?: 'disabled' | 'allowed_by_admin' | 'answered_and_allowed_by_admin' + answered_and_allowed_by_admin_question?: string + + [key: string]: unknown +} + +export default GroupSettingsBean