fix(chat): 提升二维码 OCR 稳定性
This commit is contained in:
@@ -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 ''
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user