452 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			452 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE html>
 | ||
| <html lang="en">
 | ||
|   <head>
 | ||
|     <meta charset="UTF-8" />
 | ||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 | ||
|     <meta http-equiv="X-UA-Compatible" content="ie=edge" />
 | ||
|     <meta name="baidu-site-verification" content="codeva-bhaFvYlfgd" />
 | ||
|     <meta
 | ||
|       name="keywords"
 | ||
|       content="deepl、deepl翻译、百度翻译、谷歌翻译、腾讯翻译君"
 | ||
|     />
 | ||
|     <meta
 | ||
|       name="description"
 | ||
|       content="聚合翻译提供即时免费的中文、英语、日语、韩语、法语、德语、俄语、西班牙语、葡萄牙语、越南语、印尼语、意大利语、荷兰语、泰语全文翻译等服务。"
 | ||
|     />
 | ||
|     <meta name="baidu-site-verification" content="codeva-mXz3BqI9VN" />
 | ||
|     <link rel="stylesheet" href="static/css/public.css" />
 | ||
|     <link rel="stylesheet" href="static/css/layui.css" />
 | ||
|     <script src="static/js/jquery-1.11.0.min.js"></script>
 | ||
|     <script src="static/js/axios.min.js"></script>
 | ||
|     <script src="static/js/countUp.min.js"></script>
 | ||
|     <script src="static/js/vue.js"></script>
 | ||
|     <script src="static/js/lodash.min.js"></script>
 | ||
|     <script src="static/js/layui.all.js"></script>
 | ||
|     <script src="static/js/common.js"></script>
 | ||
|     <title>聚合翻译</title>
 | ||
|     <script>
 | ||
|       var _hmt = _hmt || [];
 | ||
|       (function () {
 | ||
|         var hm = document.createElement("script");
 | ||
|         hm.src = "https://hm.baidu.com/hm.js?c4e0dd6add63dd71fa52870120ca22cf";
 | ||
|         var s = document.getElementsByTagName("script")[0];
 | ||
|         s.parentNode.insertBefore(hm, s);
 | ||
|       })();
 | ||
|     </script>
 | ||
|   </head>
 | ||
|   <body>
 | ||
|     <div class="public-header normal" id="main">
 | ||
|       <div class="container clearfix">
 | ||
|         <div class="left">
 | ||
|           <img class="logo default" src="static/picture/logo.png" alt="" /><img
 | ||
|             class="logo1 default"
 | ||
|             src="static/picture/logo1.png"
 | ||
|             alt=""
 | ||
|           /><img class="logo light" src="static/picture/logow.png" alt="" /><img
 | ||
|             class="logo1 light"
 | ||
|             src="static/picture/logo1w.png"
 | ||
|             alt=""
 | ||
|           />
 | ||
|           <div class="nav">
 | ||
|             <a class="" href="index.html"><span>首页</span></a
 | ||
|             ><a class="active" href=""><span>文本翻译</span></a
 | ||
|             ><a class="" href="voice.html"><span>语音翻译</span></a
 | ||
|             ><a class="" href="api.html"><span>API文档</span></a
 | ||
|             ><a class="" href="commonProblems.html"><span>常见问题</span></a>
 | ||
|           </div>
 | ||
|         </div>
 | ||
|         <div v-if="userInfo!=undefined&&userInfo.userId>0" class="right">
 | ||
|           <a href="userinfo.html" class="console">控制台</a>
 | ||
|           <div class="user-info">
 | ||
|             <div class="phone">{{userInfo.name}}</div>
 | ||
|             <i></i>
 | ||
|             <div class="log-out" @click="logOut">退出</div>
 | ||
|           </div>
 | ||
|         </div>
 | ||
|         <div v-else class="right">
 | ||
|           <a class="unlogin" href="login.html">登录</a>
 | ||
|         </div>
 | ||
|       </div>
 | ||
|       <div class="bg"></div>
 | ||
|     </div>
 | ||
|     <script type="text/javascript">
 | ||
|       var vm = new Vue({
 | ||
|         el: "#main",
 | ||
|         data() {
 | ||
|           return {
 | ||
|             userInfo: {},
 | ||
|             token: "",
 | ||
|           };
 | ||
|         },
 | ||
|         created() {},
 | ||
|         mounted() {
 | ||
|           let token = localStorage.getItem("token");
 | ||
|           if (token) {
 | ||
|             this.token = token;
 | ||
|             this.getUserInfo(token);
 | ||
|           } else {
 | ||
|             // location.href = "login.html";
 | ||
|           }
 | ||
|         },
 | ||
|         methods: {
 | ||
|           logOut() {
 | ||
|             axios
 | ||
|               .post("/logout", {
 | ||
|                 headers: {
 | ||
|                   Authorization: `Bearer ${this.token}`,
 | ||
|                 },
 | ||
|               })
 | ||
|               .then((response) => {
 | ||
|                 localStorage.removeItem("token");
 | ||
|                 location.reload();
 | ||
|               });
 | ||
|           },
 | ||
| 
 | ||
|           getUserInfo(token) {
 | ||
|             let that = this;
 | ||
|             axios
 | ||
|               .get("/getinfo", {
 | ||
|                 headers: {
 | ||
|                   Authorization: `Bearer ${this.token}`,
 | ||
|                 },
 | ||
|               })
 | ||
|               .then((response) => {
 | ||
|                 if (response.data.code === 200) {
 | ||
|                   this.userInfo = response.data.data;
 | ||
|                   console.log("userinfo", this.userInfo);
 | ||
|                 } else {
 | ||
|                   localStorage.removeItem("token");
 | ||
|                   location.href = "login.html";
 | ||
|                 }
 | ||
|               });
 | ||
|           },
 | ||
|         },
 | ||
|       });
 | ||
|     </script>
 | ||
|     <div class="page-translation" id="app">
 | ||
|       <div class="w1200">
 | ||
|         <div class="translation-engine">
 | ||
|           <div
 | ||
|             v-for="item in engineType"
 | ||
|             :key="item.key"
 | ||
|             class="item"
 | ||
|             :class="{ on: engine.key == item.key }"
 | ||
|             @click="onSelectEngine(item)"
 | ||
|           >
 | ||
|             <img :src="item.icon" alt="" />
 | ||
|           </div>
 | ||
|         </div>
 | ||
|         <div class="translation-row">
 | ||
|           <div class="translation-language" @mouseleave="languageShow = false">
 | ||
|             <div
 | ||
|               class="source"
 | ||
|               @mouseenter="() => onShowLanguage('100px', true, 'sourceLanguage')"
 | ||
|             >
 | ||
|               {{ sourceLanguage.name }}
 | ||
|               <div class="icon select-icon"></div>
 | ||
|             </div>
 | ||
|             <div
 | ||
|               class="target"
 | ||
|               @mouseenter="() => onShowLanguage('620px', true, 'targetLanguage')"
 | ||
|             >
 | ||
|               <div class="icon switch-icon" @click="onSwitch"></div>
 | ||
|               {{ targetLanguage.name }}
 | ||
|               <div class="icon select-icon"></div>
 | ||
|             </div>
 | ||
|             <div
 | ||
|               class="language-row"
 | ||
|               :class="{ show: languageShow }"
 | ||
|               :style="{ left: languageRowLeft }"
 | ||
|             >
 | ||
|               <div class="search">
 | ||
|                 <i class="icon"></i
 | ||
|                 ><input
 | ||
|                   type="text"
 | ||
|                   class="search-input"
 | ||
|                   v-model="serachKeywords"
 | ||
|                   placeholder="搜索你想要的"
 | ||
|                 />
 | ||
|               </div>
 | ||
|               <div class="row">
 | ||
|                 <div
 | ||
|                   v-for="(k, v) in languageCurrent"
 | ||
|                   :key="v"
 | ||
|                   :value="v"
 | ||
|                   class="col"
 | ||
|                   @click="onSelectLanguage(v)"
 | ||
|                   :class="{ on: sourceLanguage.key == v || targetLanguage.key == v }"
 | ||
|                 >
 | ||
|                   <span>{{ k }}</span>
 | ||
|                 </div>
 | ||
|               </div>
 | ||
|             </div>
 | ||
|           </div>
 | ||
|           <div class="translation-text">
 | ||
|             <div class="source">
 | ||
|               <textarea
 | ||
|                 cols="30"
 | ||
|                 rows="10"
 | ||
|                 v-model="sourceText"
 | ||
|                 placeholder="输入文字,即可翻译"
 | ||
|               ></textarea>
 | ||
|             </div>
 | ||
|             <div class="target">
 | ||
|               <textarea
 | ||
|                 disabled
 | ||
|                 cols="30"
 | ||
|                 rows="10"
 | ||
|                 v-model="targetText"
 | ||
|               ></textarea>
 | ||
|               <div class="loading" v-if="isLoading">
 | ||
|                 <img class="icon" src="static/picture/p17.png" alt="" />
 | ||
|                 <div>Loading...</div>
 | ||
|               </div>
 | ||
|               <div v-if="targetText" class="copy" @click="copy">复制</div>
 | ||
|             </div>
 | ||
|           </div>
 | ||
|         </div>
 | ||
|       </div>
 | ||
|     </div>
 | ||
|     <script src="static/js/lodash.min.js"></script>
 | ||
|     <script type="text/javascript">
 | ||
|       const CancelToken = axios.CancelToken;
 | ||
|       let source = CancelToken.source();
 | ||
|       new Vue({
 | ||
|         el: "#app",
 | ||
|         data() {
 | ||
|           return {
 | ||
|             engine: {},
 | ||
|             engineType: [
 | ||
|               {
 | ||
|                 key: "deepl",
 | ||
|                 value: 0,
 | ||
|                 icon: "https://codeai.oss-cn-hangzhou.aliyuncs.com/img/p2.png",
 | ||
|               },
 | ||
|               {
 | ||
|                 key: "google",
 | ||
|                 value: 1,
 | ||
|                 icon: "https://codeai.oss-cn-hangzhou.aliyuncs.com/img/p3.png",
 | ||
|               },
 | ||
|               {
 | ||
|                 key: "baidu",
 | ||
|                 value: 2,
 | ||
|                 icon: "https://codeai.oss-cn-hangzhou.aliyuncs.com/img/p4.png",
 | ||
|               },
 | ||
|               {
 | ||
|                 key: "youdao",
 | ||
|                 value: 3,
 | ||
|                 icon: "https://codeai.oss-cn-hangzhou.aliyuncs.com/img/youdao.png",
 | ||
|               },
 | ||
|               {
 | ||
|                 key: "bing",
 | ||
|                 value: 4,
 | ||
|                 icon: "https://codeai.oss-cn-hangzhou.aliyuncs.com/img/bing.png",
 | ||
|               },
 | ||
|               {
 | ||
|                 key: "huoshan",
 | ||
|                 value: 5,
 | ||
|                 icon: "https://codeai.oss-cn-hangzhou.aliyuncs.com/img/huoshan.png",
 | ||
|               },
 | ||
|               {
 | ||
|                 key: "chatgpt",
 | ||
|                 value: 6,
 | ||
|                 icon: "https://codeai.oss-cn-hangzhou.aliyuncs.com/img/openai.png",
 | ||
|               },
 | ||
|               {
 | ||
|                 key: "yandex",
 | ||
|                 value: 7,
 | ||
|                 icon: "https://codeai.oss-cn-hangzhou.aliyuncs.com/img/yandex.png",
 | ||
|               },
 | ||
|             ],
 | ||
|             sourceLanguage: {
 | ||
|               key: "auto",
 | ||
|               name: "自动检测",
 | ||
|             },
 | ||
|             targetLanguage: {
 | ||
|               key: "ZH",
 | ||
|               name: "中文(简体)",
 | ||
|             },
 | ||
|             sourceText: "",
 | ||
|             targetText: "",
 | ||
|             serachKeywords: "",
 | ||
|             languageShow: false,
 | ||
|             languageRowLeft: "100px",
 | ||
|             languageTotalData: {},
 | ||
|             isLoading: false,
 | ||
|           };
 | ||
|         },
 | ||
|         created() {
 | ||
|           this.engine = this.engineType[0];
 | ||
|           this.getLanguage();
 | ||
|         },
 | ||
|         mounted() {
 | ||
|           let token = localStorage.getItem("token");
 | ||
|           if (token) {
 | ||
|             this.token = token;
 | ||
|             this.getUserInfo(token);
 | ||
|           } else {
 | ||
|             // location.href = "login.html";
 | ||
|           }
 | ||
|         },
 | ||
|         watch: {
 | ||
|           sourceText(v) {
 | ||
|             if (v) {
 | ||
|               // _.debounce(this.translate, 500)
 | ||
|               this.translate();
 | ||
|             } else {
 | ||
|               source.cancel("取消请求");
 | ||
|               this.targetText = "";
 | ||
|             }
 | ||
|           },
 | ||
|         },
 | ||
|         computed: {
 | ||
|           languageCurrent() {
 | ||
|             const current = this.languageTotalData[this.engine.key];
 | ||
|             const copyCurrent = {};
 | ||
|             if (this.serachKeywords) {
 | ||
|               Object.keys(current).forEach((key) => {
 | ||
|                 // console.log('current[key]', current[key])
 | ||
|                 if (current[key].indexOf(this.serachKeywords) > -1) {
 | ||
|                   copyCurrent[key] = current[key];
 | ||
|                 }
 | ||
|               });
 | ||
|               return copyCurrent;
 | ||
|             }
 | ||
|             return this.languageTotalData[this.engine.key];
 | ||
|           },
 | ||
|         },
 | ||
|         methods: {
 | ||
|           copy() {
 | ||
|             // 模拟 输入框
 | ||
|             var cInput = document.createElement("input");
 | ||
|             cInput.value = this.targetText;
 | ||
|             document.body.appendChild(cInput);
 | ||
|             cInput.select(); // 选取文本框内容
 | ||
| 
 | ||
|             // 执行浏览器复制命令
 | ||
|             // 复制命令会将当前选中的内容复制到剪切板中(这里就是创建的input标签)
 | ||
|             // Input要在正常的编辑状态下原生复制方法才会生效
 | ||
| 
 | ||
|             document.execCommand("copy");
 | ||
|             layer.msg("复制成功");
 | ||
|             // 复制成功后再将构造的标签 移除
 | ||
|             document.body.removeChild(cInput);
 | ||
|           },
 | ||
|           onShowLanguage(left, boolean, key) {
 | ||
|             this.languageRowLeft = left ? left : "100px";
 | ||
|             this.languageShow = boolean;
 | ||
|             this.currentKey = key;
 | ||
|           },
 | ||
|           onSelectEngine(e) {
 | ||
|             this.engine = e;
 | ||
|             const firstEntry = Object.entries(this.languageCurrent)[0];
 | ||
|             this.targetLanguage = {
 | ||
|               key: firstEntry[0],
 | ||
|               name: this.languageCurrent[firstEntry[0]],
 | ||
|             };
 | ||
|             this.translate();
 | ||
|           },
 | ||
|           getLanguage() {
 | ||
|             axios.get("/api/translate/getLanguages").then((res) => {
 | ||
|               if (res.data.code == 1) {
 | ||
|                 this.languageTotalData = res.data.data;
 | ||
|               }
 | ||
|             });
 | ||
|           },
 | ||
|           translate: _.debounce(function () {
 | ||
|             source.cancel("取消请求");
 | ||
|             source = axios.CancelToken.source();
 | ||
|             const that = this;
 | ||
|             if (!this.sourceText) {
 | ||
|               that.targetText = "";
 | ||
|               return;
 | ||
|             }
 | ||
|             this.isLoading = true;
 | ||
|             axios
 | ||
|               .post(
 | ||
|                 "/api/translate/index",
 | ||
|                 {
 | ||
|                   keywords: this.sourceText,
 | ||
|                   targetLanguage: this.targetLanguage.key,
 | ||
|                   type: this.engine.value, // 0 :deepl, 1:谷歌 2:百度
 | ||
|                 },
 | ||
|                 { cancelToken: source.token }
 | ||
|               )
 | ||
|               .then(function (res) {
 | ||
|                 console.log(res.data.data.text);
 | ||
|                 if (res.data.code == 1) {
 | ||
|                   that.targetText = res.data.data.text;
 | ||
|                   if (!this.sourceText) {
 | ||
|                     this.targetText = "";
 | ||
|                   }
 | ||
|                 } else {
 | ||
|                   that.targetText = "";
 | ||
|                   layer.msg(res.data.info);
 | ||
|                 }
 | ||
|               })
 | ||
|               .catch(function (err) {
 | ||
|                 console.log(err);
 | ||
|               })
 | ||
|               .finally(() => {
 | ||
|                 this.isLoading = false;
 | ||
|               });
 | ||
|           }, 800),
 | ||
|           onSelectLanguage(e) {
 | ||
|             this[this.currentKey] = {
 | ||
|               key: e,
 | ||
|               name: this.languageCurrent[e],
 | ||
|             };
 | ||
|             this.languageShow = false;
 | ||
|             this.translate();
 | ||
|           },
 | ||
|           onSwitch() {
 | ||
|             const copySource = JSON.parse(JSON.stringify(this.sourceLanguage));
 | ||
|             const copyTarget = JSON.parse(JSON.stringify(this.targetLanguage));
 | ||
|             this.targetLanguage = copySource;
 | ||
|             this.sourceLanguage = copyTarget;
 | ||
|           },
 | ||
|           onInput(e) {
 | ||
|             if (this.sourceText) {
 | ||
|               // _.debounce(this.translate, 500)
 | ||
|               this.translate();
 | ||
|             } else {
 | ||
|               this.targetText = "";
 | ||
|             }
 | ||
|           },
 | ||
|         },
 | ||
|       });
 | ||
|     </script>
 | ||
|     <div class="public-footer">
 | ||
|       <div class="w1200">
 | ||
|         <div class="left"><img src="static/picture/logo.png" alt="" /></div>
 | ||
|         <div
 | ||
|           style="
 | ||
|             flex-direction: column;
 | ||
|             line-height: 23px;
 | ||
|             padding-left: 100px;
 | ||
|             color: #fff;
 | ||
|             font-size: 12px;
 | ||
|           "
 | ||
|         >
 | ||
|           <p style="color: #fff; font-size: 12px"><span>官方频道:@apiapl_news</span></p>
 | ||
|           <p style="color: #fff; font-size: 12px"><span>咨询客服:@apiapl</span></p>
 | ||
|             <span></span>
 | ||
|           </p>
 | ||
|         </div>
 | ||
|         <div class="right" style="white-space: nowrap">
 | ||
|           <p></p>
 | ||
| 
 | ||
|           <p><span>技术服务:@apiapl_sdk</span></p>
 | ||
|           <p><span>联系邮箱:info@apiapl.com</span></p>
 | ||
|           <p class=""><span>联系电话:+18435173355 </span></p>
 | ||
|         </div>
 | ||
|       </div>
 | ||
|       <div class="copyright">
 | ||
|         <a href="https://beian.miit.gov.cn/" target="blank"
 | ||
|           ></a
 | ||
|         >
 | ||
|       </div>
 | ||
|     </div>
 | ||
|   </body>
 | ||
| </html>
 |