/** * AKSRT Credits Frontend * * 功能: * - 签到 panel:拉取 /signin/today,按钮触发 POST /signin * - 邀请 panel:拉取 /invite/me,复制邀请链接 * * 仅在 page-profile 页面 + 启用积分时加载。 */ (function () { 'use strict'; var aksrt = window.aksrtData; if (!aksrt || !aksrt.siteUrl) { return; } // 协议修正:页面是 HTTPS 但 siteUrl 是 HTTP 时,强制使用 HTTPS(避免混合内容拦截) var siteUrl = aksrt.siteUrl; if (window.location.protocol === 'https:' && siteUrl.substring(0, 5) === 'http:') { siteUrl = 'https:' + siteUrl.substring(5); } var REST = siteUrl.replace(/\/$/, '') + '/wp-json/aksrt/v1'; var NONCE_HEADER = aksrt.restNonce ? { 'X-WP-Nonce': aksrt.restNonce } : (aksrt.nonce ? { 'X-WP-Nonce': aksrt.nonce } : {}); function api(path, options) { var merged = Object.assign({ credentials: 'same-origin', headers: Object.assign({ 'Content-Type': 'application/json' }, NONCE_HEADER), }, options || {}); return fetch(REST + path, merged).then(function (r) { // 401 时去掉 nonce 重试(页面缓存可能导致 nonce 过期,GET 请求可用 cookie 认证) if (r.status === 401 && (!options || !options.method || options.method === 'GET')) { var retry = Object.assign({}, merged, { headers: { 'Content-Type': 'application/json' } }); return fetch(REST + path, retry).then(function (r2) { return r2.json().catch(function () { return { message: '服务器返回了非 JSON 响应 (HTTP ' + r2.status + ')' }; }).then(function (j) { return { ok: r2.ok, status: r2.status, json: j }; }); }); } return r.json().catch(function () { return { message: '服务器返回了非 JSON 响应 (HTTP ' + r.status + ')' }; }).then(function (j) { return { ok: r.ok, status: r.status, json: j }; }); }); } // ===== 签到 ===== function initSignin() { var root = document.querySelector('[data-aksrt-signin]'); if (!root) return; var status = root.querySelector('[data-signin-status]'); var btn = root.querySelector('[data-signin-btn]'); var tip = root.querySelector('[data-signin-tip]'); if (!btn) return; function setStatus(text) { if (status) status.textContent = text; } function setStatusHtml(html) { if (status) status.innerHTML = html; } function setTip(text) { if (tip) tip.textContent = text; } function refresh() { api('/signin/today').then(function (r) { if (!r.ok) { setStatus((r.json && r.json.message) || '加载失败 (HTTP ' + r.status + ')'); return; } var j = r.json; if (!j.enabled) { setStatus('签到功能未启用'); btn.disabled = true; setTip(''); return; } if (j.signed) { setStatusHtml('已签到 ' + j.streak + ' 天 +' + j.reward_today); btn.disabled = true; btn.innerHTML = '已签到'; setTip(''); } else { setStatusHtml('连续 ' + j.streak + ' 天,+' + j.reward_if_signin); btn.disabled = false; setTip(''); } }).catch(function (err) { if (window.console) console.error('[AKSRT Credits] /signin/today 请求失败:', err); setStatus('加载失败,请刷新重试'); }); } function collectCaptcha() { var el = document.querySelector('[data-signin-captcha]'); if (!el) return {}; var out = {}; var keys = [ 'captcha_verified', 'cf_turnstile_response', 'tencent_ticket', 'tencent_randstr', 'tencent_sid', 'geetest_lot_number', 'geetest_captcha_output', 'geetest_pass_token', 'geetest_gen_time', 'aliyun_captcha_verify_param', ]; keys.forEach(function (k) { var inp = el.querySelector('input[name="' + k + '"]'); if (inp && inp.value !== '') out[k] = inp.value; }); return out; } function resetCaptcha() { try { var state = window.AKSRTCaptchaState; var scene = state && state.scenes && state.scenes.signin; if (scene && typeof scene.reset === 'function') scene.reset(); } catch (_) {} } function triggerCaptcha(callback) { var state = window.AKSRTCaptchaState; var scene = state && state.scenes && state.scenes.signin; if (scene && typeof scene.verify === 'function') { scene.verify(callback); return; } callback(); } btn.addEventListener('click', function () { btn.disabled = true; btn.innerHTML = '…'; setTip(''); var captchaDone = false; var timeoutId = setTimeout(function () { if (!captchaDone) { captchaDone = true; doSignin(); } }, 30000); triggerCaptcha(function () { clearTimeout(timeoutId); if (captchaDone) return; captchaDone = true; doSignin(); }); function doSignin() { api('/signin', { method: 'POST', body: JSON.stringify({ captcha: collectCaptcha() }) }).then(function (r) { if (!r.ok) { resetCaptcha(); setTip((r.json && r.json.message) || '签到失败'); btn.disabled = false; btn.innerHTML = '签到'; return; } setTip('签到成功,获得 ' + r.json.reward + ' 积分(连续 ' + r.json.streak + ' 天)'); var balanceEls = document.querySelectorAll('[data-credits-value]'); balanceEls.forEach(function (el) { el.textContent = r.json.balance.toLocaleString(); }); refresh(); }).catch(function () { resetCaptcha(); setTip('网络错误,请重试'); btn.disabled = false; btn.innerHTML = '签到'; }); } }); refresh(); } // ===== 邀请 ===== function initInvite() { var root = document.querySelector('[data-aksrt-invite]'); if (!root) return; var linkInput = root.querySelector('[data-invite-link]'); var copyBtn = root.querySelector('[data-invite-copy]'); var stats = root.querySelector('[data-invite-stats]'); var codeEl = root.querySelector('[data-invite-code]'); var listEl = root.querySelector('[data-invite-list]'); var totalEl = root.querySelector('[data-invite-total]'); function escapeHtml(value) { return String(value == null ? '' : value) .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } function formatDate(value) { if (!value || value === '0000-00-00 00:00:00') return ''; var date = new Date(String(value).replace(' ', 'T') + 'Z'); if (isNaN(date.getTime())) return String(value).slice(0, 16); function pad(n) { return n < 10 ? '0' + n : String(n); } return date.getFullYear() + '-' + pad(date.getMonth() + 1) + '-' + pad(date.getDate()) + ' ' + pad(date.getHours()) + ':' + pad(date.getMinutes()); } function statusMeta(status) { if (status === 'rewarded') { return { label: '已奖励', text: '奖励已发放', className: 'is-rewarded' }; } if (status === 'verified') { return { label: '已验证', text: '等待奖励发放', className: 'is-verified' }; } return { label: '已注册', text: '等待完成验证', className: 'is-registered' }; } function setCopyText(text) { if (!copyBtn) return; var label = copyBtn.querySelector('span'); if (label) label.textContent = text; else copyBtn.textContent = text; } function renderInviteList(items, total) { if (!listEl) return; listEl.classList.remove('is-loading'); if (totalEl) { if (total > items.length) totalEl.textContent = '最近 ' + items.length + ' 条 / 共 ' + total + ' 条'; else totalEl.textContent = total ? '共 ' + total + ' 条' : '暂无记录'; } if (!items.length) { listEl.innerHTML = '
分享链接后,好友注册记录会显示在这里。
'; return; } listEl.innerHTML = items.map(function (item) { var name = item.invitee_name || (item.invitee_id ? '用户 #' + item.invitee_id : '受邀用户'); var first = name ? name.charAt(0).toUpperCase() : '?'; var meta = statusMeta(item.status); var createdAt = formatDate(item.created_at); var rewardedAt = formatDate(item.rewarded_at); var statusText = meta.text; if (item.status === 'rewarded' && rewardedAt) statusText = '奖励于 ' + rewardedAt; var avatar = item.invitee_avatar ? '' : '' + escapeHtml(first) + ''; return '
' + '
' + avatar + '
' + '
' + '' + escapeHtml(name) + '' + '' + (createdAt ? '注册于 ' + escapeHtml(createdAt) : '注册时间未知') + '' + '
' + '
' + '' + meta.label + '' + '' + escapeHtml(statusText) + '' + '
' + '
'; }).join(''); } api('/invite/me').then(function (r) { if (!r.ok) { if (linkInput) linkInput.value = ''; if (copyBtn) copyBtn.disabled = true; if (codeEl) codeEl.textContent = '--'; if (stats) { stats.querySelectorAll('[data-stat]').forEach(function (el) { el.textContent = '—'; }); } return; } var j = r.json; if (linkInput) linkInput.value = j.invite_url || ''; if (codeEl) codeEl.textContent = j.code || '--'; if (stats && j.stats) { stats.querySelectorAll('[data-stat]').forEach(function (el) { var k = el.getAttribute('data-stat'); el.textContent = (j.stats[k] || 0).toString(); }); } }).catch(function () { if (copyBtn) copyBtn.disabled = true; if (codeEl) codeEl.textContent = '--'; }); if (listEl) { api('/invite/list?per_page=8').then(function (r) { if (!r.ok) { listEl.classList.remove('is-loading'); listEl.innerHTML = '
邀请记录加载失败,请稍后刷新。
'; if (totalEl) totalEl.textContent = '加载失败'; return; } var j = r.json || {}; renderInviteList(j.items || [], Number(j.total || 0)); }).catch(function () { listEl.classList.remove('is-loading'); listEl.innerHTML = '
邀请记录加载失败,请稍后刷新。
'; if (totalEl) totalEl.textContent = '加载失败'; }); } if (!copyBtn) return; var copying = false; copyBtn.addEventListener('click', function () { if (copying || !linkInput || !linkInput.value) return; copying = true; if (navigator.clipboard) { navigator.clipboard.writeText(linkInput.value).then(function () { setCopyText('已复制'); setTimeout(function () { setCopyText('复制链接'); copying = false; }, 2000); }).catch(function () { copying = false; }); } else { linkInput.select(); document.execCommand('copy'); setCopyText('已复制'); setTimeout(function () { setCopyText('复制链接'); copying = false; }, 2000); } }); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', function () { initSignin(); initInvite(); }); } else { initSignin(); initInvite(); } })();