676 lines
22 KiB
HTML
676 lines
22 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/fabumianfeiwenzhang.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 publish-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="page-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="publish-card">
|
|
<div class="publish-card-header">
|
|
<h2 class="publish-card-header-h2">发布文章</h2>
|
|
<p>发布您的预测分析,与彩民分享您的见解</p>
|
|
</div>
|
|
<div class="publish-card-body">
|
|
<div class="publish-tab-bar">
|
|
<a href="fabumianfeiwenzhang.html" class="publish-tab-item active"
|
|
>发布免费文章</a
|
|
>
|
|
<a href="fufei.html" class="publish-tab-item" id="paidPublishTab"
|
|
>发布付费文章</a
|
|
>
|
|
</div>
|
|
|
|
<div class="publish-tip-box">
|
|
<div class="publish-tip-item">
|
|
提示:实习期为三天,连续每天发布2篇以上的优质免费文章审核通过后,自动升级为正式专家。
|
|
</div>
|
|
<div class="publish-tip-item">
|
|
免费文章标准:标题15-30字(含期号、彩种、专家名称、标题),正文500字以上,需原创。
|
|
</div>
|
|
</div>
|
|
|
|
<form id="publishForm">
|
|
<div class="form-row">
|
|
<label>彩种分类 <span class="required">*</span></label>
|
|
<select
|
|
class="form-select form-select--full is-empty"
|
|
id="lotterySelect"
|
|
>
|
|
<option value="">请选择彩种</option>
|
|
</select>
|
|
<input type="hidden" id="menuId" value="" />
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<label>文章标题 <span class="required">*</span></label>
|
|
<div class="form-input-with-count">
|
|
<input
|
|
type="text"
|
|
class="form-input"
|
|
id="articleTitle"
|
|
placeholder="请输入文章标题(含期号、彩种、标题)"
|
|
maxlength="30"
|
|
oninput="updateTitleCount()"
|
|
/>
|
|
<span class="form-input-count"
|
|
><span id="titleCount">0</span>/30</span
|
|
>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<label>文章内容 <span class="required">*</span></label>
|
|
<textarea
|
|
placeholder="请输入内容"
|
|
id="input-content1"
|
|
class="meui-input publish-editor-textarea"
|
|
name="nr"
|
|
></textarea>
|
|
</div>
|
|
|
|
<div class="submit-row">
|
|
<button
|
|
type="button"
|
|
class="submit-btn"
|
|
id="submitBtn"
|
|
onclick="submitArticle()"
|
|
>
|
|
发布文章
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<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="publish-footer-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 src="../public/js/lay-config.js" charset="utf-8"></script>
|
|
<script charset="utf-8" src="../public/js/ke/kindeditor.min.js"></script>
|
|
<script>
|
|
var menuList = [];
|
|
var layer;
|
|
var editor;
|
|
var pageReady = false;
|
|
var publishPermission = {
|
|
canFree: false,
|
|
canPaid: false,
|
|
};
|
|
var REQUIRED_DAILY_FREE_ARTICLES = 2;
|
|
var FREE_TITLE_MIN_LENGTH = 15;
|
|
var FREE_TITLE_MAX_LENGTH = 30;
|
|
|
|
function autoFormatEditorContent() {
|
|
if (!editor) return;
|
|
try {
|
|
if (typeof editor.clickToolbar === "function") {
|
|
editor.clickToolbar("quickformat");
|
|
} else if (typeof editor.exec === "function") {
|
|
editor.exec("quickformat");
|
|
}
|
|
if (typeof editor.sync === "function") editor.sync();
|
|
} catch (e) {
|
|
console.warn("auto quickformat failed", e);
|
|
}
|
|
}
|
|
|
|
KindEditor.ready(function (K) {
|
|
editor = K.create('textarea[id="input-content1"]', {
|
|
width: "100%",
|
|
height: "400px",
|
|
afterBlur: function () {
|
|
autoFormatEditorContent();
|
|
},
|
|
items: [
|
|
"source",
|
|
"justifyleft",
|
|
"justifycenter",
|
|
"justifyright",
|
|
"justifyfull",
|
|
"fontsize",
|
|
"forecolor",
|
|
"hilitecolor",
|
|
"bold",
|
|
"italic",
|
|
"underline",
|
|
"strikethrough",
|
|
"table",
|
|
"clearhtml",
|
|
"quickformat",
|
|
"selectall",
|
|
"link",
|
|
],
|
|
});
|
|
});
|
|
|
|
layui.use(["layer", "jquery"], function () {
|
|
layer = layui.layer;
|
|
var $ = layui.$;
|
|
|
|
CommonUtil.loadPageConfig({ ads: false, links: false });
|
|
renderLoginState();
|
|
renderNav();
|
|
CommonUtil.requireAuth(function () {
|
|
loadPublishPermission().then(function (permission) {
|
|
publishPermission = permission;
|
|
if (!permission.canFree) {
|
|
layer.alert(
|
|
"您还不是实习或正式专家,暂不能发布文章。",
|
|
{ title: "暂无权限" },
|
|
function () {
|
|
window.location.href = "apply.html";
|
|
},
|
|
);
|
|
return;
|
|
}
|
|
pageReady = true;
|
|
loadMenuList();
|
|
});
|
|
});
|
|
|
|
$(window).on("scroll", function () {
|
|
$("#backTop").toggleClass("is-visible", $(window).scrollTop() > 320);
|
|
});
|
|
|
|
$(document).on("change", "#lotterySelect", function () {
|
|
var value = $(this).val();
|
|
$("#menuId").val(value);
|
|
$(this).toggleClass("is-empty", !value);
|
|
});
|
|
|
|
$(document).on("click", "#paidPublishTab", function (event) {
|
|
event.preventDefault();
|
|
var targetHref = this.href || "fufei.html";
|
|
checkPaidPublishPermission().then(function (result) {
|
|
if (!result.canPaid) {
|
|
layer.alert(result.reason || "暂无付费文章发布权限。", {
|
|
title: "暂无权限",
|
|
});
|
|
return;
|
|
}
|
|
window.location.href = targetHref;
|
|
});
|
|
});
|
|
});
|
|
|
|
function safeText(value) {
|
|
return CommonUtil.escapeHtml
|
|
? CommonUtil.escapeHtml(value)
|
|
: String(value || "");
|
|
}
|
|
|
|
function isApiSuccess(res) {
|
|
return res && (res.code === 0 || res.code === 200);
|
|
}
|
|
|
|
function isTruthy(value) {
|
|
return (
|
|
value === true ||
|
|
value === 1 ||
|
|
value === "1" ||
|
|
String(value).toLowerCase() === "true"
|
|
);
|
|
}
|
|
|
|
function padDatePart(value) {
|
|
return String(value).padStart(2, "0");
|
|
}
|
|
|
|
function formatLocalDate(date) {
|
|
return (
|
|
date.getFullYear() +
|
|
"-" +
|
|
padDatePart(date.getMonth() + 1) +
|
|
"-" +
|
|
padDatePart(date.getDate())
|
|
);
|
|
}
|
|
|
|
function getArticleDateText(value) {
|
|
if (!value) return "";
|
|
if (typeof value === "number") {
|
|
var numericDate = new Date(value);
|
|
return isNaN(numericDate.getTime())
|
|
? ""
|
|
: formatLocalDate(numericDate);
|
|
}
|
|
|
|
var text = String(value).trim();
|
|
var match = text.match(/^(\d{4})[-/](\d{1,2})[-/](\d{1,2})/);
|
|
if (match) {
|
|
return (
|
|
match[1] + "-" + padDatePart(match[2]) + "-" + padDatePart(match[3])
|
|
);
|
|
}
|
|
|
|
var parsedDate = new Date(text.replace(/-/g, "/"));
|
|
return isNaN(parsedDate.getTime()) ? "" : formatLocalDate(parsedDate);
|
|
}
|
|
|
|
function isPublishedFreeArticle(item) {
|
|
if (!item) return false;
|
|
|
|
var statusText = String(
|
|
item.statusText ||
|
|
item.auditStatusText ||
|
|
item.publishStatusText ||
|
|
item.stateText ||
|
|
"",
|
|
).toLowerCase();
|
|
if (/已发布|审核通过|通过|published|approved|pass/.test(statusText)) {
|
|
return true;
|
|
}
|
|
|
|
var status =
|
|
item.status != null
|
|
? item.status
|
|
: item.auditStatus != null
|
|
? item.auditStatus
|
|
: item.publishStatus;
|
|
return status === true || status === 1 || status === "1";
|
|
}
|
|
|
|
function getTodayPublishedFreeCount(rows) {
|
|
var today = formatLocalDate(new Date());
|
|
return ApiClient.asArray(rows).filter(function (item) {
|
|
var articleDate = getArticleDateText(
|
|
item.createTime ||
|
|
item.create_time ||
|
|
item.publishTime ||
|
|
item.publish_time ||
|
|
item.auditTime ||
|
|
item.audit_time ||
|
|
item.updateTime ||
|
|
item.update_time ||
|
|
item.createdAt,
|
|
);
|
|
return articleDate === today && isPublishedFreeArticle(item);
|
|
}).length;
|
|
}
|
|
|
|
function loadTodayPublishedFreeCount() {
|
|
return ApiClient.get(ApiClient.API.mineFreeArticleList, {
|
|
pageNum: 1,
|
|
pageSize: 100,
|
|
})
|
|
.then(function (res) {
|
|
if (!ApiClient.isSuccess(res)) return 0;
|
|
var data = res.data || res;
|
|
var rows = ApiClient.asArray(
|
|
data.rows || data.records || data.list || data.data || data,
|
|
);
|
|
return getTodayPublishedFreeCount(rows);
|
|
})
|
|
.catch(function () {
|
|
return 0;
|
|
});
|
|
}
|
|
|
|
function parsePublishPermission(userData) {
|
|
var status = String(
|
|
userData.expertStatus || userData.expert_status || "",
|
|
).toLowerCase();
|
|
var isIntern = /实习|intern|trial/.test(status);
|
|
var isRegularByStatus = /正式|regular|formal/.test(status);
|
|
var hasExpertIdentity =
|
|
isTruthy(userData.is_expert) ||
|
|
isTruthy(userData.isExpert) ||
|
|
isTruthy(userData.expert) ||
|
|
isTruthy(userData.is_regular_expert) ||
|
|
isTruthy(userData.isRegularExpert) ||
|
|
isTruthy(userData.regularExpert) ||
|
|
isIntern ||
|
|
isRegularByStatus;
|
|
var isRegularExpert =
|
|
isTruthy(userData.is_regular_expert) ||
|
|
isTruthy(userData.isRegularExpert) ||
|
|
isTruthy(userData.regularExpert) ||
|
|
isRegularByStatus;
|
|
|
|
return {
|
|
hasExpertIdentity: hasExpertIdentity,
|
|
isRegularExpert: hasExpertIdentity && isRegularExpert,
|
|
canFree: hasExpertIdentity,
|
|
canPaid: false,
|
|
todayFreeArticleCount: 0,
|
|
paidReason: isRegularExpert
|
|
? "今天需先发布2篇审核通过的免费文章后,才能发布付费文章"
|
|
: "正式专家才能发布付费文章",
|
|
};
|
|
}
|
|
|
|
function loadPublishPermission() {
|
|
return ApiClient.get(ApiClient.API.mineSummary)
|
|
.then(function (res) {
|
|
if (!ApiClient.isSuccess(res) || !res.data) {
|
|
return {
|
|
hasExpertIdentity: false,
|
|
isRegularExpert: false,
|
|
canFree: false,
|
|
canPaid: false,
|
|
todayFreeArticleCount: 0,
|
|
paidReason: "暂时无法获取发布权限。",
|
|
};
|
|
}
|
|
|
|
var permission = parsePublishPermission(res.data);
|
|
if (!permission.canFree || !permission.isRegularExpert) return permission;
|
|
|
|
return loadTodayPublishedFreeCount().then(function (count) {
|
|
permission.todayFreeArticleCount = count;
|
|
permission.canPaid = count >= REQUIRED_DAILY_FREE_ARTICLES;
|
|
permission.paidReason = permission.canPaid
|
|
? ""
|
|
: "今天需先发布2篇审核通过的免费文章后,才能发布付费文章(当前" +
|
|
count +
|
|
"篇)。";
|
|
return permission;
|
|
});
|
|
})
|
|
.catch(function () {
|
|
return {
|
|
hasExpertIdentity: false,
|
|
isRegularExpert: false,
|
|
canFree: false,
|
|
canPaid: false,
|
|
todayFreeArticleCount: 0,
|
|
paidReason: "暂时无法获取发布权限。",
|
|
};
|
|
});
|
|
}
|
|
|
|
function checkPaidPublishPermission() {
|
|
return loadPublishPermission().then(function (permission) {
|
|
publishPermission = permission;
|
|
return {
|
|
canPaid: permission.canPaid,
|
|
reason: permission.paidReason,
|
|
};
|
|
});
|
|
}
|
|
|
|
function isExpertUser(data) {
|
|
if (!data) return false;
|
|
var levelText = CommonUtil.getUserLevelText
|
|
? CommonUtil.getUserLevelText(data)
|
|
: "";
|
|
return (
|
|
data.expert === true ||
|
|
data.regularExpert === true ||
|
|
data.internExpert === true ||
|
|
data.isExpert === true ||
|
|
data.isExpert === 1 ||
|
|
data.isExpert === "1" ||
|
|
/专家/.test(levelText || "") ||
|
|
/regular|intern|formal|trial|expert|实习|正式/.test(
|
|
String(data.expertStatus || data.expert_status || ""),
|
|
)
|
|
);
|
|
}
|
|
|
|
function renderLoginState() {
|
|
var $ = layui.$;
|
|
var token = CommonUtil.getAuthToken();
|
|
if (!token) {
|
|
$("#notLoggedInBox").show();
|
|
$("#loggedInBox").hide();
|
|
return;
|
|
}
|
|
$("#notLoggedInBox").hide();
|
|
$("#loggedInBox").css("display", "flex");
|
|
CommonUtil.getCurrentUserDetail(function (data) {
|
|
if (!data) return;
|
|
$("#userName").text(data.nickName || data.username || "用户");
|
|
$("#userLevel").text(
|
|
CommonUtil.getUserLevelText
|
|
? CommonUtil.getUserLevelText(data)
|
|
: "会员",
|
|
);
|
|
if (data.avatar) $("#userAvatar").attr("src", data.avatar);
|
|
});
|
|
}
|
|
|
|
function renderNav() {
|
|
ApiClient.post("/api/web/menu/getFormatList", {}).then(function (res) {
|
|
if (!isApiSuccess(res)) return;
|
|
var list = ApiClient.asArray(ApiClient.pickData(res, []));
|
|
var $nav = layui.$("#navLotteryItems");
|
|
$nav.empty();
|
|
list.forEach(function (item) {
|
|
var code = item.suoxie || item.code || item.id || "";
|
|
var name = item.name || item.menuName || item.lotteryName || "";
|
|
if (!code || !name) return;
|
|
$nav.append(
|
|
'<a href="cai.html?id=' +
|
|
encodeURIComponent(code) +
|
|
'" class="topbar__nav-link">' +
|
|
safeText(name) +
|
|
"</a>",
|
|
);
|
|
});
|
|
});
|
|
}
|
|
|
|
function loadPublishIdentity() {
|
|
return new Promise(function (resolve) {
|
|
CommonUtil.getCurrentUserDetail(
|
|
function (data) {
|
|
resolve(isExpertUser(data));
|
|
},
|
|
function () {
|
|
resolve(false);
|
|
},
|
|
);
|
|
});
|
|
}
|
|
|
|
function isPublishLotteryMenu(item) {
|
|
if (!item) return false;
|
|
var name = String(
|
|
item.name || item.menuName || item.title || "",
|
|
).trim();
|
|
var code = String(item.suoxie || item.code || "").trim();
|
|
var type = String(item.type || "").toLowerCase();
|
|
if (["首页", "专家推荐"].indexOf(name) > -1) return false;
|
|
if (/^(home|index|zhuanjia|expert|expertRecommend)$/i.test(code))
|
|
return false;
|
|
return type === "lottery" && !!(item.id || item.menuId) && !!name;
|
|
}
|
|
|
|
function loadMenuList() {
|
|
ApiClient.post("/api/web/menu/getFormatList", {})
|
|
.then(function (res) {
|
|
if (!isApiSuccess(res)) throw new Error(res.msg || "获取彩种失败");
|
|
menuList = ApiClient.asArray(ApiClient.pickData(res, [])).filter(
|
|
isPublishLotteryMenu,
|
|
);
|
|
var $sel = layui.$("#lotterySelect");
|
|
$sel.find("option:not(:first)").remove();
|
|
menuList.forEach(function (item) {
|
|
var id = item.id || item.menuId || "";
|
|
var name = item.lotteryName || item.menuName || item.name || "";
|
|
if (!id || !name) return;
|
|
$sel.append(
|
|
'<option value="' +
|
|
safeText(id) +
|
|
'">' +
|
|
safeText(name) +
|
|
"</option>",
|
|
);
|
|
});
|
|
if (!menuList.length) {
|
|
$sel.append('<option value="" disabled>暂无可发布彩种</option>');
|
|
}
|
|
$sel.toggleClass("is-empty", !$sel.val());
|
|
})
|
|
.catch(function (err) {
|
|
layer.msg((err && err.message) || "获取彩种失败", { icon: 2 });
|
|
});
|
|
}
|
|
|
|
window.updateTitleCount = function () {
|
|
var titleInput = document.getElementById("articleTitle");
|
|
document.getElementById("titleCount").textContent = titleInput
|
|
? titleInput.value.length
|
|
: 0;
|
|
};
|
|
|
|
function getEditorHtml() {
|
|
autoFormatEditorContent();
|
|
if (editor && typeof editor.sync === "function") editor.sync();
|
|
return editor && typeof editor.html === "function"
|
|
? editor.html()
|
|
: layui.$("#input-content1").val();
|
|
}
|
|
|
|
function getEditorText() {
|
|
if (editor && typeof editor.text === "function")
|
|
return editor.text().trim();
|
|
return layui.$("<div>").html(getEditorHtml()).text().trim();
|
|
}
|
|
|
|
window.submitArticle = function () {
|
|
if (!pageReady) {
|
|
layer.msg("页面尚未准备完成", { icon: 0 });
|
|
return;
|
|
}
|
|
var $ = layui.$;
|
|
var menuId = $("#menuId").val();
|
|
var title = $("#articleTitle").val().trim();
|
|
var content = getEditorHtml();
|
|
var text = getEditorText();
|
|
|
|
if (!menuId) {
|
|
layer.msg("请选择彩种", { icon: 2 });
|
|
return;
|
|
}
|
|
if (title.length < FREE_TITLE_MIN_LENGTH) {
|
|
layer.msg("免费文章标题需控制在15-30个字之间", { icon: 2 });
|
|
return;
|
|
}
|
|
if (title.length > FREE_TITLE_MAX_LENGTH) {
|
|
layer.msg("免费文章标题需控制在15-30个字之间", { icon: 2 });
|
|
return;
|
|
}
|
|
if (!content || text.length < 500) {
|
|
layer.msg("正文内容不能少于500字", { icon: 2 });
|
|
return;
|
|
}
|
|
|
|
var $btn = $("#submitBtn");
|
|
$btn.text("发布中...").prop("disabled", true);
|
|
|
|
ApiClient.post(ApiClient.API.freeArticlePublish, {
|
|
menuId: menuId,
|
|
title: title,
|
|
content: content,
|
|
accountType: 1,
|
|
}, {
|
|
headers: CommonUtil.authHeaders(),
|
|
})
|
|
.then(function (res) {
|
|
if (isApiSuccess(res)) {
|
|
layer.msg(
|
|
"发布成功,请等待审核",
|
|
{ icon: 1, time: 1600 },
|
|
function () {
|
|
window.location.href = "index.html";
|
|
},
|
|
);
|
|
} else {
|
|
layer.msg(res.msg || "发布失败", { icon: 2 });
|
|
$btn.text("发布文章").prop("disabled", false);
|
|
}
|
|
})
|
|
.catch(function () {
|
|
layer.msg("网络错误,请稍后重试", { icon: 2 });
|
|
$btn.text("发布文章").prop("disabled", false);
|
|
});
|
|
};
|
|
</script>
|
|
</body>
|
|
</html>
|