mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-05-13 01:30:57 +08:00
feat: member表支持角色
This commit is contained in:
@@ -84,7 +84,8 @@ function createDatabase(sessionId: string): Database.Database {
|
||||
account_name TEXT,
|
||||
group_nickname TEXT,
|
||||
aliases TEXT DEFAULT '[]',
|
||||
avatar TEXT
|
||||
avatar TEXT,
|
||||
roles TEXT DEFAULT '[]'
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS member_name_history (
|
||||
@@ -174,7 +175,7 @@ export function importData(parseResult: ParseResult): string {
|
||||
)
|
||||
|
||||
const insertMember = db.prepare(`
|
||||
INSERT OR IGNORE INTO member (platform_id, account_name, group_nickname, avatar) VALUES (?, ?, ?, ?)
|
||||
INSERT OR IGNORE INTO member (platform_id, account_name, group_nickname, avatar, roles) VALUES (?, ?, ?, ?, ?)
|
||||
`)
|
||||
const getMemberId = db.prepare(`
|
||||
SELECT id FROM member WHERE platform_id = ?
|
||||
@@ -187,7 +188,8 @@ export function importData(parseResult: ParseResult): string {
|
||||
member.platformId,
|
||||
member.accountName || null,
|
||||
member.groupNickname || null,
|
||||
member.avatar || null
|
||||
member.avatar || null,
|
||||
member.roles ? JSON.stringify(member.roles) : '[]'
|
||||
)
|
||||
const row = getMemberId.get(member.platformId) as { id: number }
|
||||
memberIdMap.set(member.platformId, row.id)
|
||||
|
||||
@@ -34,7 +34,7 @@ export interface MigrationInfo {
|
||||
}
|
||||
|
||||
/** 当前 schema 版本(最新迁移的版本号) */
|
||||
export const CURRENT_SCHEMA_VERSION = 1
|
||||
export const CURRENT_SCHEMA_VERSION = 2
|
||||
|
||||
/**
|
||||
* 迁移脚本列表
|
||||
@@ -54,15 +54,19 @@ const migrations: Migration[] = [
|
||||
}
|
||||
},
|
||||
},
|
||||
// 未来的迁移示例:
|
||||
// {
|
||||
// version: 2,
|
||||
// description: '添加 xxx 字段',
|
||||
// userMessage: '新功能说明',
|
||||
// up: (db) => {
|
||||
// db.exec('ALTER TABLE xxx ADD COLUMN yyy TEXT')
|
||||
// },
|
||||
// },
|
||||
{
|
||||
version: 2,
|
||||
description: '添加 roles 字段到 member 表',
|
||||
userMessage: '支持成员角色(群主、管理员等)',
|
||||
up: (db) => {
|
||||
// 检查 roles 列是否已存在(防止重复执行)
|
||||
const tableInfo = db.prepare('PRAGMA table_info(member)').all() as Array<{ name: string }>
|
||||
const hasRolesColumn = tableInfo.some((col) => col.name === 'roles')
|
||||
if (!hasRolesColumn) {
|
||||
db.exec("ALTER TABLE member ADD COLUMN roles TEXT DEFAULT '[]'")
|
||||
}
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
/**
|
||||
|
||||
@@ -73,6 +73,7 @@ interface ChatLabMember {
|
||||
groupNickname?: string // 群昵称
|
||||
aliases?: string[]
|
||||
avatar?: string // 头像(base64 Data URL)
|
||||
roles?: Array<{ id: string; name?: string }> // 成员角色
|
||||
}
|
||||
|
||||
// ==================== 解析器实现 ====================
|
||||
@@ -159,6 +160,7 @@ async function* parseChatLab(options: ParseOptions): AsyncGenerator<ParseEvent,
|
||||
accountName: m.accountName,
|
||||
groupNickname: m.groupNickname,
|
||||
avatar: m.avatar,
|
||||
roles: m.roles,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ function createDatabaseWithoutIndexes(sessionId: string): Database.Database {
|
||||
group_id TEXT,
|
||||
group_avatar TEXT,
|
||||
owner_id TEXT,
|
||||
schema_version INTEGER DEFAULT 1
|
||||
schema_version INTEGER DEFAULT 2
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS member (
|
||||
@@ -159,7 +159,8 @@ function createDatabaseWithoutIndexes(sessionId: string): Database.Database {
|
||||
account_name TEXT,
|
||||
group_nickname TEXT,
|
||||
aliases TEXT DEFAULT '[]',
|
||||
avatar TEXT
|
||||
avatar TEXT,
|
||||
roles TEXT DEFAULT '[]'
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS member_name_history (
|
||||
@@ -263,7 +264,7 @@ export async function streamImport(filePath: string, requestId: string): Promise
|
||||
INSERT INTO meta (name, platform, type, imported_at, group_id, group_avatar, owner_id) VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
`)
|
||||
const insertMember = db.prepare(`
|
||||
INSERT OR IGNORE INTO member (platform_id, account_name, group_nickname, avatar) VALUES (?, ?, ?, ?)
|
||||
INSERT OR IGNORE INTO member (platform_id, account_name, group_nickname, avatar, roles) VALUES (?, ?, ?, ?, ?)
|
||||
`)
|
||||
const getMemberId = db.prepare(`SELECT id FROM member WHERE platform_id = ?`)
|
||||
const insertMessage = db.prepare(`
|
||||
@@ -400,7 +401,8 @@ export async function streamImport(filePath: string, requestId: string): Promise
|
||||
member.platformId,
|
||||
member.accountName || null,
|
||||
member.groupNickname || null,
|
||||
member.avatar || null
|
||||
member.avatar || null,
|
||||
member.roles ? JSON.stringify(member.roles) : '[]'
|
||||
)
|
||||
const row = getMemberId.get(member.platformId) as { id: number } | undefined
|
||||
if (row) {
|
||||
@@ -434,8 +436,8 @@ export async function streamImport(filePath: string, requestId: string): Promise
|
||||
// 确保成员存在
|
||||
let t0 = Date.now()
|
||||
if (!memberIdMap.has(msg.senderPlatformId)) {
|
||||
// 消息中没有头像信息,设为 null
|
||||
insertMember.run(msg.senderPlatformId, msg.senderAccountName || null, msg.senderGroupNickname || null, null)
|
||||
// 消息中没有头像和角色信息,设为默认值
|
||||
insertMember.run(msg.senderPlatformId, msg.senderAccountName || null, msg.senderGroupNickname || null, null, '[]')
|
||||
const row = getMemberId.get(msg.senderPlatformId) as { id: number } | undefined
|
||||
if (row) {
|
||||
memberIdMap.set(msg.senderPlatformId, row.id)
|
||||
|
||||
@@ -106,6 +106,29 @@ export enum ChatType {
|
||||
PRIVATE = 'private', // 私聊
|
||||
}
|
||||
|
||||
// ==================== 成员角色 ====================
|
||||
|
||||
/**
|
||||
* 成员角色
|
||||
* 一个成员可以有多个角色(如 Discord 的多角色系统)
|
||||
*/
|
||||
export interface MemberRole {
|
||||
/** 角色标识:标准角色使用 "owner" | "admin",自定义角色使用任意字符串 */
|
||||
id: string
|
||||
/** 角色显示名称(自定义角色需要,标准角色可省略) */
|
||||
name?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 标准角色 ID
|
||||
*/
|
||||
export const STANDARD_ROLE_IDS = {
|
||||
/** 群主/创建者 */
|
||||
OWNER: 'owner',
|
||||
/** 管理员 */
|
||||
ADMIN: 'admin',
|
||||
} as const
|
||||
|
||||
// ==================== 数据库模型 ====================
|
||||
|
||||
/**
|
||||
@@ -131,6 +154,7 @@ export interface DbMember {
|
||||
group_nickname: string | null // 群昵称(sendMemberName,可为空)
|
||||
aliases: string // 用户自定义别名(JSON数组格式)
|
||||
avatar: string | null // 头像(base64 Data URL)
|
||||
roles: string // 成员角色(JSON数组格式,如 '[{"id":"owner"}]')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,6 +180,7 @@ export interface ParsedMember {
|
||||
accountName: string // 账号名称(QQ原始昵称 sendNickName)
|
||||
groupNickname?: string // 群昵称(sendMemberName,可为空)
|
||||
avatar?: string // 头像(base64 Data URL,可为空)
|
||||
roles?: MemberRole[] // 成员角色(可为空)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-1
@@ -3,7 +3,7 @@
|
||||
* 包含:ChatLab 专属格式、合并相关、聊天记录查看器
|
||||
*/
|
||||
|
||||
import type { ChatPlatform, ChatType, MessageType } from './base'
|
||||
import type { ChatPlatform, ChatType, MessageType, MemberRole } from './base'
|
||||
|
||||
// ==================== ChatLab 专属格式类型 ====================
|
||||
|
||||
@@ -48,6 +48,7 @@ export interface ChatLabMember {
|
||||
groupNickname?: string // 群昵称(可选)
|
||||
aliases?: string[] // 用户自定义别名(可选)
|
||||
avatar?: string // 头像(base64 Data URL,可选)
|
||||
roles?: MemberRole[] // 成员角色(可选,可多个)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user