mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-03-24 15:19:03 +08:00
修复
This commit is contained in:
@@ -12,6 +12,7 @@ interface ConfigSchema {
|
||||
|
||||
// 缓存相关
|
||||
cachePath: string
|
||||
weixinDllPath: string
|
||||
lastOpenedDb: string
|
||||
lastSession: string
|
||||
|
||||
@@ -72,6 +73,7 @@ export class ConfigService {
|
||||
imageAesKey: '',
|
||||
wxidConfigs: {},
|
||||
cachePath: '',
|
||||
weixinDllPath: '',
|
||||
lastOpenedDb: '',
|
||||
lastSession: '',
|
||||
theme: 'system',
|
||||
|
||||
@@ -75,6 +75,7 @@ const detectImageMime = (buf: Buffer, fallback: string = 'image/jpeg') => {
|
||||
}
|
||||
|
||||
class SnsService {
|
||||
private configService: ConfigService
|
||||
private contactCache: ContactCacheService
|
||||
private imageCache = new Map<string, string>()
|
||||
|
||||
@@ -87,8 +88,8 @@ class SnsService {
|
||||
private nativeDecryptFn: any = null
|
||||
|
||||
constructor() {
|
||||
const config = new ConfigService()
|
||||
this.contactCache = new ContactCacheService(config.get('cachePath') as string)
|
||||
this.configService = new ConfigService()
|
||||
this.contactCache = new ContactCacheService(this.configService.get('cachePath') as string)
|
||||
}
|
||||
|
||||
async getTimeline(limit: number = 20, offset: number = 0, usernames?: string[], keyword?: string, startTime?: number, endTime?: number): Promise<{ success: boolean; timeline?: SnsPost[]; error?: string }> {
|
||||
@@ -182,11 +183,14 @@ class SnsService {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private resolveWeixinDllPath(): string | null {
|
||||
const candidates: string[] = []
|
||||
|
||||
if (process.env.WEFLOW_WEIXIN_DLL) candidates.push(process.env.WEFLOW_WEIXIN_DLL)
|
||||
|
||||
const configuredPath = String(this.configService.get('weixinDllPath') || '').trim()
|
||||
if (configuredPath) candidates.push(configuredPath)
|
||||
|
||||
const weixinExe = process.env.WEFLOW_WEIXIN_EXE
|
||||
if (weixinExe) {
|
||||
const dir = weixinExe.replace(/\\Weixin\.exe$/i, '')
|
||||
@@ -195,27 +199,32 @@ class SnsService {
|
||||
|
||||
const programFiles = process.env.ProgramFiles || 'C:\\Program Files'
|
||||
const localAppData = process.env.LOCALAPPDATA || ''
|
||||
candidates.push(
|
||||
join(programFiles, 'Tencent', 'Weixin', 'Weixin.dll'),
|
||||
'D:\\weixindata\\Weixin\\Weixin.dll',
|
||||
'C:\\Users\\16586\\Desktop\\sns\\Weixin.dll'
|
||||
)
|
||||
candidates.push(join(programFiles, 'Tencent', 'Weixin', 'Weixin.dll'))
|
||||
if (localAppData) candidates.push(join(localAppData, 'Tencent', 'xwechat', 'Weixin.dll'))
|
||||
|
||||
const seen = new Set<string>()
|
||||
for (const p of candidates) {
|
||||
if (p && existsSync(p)) return p
|
||||
if (!p) continue
|
||||
const normalized = p.trim()
|
||||
if (!normalized || seen.has(normalized)) continue
|
||||
seen.add(normalized)
|
||||
if (existsSync(normalized)) return normalized
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private ensureNativeDecryptor(): boolean {
|
||||
const configuredPath = String(this.configService.get('weixinDllPath') || '').trim()
|
||||
if (this.nativeDecryptInit && !this.nativeDecryptReady && configuredPath && configuredPath !== this.nativeDecryptDllPath) {
|
||||
this.nativeDecryptInit = false
|
||||
}
|
||||
|
||||
if (this.nativeDecryptInit) return this.nativeDecryptReady
|
||||
this.nativeDecryptInit = true
|
||||
|
||||
try {
|
||||
const dllPath = this.resolveWeixinDllPath()
|
||||
if (!dllPath) {
|
||||
this.nativeDecryptError = 'Weixin.dll not found, set WEFLOW_WEIXIN_DLL if needed'
|
||||
this.nativeDecryptError = 'Weixin.dll not found, please set it in Settings or WEFLOW_WEIXIN_DLL'
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -349,6 +358,3 @@ class SnsService {
|
||||
}
|
||||
|
||||
export const snsService = new SnsService()
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ function SettingsPage() {
|
||||
const exportExcelColumnsDropdownRef = useRef<HTMLDivElement>(null)
|
||||
const exportConcurrencyDropdownRef = useRef<HTMLDivElement>(null)
|
||||
const [cachePath, setCachePath] = useState('')
|
||||
const [weixinDllPath, setWeixinDllPath] = useState('')
|
||||
const [logEnabled, setLogEnabled] = useState(false)
|
||||
const [whisperModelName, setWhisperModelName] = useState('base')
|
||||
const [whisperModelDir, setWhisperModelDir] = useState('')
|
||||
@@ -249,6 +250,7 @@ function SettingsPage() {
|
||||
const savedPath = await configService.getDbPath()
|
||||
const savedWxid = await configService.getMyWxid()
|
||||
const savedCachePath = await configService.getCachePath()
|
||||
const savedWeixinDllPath = await configService.getWeixinDllPath()
|
||||
const savedExportPath = await configService.getExportPath()
|
||||
const savedLogEnabled = await configService.getLogEnabled()
|
||||
const savedImageXorKey = await configService.getImageXorKey()
|
||||
@@ -277,6 +279,7 @@ function SettingsPage() {
|
||||
if (savedPath) setDbPath(savedPath)
|
||||
if (savedWxid) setWxid(savedWxid)
|
||||
if (savedCachePath) setCachePath(savedCachePath)
|
||||
if (savedWeixinDllPath) setWeixinDllPath(savedWeixinDllPath)
|
||||
|
||||
const wxidConfig = savedWxid ? await configService.getWxidConfig(savedWxid) : null
|
||||
const decryptKeyToUse = wxidConfig?.decryptKey ?? savedKey ?? ''
|
||||
@@ -613,6 +616,29 @@ function SettingsPage() {
|
||||
await applyWxidSelection(selectedWxid)
|
||||
}
|
||||
|
||||
const handleSelectWeixinDllPath = async () => {
|
||||
try {
|
||||
const result = await dialog.openFile({
|
||||
title: '选择 Weixin.dll 文件',
|
||||
properties: ['openFile'],
|
||||
filters: [{ name: 'DLL', extensions: ['dll'] }]
|
||||
})
|
||||
if (!result.canceled && result.filePaths.length > 0) {
|
||||
const selectedPath = result.filePaths[0]
|
||||
setWeixinDllPath(selectedPath)
|
||||
await configService.setWeixinDllPath(selectedPath)
|
||||
showMessage('已选择 Weixin.dll 路径', true)
|
||||
}
|
||||
} catch {
|
||||
showMessage('选择 Weixin.dll 失败', false)
|
||||
}
|
||||
}
|
||||
|
||||
const handleResetWeixinDllPath = async () => {
|
||||
setWeixinDllPath('')
|
||||
await configService.setWeixinDllPath('')
|
||||
showMessage('已清空 Weixin.dll 路径', true)
|
||||
}
|
||||
const handleSelectCachePath = async () => {
|
||||
try {
|
||||
const result = await dialog.openFile({ title: '选择缓存目录', properties: ['openDirectory'] })
|
||||
@@ -1306,6 +1332,29 @@ function SettingsPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label>Weixin.dll 路径 <span className="optional">(可选)</span></label>
|
||||
<span className="form-hint">用于朋友圈在线图片原生解密,优先使用这里配置的 DLL</span>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="例如: D:\weixindata\Weixin\Weixin.dll"
|
||||
value={weixinDllPath}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value
|
||||
setWeixinDllPath(value)
|
||||
scheduleConfigSave('weixinDllPath', () => configService.setWeixinDllPath(value))
|
||||
}}
|
||||
/>
|
||||
<div className="btn-row">
|
||||
<button className="btn btn-secondary" onClick={handleSelectWeixinDllPath}>
|
||||
<FolderOpen size={16} /> 浏览选择
|
||||
</button>
|
||||
<button className="btn btn-secondary" onClick={handleResetWeixinDllPath}>
|
||||
清空
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label>账号 wxid</label>
|
||||
<span className="form-hint">微信账号标识</span>
|
||||
|
||||
@@ -434,7 +434,7 @@ export default function SnsPage() {
|
||||
<div className="sns-content-wrapper">
|
||||
<div className="sns-notice-banner">
|
||||
<AlertTriangle size={16} />
|
||||
<span>由于技术限制,当前无法解密显示部分图片与视频等加密资源文件</span>
|
||||
<span>由于技术限制,当前无法解密显示视频加密资源文件</span>
|
||||
</div>
|
||||
<div className="sns-content custom-scrollbar" onScroll={handleScroll} onWheel={handleWheel} ref={postsContainerRef}>
|
||||
<div className="posts-list">
|
||||
|
||||
@@ -12,6 +12,7 @@ export const CONFIG_KEYS = {
|
||||
LAST_SESSION: 'lastSession',
|
||||
WINDOW_BOUNDS: 'windowBounds',
|
||||
CACHE_PATH: 'cachePath',
|
||||
WEIXIN_DLL_PATH: 'weixinDllPath',
|
||||
EXPORT_PATH: 'exportPath',
|
||||
AGREEMENT_ACCEPTED: 'agreementAccepted',
|
||||
LOG_ENABLED: 'logEnabled',
|
||||
@@ -162,6 +163,17 @@ export async function setCachePath(path: string): Promise<void> {
|
||||
}
|
||||
|
||||
|
||||
// 获取 Weixin.dll 路径
|
||||
export async function getWeixinDllPath(): Promise<string | null> {
|
||||
const value = await config.get(CONFIG_KEYS.WEIXIN_DLL_PATH)
|
||||
return value as string | null
|
||||
}
|
||||
|
||||
// 设置 Weixin.dll 路径
|
||||
export async function setWeixinDllPath(path: string): Promise<void> {
|
||||
await config.set(CONFIG_KEYS.WEIXIN_DLL_PATH, path)
|
||||
}
|
||||
|
||||
// 获取导出路径
|
||||
export async function getExportPath(): Promise<string | null> {
|
||||
const value = await config.get(CONFIG_KEYS.EXPORT_PATH)
|
||||
|
||||
Reference in New Issue
Block a user