mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-24 18:50:56 +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')
|
||||
|
||||
@ -10,5 +12,10 @@ import { OcrProvider, OcrResult, SupportedOcrFile } from '@renderer/types'
|
||||
* @throws {Error}
|
||||
*/
|
||||
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