mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-09 06:49:02 +08:00
feat(ocr): 添加OCR API客户端工厂及示例实现
实现OCR API客户端工厂模式,支持根据不同提供商创建对应的客户端 新增OcrBaseApiClient作为基础类,提供通用功能 添加OcrExampleApiClient作为示例实现 修改OcrService以使用新的客户端工厂
This commit is contained in:
parent
4b031597eb
commit
31cf452974
@ -1,4 +1,6 @@
|
|||||||
import { OcrProvider, OcrResult, SupportedOcrFile } from '@renderer/types'
|
import { isOcrApiProvider, OcrProvider, OcrResult, SupportedOcrFile } from '@renderer/types'
|
||||||
|
|
||||||
|
import { OcrApiClientFactory } from './clients/OcrApiClientFactory'
|
||||||
|
|
||||||
// const logger = loggerService.withContext('renderer:OcrService')
|
// const logger = loggerService.withContext('renderer:OcrService')
|
||||||
|
|
||||||
@ -10,5 +12,10 @@ import { OcrProvider, OcrResult, SupportedOcrFile } from '@renderer/types'
|
|||||||
* @throws {Error}
|
* @throws {Error}
|
||||||
*/
|
*/
|
||||||
export const ocr = async (file: SupportedOcrFile, provider: OcrProvider): Promise<OcrResult> => {
|
export const ocr = async (file: SupportedOcrFile, provider: OcrProvider): Promise<OcrResult> => {
|
||||||
return window.api.ocr.ocr(file, provider)
|
if (isOcrApiProvider(provider)) {
|
||||||
|
const client = OcrApiClientFactory.create(provider)
|
||||||
|
return client.ocr(file)
|
||||||
|
} else {
|
||||||
|
return window.api.ocr.ocr(file, provider)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
src/renderer/src/services/ocr/clients/OcrApiClientFactory.ts
Normal file
28
src/renderer/src/services/ocr/clients/OcrApiClientFactory.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { loggerService } from '@logger'
|
||||||
|
import { OcrApiProvider } from '@renderer/types'
|
||||||
|
|
||||||
|
import { OcrBaseApiClient } from './OcrBaseApiClient'
|
||||||
|
import { OcrExampleApiClient } from './OcrExampleApiClient'
|
||||||
|
|
||||||
|
const logger = loggerService.withContext('OcrApiClientFactory')
|
||||||
|
|
||||||
|
export class OcrApiClientFactory {
|
||||||
|
/**
|
||||||
|
* Create an ApiClient instance for the given provider
|
||||||
|
* 为给定的提供者创建ApiClient实例
|
||||||
|
*/
|
||||||
|
static create(provider: OcrApiProvider): OcrBaseApiClient {
|
||||||
|
logger.debug(`Creating ApiClient for provider:`, {
|
||||||
|
id: provider.id,
|
||||||
|
config: provider.config
|
||||||
|
})
|
||||||
|
|
||||||
|
let instance: OcrBaseApiClient
|
||||||
|
|
||||||
|
// Extend other clients here
|
||||||
|
// eslint-disable-next-line prefer-const
|
||||||
|
instance = new OcrExampleApiClient(provider)
|
||||||
|
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
}
|
||||||
43
src/renderer/src/services/ocr/clients/OcrBaseApiClient.ts
Normal file
43
src/renderer/src/services/ocr/clients/OcrBaseApiClient.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { OcrApiProvider, OcrHandler } from '@renderer/types'
|
||||||
|
|
||||||
|
export abstract class OcrBaseApiClient {
|
||||||
|
public provider: OcrApiProvider
|
||||||
|
protected host: string
|
||||||
|
protected apiKey: string
|
||||||
|
|
||||||
|
constructor(provider: OcrApiProvider) {
|
||||||
|
this.provider = provider
|
||||||
|
this.host = this.getHost()
|
||||||
|
this.apiKey = this.getApiKey()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract ocr: OcrHandler
|
||||||
|
|
||||||
|
// copy from BaseApiClient
|
||||||
|
public getHost(): string {
|
||||||
|
return this.provider.config.api.apiHost
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy from BaseApiClient
|
||||||
|
public getApiKey() {
|
||||||
|
const keys = this.provider.config.api.apiKey.split(',').map((key) => key.trim())
|
||||||
|
const keyName = `ocr_provider:${this.provider.id}:last_used_key`
|
||||||
|
|
||||||
|
if (keys.length === 1) {
|
||||||
|
return keys[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
const lastUsedKey = window.keyv.get(keyName)
|
||||||
|
if (!lastUsedKey) {
|
||||||
|
window.keyv.set(keyName, keys[0])
|
||||||
|
return keys[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentIndex = keys.indexOf(lastUsedKey)
|
||||||
|
const nextIndex = (currentIndex + 1) % keys.length
|
||||||
|
const nextKey = keys[nextIndex]
|
||||||
|
window.keyv.set(keyName, nextKey)
|
||||||
|
|
||||||
|
return nextKey
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/renderer/src/services/ocr/clients/OcrExampleApiClient.ts
Normal file
15
src/renderer/src/services/ocr/clients/OcrExampleApiClient.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { OcrApiProvider, SupportedOcrFile } from '@renderer/types'
|
||||||
|
|
||||||
|
import { OcrBaseApiClient } from './OcrBaseApiClient'
|
||||||
|
|
||||||
|
export type OcrExampleProvider = OcrApiProvider
|
||||||
|
|
||||||
|
export class OcrExampleApiClient extends OcrBaseApiClient {
|
||||||
|
constructor(provider: OcrApiProvider) {
|
||||||
|
super(provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
public ocr = async (file: SupportedOcrFile) => {
|
||||||
|
return { text: `Example output: ${file.path}` }
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user