diff --git a/client/api/client_data/GroupSettings.ts b/client/api/client_data/GroupSettings.ts index eeac578..dc7ab45 100644 --- a/client/api/client_data/GroupSettings.ts +++ b/client/api/client_data/GroupSettings.ts @@ -6,7 +6,7 @@ interface GroupSettings { // 下面两个比较特殊, 由服务端给予 group_title: string - group_id: string + group_name: string [key: string]: unknown } diff --git a/client/ui/chat/ChatFragment.tsx b/client/ui/chat/ChatFragment.tsx index 63bb649..66fe399 100644 --- a/client/ui/chat/ChatFragment.tsx +++ b/client/ui/chat/ChatFragment.tsx @@ -535,10 +535,11 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC state={groupPreferenceStore.state.group_title || ''} disabled={!chatInfo.is_admin} /> {/* diff --git a/client/ui/dialog/CreateGroupDialog.tsx b/client/ui/dialog/CreateGroupDialog.tsx index ec28771..908ed73 100644 --- a/client/ui/dialog/CreateGroupDialog.tsx +++ b/client/ui/dialog/CreateGroupDialog.tsx @@ -15,13 +15,13 @@ interface Refs { export default function CreateGroupDialog({ createGroupDialogRef, }: Refs) { + const inputGroupTitleRef = React.useRef(null) const inputGroupNameRef = React.useRef(null) - const inputGroupIdRef = React.useRef(null) async function createGroup() { const re = await Client.invoke("Chat.createGroup", { - title: inputGroupNameRef.current!.value, - id: inputGroupIdRef.current!.value, + title: inputGroupTitleRef.current!.value, + name: inputGroupNameRef.current!.value, token: data.access_token, }) @@ -32,18 +32,18 @@ export default function CreateGroupDialog({ }) EventBus.emit('ContactsList.updateContacts') + inputGroupTitleRef.current!.value = '' inputGroupNameRef.current!.value = '' - inputGroupIdRef.current!.value = '' createGroupDialogRef.current!.open = false } return ( - { + { if (event.key == 'Enter') - inputGroupIdRef.current!.click() + inputGroupNameRef.current!.click() }}> - { + { if (event.key == 'Enter') createGroup() }}> diff --git a/server/api/ChatApi.ts b/server/api/ChatApi.ts index 7b830bb..83d330a 100644 --- a/server/api/ChatApi.ts +++ b/server/api/ChatApi.ts @@ -334,7 +334,7 @@ export default class ChatApi extends BaseApi { * 创建群组 * @param token 令牌 * @param title 名称 - * @param [id] 群组 ID + * @param [name] 群组别名 */ this.registerEvent("Chat.createGroup", (args, { deviceId }) => { if (this.checkArgsMissing(args, ['token', 'title'])) return { @@ -353,13 +353,7 @@ export default class ChatApi extends BaseApi { } const user = User.findById(token.author) as User - const haveId = args.id && ((args.id as string) != '') - if (haveId && Chat.findById(args.id as string) != null) return { - msg: "对话 ID 已被占用", - code: 403, - } - - const chat = ChatGroup.createGroup(haveId ? args.id as string : undefined) + const chat = ChatGroup.createGroup(args.name as string) chat.setTitle(args.title as string) chat.addMembers([ user.bean.id, @@ -419,6 +413,7 @@ export default class ChatApi extends BaseApi { msg: "成功", data: { id: args.target as string, + name: chat.bean.name, type: chat.bean.type, title: chat.getTitle(mine), avatar_file_hash: chat.getAvatarFileHash(mine) ? chat.getAvatarFileHash(mine) : undefined, @@ -434,13 +429,14 @@ export default class ChatApi extends BaseApi { msg: "成功", data: { id: args.target as string, + name: chat.bean.name, type: chat.bean.type, title: chat.getTitle(), avatar_file_hash: chat.getAvatarFileHash() ? chat.getAvatarFileHash() : undefined, settings: { ...JSON.parse(chat.bean.settings), // 下面两个比较特殊, 用于群设置 - group_id: chat.bean.id, + group_name: chat.bean.name, group_title: chat.getTitle(), }, is_member: UserChatLinker.checkUserIsLinkedToChat(token.author, chat!.bean.id), @@ -522,8 +518,8 @@ export default class ChatApi extends BaseApi { const settings = args.settings as any if (settings.group_title != null) chat.setTitle(settings.group_title) - if (settings.group_id != null) - chat.setId(settings.group_id) + if (settings.group_name != null) + chat.setName(settings.group_name == '' ? null : settings.group_name) } else return { code: 403, diff --git a/server/api/UserApi.ts b/server/api/UserApi.ts index b276977..33f4735 100644 --- a/server/api/UserApi.ts +++ b/server/api/UserApi.ts @@ -317,7 +317,7 @@ export default class UserApi extends BaseApi { } const user = User.findById(token.author) as User - const chat = Chat.findById(args.target as string) + const chat = Chat.findById(args.target as string) || Chat.findByName(args.target as string) const targetUser = User.findByAccount(args.target as string) as User if (chat) user!.addContact(chat.bean.id) diff --git a/server/data/Chat.ts b/server/data/Chat.ts index addbe69..34e13a6 100644 --- a/server/data/Chat.ts +++ b/server/data/Chat.ts @@ -27,8 +27,9 @@ export default class Chat { /* 序号 */ count INTEGER PRIMARY KEY AUTOINCREMENT, /* 类型 */ type TEXT NOT NULL, /* ID */ id TEXT NOT NULL, + /* 检索 */ name TEXT, /* 标题 */ title TEXT, - /* 头像 */ avatar_file_hash BLOB, + /* 头像 */ avatar_file_hash TEXT, /* 设置 */ settings TEXT NOT NULL ); `) @@ -48,21 +49,32 @@ export default class Chat { return new Chat(beans[0]) } - static create(chatId: string, type: ChatType) { - if (this.findAllChatBeansByCondition('id = ?', chatId).length > 0) - throw new DataWrongError(`对话 ID ${chatId} 已被使用`) + static findByName(name: string) { + const beans = this.findAllChatBeansByCondition('name = ?', name) + if (beans.length == 0) + return null + else if (beans.length > 1) + console.error(chalk.red(`警告: 查询 name = ${name} 时, 查询到多个相同 name 的 Chat`)) + return new Chat(beans[0]) + } + + static create(chatName: string | undefined, type: ChatType) { + if (this.findAllChatBeansByCondition('id = ?', chatName || null).length > 0) + throw new DataWrongError(`对话名称 ${chatName} 已被使用`) const chat = new Chat( Chat.findAllChatBeansByCondition( 'count = ?', Chat.database.prepare(`INSERT INTO Chat ( type, id, + name, title, avatar_file_hash, settings - ) VALUES (?, ?, ?, ?, ?);`).run( + ) VALUES (?, ?, ?, ?, ?, ?);`).run( type, - chatId, + crypto.randomUUID(), + chatName || null, null, null, "{}" @@ -200,11 +212,11 @@ export default class Chat { return null } - setId(id: string) { - if (this.bean.id == id) return - if (Chat.findAllChatBeansByCondition('id = ?', id).length > 0) - throw new DataWrongError(`对话ID ${id} 已被使用`) - this.setAttr("id", id) + setName(name: string) { + if (this.bean.name == name) return + if (name != null && Chat.findAllChatBeansByCondition('name = ?', name).length > 0) + throw new DataWrongError(`对话名称 ${name} 已被使用`) + this.setAttr("name", name) } setTitle(title: string) { if (this.bean.type == 'private') diff --git a/server/data/ChatBean.ts b/server/data/ChatBean.ts index ca1f388..b653a92 100644 --- a/server/data/ChatBean.ts +++ b/server/data/ChatBean.ts @@ -4,6 +4,7 @@ export default class ChatBean { declare count: number declare type: ChatType declare id: string + declare name?: string declare title?: string declare avatar_file_hash?: string declare members_list: string diff --git a/server/data/ChatGroup.ts b/server/data/ChatGroup.ts index 25cc66b..4a02ed9 100644 --- a/server/data/ChatGroup.ts +++ b/server/data/ChatGroup.ts @@ -40,7 +40,7 @@ export default class ChatGroup extends Chat { return new ChatGroup(chat.bean) } - static createGroup(chatId?: string) { - return this.create(chatId || crypto.randomUUID(), 'group') + static createGroup(group_name?: string) { + return this.create(group_name, 'group') } } \ No newline at end of file diff --git a/server/data/ChatPrivate.ts b/server/data/ChatPrivate.ts index 94c2179..c7c44de 100644 --- a/server/data/ChatPrivate.ts +++ b/server/data/ChatPrivate.ts @@ -8,11 +8,12 @@ export default class ChatPrivate extends Chat { } static getChatIdByUsersId(userIdA: string, userIdB: string) { - return [userIdA, userIdB].sort().join('------') + return 'priv_' + [userIdA, userIdB].sort().join('__').replaceAll('-', '_') } static createForPrivate(userA: User, userB: User) { - const chat = this.create(this.getChatIdByUsersId(userA.bean.id, userB.bean.id), 'private') + const chat = this.create(undefined, 'private') + chat.setAttr('id', this.getChatIdByUsersId(userA.bean.id, userB.bean.id)) chat.addMembers([ userA.bean.id, userB.bean.id