mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-03-25 15:25:50 +00:00
@@ -4,6 +4,7 @@ import { existsSync, readdirSync, statSync, readFileSync } from 'fs'
|
|||||||
import { execFile, exec } from 'child_process'
|
import { execFile, exec } from 'child_process'
|
||||||
import { promisify } from 'util'
|
import { promisify } from 'util'
|
||||||
import { createRequire } from 'module';
|
import { createRequire } from 'module';
|
||||||
|
import { spawn } from 'child_process'
|
||||||
const require = createRequire(import.meta.url);
|
const require = createRequire(import.meta.url);
|
||||||
|
|
||||||
const execFileAsync = promisify(execFile)
|
const execFileAsync = promisify(execFile)
|
||||||
@@ -51,12 +52,37 @@ export class KeyServiceLinux {
|
|||||||
await new Promise(r => setTimeout(r, 1000))
|
await new Promise(r => setTimeout(r, 1000))
|
||||||
|
|
||||||
onStatus?.('正在尝试拉起微信...', 0)
|
onStatus?.('正在尝试拉起微信...', 0)
|
||||||
const startCmds = [
|
|
||||||
'nohup wechat >/dev/null 2>&1 &',
|
const cleanEnv = { ...process.env };
|
||||||
'nohup wechat-bin >/dev/null 2>&1 &',
|
delete cleanEnv.ELECTRON_RUN_AS_NODE;
|
||||||
'nohup xwechat >/dev/null 2>&1 &'
|
delete cleanEnv.ELECTRON_NO_ATTACH_CONSOLE;
|
||||||
|
delete cleanEnv.APPDIR;
|
||||||
|
delete cleanEnv.APPIMAGE;
|
||||||
|
|
||||||
|
const wechatBins = [
|
||||||
|
'wechat',
|
||||||
|
'wechat-bin',
|
||||||
|
'xwechat',
|
||||||
|
'/opt/wechat/wechat',
|
||||||
|
'/usr/bin/wechat',
|
||||||
|
'/opt/apps/com.tencent.wechat/files/wechat'
|
||||||
]
|
]
|
||||||
for (const cmd of startCmds) execAsync(cmd).catch(() => {})
|
|
||||||
|
for (const binName of wechatBins) {
|
||||||
|
try {
|
||||||
|
const child = spawn(binName, [], {
|
||||||
|
detached: true,
|
||||||
|
stdio: 'ignore',
|
||||||
|
env: cleanEnv
|
||||||
|
});
|
||||||
|
|
||||||
|
child.on('error', () => {});
|
||||||
|
|
||||||
|
child.unref();
|
||||||
|
} catch (e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onStatus?.('等待微信进程出现...', 0)
|
onStatus?.('等待微信进程出现...', 0)
|
||||||
let pid = 0
|
let pid = 0
|
||||||
|
|||||||
@@ -273,8 +273,20 @@ export class VoiceTranscribeService {
|
|||||||
})
|
})
|
||||||
|
|
||||||
worker.on('error', (err: Error) => resolve({ success: false, error: String(err) }))
|
worker.on('error', (err: Error) => resolve({ success: false, error: String(err) }))
|
||||||
worker.on('exit', (code: number) => {
|
worker.on('exit', (code: number | null, signal: string | null) => {
|
||||||
if (code !== 0) resolve({ success: false, error: `Worker exited with code ${code}` })
|
if (code === null || signal === 'SIGSEGV') {
|
||||||
|
|
||||||
|
console.error(`[VoiceTranscribe] Worker 异常崩溃,信号: ${signal}。可能是由于底层 C++ 运行库在当前系统上发生段错误。`);
|
||||||
|
resolve({
|
||||||
|
success: false,
|
||||||
|
error: 'SEGFAULT_ERROR'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code !== 0) {
|
||||||
|
resolve({ success: false, error: `Worker exited with code ${code}` });
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -7611,6 +7611,12 @@ function MessageBubble({
|
|||||||
const [voiceWaveform, setVoiceWaveform] = useState<number[]>([])
|
const [voiceWaveform, setVoiceWaveform] = useState<number[]>([])
|
||||||
const voiceAutoDecryptTriggered = useRef(false)
|
const voiceAutoDecryptTriggered = useRef(false)
|
||||||
|
|
||||||
|
|
||||||
|
const [systemAlert, setSystemAlert] = useState<{
|
||||||
|
title: string;
|
||||||
|
message: React.ReactNode;
|
||||||
|
} | null>(null)
|
||||||
|
|
||||||
// 转账消息双方名称
|
// 转账消息双方名称
|
||||||
const [transferPayerName, setTransferPayerName] = useState<string | undefined>(undefined)
|
const [transferPayerName, setTransferPayerName] = useState<string | undefined>(undefined)
|
||||||
const [transferReceiverName, setTransferReceiverName] = useState<string | undefined>(undefined)
|
const [transferReceiverName, setTransferReceiverName] = useState<string | undefined>(undefined)
|
||||||
@@ -8300,6 +8306,21 @@ function MessageBubble({
|
|||||||
voiceTranscriptCache.set(voiceTranscriptCacheKey, transcriptText)
|
voiceTranscriptCache.set(voiceTranscriptCacheKey, transcriptText)
|
||||||
setVoiceTranscript(transcriptText)
|
setVoiceTranscript(transcriptText)
|
||||||
} else {
|
} else {
|
||||||
|
if (result.error === 'SEGFAULT_ERROR') {
|
||||||
|
console.warn('[ChatPage] 捕获到语音引擎底层段错误');
|
||||||
|
|
||||||
|
setSystemAlert({
|
||||||
|
title: '引擎崩溃提示',
|
||||||
|
message: (
|
||||||
|
<>
|
||||||
|
语音识别引擎发生底层崩溃 (Segmentation Fault)。<br /><br />
|
||||||
|
如果您使用的是 Linux 等自定义程度较高的系统,请检查 <code>sherpa-onnx</code> 的相关系统动态链接库 (如 glibc 等) 是否兼容。
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
setVoiceTranscriptError(true)
|
setVoiceTranscriptError(true)
|
||||||
voiceTranscriptRequestedRef.current = false
|
voiceTranscriptRequestedRef.current = false
|
||||||
}
|
}
|
||||||
@@ -9699,6 +9720,31 @@ function MessageBubble({
|
|||||||
{isSelected && <Check size={14} strokeWidth={3} />}
|
{isSelected && <Check size={14} strokeWidth={3} />}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{systemAlert && createPortal(
|
||||||
|
<div className="modal-overlay" onClick={() => setSystemAlert(null)} style={{ zIndex: 99999 }}>
|
||||||
|
<div className="delete-confirm-card" onClick={(e) => e.stopPropagation()} style={{ maxWidth: '400px' }}>
|
||||||
|
<div className="confirm-icon">
|
||||||
|
<AlertCircle size={32} color="var(--danger)" />
|
||||||
|
</div>
|
||||||
|
<div className="confirm-content">
|
||||||
|
<h3>{systemAlert.title}</h3>
|
||||||
|
<p style={{ marginTop: '12px', lineHeight: '1.6', fontSize: '14px', color: 'var(--text-secondary)' }}>
|
||||||
|
{systemAlert.message}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="confirm-actions" style={{ justifyContent: 'center', marginTop: '24px' }}>
|
||||||
|
<button
|
||||||
|
className="btn-primary"
|
||||||
|
onClick={() => setSystemAlert(null)}
|
||||||
|
style={{ padding: '8px 32px' }}
|
||||||
|
>
|
||||||
|
确认
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>,
|
||||||
|
document.body
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user