1、在线支付
This commit is contained in:
335
userinfo.html
335
userinfo.html
@ -16,6 +16,8 @@
|
||||
<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" />
|
||||
<!-- <link rel="stylesheet" href="static/js/css/buefy.min.css"> -->
|
||||
|
||||
<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>
|
||||
@ -26,6 +28,8 @@
|
||||
<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>
|
||||
|
||||
<!-- <script src="static/js/buefy.min.js"></script> -->
|
||||
<title>聚合翻译</title>
|
||||
<script>
|
||||
var _hmt = _hmt || [];
|
||||
@ -196,7 +200,7 @@
|
||||
<div class="cell"><span>{{item.price}}</span></div>
|
||||
<div class="cell">
|
||||
<div class="act">
|
||||
<span class="recharge" @click="show">充值</span
|
||||
<span class="recharge" @click="show(item)">充值</span
|
||||
><span class="view" @click="look(item.apiKey,index)"
|
||||
>查看API密钥</span
|
||||
>
|
||||
@ -297,27 +301,61 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-overlay" style="display: none">
|
||||
<div class="service-modal">
|
||||
<div class="content">
|
||||
<div class="close" @click="close"></div>
|
||||
<div class="contact">TRX BLOCK</div>
|
||||
<div class="contact-user">
|
||||
<div class="contact-user-text">用户ID : {{userInfo.id}}</div>
|
||||
<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>
|
||||
<p>
|
||||
<countdown :time="(rechargeData.expireUnix * 1000) - Date.now()"
|
||||
v-if="rechargeData.expireUnix && (rechargeData.expireUnix * 1000) > Date.now()" >
|
||||
<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>
|
||||
<span v-if="props.days==0&&props.hours==0&&props.minutes==0&&props.seconds==0">订单已过期,请勿支付!</span>
|
||||
</template>
|
||||
|
||||
</countdown>
|
||||
</p>
|
||||
</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>
|
||||
</div>
|
||||
<div
|
||||
id="qrcode"
|
||||
style="text-align: center;height: 214px;"
|
||||
class="border border-gray-200 rounded-lg p-2 flex justify-center items-center"
|
||||
>
|
||||
<!-- 二维码将在这里生成 -->
|
||||
<!-- <p class="text-gray-500">点击按钮生成二维码</p> -->
|
||||
</div>
|
||||
<!-- <img
|
||||
src="/static/picture/p23.jpg"
|
||||
alt=""
|
||||
class="qrcode-img"
|
||||
/> -->
|
||||
<p>{{receiveAddress}}</p>
|
||||
</div>
|
||||
|
||||
<!-- loading 遮罩层 -->
|
||||
<div class="modal-loading-overlay" v-if="loadingQr">
|
||||
<div class="spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -346,7 +384,167 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<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>
|
||||
<script type="text/javascript">
|
||||
// 工具函数:将十六进制颜色转换为 RGBA 格式
|
||||
function hexToRgba(hex, alpha) {
|
||||
@ -373,6 +571,18 @@
|
||||
token: "",
|
||||
userMoney: 0,
|
||||
userInfo: {},
|
||||
activeStep:"2",
|
||||
showRecharge:false,
|
||||
loadingQr:false,
|
||||
rechargeData:{
|
||||
platformId:null,
|
||||
name:null,
|
||||
count:1,
|
||||
amount:null,
|
||||
receiveAddress:null,
|
||||
step:1,
|
||||
expireUnix:undefined
|
||||
},
|
||||
|
||||
// ECharts 图表数据
|
||||
myChart: null, // 用于存储 ECharts 实例
|
||||
@ -407,7 +617,7 @@
|
||||
|
||||
this.getUserPlatforms();
|
||||
this.getStatistics();
|
||||
this.getReceiveAddress();
|
||||
// this.getReceiveAddress();
|
||||
},
|
||||
beforeDestroy() {
|
||||
// 销毁 ECharts 实例并移除事件监听器
|
||||
@ -453,20 +663,20 @@
|
||||
}
|
||||
});
|
||||
},
|
||||
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);
|
||||
}
|
||||
});
|
||||
},
|
||||
// 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);
|
||||
// }
|
||||
// });
|
||||
// },
|
||||
getMemberAdvent(platformId){
|
||||
axios
|
||||
.get("/tm-member/member-advent", {
|
||||
@ -540,11 +750,57 @@
|
||||
'" >复制</i></div></div>',
|
||||
});
|
||||
},
|
||||
show() {
|
||||
show(item) {
|
||||
$(".modal-overlay").fadeIn();
|
||||
this.rechargeData.platformId=item.platformId;
|
||||
this.rechargeData.name=item.name;
|
||||
},
|
||||
close() {
|
||||
$(".modal-overlay").fadeOut();
|
||||
this.rechargeData={
|
||||
platformId:null,
|
||||
name:null,
|
||||
count:1,
|
||||
amount:null,
|
||||
receiveAddress:null,
|
||||
step:1,
|
||||
expireUnix:undefined
|
||||
};
|
||||
|
||||
console.log(this.rechargeData);
|
||||
},
|
||||
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 => {
|
||||
console.log("sss",res);
|
||||
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;
|
||||
let _that=this;
|
||||
|
||||
this.$nextTick(() => {
|
||||
_that.generateQRCode(_that.rechargeData.receiveAddress);
|
||||
})
|
||||
}else{
|
||||
layer.msg(res.data.msg);
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loadingQr=false;
|
||||
});
|
||||
},
|
||||
showRecord(platformId){
|
||||
$(".modal-overlay-record").fadeIn();
|
||||
@ -779,11 +1035,12 @@
|
||||
this.myChart.resize();
|
||||
}
|
||||
},
|
||||
generateQRCode() {
|
||||
const text = this.receiveAddress.trim(); // 获取输入框内容并去除首尾空格
|
||||
generateQRCode(qrString) {
|
||||
const text = qrString.trim(); // 获取输入框内容并去除首尾空格
|
||||
const qrcodeContainer = document.getElementById('qrcode');
|
||||
|
||||
if (text) {
|
||||
console.log('container',qrcodeContainer)
|
||||
// 1. 清空容器内的所有内容,包括旧的二维码或提示信息
|
||||
qrcodeContainer.innerHTML = '';
|
||||
this.showPlaceholder = false;
|
||||
@ -797,7 +1054,7 @@
|
||||
|
||||
// 3. 使用 QRCode.toCanvas 在新创建的 canvas 上生成二维码
|
||||
QRCode.toCanvas(canvasElement, text, { // 将 canvasElement 传递给 toCanvas
|
||||
width: 214, // 设置二维码宽度
|
||||
width: 150, // 设置二维码宽度
|
||||
color: {
|
||||
dark: '#000000', // 二维码颜色
|
||||
light:'#ffffff' // 背景颜色
|
||||
|
||||
Reference in New Issue
Block a user