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

620 lines
21 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/mianfei.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="mianfeilist.html?id=1">免费推荐</a><span class="sep">></span>
<span>文章详情</span>
</div>
<!-- Article Card -->
<div class="cxz-article-card">
<div class="cxz-article-header">
<h1 class="cxz-article-title" id="articleTitle">加载中...</h1>
<div class="cxz-article-meta">
<span>作者:<span class="author" id="articleAuthor">--</span></span>
<span id="articleTime">--</span>
</div>
</div>
<div class="cxz-article-body" id="articleContent">
<p style="text-align: center; color: var(--text-muted)">加载中...</p>
</div>
<div class="cxz-article-actions">
<button class="cxz-action-btn" id="btnLike" onclick="toggleLike()">
<i class="layui-icon layui-icon-praise"></i>
<span id="likeText">点赞</span><span id="likeCount">0</span>
</button>
<button
class="cxz-action-btn"
id="btnCollect"
onclick="toggleCollect()"
>
<i class="layui-icon layui-icon-star-fill"></i>
<span id="collectText">收藏</span>
</button>
</div>
</div>
<!-- Prev/Next Navigation -->
<div class="cxz-article-nav">
<a class="cxz-nav-item" id="prevArticle" href="javascript:void(0)">
<div class="cxz-nav-label">上一篇</div>
<div class="cxz-nav-title" id="prevTitle">没有了</div>
</a>
<a class="cxz-nav-item" id="nextArticle" href="javascript:void(0)">
<div class="cxz-nav-label">下一篇</div>
<div class="cxz-nav-title" id="nextTitle">没有了</div>
</a>
</div>
<!-- Comment Section -->
<div class="cxz-comment-section">
<div class="cxz-comment-header">
<i class="layui-icon layui-icon-dialogue"></i>
<span>评论(<span id="commentCount">0</span></span>
</div>
<!-- Comment Input -->
<div class="cxz-comment-input-box">
<textarea
class="cxz-comment-textarea"
id="commentInput"
placeholder="请输入您的评论..."
></textarea>
<button class="cxz-comment-submit-btn" onclick="submitComment()">
发表评论
</button>
</div>
<!-- Comment List -->
<div class="cxz-comment-list" id="commentList">
<div class="cxz-comment-empty">
<i class="layui-icon layui-icon-face-surprised"></i>
<span>暂无评论,快来抢沙发吧~</span>
</div>
</div>
<div class="cxz-pagination" id="commentPager"></div>
</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>
const $ = layui.$;
const urlParams = new URLSearchParams(window.location.search);
const pathMatch = window.location.pathname.match(/\/mianfei\/([^/]+)\.html$/);
const articleId = urlParams.get("id") || (pathMatch ? decodeURIComponent(pathMatch[1]) : "");
let isLiked = false;
let isCollected = false;
let articleData = null;
let commentPage = 1;
const commentPageSize = 10;
let likeBusy = false;
let collectBusy = false;
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);
},
function () {
$("#notLoggedInBox").show();
$("#loggedInBox").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();
$.each(list, function (i, item) {
if (item.type && item.type !== "lottery") return;
var code = item.code || item.suoxie || "";
$nav.append(
'<a href="cai.html?id=' +
code +
'" class="topbar__nav-link">' +
escapeHtml(item.name || "") +
"</a>",
);
});
});
}
$(window).on("scroll", function () {
$(window).scrollTop() > 320
? $("#backTop").addClass("is-visible")
: $("#backTop").removeClass("is-visible");
});
// Prevent prev/next navigation when no valid href
$("#prevArticle, #nextArticle").on("click", function (e) {
var href = $(this).attr("href");
if (!href || href === "javascript:void(0)" || href === "") {
e.preventDefault();
}
});
// === Load Article ===
function loadArticle() {
var token = localStorage.getItem("token");
var opts = token ? { headers: CommonUtil.authHeaders() } : {};
ApiClient.get(ApiClient.API.freeArticleDetail(articleId), null, opts)
.then(function (res) {
if (ApiClient.isSuccess(res) && ApiClient.pickData(res, null)) {
articleData = ApiClient.pickData(res, {});
renderArticle(articleData);
loadRelatedArticles();
} else {
layui.layer.msg("文章不存在或已删除", { icon: 2 });
$("#articleTitle").text("文章不存在");
$("#articleContent").html(
'<p style="text-align:center;color:var(--text-muted);">文章不存在或已删除</p>',
);
}
})
.catch(function () {
layui.layer.msg("加载失败,请稍后重试", { icon: 2 });
});
}
function renderArticle(data) {
$("#articleTitle").text(data.title || "无标题");
$("#articleAuthor").text(data.issuer || data.nickName || data.author || data.createUserName || "佚名");
$("#articleTime").text(data.updateTime || data.createTime || data.publishTime || "--");
$("#articleContent").html(scopeArticleContent(data.content || ""));
document.title = "彩先知 - " + (data.title || "免费文章详情");
renderArticleNav(data.prev || data.previous || data.prevArticle, data.next || data.nextArticle);
isLiked = isTruthyState(data.isLike ?? data.liked ?? data.isLiked);
updateLikeButton(data);
isCollected = isTruthyState(data.isCollect ?? data.collected ?? data.isCollected);
updateCollectButton();
}
function scopeArticleContent(content) {
var html = String(content || "");
if (!html.trim()) {
return '<p class="cxz-content-empty">暂无内容</p>';
}
var scopedStyles = [];
html = html.replace(/<style[^>]*>([\s\S]*?)<\/style>/gi, function (_, css) {
scopedStyles.push(prefixContentCss(css));
return "";
});
var styleHtml = scopedStyles.length
? '<style data-cxz-content-style>' + scopedStyles.join("\n") + "</style>"
: "";
return styleHtml + '<div class="cxz-content-inner">' + html + "</div>";
}
function prefixContentCss(css) {
return String(css || "").replace(/(^|})(\s*)([^@{}][^{}]*)\{/g, function (match, close, space, selectorText) {
var selectors = selectorText
.split(",")
.map(function (selector) {
selector = selector.trim();
if (!selector) return "";
if (
selector.indexOf("#articleContent") === 0 ||
selector.indexOf(".cxz-article-body") === 0
) {
return selector;
}
if (/^(html|body)$/i.test(selector)) return "#articleContent";
if (/^(html|body)\b/i.test(selector)) {
return selector.replace(/^(html|body)\b/i, "#articleContent");
}
return "#articleContent " + selector;
})
.filter(Boolean)
.join(", ");
return close + space + selectors + " {";
});
}
function isTruthyState(value) {
return (
value === true ||
value === 1 ||
value === "1" ||
value === 0 ||
value === "0"
);
}
function articleLinkOf(item) {
var id = item && (item.id || item.articleId || item.freeArticleId);
return CommonUtil.freeArticleHref(id);
}
function applyNavItem($item, $title, item, emptyText) {
if (item && (item.id || item.articleId || item.freeArticleId)) {
$item.attr("href", articleLinkOf(item)).removeClass("is-disabled").css("opacity", "");
$title.text(item.title || emptyText);
return;
}
$item.attr("href", "javascript:void(0)").addClass("is-disabled").css("opacity", "");
$title.text("没有了");
}
function renderArticleNav(prev, next) {
applyNavItem($("#prevArticle"), $("#prevTitle"), prev, "上一篇");
applyNavItem($("#nextArticle"), $("#nextTitle"), next, "下一篇");
}
function loadRelatedArticles() {
ApiClient.get(ApiClient.API.freeArticleRelated(articleId))
.then(function (res) {
if (!ApiClient.isSuccess(res)) return;
var data = ApiClient.pickData(res, {}) || {};
var prev = data.prev || data.previous || data.prevArticle;
var next = data.next || data.nextArticle;
var rows = ApiClient.asArray(data);
if (!prev && rows[0]) prev = rows[0];
if (!next && rows[1]) next = rows[1];
if (prev || next) renderArticleNav(prev, next);
})
.catch(function () {});
}
function updateLikeButton(data) {
var count = data.likeCount || 0;
$("#likeCount").text(count);
if (isLiked) {
$("#btnLike").addClass("liked");
$("#likeText").text("已点赞");
} else {
$("#btnLike").removeClass("liked");
$("#likeText").text("点赞");
}
}
function updateCollectButton() {
if (isCollected) {
$("#btnCollect").addClass("collected");
$("#collectText").text("已收藏");
} else {
$("#btnCollect").removeClass("collected");
$("#collectText").text("收藏");
}
}
// === Like ===
function toggleLike() {
if (likeBusy) return;
var token = localStorage.getItem("token");
if (!token) {
layui.layer.confirm(
"点赞需要先登录,是否前往登录?",
{ icon: 3, title: "提示" },
function (index) {
layui.layer.close(index);
window.location.href = "login.html";
},
);
return;
}
var wasLiked = isLiked;
likeBusy = true;
$("#btnLike").prop("disabled", true);
ApiClient.post(ApiClient.API.freeArticleLike(articleId), {}, { headers: CommonUtil.authHeaders() })
.then(function (res) {
if (ApiClient.isSuccess(res)) {
loadArticle();
layui.layer.msg(wasLiked ? "已取消点赞" : "点赞成功", {
icon: 1,
time: 1500,
});
} else {
layui.layer.msg(res.msg || "操作失败", { icon: 2 });
}
})
.finally(function () {
likeBusy = false;
$("#btnLike").prop("disabled", false);
});
}
// === Collect ===
function toggleCollect() {
if (collectBusy) return;
var token = localStorage.getItem("token");
if (!token) {
layui.layer.confirm(
"收藏需要先登录,是否前往登录?",
{ icon: 3, title: "提示" },
function (index) {
layui.layer.close(index);
window.location.href = "login.html";
},
);
return;
}
var wasCollected = isCollected;
collectBusy = true;
$("#btnCollect").prop("disabled", true);
ApiClient.post(ApiClient.API.freeArticleCollect(articleId), {}, { headers: CommonUtil.authHeaders() })
.then(function (res) {
if (ApiClient.isSuccess(res)) {
loadArticle();
layui.layer.msg(wasCollected ? "已取消收藏" : "收藏成功", {
icon: 1,
time: 1500,
});
} else {
layui.layer.msg(res.msg || "操作失败", { icon: 2 });
}
})
.finally(function () {
collectBusy = false;
$("#btnCollect").prop("disabled", false);
});
}
// === Comments ===
function loadComments(pageNum) {
if (pageNum) commentPage = pageNum;
ApiClient.get(ApiClient.API.freeArticleComments(articleId), {
pageNum: commentPage,
pageSize: commentPageSize,
})
.then(function (res) {
if (ApiClient.isSuccess(res) && ApiClient.pickData(res, null)) {
var data = ApiClient.pickData(res, {}) || {};
var list = ApiClient.asArray(data);
var total = data.totalRow || data.total || data.count || list.length || 0;
renderComments(list);
$("#commentCount").text(total);
renderCommentPager(total);
} else {
renderCommentEmpty();
}
})
.catch(function () {
renderCommentEmpty("加载失败");
});
}
function renderComments(list) {
var $container = $("#commentList");
$container.empty();
if (!list || list.length === 0) {
renderCommentEmpty();
return;
}
$.each(list, function (i, item) {
var avatarHtml;
if (item.avatar) {
avatarHtml =
'<img class="cxz-comment-avatar" src="' +
escapeHtml(item.avatar) +
'" />';
} else {
var initial = (item.nickName || item.nickname || item.userName || "匿").charAt(0);
avatarHtml =
'<div class="cxz-comment-avatar-placeholder">' +
escapeHtml(initial) +
"</div>";
}
var name = escapeHtml(item.nickName || item.nickname || item.userName || "匿名用户");
var text = escapeHtml(item.comment || item.content || "");
var time = item.createTime || item.commentTime || item.updateTime || "--";
if (time && time.length > 16) time = time.substring(0, 16);
$container.append(
'<div class="cxz-comment-item">' +
avatarHtml +
'<div class="cxz-comment-body">' +
'<div class="cxz-comment-name">' +
name +
"</div>" +
'<div class="cxz-comment-text">' +
text +
"</div>" +
'<div class="cxz-comment-time">' +
time +
"</div>" +
"</div>" +
"</div>",
);
});
}
function renderCommentEmpty(msg) {
$("#commentList").html(
'<div class="cxz-comment-empty">' +
'<i class="layui-icon layui-icon-face-surprised"></i>' +
"<span>" +
(msg || "暂无评论,快来抢沙发吧~") +
"</span>" +
"</div>",
);
}
function renderCommentPager(total) {
if (total <= 0) {
$("#commentPager").empty();
return;
}
layui.laypage.render({
elem: "commentPager",
count: total,
limit: commentPageSize,
curr: commentPage,
jump: function (obj, first) {
if (!first) {
commentPage = obj.curr;
loadComments();
}
},
});
}
function submitComment() {
var content = $("#commentInput").val().trim();
if (!content) {
layui.layer.msg("请输入评论内容", { icon: 2 });
return;
}
var token = localStorage.getItem("token");
if (!token) {
layui.layer.confirm(
"发表评论需要先登录,是否前往登录?",
{ icon: 3, title: "提示" },
function (index) {
layui.layer.close(index);
window.location.href = "login.html";
},
);
return;
}
var $btn = $(".cxz-comment-submit-btn");
$btn.text("提交中...").prop("disabled", true);
ApiClient.post(ApiClient.API.freeArticleComment(articleId), { comment: content }, { headers: CommonUtil.authHeaders() })
.then(function (res) {
if (ApiClient.isSuccess(res)) {
layui.layer.msg("评论成功", { icon: 1, time: 1500 });
$("#commentInput").val("");
commentPage = 1;
loadComments();
} else {
layui.layer.msg(res.msg || "评论失败", { icon: 2 });
}
$btn.text("发表评论").prop("disabled", false);
})
.catch(function () {
layui.layer.msg("网络错误,请重试", { icon: 2 });
$btn.text("发表评论").prop("disabled", false);
});
}
function escapeHtml(str) {
if (!str) return "";
return String(str)
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;");
}
// === Init ===
$(function () {
checkLogin();
renderNav();
CommonUtil.loadPageConfig();
if (articleId) {
loadArticle();
loadComments();
} else {
layui.layer.msg("文章ID不存在", { icon: 2 });
}
});
</script>
</body>
</html>