fix(chat): 提升二维码 OCR 稳定性

This commit is contained in:
yml2213
2026-08-25 16:59:05 +08:00
parent 8f6356a3d7
commit d95b95211c
7 changed files with 761 additions and 102 deletions
@@ -32,6 +32,7 @@ import { formatDateTime } from '@/shared/utils/time'
import AdminTablePagination from '../components/AdminTablePagination.vue'
import AuthImage from '@/shared/components/business/AuthImage.vue'
import { readError } from '@/shared/utils/error'
import { optimizeImageForUpload } from '@/shared/utils/imageUpload'
import { useAdminSessionStore } from '@/stores/adminSession'
const adminSession = useAdminSessionStore()
@@ -243,34 +244,33 @@ function parseGroupNameFromOcrText(text: string) {
)
}
const ocrConcurrencyLimit = 4
const ocrConcurrencyLimit = 2
let ocrRunningCount = 0
const ocrWaitQueue: (() => void)[] = []
class OCRQueueResetError extends Error {}
const ocrWaitQueue: { resolve: () => void; reject: (error: Error) => void }[] = []
function ocrAcquireSlot(): Promise<void> {
if (ocrRunningCount < ocrConcurrencyLimit) {
ocrRunningCount++
return Promise.resolve()
}
return new Promise(resolve => {
ocrWaitQueue.push(() => {
ocrRunningCount++
resolve()
})
return new Promise((resolve, reject) => {
ocrWaitQueue.push({ resolve, reject })
})
}
function ocrReleaseSlot() {
ocrRunningCount = Math.max(0, ocrRunningCount - 1)
const next = ocrWaitQueue.shift()
if (next) next()
if (next) {
ocrRunningCount++
next.resolve()
}
}
function ocrResetSlots() {
ocrRunningCount = 0
while (ocrWaitQueue.length > 0) {
const next = ocrWaitQueue.shift()
next?.()
for (const waiter of ocrWaitQueue.splice(0)) {
waiter.reject(new OCRQueueResetError('OCR queue reset'))
}
}
@@ -322,9 +322,11 @@ async function handleFileUpload(options: { file: File }) {
}
uploadedImages.value.push(item)
const normalizedFile = await optimizeImageForUpload(options.file, 'qrcode')
const [uploaded, groupName] = await Promise.all([
uploadAdminFile(options.file, 'qrcode'),
recognizeGroupNameWithLimit(options.file).catch(error => {
uploadAdminFile(normalizedFile, 'qrcode', { optimize: false }),
recognizeGroupNameWithLimit(normalizedFile).catch(error => {
if (error instanceof OCRQueueResetError) return ''
console.warn('二维码群名 OCR 失败', error)
ElMessage.warning(readError(error, '二维码群名 OCR 失败'))
return ''
+6 -2
View File
@@ -23,8 +23,12 @@ export async function uploadFile(file: File, scene: string) {
return data.data
}
export async function uploadAdminFile(file: File, scene: string) {
const uploadTarget = await optimizeImageForUpload(file, scene)
export async function uploadAdminFile(
file: File,
scene: string,
options: { optimize?: boolean } = {}
) {
const uploadTarget = options.optimize === false ? file : await optimizeImageForUpload(file, scene)
const form = new FormData()
form.append('file', uploadTarget)
form.append('scene', scene)