feat(typeartice.vue): add baidu translate

This commit is contained in:
zyronon
2023-09-10 23:52:59 +08:00
parent 7b1b82430a
commit f22a6fb322
7 changed files with 349 additions and 2 deletions

View File

@@ -24,6 +24,7 @@ import {useEventListener} from "@/hooks/useEvent.ts";
import TypeWord from "@/components/Practice/TypeWord.vue";
import {emitter, EventKey} from "@/utils/eventBus.ts";
import Baidu from "@opentranslate/baidu";
import {AxiosInstance} from "@/utils/http";
let article1 = `How does the older investor differ in his approach to investment from the younger investor?
There is no shortage of tipsters around offering 'get-rich-quick' opportunities. But if you are a serious private investor, leave the Las Vegas mentality to those with money to fritter. The serious investor needs a proper 'portfolio' -- a well-planned selection of investments, with a definite structure and a clear aim. But exactly how does a newcomer to the stock market go about achieving that?
@@ -96,12 +97,13 @@ onMounted(() => {
let sections = useSplitArticle(article.article)
let temp = useSplitCNArticle(article.articleTranslate, 'cn', CnKeyboardMap)
const baidu = new Baidu({
axios: AxiosInstance,
config: {
appid: "20230910001811857",
key: "Xxe_yftQR3K3Ue43NQMC"
}
})
baidu.translate('fuck', 'en','zh-CN').then(r => {
baidu.translate('fuck', 'en', 'zh-CN').then(r => {
console.log('s', r)
})
practiceStore.total = 0

View File

@@ -0,0 +1,146 @@
import {
Language,
Translator,
TranslateError,
TranslateQueryResult
} from "@opentranslate/translator";
import md5 from "md5";
import qs from "qs";
const langMap: [Language, string][] = [
["auto", "auto"],
["zh-CN", "zh"],
["en", "en"],
["yue", "yue"],
["wyw", "wyw"],
["ja", "jp"],
["ko", "kor"],
["fr", "fra"],
["es", "spa"],
["th", "th"],
["ar", "ara"],
["ru", "ru"],
["pt", "pt"],
["de", "de"],
["it", "it"],
["el", "el"],
["nl", "nl"],
["pl", "pl"],
["bg", "bul"],
["et", "est"],
["da", "dan"],
["fi", "fin"],
["cs", "cs"],
["ro", "rom"],
["sl", "slo"],
["sv", "swe"],
["hu", "hu"],
["zh-TW", "cht"],
["vi", "vie"]
];
export interface BaiduConfig {
placeholder?: string;
appid: string;
key: string;
}
export class BaiduTranslate {
readonly name = "baidu";
apiUrl = "https://api.fanyi.baidu.com/api/trans/vip/translate";
readonly endpoint = "https://api.fanyi.baidu.com/api/trans/vip/translate";
protected async query(
text: string,
from: Language,
to: Language,
config: BaiduConfig
): Promise<TranslateQueryResult> {
type BaiduTranslateError = {
error_code: "54001" | string;
error_msg: "Invalid Sign" | string;
};
type BaiduTranslateResult = {
from: string;
to: string;
trans_result: Array<{
dst: string;
src: string;
}>;
};
const salt = Date.now();
const {endpoint} = this;
const {appid, key} = config;
const res = await this.request<BaiduTranslateResult | BaiduTranslateError>(
endpoint,
{
params: {
from: Baidu.langMap.get(from),
to: Baidu.langMap.get(to),
q: text,
salt,
appid,
sign: md5(appid + text + salt + key)
}
}
).catch(() => {
throw new TranslateError("NETWORK_ERROR");
});
const {data} = res;
if ((data as BaiduTranslateError).error_code) {
console.error(
new Error("[Baidu service]" + (data as BaiduTranslateError).error_msg)
);
throw new TranslateError("API_SERVER_ERROR");
}
const {
trans_result: transResult,
from: langDetected
} = data as BaiduTranslateResult;
const transParagraphs = transResult.map(({dst}) => dst);
const detectedFrom = Baidu.langMapReverse.get(langDetected) as Language;
return {
text,
from: detectedFrom,
to,
origin: {
paragraphs: transResult.map(({src}) => src),
tts: await this.textToSpeech(text, detectedFrom)
},
trans: {
paragraphs: transParagraphs,
tts: await this.textToSpeech(transParagraphs.join(" "), to)
}
};
}
/** Translator lang to custom lang */
private static readonly langMap = new Map(langMap);
/** Custom lang to translator lang */
private static readonly langMapReverse = new Map(
langMap.map(([translatorLang, lang]) => [lang, translatorLang])
);
getSupportLanguages(): Language[] {
return [...Baidu.langMap.keys()];
}
async textToSpeech(text: string, lang: Language): Promise<string> {
return `https://fanyi.baidu.com/gettts?${qs.stringify({
lan: Baidu.langMap.get(lang !== "auto" ? lang : "zh-CN") || "zh",
text,
spd: 5,
})}`;
}
}
export default Baidu;

114
src/utils/http.ts Normal file
View File

@@ -0,0 +1,114 @@
import axios from 'axios'
// import globalMethods from './global-methods'
// import Config from '../config/index'
// import CONSTANT from './const_var'
// import store from '../store'
// import Storage from './storage'
export const AxiosInstance = axios.create({
// baseURL: process.env.NODE_ENV === 'production' ? Config.PRODUCT_API_URL : Config.API_URL,
// baseURL: 'http://testtestgp.com',
timeout: 15000,
})
// request 拦截器
AxiosInstance.interceptors.request.use(
(config) => {
console.log('config', config)
if (config.url === 'https://api.fanyi.baidu.com/api/trans/vip/translate'){
config.url = '/baidu'
}
return config
},
error => Promise.reject(error),
)
// respone 拦截器
// instance.interceptors.response.use(
// // 响应正常的处理
// (response) => {
// // console.log(response)
// // console.log(response.data)
// const { data } = response
// if (response.status !== 200) {
// globalMethods.$warning(response.statusText)
// return Promise.reject(data)
// }
// if (data === null) {
// return Promise.resolve({
// code: '009900',
// msg: '系统出现错误',
// data: {},
// })
// }
// return Promise.resolve(data)
// },
// // 请求出错的处理
// (error) => {
// console.log(error)
// if (error.response === undefined && error.status === undefined) {
// return Promise.resolve({
// code: '009900',
// msg: '服务器响应超时',
// data: null,
// })
// }
// if (error.response.status >= 500) {
// return Promise.resolve({
// code: '009900',
// msg: '服务器出现错误',
// data: null,
// })
// }
// if (error.response.status === 401) {
// return Promise.resolve({
// code: '009900',
// msg: '用户名或密码不正确',
// data: null,
// })
// }
// const { data } = error.response
// if (data.code !== undefined) {
// return Promise.resolve({
// code: data.code,
// msg: data.msg,
// })
// }
// return Promise.resolve({
// code: '009900',
// msg: data.msg,
// data: null,
// })
// },
// )
/**
* @apiDescription 封装的网络请求方法
* @apiGroup
* @apiName request
* @apiParam url 地址
* @apiParam data 请求数据
* @apiParam params 请求参数
* @apiParam method 方法类型get或者post
* @apiParam version 接口版本号
* @apiParamExample
* request('Appointment/appointmentList', data, params, CONSTANT.GET)
* @apiReturn Promise
*/
// async function request(url, data = {}, params = {}, method = CONSTANT.POST, version = Config.API_VERSION) {
// // console.log(url)
// if (method === CONSTANT.POST) {
// data.userId = store.state.user.userInfo === null ? '' : store.state.user.userInfo.id
// } else {
// params.userId = store.state.user.userInfo === null ? '' : store.state.user.userInfo.id
// }
// return instance({
// url: version + url,
// method,
// data,
// params,
// })
// }
// export default request