Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
308 lines
8.7 KiB
JavaScript
308 lines
8.7 KiB
JavaScript
(function () {
|
|
var mask = document.getElementById("coinDialog");
|
|
if (!mask) return;
|
|
|
|
var balanceEls = mask.querySelectorAll("[data-coin-balance]");
|
|
var costEls = mask.querySelectorAll("[data-coin-cost]");
|
|
var payBtn = mask.querySelector("[data-coin-dialog-pay]");
|
|
var loading = false;
|
|
var paying = false;
|
|
|
|
function formatCoins(n) {
|
|
var num = Number(n);
|
|
if (!Number.isFinite(num) || num < 0) num = 0;
|
|
return String(Math.floor(num));
|
|
}
|
|
|
|
function setBalance(n) {
|
|
var text = formatCoins(n);
|
|
balanceEls.forEach(function (el) {
|
|
el.textContent = text;
|
|
});
|
|
}
|
|
|
|
function setCost(n) {
|
|
var text = formatCoins(n);
|
|
costEls.forEach(function (el) {
|
|
el.textContent = text;
|
|
});
|
|
}
|
|
|
|
function toast(message, type) {
|
|
if (typeof window.showToast === "function") {
|
|
window.showToast(message, type);
|
|
return;
|
|
}
|
|
window.alert(message);
|
|
}
|
|
|
|
function openLogin() {
|
|
var loginOpen = document.querySelector("[data-login-dialog-open]");
|
|
if (loginOpen) loginOpen.click();
|
|
}
|
|
|
|
function goToCoinRecharge() {
|
|
window.location.href = "/deposit/coin/";
|
|
}
|
|
|
|
function isInsufficientBalance(res) {
|
|
if (!res) return false;
|
|
if (Number(res.code) === 20004) return true;
|
|
var message = String(res.tip || res.msg || "");
|
|
return /(?:金币|余额).{0,6}不足|不足.{0,6}(?:金币|余额)/.test(message);
|
|
}
|
|
|
|
function resolvePlayletId(trigger) {
|
|
if (trigger) {
|
|
var fromTrigger = Number(trigger.getAttribute("data-playlet-id") || 0);
|
|
if (fromTrigger > 0) return fromTrigger;
|
|
}
|
|
var fromMask = Number(mask.getAttribute("data-playlet-id") || 0);
|
|
if (fromMask > 0) return fromMask;
|
|
var playPage =
|
|
document.querySelector("[data-play-page]") ||
|
|
document.querySelector(".play-page");
|
|
if (playPage) {
|
|
var fromPage = Number(playPage.getAttribute("data-playlet-id") || 0);
|
|
if (fromPage > 0) return fromPage;
|
|
}
|
|
var player = document.querySelector("[data-play-player]");
|
|
if (player) {
|
|
var fromPlayer = Number(player.getAttribute("data-playlet-id") || 0);
|
|
if (fromPlayer > 0) return fromPlayer;
|
|
}
|
|
var likeBtn = document.querySelector("[data-playlet-id]");
|
|
if (likeBtn) {
|
|
var fromBtn = Number(likeBtn.getAttribute("data-playlet-id") || 0);
|
|
if (fromBtn > 0) return fromBtn;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
function resolvePlayletSlug(trigger) {
|
|
if (trigger) {
|
|
var fromTrigger = String(trigger.getAttribute("data-playlet-slug") || "").trim();
|
|
if (fromTrigger) return fromTrigger;
|
|
}
|
|
var fromMask = String(mask.getAttribute("data-playlet-slug") || "").trim();
|
|
if (fromMask) return fromMask;
|
|
var playPage =
|
|
document.querySelector("[data-play-page]") ||
|
|
document.querySelector(".play-page");
|
|
if (playPage) {
|
|
var fromPage = String(playPage.getAttribute("data-playlet-slug") || "").trim();
|
|
if (fromPage) return fromPage;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
function buildPlayHref(playletId, chapterId) {
|
|
if (!playletId || !chapterId) return "";
|
|
var slug = resolvePlayletSlug(null);
|
|
var key = slug || String(playletId);
|
|
return "/play/" + encodeURIComponent(key) + "/" + chapterId + "/";
|
|
}
|
|
|
|
function isOnPlayPage() {
|
|
return !!(
|
|
document.querySelector("[data-play-page]") ||
|
|
document.querySelector(".play-page")
|
|
);
|
|
}
|
|
|
|
function afterUnlockSuccess(playletId, chapterId, data) {
|
|
var detail = {
|
|
playletId: playletId,
|
|
chapterId: chapterId,
|
|
balance: data && typeof data.balance === "number" ? data.balance : null,
|
|
canWatch: !!(data && data.canWatch),
|
|
unlocked: !!(data && data.unlocked),
|
|
};
|
|
window.dispatchEvent(
|
|
new CustomEvent("play:chapter-unlocked", { detail: detail })
|
|
);
|
|
if (
|
|
isOnPlayPage() &&
|
|
typeof window.playAfterChapterUnlock === "function"
|
|
) {
|
|
window.playAfterChapterUnlock(detail);
|
|
return;
|
|
}
|
|
var href = buildPlayHref(playletId, chapterId);
|
|
if (href) {
|
|
window.location.href = href;
|
|
}
|
|
}
|
|
|
|
function setPaying(on) {
|
|
paying = !!on;
|
|
if (!payBtn) return;
|
|
payBtn.disabled = paying;
|
|
payBtn.classList.toggle("is-loading", paying);
|
|
payBtn.setAttribute("aria-busy", paying ? "true" : "false");
|
|
}
|
|
|
|
function fetchBalance() {
|
|
if (!window.HttpRequest) {
|
|
setBalance(0);
|
|
return Promise.resolve(0);
|
|
}
|
|
return window.HttpRequest.get("/api/auth/getInfo")
|
|
.then(function (res) {
|
|
if (!res || res.code !== 200 || !res.data) {
|
|
if (res && res.code === 401) {
|
|
openLogin();
|
|
}
|
|
throw new Error((res && (res.tip || res.msg)) || "获取余额失败");
|
|
}
|
|
var recharge = res.data.recharge;
|
|
setBalance(recharge);
|
|
if (window.CookieUtil && CookieUtil.setAuthSession) {
|
|
CookieUtil.setAuthSession(res.data);
|
|
}
|
|
return Number(recharge) || 0;
|
|
})
|
|
.catch(function (err) {
|
|
setBalance(0);
|
|
toast((err && err.message) || "获取余额失败", "error");
|
|
return 0;
|
|
});
|
|
}
|
|
|
|
function unlockAndPlay() {
|
|
if (paying) return;
|
|
if (!window.HttpRequest) {
|
|
toast("网络模块未就绪", "error");
|
|
return;
|
|
}
|
|
|
|
var chapterId = Number(mask.getAttribute("data-chapter-id") || 0);
|
|
var playletId = Number(mask.getAttribute("data-playlet-id") || 0);
|
|
var cost = Number(mask.getAttribute("data-single-coins") || 0);
|
|
var balance = Number(
|
|
(balanceEls[0] && balanceEls[0].textContent) || 0
|
|
);
|
|
|
|
if (!chapterId || !playletId) {
|
|
toast("缺少剧集信息,请刷新后重试", "error");
|
|
return;
|
|
}
|
|
|
|
if (Number.isFinite(balance) && Number.isFinite(cost) && balance < cost) {
|
|
goToCoinRecharge();
|
|
return;
|
|
}
|
|
|
|
setPaying(true);
|
|
window.HttpRequest.post("/api/playlet/chapter/unlock", {
|
|
chapterId: chapterId,
|
|
playletId: playletId,
|
|
})
|
|
.then(function (res) {
|
|
if (!res || res.code !== 200) {
|
|
if (res && res.code === 401) {
|
|
closeDialog();
|
|
openLogin();
|
|
return;
|
|
}
|
|
if (isInsufficientBalance(res)) {
|
|
goToCoinRecharge();
|
|
return;
|
|
}
|
|
throw new Error((res && (res.tip || res.msg)) || "解锁失败");
|
|
}
|
|
var data = res.data || {};
|
|
if (typeof data.balance === "number") {
|
|
setBalance(data.balance);
|
|
if (window.CookieUtil && CookieUtil.setAuthSession) {
|
|
CookieUtil.setAuthSession({ recharge: data.balance });
|
|
}
|
|
}
|
|
toast((res && res.tip) || "解锁成功", "success");
|
|
closeDialog();
|
|
afterUnlockSuccess(
|
|
Number(data.playletId) || playletId,
|
|
Number(data.chapterId) || chapterId,
|
|
data
|
|
);
|
|
})
|
|
.catch(function (err) {
|
|
toast((err && err.message) || "解锁失败,请稍后重试", "error");
|
|
})
|
|
.finally(function () {
|
|
setPaying(false);
|
|
});
|
|
}
|
|
|
|
function openDialog(event) {
|
|
if (event) event.preventDefault();
|
|
var trigger =
|
|
event && event.target && event.target.closest
|
|
? event.target.closest("[data-coin-dialog-open]")
|
|
: null;
|
|
var singleCoins = trigger
|
|
? Number(trigger.getAttribute("data-single-coins") || 0)
|
|
: 0;
|
|
setCost(singleCoins);
|
|
if (trigger) {
|
|
mask.setAttribute(
|
|
"data-chapter-id",
|
|
trigger.getAttribute("data-chapter-id") || ""
|
|
);
|
|
mask.setAttribute("data-single-coins", String(singleCoins || 0));
|
|
mask.setAttribute(
|
|
"data-playlet-id",
|
|
String(resolvePlayletId(trigger) || "")
|
|
);
|
|
mask.setAttribute("data-playlet-slug", resolvePlayletSlug(trigger));
|
|
} else if (!mask.getAttribute("data-playlet-id")) {
|
|
mask.setAttribute("data-playlet-id", String(resolvePlayletId(null) || ""));
|
|
}
|
|
|
|
mask.classList.add("is-open");
|
|
document.body.style.overflow = "hidden";
|
|
|
|
if (loading) return;
|
|
loading = true;
|
|
fetchBalance().finally(function () {
|
|
loading = false;
|
|
});
|
|
}
|
|
|
|
function closeDialog() {
|
|
mask.classList.remove("is-open");
|
|
document.body.style.overflow = "";
|
|
}
|
|
|
|
document.addEventListener("click", function (event) {
|
|
if (event.target.closest("[data-coin-dialog-open]")) {
|
|
openDialog(event);
|
|
return;
|
|
}
|
|
|
|
if (event.target.closest("[data-coin-dialog-close]")) {
|
|
closeDialog();
|
|
return;
|
|
}
|
|
|
|
if (event.target.closest("[data-coin-dialog-pay]")) {
|
|
event.preventDefault();
|
|
unlockAndPlay();
|
|
return;
|
|
}
|
|
|
|
if (event.target === mask) {
|
|
closeDialog();
|
|
}
|
|
});
|
|
|
|
document.addEventListener("keydown", function (event) {
|
|
if (event.key === "Escape" && mask.classList.contains("is-open")) {
|
|
closeDialog();
|
|
}
|
|
});
|
|
|
|
window.openCoinDialog = openDialog;
|
|
window.closeCoinDialog = closeDialog;
|
|
})();
|