| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  | <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/translate/css/public.css?v=4"> --> | 
					
						
							|  |  |  |  |     <link rel="stylesheet" href="static/css/layui.css" /> | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |      <!-- <link rel="stylesheet" href="static/js/css/buefy.min.css"> --> | 
					
						
							|  |  |  |  |      | 
					
						
							| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  |     <script src="static/js/jquery-1.11.0.min.js"></script> | 
					
						
							|  |  |  |  |     <script src="static/js/axios.min.js"></script> | 
					
						
							|  |  |  |  |     <script src="static/translate/js/echarts.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> | 
					
						
							|  |  |  |  |     <script src="https://cdn.jsdelivr.net/npm/qrcode@1.4.4/build/qrcode.min.js"></script> | 
					
						
							|  |  |  |  |     <script src="static/js/countdown.js"></script> | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |      | 
					
						
							|  |  |  |  |     <!-- <script src="static/js/buefy.min.js"></script> --> | 
					
						
							| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  |     <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 id="main" class="public-header normal"> | 
					
						
							|  |  |  |  |       <div class="container clearfix"> | 
					
						
							|  |  |  |  |         <div class="left"> | 
					
						
							|  |  |  |  |           <img | 
					
						
							|  |  |  |  |             src="https://codeai.oss-cn-hangzhou.aliyuncs.com/img/logo.png" | 
					
						
							|  |  |  |  |             alt="" | 
					
						
							|  |  |  |  |             class="logo default" | 
					
						
							|  |  |  |  |           /><img | 
					
						
							|  |  |  |  |             src="https://codeai.oss-cn-hangzhou.aliyuncs.com/img/logo1.png" | 
					
						
							|  |  |  |  |             alt="" | 
					
						
							|  |  |  |  |             class="logo1 default" | 
					
						
							|  |  |  |  |           /><img | 
					
						
							|  |  |  |  |             src="https://codeai.oss-cn-hangzhou.aliyuncs.com/img/logow.png" | 
					
						
							|  |  |  |  |             alt="" | 
					
						
							|  |  |  |  |             class="logo light" | 
					
						
							|  |  |  |  |           /><img | 
					
						
							|  |  |  |  |             src="https://codeai.oss-cn-hangzhou.aliyuncs.com/img/logo1w.png" | 
					
						
							|  |  |  |  |             alt="" | 
					
						
							|  |  |  |  |             class="logo1 light" | 
					
						
							|  |  |  |  |           /> | 
					
						
							|  |  |  |  |           <div class="nav"> | 
					
						
							|  |  |  |  |             <a class="" href="index.html"><span>首页</span></a | 
					
						
							|  |  |  |  |             ><a class="" href="onlineTranslation.html"><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> | 
					
						
							|  |  |  |  |     <style> | 
					
						
							|  |  |  |  |       .page-console { | 
					
						
							|  |  |  |  |         height: auto !important; | 
					
						
							|  |  |  |  |         padding-bottom: 16px; | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |       .range-picker { | 
					
						
							|  |  |  |  |         display: flex; | 
					
						
							|  |  |  |  |         align-items: center; | 
					
						
							|  |  |  |  |         justify-content: flex-end; | 
					
						
							|  |  |  |  |         margin: 40px auto 0; | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |       .range-picker .col { | 
					
						
							|  |  |  |  |         margin-right: 16px; | 
					
						
							|  |  |  |  |         font-size: 16px; | 
					
						
							|  |  |  |  |         color: #333; | 
					
						
							|  |  |  |  |         cursor: pointer; | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |       .range-picker .col.on { | 
					
						
							|  |  |  |  |         color: #2578ff; | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |     </style> | 
					
						
							|  |  |  |  |     <div id="app" class="page-console" style="padding-top: 90px"> | 
					
						
							|  |  |  |  |       <div class="id-container"> | 
					
						
							|  |  |  |  |         <div class="user-id-container"> | 
					
						
							|  |  |  |  |           <img | 
					
						
							|  |  |  |  |             src="https://codeai.oss-cn-hangzhou.aliyuncs.com/img/pay.png" | 
					
						
							|  |  |  |  |             class="user-id-icon" | 
					
						
							|  |  |  |  |           /><span class="user-id-text">用户ID : {{userInfo.userId}}</span> | 
					
						
							|  |  |  |  |         </div> | 
					
						
							|  |  |  |  |       </div> | 
					
						
							|  |  |  |  |       <div class="tab-container"> | 
					
						
							|  |  |  |  |         <!-- <div class="tabs">
 | 
					
						
							|  |  |  |  |           <div class="tab on">文本翻译</div> | 
					
						
							|  |  |  |  |           <div class="tab">语音翻译</div> | 
					
						
							|  |  |  |  |         </div> --> | 
					
						
							|  |  |  |  |         <div id="text-translation" class="w1200 transUserinfo"> | 
					
						
							|  |  |  |  |           <h5>使用情况</h5> | 
					
						
							|  |  |  |  |           <div class="line"></div> | 
					
						
							|  |  |  |  |           <div class="table-row"> | 
					
						
							|  |  |  |  |             <div class="col"> | 
					
						
							|  |  |  |  |               <div class="cell"><span>翻译引擎</span></div> | 
					
						
							|  |  |  |  |               <div class="cell"><span>已使用字符数</span></div> | 
					
						
							|  |  |  |  |               <div class="cell"><span>剩余字符数</span></div> | 
					
						
							|  |  |  |  |               <div class="cell"><span>价格(U/百万字符)</span></div> | 
					
						
							|  |  |  |  |               <div class="cell"><span>操作</span></div> | 
					
						
							|  |  |  |  |             </div> | 
					
						
							|  |  |  |  |             <div | 
					
						
							|  |  |  |  |               class="col" | 
					
						
							|  |  |  |  |               v-for="(item,index) in translateInfos" | 
					
						
							|  |  |  |  |               :key="'platform_'+index" | 
					
						
							|  |  |  |  |             > | 
					
						
							|  |  |  |  |               <div class="cell"><span>{{item.name}}</span></div> | 
					
						
							|  |  |  |  |               <div class="cell"><span>{{item.useChars}}</span></div> | 
					
						
							|  |  |  |  |               <div class="cell"> | 
					
						
							|  |  |  |  |                 <span>{{item.remainChars}}</span> | 
					
						
							|  |  |  |  |                 <img v-if="item.remainChars>0" class="btn-clock" @click="showRecord(item.platformId,index)" src="static/image/clock.png"/> | 
					
						
							|  |  |  |  |               </div> | 
					
						
							|  |  |  |  |               <div class="cell"><span>{{item.price}}</span></div> | 
					
						
							|  |  |  |  |               <div class="cell"> | 
					
						
							|  |  |  |  |                 <div class="act"> | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |                   <span class="recharge" @click="show(item)">充值</span | 
					
						
							| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  |                   ><span class="view" @click="look(item.apiKey,index)" | 
					
						
							|  |  |  |  |                     >查看API密钥</span | 
					
						
							|  |  |  |  |                   > | 
					
						
							|  |  |  |  |                 </div> | 
					
						
							|  |  |  |  |               </div> | 
					
						
							|  |  |  |  |             </div> | 
					
						
							|  |  |  |  |           </div> | 
					
						
							|  |  |  |  |           <div class="warn">备注:技术问题,请联系客服。</div> | 
					
						
							|  |  |  |  |           <div class="clearfix" style="height: 361px"> | 
					
						
							|  |  |  |  |             <!-- <div class="range-picker">
 | 
					
						
							|  |  |  |  |               <div class="col on">近7天</div> | 
					
						
							|  |  |  |  |               <div class="col">近15天</div> | 
					
						
							|  |  |  |  |               <div class="col">近30天</div> | 
					
						
							|  |  |  |  |             </div> --> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             <div class="chart-container-wrapper"> | 
					
						
							|  |  |  |  |               <!-- ECharts 图表将渲染到这个 div 中 --> | 
					
						
							|  |  |  |  |               <div id="mainEchart" class="echarts-chart-direct"></div> | 
					
						
							|  |  |  |  |             </div> | 
					
						
							|  |  |  |  |           </div> | 
					
						
							|  |  |  |  |         </div> | 
					
						
							|  |  |  |  |         <div | 
					
						
							|  |  |  |  |           id="voice-translation" | 
					
						
							|  |  |  |  |           class="w1200 transUserinfo" | 
					
						
							|  |  |  |  |           style="display: none" | 
					
						
							|  |  |  |  |         > | 
					
						
							|  |  |  |  |           <div class="header-container"> | 
					
						
							|  |  |  |  |             <div class="title-section"> | 
					
						
							|  |  |  |  |               <h5>使用情况</h5> | 
					
						
							|  |  |  |  |               <div class="api-key"> | 
					
						
							|  |  |  |  |                 <span>密钥:</span | 
					
						
							|  |  |  |  |                 ><button class="copy-btn" style="display: none">复制</button> | 
					
						
							|  |  |  |  |               </div> | 
					
						
							|  |  |  |  |             </div> | 
					
						
							|  |  |  |  |             <div class="balance-section"> | 
					
						
							|  |  |  |  |               <div class="balance">剩余金额:0元</div> | 
					
						
							|  |  |  |  |               <button class="recharge-btn">充值</button> | 
					
						
							|  |  |  |  |             </div> | 
					
						
							|  |  |  |  |           </div> | 
					
						
							|  |  |  |  |           <div class="line"></div> | 
					
						
							|  |  |  |  |           <div class="table-container table-row"> | 
					
						
							|  |  |  |  |             <div class="grid-header col"> | 
					
						
							|  |  |  |  |               <div class="cell" style="width: 180px">翻译引擎</div> | 
					
						
							|  |  |  |  |               <div class="cell">服务类型</div> | 
					
						
							|  |  |  |  |               <div class="cell">已消耗时常/用量</div> | 
					
						
							|  |  |  |  |               <div class="cell">已消费金额(元)</div> | 
					
						
							|  |  |  |  |               <div class="cell">价格(元/小时)</div> | 
					
						
							|  |  |  |  |             </div> | 
					
						
							|  |  |  |  |             <div class="grid-body"> | 
					
						
							|  |  |  |  |               <div class="vendor-cell" style="grid-row: span 3"> | 
					
						
							|  |  |  |  |                 <span>微软</span> | 
					
						
							|  |  |  |  |               </div> | 
					
						
							|  |  |  |  |             </div> | 
					
						
							|  |  |  |  |           </div> | 
					
						
							|  |  |  |  |           <div class="warn">备注:技术问题,请联系客服。</div> | 
					
						
							|  |  |  |  |           <div class="clearfix" style="height: 361px"> | 
					
						
							|  |  |  |  |             <div class="range-picker"> | 
					
						
							|  |  |  |  |               <div class="col on">近7天</div> | 
					
						
							|  |  |  |  |               <div class="col">近15天</div> | 
					
						
							|  |  |  |  |               <div class="col">近30天</div> | 
					
						
							|  |  |  |  |             </div> | 
					
						
							|  |  |  |  |             <!-- <div
 | 
					
						
							|  |  |  |  |               id="chartDoms" | 
					
						
							|  |  |  |  |               style="width: 1200px; height: 300px; margin: 30px auto" | 
					
						
							|  |  |  |  |             ></div> --> | 
					
						
							|  |  |  |  |           </div> | 
					
						
							|  |  |  |  |         </div> | 
					
						
							|  |  |  |  |       </div> | 
					
						
							|  |  |  |  |       <div class="public-customer"> | 
					
						
							|  |  |  |  |         <div class="ctr"> | 
					
						
							|  |  |  |  |           <div class="item"> | 
					
						
							|  |  |  |  |             <img | 
					
						
							|  |  |  |  |               src="https://codeai.oss-cn-hangzhou.aliyuncs.com/img/p25.png" | 
					
						
							|  |  |  |  |               alt="" | 
					
						
							|  |  |  |  |             /> | 
					
						
							|  |  |  |  |             <div>电报咨询</div> | 
					
						
							|  |  |  |  |             <div class="detail wechat"> | 
					
						
							|  |  |  |  |               <h5>电报咨询</h5> | 
					
						
							|  |  |  |  |               <img | 
					
						
							|  |  |  |  |                 src="/static/picture/p23.jpg" | 
					
						
							|  |  |  |  |                 alt="" | 
					
						
							|  |  |  |  |               /> | 
					
						
							|  |  |  |  |               <p>手机扫码加我电报</p> | 
					
						
							|  |  |  |  |             </div> | 
					
						
							|  |  |  |  |           </div> | 
					
						
							|  |  |  |  |           <div class="line"></div> | 
					
						
							|  |  |  |  |           <div class="item"> | 
					
						
							|  |  |  |  |             <img | 
					
						
							|  |  |  |  |               src="https://codeai.oss-cn-hangzhou.aliyuncs.com/img/p26.png" | 
					
						
							|  |  |  |  |               alt="" | 
					
						
							|  |  |  |  |             /> | 
					
						
							|  |  |  |  |             <div>电话咨询</div> | 
					
						
							|  |  |  |  |             <div class="detail"> | 
					
						
							|  |  |  |  |               <h5>电话咨询</h5> | 
					
						
							|  |  |  |  |               <div class="phone">+18435173355</div> | 
					
						
							|  |  |  |  |             </div> | 
					
						
							|  |  |  |  |           </div> | 
					
						
							|  |  |  |  |         </div> | 
					
						
							|  |  |  |  |       </div> | 
					
						
							|  |  |  |  |       <div class="modal-overlay" style="display: none"> | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |           <div class="modal"> | 
					
						
							|  |  |  |  |             <button class="close-btn" @click="close">×</button> | 
					
						
							|  |  |  |  |              <div | 
					
						
							|  |  |  |  |                 class="modal-content" | 
					
						
							|  |  |  |  |                 :style="loadingQr ? 'opacity: 0.4; pointer-events: none;' : ''" | 
					
						
							|  |  |  |  |               > | 
					
						
							|  |  |  |  |                 <h3 v-if="rechargeData.step === 1">Step 1: 输入购买数量</h3> | 
					
						
							|  |  |  |  |                 <h3 v-else>Step 2: 支付信息</h3> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 <!-- Step 1 --> | 
					
						
							|  |  |  |  |                 <div v-if="rechargeData.step === 1" class="step"> | 
					
						
							|  |  |  |  |                   <label>购买数量:</label> | 
					
						
							|  |  |  |  |                   <input type="number" v-model.number="rechargeData.count" min="1" /> | 
					
						
							|  |  |  |  |                 </div> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 <!-- Step 2 --> | 
					
						
							|  |  |  |  |                 <div v-else class="step"> | 
					
						
							|  |  |  |  |                   <div class="qr-code"> | 
					
						
							|  |  |  |  |                     <div id="qrcode"></div> | 
					
						
							|  |  |  |  |                     <!-- <div v-if="loadingQr" class="loading-spinner"></div> --> | 
					
						
							|  |  |  |  |                     <!-- <img v-else-if="qrCodeUrl" :src="qrCodeUrl" alt="二维码"
 | 
					
						
							|  |  |  |  |                         @load="onQrLoadSuccess" @error="onQrLoadError" | 
					
						
							|  |  |  |  |                         style="width: 100%; height: 100%; border-radius: 8px;" /> | 
					
						
							|  |  |  |  |                     <span v-else style="font-size: 12px; color: #999;">加载失败</span> --> | 
					
						
							|  |  |  |  |                   </div> | 
					
						
							|  |  |  |  |                   <div class="wallet-info"> | 
					
						
							|  |  |  |  |                     <p>主链:<strong>{{ rechargeData.blockChain }}</strong></p> | 
					
						
							|  |  |  |  |                     <p>钱包地址: <strong>{{ rechargeData.receiveAddress }}</strong></p> | 
					
						
							|  |  |  |  |                     <p>支付金额: <strong>{{ rechargeData.amount }} USDT</strong></p> | 
					
						
							| 
									
										
										
										
											2025-08-04 09:09:17 +08:00
										 |  |  |  |                     <div> | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |                       <countdown  :time="(rechargeData.expireUnix * 1000) - Date.now()" | 
					
						
							| 
									
										
										
										
											2025-08-04 09:09:17 +08:00
										 |  |  |  |                         v-if="rechargeData.status!==2&& rechargeData.expireUnix && (rechargeData.expireUnix * 1000) > Date.now()" > | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |                         <template slot-scope="props"> | 
					
						
							|  |  |  |  |                           倒计时: | 
					
						
							|  |  |  |  |                           <span v-if="props.minutes>0||props.hours>0||props.days>0">{{ props.minutes }} 分</span> | 
					
						
							|  |  |  |  |                           <span v-if="props.seconds>0||props.minutes>0||props.hours>0||props.days>0">{{ props.seconds }} 秒</span>   | 
					
						
							| 
									
										
										
										
											2025-07-08 14:04:05 +08:00
										 |  |  |  |                           <span style="color: red;" v-if="props.days==0&&props.hours==0&&props.minutes==0&&props.seconds==0">订单已过期,请勿支付!</span> | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |                         </template> | 
					
						
							|  |  |  |  |                            | 
					
						
							|  |  |  |  |                         </countdown> | 
					
						
							| 
									
										
										
										
											2025-08-04 09:09:17 +08:00
										 |  |  |  |                        <div v-else-if="rechargeData.status===2" style="color: green"> | 
					
						
							|  |  |  |  |                         充值成功,请勿重复支付! | 
					
						
							|  |  |  |  |                       </div> | 
					
						
							|  |  |  |  |                     </div> | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |                   </div> | 
					
						
							|  |  |  |  |                 </div> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             <div class="btn-group"> | 
					
						
							|  |  |  |  |               <!-- <button class="btn btn-secondary" @click="close">关闭</button> --> | 
					
						
							|  |  |  |  |               <button class="btn btn-secondary" v-if="rechargeData.step === 2" @click="prevStep">上一步</button> | 
					
						
							|  |  |  |  |               <button class="btn btn-primary" v-if="rechargeData.step === 1" :disabled="!rechargeData.count" @click="nextStep">下一步</button> | 
					
						
							| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  |             </div> | 
					
						
							|  |  |  |  |             </div> | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |           </div> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           <!-- loading 遮罩层 --> | 
					
						
							|  |  |  |  |           <div class="modal-loading-overlay" v-if="loadingQr"> | 
					
						
							|  |  |  |  |             <div class="spinner"></div> | 
					
						
							| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  |           </div> | 
					
						
							|  |  |  |  |         </div> | 
					
						
							| 
									
										
										
										
											2025-07-18 18:08:30 +08:00
										 |  |  |  |          | 
					
						
							| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  |       <div class="modal-overlay-record" style="display: none"> | 
					
						
							|  |  |  |  |         <div class="service-modal"> | 
					
						
							|  |  |  |  |           <div class="content-normal"> | 
					
						
							|  |  |  |  |             <div class="close" @click="closeRecord"></div> | 
					
						
							|  |  |  |  |             <div v-for="(item,index) in rechargeList" :key="'record'+index" class="content-item"> | 
					
						
							|  |  |  |  |              <div>订单号:{{item.orderNo}}</div>  | 
					
						
							|  |  |  |  |              <div>金额:{{item.amount}}</div> | 
					
						
							|  |  |  |  |              <div>总字符数:{{item.totalCharater}}</div> | 
					
						
							|  |  |  |  |              <div>可用字符数:{{item.remainCharater}}</div> | 
					
						
							|  |  |  |  |              <!-- <div>倒计时:{{item.expireUnix}}</div> --> | 
					
						
							|  |  |  |  |               <countdown  :time="(item.expireUnix * 1000) - Date.now()" | 
					
						
							|  |  |  |  |         v-if="item.expireUnix && (item.expireUnix * 1000) > Date.now()" > | 
					
						
							|  |  |  |  |               <template slot-scope="props"> | 
					
						
							|  |  |  |  |                 倒计时:<span v-if="props.days > 0">{{ props.days }} 天</span>  | 
					
						
							|  |  |  |  |                 <span v-if="props.hours>0||props.days>0">{{ props.hours }} 时</span>  | 
					
						
							|  |  |  |  |                 <span v-if="props.minutes>0||props.hours>0||props.days>0">{{ props.minutes }} 分</span> | 
					
						
							|  |  |  |  |                 <span v-if="props.seconds>0||props.minutes>0||props.hours>0||props.days>0">{{ props.seconds }} 秒</span>   | 
					
						
							|  |  |  |  |               </template> | 
					
						
							|  |  |  |  |                  | 
					
						
							|  |  |  |  |               </countdown> | 
					
						
							|  |  |  |  |             </div> | 
					
						
							|  |  |  |  |           </div> | 
					
						
							|  |  |  |  |         </div> | 
					
						
							|  |  |  |  |       </div> | 
					
						
							|  |  |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |     <style> | 
					
						
							|  |  |  |  |         | 
					
						
							|  |  |  |  |     .modal-overlay { | 
					
						
							|  |  |  |  |       position: fixed; | 
					
						
							|  |  |  |  |       inset: 0; | 
					
						
							|  |  |  |  |       background: rgba(0, 0, 0, 0.4); | 
					
						
							|  |  |  |  |       display: flex; | 
					
						
							|  |  |  |  |       justify-content: center; | 
					
						
							|  |  |  |  |       align-items: center; | 
					
						
							|  |  |  |  |       z-index: 999; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     .modal { | 
					
						
							|  |  |  |  |       background: #ffffff; | 
					
						
							|  |  |  |  |       border-radius: 12px; | 
					
						
							|  |  |  |  |       box-shadow: 0 8px 30px rgba(0, 0, 0, 0.1); | 
					
						
							|  |  |  |  |       padding: 24px 28px; | 
					
						
							|  |  |  |  |       width: 400px; | 
					
						
							|  |  |  |  |       max-width: 90%; | 
					
						
							|  |  |  |  |       animation: fadeIn 0.3s ease; | 
					
						
							|  |  |  |  |       position:relative; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     .modal-content { | 
					
						
							|  |  |  |  |       transition: opacity 0.2s; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     .modal-loading-overlay { | 
					
						
							|  |  |  |  |       position: absolute; | 
					
						
							|  |  |  |  |       top: 0; left: 0; right: 0; bottom: 0; | 
					
						
							|  |  |  |  |       background-color: rgba(255, 255, 255, 0.6); | 
					
						
							|  |  |  |  |       display: flex; | 
					
						
							|  |  |  |  |       justify-content: center; | 
					
						
							|  |  |  |  |       align-items: center; | 
					
						
							|  |  |  |  |       z-index: 10; | 
					
						
							|  |  |  |  |       border-radius: 12px; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     .spinner { | 
					
						
							|  |  |  |  |       border: 4px solid #f3f3f3; | 
					
						
							|  |  |  |  |       border-top: 4px solid #409eff; | 
					
						
							|  |  |  |  |       border-radius: 50%; | 
					
						
							|  |  |  |  |       width: 32px; | 
					
						
							|  |  |  |  |       height: 32px; | 
					
						
							|  |  |  |  |       animation: spin 0.8s linear infinite; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     @keyframes fadeIn { | 
					
						
							|  |  |  |  |       from { opacity: 0; transform: translateY(-20px); } | 
					
						
							|  |  |  |  |       to { opacity: 1; transform: translateY(0); } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     .modal h3 { | 
					
						
							|  |  |  |  |       margin-top: 0; | 
					
						
							|  |  |  |  |       font-size: 20px; | 
					
						
							|  |  |  |  |       color: #333; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     input[type="number"] { | 
					
						
							|  |  |  |  |       width: 100%; | 
					
						
							|  |  |  |  |       padding: 10px 12px; | 
					
						
							|  |  |  |  |       font-size: 16px; | 
					
						
							|  |  |  |  |       margin-top: 8px; | 
					
						
							|  |  |  |  |       border: 1px solid #ccc; | 
					
						
							|  |  |  |  |       border-radius: 6px; | 
					
						
							|  |  |  |  |       transition: border-color 0.2s; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     input[type="number"]:focus { | 
					
						
							|  |  |  |  |       border-color: #409eff; | 
					
						
							|  |  |  |  |       outline: none; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     button{ | 
					
						
							|  |  |  |  |       cursor: pointer; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     .step { | 
					
						
							|  |  |  |  |       padding-top: 16px; | 
					
						
							|  |  |  |  |       margin-bottom: 16px; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     .qr-code { | 
					
						
							|  |  |  |  |       width: 150px; | 
					
						
							|  |  |  |  |       height: 150px; | 
					
						
							|  |  |  |  |       background: #f8f8f8; | 
					
						
							|  |  |  |  |       border: 1px dashed #ccc; | 
					
						
							|  |  |  |  |       display: flex; | 
					
						
							|  |  |  |  |       align-items: center; | 
					
						
							|  |  |  |  |       justify-content: center; | 
					
						
							|  |  |  |  |       margin: 0 auto; | 
					
						
							|  |  |  |  |       border-radius: 8px; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     .loading-spinner { | 
					
						
							|  |  |  |  |       border: 3px solid #f3f3f3; | 
					
						
							|  |  |  |  |       border-top: 3px solid #409eff; | 
					
						
							|  |  |  |  |       border-radius: 50%; | 
					
						
							|  |  |  |  |       width: 28px; | 
					
						
							|  |  |  |  |       height: 28px; | 
					
						
							|  |  |  |  |       animation: spin 0.8s linear infinite; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     @keyframes spin { | 
					
						
							|  |  |  |  |       to { transform: rotate(360deg); } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     .btn-group { | 
					
						
							|  |  |  |  |       display: flex; | 
					
						
							|  |  |  |  |       justify-content: flex-end; | 
					
						
							|  |  |  |  |       gap: 8px; | 
					
						
							|  |  |  |  |       margin-top: 16px; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     .btn { | 
					
						
							|  |  |  |  |       padding: 8px 16px; | 
					
						
							|  |  |  |  |       border: none; | 
					
						
							|  |  |  |  |       border-radius: 6px; | 
					
						
							|  |  |  |  |       font-size: 14px; | 
					
						
							|  |  |  |  |       transition: background-color 0.2s ease; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     .btn-primary { | 
					
						
							|  |  |  |  |       background-color: #409eff; | 
					
						
							|  |  |  |  |       color: #fff; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     .btn-primary:disabled { | 
					
						
							|  |  |  |  |       background-color: #a0cfff; | 
					
						
							|  |  |  |  |       cursor: not-allowed; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     .btn-secondary { | 
					
						
							|  |  |  |  |       background-color: #e0e0e0; | 
					
						
							|  |  |  |  |       color: #333; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     .wallet-info { | 
					
						
							|  |  |  |  |       font-size: 14px; | 
					
						
							|  |  |  |  |       color: #555; | 
					
						
							|  |  |  |  |       text-align: center; | 
					
						
							|  |  |  |  |       margin-top: 12px; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     .close-btn { | 
					
						
							|  |  |  |  |   position: absolute; | 
					
						
							|  |  |  |  |   top: 12px; | 
					
						
							|  |  |  |  |   right: 12px; | 
					
						
							|  |  |  |  |   background: transparent; | 
					
						
							|  |  |  |  |   border: none; | 
					
						
							|  |  |  |  |   font-size: 20px; | 
					
						
							|  |  |  |  |   color: #999; | 
					
						
							|  |  |  |  |   cursor: pointer; | 
					
						
							|  |  |  |  |   transition: color 0.2s ease; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | .close-btn:hover { | 
					
						
							|  |  |  |  |   color: #333; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  |     </style> | 
					
						
							| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  |     <script type="text/javascript"> | 
					
						
							|  |  |  |  |       // 工具函数:将十六进制颜色转换为 RGBA 格式 | 
					
						
							|  |  |  |  |       function hexToRgba(hex, alpha) { | 
					
						
							|  |  |  |  |         const r = parseInt(hex.slice(1, 3), 16); | 
					
						
							|  |  |  |  |         const g = parseInt(hex.slice(3, 5), 16); | 
					
						
							|  |  |  |  |         const b = parseInt(hex.slice(5, 7), 16); | 
					
						
							|  |  |  |  |         return `rgba(${r}, ${g}, ${b}, ${alpha})`; | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |        | 
					
						
							|  |  |  |  |       var vm = new Vue({ | 
					
						
							|  |  |  |  |         el: "#app", | 
					
						
							|  |  |  |  |         components:{ | 
					
						
							|  |  |  |  |           countdown: window.VueCountdown, | 
					
						
							|  |  |  |  |         }, | 
					
						
							|  |  |  |  |         data() { | 
					
						
							|  |  |  |  |           return { | 
					
						
							|  |  |  |  |             translateInfo: [], | 
					
						
							|  |  |  |  |             translateInfos: [], | 
					
						
							|  |  |  |  |             isShow: false, | 
					
						
							|  |  |  |  |             dateType: 0, | 
					
						
							|  |  |  |  |             pageChart: null, | 
					
						
							|  |  |  |  |             tabShow: "text", | 
					
						
							|  |  |  |  |             token: "", | 
					
						
							|  |  |  |  |             userMoney: 0, | 
					
						
							|  |  |  |  |             userInfo: {}, | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |             activeStep:"2", | 
					
						
							|  |  |  |  |             showRecharge:false, | 
					
						
							|  |  |  |  |             loadingQr:false, | 
					
						
							|  |  |  |  |             rechargeData:{ | 
					
						
							|  |  |  |  |               platformId:null, | 
					
						
							| 
									
										
										
										
											2025-08-04 09:09:17 +08:00
										 |  |  |  |               orderNo:undefined, | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |               name:null, | 
					
						
							|  |  |  |  |               count:1, | 
					
						
							|  |  |  |  |               amount:null, | 
					
						
							|  |  |  |  |               receiveAddress:null, | 
					
						
							|  |  |  |  |               step:1, | 
					
						
							| 
									
										
										
										
											2025-08-04 09:09:17 +08:00
										 |  |  |  |               expireUnix:undefined, | 
					
						
							|  |  |  |  |               status:undefined, | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |             }, | 
					
						
							| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |             // ECharts 图表数据 | 
					
						
							|  |  |  |  |             myChart: null, // 用于存储 ECharts 实例 | 
					
						
							|  |  |  |  |             xAxisData: [], | 
					
						
							|  |  |  |  |             seriesData: [], | 
					
						
							|  |  |  |  |             receiveAddress: "", | 
					
						
							| 
									
										
										
										
											2025-08-04 09:09:17 +08:00
										 |  |  |  |             rechargeList:[], | 
					
						
							|  |  |  |  |             checkOrderTimer: null, | 
					
						
							| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  |           }; | 
					
						
							|  |  |  |  |         }, | 
					
						
							|  |  |  |  |         created() { | 
					
						
							|  |  |  |  |         }, | 
					
						
							|  |  |  |  |         mounted() { | 
					
						
							|  |  |  |  |            | 
					
						
							|  |  |  |  |           let token = localStorage.getItem("token"); | 
					
						
							|  |  |  |  |           if (token) { | 
					
						
							|  |  |  |  |             this.token = token; | 
					
						
							|  |  |  |  |             this.getUserInfo(token); | 
					
						
							|  |  |  |  |           } else { | 
					
						
							|  |  |  |  |             location.href = "login.html"; | 
					
						
							|  |  |  |  |           } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           // === 直接在主 Vue 实例的 mounted 钩子中初始化 ECharts === | 
					
						
							|  |  |  |  |           // 确保在 DOM 更新周期之后再初始化 ECharts | 
					
						
							|  |  |  |  |           this.$nextTick(() => { | 
					
						
							|  |  |  |  |             setTimeout(() => { | 
					
						
							|  |  |  |  |               this.initECharts(); | 
					
						
							|  |  |  |  |             }, 100); // 增加一个短暂的延迟 | 
					
						
							|  |  |  |  |           }); | 
					
						
							|  |  |  |  |           // 监听窗口大小变化,使图表自适应 | 
					
						
							|  |  |  |  |           window.addEventListener("resize", this.resizeECharts); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           this.getUserPlatforms(); | 
					
						
							|  |  |  |  |           this.getStatistics(); | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |           // this.getReceiveAddress(); | 
					
						
							| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  |         }, | 
					
						
							|  |  |  |  |         beforeDestroy() { | 
					
						
							|  |  |  |  |           // 销毁 ECharts 实例并移除事件监听器 | 
					
						
							|  |  |  |  |           if (this.myChart) { | 
					
						
							|  |  |  |  |             this.myChart.dispose(); | 
					
						
							|  |  |  |  |           } | 
					
						
							|  |  |  |  |           window.removeEventListener("resize", this.resizeECharts); | 
					
						
							|  |  |  |  |         }, | 
					
						
							|  |  |  |  |         watch: { | 
					
						
							|  |  |  |  |           dateType() { | 
					
						
							|  |  |  |  |             if (this.tabShow == "voice") { | 
					
						
							|  |  |  |  |               this.getVoicestatistics(); | 
					
						
							|  |  |  |  |             } else { | 
					
						
							|  |  |  |  |               this.getStatistics(); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |           }, | 
					
						
							|  |  |  |  |           // 监听数据变化,重新渲染图表 | 
					
						
							|  |  |  |  |           seriesData: { | 
					
						
							|  |  |  |  |             deep: true, | 
					
						
							|  |  |  |  |             handler() { | 
					
						
							|  |  |  |  |               this.updateECharts(); | 
					
						
							|  |  |  |  |             }, | 
					
						
							|  |  |  |  |           }, | 
					
						
							|  |  |  |  |           xAxisData: { | 
					
						
							|  |  |  |  |             deep: true, | 
					
						
							|  |  |  |  |             handler() { | 
					
						
							|  |  |  |  |               this.updateECharts(); | 
					
						
							|  |  |  |  |             }, | 
					
						
							|  |  |  |  |           }, | 
					
						
							|  |  |  |  |         }, | 
					
						
							|  |  |  |  |         methods: { | 
					
						
							|  |  |  |  |           getUserPlatforms() { | 
					
						
							|  |  |  |  |             axios | 
					
						
							|  |  |  |  |               .get("/tm-member/platforms", { | 
					
						
							|  |  |  |  |                 headers: { Authorization: `Bearer ${this.token}` }, | 
					
						
							|  |  |  |  |               }) | 
					
						
							|  |  |  |  |               .then((res) => { | 
					
						
							|  |  |  |  |                 if (res.data.code == 200) { | 
					
						
							|  |  |  |  |                   let result = res.data.data; | 
					
						
							|  |  |  |  |                   this.translateInfos = result; | 
					
						
							|  |  |  |  |                 } else { | 
					
						
							|  |  |  |  |                   layer.msg(response.data.msg); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |               }); | 
					
						
							|  |  |  |  |           }, | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |           // getReceiveAddress() { | 
					
						
							|  |  |  |  |           //   axios | 
					
						
							|  |  |  |  |           //     .get("/configKey/trx_receive_address", { | 
					
						
							|  |  |  |  |           //       headers: { Authorization: `Bearer ${this.token}` }, | 
					
						
							|  |  |  |  |           //     }) | 
					
						
							|  |  |  |  |           //     .then((res) => { | 
					
						
							|  |  |  |  |           //       if (res.data.code == 200) { | 
					
						
							|  |  |  |  |           //         this.receiveAddress = res.data.data.configValue; | 
					
						
							|  |  |  |  |           //         this.generateQRCode(); | 
					
						
							|  |  |  |  |           //       } else { | 
					
						
							|  |  |  |  |           //         layer.msg(response.data.msg); | 
					
						
							|  |  |  |  |           //       } | 
					
						
							|  |  |  |  |           //     }); | 
					
						
							|  |  |  |  |           // }, | 
					
						
							| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  |           getMemberAdvent(platformId){ | 
					
						
							|  |  |  |  |             axios | 
					
						
							|  |  |  |  |               .get("/tm-member/member-advent", { | 
					
						
							|  |  |  |  |                 headers: { Authorization: `Bearer ${this.token}` }, | 
					
						
							|  |  |  |  |                 params:{platformId} | 
					
						
							|  |  |  |  |               }) | 
					
						
							|  |  |  |  |               .then((res) => { | 
					
						
							|  |  |  |  |                 if (res.data.code == 200) { | 
					
						
							|  |  |  |  |                   let result = res.data.data; | 
					
						
							|  |  |  |  |                   this.rechargeList = result; | 
					
						
							|  |  |  |  |                 } else { | 
					
						
							|  |  |  |  |                   layer.msg(response.data.msg); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |               }); | 
					
						
							|  |  |  |  |           }, | 
					
						
							|  |  |  |  |           getUserInfo(token) { | 
					
						
							|  |  |  |  |             let that = this; | 
					
						
							|  |  |  |  |             axios | 
					
						
							|  |  |  |  |               .get("/getinfo", { | 
					
						
							|  |  |  |  |                 headers: { | 
					
						
							|  |  |  |  |                   Authorization: `Bearer ${token}`, | 
					
						
							|  |  |  |  |                 }, | 
					
						
							|  |  |  |  |               }) | 
					
						
							|  |  |  |  |               .then((response) => { | 
					
						
							|  |  |  |  |                 if (response.data.code === 200) { | 
					
						
							|  |  |  |  |                   that.userInfo = response.data.data; | 
					
						
							|  |  |  |  |                 } else { | 
					
						
							|  |  |  |  |                   localStorage.removeItem("token"); | 
					
						
							|  |  |  |  |                   location.href = "login.html"; | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |               }); | 
					
						
							|  |  |  |  |           }, | 
					
						
							|  |  |  |  |           getStatistics() { | 
					
						
							|  |  |  |  |             const that = this; | 
					
						
							|  |  |  |  |             axios | 
					
						
							|  |  |  |  |               .get("/tm-member-platform/statistics", { | 
					
						
							|  |  |  |  |                 headers: { Authorization: `Bearer ${this.token}` }, | 
					
						
							|  |  |  |  |               }) | 
					
						
							|  |  |  |  |               .then((response) => { | 
					
						
							|  |  |  |  |                 if (response.data.code == 200) { | 
					
						
							|  |  |  |  |                   this.xAxisData = response.data.data.xAxis; | 
					
						
							|  |  |  |  |                   this.seriesData = response.data.data.data || []; | 
					
						
							|  |  |  |  |                 } else { | 
					
						
							|  |  |  |  |                   layer.msg(response.data.msg); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |               }); | 
					
						
							|  |  |  |  |           }, | 
					
						
							|  |  |  |  |           look(apiKey, index) { | 
					
						
							|  |  |  |  |             var layer = layui.layer; | 
					
						
							|  |  |  |  |             // layer.open({ | 
					
						
							|  |  |  |  |             //     content: token, | 
					
						
							|  |  |  |  |             //     // shade: 0.8 | 
					
						
							|  |  |  |  |             //     shade: ["0.4"] | 
					
						
							|  |  |  |  |             //     // shade: false | 
					
						
							|  |  |  |  |             // }) | 
					
						
							|  |  |  |  |             layer.open({ | 
					
						
							|  |  |  |  |               type: 1, | 
					
						
							|  |  |  |  |               title: "API密钥", | 
					
						
							|  |  |  |  |               closeBtn: 1, | 
					
						
							|  |  |  |  |               shadeClose: true, | 
					
						
							|  |  |  |  |               skin: "11", | 
					
						
							|  |  |  |  |               content: | 
					
						
							|  |  |  |  |                 '<div class="secret-key"><div class="secret"><span>' + | 
					
						
							|  |  |  |  |                 apiKey + | 
					
						
							|  |  |  |  |                 '</span><i class="copy" data="' + | 
					
						
							|  |  |  |  |                 apiKey + | 
					
						
							|  |  |  |  |                 '" >复制</i></div></div>', | 
					
						
							|  |  |  |  |             }); | 
					
						
							|  |  |  |  |           }, | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |           show(item) { | 
					
						
							| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  |             $(".modal-overlay").fadeIn(); | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |             this.rechargeData.platformId=item.platformId; | 
					
						
							|  |  |  |  |             this.rechargeData.name=item.name; | 
					
						
							| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  |           }, | 
					
						
							|  |  |  |  |           close() { | 
					
						
							|  |  |  |  |             $(".modal-overlay").fadeOut(); | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |             this.rechargeData={ | 
					
						
							|  |  |  |  |               platformId:null, | 
					
						
							|  |  |  |  |               name:null, | 
					
						
							|  |  |  |  |               count:1, | 
					
						
							|  |  |  |  |               amount:null, | 
					
						
							|  |  |  |  |               receiveAddress:null, | 
					
						
							|  |  |  |  |               step:1, | 
					
						
							| 
									
										
										
										
											2025-08-04 09:09:17 +08:00
										 |  |  |  |               expireUnix:undefined, | 
					
						
							|  |  |  |  |               status:undefined, | 
					
						
							|  |  |  |  |             }; | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-04 09:09:17 +08:00
										 |  |  |  |             this.cleanCheckOrderTimer(); | 
					
						
							|  |  |  |  |              | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |           }, | 
					
						
							|  |  |  |  |           prevStep(){ | 
					
						
							|  |  |  |  |       | 
					
						
							|  |  |  |  |             this.rechargeData.step=1; | 
					
						
							|  |  |  |  |              | 
					
						
							|  |  |  |  |           }, | 
					
						
							|  |  |  |  |           nextStep(){ | 
					
						
							|  |  |  |  |             if(this.rechargeData.count<=0){ | 
					
						
							|  |  |  |  |                layer.msg("数量不能小于0"); | 
					
						
							|  |  |  |  |                return; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             this.loadingQr=true; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             axios.post("/tm-member/recharge",this.rechargeData,{headers: { Authorization: `Bearer ${this.token}` }}) | 
					
						
							|  |  |  |  |             .then(res => { | 
					
						
							| 
									
										
										
										
											2025-08-04 09:09:17 +08:00
										 |  |  |  |                | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |               if(res.data.code===200){ | 
					
						
							|  |  |  |  |                 this.rechargeData.step=2; | 
					
						
							|  |  |  |  |                 this.rechargeData.amount=res.data.data.amount; | 
					
						
							|  |  |  |  |                 this.rechargeData.receiveAddress=res.data.data.receiveAddress; | 
					
						
							|  |  |  |  |                 this.rechargeData.blockChain=res.data.data.blockChain; | 
					
						
							|  |  |  |  |                 this.rechargeData.expireUnix=res.data.data.expireUnix; | 
					
						
							| 
									
										
										
										
											2025-08-04 09:09:17 +08:00
										 |  |  |  |                 this.rechargeData.orderNo=res.data.data.orderNo; | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |                 let _that=this; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 this.$nextTick(() => { | 
					
						
							|  |  |  |  |                   _that.generateQRCode(_that.rechargeData.receiveAddress); | 
					
						
							|  |  |  |  |                 }) | 
					
						
							| 
									
										
										
										
											2025-08-04 09:09:17 +08:00
										 |  |  |  |                 _that.createCheckOrderTimer(); | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |               }else{ | 
					
						
							|  |  |  |  |                 layer.msg(res.data.msg); | 
					
						
							|  |  |  |  |               } | 
					
						
							|  |  |  |  |             }).finally(() => { | 
					
						
							|  |  |  |  |               this.loadingQr=false; | 
					
						
							|  |  |  |  |               }); | 
					
						
							| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  |           }, | 
					
						
							|  |  |  |  |           showRecord(platformId){ | 
					
						
							|  |  |  |  |             $(".modal-overlay-record").fadeIn(); | 
					
						
							|  |  |  |  |             this.getMemberAdvent(platformId); | 
					
						
							|  |  |  |  |           }, | 
					
						
							|  |  |  |  |           closeRecord(){ | 
					
						
							|  |  |  |  |             $(".modal-overlay-record").fadeOut(); | 
					
						
							|  |  |  |  |           }, | 
					
						
							|  |  |  |  |           tabClick(val) { | 
					
						
							|  |  |  |  |             this.tabShow = val; | 
					
						
							|  |  |  |  |             this.pageChart = null; | 
					
						
							|  |  |  |  |             if (val == "voice") { | 
					
						
							|  |  |  |  |               this.getVoicestatistics(); | 
					
						
							|  |  |  |  |               this.getuserinfo(); | 
					
						
							|  |  |  |  |               this.getUsersDuration(); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |           }, | 
					
						
							|  |  |  |  |           copy() { | 
					
						
							|  |  |  |  |             const apiKey = this.token; | 
					
						
							|  |  |  |  |             navigator.clipboard.writeText(apiKey).then(() => { | 
					
						
							|  |  |  |  |               console.log("已复制"); | 
					
						
							|  |  |  |  |               layer.msg("复制成功"); | 
					
						
							|  |  |  |  |             }); | 
					
						
							|  |  |  |  |           }, | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           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; | 
					
						
							| 
									
										
										
										
											2025-08-04 09:09:17 +08:00
										 |  |  |  |                    | 
					
						
							| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  |                 } else { | 
					
						
							|  |  |  |  |                   location.href = "login.html"; | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |               }); | 
					
						
							|  |  |  |  |           }, | 
					
						
							|  |  |  |  |           // 模拟更新图表数据的方法 | 
					
						
							|  |  |  |  |           updateRandomChartData() { | 
					
						
							|  |  |  |  |             // 直接调用 fetchChartData 来模拟数据更新 | 
					
						
							|  |  |  |  |             this.fetchChartData(); | 
					
						
							|  |  |  |  |             layer.msg("图表数据已更新!"); | 
					
						
							|  |  |  |  |           }, | 
					
						
							|  |  |  |  |           // === ECharts 初始化和更新方法 === | 
					
						
							|  |  |  |  |           initECharts() { | 
					
						
							|  |  |  |  |             // 在这里添加一个检查,确保 echarts 对象是存在的 | 
					
						
							|  |  |  |  |             if (typeof echarts === "undefined") { | 
					
						
							|  |  |  |  |               console.error("ECharts 库未加载!"); | 
					
						
							|  |  |  |  |               return; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             const chartDom = document.getElementById("mainEchart"); | 
					
						
							|  |  |  |  |             if (!chartDom) { | 
					
						
							|  |  |  |  |               console.error("ECharts 图表容器 DOM 元素 #mainEchart 未找到!"); | 
					
						
							|  |  |  |  |               return; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             // 初始化 ECharts 实例 | 
					
						
							|  |  |  |  |             this.myChart = echarts.init(chartDom); | 
					
						
							|  |  |  |  |             this.updateECharts(); // 首次加载数据 | 
					
						
							|  |  |  |  |           }, | 
					
						
							|  |  |  |  |           updateECharts() { | 
					
						
							|  |  |  |  |             if (!this.myChart) { | 
					
						
							|  |  |  |  |               console.error("ECharts 实例未创建!无法更新图表。"); | 
					
						
							|  |  |  |  |               return; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             // 动态生成 series 配置 | 
					
						
							|  |  |  |  |             const series = this.seriesData.map((item, index) => { | 
					
						
							|  |  |  |  |               // 使用 this.seriesData | 
					
						
							|  |  |  |  |               const colors = [ | 
					
						
							|  |  |  |  |                 "#3c8dbc", | 
					
						
							|  |  |  |  |                 "#00a65a", | 
					
						
							|  |  |  |  |                 "#f39c12", | 
					
						
							|  |  |  |  |                 "#724a9c", | 
					
						
							|  |  |  |  |                 "#e74c3c", | 
					
						
							|  |  |  |  |                 "#1abc9c", | 
					
						
							|  |  |  |  |               ]; | 
					
						
							|  |  |  |  |               const color = colors[index % colors.length]; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |               return { | 
					
						
							|  |  |  |  |                 name: item.platformName, // 使用 platformName | 
					
						
							|  |  |  |  |                 type: "line", | 
					
						
							|  |  |  |  |                 // stack: '总量', // 如果不需要堆叠,请注释或移除此行 | 
					
						
							|  |  |  |  |                 smooth: true, | 
					
						
							|  |  |  |  |                 lineStyle: { | 
					
						
							|  |  |  |  |                   width: 3, | 
					
						
							|  |  |  |  |                 }, | 
					
						
							|  |  |  |  |                 itemStyle: { | 
					
						
							|  |  |  |  |                   borderColor: color, | 
					
						
							|  |  |  |  |                   borderWidth: 2, | 
					
						
							|  |  |  |  |                 }, | 
					
						
							|  |  |  |  |                 emphasis: { | 
					
						
							|  |  |  |  |                   focus: "series", | 
					
						
							|  |  |  |  |                 }, | 
					
						
							|  |  |  |  |                 data: item.data, // 使用 item.data | 
					
						
							|  |  |  |  |                 areaStyle: { | 
					
						
							|  |  |  |  |                   opacity: 0.8, | 
					
						
							|  |  |  |  |                   // 确保 echarts.graphic 存在 | 
					
						
							|  |  |  |  |                   color: | 
					
						
							|  |  |  |  |                     typeof echarts !== "undefined" && echarts.graphic | 
					
						
							|  |  |  |  |                       ? new echarts.graphic.LinearGradient(0, 0, 0, 1, [ | 
					
						
							|  |  |  |  |                           { | 
					
						
							|  |  |  |  |                             offset: 0, | 
					
						
							|  |  |  |  |                             color: hexToRgba(color, 0.3), | 
					
						
							|  |  |  |  |                           }, | 
					
						
							|  |  |  |  |                           { | 
					
						
							|  |  |  |  |                             offset: 1, | 
					
						
							|  |  |  |  |                             color: hexToRgba(color, 0), | 
					
						
							|  |  |  |  |                           }, | 
					
						
							|  |  |  |  |                         ]) | 
					
						
							|  |  |  |  |                       : color, // Fallback to solid color if graphic is not available | 
					
						
							|  |  |  |  |                 }, | 
					
						
							|  |  |  |  |               }; | 
					
						
							|  |  |  |  |             }); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             // 动态生成 legend data | 
					
						
							|  |  |  |  |             const legendData = (this.seriesData || []).map( | 
					
						
							|  |  |  |  |               (item) => item.platformName | 
					
						
							|  |  |  |  |             ); // 使用 platformName | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             const option = { | 
					
						
							|  |  |  |  |               title: { | 
					
						
							|  |  |  |  |                 text: "字符消耗统计", // 标题可以直接在主实例中定义 | 
					
						
							|  |  |  |  |                 left: "center", | 
					
						
							|  |  |  |  |                 textStyle: { | 
					
						
							|  |  |  |  |                   color: "#333", | 
					
						
							|  |  |  |  |                   fontSize: 18, | 
					
						
							|  |  |  |  |                   fontWeight: "bold", | 
					
						
							|  |  |  |  |                 }, | 
					
						
							|  |  |  |  |               }, | 
					
						
							|  |  |  |  |               tooltip: { | 
					
						
							|  |  |  |  |                 trigger: "axis", | 
					
						
							|  |  |  |  |                 axisPointer: { | 
					
						
							|  |  |  |  |                   type: "cross", | 
					
						
							|  |  |  |  |                   label: { | 
					
						
							|  |  |  |  |                     backgroundColor: "#6a7985", | 
					
						
							|  |  |  |  |                   }, | 
					
						
							|  |  |  |  |                 }, | 
					
						
							|  |  |  |  |                 formatter: function (params) { | 
					
						
							|  |  |  |  |                   var result = params[0].name + "<br/>"; | 
					
						
							|  |  |  |  |                   params.forEach(function (item) { | 
					
						
							|  |  |  |  |                     if ( | 
					
						
							|  |  |  |  |                       item.data !== null && | 
					
						
							|  |  |  |  |                       item.seriesName && | 
					
						
							|  |  |  |  |                       item.value !== undefined | 
					
						
							|  |  |  |  |                     ) { | 
					
						
							|  |  |  |  |                       result += | 
					
						
							|  |  |  |  |                         '<span style="display:inline-block;margin-right:4px;border-radius:10px;width:10px;height:10px;background-color:' + | 
					
						
							|  |  |  |  |                         item.color + | 
					
						
							|  |  |  |  |                         ';"></span>' + | 
					
						
							|  |  |  |  |                         item.seriesName + | 
					
						
							|  |  |  |  |                         ": " + | 
					
						
							|  |  |  |  |                         item.value + | 
					
						
							|  |  |  |  |                         "<br/>"; | 
					
						
							|  |  |  |  |                     } | 
					
						
							|  |  |  |  |                   }); | 
					
						
							|  |  |  |  |                   return result; | 
					
						
							|  |  |  |  |                 }, | 
					
						
							|  |  |  |  |               }, | 
					
						
							|  |  |  |  |               legend: { | 
					
						
							|  |  |  |  |                 data: legendData, | 
					
						
							|  |  |  |  |                 top: "bottom", | 
					
						
							|  |  |  |  |                 textStyle: { | 
					
						
							|  |  |  |  |                   color: "#666", | 
					
						
							|  |  |  |  |                 }, | 
					
						
							|  |  |  |  |                 padding: [10, 0, 0, 0], | 
					
						
							|  |  |  |  |               }, | 
					
						
							|  |  |  |  |               grid: { | 
					
						
							|  |  |  |  |                 left: "3%", | 
					
						
							|  |  |  |  |                 right: "4%", | 
					
						
							|  |  |  |  |                 bottom: "10%", | 
					
						
							|  |  |  |  |                 containLabel: true, | 
					
						
							|  |  |  |  |               }, | 
					
						
							|  |  |  |  |               xAxis: { | 
					
						
							|  |  |  |  |                 type: "category", | 
					
						
							|  |  |  |  |                 boundaryGap: false, | 
					
						
							|  |  |  |  |                 data: this.xAxisData, // 直接使用 xAxisData | 
					
						
							|  |  |  |  |                 axisLabel: { | 
					
						
							|  |  |  |  |                   color: "#555", | 
					
						
							|  |  |  |  |                 }, | 
					
						
							|  |  |  |  |                 axisLine: { | 
					
						
							|  |  |  |  |                   lineStyle: { | 
					
						
							|  |  |  |  |                     color: "#ccc", | 
					
						
							|  |  |  |  |                   }, | 
					
						
							|  |  |  |  |                 }, | 
					
						
							|  |  |  |  |               }, | 
					
						
							|  |  |  |  |               yAxis: { | 
					
						
							|  |  |  |  |                 type: "value", | 
					
						
							|  |  |  |  |                 name: "字符数", // Y轴名称可以直接在主实例中定义 | 
					
						
							|  |  |  |  |                 nameTextStyle: { | 
					
						
							|  |  |  |  |                   color: "#555", | 
					
						
							|  |  |  |  |                   padding: [0, 0, 10, 0], | 
					
						
							|  |  |  |  |                 }, | 
					
						
							|  |  |  |  |                 axisLabel: { | 
					
						
							|  |  |  |  |                   formatter: "{value} ", | 
					
						
							|  |  |  |  |                   color: "#555", | 
					
						
							|  |  |  |  |                 }, | 
					
						
							|  |  |  |  |                 axisLine: { | 
					
						
							|  |  |  |  |                   lineStyle: { | 
					
						
							|  |  |  |  |                     color: "#ccc", | 
					
						
							|  |  |  |  |                   }, | 
					
						
							|  |  |  |  |                 }, | 
					
						
							|  |  |  |  |                 splitLine: { | 
					
						
							|  |  |  |  |                   lineStyle: { | 
					
						
							|  |  |  |  |                     type: "dashed", | 
					
						
							|  |  |  |  |                     color: "#e0e0e0", | 
					
						
							|  |  |  |  |                   }, | 
					
						
							|  |  |  |  |                 }, | 
					
						
							|  |  |  |  |               }, | 
					
						
							|  |  |  |  |               series: series, | 
					
						
							|  |  |  |  |             }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             this.myChart.setOption(option); | 
					
						
							|  |  |  |  |             // 确保在设置选项后也调整图表大小 | 
					
						
							|  |  |  |  |             setTimeout(() => { | 
					
						
							|  |  |  |  |               if (this.myChart) { | 
					
						
							|  |  |  |  |                 this.myChart.resize(); | 
					
						
							|  |  |  |  |               } | 
					
						
							|  |  |  |  |             }, 50); // 增加一个短暂的延迟 | 
					
						
							|  |  |  |  |           }, | 
					
						
							|  |  |  |  |           resizeECharts() { | 
					
						
							|  |  |  |  |             // 更改方法名以与组件内的 resizeChart 区分 | 
					
						
							|  |  |  |  |             if (this.myChart) { | 
					
						
							|  |  |  |  |               const chartDom = document.getElementById("mainEchart"); | 
					
						
							|  |  |  |  |               if (chartDom) { | 
					
						
							|  |  |  |  |               } | 
					
						
							|  |  |  |  |               this.myChart.resize(); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |           }, | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |            generateQRCode(qrString) { | 
					
						
							|  |  |  |  |             const text = qrString.trim(); // 获取输入框内容并去除首尾空格 | 
					
						
							| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  |             const qrcodeContainer = document.getElementById('qrcode'); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if (text) { | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |               console.log('container',qrcodeContainer) | 
					
						
							| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  |               // 1. 清空容器内的所有内容,包括旧的二维码或提示信息 | 
					
						
							|  |  |  |  |               qrcodeContainer.innerHTML = '';  | 
					
						
							|  |  |  |  |               this.showPlaceholder = false; | 
					
						
							|  |  |  |  |               this.qrError = null; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |               // 2. 创建一个新的 canvas 元素 | 
					
						
							|  |  |  |  |               const canvasElement = document.createElement('canvas'); | 
					
						
							|  |  |  |  |               // 可以给 canvas 设置一个 ID 或者类名,如果需要后续引用或样式控制 | 
					
						
							|  |  |  |  |               // canvasElement.id = 'qrCanvas';  | 
					
						
							|  |  |  |  |               qrcodeContainer.appendChild(canvasElement); // 将 canvas 添加到容器中 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |               // 3. 使用 QRCode.toCanvas 在新创建的 canvas 上生成二维码 | 
					
						
							|  |  |  |  |               QRCode.toCanvas(canvasElement, text, { // 将 canvasElement 传递给 toCanvas | 
					
						
							| 
									
										
										
										
											2025-07-07 19:03:16 +08:00
										 |  |  |  |                 width: 150, // 设置二维码宽度 | 
					
						
							| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  |                 color: { | 
					
						
							|  |  |  |  |                   dark: '#000000',  // 二维码颜色 | 
					
						
							|  |  |  |  |                   light:'#ffffff' // 背景颜色 | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |               }, (error) => { | 
					
						
							|  |  |  |  |                 if (error) { | 
					
						
							|  |  |  |  |                   qrcodeContainer.innerHTML = `<p class="text-red-500">获取地址失败请刷新</p>`; // 重新显示错误信息 | 
					
						
							|  |  |  |  |                 } else { | 
					
						
							|  |  |  |  |                   console.log('二维码生成成功!'); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |               }); | 
					
						
							|  |  |  |  |             } else { | 
					
						
							|  |  |  |  |               // 如果输入为空,给出提示 | 
					
						
							|  |  |  |  |               qrcodeContainer.innerHTML = ''; // 清空可能存在的旧二维码 | 
					
						
							|  |  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-08-04 09:09:17 +08:00
										 |  |  |  |           }, | 
					
						
							|  |  |  |  |           getOrderStatus(orderNo){ | 
					
						
							|  |  |  |  |             let that=this; | 
					
						
							|  |  |  |  |             let params={orderNo} | 
					
						
							|  |  |  |  |              | 
					
						
							|  |  |  |  |              axios | 
					
						
							|  |  |  |  |               .get("/tm-member/order", { | 
					
						
							|  |  |  |  |                 headers: { | 
					
						
							|  |  |  |  |                   Authorization: `Bearer ${this.token}`, | 
					
						
							|  |  |  |  |                 }, | 
					
						
							|  |  |  |  |                 params:{orderNo} | 
					
						
							|  |  |  |  |               }) | 
					
						
							|  |  |  |  |               .then((response) => { | 
					
						
							|  |  |  |  |                 if (response.data.code === 200) { | 
					
						
							|  |  |  |  |                   if(that.rechargeData.orderNo===response.data.data.orderNo && response.data.data.status===2){ | 
					
						
							|  |  |  |  |                     that.rechargeData.status=response.data.data.status; | 
					
						
							|  |  |  |  |                      | 
					
						
							|  |  |  |  |                     that.cleanCheckOrderTimer(); | 
					
						
							|  |  |  |  |                   } | 
					
						
							|  |  |  |  |                 } else { | 
					
						
							|  |  |  |  |                   // location.href = "login.html"; | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |               }); | 
					
						
							|  |  |  |  |           }, | 
					
						
							|  |  |  |  |           //定时检查订单状态 | 
					
						
							|  |  |  |  |           createCheckOrderTimer() { | 
					
						
							|  |  |  |  |             if (this.checkOrderTimer) { | 
					
						
							|  |  |  |  |               clearInterval(this.checkOrderTimer); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |              | 
					
						
							|  |  |  |  |               console.log("createCheckOrderTimer") | 
					
						
							|  |  |  |  |               this.checkOrderTimer = setInterval(() => { | 
					
						
							|  |  |  |  |                 this.getOrderStatus(this.rechargeData.orderNo); | 
					
						
							|  |  |  |  |               }, 10000); | 
					
						
							|  |  |  |  |           }, | 
					
						
							|  |  |  |  |           cleanCheckOrderTimer() { | 
					
						
							|  |  |  |  |             if (this.checkOrderTimer) { | 
					
						
							|  |  |  |  |               clearInterval(this.checkOrderTimer); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |           }, | 
					
						
							| 
									
										
										
										
											2025-07-02 18:32:06 +08:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  |       }); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |       function copy(val) { | 
					
						
							|  |  |  |  |         var layer = layui.layer; | 
					
						
							|  |  |  |  |         const jsonStr = JSON.stringify(val); | 
					
						
							|  |  |  |  |         // 模拟 输入框 | 
					
						
							|  |  |  |  |         var cInput = document.createElement("input"); | 
					
						
							|  |  |  |  |         cInput.value = jsonStr; | 
					
						
							|  |  |  |  |         document.body.appendChild(cInput); | 
					
						
							|  |  |  |  |         cInput.select(); // 选取文本框内容 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 执行浏览器复制命令 | 
					
						
							|  |  |  |  |         // 复制命令会将当前选中的内容复制到剪切板中(这里就是创建的input标签) | 
					
						
							|  |  |  |  |         // Input要在正常的编辑状态下原生复制方法才会生效 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         document.execCommand("copy"); | 
					
						
							|  |  |  |  |         layer.msg("复制成功"); | 
					
						
							|  |  |  |  |         // 复制成功后再将构造的标签 移除 | 
					
						
							|  |  |  |  |         document.body.removeChild(cInput); | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |       $("body").on("click", ".copy", function () { | 
					
						
							|  |  |  |  |         console.log($(this).attr("data")); | 
					
						
							|  |  |  |  |         copy($(this).attr("data")); | 
					
						
							|  |  |  |  |       }); | 
					
						
							|  |  |  |  |       // $('body .copy').click(function() { | 
					
						
							|  |  |  |  |       //     console.log($(this).attr('data')) | 
					
						
							|  |  |  |  |       //     copy($(this).attr('data')) | 
					
						
							|  |  |  |  |       // }) | 
					
						
							|  |  |  |  |     </script> | 
					
						
							|  |  |  |  |     <div class="public-footer"> | 
					
						
							|  |  |  |  |       <div class="w1200"> | 
					
						
							|  |  |  |  |         <div class="left"> | 
					
						
							|  |  |  |  |           <img | 
					
						
							|  |  |  |  |             src="https://codeai.oss-cn-hangzhou.aliyuncs.com/img/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> | 
					
						
							|  |  |  |  |           <p></p> | 
					
						
							|  |  |  |  |         </div> | 
					
						
							|  |  |  |  |       </div> | 
					
						
							|  |  |  |  |       <div class="copyright"> | 
					
						
							|  |  |  |  |         <a href="https://beian.miit.gov.cn/" target="blank"></a> | 
					
						
							|  |  |  |  |       </div> | 
					
						
							|  |  |  |  |     </div> | 
					
						
							|  |  |  |  |     <div class="layui-layer-move" style="cursor: move; display: none"></div> | 
					
						
							|  |  |  |  |     <style> | 
					
						
							|  |  |  |  |       .btn-clock{ | 
					
						
							|  |  |  |  |         width: 15px; | 
					
						
							|  |  |  |  |         cursor: pointer; | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |       .chart-container-wrapper { | 
					
						
							|  |  |  |  |         width: 100%; | 
					
						
							|  |  |  |  |         max-width: 900px; /* 最大宽度 */ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         background-color: #ffffff; | 
					
						
							|  |  |  |  |         border-radius: 12px; /* 圆角 */ | 
					
						
							|  |  |  |  |         box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); /* 阴影 */ | 
					
						
							|  |  |  |  |         padding: 20px; | 
					
						
							|  |  |  |  |         box-sizing: border-box; | 
					
						
							|  |  |  |  |         display: flex; | 
					
						
							|  |  |  |  |         flex-direction: column; | 
					
						
							|  |  |  |  |         justify-content: center; | 
					
						
							|  |  |  |  |         align-items: center; | 
					
						
							|  |  |  |  |         margin: 20px auto; /* 居中显示 */ | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |       .echarts-chart-direct { | 
					
						
							|  |  |  |  |         /* 更改类名以区分,这里是直接渲染的div */ | 
					
						
							|  |  |  |  |         width: 100%; | 
					
						
							|  |  |  |  |         height: 300px; /* === 移除此行,高度由内联样式直接控制 === */ | 
					
						
							|  |  |  |  |         /* === 调试用样式:添加边框和背景色 === */ | 
					
						
							|  |  |  |  |         /* ==================================== */ | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |       /* 响应式调整图表高度 */ | 
					
						
							|  |  |  |  |       @media (max-width: 768px) { | 
					
						
							|  |  |  |  |         .chart-container-wrapper { | 
					
						
							|  |  |  |  |           height: 350px !important; /* 响应式也添加 !important */ | 
					
						
							|  |  |  |  |           padding: 15px; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |       @media (max-width: 480px) { | 
					
						
							|  |  |  |  |         .chart-container-wrapper { | 
					
						
							|  |  |  |  |           height: 300px !important; /* 响应式也添加 !important */ | 
					
						
							|  |  |  |  |           padding: 10px; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |     </style> | 
					
						
							|  |  |  |  |   </body> | 
					
						
							|  |  |  |  | </html> |