Files
shencaisuan/html/duanzuhe.html
T
2026-06-04 11:43:41 +08:00

1077 lines
38 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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/combo.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">
<a href="index.html" class="topbar__nav-link">首页</a>
</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 is-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 Content -->
<main class="page-main">
<section class="content-section duan-scheme">
<div class="content-title">
<i class="layui-icon layui-icon-template-1"></i> 断组方案
</div>
<div class="duan-buy-panel" id="schemeBuyPanel">
<div class="duan-scheme-text" id="schemeSummary">正在加载方案...</div>
<div class="duan-scheme-actions">
<span class="duan-price"
>¥ <span id="schemePrice">--</span> 彩币</span
>
<button class="duan-buy-btn" type="button" onclick="buy()">
购买
</button>
</div>
</div>
<div class="duan-plan-panel" id="schemePlanPanel">
<div class="duan-scheme-text">计算公式说明:</div>
<div class="duan-scheme-actions">
<button class="duan-plan-btn" type="button" data-plan-index="1">
断组方案
</button>
</div>
</div>
</section>
<section class="content-section">
<div class="content-title">
<i class="layui-icon layui-icon-table"></i> 断组合推荐
</div>
<div class="duan-table-wrap">
<table class="duan-table">
<colgroup>
<col class="duan-col-name" />
<col class="duan-col-type" />
<col class="duan-col-issue" />
<col class="duan-col-open" />
<col class="duan-col-group" />
<col class="duan-col-status" />
<col class="duan-col-group" />
<col class="duan-col-status" />
<col class="duan-col-copy" />
<col class="duan-col-price" />
<col class="duan-col-action" />
</colgroup>
<thead>
<tr>
<th>名称</th>
<th>类型</th>
<th>期号</th>
<th>开奖号</th>
<th>断组1</th>
<th>状态1</th>
<th>断组2</th>
<th>状态2</th>
<th>复制</th>
<th>彩币</th>
<th>操作</th>
</tr>
</thead>
<tbody id="predictBody">
<tr>
<td colspan="11">
<div class="duan-empty">正在加载断组数据...</div>
</td>
</tr>
</tbody>
</table>
</div>
</section>
</main>
<div class="cxz-dialog-overlay" id="buyDialog">
<div class="cxz-dialog-box">
<div class="cxz-dialog-header">
<div class="cxz-dialog-title">购买断组方案</div>
<button class="cxz-dialog-close" type="button" onclick="closeBuyDialog()">
&times;
</button>
</div>
<div class="cxz-dialog-body">
<div class="cxz-pay-hero">
<div class="cxz-pay-hero-label">应付金额</div>
<div class="cxz-pay-hero-price">¥ <span id="payFinalAmount">--</span></div>
<div class="cxz-pay-hero-sub">
原价 ¥ <span id="payOriginalAmount">--</span>
<span class="cxz-pay-deduct">积分抵扣 ¥ <span id="pointDeductAmount">0.00</span></span>
</div>
</div>
<div class="cxz-pay-section-title">选择支付余额</div>
<div class="cxz-pay-wallets">
<button class="cxz-pay-option selected" data-type="account" type="button" onclick="selectPayType(this)">
<span class="cxz-pay-radio"></span>
<span class="cxz-pay-info">
<span class="cxz-pay-name">账户余额</span>
<span class="cxz-pay-desc">通用余额</span>
</span>
<span class="cxz-pay-balance">¥ <span id="accountBalance">0.00</span></span>
</button>
<button class="cxz-pay-option" data-type="sales" type="button" onclick="selectPayType(this)">
<span class="cxz-pay-radio"></span>
<span class="cxz-pay-info">
<span class="cxz-pay-name">分销余额</span>
<span class="cxz-pay-desc">推广收益</span>
</span>
<span class="cxz-pay-balance">¥ <span id="distributionBalance">0.00</span></span>
</button>
<button class="cxz-pay-option" data-type="expert" type="button" onclick="selectPayType(this)">
<span class="cxz-pay-radio"></span>
<span class="cxz-pay-info">
<span class="cxz-pay-name">专家余额</span>
<span class="cxz-pay-desc">专家佣金</span>
</span>
<span class="cxz-pay-balance">¥ <span id="expertBalance">0.00</span></span>
</button>
</div>
<label class="cxz-point-card">
<span class="cxz-point-main">
<input type="checkbox" id="usePoint" />
<span>
<span class="cxz-point-title">积分抵扣</span>
<span class="cxz-point-desc" id="pointBalance">可用积分 --</span>
</span>
</span>
<span class="cxz-point-value">- ¥ <span id="pointDeductPreview">0.00</span></span>
</label>
<div class="cxz-pay-total-card">
<div>
<span id="selectedWalletLabel">账户余额</span>
<em id="payBalanceHint">余额 ¥ <span id="selectedWalletBalance">0.00</span></em>
</div>
<strong>实付 ¥ <span id="payFooterAmount">--</span></strong>
</div>
</div>
<div class="cxz-dialog-footer">
<button class="cxz-dialog-confirm" type="button" onclick="okbuy()">
确认购买
</button>
</div>
</div>
</div>
<!-- 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"
class="site-footer__beian-link"
>工信部备案号</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>
layui.use(["layer", "jquery"], function () {
var layer = layui.layer;
var $ = layui.$;
var pageSize = 50;
var currentScheme = null;
var currentSchemes = [];
var currentPredictMenuId = "";
var currentPayAmount = 0;
var currentWalletOverview = {};
loadBasicConfig();
checkLogin();
renderNav();
loadScheme();
loadPredictMenu();
window.logout = function () {
localStorage.removeItem("token");
window.location.href = "login.html";
};
function esc(value) {
return CommonUtil.escapeHtml
? CommonUtil.escapeHtml(value)
: String(value || "");
}
function firstValue(source, keys, fallback) {
for (var i = 0; i < keys.length; i += 1) {
var key = keys[i];
if (
source &&
source[key] !== undefined &&
source[key] !== null &&
source[key] !== ""
)
return source[key];
}
return fallback === undefined ? "" : fallback;
}
function asRows(res) {
if (Array.isArray(res)) return res;
if (!res || typeof res !== "object") return [];
if (Array.isArray(res.rows)) return res.rows;
if (Array.isArray(res.records)) return res.records;
if (Array.isArray(res.list)) return res.list;
var data = ApiClient.pickData
? ApiClient.pickData(res, [])
: res.data;
return ApiClient.asArray ? ApiClient.asArray(data) : [];
}
function cleanParams(params) {
var result = {};
Object.keys(params || {}).forEach(function (key) {
if (
params[key] !== undefined &&
params[key] !== null &&
params[key] !== ""
)
result[key] = params[key];
});
return result;
}
function loadBasicConfig() {
Promise.all([
ApiClient.get("/api/web/config").catch(function () {
return { data: {} };
}),
ApiClient.get("/api/web/config/site").catch(function () {
return { data: {} };
}),
]).then(function (results) {
if (!CommonUtil.applyWebConfigs) return;
CommonUtil.applyWebConfigs(
ApiClient.pickData(results[0], {}) || {},
);
CommonUtil.applyWebConfigs(
ApiClient.pickData(results[1], {}) || {},
);
});
}
function checkLogin() {
if (!ApiClient.getToken()) return;
$("#notLoggedInBox").hide();
$("#loggedInBox").removeClass("is-hidden").css("display", "flex");
CommonUtil.getCurrentUserDetail(
function (data) {
if (!data) return;
$("#userName").text(data.nickName || data.nickname || "用户");
$("#userLevel").text(
data.isExpert === "1" || data.isExpert === true
? "专家"
: "会员",
);
if (data.avatar) $("#userAvatar").attr("src", data.avatar);
},
function () {
$("#notLoggedInBox").show();
$("#loggedInBox").addClass("is-hidden").hide();
},
);
}
function renderNav() {
ApiClient.get(ApiClient.API.homeNav).then(function (res) {
if (!ApiClient.isSuccess(res)) return;
var list = ApiClient.asArray(ApiClient.pickData(res, []));
var $nav = $("#navLotteryItems");
$nav.find(".topbar__nav-link").not(":first").remove();
list
.filter(function (item) {
return item.type === "lottery";
})
.forEach(function (item) {
$nav.append(
'<a href="cai.html?id=' +
(item.code || item.suoxie || "") +
'" class="topbar__nav-link">' +
esc(item.name || "") +
"</a>",
);
});
});
}
$(window).on("scroll", function () {
$(window).scrollTop() > 320
? $("#backTop").addClass("is-visible")
: $("#backTop").removeClass("is-visible");
});
function schemeIdOf(scheme) {
return firstValue(
scheme,
["id", "schemeId", "goodsId", "productId"],
"",
);
}
function schemePriceOf(scheme) {
return (
Number(
firstValue(
scheme,
["price", "amount", "coin", "points", "payAmount"],
0,
),
) || 0
);
}
function isSchemePurchased(scheme) {
return Boolean(
scheme &&
(scheme.isBuy === true ||
scheme.isBuy === 1 ||
scheme.isBuy === "1" ||
scheme.buyStatus === 1 ||
scheme.buyStatus === "1" ||
scheme.purchased === true ||
scheme.purchased === 1 ||
scheme.purchased === "1" ||
scheme.isPurchased === true ||
scheme.isPurchased === 1 ||
scheme.isPurchased === "1" ||
scheme.canView === true ||
scheme.canView === 1 ||
scheme.canView === "1"),
);
}
function findCurrentScheme(list) {
return (
ApiClient.asArray(list).find(function (item) {
if (
String(firstValue(item, ["schemeType", "type"], "")) ===
"break_group"
)
return true;
return (
String(
firstValue(
item,
["name", "title", "schemeName", "menuName"],
"",
),
).indexOf("断") >= 0
);
}) ||
ApiClient.asArray(list)[0] ||
null
);
}
function mergeSchemeDetail(scheme, detail) {
var merged = Object.assign({}, scheme || {}, detail || {});
var mergedId = schemeIdOf(merged);
if (mergedId) {
var index = currentSchemes.findIndex(function (item) {
return String(schemeIdOf(item)) === String(mergedId);
});
if (index >= 0) currentSchemes.splice(index, 1, merged);
else currentSchemes.push(merged);
}
if (
currentScheme &&
String(schemeIdOf(currentScheme)) === String(mergedId)
)
currentScheme = merged;
return merged;
}
function loadSchemeDetail(scheme) {
var id = schemeIdOf(scheme);
if (!id) return Promise.resolve(scheme || null);
return ApiClient.get(ApiClient.API.fc3dSchemeDetail(id))
.then(function (res) {
if (!ApiClient.isSuccess(res)) return scheme;
return mergeSchemeDetail(
scheme,
ApiClient.pickData(res, {}) || {},
);
})
.catch(function () {
return scheme;
});
}
function renderCurrentScheme(scheme) {
currentScheme = scheme || null;
var price = schemePriceOf(currentScheme);
$("#schemePrice").text(price.toFixed(2));
$("#schemeSummary").text(
"购买此方案-此方案适合:所有开奖号码为三个号码,包括前三,后三彩种",
);
if (isSchemePurchased(currentScheme)) {
$("#schemeBuyPanel").hide();
$("#schemePlanPanel").css("display", "flex");
} else {
$("#schemeBuyPanel").css("display", "flex");
$("#schemePlanPanel").hide();
}
}
function loadScheme() {
return ApiClient.get(ApiClient.API.fc3dSchemeList)
.then(function (res) {
if (!ApiClient.isSuccess(res))
throw new Error(res.msg || "获取方案失败");
currentSchemes = asRows(res);
var scheme = findCurrentScheme(currentSchemes);
renderCurrentScheme(scheme);
return loadSchemeDetail(scheme).then(renderCurrentScheme);
})
.catch(function () {
renderCurrentScheme(null);
});
}
function schemePlanContent(index, scheme) {
return firstValue(
scheme || currentScheme,
[
"plan" + index,
"plan" + index + "Content",
"scheme" + index,
"scheme" + index + "Content",
"formula" + index,
"content" + index,
index === 1 ? "planOne" : "planTwo",
index === 1 ? "schemeOne" : "schemeTwo",
"content",
"detail",
"htmlContent",
],
"暂无方案内容",
);
}
function openSchemePlan(index) {
if (!isSchemePurchased(currentScheme)) {
layer.msg("购买后可查看方案", { icon: 2 });
return;
}
var loading = layer.load(1);
loadSchemeDetail(currentScheme).then(function (scheme) {
layer.close(loading);
var content = String(schemePlanContent(index, scheme) || "");
var html = /<[a-z][\s\S]*>/i.test(content)
? content
: esc(content).replace(/\n/g, "<br>");
layer.open({
type: 1,
title: "断组方案",
skin: "cxz-plan-layer",
area: "760px",
resize: false,
shadeClose: true,
btn: ["我知道了"],
btnAlign: "c",
content:
'<div class="duan-plan-content duan-plan-content--brand"><div class="duan-plan-doc">' +
html +
"</div></div>",
});
});
}
$(".duan-plan-btn").on("click", function () {
openSchemePlan(Number($(this).data("plan-index")) || 1);
});
function loadPredictMenu() {
ApiClient.get(ApiClient.API.fc3dFreePredictMenus)
.then(function (res) {
if (!ApiClient.isSuccess(res))
throw new Error(res.msg || "获取断组菜单失败");
var menus = ApiClient.asArray(ApiClient.pickData(res, []));
var menu =
menus.find(function (item) {
return (
String(
item.name || item.title || item.menuName || "",
).indexOf("断") >= 0
);
}) ||
menus[0] ||
{};
currentPredictMenuId = menu.id || menu.menuId || "";
loadPredictList();
})
.catch(function (error) {
renderPredictRows([], error.message || "获取断组菜单失败");
});
}
function formatCodeBalls(value) {
var text = String(value || "");
if (!text) return "-";
return text
.split(/[,\s+]+/)
.filter(Boolean)
.map(function (num) {
return '<span class="duan-code-ball">' + esc(num) + "</span>";
})
.join("");
}
function splitRecommend(row) {
var list = ApiClient.asArray(
row.recommends ||
row.recommendList ||
row.predictList ||
row.items ||
row.children,
);
if (list.length) {
return [
firstValue(
list[0],
[
"code",
"number",
"value",
"recommendCode",
"predictedCode",
"content",
],
list[0],
),
firstValue(
list[1],
[
"code",
"number",
"value",
"recommendCode",
"predictedCode",
"content",
],
"",
),
];
}
var text = String(
firstValue(
row,
["predictedCode", "recommendCode", "recommend", "content"],
"",
),
);
var parts = text.split(/[_;]+/).filter(Boolean);
return [parts[0] || text, parts[1] || ""];
}
function predictGroupIndex(row) {
var name = String(
firstValue(
row,
["typeName", "playName", "menuName", "name", "title"],
"",
),
);
return /2|二/.test(name) ? 2 : 1;
}
function compactRecommend(pairs) {
var left = [];
var right = [];
pairs.forEach(function (pair) {
if (pair[0]) left.push(String(pair[0]).trim());
if (pair[1]) right.push(String(pair[1]).trim());
});
return left.join("") + (right.length ? "|" + right.join("") : "");
}
function normalizeCodeList(value) {
if (Array.isArray(value)) {
return value
.map(function (item) {
return String(item || "").replace(/[^0-9]/g, "");
})
.filter(Boolean);
}
return String(value || "")
.split(/[|,,、\s]+/)
.map(function (item) {
return item.replace(/[^0-9]/g, "");
})
.filter(Boolean);
}
function rowHitCodes(row) {
return normalizeCodeList(firstValue(row, ["hitCodes", "hitCode", "hitList"], ""));
}
function rowMissCodes(row) {
return normalizeCodeList(firstValue(row, ["missCodes", "missCode", "missList"], ""));
}
function rowStatus(row) {
var status = firstValue(row, ["status", "statusText", "resultText"], "");
if (status) return String(status);
var result = firstValue(row, ["result", "correct", "isCorrect"], "");
if (result === -1 || result === "-1" || result === false || result === "false") return "错";
if (result === 1 || result === "1" || result === true || result === "true") return "正确";
if (rowMissCodes(row).length) return "错";
if (rowHitCodes(row).length) return "正确";
return "待开奖";
}
function groupStatus(items) {
var statuses = items.map(function (item) {
return rowStatus(item.row);
});
if (statuses.some(function (item) { return /错|错误|error|fail/i.test(item); })) return "错";
if (statuses.some(function (item) { return /正确|全对|命中/.test(item); })) return "正确";
return statuses[0] || "待开奖";
}
function statusClass(value) {
if (/正确|全对|命中/.test(String(value || ""))) return "duan-ok";
if (/错|错误|待|未|error|fail|pending/i.test(String(value || ""))) return "duan-wrong";
return "";
}
function collectGroupCodes(items, getter) {
var map = {};
items.forEach(function (item) {
getter(item.row).forEach(function (code) {
map[code] = true;
});
});
return Object.keys(map);
}
function mergePredictRows(rows) {
var map = {};
(rows || []).forEach(function (row) {
var issue = firstValue(row, ["issue", "expect", "period"], "--");
var key = [
firstValue(row, ["lotteryName", "codeName"], "福彩3D"),
issue,
].join("_");
if (!map[key]) {
map[key] = {
base: row,
group1: [],
group2: [],
openCode: firstValue(
row,
["openCode", "lotteryResult", "resultCode", "openResult"],
"",
),
};
}
var recs = splitRecommend(row);
if (!map[key].openCode)
map[key].openCode = firstValue(
row,
["openCode", "lotteryResult", "resultCode", "openResult"],
"",
);
var item = { row: row, recs: recs };
if (predictGroupIndex(row) === 2) map[key].group2.push(item);
else map[key].group1.push(item);
});
return Object.keys(map).map(function (key) {
var group = map[key];
var rec1 = compactRecommend(group.group1.map(function (item) { return item.recs; }));
var rec2 = compactRecommend(group.group2.map(function (item) { return item.recs; }));
return Object.assign({}, group.base, {
typeName: "超级断组",
mergedRecommend1: rec1,
mergedRecommend2: rec2,
mergedStatus1: groupStatus(group.group1),
mergedStatus2: groupStatus(group.group2),
mergedHitCodes1: collectGroupCodes(group.group1, rowHitCodes),
mergedHitCodes2: collectGroupCodes(group.group2, rowHitCodes),
mergedMissCodes1: collectGroupCodes(group.group1, rowMissCodes),
mergedMissCodes2: collectGroupCodes(group.group2, rowMissCodes),
openCode: group.openCode,
});
});
}
function recommendHtml(value, hitCodes, missCodes, status) {
var text = String(value || "-").replace(/\s+/g, "");
var hitMap = {};
var missMap = {};
var state = String(status || "");
(hitCodes || []).forEach(function (code) {
hitMap[String(code)] = true;
});
(missCodes || []).forEach(function (code) {
missMap[String(code)] = true;
});
return text
.split(/([|,,、])/)
.map(function (part) {
if (/^[|,,、]$/.test(part)) return esc(part);
var code = part.replace(/[^0-9]/g, "");
if (missMap[code]) {
return '<span class="duan-rec-miss">' + esc(part) + "</span>";
}
if (hitMap[code] || /正确|全对|命中/.test(state)) {
return '<span class="duan-rec-hit">' + esc(part) + "</span>";
}
if (/待|未|pending/i.test(state)) {
return '<span class="duan-rec-miss">' + esc(part) + "</span>";
}
return esc(part);
})
.join("");
}
function renderPredictRows(rows, message) {
var $body = $("#predictBody");
var mergedRows = mergePredictRows(rows);
if (!mergedRows.length) {
$body.html(
'<tr><td colspan="11"><div class="duan-empty">' +
esc(message || "暂无断组数据") +
"</div></td></tr>",
);
return;
}
$body.html(
mergedRows
.map(function (row) {
var recs = [row.mergedRecommend1, row.mergedRecommend2];
var copyText = recs.filter(Boolean).join(",");
var openCode = firstValue(
row,
["openCode", "lotteryResult", "resultCode", "openResult"],
"",
);
var price = firstValue(
row,
["price", "amount", "coin", "points"],
"0.00",
);
var actionText = firstValue(
row,
["actionText", "payText", "freeText"],
"免费",
);
return (
'<tr title="' +
esc(copyText) +
'">' +
"<td>" +
esc(
firstValue(
row,
["lotteryName", "name", "codeName"],
"福彩3D",
),
) +
"</td>" +
"<td>" +
esc(
firstValue(
row,
["typeName", "playName", "menuName"],
"超级断组",
),
) +
"</td>" +
"<td>" +
esc(firstValue(row, ["issue", "expect", "period"], "--")) +
"</td>" +
'<td><div class="duan-cell">' +
formatCodeBalls(openCode) +
"</div></td>" +
'<td><div class="duan-cell">' +
recommendHtml(recs[0], row.mergedHitCodes1, row.mergedMissCodes1, row.mergedStatus1) +
"</div></td>" +
'<td><span class="' +
statusClass(row.mergedStatus1) +
'">' +
esc(row.mergedStatus1) +
"</span></td>" +
'<td><div class="duan-cell">' +
recommendHtml(recs[1], row.mergedHitCodes2, row.mergedMissCodes2, row.mergedStatus2) +
"</div></td>" +
'<td><span class="' +
statusClass(row.mergedStatus2) +
'">' +
esc(row.mergedStatus2) +
"</span></td>" +
'<td><button class="duan-copy-btn" type="button" data-copy="' +
esc(copyText) +
'">复制</button></td>' +
"<td>" +
esc(price) +
"</td>" +
"<td>" +
esc(actionText) +
"</td>" +
"</tr>"
);
})
.join(""),
);
$(".duan-copy-btn")
.off("click")
.on("click", function () {
var text = $(this).data("copy") || "";
if (!text) return;
navigator.clipboard.writeText(String(text)).then(function () {
layer.msg("复制成功", { icon: 1, time: 1200 });
});
});
}
function loadPredictList() {
if (!currentPredictMenuId) {
renderPredictRows([], "断组菜单加载失败");
return;
}
$("#predictBody").html(
'<tr><td colspan="11"><div class="duan-empty">正在加载断组数据...</div></td></tr>',
);
ApiClient.get(
ApiClient.API.fc3dFreePredictList,
cleanParams({
menuId: currentPredictMenuId,
pageNum: 1,
pageSize: pageSize,
}),
)
.then(function (res) {
if (!ApiClient.isSuccess(res))
throw new Error(res.msg || "获取断组数据失败");
renderPredictRows(asRows(res));
})
.catch(function (error) {
renderPredictRows([], error.message || "获取断组数据失败");
});
}
window.buy = function () {
if (!ApiClient.getToken()) {
layer.msg("请先登录后购买", { icon: 2 });
setTimeout(function () {
window.location.href = "login.html";
}, 800);
return;
}
if (!schemeIdOf(currentScheme)) {
layer.msg("方案信息加载失败,请刷新后重试", { icon: 2 });
return;
}
currentPayAmount = schemePriceOf(currentScheme);
$("#buyDialog").addClass("active");
$(".cxz-pay-option").removeClass("selected");
$('.cxz-pay-option[data-type="account"]').addClass("selected");
$("#usePoint").prop("checked", false);
updatePayCalculation();
loadWalletInfo();
};
window.closeBuyDialog = function () {
$("#buyDialog").removeClass("active");
};
$("#buyDialog").on("click", function (event) {
if (event.target === this) closeBuyDialog();
});
$(".cxz-dialog-box").on("click", function (event) {
event.stopPropagation();
});
window.selectPayType = function (element) {
$(".cxz-pay-option").removeClass("selected");
$(element).addClass("selected");
updatePayCalculation();
};
function parseMoney(value) {
var number = Number(String(value == null ? 0 : value).replace(/[^\d.-]/g, ""));
return Number.isFinite(number) ? number : 0;
}
function formatMoney(value) {
var number = Number(value || 0);
return Number.isFinite(number) ? number.toFixed(2) : "0.00";
}
function formatPoint(value) {
var number = Number(value || 0);
return Number.isFinite(number) ? String(Math.floor(number)) : "0";
}
function walletValue(type) {
var data = currentWalletOverview || {};
if (type === "sales") {
return parseMoney(
firstValue(
data,
["salesBalance", "referralBalance", "distributionBalance", "rebateBalance", "saleBalance"],
0,
),
);
}
if (type === "expert") {
return parseMoney(
firstValue(data, ["expertBalance", "expertCommission", "expertWallet", "commissionBalance"], 0),
);
}
return parseMoney(firstValue(data, ["accountBalance", "balance", "walletBalance"], 0));
}
function pointValue() {
return parseMoney(firstValue(currentWalletOverview || {}, ["points", "point", "score", "integral"], 0));
}
function currentWalletType() {
var type = $(".cxz-pay-option.selected").data("type") || "account";
return type === "sales" || type === "expert" ? type : "account";
}
function walletLabel(type) {
if (type === "sales") return "分销余额";
if (type === "expert") return "专家余额";
return "账户余额";
}
function updatePayCalculation() {
var walletType = currentWalletType();
var usePoint = $("#usePoint").prop("checked") === true;
var pointDeduct = usePoint ? Math.min(currentPayAmount, pointValue()) : 0;
var finalAmount = Math.max(currentPayAmount - pointDeduct, 0);
var balance = walletValue(walletType);
$("#payOriginalAmount").text(formatMoney(currentPayAmount));
$("#pointDeductAmount").text(formatMoney(pointDeduct));
$("#pointDeductPreview").text(formatMoney(pointDeduct));
$("#payFinalAmount").text(formatMoney(finalAmount));
$("#payFooterAmount").text(formatMoney(finalAmount));
$("#selectedWalletLabel").text(walletLabel(walletType));
$("#selectedWalletBalance").text(formatMoney(balance));
$("#payBalanceHint").toggleClass("is-insufficient", balance < finalAmount);
$(".cxz-dialog-confirm").prop("disabled", balance < finalAmount);
$(".cxz-dialog-confirm").text(balance < finalAmount ? "余额不足" : "确认购买");
}
function loadWalletInfo() {
ApiClient.get(ApiClient.API.walletOverview)
.then(function (res) {
if (!ApiClient.isSuccess(res)) return;
currentWalletOverview = ApiClient.pickData(res, {}) || {};
$("#accountBalance").text(formatMoney(walletValue("account")));
$("#distributionBalance").text(formatMoney(walletValue("sales")));
$("#expertBalance").text(formatMoney(walletValue("expert")));
$("#pointBalance").text("可用积分 " + formatPoint(pointValue()));
updatePayCalculation();
})
.catch(function () {});
}
$("#usePoint").on("change", updatePayCalculation);
window.okbuy = function () {
var schemeId = schemeIdOf(currentScheme);
if (!schemeId) {
layer.msg("方案信息加载失败,请刷新后重试", { icon: 2 });
return;
}
$(".cxz-dialog-confirm").prop("disabled", true).text("购买中...");
ApiClient.post(ApiClient.API.walletPurchaseFc3dScheme, {
schemeId: schemeId,
walletType: currentWalletType(),
usePoints: $("#usePoint").prop("checked") === true,
})
.then(function (res) {
if (!ApiClient.isSuccess(res))
throw new Error(res.msg || "购买失败");
layer.msg("购买成功", { icon: 1, time: 1200 });
renderCurrentScheme(
Object.assign({}, currentScheme || {}, { purchased: true }),
);
closeBuyDialog();
loadPredictList();
})
.catch(function (error) {
layer.msg(error.message || "购买失败", { icon: 2 });
})
.finally(function () {
updatePayCalculation();
});
};
});
</script>
</body>
</html>