修改 房间奖励 手动领取

This commit is contained in:
zhx 2026-05-19 15:18:34 +08:00
parent f813f5ea19
commit e4a2f913bb
4 changed files with 243 additions and 11 deletions

View File

@ -57,7 +57,7 @@
background:
radial-gradient(circle at 50% 0, rgba(249, 164, 53, 0.2) 0, rgba(249, 164, 53, 0) 36%),
linear-gradient(180deg, #2b0d02 0%, #1b0600 42%, #150500 100%);
padding-bottom: calc(92px + env(safe-area-inset-bottom));
padding-bottom: calc(142px + env(safe-area-inset-bottom));
}
.hero {
@ -391,6 +391,75 @@
height: 12px;
}
.claim-button {
grid-column: 1 / -1;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
width: 100%;
min-height: 38px;
padding: 0 16px;
border: 1px solid #c37019;
border-radius: 999px;
appearance: none;
background: linear-gradient(180deg, #fff0bd 0%, #ffc35b 48%, #f3932c 100%);
color: #7d2b05;
font-size: 15px;
font-weight: 900;
line-height: 1.1;
text-align: center;
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.78),
0 2px 0 rgba(104, 36, 2, 0.86),
0 5px 12px rgba(0, 0, 0, 0.28);
}
.claim-button:not(:disabled):active {
transform: translateY(1px);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.78),
0 1px 0 rgba(104, 36, 2, 0.86),
0 3px 9px rgba(0, 0, 0, 0.26);
}
.claim-button:disabled {
background: linear-gradient(180deg, #6a3a18 0%, #47200b 100%);
color: rgba(255, 233, 196, 0.58);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.08),
0 1px 0 rgba(0, 0, 0, 0.36);
}
.claim-button .coin {
width: 15px;
height: 15px;
}
.claim-button .coin[hidden] {
display: none;
}
.toast {
position: fixed;
left: 50%;
bottom: calc(132px + env(safe-area-inset-bottom));
z-index: 30;
width: min(calc(100% - 44px), 330px);
min-height: 38px;
padding: 10px 14px;
transform: translateX(-50%);
border: 1px solid rgba(255, 221, 152, 0.44);
border-radius: 999px;
background: rgba(23, 6, 0, 0.94);
color: #fff4df;
font-size: 13px;
line-height: 1.2;
font-weight: 700;
text-align: center;
box-shadow: 0 8px 22px rgba(0, 0, 0, 0.38);
}
@media (max-width: 360px) {
.content {
padding-left: 10px;
@ -421,6 +490,14 @@
overflow: hidden;
text-overflow: ellipsis;
}
.page {
padding-bottom: calc(208px + env(safe-area-inset-bottom));
}
.toast {
bottom: calc(194px + env(safe-area-inset-bottom));
}
}
</style>
<script>
@ -482,7 +559,12 @@
</span>
</div>
</div>
<button class="claim-button" id="claimButton" type="button" disabled>
<span id="claimButtonText">Checking...</span>
<span class="coin" id="claimButtonCoin" aria-hidden="true" hidden></span>
</button>
</aside>
<div class="toast" id="pageToast" role="status" aria-live="polite" hidden></div>
</main>
<script>
@ -509,6 +591,14 @@
profileName: textFromQuery(["roomName", "name", "nickname"], "Namename..."),
profileId: textFromQuery(["roomAccount", "account", "roomId", "id"], "123456789"),
profileAvatar: textFromQuery(["roomCover", "avatar", "userAvatar"], DEFAULT_AVATAR),
claimStatus: {
canClaim: false,
reason: "loading",
autoRewardEnabled: false,
record: null,
},
claimLoading: false,
toastTimer: 0,
};
const els = {
@ -519,6 +609,10 @@
profileName: document.getElementById("profileName"),
profileId: document.getElementById("profileId"),
profileAvatar: document.getElementById("profileAvatar"),
claimButton: document.getElementById("claimButton"),
claimButtonText: document.getElementById("claimButtonText"),
claimButtonCoin: document.getElementById("claimButtonCoin"),
pageToast: document.getElementById("pageToast"),
};
function trimValue(value) {
@ -634,15 +728,27 @@
? state.token
: "Bearer " + state.token;
}
const response = await fetch(url.toString(), { headers });
if (!response.ok) {
throw new Error("Request failed: " + response.status);
const fetchOptions = {
method: options.method || "GET",
headers,
};
if (options.body != null) {
headers["Content-Type"] = "application/json";
fetchOptions.body = JSON.stringify(options.body);
}
const response = await fetch(url.toString(), fetchOptions);
const contentType = response.headers.get("content-type") || "";
if (!contentType.includes("application/json")) {
if (!response.ok) {
throw new Error("Request failed: " + response.status);
}
return null;
}
const json = await response.json();
if (!response.ok) {
const message = json && (json.message || json.errorMsg || json.code);
throw new Error(message || "Request failed: " + response.status);
}
return json && (json.body || json.data || json);
}
@ -718,6 +824,67 @@
}
}
function applyClaimStatus(body) {
const source = body && typeof body === "object" ? body : {};
const canClaim = Boolean(source.canClaim);
state.claimStatus = {
canClaim,
reason: trimValue(source.reason) || (canClaim ? "available" : "no_claimable_reward"),
autoRewardEnabled: Boolean(source.autoRewardEnabled),
record: source.record || null,
};
}
function claimButtonText() {
const status = state.claimStatus || {};
if (state.claimLoading) {
return "Claiming...";
}
if (!state.token) {
return "Login required";
}
if (status.reason === "loading") {
return "Checking...";
}
if (status.canClaim) {
const rewardGold = Number(status.record && status.record.rewardGold ? status.record.rewardGold : 0);
return rewardGold > 0 ? "Claim " + formatCompact(rewardGold) : "Claim reward";
}
if (status.reason === "claimed") {
return "Claimed";
}
if (status.reason === "auto_reward_enabled") {
return "Auto issued";
}
if (status.reason === "status_unavailable") {
return "Retry later";
}
return "No reward";
}
function renderClaimButton() {
const status = state.claimStatus || {};
const rewardGold = Number(status.record && status.record.rewardGold ? status.record.rewardGold : 0);
const canClaim = Boolean(state.token && status.canClaim && !state.claimLoading);
els.claimButton.disabled = !canClaim;
els.claimButton.setAttribute("aria-busy", state.claimLoading ? "true" : "false");
els.claimButtonText.textContent = claimButtonText();
els.claimButtonCoin.hidden = !(status.canClaim && rewardGold > 0);
}
function showToast(message) {
const text = trimValue(message);
if (!text) {
return;
}
window.clearTimeout(state.toastTimer);
els.pageToast.textContent = text;
els.pageToast.hidden = false;
state.toastTimer = window.setTimeout(() => {
els.pageToast.hidden = true;
}, 2200);
}
function render() {
els.highlightReward.textContent = formatMeterValue(state.highlightReward);
els.currentTurnover.textContent = formatCompact(state.currentTurnover);
@ -735,26 +902,90 @@
</div>
</div>`;
}).join("");
renderClaimButton();
}
async function fetchPageData() {
try {
if (state.token) {
if (state.token) {
try {
const home = await requestJSON("/app/h5/room-turnover-reward/home", { auth: true });
applyHomeData(home);
} catch (_) {
} finally {
render();
return;
}
await fetchClaimStatus();
return;
}
try {
const body = await requestJSON("/public/h5/room-turnover-reward/page", {
searchParams: { sysOrigin: query.get("sysOrigin") },
});
applyPublicPageData(body);
render();
} catch (_) {
render();
}
applyClaimStatus({ canClaim: false, reason: "login_required", autoRewardEnabled: false });
render();
}
async function fetchClaimStatus() {
if (!state.token) {
applyClaimStatus({ canClaim: false, reason: "login_required", autoRewardEnabled: false });
renderClaimButton();
return;
}
state.claimStatus = {
canClaim: false,
reason: "loading",
autoRewardEnabled: false,
record: null,
};
renderClaimButton();
try {
const body = await requestJSON("/app/h5/room-turnover-reward/reward/claim/status", { auth: true });
applyClaimStatus(body);
} catch (_) {
applyClaimStatus({ canClaim: false, reason: "status_unavailable", autoRewardEnabled: false });
}
renderClaimButton();
}
async function handleClaimClick() {
const status = state.claimStatus || {};
if (state.claimLoading || !state.token || !status.canClaim) {
return;
}
const record = status.record || {};
const payload = {};
const recordId = trimValue(record.id);
if (recordId) {
payload.recordId = recordId;
}
state.claimLoading = true;
renderClaimButton();
try {
const body = await requestJSON("/app/h5/room-turnover-reward/reward/claim", {
auth: true,
method: "POST",
body: payload,
});
applyClaimStatus({
canClaim: false,
reason: "claimed",
autoRewardEnabled: false,
record: body && body.record ? body.record : record,
});
showToast(body && body.claimed === false ? "Reward already claimed" : "Reward claimed");
} catch (error) {
showToast(error && error.message ? error.message : "Claim failed");
} finally {
state.claimLoading = false;
renderClaimButton();
}
fetchClaimStatus();
}
els.claimButton.addEventListener("click", handleClaimClick);
render();
fetchPageData();
</script>

View File

@ -1,5 +1,5 @@
;(function () {
var defaultGatewayBase = 'http://127.0.0.1:1100'
var defaultGatewayBase = 'http://192.168.110.66:1100'
var defaultGatewayPrefix = '/go'
var defaultLocalGoBase = 'http://127.0.0.1:2900'
var hostApiBaseMap = {

View File

@ -0,0 +1 @@
../../assets

View File

@ -1,5 +1,5 @@
(function () {
var localGatewayBase = 'http://127.0.0.1:1100';
var localGatewayBase = 'http://192.168.110.64:1100';
var productionGatewayBase = 'https://jvapi.haiyihy.com';
var defaultGatewayBase = resolveDefaultGatewayBase();
var defaultGatewayPrefix = '/go';