mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-03-25 07:16:51 +00:00
修复批量解密图片逻辑 加快速度
This commit is contained in:
@@ -3331,9 +3331,12 @@
|
|||||||
// 批量转写模态框基础样式(共享样式在 styles/batchTranscribe.scss)
|
// 批量转写模态框基础样式(共享样式在 styles/batchTranscribe.scss)
|
||||||
|
|
||||||
// 批量转写确认对话框
|
// 批量转写确认对话框
|
||||||
.batch-confirm-modal {
|
.batch-modal-content.batch-confirm-modal {
|
||||||
width: 480px;
|
width: 480px;
|
||||||
max-width: 90vw;
|
max-width: 90vw;
|
||||||
|
max-height: none;
|
||||||
|
overflow: visible;
|
||||||
|
overflow-y: visible;
|
||||||
|
|
||||||
.batch-modal-header {
|
.batch-modal-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -3470,6 +3473,74 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.batch-concurrency-field {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.batch-concurrency-trigger {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
background: var(--bg-primary);
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 13px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: var(--text-tertiary);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
border-color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
color: var(--text-tertiary);
|
||||||
|
transition: transform 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.open svg {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.batch-concurrency-dropdown {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(100% + 6px);
|
||||||
|
right: 0;
|
||||||
|
min-width: 180px;
|
||||||
|
background: color-mix(in srgb, var(--bg-primary) 90%, var(--bg-secondary));
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 6px;
|
||||||
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.batch-concurrency-option {
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 13px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: var(--bg-tertiary);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3527,7 +3598,7 @@
|
|||||||
&.btn-primary,
|
&.btn-primary,
|
||||||
&.batch-transcribe-start-btn {
|
&.batch-transcribe-start-btn {
|
||||||
background: var(--primary-color);
|
background: var(--primary-color);
|
||||||
color: white;
|
color: #000;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
|
|||||||
@@ -345,6 +345,8 @@ function ChatPage(_props: ChatPageProps) {
|
|||||||
const [batchImageMessages, setBatchImageMessages] = useState<BatchImageDecryptCandidate[] | null>(null)
|
const [batchImageMessages, setBatchImageMessages] = useState<BatchImageDecryptCandidate[] | null>(null)
|
||||||
const [batchImageDates, setBatchImageDates] = useState<string[]>([])
|
const [batchImageDates, setBatchImageDates] = useState<string[]>([])
|
||||||
const [batchImageSelectedDates, setBatchImageSelectedDates] = useState<Set<string>>(new Set())
|
const [batchImageSelectedDates, setBatchImageSelectedDates] = useState<Set<string>>(new Set())
|
||||||
|
const [batchDecryptConcurrency, setBatchDecryptConcurrency] = useState(6)
|
||||||
|
const [showConcurrencyDropdown, setShowConcurrencyDropdown] = useState(false)
|
||||||
|
|
||||||
// 批量删除相关状态
|
// 批量删除相关状态
|
||||||
const [isDeleting, setIsDeleting] = useState(false)
|
const [isDeleting, setIsDeleting] = useState(false)
|
||||||
@@ -1662,29 +1664,44 @@ function ChatPage(_props: ChatPageProps) {
|
|||||||
|
|
||||||
let successCount = 0
|
let successCount = 0
|
||||||
let failCount = 0
|
let failCount = 0
|
||||||
for (let i = 0; i < images.length; i++) {
|
let completed = 0
|
||||||
const img = images[i]
|
const concurrency = batchDecryptConcurrency
|
||||||
|
|
||||||
|
const decryptOne = async (img: typeof images[0]) => {
|
||||||
try {
|
try {
|
||||||
const r = await window.electronAPI.image.decrypt({
|
const r = await window.electronAPI.image.decrypt({
|
||||||
sessionId: session.username,
|
sessionId: session.username,
|
||||||
imageMd5: img.imageMd5,
|
imageMd5: img.imageMd5,
|
||||||
imageDatName: img.imageDatName,
|
imageDatName: img.imageDatName,
|
||||||
force: false
|
force: true
|
||||||
})
|
})
|
||||||
if (r?.success) successCount++
|
if (r?.success) successCount++
|
||||||
else failCount++
|
else failCount++
|
||||||
} catch {
|
} catch {
|
||||||
failCount++
|
failCount++
|
||||||
}
|
}
|
||||||
|
completed++
|
||||||
|
updateDecryptProgress(completed, images.length)
|
||||||
|
}
|
||||||
|
|
||||||
updateDecryptProgress(i + 1, images.length)
|
// 并发池:同时跑 concurrency 个任务
|
||||||
if (i % 5 === 0) {
|
const pool: Promise<void>[] = []
|
||||||
await new Promise(resolve => setTimeout(resolve, 0))
|
for (const img of images) {
|
||||||
|
const p = decryptOne(img)
|
||||||
|
pool.push(p)
|
||||||
|
if (pool.length >= concurrency) {
|
||||||
|
await Promise.race(pool)
|
||||||
|
// 移除已完成的
|
||||||
|
for (let j = pool.length - 1; j >= 0; j--) {
|
||||||
|
const settled = await Promise.race([pool[j].then(() => true), Promise.resolve(false)])
|
||||||
|
if (settled) pool.splice(j, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
await Promise.all(pool)
|
||||||
|
|
||||||
finishDecrypt(successCount, failCount)
|
finishDecrypt(successCount, failCount)
|
||||||
}, [batchImageMessages, batchImageSelectedDates, currentSessionId, finishDecrypt, sessions, startDecrypt, updateDecryptProgress])
|
}, [batchImageMessages, batchImageSelectedDates, batchDecryptConcurrency, currentSessionId, finishDecrypt, sessions, startDecrypt, updateDecryptProgress])
|
||||||
|
|
||||||
const batchImageCountByDate = useMemo(() => {
|
const batchImageCountByDate = useMemo(() => {
|
||||||
const map = new Map<string, number>()
|
const map = new Map<string, number>()
|
||||||
@@ -2623,6 +2640,39 @@ function ChatPage(_props: ChatPageProps) {
|
|||||||
<span className="label">已选:</span>
|
<span className="label">已选:</span>
|
||||||
<span className="value">{batchImageSelectedDates.size} 天,共 {batchImageSelectedCount} 张图片</span>
|
<span className="value">{batchImageSelectedDates.size} 天,共 {batchImageSelectedCount} 张图片</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="info-item">
|
||||||
|
<span className="label">并发数:</span>
|
||||||
|
<div className="batch-concurrency-field">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={`batch-concurrency-trigger ${showConcurrencyDropdown ? 'open' : ''}`}
|
||||||
|
onClick={() => setShowConcurrencyDropdown(!showConcurrencyDropdown)}
|
||||||
|
>
|
||||||
|
<span>{batchDecryptConcurrency === 1 ? '1(最慢,最稳)' : batchDecryptConcurrency === 6 ? '6(推荐)' : batchDecryptConcurrency === 20 ? '20(最快,可能卡顿)' : String(batchDecryptConcurrency)}</span>
|
||||||
|
<ChevronDown size={14} />
|
||||||
|
</button>
|
||||||
|
{showConcurrencyDropdown && (
|
||||||
|
<div className="batch-concurrency-dropdown">
|
||||||
|
{[
|
||||||
|
{ value: 1, label: '1(最慢,最稳)' },
|
||||||
|
{ value: 3, label: '3' },
|
||||||
|
{ value: 6, label: '6(推荐)' },
|
||||||
|
{ value: 10, label: '10' },
|
||||||
|
{ value: 20, label: '20(最快,可能卡顿)' },
|
||||||
|
].map(opt => (
|
||||||
|
<button
|
||||||
|
key={opt.value}
|
||||||
|
type="button"
|
||||||
|
className={`batch-concurrency-option ${batchDecryptConcurrency === opt.value ? 'active' : ''}`}
|
||||||
|
onClick={() => { setBatchDecryptConcurrency(opt.value); setShowConcurrencyDropdown(false) }}
|
||||||
|
>
|
||||||
|
{opt.label}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="batch-warning">
|
<div className="batch-warning">
|
||||||
<AlertCircle size={16} />
|
<AlertCircle size={16} />
|
||||||
|
|||||||
Reference in New Issue
Block a user