819 lines
39 KiB
HTML
819 lines
39 KiB
HTML
<!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/tixian.css" />
|
||
</head>
|
||
<body>
|
||
<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 tx-hidden">
|
||
<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 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>
|
||
|
||
<div class="tx-balance-grid">
|
||
<div class="tx-balance-card">
|
||
<div class="tx-balance-icon account">
|
||
<i class="layui-icon layui-icon-rmb"></i>
|
||
</div>
|
||
<div class="tx-balance-info">
|
||
<div class="tx-balance-label">账户余额</div>
|
||
<div class="tx-balance-value" id="accountBalance">0.00<span class="unit">元</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="tx-balance-card">
|
||
<div class="tx-balance-icon sales">
|
||
<i class="layui-icon layui-icon-group"></i>
|
||
</div>
|
||
<div class="tx-balance-info">
|
||
<div class="tx-balance-label">销售余额</div>
|
||
<div class="tx-balance-value" id="salesBalance">0.00<span class="unit">元</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="tx-balance-card">
|
||
<div class="tx-balance-icon expert">
|
||
<i class="layui-icon layui-icon-star-fill"></i>
|
||
</div>
|
||
<div class="tx-balance-info">
|
||
<div class="tx-balance-label">专家余额</div>
|
||
<div class="tx-balance-value" id="expertBalance">0.00<span class="unit">元</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="tx-balance-card">
|
||
<div class="tx-balance-icon withdrawable">
|
||
<i class="layui-icon layui-icon-ok-circle"></i>
|
||
</div>
|
||
<div class="tx-balance-info">
|
||
<div class="tx-balance-label">可提现金额</div>
|
||
<div class="tx-balance-value" id="withdrawableAmount">0.00<span class="unit">元</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="tx-balance-card">
|
||
<div class="tx-balance-icon frozen">
|
||
<i class="layui-icon layui-icon-password"></i>
|
||
</div>
|
||
<div class="tx-balance-info">
|
||
<div class="tx-balance-label">冻结金额</div>
|
||
<div class="tx-balance-value" id="frozenAmount">0.00<span class="unit">元</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="publish-tab-bar tx-tab-bar">
|
||
<div class="publish-tab-item active" data-tab="withdraw" onclick="switchTab('withdraw')">提现</div>
|
||
<div class="publish-tab-item" data-tab="transfer" onclick="switchTab('transfer')">余额转入</div>
|
||
<a href="tixianlist.html" class="publish-tab-item">提现记录</a>
|
||
</div>
|
||
|
||
<div class="tx-panel active" id="panelWithdraw">
|
||
<div class="cxz-form-card">
|
||
<div class="cxz-form-title">申请提现</div>
|
||
|
||
<div class="cxz-form-group">
|
||
<label class="cxz-form-label">提现来源 <span class="required">*</span></label>
|
||
<input id="withdrawSource" type="hidden" value="sales" />
|
||
<div class="tx-choice-grid" id="withdrawSourceCards"></div>
|
||
</div>
|
||
|
||
<div class="cxz-form-group">
|
||
<label class="cxz-form-label">可提现金额</label>
|
||
<div class="tx-available" id="withdrawAvailableAmount">0.00 元</div>
|
||
</div>
|
||
|
||
<div class="cxz-form-group">
|
||
<label class="cxz-form-label">提现金额 <span class="required">*</span></label>
|
||
<div class="tx-amount-row">
|
||
<input class="cxz-form-input" id="withdrawAmount" type="number" min="1" step="0.01" placeholder="请输入提现金额" />
|
||
<button class="tx-all-btn" id="withdrawAll" type="button">全部</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="cxz-form-group">
|
||
<label class="cxz-form-label">提现方式 <span class="required">*</span></label>
|
||
<input id="withdrawMethod" type="hidden" value="alipay" />
|
||
<input id="receiveAccountId" type="hidden" />
|
||
<div class="tx-method-grid" id="withdrawMethodCards"></div>
|
||
</div>
|
||
|
||
<div class="cxz-form-group">
|
||
<div class="tx-account-head">
|
||
<label class="cxz-form-label tx-label-tight">收款账户 <span class="required">*</span></label>
|
||
<button class="tx-link-btn" type="button" onclick="openAddAccount()">新增收款账户</button>
|
||
</div>
|
||
<div class="tx-account-grid" id="receiveAccountCards"></div>
|
||
<div class="tx-add-panel" id="addAccountPanel"></div>
|
||
<div class="tx-note" id="withdrawHint">请选择或新增对应提现方式的收款账户。</div>
|
||
</div>
|
||
|
||
<button class="cxz-submit-btn" id="withdrawSubmitBtn" onclick="submitWithdraw()">确认提现</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tx-panel" id="panelTransfer">
|
||
<div class="cxz-form-card">
|
||
<div class="cxz-form-title">余额转入</div>
|
||
|
||
<div class="cxz-form-group">
|
||
<label class="cxz-form-label">转出来源 <span class="required">*</span></label>
|
||
<input id="transferSource" type="hidden" value="sales" />
|
||
<div class="tx-choice-grid" id="transferSourceCards"></div>
|
||
</div>
|
||
|
||
<div class="cxz-form-group">
|
||
<label class="cxz-form-label">可转余额</label>
|
||
<div class="tx-available" id="transferAvailableAmount">0.00 元</div>
|
||
</div>
|
||
|
||
<div class="cxz-form-group">
|
||
<label class="cxz-form-label">转入金额 <span class="required">*</span></label>
|
||
<div class="tx-amount-row">
|
||
<input class="cxz-form-input" id="transferAmount" type="number" min="1" step="0.01" placeholder="请输入转入账户余额的金额" />
|
||
<button class="tx-all-btn" id="transferAll" type="button">全部</button>
|
||
</div>
|
||
<div class="tx-note">转入账户余额后,可用于购买付费文章、专家预测或其他站内服务。</div>
|
||
</div>
|
||
|
||
<button class="cxz-submit-btn" id="transferSubmitBtn" onclick="submitTransfer()">确认转入</button>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
|
||
<div class="tx-modal-mask" id="receiveAccountEditMask">
|
||
<div class="tx-modal">
|
||
<div class="tx-modal-head">
|
||
<div class="tx-modal-title">编辑收款账户</div>
|
||
<button class="tx-modal-close" type="button" onclick="closeReceiveAccountEdit()">×</button>
|
||
</div>
|
||
<div class="tx-modal-body">
|
||
<div id="receiveAccountEditBody"></div>
|
||
<div class="tx-modal-actions">
|
||
<button class="tx-secondary-btn" type="button" onclick="closeReceiveAccountEdit()">取消</button>
|
||
<button class="tx-small-btn" type="button" onclick="saveReceiveAccountEdit()">保存修改</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<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" class="tx-beian-link" href="https://beian.miit.gov.cn/" target="_blank">工信部备案号</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>
|
||
const $ = layui.$;
|
||
let receiveAccounts = [];
|
||
let editingReceiveAccountId = "";
|
||
let userBalances = { account: 0, sales: 0, expert: 0, withdrawable: 0, frozen: 0 };
|
||
|
||
const walletSourceOptions = [
|
||
{ value: "sales", title: "销售余额", desc: "销售返佣可提现或转入账户余额" },
|
||
{ value: "expert", title: "专家余额", desc: "专家收益可提现或转入账户余额" },
|
||
];
|
||
|
||
const withdrawMethodOptions = [
|
||
{ value: "alipay", title: "支付宝", desc: "支持支付宝账号或收款二维码" },
|
||
{ value: "wechat_qr", title: "微信", desc: "使用微信收款二维码" },
|
||
{ value: "bank", title: "银行卡", desc: "绑定银行卡收款" },
|
||
];
|
||
|
||
function logout() {
|
||
localStorage.removeItem("token");
|
||
window.location.reload();
|
||
}
|
||
|
||
function isSuccess(res) {
|
||
return ApiClient.isSuccess ? ApiClient.isSuccess(res) : res && (res.code === 0 || res.code === 200);
|
||
}
|
||
|
||
function pickData(res) {
|
||
return ApiClient.pickData ? ApiClient.pickData(res) : res && res.data;
|
||
}
|
||
|
||
function asArray(value) {
|
||
return ApiClient.asArray ? ApiClient.asArray(value) : Array.isArray(value) ? value : value ? [value] : [];
|
||
}
|
||
|
||
function escapeHtml(value) {
|
||
return String(value == null ? "" : value)
|
||
.replace(/&/g, "&")
|
||
.replace(/</g, "<")
|
||
.replace(/>/g, ">")
|
||
.replace(/"/g, """)
|
||
.replace(/'/g, "'");
|
||
}
|
||
|
||
function fieldValue(item, keys) {
|
||
for (let i = 0; i < keys.length; i += 1) {
|
||
const value = item && item[keys[i]];
|
||
if (value !== undefined && value !== null && value !== "") return value;
|
||
}
|
||
return "";
|
||
}
|
||
|
||
function money(value) {
|
||
const number = Number(value || 0);
|
||
return Number.isFinite(number) ? number.toFixed(2) : "0.00";
|
||
}
|
||
|
||
function normalizeReceiveType(type) {
|
||
const value = String(type || "").toLowerCase();
|
||
if (value === "wechat") return "wechat_qr";
|
||
if (value === "alipay_qr" || value === "alipay_qrcode") return "alipay";
|
||
return value;
|
||
}
|
||
|
||
function getAccountId(item) {
|
||
return fieldValue(item, ["id", "receiveAccountId", "accountId"]);
|
||
}
|
||
|
||
function getAccountById(id) {
|
||
return receiveAccounts.find((item) => String(getAccountId(item)) === String(id)) || null;
|
||
}
|
||
|
||
function getSourceAmount(source) {
|
||
return Number(userBalances[source] || 0);
|
||
}
|
||
|
||
function getQrcodeUrl(item) {
|
||
return fieldValue(item, ["qrcodeUrl", "qrCodeUrl", "ossUrl", "url", "fileUrl"]);
|
||
}
|
||
|
||
function getQrcodeFileId(item) {
|
||
return fieldValue(item, ["qrCodeFileId", "qrcodeFileId", "qrcodeOssId", "ossId", "fileId"]);
|
||
}
|
||
|
||
function hasQrcode(item) {
|
||
return Boolean(getQrcodeUrl(item) || getQrcodeFileId(item));
|
||
}
|
||
|
||
function getReceiveTypeText(type) {
|
||
const value = normalizeReceiveType(type);
|
||
if (value === "bank") return "银行卡";
|
||
if (value === "wechat_qr") return "微信";
|
||
return "支付宝";
|
||
}
|
||
|
||
function getReceiveAccountText(item) {
|
||
const type = normalizeReceiveType(item.receiveType || item.withdrawType);
|
||
if (type === "bank") {
|
||
return [item.bankName, fieldValue(item, ["bankCardNo", "bankAccount", "accountNo"])].filter(Boolean).join(" ");
|
||
}
|
||
if (type === "wechat_qr") {
|
||
return fieldValue(item, ["wechatAccount", "account", "accountNo", "receiveAccount"]) || (hasQrcode(item) ? "已保存微信收款码" : "微信收款账户");
|
||
}
|
||
return fieldValue(item, ["alipayAccount", "account", "accountNo", "receiveAccount"]) || (hasQrcode(item) ? "已保存支付宝收款码" : "支付宝收款账户");
|
||
}
|
||
|
||
function checkLogin() {
|
||
const token = CommonUtil.getAuthToken ? CommonUtil.getAuthToken() : localStorage.getItem("token");
|
||
if (!token) {
|
||
window.location.href = "login.html";
|
||
return;
|
||
}
|
||
$("#notLoggedInBox").addClass("tx-hidden");
|
||
$("#loggedInBox").removeClass("tx-hidden");
|
||
CommonUtil.getCurrentUserDetail(
|
||
function (data) {
|
||
$("#userName").text(data.nickName || data.nickname || "用户");
|
||
$("#userLevel").text(data.isExpert === "1" ? "专家" : "会员");
|
||
if (data.avatar) $("#userAvatar").attr("src", data.avatar);
|
||
},
|
||
function () {
|
||
$("#notLoggedInBox").removeClass("tx-hidden");
|
||
$("#loggedInBox").addClass("tx-hidden");
|
||
},
|
||
);
|
||
loadWalletOverview();
|
||
}
|
||
|
||
function renderNav() {
|
||
ApiClient.get(ApiClient.API.homeNav).then(function (res) {
|
||
if (!isSuccess(res) || !res.data) return;
|
||
const $nav = $("#navLotteryItems").empty();
|
||
$.each(asArray(pickData(res)), function (_, item) {
|
||
if (item.type && item.type !== "lottery") return;
|
||
const 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>");
|
||
});
|
||
});
|
||
}
|
||
|
||
function loadWalletOverview() {
|
||
ApiClient.get(ApiClient.API.walletOverview).then(function (res) {
|
||
if (!isSuccess(res)) return;
|
||
const data = pickData(res) || {};
|
||
userBalances.account = Number(fieldValue(data, ["accountBalance", "balance", "accountAmount"]));
|
||
userBalances.sales = Number(fieldValue(data, ["salesBalance", "saleBalance", "distributionBalance", "commissionBalance"]));
|
||
userBalances.expert = Number(fieldValue(data, ["expertBalance", "expertCommission", "expertAmount"]));
|
||
userBalances.withdrawable = Number(fieldValue(data, ["withdrawableAmount", "availableWithdrawAmount", "availableAmount"])) || userBalances.sales + userBalances.expert;
|
||
userBalances.frozen = Number(fieldValue(data, ["frozenAmount", "freezeAmount", "frozenBalance"]));
|
||
$("#accountBalance").html(money(userBalances.account) + '<span class="unit">元</span>');
|
||
$("#salesBalance").html(money(userBalances.sales) + '<span class="unit">元</span>');
|
||
$("#expertBalance").html(money(userBalances.expert) + '<span class="unit">元</span>');
|
||
$("#withdrawableAmount").html(money(userBalances.withdrawable) + '<span class="unit">元</span>');
|
||
$("#frozenAmount").html(money(userBalances.frozen) + '<span class="unit">元</span>');
|
||
updateAvailableAmounts();
|
||
renderWalletSourceCards();
|
||
});
|
||
}
|
||
|
||
function loadReceiveAccounts(selectedId) {
|
||
return ApiClient.get(ApiClient.API.walletReceiveAccountList)
|
||
.then(function (res) {
|
||
const data = pickData(res);
|
||
receiveAccounts = isSuccess(res) ? asArray((data && (data.records || data.rows || data.list)) || data) : [];
|
||
renderReceiveAccounts(selectedId);
|
||
})
|
||
.catch(function () {
|
||
receiveAccounts = [];
|
||
renderReceiveAccounts();
|
||
});
|
||
}
|
||
|
||
function switchTab(tab) {
|
||
$(".publish-tab-item[data-tab]").removeClass("active");
|
||
$('.publish-tab-item[data-tab="' + tab + '"]').addClass("active");
|
||
$(".tx-panel").removeClass("active");
|
||
if (tab === "withdraw") $("#panelWithdraw").addClass("active");
|
||
if (tab === "transfer") $("#panelTransfer").addClass("active");
|
||
}
|
||
|
||
function renderWalletSourceCards() {
|
||
renderSourceCards("#withdrawSourceCards", "#withdrawSource", function () {
|
||
updateAvailableAmounts();
|
||
});
|
||
renderSourceCards("#transferSourceCards", "#transferSource", function () {
|
||
updateAvailableAmounts();
|
||
});
|
||
}
|
||
|
||
function renderSourceCards(containerSelector, inputSelector, onChange) {
|
||
const $container = $(containerSelector).empty();
|
||
const selectedValue = $(inputSelector).val();
|
||
$.each(walletSourceOptions, function (_, item) {
|
||
const selected = selectedValue === item.value ? " selected" : "";
|
||
const $card = $(
|
||
'<div class="tx-choice-card' + selected + '" data-value="' + item.value + '">' +
|
||
'<div class="tx-choice-title">' + escapeHtml(item.title) + '</div>' +
|
||
'<div class="tx-choice-desc">' + escapeHtml(item.desc) + ":" + money(getSourceAmount(item.value)) + " 元</div>" +
|
||
"</div>",
|
||
);
|
||
$card.on("click", function () {
|
||
$(inputSelector).val(item.value);
|
||
renderSourceCards(containerSelector, inputSelector, onChange);
|
||
if (onChange) onChange();
|
||
});
|
||
$container.append($card);
|
||
});
|
||
}
|
||
|
||
function updateAvailableAmounts() {
|
||
$("#withdrawAvailableAmount").text(money(getSourceAmount($("#withdrawSource").val())) + " 元");
|
||
$("#transferAvailableAmount").text(money(getSourceAmount($("#transferSource").val())) + " 元");
|
||
}
|
||
|
||
function renderMethodCards() {
|
||
const $container = $("#withdrawMethodCards").empty();
|
||
const selectedMethod = $("#withdrawMethod").val();
|
||
$.each(withdrawMethodOptions, function (_, item) {
|
||
const selected = selectedMethod === item.value ? " selected" : "";
|
||
const $card = $(
|
||
'<div class="tx-method-card' + selected + '" data-method="' + item.value + '">' +
|
||
'<div class="tx-method-title">' + escapeHtml(item.title) + '</div>' +
|
||
'<div class="tx-method-desc">' + escapeHtml(item.desc) + "</div>" +
|
||
"</div>",
|
||
);
|
||
$card.on("click", function () {
|
||
$("#withdrawMethod").val(item.value);
|
||
$("#receiveAccountId").val("");
|
||
$("#addAccountPanel").removeClass("show").empty();
|
||
renderMethodCards();
|
||
renderReceiveAccounts();
|
||
});
|
||
$container.append($card);
|
||
});
|
||
}
|
||
|
||
function renderReceiveAccounts(selectedId) {
|
||
const method = $("#withdrawMethod").val();
|
||
const $wrap = $("#receiveAccountCards").empty();
|
||
const list = receiveAccounts.filter((item) => normalizeReceiveType(item.receiveType || item.withdrawType) === method);
|
||
if (selectedId) $("#receiveAccountId").val(selectedId);
|
||
if (!list.length) {
|
||
$wrap.html('<div class="tx-empty">当前提现方式暂无收款账户,请先新增。</div>');
|
||
$("#withdrawHint").text("新增收款账户并保存后,就可以选择它提交提现。");
|
||
return;
|
||
}
|
||
$.each(list, function (_, item) {
|
||
const id = getAccountId(item);
|
||
const current = $("#receiveAccountId").val();
|
||
const selected = String(current) === String(id) || (!current && item.isDefault == 1);
|
||
if (selected) $("#receiveAccountId").val(id);
|
||
const defaultTag = item.isDefault == 1 ? "<em>默认</em>" : "";
|
||
const $card = $(
|
||
'<div class="tx-account-card' + (selected ? " selected" : "") + '" data-id="' + escapeHtml(id) + '">' +
|
||
'<div class="tx-account-title">' + escapeHtml(item.realName || item.name || getReceiveTypeText(method)) + defaultTag + '</div>' +
|
||
'<div class="tx-account-desc">' + escapeHtml(getReceiveTypeText(method) + ":" + getReceiveAccountText(item)) + '</div>' +
|
||
'<div class="tx-account-actions">' +
|
||
'<span data-action="edit">编辑</span>' +
|
||
(item.isDefault == 1 ? "" : '<span data-action="default">设默认</span>') +
|
||
'<span data-action="delete">删除</span>' +
|
||
"</div>" +
|
||
"</div>",
|
||
);
|
||
$card.on("click", function () {
|
||
$("#receiveAccountId").val(id);
|
||
renderReceiveAccounts();
|
||
});
|
||
$card.find("[data-action]").on("click", function (event) {
|
||
event.stopPropagation();
|
||
const action = $(this).data("action");
|
||
if (action === "edit") openReceiveAccountEdit(id);
|
||
if (action === "default") setDefaultReceiveAccount(id);
|
||
if (action === "delete") deleteReceiveAccount(id);
|
||
});
|
||
$wrap.append($card);
|
||
});
|
||
$("#withdrawHint").text("请选择已维护的收款账户;需要变更信息时可直接编辑。");
|
||
}
|
||
|
||
function renderUploadHtml(scope, label, existingUrl) {
|
||
return (
|
||
'<div class="tx-upload-box">' +
|
||
'<input id="' + scope + 'Qrcode" class="tx-qrcode-file tx-hidden" type="file" accept="image/*" />' +
|
||
'<button class="tx-secondary-btn" type="button" data-upload-trigger="' + scope + '">' + escapeHtml(label) + '</button>' +
|
||
'<span class="tx-upload-name" id="' + scope + 'UploadName">' + (existingUrl ? "已保存收款码,可重新选择图片" : "未选择图片") + '</span>' +
|
||
'<img id="' + scope + 'QrcodePreview" class="tx-qrcode-preview' + (existingUrl ? " is-visible" : "") + '" ' + (existingUrl ? 'src="' + escapeHtml(existingUrl) + '"' : "") + " />" +
|
||
"</div>"
|
||
);
|
||
}
|
||
|
||
function openAddAccount() {
|
||
const method = $("#withdrawMethod").val();
|
||
const $currentPanel = $("#addAccountPanel");
|
||
if ($currentPanel.hasClass("show") && $currentPanel.attr("data-method") === method) {
|
||
$currentPanel.removeClass("show").empty().removeAttr("data-method").removeData("method");
|
||
return;
|
||
}
|
||
const $panel = $("#addAccountPanel").addClass("show").attr("data-method", method).data("method", method);
|
||
let html = "";
|
||
if (method === "alipay") {
|
||
html += '<div class="tx-bind-mode" data-bind-type="account"><button class="active" type="button" data-bind-type="account">支付宝账号</button><button type="button" data-bind-type="qrcode">收款二维码</button></div>';
|
||
}
|
||
html += '<div class="tx-add-grid">';
|
||
html += '<input class="cxz-form-input" id="addRealName" placeholder="请输入真实姓名" />';
|
||
if (method === "bank") {
|
||
html += '<input class="cxz-form-input" id="addBankName" placeholder="请输入开户银行" />';
|
||
html += '<input class="cxz-form-input full" id="addAccountNo" placeholder="请输入银行卡号" />';
|
||
} else if (method === "wechat_qr") {
|
||
html += renderUploadHtml("add", "选择微信收款码", "");
|
||
} else {
|
||
html += '<input class="cxz-form-input" id="addAccountNo" placeholder="请输入支付宝账号" />';
|
||
html += '<div class="tx-alipay-qrcode full tx-hidden">' + renderUploadHtml("add", "选择支付宝收款码", "") + '</div>';
|
||
}
|
||
html += '<label class="tx-check-row full"><input id="addIsDefault" type="checkbox" /> 设为默认收款账户</label>';
|
||
html += "</div>";
|
||
html += '<div class="tx-note">保存成功后会自动加入收款账户列表,并用于本次提现选择。</div>';
|
||
html += '<button class="cxz-submit-btn tx-save-account-btn" type="button" onclick="saveReceiveAccountAdd()">保存收款账户</button>';
|
||
$panel.html(html);
|
||
}
|
||
|
||
function applyAlipayBindMode($panel, bindType) {
|
||
$panel.find(".tx-bind-mode").attr("data-bind-type", bindType);
|
||
$panel.find(".tx-bind-mode button").removeClass("active");
|
||
$panel.find('.tx-bind-mode button[data-bind-type="' + bindType + '"]').addClass("active");
|
||
$panel.find("#addAccountNo").toggleClass("tx-hidden", bindType !== "account");
|
||
$panel.find(".tx-alipay-qrcode").toggleClass("tx-hidden", bindType !== "qrcode");
|
||
}
|
||
|
||
function uploadQrcode(scope, method) {
|
||
const input = $("#" + scope + "Qrcode")[0];
|
||
const file = input && input.files && input.files[0];
|
||
if (!file) return Promise.resolve({});
|
||
const formData = new FormData();
|
||
formData.append("file", file);
|
||
formData.append("receiveType", method);
|
||
return ApiClient.post(ApiClient.API.walletReceiveAccountUploadQrcode, formData).then(function (res) {
|
||
if (!isSuccess(res)) throw new Error(res.msg || "收款码上传失败");
|
||
const data = pickData(res) || {};
|
||
const qrCodeFileId = fieldValue(data, ["qrCodeFileId", "qrcodeFileId", "fileId", "ossId", "id"]) || fieldValue(res, ["qrCodeFileId", "qrcodeFileId", "fileId", "ossId", "id"]);
|
||
if (!qrCodeFileId) throw new Error("收款码上传成功,但未返回二维码文件ID");
|
||
return { qrCodeFileId: qrCodeFileId };
|
||
});
|
||
}
|
||
|
||
function appendQrcodePayload(payload, uploadData) {
|
||
if (uploadData && uploadData.qrCodeFileId) payload.qrCodeFileId = uploadData.qrCodeFileId;
|
||
return payload;
|
||
}
|
||
|
||
function buildAddPayload(uploadData) {
|
||
const method = $("#addAccountPanel").attr("data-method") || $("#withdrawMethod").val();
|
||
const realName = $("#addRealName").val().trim();
|
||
const account = String($("#addAccountNo").val() || "").trim();
|
||
if (!realName) throw new Error("请输入真实姓名");
|
||
const payload = {
|
||
receiveType: method,
|
||
realName: realName,
|
||
isDefault: $("#addIsDefault").prop("checked") || receiveAccounts.length === 0 ? 1 : 0,
|
||
};
|
||
if (method === "bank") {
|
||
const bankName = $("#addBankName").val().trim();
|
||
if (!bankName) throw new Error("请输入开户银行");
|
||
if (!account) throw new Error("请输入银行卡号");
|
||
payload.bankName = bankName;
|
||
payload.bankCardNo = account;
|
||
} else if (method === "wechat_qr") {
|
||
appendQrcodePayload(payload, uploadData);
|
||
if (!payload.qrCodeFileId) throw new Error("请上传微信收款码");
|
||
} else {
|
||
const bindType = $("#addAccountPanel .tx-bind-mode").attr("data-bind-type") || "account";
|
||
if (bindType === "qrcode") {
|
||
appendQrcodePayload(payload, uploadData);
|
||
if (!payload.qrCodeFileId) throw new Error("请上传支付宝收款码");
|
||
} else {
|
||
if (!account) throw new Error("请输入支付宝账号");
|
||
payload.alipayAccount = account;
|
||
}
|
||
}
|
||
return payload;
|
||
}
|
||
|
||
function saveReceiveAccountAdd() {
|
||
const method = $("#addAccountPanel").attr("data-method") || $("#withdrawMethod").val();
|
||
uploadQrcode("add", method)
|
||
.then(function (uploadData) {
|
||
return ApiClient.post(ApiClient.API.walletReceiveAccount, buildAddPayload(uploadData));
|
||
})
|
||
.then(function (res) {
|
||
if (!isSuccess(res)) throw new Error(res.msg || "保存失败");
|
||
const data = pickData(res) || {};
|
||
const createdId = fieldValue(data, ["id", "receiveAccountId", "accountId"]);
|
||
layui.layer.msg("收款账户已保存", { icon: 1 });
|
||
$("#addAccountPanel").removeClass("show").empty();
|
||
return loadReceiveAccounts(createdId);
|
||
})
|
||
.catch(function (err) {
|
||
layui.layer.msg(err.message || "保存失败", { icon: 2 });
|
||
});
|
||
}
|
||
|
||
function openReceiveAccountEdit(id) {
|
||
const item = getAccountById(id);
|
||
if (!item) return;
|
||
editingReceiveAccountId = id;
|
||
const method = normalizeReceiveType(item.receiveType || item.withdrawType);
|
||
let html = '<div class="tx-add-grid" data-edit-method="' + method + '">';
|
||
html += '<input class="cxz-form-input" id="editRealName" placeholder="请输入真实姓名" value="' + escapeHtml(item.realName || item.name || "") + '" />';
|
||
if (method === "bank") {
|
||
html += '<input class="cxz-form-input" id="editBankName" placeholder="请输入开户银行" value="' + escapeHtml(item.bankName || "") + '" />';
|
||
html += '<input class="cxz-form-input full" id="editAccountNo" placeholder="请输入银行卡号" value="' + escapeHtml(fieldValue(item, ["bankCardNo", "bankAccount", "accountNo"])) + '" />';
|
||
} else if (method === "wechat_qr") {
|
||
html += renderUploadHtml("edit", "更换微信收款码", getQrcodeUrl(item));
|
||
} else {
|
||
const isQrcode = hasQrcode(item) && !fieldValue(item, ["alipayAccount", "account", "accountNo", "receiveAccount"]);
|
||
html += '<div class="full"><div class="tx-bind-mode" data-bind-type="' + (isQrcode ? "qrcode" : "account") + '"><button class="' + (isQrcode ? "" : "active") + '" type="button" data-bind-type="account">支付宝账号</button><button class="' + (isQrcode ? "active" : "") + '" type="button" data-bind-type="qrcode">收款二维码</button></div></div>';
|
||
html += '<input class="cxz-form-input' + (isQrcode ? " tx-hidden" : "") + '" id="editAccountNo" placeholder="请输入支付宝账号" value="' + escapeHtml(fieldValue(item, ["alipayAccount", "account", "accountNo", "receiveAccount"])) + '" />';
|
||
html += '<div class="tx-alipay-qrcode full' + (isQrcode ? "" : " tx-hidden") + '">' + renderUploadHtml("edit", "更换支付宝收款码", getQrcodeUrl(item)) + '</div>';
|
||
}
|
||
html += '<label class="tx-check-row full"><input id="editIsDefault" type="checkbox" ' + (item.isDefault == 1 ? "checked" : "") + " /> 设为默认收款账户</label>";
|
||
html += "</div>";
|
||
$("#receiveAccountEditBody").html(html);
|
||
$("#receiveAccountEditMask").addClass("show");
|
||
}
|
||
|
||
function closeReceiveAccountEdit() {
|
||
editingReceiveAccountId = "";
|
||
$("#receiveAccountEditBody").empty();
|
||
$("#receiveAccountEditMask").removeClass("show");
|
||
}
|
||
|
||
function buildEditPayload(uploadData) {
|
||
const item = getAccountById(editingReceiveAccountId);
|
||
const method = normalizeReceiveType(item.receiveType || item.withdrawType);
|
||
const realName = $("#editRealName").val().trim();
|
||
const account = String($("#editAccountNo").val() || "").trim();
|
||
if (!realName) throw new Error("请输入真实姓名");
|
||
const payload = {
|
||
receiveType: method,
|
||
realName: realName,
|
||
isDefault: $("#editIsDefault").prop("checked") ? 1 : 0,
|
||
};
|
||
if (method === "bank") {
|
||
const bankName = $("#editBankName").val().trim();
|
||
if (!bankName) throw new Error("请输入开户银行");
|
||
if (!account) throw new Error("请输入银行卡号");
|
||
payload.bankName = bankName;
|
||
payload.bankCardNo = account;
|
||
} else if (method === "wechat_qr") {
|
||
appendQrcodePayload(payload, uploadData);
|
||
if (!payload.qrCodeFileId && getQrcodeFileId(item)) payload.qrCodeFileId = getQrcodeFileId(item);
|
||
} else {
|
||
const bindType = $("#receiveAccountEditBody .tx-bind-mode").attr("data-bind-type") || "account";
|
||
if (bindType === "qrcode") {
|
||
appendQrcodePayload(payload, uploadData);
|
||
if (!payload.qrCodeFileId && getQrcodeFileId(item)) payload.qrCodeFileId = getQrcodeFileId(item);
|
||
if (!payload.qrCodeFileId) throw new Error("请上传支付宝收款码");
|
||
} else {
|
||
if (!account) throw new Error("请输入支付宝账号");
|
||
payload.alipayAccount = account;
|
||
}
|
||
}
|
||
return payload;
|
||
}
|
||
|
||
function saveReceiveAccountEdit() {
|
||
if (!editingReceiveAccountId) return;
|
||
const item = getAccountById(editingReceiveAccountId);
|
||
const method = normalizeReceiveType(item.receiveType || item.withdrawType);
|
||
uploadQrcode("edit", method)
|
||
.then(function (uploadData) {
|
||
return ApiClient.put(ApiClient.API.walletReceiveAccountUpdate(editingReceiveAccountId), buildEditPayload(uploadData));
|
||
})
|
||
.then(function (res) {
|
||
if (!isSuccess(res)) throw new Error(res.msg || "保存失败");
|
||
layui.layer.msg("收款账户已更新", { icon: 1 });
|
||
const selectedId = editingReceiveAccountId;
|
||
closeReceiveAccountEdit();
|
||
return loadReceiveAccounts(selectedId);
|
||
})
|
||
.catch(function (err) {
|
||
layui.layer.msg(err.message || "保存失败", { icon: 2 });
|
||
});
|
||
}
|
||
|
||
function setDefaultReceiveAccount(id) {
|
||
ApiClient.put(ApiClient.API.walletReceiveAccountDefault(id)).then(function (res) {
|
||
if (!isSuccess(res)) return layui.layer.msg(res.msg || "设置失败", { icon: 2 });
|
||
layui.layer.msg("默认收款账户已更新", { icon: 1 });
|
||
loadReceiveAccounts(id);
|
||
});
|
||
}
|
||
|
||
function deleteReceiveAccount(id) {
|
||
layui.layer.confirm("确认删除这个收款账户?", function (index) {
|
||
layui.layer.close(index);
|
||
ApiClient.delete(ApiClient.API.walletReceiveAccountDelete(id)).then(function (res) {
|
||
if (!isSuccess(res)) return layui.layer.msg(res.msg || "删除失败", { icon: 2 });
|
||
layui.layer.msg("已删除", { icon: 1 });
|
||
if (String($("#receiveAccountId").val()) === String(id)) $("#receiveAccountId").val("");
|
||
loadReceiveAccounts();
|
||
});
|
||
});
|
||
}
|
||
|
||
function submitWithdraw() {
|
||
const amount = Number($("#withdrawAmount").val());
|
||
const sourceWallet = $("#withdrawSource").val();
|
||
const method = $("#withdrawMethod").val();
|
||
const receiveAccountId = $("#receiveAccountId").val();
|
||
if (!amount || amount <= 0) return layui.layer.msg("请输入有效的提现金额", { icon: 2 });
|
||
if (amount > getSourceAmount(sourceWallet)) return layui.layer.msg("提现金额不能超过可提现余额", { icon: 2 });
|
||
if (!receiveAccountId) return layui.layer.msg("请选择收款账户", { icon: 2 });
|
||
const $btn = $("#withdrawSubmitBtn").text("提交中...").prop("disabled", true);
|
||
ApiClient.post(ApiClient.API.walletWithdraw, {
|
||
sourceWallet: sourceWallet,
|
||
withdrawType: method,
|
||
amount: amount,
|
||
receiveAccountId: receiveAccountId,
|
||
})
|
||
.then(function (res) {
|
||
if (!isSuccess(res)) throw new Error(res.msg || "提现失败");
|
||
layui.layer.msg("提现申请已提交,请等待审核", { icon: 1 });
|
||
$("#withdrawAmount").val("");
|
||
loadWalletOverview();
|
||
})
|
||
.catch(function (err) {
|
||
layui.layer.msg(err.message || "提现失败", { icon: 2 });
|
||
})
|
||
.finally(function () {
|
||
$btn.text("确认提现").prop("disabled", false);
|
||
});
|
||
}
|
||
|
||
function submitTransfer() {
|
||
const amount = Number($("#transferAmount").val());
|
||
const sourceWallet = $("#transferSource").val();
|
||
if (!amount || amount <= 0) return layui.layer.msg("请输入有效的转入金额", { icon: 2 });
|
||
if (amount > getSourceAmount(sourceWallet)) return layui.layer.msg("转入金额不能超过可转余额", { icon: 2 });
|
||
const $btn = $("#transferSubmitBtn").text("转入中...").prop("disabled", true);
|
||
ApiClient.post(ApiClient.API.walletTransferToAccount, {
|
||
sourceWallet: sourceWallet,
|
||
amount: amount,
|
||
})
|
||
.then(function (res) {
|
||
if (!isSuccess(res)) throw new Error(res.msg || "操作失败");
|
||
layui.layer.msg("余额转入成功", { icon: 1 });
|
||
$("#transferAmount").val("");
|
||
loadWalletOverview();
|
||
})
|
||
.catch(function (err) {
|
||
layui.layer.msg(err.message || "操作失败", { icon: 2 });
|
||
})
|
||
.finally(function () {
|
||
$btn.text("确认转入").prop("disabled", false);
|
||
});
|
||
}
|
||
|
||
$(document).on("click", "[data-upload-trigger]", function () {
|
||
$("#" + $(this).data("upload-trigger") + "Qrcode").trigger("click");
|
||
});
|
||
|
||
$(document).on("change", ".tx-qrcode-file", function () {
|
||
const scope = this.id.replace("Qrcode", "");
|
||
const file = this.files && this.files[0];
|
||
$("#" + scope + "UploadName").text(file ? file.name : "未选择图片");
|
||
if (file) {
|
||
const reader = new FileReader();
|
||
reader.onload = function (event) {
|
||
$("#" + scope + "QrcodePreview").attr("src", event.target.result).addClass("is-visible");
|
||
};
|
||
reader.readAsDataURL(file);
|
||
}
|
||
});
|
||
|
||
$(document).on("click", ".tx-bind-mode button", function () {
|
||
const $panel = $(this).closest("#addAccountPanel, #receiveAccountEditBody");
|
||
const bindType = $(this).data("bind-type");
|
||
$panel.find(".tx-bind-mode").attr("data-bind-type", bindType);
|
||
$panel.find(".tx-bind-mode button").removeClass("active");
|
||
$(this).addClass("active");
|
||
$panel.find("#addAccountNo, #editAccountNo").toggleClass("tx-hidden", bindType !== "account");
|
||
$panel.find(".tx-alipay-qrcode").toggleClass("tx-hidden", bindType !== "qrcode");
|
||
});
|
||
|
||
$("#withdrawAll").on("click", function () {
|
||
$("#withdrawAmount").val(money(getSourceAmount($("#withdrawSource").val())));
|
||
});
|
||
|
||
$("#transferAll").on("click", function () {
|
||
$("#transferAmount").val(money(getSourceAmount($("#transferSource").val())));
|
||
});
|
||
|
||
$("#receiveAccountEditMask").on("click", function (event) {
|
||
if (event.target === this) closeReceiveAccountEdit();
|
||
});
|
||
|
||
$(window).on("scroll", function () {
|
||
$(window).scrollTop() > 320 ? $("#backTop").addClass("is-visible") : $("#backTop").removeClass("is-visible");
|
||
});
|
||
|
||
$(function () {
|
||
checkLogin();
|
||
renderNav();
|
||
renderWalletSourceCards();
|
||
renderMethodCards();
|
||
CommonUtil.loadPageConfig({ ads: false, links: false });
|
||
CommonUtil.requireAuth(function () {
|
||
loadReceiveAccounts();
|
||
});
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|