mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-04-04 15:08:14 +00:00
Merge branch 'dev' of https://github.com/hicccc77/WeFlow into dev
This commit is contained in:
@@ -87,11 +87,14 @@ export class BizService {
|
||||
|
||||
async listAccounts(account?: string): Promise<BizAccount[]> {
|
||||
try {
|
||||
// 1. 获取公众号联系人列表
|
||||
const contactsResult = await chatService.getContacts({ lite: true })
|
||||
if (!contactsResult.success || !contactsResult.contacts) return []
|
||||
|
||||
const officialContacts = contactsResult.contacts.filter(c => c.type === 'official')
|
||||
const usernames = officialContacts.map(c => c.username)
|
||||
|
||||
// 获取头像和昵称等补充信息
|
||||
const enrichment = await chatService.enrichSessionsContactInfo(usernames)
|
||||
const contactInfoMap = enrichment.success && enrichment.contacts ? enrichment.contacts : {}
|
||||
|
||||
@@ -100,31 +103,45 @@ export class BizService {
|
||||
const accountWxid = account || myWxid
|
||||
if (!root || !accountWxid) return []
|
||||
|
||||
const dbDir = join(root, accountWxid, 'db_storage', 'message')
|
||||
const bizLatestTime: Record<string, number> = {}
|
||||
|
||||
if (existsSync(dbDir)) {
|
||||
const bizDbFiles = readdirSync(dbDir).filter(f => f.startsWith('biz_message') && f.endsWith('.db'))
|
||||
for (const file of bizDbFiles) {
|
||||
const dbPath = join(dbDir, file)
|
||||
const name2idRes = await wcdbService.execQuery('message', dbPath, 'SELECT username FROM Name2Id')
|
||||
if (name2idRes.success && name2idRes.rows) {
|
||||
for (const row of name2idRes.rows) {
|
||||
const uname = row.username || row.user_name
|
||||
if (uname) {
|
||||
const md5 = createHash('md5').update(uname).digest('hex').toLowerCase()
|
||||
const tName = `Msg_${md5}`
|
||||
const timeRes = await wcdbService.execQuery('message', dbPath, `SELECT MAX(create_time) as max_time FROM ${tName}`)
|
||||
if (timeRes.success && timeRes.rows && timeRes.rows[0]?.max_time) {
|
||||
const t = parseInt(timeRes.rows[0].max_time)
|
||||
if (!isNaN(t)) bizLatestTime[uname] = Math.max(bizLatestTime[uname] || 0, t)
|
||||
}
|
||||
}
|
||||
try {
|
||||
const sessionsRes = await wcdbService.getSessions()
|
||||
if (sessionsRes.success && sessionsRes.sessions) {
|
||||
for (const session of sessionsRes.sessions) {
|
||||
const uname = session.username || session.strUsrName || session.userName || session.id
|
||||
// 适配日志中发现的字段,注意转为整型数字
|
||||
const timeStr = session.last_timestamp || session.sort_timestamp || session.nTime || session.timestamp || '0'
|
||||
const time = parseInt(timeStr.toString(), 10)
|
||||
|
||||
if (usernames.includes(uname) && time > 0) {
|
||||
bizLatestTime[uname] = time
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取 Sessions 失败:', e)
|
||||
}
|
||||
|
||||
// 3. 格式化时间显示
|
||||
const formatBizTime = (ts: number) => {
|
||||
if (!ts) return ''
|
||||
const date = new Date(ts * 1000)
|
||||
const now = new Date()
|
||||
const isToday = date.toDateString() === now.toDateString()
|
||||
if (isToday) return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', hour12: false })
|
||||
|
||||
const yesterday = new Date(now)
|
||||
yesterday.setDate(now.getDate() - 1)
|
||||
if (date.toDateString() === yesterday.toDateString()) return '昨天'
|
||||
|
||||
const isThisYear = date.getFullYear() === now.getFullYear()
|
||||
if (isThisYear) return `${date.getMonth() + 1}/${date.getDate()}`
|
||||
|
||||
return `${date.getFullYear().toString().slice(-2)}/${date.getMonth() + 1}/${date.getDate()}`
|
||||
}
|
||||
|
||||
// 4. 组装数据
|
||||
const result: BizAccount[] = officialContacts.map(contact => {
|
||||
const uname = contact.username
|
||||
const info = contactInfoMap[uname]
|
||||
@@ -135,11 +152,12 @@ export class BizService {
|
||||
avatar: info?.avatarUrl || '',
|
||||
type: 0,
|
||||
last_time: lastTime,
|
||||
formatted_last_time: lastTime ? new Date(lastTime * 1000).toISOString().split('T')[0] : ''
|
||||
formatted_last_time: formatBizTime(lastTime)
|
||||
}
|
||||
})
|
||||
|
||||
const contactDbPath = join(root, accountWxid, 'contact.db')
|
||||
// 5. 补充公众号类型 (订阅号/服务号)
|
||||
const contactDbPath = join(root, accountWxid, 'db_storage', 'contact', 'contact.db')
|
||||
if (existsSync(contactDbPath)) {
|
||||
const bizInfoRes = await wcdbService.execQuery('contact', contactDbPath, 'SELECT username, type FROM biz_info')
|
||||
if (bizInfoRes.success && bizInfoRes.rows) {
|
||||
@@ -149,14 +167,18 @@ export class BizService {
|
||||
}
|
||||
}
|
||||
|
||||
// 6. 排序输出
|
||||
return result
|
||||
.filter(acc => !acc.name.includes('朋友圈广告'))
|
||||
.sort((a, b) => {
|
||||
if (a.username === 'gh_3dfda90e39d6') return -1
|
||||
if (b.username === 'gh_3dfda90e39d6') return 1
|
||||
return b.last_time - a.last_time
|
||||
})
|
||||
} catch (e) { return [] }
|
||||
.filter(acc => !acc.name.includes('广告'))
|
||||
.sort((a, b) => {
|
||||
if (a.username === 'gh_3dfda90e39d6') return -1 // 微信支付置顶
|
||||
if (b.username === 'gh_3dfda90e39d6') return 1
|
||||
return b.last_time - a.last_time // 按最新时间降序排列
|
||||
})
|
||||
} catch (e) {
|
||||
console.error('获取账号列表发生错误:', e)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
async listMessages(username: string, account?: string, limit: number = 20, offset: number = 0): Promise<BizMessage[]> {
|
||||
|
||||
Reference in New Issue
Block a user