226 lines
9.9 KiB
HTML
226 lines
9.9 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<title>模拟充值收银台</title>
|
||
<style>
|
||
body { font-family: system-ui, sans-serif; background: #f5f7fa; margin: 0; padding: 24px; }
|
||
.card { max-width: 420px; margin: 40px auto; background: #fff; border-radius: 12px; padding: 24px; box-shadow: 0 4px 24px rgba(0,0,0,.08); }
|
||
h1 { font-size: 20px; margin: 0 0 8px; }
|
||
p { color: #666; line-height: 1.6; margin: 8px 0; }
|
||
.amt { font-size: 28px; color: #1677ff; font-weight: 700; margin: 16px 0; }
|
||
.countdown { font-size: 15px; color: #fa8c16; font-weight: 600; margin: 12px 0; }
|
||
.countdown.expired { color: #cf1322; }
|
||
button { width: 100%; padding: 14px; font-size: 16px; border: 0; border-radius: 8px; background: #1677ff; color: #fff; cursor: pointer; margin-top: 12px; }
|
||
button:disabled { background: #ccc; cursor: not-allowed; }
|
||
.btn-back { display: none; background: #fff; color: #cf1322; border: 1px solid #d9d9d9; }
|
||
.hint { font-size: 13px; color: #999; }
|
||
.ok { display: none; margin-top: 16px; padding: 12px; background: #f6ffed; border: 1px solid #b7eb8f; border-radius: 8px; color: #389e0d; line-height: 1.6; }
|
||
.info { margin-top: 12px; padding: 12px; background: #e6f4ff; border: 1px solid #91caff; border-radius: 8px; color: #0958d9; font-size: 14px; line-height: 1.6; }
|
||
.err { margin-top: 12px; padding: 12px; background: #fff2f0; border: 1px solid #ffccc7; border-radius: 8px; color: #cf1322; font-size: 14px; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="card">
|
||
<h1>模拟充值收银台</h1>
|
||
<p class="hint">订单号:<span id="orderNo">-</span></p>
|
||
<div id="amountBlock" style="display:none;">
|
||
<p>充值金额 <strong id="amount">-</strong>,赠送 <strong id="bonus">-</strong></p>
|
||
<div class="amt">预计到账 <span id="total">-</span></div>
|
||
</div>
|
||
<p class="countdown" id="countdown">正在加载…</p>
|
||
<p class="hint" id="expireLine"></p>
|
||
<button type="button" id="btnPay">确认支付</button>
|
||
<div class="ok" id="okBox"><strong>支付成功(模拟)</strong><br />订单已提交,需管理员在后台审核通过后才会入账。</div>
|
||
<button type="button" class="btn-back" id="btnBackGame">返回游戏</button>
|
||
<div id="msg"></div>
|
||
</div>
|
||
<script>
|
||
(function () {
|
||
var params = new URLSearchParams(window.location.search);
|
||
var orderNo = params.get('order_no') || '';
|
||
var apiBase = (params.get('api_base') || '').replace(/\/$/, '');
|
||
var expireAt = parseInt(params.get('expire_at') || '0', 10);
|
||
var sign = params.get('sign') || '';
|
||
var returnGameUrl = params.get('return_game_url') || '';
|
||
if (!apiBase) {
|
||
apiBase = window.location.protocol + '//' + window.location.hostname + (window.location.port ? ':' + window.location.port : '');
|
||
}
|
||
document.getElementById('orderNo').textContent = orderNo || '(缺少 order_no)';
|
||
|
||
var countdownEl = document.getElementById('countdown');
|
||
var expireLineEl = document.getElementById('expireLine');
|
||
var btnPay = document.getElementById('btnPay');
|
||
var btnBackGame = document.getElementById('btnBackGame');
|
||
var countdownTimer = null;
|
||
|
||
function showBackGame(url) {
|
||
var target = (url || returnGameUrl || '').trim();
|
||
if (!target) return;
|
||
returnGameUrl = target;
|
||
btnBackGame.style.display = 'block';
|
||
btnBackGame.onclick = function () {
|
||
window.location.href = returnGameUrl;
|
||
};
|
||
}
|
||
|
||
function showErr(text) {
|
||
document.getElementById('msg').innerHTML = '<div class="err">' + text + '</div>';
|
||
}
|
||
function showInfo(text) {
|
||
document.getElementById('msg').innerHTML = '<div class="info">' + text + '</div>';
|
||
}
|
||
function pad(n) { return n < 10 ? '0' + n : String(n); }
|
||
function formatTs(ts) {
|
||
var d = new Date(ts * 1000);
|
||
return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate()) + ' '
|
||
+ pad(d.getHours()) + ':' + pad(d.getMinutes()) + ':' + pad(d.getSeconds());
|
||
}
|
||
function formatRemain(sec) {
|
||
if (sec <= 0) return '00:00';
|
||
var m = Math.floor(sec / 60);
|
||
var s = sec % 60;
|
||
return pad(m) + ':' + pad(s);
|
||
}
|
||
function updateCountdown(remaining) {
|
||
if (remaining <= 0) {
|
||
countdownEl.textContent = '支付链接已过期,请返回应用重新发起充值';
|
||
countdownEl.className = 'countdown expired';
|
||
btnPay.disabled = true;
|
||
return;
|
||
}
|
||
countdownEl.textContent = '剩余支付时间 ' + formatRemain(remaining);
|
||
countdownEl.className = 'countdown';
|
||
if (expireAt > 0) {
|
||
expireLineEl.textContent = '链接有效期至 ' + formatTs(expireAt);
|
||
}
|
||
}
|
||
function startCountdown(remaining) {
|
||
if (countdownTimer) clearInterval(countdownTimer);
|
||
var left = remaining;
|
||
updateCountdown(left);
|
||
countdownTimer = setInterval(function () {
|
||
left -= 1;
|
||
updateCountdown(left);
|
||
if (left <= 0) clearInterval(countdownTimer);
|
||
}, 1000);
|
||
}
|
||
|
||
function applyStatus(data) {
|
||
var amount = data.amount;
|
||
var bonus = data.bonus_amount;
|
||
var total = data.total_amount;
|
||
if (amount !== undefined) {
|
||
document.getElementById('amount').textContent = Number(amount).toFixed(2);
|
||
document.getElementById('bonus').textContent = Number(bonus || 0).toFixed(2);
|
||
document.getElementById('total').textContent = Number(total || 0).toFixed(2);
|
||
document.getElementById('amountBlock').style.display = 'block';
|
||
}
|
||
if (data.expire_at) expireAt = data.expire_at;
|
||
var remaining = data.remaining_seconds !== undefined ? data.remaining_seconds : Math.max(0, expireAt - Math.floor(Date.now() / 1000));
|
||
startCountdown(remaining);
|
||
|
||
if (data.status === 'paid') {
|
||
showInfo('该订单已入账。');
|
||
btnPay.style.display = 'none';
|
||
showBackGame(data.return_game_url);
|
||
return;
|
||
}
|
||
if (data.status === 'pending_review') {
|
||
document.getElementById('okBox').style.display = 'block';
|
||
btnPay.style.display = 'none';
|
||
showInfo('您已提交支付,请等待管理员审核通过后到账。');
|
||
showBackGame(data.return_game_url);
|
||
return;
|
||
}
|
||
if (data.status === 'failed') {
|
||
showErr(data.reject_reason || '订单已失效或超时,请重新发起充值。');
|
||
btnPay.disabled = true;
|
||
return;
|
||
}
|
||
if (!data.can_pay) {
|
||
btnPay.disabled = true;
|
||
if (remaining <= 0) {
|
||
showErr('支付链接已过期,请返回应用重新发起充值。');
|
||
}
|
||
} else {
|
||
btnPay.disabled = false;
|
||
}
|
||
}
|
||
|
||
function loadStatus() {
|
||
if (!orderNo || !sign || expireAt <= 0) {
|
||
showErr('链接无效或缺少签名参数,请通过 App 内「去支付」打开完整链接。');
|
||
btnPay.disabled = true;
|
||
countdownEl.textContent = '';
|
||
return;
|
||
}
|
||
var statusUrl = apiBase + '/api/finance/mockDepositStatus?' + new URLSearchParams({
|
||
order_no: orderNo,
|
||
expire_at: String(expireAt),
|
||
sign: sign
|
||
}).toString();
|
||
fetch(statusUrl, { method: 'GET', credentials: 'omit' })
|
||
.then(function (r) { return r.json(); })
|
||
.then(function (res) {
|
||
if (res && res.code === 1 && res.data) {
|
||
applyStatus(res.data);
|
||
} else {
|
||
showErr((res && res.message) ? res.message : '无法加载订单信息');
|
||
btnPay.disabled = true;
|
||
}
|
||
})
|
||
.catch(function () {
|
||
showErr('无法连接支付服务,请检查网络或 api_base 配置。');
|
||
btnPay.disabled = true;
|
||
});
|
||
}
|
||
|
||
btnPay.onclick = function () {
|
||
if (!orderNo || !sign || expireAt <= 0) return;
|
||
btnPay.disabled = true;
|
||
btnPay.textContent = '处理中...';
|
||
var confirmUrl = apiBase + '/api/finance/mockDepositConfirm';
|
||
fetch(confirmUrl, {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||
body: new URLSearchParams({
|
||
order_no: orderNo,
|
||
expire_at: String(expireAt),
|
||
sign: sign
|
||
}).toString()
|
||
})
|
||
.then(function (r) { return r.json(); })
|
||
.then(function (res) {
|
||
if (res && res.code === 1) {
|
||
document.getElementById('okBox').style.display = 'block';
|
||
btnPay.style.display = 'none';
|
||
document.getElementById('msg').innerHTML = '';
|
||
if (countdownTimer) clearInterval(countdownTimer);
|
||
countdownEl.textContent = '已提交,等待后台审核';
|
||
countdownEl.className = 'countdown';
|
||
if (res.data && res.data.return_game_url) {
|
||
showBackGame(res.data.return_game_url);
|
||
} else {
|
||
showBackGame('');
|
||
}
|
||
} else {
|
||
showErr((res && res.message) ? res.message : '提交失败');
|
||
btnPay.disabled = false;
|
||
btnPay.textContent = '确认支付';
|
||
}
|
||
})
|
||
.catch(function () {
|
||
showErr('网络错误,请稍后重试。');
|
||
btnPay.disabled = false;
|
||
btnPay.textContent = '确认支付';
|
||
});
|
||
};
|
||
|
||
loadStatus();
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|