mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-04-05 23:15:59 +00:00
交互细节修复与代码修复
This commit is contained in:
@@ -2,7 +2,7 @@ import { join, dirname } from 'path'
|
||||
|
||||
/**
|
||||
* 强制将本地资源目录添加到 PATH 最前端,确保优先加载本地 DLL
|
||||
* 解决系统中存在冲突版本的 DLL 导致的应用崩溃问题
|
||||
* 解决系统中存在冲突版本的数据服务导致的应用崩溃问题
|
||||
*/
|
||||
function enforceLocalDllPriority() {
|
||||
const isDev = !!process.env.VITE_DEV_SERVER_URL
|
||||
@@ -35,5 +35,5 @@ function enforceLocalDllPriority() {
|
||||
try {
|
||||
enforceLocalDllPriority()
|
||||
} catch (e) {
|
||||
console.error('[WeFlow] Failed to enforce local DLL priority:', e)
|
||||
console.error('[WeFlow] Failed to enforce local service priority:', e)
|
||||
}
|
||||
|
||||
@@ -469,7 +469,7 @@ class ChatService {
|
||||
if (this.monitorSetup) return
|
||||
this.monitorSetup = true
|
||||
|
||||
// 使用 C++ DLL 内部的文件监控 (ReadDirectoryChangesW)
|
||||
// 使用 C++数据服务内部的文件监控 (ReadDirectoryChangesW)
|
||||
// 这种方式更高效,且不占用 JS 线程,并能直接监听 session/message 目录变更
|
||||
wcdbService.setMonitor((type, json) => {
|
||||
this.handleSessionStatsMonitorChange(type, json)
|
||||
@@ -5117,7 +5117,7 @@ class ChatService {
|
||||
}
|
||||
}
|
||||
|
||||
//手动查找 media_*.db 文件(当 WCDB DLL 不支持 listMediaDbs 时的 fallback)
|
||||
//手动查找 media_*.db 文件(当 WCDB数据服务不支持 listMediaDbs 时的 fallback)
|
||||
private async findMediaDbsManually(): Promise<string[]> {
|
||||
try {
|
||||
const dbPath = this.configService.get('dbPath')
|
||||
@@ -5676,7 +5676,7 @@ class ChatService {
|
||||
if (!result.success || !result.contact) return null
|
||||
const contact = result.contact as Record<string, any>
|
||||
let alias = String(contact.alias || contact.Alias || '')
|
||||
// DLL 有时不返回 alias 字段,补一条直接 SQL 查询兜底
|
||||
//数据服务有时不返回 alias 字段,补一条直接 SQL 查询兜底
|
||||
if (!alias) {
|
||||
try {
|
||||
const aliasResult = await wcdbService.getContactAliasMap([username])
|
||||
|
||||
@@ -1423,7 +1423,7 @@ class ExportService {
|
||||
}
|
||||
return this.buildTrustedGroupNicknameMap(Object.entries(dllResult.nicknames), candidates)
|
||||
} catch (e) {
|
||||
console.error('getGroupNicknamesForRoom dll error:', e)
|
||||
console.error('getGroupNicknamesForRoom service error:', e)
|
||||
return new Map<string, string>()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ class GroupAnalyticsService {
|
||||
}
|
||||
return this.buildTrustedGroupNicknameMap(Object.entries(dllResult.nicknames), candidates)
|
||||
} catch (e) {
|
||||
console.error('getGroupNicknamesForRoom dll error:', e)
|
||||
console.error('getGroupNicknamesForRoom service error:', e)
|
||||
return new Map<string, string>()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -684,10 +684,7 @@ export class KeyService {
|
||||
return { success: false, error: '获取密钥超时', logs }
|
||||
}
|
||||
|
||||
// --- Image Key (通过 DLL 从缓存目录获取 code,用前端 wxid 计算密钥) ---
|
||||
|
||||
private cleanWxid(wxid: string): string {
|
||||
// 截断到第二个下划线: wxid_g4pshorcc0r529_da6c → wxid_g4pshorcc0r529
|
||||
const first = wxid.indexOf('_')
|
||||
if (first === -1) return wxid
|
||||
const second = wxid.indexOf('_', first + 1)
|
||||
|
||||
@@ -1062,14 +1062,14 @@ class SnsService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 补全 DLL 返回的评论中缺失的 refNickname
|
||||
* DLL 返回的 refCommentId 是被回复评论的 cmtid
|
||||
* 补全数据服务返回的评论中缺失的 refNickname
|
||||
*数据服务返回的 refCommentId 是被回复评论的 cmtid
|
||||
* 评论按 cmtid 从小到大排列,cmtid 从 1 开始递增
|
||||
*/
|
||||
private fixCommentRefs(comments: any[]): any[] {
|
||||
if (!comments || comments.length === 0) return []
|
||||
|
||||
// DLL 现在返回完整的评论数据(含 emojis、refNickname)
|
||||
//数据服务现在返回完整的评论数据(含 emojis、refNickname)
|
||||
// 此处做最终的格式化和兜底补全
|
||||
const idToNickname = new Map<string, string>()
|
||||
comments.forEach((c, idx) => {
|
||||
@@ -1140,14 +1140,14 @@ class SnsService {
|
||||
} : undefined
|
||||
}))
|
||||
|
||||
// DLL 已返回完整评论数据(含 emojis、refNickname)
|
||||
// 如果 DLL 评论缺少表情包信息,回退到从 rawXml 重新解析
|
||||
//数据服务已返回完整评论数据(含 emojis、refNickname)
|
||||
// 如果数据服务评论缺少表情包信息,回退到从 rawXml 重新解析
|
||||
const dllComments: any[] = post.comments || []
|
||||
const hasEmojisInDll = dllComments.some((c: any) => c.emojis && c.emojis.length > 0)
|
||||
|
||||
let finalComments: any[]
|
||||
if (dllComments.length > 0 && (hasEmojisInDll || !rawXml)) {
|
||||
// DLL 数据完整,直接使用
|
||||
//数据服务数据完整,直接使用
|
||||
finalComments = this.fixCommentRefs(dllComments)
|
||||
} else if (rawXml) {
|
||||
// 回退:从 rawXml 重新解析(兼容旧版 DLL)
|
||||
|
||||
@@ -76,7 +76,7 @@ export class VoiceTranscribeService {
|
||||
console.warn(`[VoiceTranscribe] 未找到 ${platformPkg} 目录,可能导致语音引擎加载失败`)
|
||||
}
|
||||
} else if (process.platform === 'win32') {
|
||||
// Windows: 把 sherpa-onnx DLL 所在目录加到 PATH,否则 native module 找不到依赖
|
||||
// Windows: 把 sherpa-onnx 所在目录加到 PATH,否则 native module 找不到依赖
|
||||
const existing = env['PATH'] || ''
|
||||
const merged = [...candidates, ...existing.split(';').filter(Boolean)]
|
||||
env['PATH'] = Array.from(new Set(merged)).join(';')
|
||||
|
||||
@@ -2,7 +2,7 @@ import { join, dirname, basename } from 'path'
|
||||
import { appendFileSync, existsSync, mkdirSync, readdirSync, statSync, readFileSync } from 'fs'
|
||||
import { tmpdir } from 'os'
|
||||
|
||||
// DLL 初始化错误信息,用于帮助用户诊断问题
|
||||
//数据服务初始化错误信息,用于帮助用户诊断问题
|
||||
let lastDllInitError: string | null = null
|
||||
|
||||
export function getLastDllInitError(): string | null {
|
||||
@@ -157,7 +157,7 @@ export class WcdbCore {
|
||||
return false
|
||||
}
|
||||
|
||||
// 从 DLL 获取动态管道名(含 PID)
|
||||
// 从数据服务获取动态管道名(含 PID)
|
||||
let pipePath = '\\\\.\\pipe\\weflow_monitor'
|
||||
if (this.wcdbGetMonitorPipeName) {
|
||||
try {
|
||||
@@ -638,8 +638,8 @@ export class WcdbCore {
|
||||
this.writeLog(`[bootstrap] initialize platform=${process.platform} dllPath=${dllPath} resourcesPath=${this.resourcesPath || ''} userDataPath=${this.userDataPath || ''}`, true)
|
||||
|
||||
if (!existsSync(dllPath)) {
|
||||
console.error('WCDB DLL 不存在:', dllPath)
|
||||
this.writeLog(`[bootstrap] initialize failed: dll not found path=${dllPath}`, true)
|
||||
console.error('WCDB数据服务不存在:', dllPath)
|
||||
this.writeLog(`[bootstrap] initialize failed:数据服务not found path=${dllPath}`, true)
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -694,7 +694,7 @@ export class WcdbCore {
|
||||
|
||||
// 尝试多个可能的资源路径
|
||||
const resourcePaths = [
|
||||
dllDir, // DLL 所在目录
|
||||
dllDir, //数据服务所在目录
|
||||
dirname(dllDir), // 上级目录
|
||||
process.resourcesPath, // 打包后 Contents/Resources
|
||||
process.resourcesPath ? join(process.resourcesPath as string, 'resources') : null, // Contents/Resources/resources
|
||||
@@ -1280,7 +1280,7 @@ export class WcdbCore {
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印 DLL 内部日志(仅在出错时调用)
|
||||
* 打印数据服务内部日志(仅在出错时调用)
|
||||
*/
|
||||
private async printLogs(force = false): Promise<void> {
|
||||
try {
|
||||
@@ -1603,7 +1603,7 @@ export class WcdbCore {
|
||||
const outPtr = [null as any]
|
||||
const result = this.wcdbGetSessions(this.handle, outPtr)
|
||||
|
||||
// DLL 调用后再次让出控制权
|
||||
//数据服务调用后再次让出控制权
|
||||
await new Promise(resolve => setImmediate(resolve))
|
||||
|
||||
if (result !== 0 || !outPtr[0]) {
|
||||
@@ -1958,7 +1958,7 @@ export class WcdbCore {
|
||||
const outPtr = [null as any]
|
||||
const result = this.wcdbGetDisplayNames(this.handle, JSON.stringify(usernames), outPtr)
|
||||
|
||||
// DLL 调用后再次让出控制权
|
||||
//数据服务调用后再次让出控制权
|
||||
await new Promise(resolve => setImmediate(resolve))
|
||||
|
||||
if (result !== 0 || !outPtr[0]) {
|
||||
@@ -2043,7 +2043,7 @@ export class WcdbCore {
|
||||
const outPtr = [null as any]
|
||||
const result = this.wcdbGetAvatarUrls(handle, JSON.stringify(toFetch), outPtr)
|
||||
|
||||
// DLL 调用后再次让出控制权
|
||||
//数据服务调用后再次让出控制权
|
||||
await new Promise(resolve => setImmediate(resolve))
|
||||
|
||||
if (result !== 0 || !outPtr[0]) {
|
||||
@@ -2143,7 +2143,7 @@ export class WcdbCore {
|
||||
return { success: false, error: 'WCDB 未连接' }
|
||||
}
|
||||
if (!this.wcdbGetGroupNicknames) {
|
||||
return { success: false, error: '当前 DLL 版本不支持获取群昵称接口' }
|
||||
return { success: false, error: '当前数据服务版本不支持获取群昵称接口' }
|
||||
}
|
||||
try {
|
||||
const outPtr = [null as any]
|
||||
@@ -2986,7 +2986,7 @@ export class WcdbCore {
|
||||
|
||||
async getVoiceData(sessionId: string, createTime: number, candidates: string[], localId: number = 0, svrId: string | number = 0): Promise<{ success: boolean; hex?: string; error?: string }> {
|
||||
if (!this.ensureReady()) return { success: false, error: 'WCDB 未连接' }
|
||||
if (!this.wcdbGetVoiceData) return { success: false, error: '当前 DLL 版本不支持获取语音数据' }
|
||||
if (!this.wcdbGetVoiceData) return { success: false, error: '当前数据服务版本不支持获取语音数据' }
|
||||
try {
|
||||
const outPtr = [null as any]
|
||||
const result = this.wcdbGetVoiceData(this.handle, sessionId, createTime, localId, BigInt(svrId || 0), JSON.stringify(candidates), outPtr)
|
||||
@@ -3400,7 +3400,7 @@ export class WcdbCore {
|
||||
|
||||
async searchMessages(keyword: string, sessionId?: string, limit?: number, offset?: number, beginTimestamp?: number, endTimestamp?: number): Promise<{ success: boolean; messages?: any[]; error?: string }> {
|
||||
if (!this.ensureReady()) return { success: false, error: 'WCDB 未连接' }
|
||||
if (!this.wcdbSearchMessages) return { success: false, error: '当前 DLL 版本不支持搜索消息' }
|
||||
if (!this.wcdbSearchMessages) return { success: false, error: '当前数据服务版本不支持搜索消息' }
|
||||
try {
|
||||
const handle = this.handle
|
||||
await new Promise(resolve => setImmediate(resolve))
|
||||
@@ -3430,7 +3430,7 @@ export class WcdbCore {
|
||||
|
||||
async getSnsTimeline(limit: number, offset: number, usernames?: string[], keyword?: string, startTime?: number, endTime?: number): Promise<{ success: boolean; timeline?: any[]; error?: string }> {
|
||||
if (!this.ensureReady()) return { success: false, error: 'WCDB 未连接' }
|
||||
if (!this.wcdbGetSnsTimeline) return { success: false, error: '当前 DLL 版本不支持获取朋友圈' }
|
||||
if (!this.wcdbGetSnsTimeline) return { success: false, error: '当前数据服务版本不支持获取朋友圈' }
|
||||
try {
|
||||
const outPtr = [null as any]
|
||||
const usernamesJson = usernames && usernames.length > 0 ? JSON.stringify(usernames) : ''
|
||||
@@ -3522,7 +3522,7 @@ export class WcdbCore {
|
||||
|
||||
async installMessageAntiRevokeTrigger(sessionId: string): Promise<{ success: boolean; alreadyInstalled?: boolean; error?: string }> {
|
||||
if (!this.ensureReady()) return { success: false, error: 'WCDB 未连接' }
|
||||
if (!this.wcdbInstallMessageAntiRevokeTrigger) return { success: false, error: '当前 DLL 版本不支持此功能' }
|
||||
if (!this.wcdbInstallMessageAntiRevokeTrigger) return { success: false, error: '当前数据服务版本不支持此功能' }
|
||||
const normalizedSessionId = String(sessionId || '').trim()
|
||||
if (!normalizedSessionId) return { success: false, error: 'sessionId 不能为空' }
|
||||
try {
|
||||
@@ -3547,7 +3547,7 @@ export class WcdbCore {
|
||||
|
||||
async uninstallMessageAntiRevokeTrigger(sessionId: string): Promise<{ success: boolean; error?: string }> {
|
||||
if (!this.ensureReady()) return { success: false, error: 'WCDB 未连接' }
|
||||
if (!this.wcdbUninstallMessageAntiRevokeTrigger) return { success: false, error: '当前 DLL 版本不支持此功能' }
|
||||
if (!this.wcdbUninstallMessageAntiRevokeTrigger) return { success: false, error: '当前数据服务版本不支持此功能' }
|
||||
const normalizedSessionId = String(sessionId || '').trim()
|
||||
if (!normalizedSessionId) return { success: false, error: 'sessionId 不能为空' }
|
||||
try {
|
||||
@@ -3569,7 +3569,7 @@ export class WcdbCore {
|
||||
|
||||
async checkMessageAntiRevokeTrigger(sessionId: string): Promise<{ success: boolean; installed?: boolean; error?: string }> {
|
||||
if (!this.ensureReady()) return { success: false, error: 'WCDB 未连接' }
|
||||
if (!this.wcdbCheckMessageAntiRevokeTrigger) return { success: false, error: '当前 DLL 版本不支持此功能' }
|
||||
if (!this.wcdbCheckMessageAntiRevokeTrigger) return { success: false, error: '当前数据服务版本不支持此功能' }
|
||||
const normalizedSessionId = String(sessionId || '').trim()
|
||||
if (!normalizedSessionId) return { success: false, error: 'sessionId 不能为空' }
|
||||
try {
|
||||
@@ -3640,7 +3640,7 @@ export class WcdbCore {
|
||||
*/
|
||||
async installSnsBlockDeleteTrigger(): Promise<{ success: boolean; alreadyInstalled?: boolean; error?: string }> {
|
||||
if (!this.ensureReady()) return { success: false, error: 'WCDB 未连接' }
|
||||
if (!this.wcdbInstallSnsBlockDeleteTrigger) return { success: false, error: '当前 DLL 版本不支持此功能' }
|
||||
if (!this.wcdbInstallSnsBlockDeleteTrigger) return { success: false, error: '当前数据服务版本不支持此功能' }
|
||||
try {
|
||||
const outPtr = [null]
|
||||
const status = this.wcdbInstallSnsBlockDeleteTrigger(this.handle, outPtr)
|
||||
@@ -3650,7 +3650,7 @@ export class WcdbCore {
|
||||
try { this.wcdbFreeString(outPtr[0]) } catch { }
|
||||
}
|
||||
if (status === 1) {
|
||||
// DLL 返回 1 表示已安装
|
||||
//数据服务返回 1 表示已安装
|
||||
return { success: true, alreadyInstalled: true }
|
||||
}
|
||||
if (status !== 0) {
|
||||
@@ -3667,7 +3667,7 @@ export class WcdbCore {
|
||||
*/
|
||||
async uninstallSnsBlockDeleteTrigger(): Promise<{ success: boolean; error?: string }> {
|
||||
if (!this.ensureReady()) return { success: false, error: 'WCDB 未连接' }
|
||||
if (!this.wcdbUninstallSnsBlockDeleteTrigger) return { success: false, error: '当前 DLL 版本不支持此功能' }
|
||||
if (!this.wcdbUninstallSnsBlockDeleteTrigger) return { success: false, error: '当前数据服务版本不支持此功能' }
|
||||
try {
|
||||
const outPtr = [null]
|
||||
const status = this.wcdbUninstallSnsBlockDeleteTrigger(this.handle, outPtr)
|
||||
@@ -3690,7 +3690,7 @@ export class WcdbCore {
|
||||
*/
|
||||
async checkSnsBlockDeleteTrigger(): Promise<{ success: boolean; installed?: boolean; error?: string }> {
|
||||
if (!this.ensureReady()) return { success: false, error: 'WCDB 未连接' }
|
||||
if (!this.wcdbCheckSnsBlockDeleteTrigger) return { success: false, error: '当前 DLL 版本不支持此功能' }
|
||||
if (!this.wcdbCheckSnsBlockDeleteTrigger) return { success: false, error: '当前数据服务版本不支持此功能' }
|
||||
try {
|
||||
const outInstalled = [0]
|
||||
const status = this.wcdbCheckSnsBlockDeleteTrigger(this.handle, outInstalled)
|
||||
@@ -3705,7 +3705,7 @@ export class WcdbCore {
|
||||
|
||||
async deleteSnsPost(postId: string): Promise<{ success: boolean; error?: string }> {
|
||||
if (!this.ensureReady()) return { success: false, error: 'WCDB 未连接' }
|
||||
if (!this.wcdbDeleteSnsPost) return { success: false, error: '当前 DLL 版本不支持此功能' }
|
||||
if (!this.wcdbDeleteSnsPost) return { success: false, error: '当前数据服务版本不支持此功能' }
|
||||
try {
|
||||
const outPtr = [null]
|
||||
const status = this.wcdbDeleteSnsPost(this.handle, postId, outPtr)
|
||||
|
||||
@@ -80,7 +80,7 @@ export class WcdbService {
|
||||
// Worker 退出,需要 reject 所有 pending promises
|
||||
if (code !== 0) {
|
||||
console.error('WCDB Worker 异常退出,退出码:', code)
|
||||
const errorMsg = `Worker 异常退出 (退出码: ${code})。可能是 DLL 加载失败,请检查是否安装了 Visual C++ Redistributable。`
|
||||
const errorMsg = `Worker 异常退出 (退出码: ${code})。可能是数据服务加载失败,请检查是否安装了 Visual C++ Redistributable。`
|
||||
for (const [id, p] of this.pending) {
|
||||
p.reject(new Error(errorMsg))
|
||||
}
|
||||
@@ -467,7 +467,7 @@ export class WcdbService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表情包释义(严格 DLL 接口)
|
||||
* 获取表情包释义(严格数据服务接口)
|
||||
*/
|
||||
async getEmoticonCaptionStrict(md5: string): Promise<{ success: boolean; caption?: string; error?: string }> {
|
||||
return this.callWorker('getEmoticonCaptionStrict', { md5 })
|
||||
@@ -608,7 +608,7 @@ export class WcdbService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 DLL 内部日志
|
||||
* 获取数据服务内部日志
|
||||
*/
|
||||
async getLogs(): Promise<{ success: boolean; logs?: string[]; error?: string }> {
|
||||
return this.callWorker('getLogs')
|
||||
|
||||
Reference in New Issue
Block a user