feat(ocr): 添加OCR提供者管理功能并改进错误处理

添加useOcrProviders钩子用于管理OCR提供者的添加和删除
当内置OCR提供者不存在时自动恢复默认配置
改进错误提示信息并增加国际化支持
This commit is contained in:
icarus 2025-08-23 21:14:08 +08:00
parent f23e37941a
commit e61bfef366

View File

@ -1,22 +1,76 @@
import { loggerService } from '@logger'
import { BUILTIN_OCR_PROVIDERS_MAP } from '@renderer/config/ocr'
import { useAppSelector } from '@renderer/store'
import { updateOcrProviderConfig } from '@renderer/store/ocr'
import { OcrProviderConfig } from '@renderer/types'
import { addOcrProvider, removeOcrProvider, updateOcrProviderConfig } from '@renderer/store/ocr'
import { isBuiltinOcrProviderId, OcrProvider, OcrProviderConfig } from '@renderer/types'
import { useTranslation } from 'react-i18next'
import { useDispatch } from 'react-redux'
const logger = loggerService.withContext('useOcrProvider')
export const useOcrProviders = () => {
const providers = useAppSelector((state) => state.ocr.providers)
const dispatch = useDispatch()
const { t } = useTranslation()
/**
* OCR服务提供者
* @param provider - OCR提供者对象id和其他配置信息
* @throws {Error} ID的提供者时抛出错误
*/
const addProvider = (provider: OcrProvider) => {
if (providers.some((p) => p.id === provider.id)) {
const msg = `Provider with id ${provider.id} already exists`
logger.error(msg)
window.message.error(t('ocr.error.provider.existing'))
throw new Error(msg)
}
dispatch(addOcrProvider(provider))
}
/**
* OCR服务提供者
* @param id - OCR提供者ID
* @throws {Error}
*/
const removeProvider = (id: string) => {
if (isBuiltinOcrProviderId(id)) {
const msg = `Cannot remove builtin provider ${id}`
logger.error(msg)
window.message.error(t('ocr.error.provider.cannot_remove_builtin'))
throw new Error(msg)
}
dispatch(removeOcrProvider(id))
}
return { providers, addProvider, removeProvider }
}
export const useOcrProvider = (id: string) => {
const { t } = useTranslation()
const dispatch = useDispatch()
const providers = useAppSelector((state) => state.ocr.providers)
const provider = providers.find((p) => p.id === id)
const { providers, addProvider } = useOcrProviders()
let provider = providers.find((p) => p.id === id)
// safely fallback
if (!provider) {
logger.error(`Ocr Provider ${id} not found`)
window.message.error(t('ocr.provider.not_found'))
throw new Error(`Ocr Provider ${id} not found`)
window.message.error(t('ocr.error.provider.not_found'))
if (isBuiltinOcrProviderId(id)) {
try {
addProvider(BUILTIN_OCR_PROVIDERS_MAP[id])
} catch (e) {
logger.warn(`Add ${BUILTIN_OCR_PROVIDERS_MAP[id].name} failed. Just use temp provider from config.`)
window.message.warning(t('ocr.warning.provider.fallback', { name: BUILTIN_OCR_PROVIDERS_MAP[id].name }))
} finally {
provider = BUILTIN_OCR_PROVIDERS_MAP[id]
}
} else {
logger.warn(`Fallback to tesseract`)
window.message.warning(t('ocr.warning.provider.fallback', { name: 'Tesseract' }))
provider = BUILTIN_OCR_PROVIDERS_MAP.tesseract
}
}
const updateConfig = (update: Partial<OcrProviderConfig>) => {