彩先知pc
This commit is contained in:
@@ -0,0 +1,894 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title id="page-title">彩先知 - 充值</title>
|
||||
<script src="../public/css/layui/layui.js"></script>
|
||||
<script src="../config.js"></script>
|
||||
<script src="../utils/ApiClient.js"></script>
|
||||
<script src="../utils/DateUtil.js"></script>
|
||||
<script src="../utils/CommonUtil.js"></script>
|
||||
<link rel="stylesheet" href="../public/css/layui/css/layui.css" />
|
||||
<link rel="stylesheet" href="../public/css/public.css" />
|
||||
<link rel="stylesheet" href="../public/css/publish.css" />
|
||||
<link rel="stylesheet" href="../public/css/finance.css" />
|
||||
</head>
|
||||
<body>
|
||||
<!-- Header -->
|
||||
<nav class="topbar" id="navbar">
|
||||
<div class="topbar__inner">
|
||||
<a href="index.html" class="topbar__brand">
|
||||
<img
|
||||
src="../images/home-logo.png"
|
||||
alt="彩先知"
|
||||
class="topbar__logo"
|
||||
/>
|
||||
</a>
|
||||
<div class="topbar__nav" id="navLotteryItems"></div>
|
||||
<div class="topbar__user">
|
||||
<div id="notLoggedInBox" class="topbar__guest">
|
||||
<a href="login.html" class="topbar__btn topbar__btn--ghost">登录</a>
|
||||
<a href="reg.html" class="topbar__btn topbar__btn--primary"
|
||||
>免费注册</a
|
||||
>
|
||||
</div>
|
||||
<div id="loggedInBox" class="topbar__logged" style="display: none">
|
||||
<a href="usercenter.html" class="topbar__profile">
|
||||
<img
|
||||
id="userAvatar"
|
||||
src="../public/img/userimg.png"
|
||||
alt=""
|
||||
class="topbar__avatar"
|
||||
/>
|
||||
<div class="topbar__meta">
|
||||
<span id="userName" class="topbar__uname">用户</span>
|
||||
<span id="userLevel" class="topbar__ubadge">会员</span>
|
||||
</div>
|
||||
</a>
|
||||
<button class="topbar__btn topbar__btn--logout" onclick="logout()">
|
||||
退出登录
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Main -->
|
||||
<main class="cxz-main">
|
||||
<div class="cxz-breadcrumb">
|
||||
<a href="index.html">首页</a><span class="sep">></span>
|
||||
<a href="usercenter.html">个人中心</a><span class="sep">></span>
|
||||
<span>充值</span>
|
||||
</div>
|
||||
|
||||
<!-- Balance Overview -->
|
||||
<div class="cz-balance-bar">
|
||||
<div class="cz-balance-bar__item">
|
||||
<div
|
||||
class="cz-balance-bar__icon"
|
||||
style="background: rgba(16, 43, 106, 0.08); color: var(--primary)"
|
||||
>
|
||||
<i class="layui-icon layui-icon-rmb"></i>
|
||||
</div>
|
||||
<div class="cz-balance-bar__info">
|
||||
<div class="cz-balance-bar__label">账户余额</div>
|
||||
<div class="cz-balance-bar__value" id="currentBalance">
|
||||
0.00<span class="unit">元</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Package Selection -->
|
||||
<div class="cxz-form-card">
|
||||
<div class="cxz-form-title">选择充值套餐</div>
|
||||
|
||||
<div class="cz-package-grid" id="packageGrid">
|
||||
<div class="cz-package-loading">
|
||||
<i
|
||||
class="layui-icon layui-icon-loading-1 layui-anim layui-anim-rotate layui-anim-loop"
|
||||
></i>
|
||||
<span>加载套餐中...</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="cxz-submit-btn"
|
||||
id="rechargeBtn"
|
||||
onclick="handleRecharge()"
|
||||
>
|
||||
立即充值
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- QR Code Payment Section -->
|
||||
<div class="cxz-form-card" id="qrcodeCard" style="display: none">
|
||||
<div class="cz-qr-section" id="qrSection">
|
||||
<div class="cz-qr-header">
|
||||
<div class="cz-qr-icon">
|
||||
<i class="layui-icon layui-icon-cellphone"></i>
|
||||
</div>
|
||||
<div class="cz-qr-title">微信扫码支付</div>
|
||||
<div class="cz-qr-subtitle">请使用微信扫描下方二维码完成支付</div>
|
||||
</div>
|
||||
<div class="cz-qr-amount" id="payAmountDisplay">0<span>元</span></div>
|
||||
<div class="cz-qr-wrap">
|
||||
<div id="qrcodeContainer"></div>
|
||||
</div>
|
||||
<div class="cz-qr-hint">
|
||||
二维码有效期 <strong>5分钟</strong>,请尽快完成支付
|
||||
</div>
|
||||
<div class="cz-qr-timer">
|
||||
剩余时间:<span id="countdownTimer">05:00</span>
|
||||
</div>
|
||||
<button class="cz-qr-cancel" onclick="cancelPayment()">
|
||||
取消支付
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="cz-pay-result" id="paymentSuccess" style="display: none">
|
||||
<div class="cz-pay-result__icon success">
|
||||
<i class="layui-icon layui-icon-ok-circle"></i>
|
||||
</div>
|
||||
<div class="cz-pay-result__title">支付成功</div>
|
||||
<div class="cz-pay-result__desc">充值金额已到账,请查看余额</div>
|
||||
<a href="usercenter.html" class="cz-pay-result__btn">返回个人中心</a>
|
||||
</div>
|
||||
|
||||
<div class="cz-pay-result" id="paymentTimeout" style="display: none">
|
||||
<div class="cz-pay-result__icon timeout">
|
||||
<i class="layui-icon layui-icon-close-fill"></i>
|
||||
</div>
|
||||
<div class="cz-pay-result__title">支付超时</div>
|
||||
<div class="cz-pay-result__desc">二维码已过期,请重新发起充值</div>
|
||||
<button class="cz-pay-result__btn" onclick="resetPayment()">
|
||||
重新充值
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tips -->
|
||||
<div class="cz-tips-card">
|
||||
<div class="cz-tips-title">
|
||||
<i class="layui-icon layui-icon-about"></i> 充值说明
|
||||
</div>
|
||||
<ul class="cz-tips-list">
|
||||
<li>充值后余额将实时到账,可用于购买付费方案</li>
|
||||
<li>微信扫码支付请在5分钟内完成,超时需重新发起</li>
|
||||
<li>如遇支付问题,请联系客服处理</li>
|
||||
<li>充值金额不支持退款,请确认后再支付</li>
|
||||
</ul>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="site-footer">
|
||||
<div class="site-footer__inner">
|
||||
<img
|
||||
src="../images/home-logo.png"
|
||||
alt="彩先知"
|
||||
class="site-footer__logo"
|
||||
/>
|
||||
<p id="copyright-info">彩先知以开奖数据、免费文章、资讯推荐为核心</p>
|
||||
<div class="site-footer__meta">
|
||||
<a
|
||||
id="beian"
|
||||
href="https://beian.miit.gov.cn/"
|
||||
target="_blank"
|
||||
style="font-size: 12px; color: rgba(255, 255, 255, 0.5)"
|
||||
>工信部备案号</a
|
||||
>
|
||||
<span id="additional-info">本站仅供数据分析参考</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<button
|
||||
class="gotop"
|
||||
id="backTop"
|
||||
type="button"
|
||||
onclick="window.scrollTo({ top: 0, behavior: 'smooth' })"
|
||||
>
|
||||
↑
|
||||
</button>
|
||||
|
||||
<script src="../public/js/qrcode.min.js"></script>
|
||||
<style>
|
||||
/* Balance Bar */
|
||||
.cz-balance-bar {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 16px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.cz-balance-bar__item {
|
||||
background: var(--white);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 20px 24px;
|
||||
box-shadow: var(--shadow-sm);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
border: 1px solid var(--border-light);
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.cz-balance-bar__item:hover {
|
||||
border-color: transparent;
|
||||
box-shadow: var(--shadow-md);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.cz-balance-bar__icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 22px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.cz-balance-bar__label {
|
||||
font-size: 13px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.cz-balance-bar__value {
|
||||
font-size: 24px;
|
||||
font-weight: 800;
|
||||
color: var(--text-dark);
|
||||
line-height: 1.2;
|
||||
}
|
||||
.cz-balance-bar__value .unit {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: var(--text-muted);
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
/* Package Grid */
|
||||
.cz-package-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 14px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.cz-package-loading {
|
||||
grid-column: 1/-1;
|
||||
text-align: center;
|
||||
padding: 40px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.cz-package-loading i {
|
||||
font-size: 28px;
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
color: var(--primary);
|
||||
}
|
||||
.cz-pkg {
|
||||
position: relative;
|
||||
background: var(--bg-light);
|
||||
border: 2px solid var(--border-light);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 20px 16px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
user-select: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
.cz-pkg:hover {
|
||||
border-color: var(--primary);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
.cz-pkg.selected {
|
||||
border-color: var(--primary);
|
||||
background: rgba(16, 43, 106, 0.04);
|
||||
box-shadow: 0 0 0 3px rgba(16, 43, 106, 0.12);
|
||||
}
|
||||
.cz-pkg.selected::after {
|
||||
content: "\2713";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background: var(--primary);
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 0 var(--radius-lg) 0 var(--radius-lg);
|
||||
}
|
||||
.cz-pkg__price {
|
||||
font-size: 28px;
|
||||
font-weight: 800;
|
||||
color: var(--primary);
|
||||
line-height: 1.2;
|
||||
}
|
||||
.cz-pkg__price span {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.cz-pkg__credit {
|
||||
display: inline-block;
|
||||
margin-top: 8px;
|
||||
padding: 3px 10px;
|
||||
border-radius: 999px;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
background: rgba(253, 185, 51, 0.12);
|
||||
color: var(--gold);
|
||||
}
|
||||
.cz-pkg__bonus {
|
||||
display: inline-block;
|
||||
margin-top: 4px;
|
||||
padding: 2px 8px;
|
||||
border-radius: 999px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
background: rgba(241, 90, 34, 0.1);
|
||||
color: var(--orange);
|
||||
}
|
||||
.cz-pkg.selected .cz-pkg__price {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
/* Hot / Recommend tag */
|
||||
.cz-pkg__tag {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
left: 8px;
|
||||
padding: 2px 8px;
|
||||
border-radius: 999px;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.5px;
|
||||
color: #fff;
|
||||
}
|
||||
.cz-pkg__tag.hot {
|
||||
background: linear-gradient(135deg, #ff6b35, #f15a22);
|
||||
}
|
||||
.cz-pkg__tag.rec {
|
||||
background: linear-gradient(135deg, var(--primary), #1a3f8f);
|
||||
}
|
||||
|
||||
/* QR Code Section */
|
||||
.cz-qr-section {
|
||||
text-align: center;
|
||||
padding: 24px 0;
|
||||
}
|
||||
.cz-qr-header {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.cz-qr-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: rgba(7, 193, 96, 0.1);
|
||||
color: #07c160;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 24px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.cz-qr-title {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: var(--text-dark);
|
||||
}
|
||||
.cz-qr-subtitle {
|
||||
font-size: 13px;
|
||||
color: var(--text-muted);
|
||||
margin-top: 4px;
|
||||
}
|
||||
.cz-qr-amount {
|
||||
font-size: 32px;
|
||||
font-weight: 800;
|
||||
color: var(--orange);
|
||||
margin: 16px 0;
|
||||
}
|
||||
.cz-qr-amount span {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.cz-qr-wrap {
|
||||
display: inline-block;
|
||||
padding: 16px;
|
||||
background: #fff;
|
||||
border: 2px solid var(--border-light);
|
||||
border-radius: var(--radius-lg);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.cz-qr-wrap img,
|
||||
.cz-qr-wrap canvas {
|
||||
display: block;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
.cz-qr-hint {
|
||||
font-size: 13px;
|
||||
color: var(--text-muted);
|
||||
margin-top: 8px;
|
||||
}
|
||||
.cz-qr-timer {
|
||||
font-size: 14px;
|
||||
color: var(--orange);
|
||||
margin-top: 8px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.cz-qr-cancel {
|
||||
margin-top: 16px;
|
||||
padding: 8px 24px;
|
||||
border: 1px solid var(--border-light);
|
||||
border-radius: 999px;
|
||||
background: transparent;
|
||||
color: var(--text-muted);
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
transition: all 0.25s;
|
||||
}
|
||||
.cz-qr-cancel:hover {
|
||||
border-color: var(--primary);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
/* Payment Result */
|
||||
.cz-pay-result {
|
||||
text-align: center;
|
||||
padding: 40px 0;
|
||||
}
|
||||
.cz-pay-result__icon {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
border-radius: 50%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 36px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.cz-pay-result__icon.success {
|
||||
background: rgba(40, 167, 69, 0.12);
|
||||
color: var(--green);
|
||||
}
|
||||
.cz-pay-result__icon.timeout {
|
||||
background: rgba(255, 193, 7, 0.15);
|
||||
color: #ffc107;
|
||||
}
|
||||
.cz-pay-result__title {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: var(--text-dark);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.cz-pay-result__desc {
|
||||
font-size: 13px;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.cz-pay-result__btn {
|
||||
display: inline-block;
|
||||
padding: 10px 32px;
|
||||
border-radius: 999px;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
background: linear-gradient(135deg, var(--primary), #1a3f8f);
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.cz-pay-result__btn:hover {
|
||||
box-shadow: 0 6px 20px rgba(16, 43, 106, 0.4);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
/* Tips Card */
|
||||
.cz-tips-card {
|
||||
background: var(--white);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 20px 24px;
|
||||
border: 1px solid var(--border-light);
|
||||
margin-top: 24px;
|
||||
}
|
||||
.cz-tips-title {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: var(--text-dark);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.cz-tips-title i {
|
||||
color: var(--primary);
|
||||
margin-right: 4px;
|
||||
}
|
||||
.cz-tips-list {
|
||||
margin: 0;
|
||||
padding-left: 18px;
|
||||
}
|
||||
.cz-tips-list li {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
line-height: 2;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {
|
||||
.cz-balance-bar {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.cz-package-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
.cz-pkg {
|
||||
padding: 16px 12px;
|
||||
}
|
||||
.cz-pkg__price {
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.cz-package-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 8px;
|
||||
}
|
||||
.cz-pkg__price {
|
||||
font-size: 20px;
|
||||
}
|
||||
.cz-pkg__credit {
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
const $ = layui.$;
|
||||
var configList = [];
|
||||
var selectedConfigId = "";
|
||||
var selectedConfigAmount = 0;
|
||||
var pollingTimer = null;
|
||||
var countdownTimer = null;
|
||||
var countdownSeconds = 300;
|
||||
var pollingStartTime = 0;
|
||||
var MAX_POLLING_DURATION = 300000;
|
||||
|
||||
function escapeHtml(value) {
|
||||
return String(value == null ? "" : value)
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
function logout() {
|
||||
localStorage.removeItem("token");
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
function checkLogin() {
|
||||
var token = localStorage.getItem("token");
|
||||
if (token) {
|
||||
$("#notLoggedInBox").hide();
|
||||
$("#loggedInBox").css("display", "flex");
|
||||
CommonUtil.getCurrentUserDetail(
|
||||
function (data) {
|
||||
$("#userName").text(data.nickName || "用户");
|
||||
$("#userLevel").text(data.isExpert === "1" ? "专家" : "会员");
|
||||
if (data.avatar) $("#userAvatar").attr("src", data.avatar);
|
||||
var accountBalance = Number(
|
||||
data.accountBalance || data.balance || data.amount || 0,
|
||||
);
|
||||
$("#currentBalance").html(
|
||||
(Number.isFinite(accountBalance) ? accountBalance : 0).toFixed(2) +
|
||||
'<span class="unit">\u5143</span>',
|
||||
);
|
||||
},
|
||||
function () {
|
||||
$("#notLoggedInBox").show();
|
||||
$("#loggedInBox").hide();
|
||||
},
|
||||
);
|
||||
} else {
|
||||
window.location.href = "login.html";
|
||||
}
|
||||
}
|
||||
|
||||
function renderNav() {
|
||||
ApiClient.get(ApiClient.API.homeNav).then(function (res) {
|
||||
if (!ApiClient.isSuccess(res) || !res.data) return;
|
||||
var $nav = $("#navLotteryItems");
|
||||
$nav.find(".topbar__nav-link").not(":first").remove();
|
||||
$.each(ApiClient.asArray(res.data), function (i, item) {
|
||||
if (item.type && item.type !== "lottery") return;
|
||||
var code = item.code || item.suoxie || "";
|
||||
if (!code) return;
|
||||
$nav.append(
|
||||
'<a href="cai.html?id=' +
|
||||
encodeURIComponent(code) +
|
||||
'" class="topbar__nav-link">' +
|
||||
escapeHtml(item.name || item.lotteryName || code) +
|
||||
"</a>",
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$(window).on("scroll", function () {
|
||||
$(window).scrollTop() > 320
|
||||
? $("#backTop").addClass("is-visible")
|
||||
: $("#backTop").removeClass("is-visible");
|
||||
});
|
||||
|
||||
// Load packages from API
|
||||
function loadConfigList() {
|
||||
ApiClient.get(ApiClient.API.walletRechargeConfigList)
|
||||
.then(function (res) {
|
||||
var data = ApiClient.pickData ? ApiClient.pickData(res) : res.data;
|
||||
var list = ApiClient.asArray(data);
|
||||
if (ApiClient.isSuccess(res) && list.length > 0) {
|
||||
configList = list;
|
||||
// Sort by sort field
|
||||
configList.sort(function (a, b) {
|
||||
return (a.sort || 0) - (b.sort || 0);
|
||||
});
|
||||
renderPackages(configList);
|
||||
} else {
|
||||
renderEmptyPackages();
|
||||
}
|
||||
})
|
||||
.catch(function () {
|
||||
renderEmptyPackages("加载失败,请刷新重试");
|
||||
});
|
||||
}
|
||||
|
||||
function formatMoney(value) {
|
||||
var number = Number(value || 0);
|
||||
return Number.isFinite(number) ? number.toFixed(2) : "0.00";
|
||||
}
|
||||
|
||||
function renderPackages(list) {
|
||||
var $grid = $("#packageGrid");
|
||||
$grid.empty();
|
||||
|
||||
$.each(list, function (i, item) {
|
||||
var paidAmount =
|
||||
parseFloat(item.paidAmount || item.amount || item.price) || 0;
|
||||
var totalCredited =
|
||||
parseFloat(
|
||||
item.totalCredited ||
|
||||
item.arrivalAmount ||
|
||||
item.creditedAmount ||
|
||||
item.receiveAmount,
|
||||
) || paidAmount;
|
||||
var bonus =
|
||||
parseFloat(item.giftAmount || item.bonusAmount || item.giveAmount) ||
|
||||
totalCredited - paidAmount;
|
||||
var bonusRate =
|
||||
paidAmount > 0 ? Math.round((bonus / paidAmount) * 100) : 0;
|
||||
|
||||
var tagHtml = "";
|
||||
if (bonusRate >= 80) {
|
||||
tagHtml = '<div class="cz-pkg__tag hot">超值</div>';
|
||||
} else if (bonusRate >= 30) {
|
||||
tagHtml = '<div class="cz-pkg__tag rec">推荐</div>';
|
||||
}
|
||||
|
||||
var creditHtml =
|
||||
'<div class="cz-pkg__credit">\u5230\u8d26 ' +
|
||||
formatMoney(totalCredited) +
|
||||
" \u5143</div>";
|
||||
var bonusHtml =
|
||||
bonus > 0
|
||||
? '<div class="cz-pkg__bonus">\u8d60 ' +
|
||||
formatMoney(bonus) +
|
||||
" \u5143</div>"
|
||||
: "";
|
||||
|
||||
var selectedClass = i === 0 ? " selected" : "";
|
||||
if (i === 0) {
|
||||
selectedConfigId = item.id;
|
||||
selectedConfigAmount = paidAmount;
|
||||
}
|
||||
|
||||
$grid.append(
|
||||
'<div class="cz-pkg' +
|
||||
selectedClass +
|
||||
'" data-id="' +
|
||||
item.id +
|
||||
'" data-amount="' +
|
||||
paidAmount +
|
||||
'" onclick="selectPackage(this)">' +
|
||||
tagHtml +
|
||||
'<div class="cz-pkg__price">' +
|
||||
formatMoney(paidAmount) +
|
||||
"<span>\u5143</span></div>" +
|
||||
creditHtml +
|
||||
bonusHtml +
|
||||
"</div>",
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function renderEmptyPackages(msg) {
|
||||
$("#packageGrid").html(
|
||||
'<div class="cz-package-loading">' +
|
||||
'<i class="layui-icon layui-icon-face-surprised"></i>' +
|
||||
"<span>" +
|
||||
(msg || "暂无充值套餐") +
|
||||
"</span>" +
|
||||
"</div>",
|
||||
);
|
||||
}
|
||||
|
||||
function selectPackage(el) {
|
||||
$(".cz-pkg").removeClass("selected");
|
||||
$(el).addClass("selected");
|
||||
selectedConfigId = $(el).data("id");
|
||||
selectedConfigAmount = parseFloat($(el).data("amount")) || 0;
|
||||
}
|
||||
|
||||
// Handle recharge
|
||||
function handleRecharge() {
|
||||
if (!selectedConfigId) {
|
||||
layui.layer.msg("请选择充值套餐", { icon: 2 });
|
||||
return;
|
||||
}
|
||||
|
||||
var $btn = $("#rechargeBtn");
|
||||
$btn.text("正在生成订单...").prop("disabled", true);
|
||||
|
||||
ApiClient.post(ApiClient.API.walletRechargeOrder, {
|
||||
rechargeId: selectedConfigId,
|
||||
})
|
||||
.then(function (res) {
|
||||
$btn.text("\u7acb\u5373\u5145\u503c").prop("disabled", false);
|
||||
var data = ApiClient.pickData ? ApiClient.pickData(res) : res.data;
|
||||
if (ApiClient.isSuccess(res) && data) {
|
||||
var payUrl = getRechargePaymentUrl(data);
|
||||
var amount = data.amount || data.paidAmount || selectedConfigAmount;
|
||||
if (!payUrl) {
|
||||
layui.layer.msg("\u8ba2\u5355\u672a\u8fd4\u56de\u652f\u4ed8\u4e8c\u7ef4\u7801\u5185\u5bb9", { icon: 2 });
|
||||
return;
|
||||
}
|
||||
showQRCode(payUrl, amount);
|
||||
} else {
|
||||
layui.layer.msg(res.msg || "创建订单失败", { icon: 2 });
|
||||
}
|
||||
})
|
||||
.catch(function () {
|
||||
$btn.text("立即充值").prop("disabled", false);
|
||||
layui.layer.msg("网络错误,请稍后重试", { icon: 2 });
|
||||
});
|
||||
}
|
||||
|
||||
function getRechargePaymentUrl(data) {
|
||||
if (typeof data === "string") return data;
|
||||
if (!data || typeof data !== "object") return "";
|
||||
return (
|
||||
data.qrCode ||
|
||||
data.payUrl ||
|
||||
data.paymentUrl ||
|
||||
data.codeUrl ||
|
||||
data.qrCodeUrl ||
|
||||
data.nativeUrl ||
|
||||
data.url ||
|
||||
""
|
||||
);
|
||||
}
|
||||
|
||||
// Show QR code
|
||||
function showQRCode(url, amount) {
|
||||
$("#qrcodeCard").show();
|
||||
$("#qrSection").show();
|
||||
$("#paymentSuccess").hide();
|
||||
$("#paymentTimeout").hide();
|
||||
$("#qrcodeContainer").empty();
|
||||
|
||||
$("#payAmountDisplay").html(amount + "<span>元</span>");
|
||||
|
||||
new QRCode(document.getElementById("qrcodeContainer"), {
|
||||
text: url,
|
||||
width: 200,
|
||||
height: 200,
|
||||
colorDark: "#102b6a",
|
||||
colorLight: "#ffffff",
|
||||
correctLevel: QRCode.CorrectLevel.H,
|
||||
});
|
||||
|
||||
countdownSeconds = 300;
|
||||
pollingStartTime = Date.now();
|
||||
startCountdown();
|
||||
|
||||
$("html,body").animate(
|
||||
{ scrollTop: $("#qrcodeCard").offset().top - 20 },
|
||||
400,
|
||||
);
|
||||
}
|
||||
|
||||
// Countdown
|
||||
function startCountdown() {
|
||||
if (countdownTimer) clearInterval(countdownTimer);
|
||||
countdownTimer = setInterval(function () {
|
||||
countdownSeconds--;
|
||||
if (countdownSeconds <= 0) {
|
||||
clearInterval(countdownTimer);
|
||||
stopPolling();
|
||||
$("#qrSection").hide();
|
||||
$("#paymentTimeout").show();
|
||||
return;
|
||||
}
|
||||
var min = Math.floor(countdownSeconds / 60);
|
||||
var sec = countdownSeconds % 60;
|
||||
$("#countdownTimer").text(
|
||||
(min < 10 ? "0" + min : min) + ":" + (sec < 10 ? "0" + sec : sec),
|
||||
);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
// Polling for payment confirmation
|
||||
function startPolling() {
|
||||
stopPolling();
|
||||
doPoll();
|
||||
}
|
||||
|
||||
function doPoll() {
|
||||
var elapsed = Date.now() - pollingStartTime;
|
||||
if (elapsed >= MAX_POLLING_DURATION) {
|
||||
stopPolling();
|
||||
clearInterval(countdownTimer);
|
||||
$("#qrSection").hide();
|
||||
$("#paymentTimeout").show();
|
||||
return;
|
||||
}
|
||||
|
||||
scheduleNextPoll();
|
||||
}
|
||||
|
||||
function scheduleNextPoll() {
|
||||
var delay = 1000 + Math.floor(Math.random() * 4000);
|
||||
pollingTimer = setTimeout(doPoll, delay);
|
||||
}
|
||||
|
||||
function stopPolling() {
|
||||
if (pollingTimer) {
|
||||
clearTimeout(pollingTimer);
|
||||
pollingTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
function cancelPayment() {
|
||||
stopPolling();
|
||||
if (countdownTimer) clearInterval(countdownTimer);
|
||||
$("#qrcodeCard").hide();
|
||||
}
|
||||
|
||||
function resetPayment() {
|
||||
$("#paymentTimeout").hide();
|
||||
$("#qrSection").hide();
|
||||
$("#qrcodeCard").hide();
|
||||
$("html,body").animate({ scrollTop: 0 }, 300);
|
||||
}
|
||||
|
||||
// Init
|
||||
$(function () {
|
||||
checkLogin();
|
||||
renderNav();
|
||||
CommonUtil.loadPageConfig({ ads: false, links: false });
|
||||
CommonUtil.requireAuth(function () {
|
||||
loadConfigList();
|
||||
});
|
||||
});
|
||||
|
||||
$(window).on("beforeunload", function () {
|
||||
stopPolling();
|
||||
if (countdownTimer) clearInterval(countdownTimer);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user