mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-04-23 01:39:37 +08:00
feat: 支持头像导入
This commit is contained in:
@@ -69,6 +69,7 @@ export function getMemberActivity(sessionId: string, filter?: TimeFilter): any[]
|
||||
m.id as memberId,
|
||||
m.platform_id as platformId,
|
||||
COALESCE(m.group_nickname, m.account_name, m.platform_id) as name,
|
||||
m.avatar as avatar,
|
||||
COUNT(msg.id) as messageCount
|
||||
FROM member m
|
||||
LEFT JOIN message msg ON m.id = msg.sender_id ${msgFilterWithSystem}
|
||||
@@ -82,6 +83,7 @@ export function getMemberActivity(sessionId: string, filter?: TimeFilter): any[]
|
||||
memberId: number
|
||||
platformId: string
|
||||
name: string
|
||||
avatar: string | null
|
||||
messageCount: number
|
||||
}>
|
||||
|
||||
@@ -89,6 +91,7 @@ export function getMemberActivity(sessionId: string, filter?: TimeFilter): any[]
|
||||
memberId: row.memberId,
|
||||
platformId: row.platformId,
|
||||
name: row.name,
|
||||
avatar: row.avatar,
|
||||
messageCount: row.messageCount,
|
||||
percentage: totalMessages > 0 ? Math.round((row.messageCount / totalMessages) * 10000) / 100 : 0,
|
||||
}))
|
||||
@@ -313,6 +316,8 @@ interface DbMeta {
|
||||
platform: string
|
||||
type: string
|
||||
imported_at: number
|
||||
group_id: string | null
|
||||
group_avatar: string | null
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -367,6 +372,8 @@ export function getAllSessions(): any[] {
|
||||
messageCount,
|
||||
memberCount,
|
||||
dbPath,
|
||||
groupId: meta.group_id || null,
|
||||
groupAvatar: meta.group_avatar || null,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -419,6 +426,8 @@ export function getSession(sessionId: string): any | null {
|
||||
messageCount,
|
||||
memberCount,
|
||||
dbPath: getDbPath(sessionId),
|
||||
groupId: meta.group_id || null,
|
||||
groupAvatar: meta.group_avatar || null,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,10 +443,13 @@ interface MemberWithStats {
|
||||
groupNickname: string | null
|
||||
aliases: string[]
|
||||
messageCount: number
|
||||
avatar: string | null
|
||||
}
|
||||
|
||||
// 用于标记已检查过 aliases 字段的会话
|
||||
const aliasesCheckedSessions = new Set<string>()
|
||||
// 用于标记已检查过 avatar 字段的会话
|
||||
const avatarCheckedSessions = new Set<string>()
|
||||
|
||||
/**
|
||||
* 确保 member 表有 aliases 字段(数据库迁移)
|
||||
@@ -476,11 +488,48 @@ function ensureAliasesColumn(sessionId: string): void {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有成员列表(含消息数和别名)
|
||||
* 确保 member 表有 avatar 字段(数据库迁移)
|
||||
* 用于兼容旧数据库
|
||||
*/
|
||||
export function ensureAvatarColumn(sessionId: string): void {
|
||||
// 每个会话只检查一次
|
||||
if (avatarCheckedSessions.has(sessionId)) return
|
||||
|
||||
const dbPath = getDbPath(sessionId)
|
||||
if (!fs.existsSync(dbPath)) return
|
||||
|
||||
// 先关闭可能缓存的只读连接
|
||||
closeDatabase(sessionId)
|
||||
|
||||
// 使用写入模式打开数据库检查并添加字段
|
||||
const db = new Database(dbPath)
|
||||
db.pragma('journal_mode = WAL')
|
||||
|
||||
try {
|
||||
// 检查 avatar 字段是否存在
|
||||
const columns = db.prepare('PRAGMA table_info(member)').all() as Array<{ name: string }>
|
||||
const hasAvatar = columns.some((col) => col.name === 'avatar')
|
||||
|
||||
if (!hasAvatar) {
|
||||
// 添加 avatar 字段
|
||||
db.exec('ALTER TABLE member ADD COLUMN avatar TEXT')
|
||||
console.log(`[Worker] Added avatar column to member table in session ${sessionId}`)
|
||||
}
|
||||
|
||||
// 标记为已检查
|
||||
avatarCheckedSessions.add(sessionId)
|
||||
} finally {
|
||||
db.close()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有成员列表(含消息数、别名和头像)
|
||||
*/
|
||||
export function getMembers(sessionId: string): MemberWithStats[] {
|
||||
// 先确保数据库有 aliases 字段(兼容旧数据库)
|
||||
// 先确保数据库有 aliases 和 avatar 字段(兼容旧数据库)
|
||||
ensureAliasesColumn(sessionId)
|
||||
ensureAvatarColumn(sessionId)
|
||||
|
||||
const db = openDatabase(sessionId)
|
||||
if (!db) return []
|
||||
@@ -494,6 +543,7 @@ export function getMembers(sessionId: string): MemberWithStats[] {
|
||||
m.account_name as accountName,
|
||||
m.group_nickname as groupNickname,
|
||||
m.aliases,
|
||||
m.avatar,
|
||||
COUNT(msg.id) as messageCount
|
||||
FROM member m
|
||||
LEFT JOIN message msg ON m.id = msg.sender_id
|
||||
@@ -508,6 +558,7 @@ export function getMembers(sessionId: string): MemberWithStats[] {
|
||||
accountName: string | null
|
||||
groupNickname: string | null
|
||||
aliases: string | null
|
||||
avatar: string | null
|
||||
messageCount: number
|
||||
}>
|
||||
|
||||
@@ -518,6 +569,7 @@ export function getMembers(sessionId: string): MemberWithStats[] {
|
||||
groupNickname: row.groupNickname,
|
||||
aliases: row.aliases ? JSON.parse(row.aliases) : [],
|
||||
messageCount: row.messageCount,
|
||||
avatar: row.avatar,
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
import { openDatabase, buildTimeFilter, type TimeFilter } from '../core'
|
||||
import { ensureAvatarColumn } from './basic'
|
||||
|
||||
// ==================== 类型定义 ====================
|
||||
|
||||
@@ -16,6 +17,7 @@ export interface MessageResult {
|
||||
senderName: string
|
||||
senderPlatformId: string
|
||||
senderAliases: string[]
|
||||
senderAvatar: string | null
|
||||
content: string
|
||||
timestamp: number
|
||||
type: number
|
||||
@@ -40,13 +42,14 @@ export interface MessagesWithTotal {
|
||||
// ==================== 工具函数 ====================
|
||||
|
||||
/**
|
||||
* 数据库行类型(包含 aliases JSON 字符串)
|
||||
* 数据库行类型(包含 aliases JSON 字符串和头像)
|
||||
*/
|
||||
interface DbMessageRow {
|
||||
id: number
|
||||
senderName: string
|
||||
senderPlatformId: string
|
||||
aliases: string | null
|
||||
avatar: string | null
|
||||
content: string
|
||||
timestamp: number
|
||||
type: number
|
||||
@@ -72,6 +75,7 @@ function sanitizeMessageRow(row: DbMessageRow): MessageResult {
|
||||
senderName: String(row.senderName || ''),
|
||||
senderPlatformId: String(row.senderPlatformId || ''),
|
||||
senderAliases: aliases,
|
||||
senderAvatar: row.avatar || null,
|
||||
content: row.content != null ? String(row.content) : '',
|
||||
timestamp: Number(row.timestamp),
|
||||
type: Number(row.type),
|
||||
@@ -119,6 +123,9 @@ export function getRecentMessages(
|
||||
filter?: TimeFilter,
|
||||
limit: number = 100
|
||||
): MessagesWithTotal {
|
||||
// 确保数据库有 avatar 字段(兼容旧数据库)
|
||||
ensureAvatarColumn(sessionId)
|
||||
|
||||
const db = openDatabase(sessionId)
|
||||
if (!db) return { messages: [], total: 0 }
|
||||
|
||||
@@ -146,6 +153,7 @@ export function getRecentMessages(
|
||||
COALESCE(m.group_nickname, m.account_name, m.platform_id) as senderName,
|
||||
m.platform_id as senderPlatformId,
|
||||
m.aliases,
|
||||
m.avatar,
|
||||
msg.content,
|
||||
msg.ts as timestamp,
|
||||
msg.type
|
||||
@@ -185,6 +193,9 @@ export function searchMessages(
|
||||
offset: number = 0,
|
||||
senderId?: number
|
||||
): MessagesWithTotal {
|
||||
// 确保数据库有 avatar 字段(兼容旧数据库)
|
||||
ensureAvatarColumn(sessionId)
|
||||
|
||||
const db = openDatabase(sessionId)
|
||||
if (!db) return { messages: [], total: 0 }
|
||||
|
||||
@@ -223,6 +234,7 @@ export function searchMessages(
|
||||
COALESCE(m.group_nickname, m.account_name, m.platform_id) as senderName,
|
||||
m.platform_id as senderPlatformId,
|
||||
m.aliases,
|
||||
m.avatar,
|
||||
msg.content,
|
||||
msg.ts as timestamp,
|
||||
msg.type
|
||||
@@ -257,6 +269,9 @@ export function getMessageContext(
|
||||
messageIds: number | number[],
|
||||
contextSize: number = 20
|
||||
): MessageResult[] {
|
||||
// 确保数据库有 avatar 字段(兼容旧数据库)
|
||||
ensureAvatarColumn(sessionId)
|
||||
|
||||
const db = openDatabase(sessionId)
|
||||
if (!db) return []
|
||||
|
||||
@@ -305,6 +320,7 @@ export function getMessageContext(
|
||||
COALESCE(m.group_nickname, m.account_name, m.platform_id) as senderName,
|
||||
m.platform_id as senderPlatformId,
|
||||
m.aliases,
|
||||
m.avatar,
|
||||
msg.content,
|
||||
msg.ts as timestamp,
|
||||
msg.type
|
||||
@@ -336,6 +352,9 @@ export function getMessagesBefore(
|
||||
senderId?: number,
|
||||
keywords?: string[]
|
||||
): PaginatedMessages {
|
||||
// 确保数据库有 avatar 字段(兼容旧数据库)
|
||||
ensureAvatarColumn(sessionId)
|
||||
|
||||
const db = openDatabase(sessionId)
|
||||
if (!db) return { messages: [], hasMore: false }
|
||||
|
||||
@@ -355,6 +374,7 @@ export function getMessagesBefore(
|
||||
COALESCE(m.group_nickname, m.account_name, m.platform_id) as senderName,
|
||||
m.platform_id as senderPlatformId,
|
||||
m.aliases,
|
||||
m.avatar,
|
||||
msg.content,
|
||||
msg.ts as timestamp,
|
||||
msg.type
|
||||
@@ -398,6 +418,9 @@ export function getMessagesAfter(
|
||||
senderId?: number,
|
||||
keywords?: string[]
|
||||
): PaginatedMessages {
|
||||
// 确保数据库有 avatar 字段(兼容旧数据库)
|
||||
ensureAvatarColumn(sessionId)
|
||||
|
||||
const db = openDatabase(sessionId)
|
||||
if (!db) return { messages: [], hasMore: false }
|
||||
|
||||
@@ -417,6 +440,7 @@ export function getMessagesAfter(
|
||||
COALESCE(m.group_nickname, m.account_name, m.platform_id) as senderName,
|
||||
m.platform_id as senderPlatformId,
|
||||
m.aliases,
|
||||
m.avatar,
|
||||
msg.content,
|
||||
msg.ts as timestamp,
|
||||
msg.type
|
||||
@@ -458,6 +482,9 @@ export function getConversationBetween(
|
||||
filter?: TimeFilter,
|
||||
limit: number = 100
|
||||
): MessagesWithTotal & { member1Name: string; member2Name: string } {
|
||||
// 确保数据库有 avatar 字段(兼容旧数据库)
|
||||
ensureAvatarColumn(sessionId)
|
||||
|
||||
const db = openDatabase(sessionId)
|
||||
if (!db) return { messages: [], total: 0, member1Name: '', member2Name: '' }
|
||||
|
||||
@@ -499,6 +526,7 @@ export function getConversationBetween(
|
||||
COALESCE(m.group_nickname, m.account_name, m.platform_id) as senderName,
|
||||
m.platform_id as senderPlatformId,
|
||||
m.aliases,
|
||||
m.avatar,
|
||||
msg.content,
|
||||
msg.ts as timestamp,
|
||||
msg.type
|
||||
|
||||
Reference in New Issue
Block a user