425 lines
14 KiB
HTML
425 lines
14 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>彩先知 - 双色球走势图</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/trend.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" 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>
|
|
|
|
<div class="breadcrumb-bar">
|
|
<a href="javascript:history.back();"
|
|
><i class="layui-icon layui-icon-left"></i> 返回</a
|
|
>
|
|
<span>/</span>
|
|
<span>双色球走势图</span>
|
|
</div>
|
|
|
|
<div class="page-title-bar">
|
|
<div class="page-title">双色球走势图</div>
|
|
<div class="qishu">
|
|
<div class="qishu-but active" data-count="30">30期</div>
|
|
<div class="qishu-but" data-count="60">60期</div>
|
|
<div class="qishu-but" data-count="100">100期</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="table-wrapper">
|
|
<table class="trend-table" border="1" id="trend-table">
|
|
<thead>
|
|
<tr>
|
|
<td rowspan="2" class="col-issue">期号</td>
|
|
<td rowspan="2" class="col-code">开奖号</td>
|
|
<td colspan="33" class="zone-red-header">红球</td>
|
|
<td colspan="16" class="zone-blue-header">蓝球</td>
|
|
</tr>
|
|
<tr id="header-row"></tr>
|
|
</thead>
|
|
<tbody id="data-body"></tbody>
|
|
</table>
|
|
</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"
|
|
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>
|
|
const $ = layui.$;
|
|
CommonUtil.loadPageConfig();
|
|
|
|
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);
|
|
},
|
|
function () {
|
|
$("#notLoggedInBox").show();
|
|
$("#loggedInBox").hide();
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
function renderNav() {
|
|
ApiClient.post("/api/web/menu/getFormatList", {}).then(function (res) {
|
|
if (res.code !== 0 || !res.data) return;
|
|
var $nav = $("#navLotteryItems");
|
|
$nav.find(".topbar__nav-link").not(":first").remove();
|
|
$.each(res.data, function (i, item) {
|
|
$nav.append(
|
|
'<a href="cai.html?id=' +
|
|
item.suoxie +
|
|
'" class="topbar__nav-link">' +
|
|
item.name +
|
|
"</a>",
|
|
);
|
|
});
|
|
});
|
|
}
|
|
|
|
$(window).on("scroll", function () {
|
|
$(window).scrollTop() > 320
|
|
? $("#backTop").addClass("is-visible")
|
|
: $("#backTop").removeClass("is-visible");
|
|
});
|
|
|
|
checkLogin();
|
|
renderNav();
|
|
|
|
(function () {
|
|
var RED_MAX = 33,
|
|
BLUE_MAX = 16;
|
|
var currentCount = 30;
|
|
var allData = [];
|
|
|
|
// Build header row
|
|
function buildHeader() {
|
|
var html = "";
|
|
for (var i = 1; i <= RED_MAX; i++) {
|
|
html += "<td>" + (i < 10 ? "0" + i : i) + "</td>";
|
|
}
|
|
for (var i = 1; i <= BLUE_MAX; i++) {
|
|
html += "<td>" + (i < 10 ? "0" + i : i) + "</td>";
|
|
}
|
|
$("#header-row").html(html);
|
|
}
|
|
|
|
// Parse openCode like "01,10,11,16,24,26+03"
|
|
function parseCode(code) {
|
|
var parts = code.split("+");
|
|
var reds = parts[0].split(",").map(function (n) {
|
|
return parseInt(n);
|
|
});
|
|
var blues = parts[1]
|
|
? parts[1].split(",").map(function (n) {
|
|
return parseInt(n);
|
|
})
|
|
: [];
|
|
return { reds: reds, blues: blues };
|
|
}
|
|
|
|
// Render data rows
|
|
function renderData(count) {
|
|
var data = allData.slice(0, count);
|
|
var html = "";
|
|
for (var r = 0; r < data.length; r++) {
|
|
var item = data[r];
|
|
var parsed = parseCode(item.openCode);
|
|
var redSet = {};
|
|
var blueSet = {};
|
|
parsed.reds.forEach(function (n) {
|
|
redSet[n] = true;
|
|
});
|
|
parsed.blues.forEach(function (n) {
|
|
blueSet[n] = true;
|
|
});
|
|
|
|
html += "<tr>";
|
|
html += '<td class="col-issue">' + item.issue + "</td>";
|
|
html +=
|
|
'<td class="col-code">' +
|
|
item.openCode.replace(/\+/g, "+") +
|
|
"</td>";
|
|
|
|
for (var i = 1; i <= RED_MAX; i++) {
|
|
if (redSet[i]) {
|
|
html +=
|
|
'<td><span class="hit-red">' +
|
|
(i < 10 ? "0" + i : i) +
|
|
"</span></td>";
|
|
} else {
|
|
html +=
|
|
'<td><span class="miss-num">' +
|
|
(i < 10 ? "0" + i : i) +
|
|
"</span></td>";
|
|
}
|
|
}
|
|
for (var i = 1; i <= BLUE_MAX; i++) {
|
|
if (blueSet[i]) {
|
|
html +=
|
|
'<td><span class="hit-blue">' +
|
|
(i < 10 ? "0" + i : i) +
|
|
"</span></td>";
|
|
} else {
|
|
html +=
|
|
'<td><span class="miss-num">' +
|
|
(i < 10 ? "0" + i : i) +
|
|
"</span></td>";
|
|
}
|
|
}
|
|
html += "</tr>";
|
|
}
|
|
|
|
// Statistics
|
|
html += buildStats(data);
|
|
$("#data-body").html(html);
|
|
}
|
|
|
|
// Build statistics rows
|
|
function buildStats(data) {
|
|
var redCount = {},
|
|
blueCount = {};
|
|
var redMaxOmit = {},
|
|
blueMaxOmit = {};
|
|
var redCurrOmit = {},
|
|
blueCurrOmit = {};
|
|
var redMaxConsec = {},
|
|
blueMaxConsec = {};
|
|
var redAvgOmit = {},
|
|
blueAvgOmit = {};
|
|
|
|
for (var i = 1; i <= RED_MAX; i++) {
|
|
redCount[i] = 0;
|
|
redMaxOmit[i] = 0;
|
|
redCurrOmit[i] = 0;
|
|
redMaxConsec[i] = 0;
|
|
redAvgOmit[i] = 0;
|
|
}
|
|
for (var i = 1; i <= BLUE_MAX; i++) {
|
|
blueCount[i] = 0;
|
|
blueMaxOmit[i] = 0;
|
|
blueCurrOmit[i] = 0;
|
|
blueMaxConsec[i] = 0;
|
|
blueAvgOmit[i] = 0;
|
|
}
|
|
|
|
// Calculate occurrence count, max omission, current omission, max consecutive, avg omission
|
|
for (var i = 1; i <= RED_MAX; i++) {
|
|
var omit = 0,
|
|
maxOmit = 0,
|
|
consec = 0,
|
|
maxConsec = 0,
|
|
totalOmit = 0,
|
|
omitCount = 0;
|
|
for (var r = 0; r < data.length; r++) {
|
|
var parsed = parseCode(data[r].openCode);
|
|
if (parsed.reds.indexOf(i) >= 0) {
|
|
redCount[i]++;
|
|
if (omit > maxOmit) maxOmit = omit;
|
|
totalOmit += omit;
|
|
omitCount++;
|
|
omit = 0;
|
|
consec++;
|
|
if (consec > maxConsec) maxConsec = consec;
|
|
} else {
|
|
omit++;
|
|
consec = 0;
|
|
}
|
|
}
|
|
if (omit > maxOmit) maxOmit = omit;
|
|
redCurrOmit[i] = omit;
|
|
redMaxOmit[i] = maxOmit;
|
|
redMaxConsec[i] = maxConsec;
|
|
redAvgOmit[i] =
|
|
omitCount > 0 ? (totalOmit / omitCount).toFixed(1) : data.length;
|
|
}
|
|
|
|
for (var i = 1; i <= BLUE_MAX; i++) {
|
|
var omit = 0,
|
|
maxOmit = 0,
|
|
consec = 0,
|
|
maxConsec = 0,
|
|
totalOmit = 0,
|
|
omitCount = 0;
|
|
for (var r = 0; r < data.length; r++) {
|
|
var parsed = parseCode(data[r].openCode);
|
|
if (parsed.blues.indexOf(i) >= 0) {
|
|
blueCount[i]++;
|
|
if (omit > maxOmit) maxOmit = omit;
|
|
totalOmit += omit;
|
|
omitCount++;
|
|
omit = 0;
|
|
consec++;
|
|
if (consec > maxConsec) maxConsec = consec;
|
|
} else {
|
|
omit++;
|
|
consec = 0;
|
|
}
|
|
}
|
|
if (omit > maxOmit) maxOmit = omit;
|
|
blueCurrOmit[i] = omit;
|
|
blueMaxOmit[i] = maxOmit;
|
|
blueMaxConsec[i] = maxConsec;
|
|
blueAvgOmit[i] =
|
|
omitCount > 0 ? (totalOmit / omitCount).toFixed(1) : data.length;
|
|
}
|
|
|
|
var stats = "";
|
|
// Occurrence count row
|
|
stats +=
|
|
'<tr class="stat-row"><td colspan="2" class="stat-label">出现次数</td>';
|
|
for (var i = 1; i <= RED_MAX; i++)
|
|
stats += "<td>" + redCount[i] + "</td>";
|
|
for (var i = 1; i <= BLUE_MAX; i++)
|
|
stats += "<td>" + blueCount[i] + "</td>";
|
|
stats += "</tr>";
|
|
|
|
// Max omission row
|
|
stats +=
|
|
'<tr class="stat-row alt"><td colspan="2" class="stat-label">最大遗漏</td>';
|
|
for (var i = 1; i <= RED_MAX; i++)
|
|
stats += "<td>" + redMaxOmit[i] + "</td>";
|
|
for (var i = 1; i <= BLUE_MAX; i++)
|
|
stats += "<td>" + blueMaxOmit[i] + "</td>";
|
|
stats += "</tr>";
|
|
|
|
// Avg omission row
|
|
stats +=
|
|
'<tr class="stat-row"><td colspan="2" class="stat-label">平均遗漏</td>';
|
|
for (var i = 1; i <= RED_MAX; i++)
|
|
stats += "<td>" + redAvgOmit[i] + "</td>";
|
|
for (var i = 1; i <= BLUE_MAX; i++)
|
|
stats += "<td>" + blueAvgOmit[i] + "</td>";
|
|
stats += "</tr>";
|
|
|
|
// Max consecutive row
|
|
stats +=
|
|
'<tr class="stat-row alt"><td colspan="2" class="stat-label">最大连出</td>';
|
|
for (var i = 1; i <= RED_MAX; i++)
|
|
stats += "<td>" + redMaxConsec[i] + "</td>";
|
|
for (var i = 1; i <= BLUE_MAX; i++)
|
|
stats += "<td>" + blueMaxConsec[i] + "</td>";
|
|
stats += "</tr>";
|
|
|
|
// Current omission row
|
|
stats +=
|
|
'<tr class="stat-row"><td colspan="2" class="stat-label">当前遗漏</td>';
|
|
for (var i = 1; i <= RED_MAX; i++)
|
|
stats += "<td>" + redCurrOmit[i] + "</td>";
|
|
for (var i = 1; i <= BLUE_MAX; i++)
|
|
stats += "<td>" + blueCurrOmit[i] + "</td>";
|
|
stats += "</tr>";
|
|
|
|
return stats;
|
|
}
|
|
|
|
// Load data from API
|
|
function loadData() {
|
|
ApiClient.post(
|
|
"/api/web/lotteryResult/getList",
|
|
{ suoxie: "ssq" },
|
|
function (res) {
|
|
if (res && res.data) {
|
|
allData = res.data;
|
|
renderData(currentCount);
|
|
}
|
|
},
|
|
);
|
|
}
|
|
|
|
// Period count buttons
|
|
$(document).on("click", ".qishu-but", function () {
|
|
$(".qishu-but").removeClass("active");
|
|
$(this).addClass("active");
|
|
currentCount = parseInt($(this).data("count"));
|
|
renderData(currentCount);
|
|
});
|
|
|
|
buildHeader();
|
|
loadData();
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|