From cb362a4e2e60347c73aca63b91a60836d8cd7198 Mon Sep 17 00:00:00 2001 From: icarus Date: Sat, 23 Aug 2025 23:51:05 +0800 Subject: [PATCH] =?UTF-8?q?feat(OCR=E8=AE=BE=E7=BD=AE):=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0OCR=E6=8F=90=E4=BE=9B=E5=95=86=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=8F=8A=E7=8A=B6=E6=80=81=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增OCR提供商设置组件,支持显示当前选择的OCR提供商信息 在OCR图片设置中添加状态管理,同步提供商选择到父组件 添加Tesseract OCR设置组件,支持多语言选择(暂不可用) --- .../DocProcessSettings/OcrImageSettings.tsx | 15 +++++- .../OcrProviderSettings.tsx | 51 ++++++++++++++++++ .../DocProcessSettings/OcrSettings.tsx | 12 ++++- .../OcrTesseractSettings.tsx | 52 +++++++++++++++++++ 4 files changed, 126 insertions(+), 4 deletions(-) create mode 100644 src/renderer/src/pages/settings/DocProcessSettings/OcrProviderSettings.tsx create mode 100644 src/renderer/src/pages/settings/DocProcessSettings/OcrTesseractSettings.tsx diff --git a/src/renderer/src/pages/settings/DocProcessSettings/OcrImageSettings.tsx b/src/renderer/src/pages/settings/DocProcessSettings/OcrImageSettings.tsx index d5e3bf09a4..3efdf94fa0 100644 --- a/src/renderer/src/pages/settings/DocProcessSettings/OcrImageSettings.tsx +++ b/src/renderer/src/pages/settings/DocProcessSettings/OcrImageSettings.tsx @@ -1,8 +1,9 @@ import { loggerService } from '@logger' import { useAppSelector } from '@renderer/store' import { setImageOcrProvider } from '@renderer/store/ocr' -import { isImageOcrProvider } from '@renderer/types' +import { isImageOcrProvider, OcrProvider } from '@renderer/types' import { Select } from 'antd' +import { useEffect } from 'react' import { useTranslation } from 'react-i18next' import { useDispatch } from 'react-redux' @@ -10,13 +11,22 @@ import { SettingRow, SettingRowTitle } from '..' const logger = loggerService.withContext('OcrImageSettings') -const OcrImageSettings = () => { +type Props = { + setProvider: (provider: OcrProvider) => void +} + +const OcrImageSettings = ({ setProvider }: Props) => { const { t } = useTranslation() const providers = useAppSelector((state) => state.ocr.providers) const imageProvider = useAppSelector((state) => state.ocr.imageProvider) const imageProviders = providers.filter((p) => isImageOcrProvider(p)) const dispatch = useDispatch() + // 挂载时更新外部状态 + useEffect(() => { + setProvider(imageProvider) + }, [imageProvider, setProvider]) + const updateImageProvider = (id: string) => { const provider = imageProviders.find((p) => p.id === id) if (!provider) { @@ -25,6 +35,7 @@ const OcrImageSettings = () => { return } + setProvider(provider) dispatch(setImageOcrProvider(provider)) } diff --git a/src/renderer/src/pages/settings/DocProcessSettings/OcrProviderSettings.tsx b/src/renderer/src/pages/settings/DocProcessSettings/OcrProviderSettings.tsx new file mode 100644 index 0000000000..a9ba128d7a --- /dev/null +++ b/src/renderer/src/pages/settings/DocProcessSettings/OcrProviderSettings.tsx @@ -0,0 +1,51 @@ +// import { loggerService } from '@logger' +import { isBuiltinOcrProvider, OcrProvider } from '@renderer/types' +import { getOcrProviderLogo } from '@renderer/utils/ocr' +import { Avatar, Divider, Flex } from 'antd' +import styled from 'styled-components' + +import { SettingTitle } from '..' +import { OcrTesseractSettings } from './OcrTesseractSettings' + +// const logger = loggerService.withContext('OcrTesseractSettings') + +type Props = { + provider: OcrProvider +} + +const OcrProviderSettings = ({ provider }: Props) => { + // const { t } = useTranslation() + const getProviderSettings = () => { + if (isBuiltinOcrProvider(provider)) { + switch (provider.id) { + case 'tesseract': + return + } + } else { + throw new Error('Not supported OCR provider') + } + } + + return ( + <> + + + + {provider.name} + + + + {getProviderSettings()} + + ) +} + +const ProviderName = styled.span` + font-size: 14px; + font-weight: 500; +` +const ProviderLogo = styled(Avatar)` + border: 0.5px solid var(--color-border); +` + +export default OcrProviderSettings diff --git a/src/renderer/src/pages/settings/DocProcessSettings/OcrSettings.tsx b/src/renderer/src/pages/settings/DocProcessSettings/OcrSettings.tsx index 825e5fb86d..9ad2d111ad 100644 --- a/src/renderer/src/pages/settings/DocProcessSettings/OcrSettings.tsx +++ b/src/renderer/src/pages/settings/DocProcessSettings/OcrSettings.tsx @@ -1,22 +1,27 @@ import { PictureOutlined } from '@ant-design/icons' import { useTheme } from '@renderer/context/ThemeProvider' +import { useAppSelector } from '@renderer/store' +import { OcrProvider } from '@renderer/types' import { Tabs, TabsProps } from 'antd' -import { FC } from 'react' +import { FC, useState } from 'react' import { useTranslation } from 'react-i18next' import { SettingDivider, SettingGroup, SettingTitle } from '..' import OcrImageSettings from './OcrImageSettings' +import OcrProviderSettings from './OcrProviderSettings' const OcrSettings: FC = () => { const { t } = useTranslation() const { theme: themeMode } = useTheme() + const imageProvider = useAppSelector((state) => state.ocr.imageProvider) + const [provider, setProvider] = useState(imageProvider) // since default to image provider const tabs: TabsProps['items'] = [ { key: 'image', label: t('settings.tool.ocr.image.title'), icon: , - children: + children: } ] @@ -27,6 +32,9 @@ const OcrSettings: FC = () => { + + + ) } diff --git a/src/renderer/src/pages/settings/DocProcessSettings/OcrTesseractSettings.tsx b/src/renderer/src/pages/settings/DocProcessSettings/OcrTesseractSettings.tsx new file mode 100644 index 0000000000..3d51c82c45 --- /dev/null +++ b/src/renderer/src/pages/settings/DocProcessSettings/OcrTesseractSettings.tsx @@ -0,0 +1,52 @@ +// import { loggerService } from '@logger' +import InfoTooltip from '@renderer/components/InfoTooltip' +import { useOcrProvider } from '@renderer/hooks/useOcrProvider' +import { BuiltinOcrProviderIds, isOcrTesseractProvider } from '@renderer/types' +import { Flex, Select } from 'antd' +import { useTranslation } from 'react-i18next' + +import { SettingRow, SettingRowTitle } from '..' + +// const logger = loggerService.withContext('OcrTesseractSettings') + +export const OcrTesseractSettings = () => { + const { t } = useTranslation() + const { provider } = useOcrProvider(BuiltinOcrProviderIds.tesseract) + + // TODO: use error boundary + if (!isOcrTesseractProvider(provider)) { + throw new Error('Not tesseract provider.') + } + + // const [langs, setLangs] = useState(provider.config?.langs ?? {}) + + // currently static + const options = [ + { value: 'chi_sim', label: t('languages.chinese') }, + { value: 'chi_tra', label: t('languages.chinese-traditional') }, + { value: 'eng', label: t('languages.english') } + ] + + return ( + <> + + + + {t('settings.tool.ocr.image.tesseract.langs')} + + + +
+