mirror of
https://gitee.com/mirrors/AllinSSL.git
synced 2026-03-18 20:18:49 +08:00
【新增】插件git同步模块,用于同步项目内容,加速项目开发
【调整】前端暗色问题
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import { TranslationAdapter } from './index.js'
|
||||
import { ZhipuAITranslator } from '../ai/zhipuAI.js'
|
||||
import { QianwenAITranslator } from '../ai/qianwenAI.js'
|
||||
import { DeepSeekAITranslator } from '../ai/deepseekAI.js'
|
||||
import config from '../../config/config.js'
|
||||
|
||||
/**
|
||||
* AI批量翻译适配器 - 用于处理大规模AI翻译服务
|
||||
*/
|
||||
export class AIBatchAdapter extends TranslationAdapter {
|
||||
constructor() {
|
||||
super()
|
||||
this.translator = new DeepSeekAITranslator(config.apiKey[config.translateMethod])
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染翻译名称
|
||||
* @returns {Promise<string>} 生成的唯一翻译名称
|
||||
*/
|
||||
renderTranslateName(index) {
|
||||
const timestamp = Date.now()
|
||||
return `t_${index}_${timestamp}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行AI批量翻译 - 包含错误重试机制
|
||||
* @param {string} text - 待翻译的文本内容
|
||||
* @param {string[]} languages - 目标语言列表
|
||||
* @param {number} maxRetries - 最大重试次数
|
||||
* @param {number} index - 翻译名称索引
|
||||
* @returns {Promise<{text: string, translations: Record<string, string}>} 翻译结果对象
|
||||
* @throws {Error} 当所有重试都失败时抛出错误
|
||||
*/
|
||||
async translate(text, languages, maxRetries, index) {
|
||||
let lastError = null
|
||||
let retryCount = 0
|
||||
while (retryCount <= maxRetries) {
|
||||
try {
|
||||
const result = await this.translator.translate({
|
||||
text,
|
||||
languages,
|
||||
})
|
||||
const key = this.renderTranslateName(index)
|
||||
return {
|
||||
text,
|
||||
key,
|
||||
translations: result.translations,
|
||||
}
|
||||
} catch (error) {
|
||||
lastError = error
|
||||
retryCount++
|
||||
// 如果还有重试机会,等待一段时间后重试
|
||||
if (retryCount <= maxRetries) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000 * retryCount))
|
||||
continue
|
||||
}
|
||||
|
||||
throw new Error(`AI批量翻译失败(已重试${retryCount}次) - ${lastError.message}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取AI翻译服务支持的语言列表
|
||||
* @returns {string[]} 支持的语言代码列表
|
||||
*/
|
||||
getSupportedLanguages() {
|
||||
return this.translator.getSupportedLanguages()
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证API密钥是否有效
|
||||
* @param {string} apiKey - 待验证的API密钥
|
||||
* @returns {Promise<boolean>} 密钥是否有效
|
||||
*/
|
||||
async validateApiKey(apiKey) {
|
||||
try {
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* 翻译适配器基类 - 用于统一不同翻译服务的接口实现
|
||||
*/
|
||||
export class TranslationAdapter {
|
||||
constructor() {
|
||||
if (this.constructor === TranslationAdapter) {
|
||||
throw new Error('翻译适配器:抽象类不能被直接实例化')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行翻译 - 将给定文本翻译为目标语言
|
||||
* @param {string} text - 待翻译的文本内容
|
||||
* @param {string} apiKey - 翻译服务的API密钥
|
||||
* @param {string[]} languages - 目标语言代码列表,如 ['enUS', 'jaJP']
|
||||
* @param {number} maxRetries - 翻译失败时的最大重试次数
|
||||
* @returns {Promise<{text: string, translations: Record<string, string}>} 翻译结果对象
|
||||
* @throws {Error} 当翻译失败且超过重试次数时抛出错误
|
||||
*/
|
||||
async translate(text, apiKey, languages, maxRetries) {
|
||||
throw new Error('翻译适配器:translate 方法必须在子类中实现')
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前适配器支持的语言列表
|
||||
* @returns {string[]} 支持的语言代码列表
|
||||
*/
|
||||
getSupportedLanguages() {
|
||||
throw new Error('翻译适配器:getSupportedLanguages 方法必须在子类中实现')
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查指定语言是否被当前适配器支持
|
||||
* @param {string} language - 需要检查的语言代码
|
||||
* @returns {boolean} 是否支持该语言
|
||||
*/
|
||||
isLanguageSupported(language) {
|
||||
return this.getSupportedLanguages().includes(language)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import { TranslationAdapter } from './index.js'
|
||||
import { translate as traditionalApiTranslate } from '../traditional/api1.js'
|
||||
|
||||
/**
|
||||
* 传统API翻译适配器 - 用于适配常规REST API类型的翻译服务
|
||||
*/
|
||||
export class TraditionalApiAdapter extends TranslationAdapter {
|
||||
constructor(apiModule) {
|
||||
super()
|
||||
if (!apiModule?.translate || typeof apiModule.translate !== 'function') {
|
||||
throw new Error('传统API适配器:无效的API模块,必须提供translate方法')
|
||||
}
|
||||
this.apiModule = apiModule
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行翻译请求 - 将数据转换为传统API格式并处理响应
|
||||
* @param {string} text - 待翻译的文本内容
|
||||
* @param {string} apiKey - API密钥
|
||||
* @param {string[]} languages - 目标语言列表
|
||||
* @param {number} maxRetries - 最大重试次数
|
||||
* @returns {Promise<{text: string, translations: Record<string, string>}>} 标准化的翻译结果
|
||||
* @throws {Error} 当翻译失败或语言不支持时抛出错误
|
||||
*/
|
||||
async translate(text, apiKey, languages, maxRetries) {
|
||||
// 检查所有目标语言是否支持
|
||||
for (const lang of languages) {
|
||||
if (!this.isLanguageSupported(lang)) {
|
||||
throw new Error(`传统API适配器:不支持的目标语言 "${lang}"`)
|
||||
}
|
||||
}
|
||||
|
||||
// 转换为API期望的请求格式
|
||||
const requestData = {
|
||||
text,
|
||||
apiKey,
|
||||
targetLanguages: languages,
|
||||
retryCount: maxRetries,
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await this.apiModule.translate(requestData)
|
||||
return {
|
||||
text,
|
||||
translations: result.translations,
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`传统API适配器:翻译失败 - ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取API支持的语言列表
|
||||
* @returns {string[]} 支持的语言代码数组
|
||||
*/
|
||||
getSupportedLanguages() {
|
||||
return this.apiModule.getSupportedLanguages?.() || []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
import axios from 'axios'
|
||||
import CryptoJS from 'crypto-js'
|
||||
import { Utils } from '../../utils/index.js'
|
||||
|
||||
export class DeepSeekAITranslator {
|
||||
constructor(apiKey) {
|
||||
this.apiKey = 'sk-cdhgecffemwndfqfiohtzhzkqxkjtstqflnoeoazqxzhfswd'
|
||||
this.baseURL = 'https://api.siliconflow.cn/v1/chat/completions'
|
||||
this.model = 'deepseek-ai/DeepSeek-V3'
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成翻译提示词
|
||||
* @param {string} text - 待翻译文本
|
||||
* @param {string[]} languages - 目标语言列表
|
||||
* @returns {string}
|
||||
*/
|
||||
generatePrompt(text, languages) {
|
||||
const targetLanguages = languages
|
||||
.map((code) => {
|
||||
const { language, region } = Utils.parseLanguageCode(code)
|
||||
return `${language}${region}`
|
||||
})
|
||||
.join(', ')
|
||||
|
||||
return `你是专业的翻译,根据用户提供的翻译文本,生成不同的翻译结果,请将以下文本翻译成${targetLanguages}多种语言,\r\n
|
||||
如果翻译文本包含{riskNum}包裹的字符,保持{}和包裹的字符,以及翻译文本本身是英文的时候,直接跳过翻译,输出原文按当前格式返回即可,\r\n
|
||||
其他的内容继续翻译,返回JSON格式,注意要严格按照JSON格式返回,返回前先检查是否符合JSON格式,字符串内部不能有换行,输出格式示例:\n{
|
||||
"zhCN": "中文",
|
||||
"enUS": "English"
|
||||
}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用智谱AI进行翻译
|
||||
* @param {string} text - 待翻译文本
|
||||
* @param {string[]} languages - 目标语言列表
|
||||
* @returns {Promise<{text: string, translations: Object}>}
|
||||
*/
|
||||
async translate({ text, languages }) {
|
||||
try {
|
||||
const translations = {}
|
||||
// 判断当前翻译内容是否为纯英文,如果是,则直接返回原文
|
||||
if (/^[\x00-\x7F]*$/.test(text)) {
|
||||
for (const code of languages) {
|
||||
translations[code] = text
|
||||
}
|
||||
} else {
|
||||
const prompt = this.generatePrompt(text, languages)
|
||||
|
||||
const response = await axios({
|
||||
method: 'post',
|
||||
url: this.baseURL,
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: {
|
||||
model: this.model,
|
||||
messages: [
|
||||
{
|
||||
role: 'system',
|
||||
content: prompt,
|
||||
},
|
||||
{ role: 'user', content: `翻译文本:${text}` },
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
if (!response.data || !response.data.choices || !response.data.choices[0]) {
|
||||
throw new Error('无效的API响应')
|
||||
}
|
||||
|
||||
// 解析智谱AI翻译结果
|
||||
const rawTranslations = this.parseTranslations(response.data.choices[0].message.content)
|
||||
|
||||
// console.log(rawTranslations, text)
|
||||
// 转换语言代码格式
|
||||
for (const [code, value] of Object.entries(rawTranslations)) {
|
||||
translations[code] = value
|
||||
}
|
||||
}
|
||||
return {
|
||||
text,
|
||||
translations: Utils.formatTranslations(translations),
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`DeepSeek-V3翻译失败: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析智谱AI翻译结果,转换为标准格式
|
||||
* @param {string} text - 待翻译文本
|
||||
* @returns {Object} - 标准格式的翻译结果
|
||||
*/
|
||||
parseTranslations(text) {
|
||||
text = text.replace('```json\n', '').replace('```', '')
|
||||
return JSON.parse(text)
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查API密钥是否有效
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async validateApiKey() {
|
||||
try {
|
||||
await axios.get(`${this.baseURL}/validate`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.apiKey}`,
|
||||
},
|
||||
})
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default DeepSeekAITranslator
|
||||
145
frontend/plugin/vite-plugin-i18n/src/translation/ai/qianwenAI.js
Normal file
145
frontend/plugin/vite-plugin-i18n/src/translation/ai/qianwenAI.js
Normal file
@@ -0,0 +1,145 @@
|
||||
import axios from 'axios'
|
||||
import CryptoJS from 'crypto-js'
|
||||
import { Utils } from '../../utils/index.js'
|
||||
|
||||
export class QianwenAITranslator {
|
||||
constructor(apiKey) {
|
||||
this.apiKey = apiKey
|
||||
this.baseURL = 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions'
|
||||
this.model = 'qwen-max'
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成翻译提示词
|
||||
* @param {string} text - 待翻译文本
|
||||
* @param {string[]} languages - 目标语言列表
|
||||
* @returns {string}
|
||||
*/
|
||||
generatePrompt(text, languages) {
|
||||
const targetLanguages = languages
|
||||
.map((code) => {
|
||||
const { language, region } = Utils.parseLanguageCode(code)
|
||||
return `${language}${region}`
|
||||
})
|
||||
.join(', ')
|
||||
|
||||
return `你是专业的翻译,根据用户提供的翻译文本,生成不同的翻译结果,请将以下文本翻译成${targetLanguages}多种语言,\r\n
|
||||
如果翻译文本包含{riskNum}包裹的字符,保持{}和包裹的字符,以及翻译文本本身是英文的时候,直接跳过翻译,输出原文按当前格式返回即可,\r\n
|
||||
其他的内容继续翻译,返回JSON格式,注意要严格按照JSON格式返回,返回前先检查是否符合JSON格式,字符串内部不能有换行,输出格式示例:\n{
|
||||
"zhCN": "中文",
|
||||
"enUS": "English"
|
||||
}`
|
||||
}
|
||||
|
||||
// 生成智谱AI API所需的JWT token
|
||||
async getToken() {
|
||||
const [id, secret] = this.apiKey.split('.')
|
||||
const header = { alg: 'HS256', sign_type: 'SIGN' }
|
||||
const payload = {
|
||||
api_key: id,
|
||||
exp: Math.floor(Date.now() / 1000) + 3600,
|
||||
timestamp: Math.floor(Date.now() / 1000),
|
||||
}
|
||||
const headerBase64 = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(JSON.stringify(header))).replace(
|
||||
/=/g,
|
||||
'',
|
||||
)
|
||||
const payloadBase64 = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(JSON.stringify(payload))).replace(
|
||||
/=/g,
|
||||
'',
|
||||
)
|
||||
|
||||
const signature = CryptoJS.enc.Base64.stringify(
|
||||
CryptoJS.HmacSHA256(`${headerBase64}.${payloadBase64}`, secret),
|
||||
).replace(/=/g, '')
|
||||
return `${headerBase64}.${payloadBase64}.${signature}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用智谱AI进行翻译
|
||||
* @param {string} text - 待翻译文本
|
||||
* @param {string[]} languages - 目标语言列表
|
||||
* @returns {Promise<{text: string, translations: Object}>}
|
||||
*/
|
||||
async translate({ text, languages }) {
|
||||
try {
|
||||
const translations = {}
|
||||
// 判断当前翻译内容是否为纯英文,如果是,则直接返回原文
|
||||
if (/^[\x00-\x7F]*$/.test(text)) {
|
||||
for (const code of languages) {
|
||||
translations[code] = text
|
||||
}
|
||||
} else {
|
||||
const prompt = this.generatePrompt(text, languages)
|
||||
// const token = await this.getToken()
|
||||
|
||||
const response = await axios({
|
||||
method: 'post',
|
||||
url: this.baseURL,
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: {
|
||||
model: this.model,
|
||||
messages: [
|
||||
{
|
||||
role: 'system',
|
||||
content: prompt,
|
||||
},
|
||||
{ role: 'user', content: `翻译文本:${text}` },
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
if (!response.data || !response.data.choices || !response.data.choices[0]) {
|
||||
throw new Error('无效的API响应')
|
||||
}
|
||||
|
||||
// 解析智谱AI翻译结果
|
||||
const rawTranslations = this.parseTranslations(response.data.choices[0].message.content)
|
||||
|
||||
// console.log(rawTranslations, text)
|
||||
// 转换语言代码格式
|
||||
for (const [code, value] of Object.entries(rawTranslations)) {
|
||||
translations[code] = value
|
||||
}
|
||||
}
|
||||
return {
|
||||
text,
|
||||
translations: Utils.formatTranslations(translations),
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`千问AI翻译失败: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析智谱AI翻译结果,转换为标准格式
|
||||
* @param {string} text - 待翻译文本
|
||||
* @returns {Object} - 标准格式的翻译结果
|
||||
*/
|
||||
parseTranslations(text) {
|
||||
text = text.replace('```json\n', '').replace('```', '')
|
||||
return JSON.parse(text)
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查API密钥是否有效
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async validateApiKey() {
|
||||
try {
|
||||
await axios.get(`${this.baseURL}/validate`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.apiKey}`,
|
||||
},
|
||||
})
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default QianwenAITranslator
|
||||
145
frontend/plugin/vite-plugin-i18n/src/translation/ai/zhipuAI.js
Normal file
145
frontend/plugin/vite-plugin-i18n/src/translation/ai/zhipuAI.js
Normal file
@@ -0,0 +1,145 @@
|
||||
import axios from 'axios'
|
||||
import CryptoJS from 'crypto-js'
|
||||
import { Utils } from '../../utils/index.js'
|
||||
|
||||
export class ZhipuAITranslator {
|
||||
constructor(apiKey) {
|
||||
this.apiKey = apiKey
|
||||
this.baseURL = 'https://open.bigmodel.cn/api/paas/v4/chat/completions'
|
||||
this.model = 'glm-4-flash'
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成翻译提示词
|
||||
* @param {string} text - 待翻译文本
|
||||
* @param {string[]} languages - 目标语言列表
|
||||
* @returns {string}
|
||||
*/
|
||||
generatePrompt(text, languages) {
|
||||
const targetLanguages = languages
|
||||
.map((code) => {
|
||||
const { language, region } = Utils.parseLanguageCode(code)
|
||||
return `${language}${region}`
|
||||
})
|
||||
.join(', ')
|
||||
|
||||
return `你是专业的翻译,根据用户提供的翻译文本,生成不同的翻译结果,请将以下文本翻译成${targetLanguages}多种语言,\r\n
|
||||
如果翻译文本包含{riskNum}包裹的字符,保持{}和包裹的字符,以及翻译文本本身是英文的时候,直接跳过翻译,输出原文按当前格式返回即可,\r\n
|
||||
其他的内容继续翻译,返回JSON格式,注意要严格按照JSON格式返回,返回前先检查是否符合JSON格式,字符串内部不能有换行,输出格式示例:\n{
|
||||
"zhCN": "中文",
|
||||
"enUS": "English"
|
||||
}`
|
||||
}
|
||||
|
||||
// 生成智谱AI API所需的JWT token
|
||||
async getToken() {
|
||||
const [id, secret] = this.apiKey.split('.')
|
||||
const header = { alg: 'HS256', sign_type: 'SIGN' }
|
||||
const payload = {
|
||||
api_key: id,
|
||||
exp: Math.floor(Date.now() / 1000) + 3600,
|
||||
timestamp: Math.floor(Date.now() / 1000),
|
||||
}
|
||||
const headerBase64 = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(JSON.stringify(header))).replace(
|
||||
/=/g,
|
||||
'',
|
||||
)
|
||||
const payloadBase64 = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(JSON.stringify(payload))).replace(
|
||||
/=/g,
|
||||
'',
|
||||
)
|
||||
|
||||
const signature = CryptoJS.enc.Base64.stringify(
|
||||
CryptoJS.HmacSHA256(`${headerBase64}.${payloadBase64}`, secret),
|
||||
).replace(/=/g, '')
|
||||
return `${headerBase64}.${payloadBase64}.${signature}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用智谱AI进行翻译
|
||||
* @param {string} text - 待翻译文本
|
||||
* @param {string[]} languages - 目标语言列表
|
||||
* @returns {Promise<{text: string, translations: Object}>}
|
||||
*/
|
||||
async translate({ text, languages }) {
|
||||
try {
|
||||
const translations = {}
|
||||
// 判断当前翻译内容是否为纯英文,如果是,则直接返回原文
|
||||
if (/^[\x00-\x7F]*$/.test(text)) {
|
||||
for (const code of languages) {
|
||||
translations[code] = text
|
||||
}
|
||||
} else {
|
||||
const prompt = this.generatePrompt(text, languages)
|
||||
const token = await this.getToken()
|
||||
|
||||
const response = await axios({
|
||||
method: 'post',
|
||||
url: this.baseURL,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: {
|
||||
model: this.model,
|
||||
messages: [
|
||||
{
|
||||
role: 'system',
|
||||
content: prompt,
|
||||
},
|
||||
{ role: 'user', content: `翻译文本:${text}` },
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
if (!response.data || !response.data.choices || !response.data.choices[0]) {
|
||||
throw new Error('无效的API响应')
|
||||
}
|
||||
|
||||
// 解析智谱AI翻译结果
|
||||
const rawTranslations = this.parseTranslations(response.data.choices[0].message.content)
|
||||
|
||||
// console.log(rawTranslations, text)
|
||||
// 转换语言代码格式
|
||||
for (const [code, value] of Object.entries(rawTranslations)) {
|
||||
translations[code] = value
|
||||
}
|
||||
}
|
||||
return {
|
||||
text,
|
||||
translations: Utils.formatTranslations(translations),
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`智谱AI翻译失败: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析智谱AI翻译结果,转换为标准格式
|
||||
* @param {string} text - 待翻译文本
|
||||
* @returns {Object} - 标准格式的翻译结果
|
||||
*/
|
||||
parseTranslations(text) {
|
||||
text = text.replace('```json\n', '').replace('```', '')
|
||||
return JSON.parse(text)
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查API密钥是否有效
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async validateApiKey() {
|
||||
try {
|
||||
await axios.get(`${this.baseURL}/validate`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.apiKey}`,
|
||||
},
|
||||
})
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default ZhipuAITranslator
|
||||
@@ -0,0 +1,85 @@
|
||||
import axios from 'axios'
|
||||
|
||||
export class TraditionalApi1 {
|
||||
constructor() {
|
||||
this.baseURL = 'https://api.example.com/translate'
|
||||
this.supportedLanguages = ['zhCN', 'zhTW', 'enUS', 'jaJP', 'koKR']
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行翻译
|
||||
* @param {Object} requestData - 请求数据
|
||||
* @returns {Promise<{translations: Object}>}
|
||||
*/
|
||||
async translate(requestData) {
|
||||
const { text, apiKey, languages } = requestData
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
this.baseURL,
|
||||
{
|
||||
q: text,
|
||||
target: languages.map((lang) => this.formatLanguageCode(lang)),
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
if (!response.data || !response.data.translations) {
|
||||
throw new Error('无效的API响应')
|
||||
}
|
||||
|
||||
// 转换响应格式
|
||||
const translations = {}
|
||||
response.data.translations.forEach((translation, index) => {
|
||||
translations[languages[index]] = translation.text
|
||||
})
|
||||
|
||||
return { translations }
|
||||
} catch (error) {
|
||||
throw new Error(`API请求失败: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证API密钥
|
||||
* @param {string} apiKey - API密钥
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async validateApiKey(apiKey) {
|
||||
try {
|
||||
await axios.get(`${this.baseURL}/validate`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${apiKey}`,
|
||||
},
|
||||
})
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支持的语言列表
|
||||
* @returns {string[]}
|
||||
*/
|
||||
getSupportedLanguages() {
|
||||
return this.supportedLanguages
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化语言代码
|
||||
* @param {string} code - 语言代码
|
||||
* @returns {string}
|
||||
*/
|
||||
formatLanguageCode(code) {
|
||||
return `${code.slice(0, 2).toLowerCase()}-${code.slice(2).toUpperCase()}`
|
||||
}
|
||||
}
|
||||
|
||||
export const api1 = new TraditionalApi1()
|
||||
export default api1
|
||||
Reference in New Issue
Block a user