修改完成

This commit is contained in:
2026-08-21 17:06:08 +08:00
parent 55da9a9e8a
commit 76af4cc492
10 changed files with 212 additions and 199 deletions
+40 -2
View File
@@ -37,6 +37,37 @@ window.CURRENT_CONFIG = window.ENV[window.CURRENT_ENV];
window.NavigationUtil = (function (window, document) {
const blockedProtocols = /^(?:javascript|data|vbscript|mailto|tel):/i;
function inviteCodeFromUrl(url) {
try {
return String(new URL(url || window.location.href, window.location.href).searchParams.get('inviteCode') || '').trim();
} catch (error) {
return '';
}
}
function isRegisterUrl(url) {
try {
return /(?:^|\/)reg\.html$/i.test(new URL(url, window.location.href).pathname);
} catch (error) {
return false;
}
}
function withReferralInviteCode(url, inviteCode) {
const destination = String(url || '').trim();
if (!destination || !isRegisterUrl(destination)) return destination;
const code = String(inviteCode || inviteCodeFromUrl(window.location.href)).trim();
if (!code) return destination;
const target = new URL(destination, window.location.href);
if (!target.searchParams.get('inviteCode')) target.searchParams.set('inviteCode', code);
return target.href;
}
function referralRegisterUrl(referralUrl, inviteCode) {
const code = String(inviteCode || inviteCodeFromUrl(referralUrl)).trim();
return code ? withReferralInviteCode('reg.html', code) : '';
}
function shouldOpenInNewTab(anchor) {
const href = (anchor.getAttribute('href') || '').trim();
@@ -49,6 +80,10 @@ window.NavigationUtil = (function (window, document) {
return;
}
const href = anchor.getAttribute('href') || '';
const referralHref = withReferralInviteCode(href);
if (referralHref !== href) anchor.setAttribute('href', referralHref);
if (anchor.target !== '_blank') {
anchor.target = '_blank';
}
@@ -100,7 +135,7 @@ window.NavigationUtil = (function (window, document) {
return {
open(url) {
const destination = String(url || '').trim();
const destination = withReferralInviteCode(url);
if (!destination) {
return null;
@@ -113,6 +148,9 @@ window.NavigationUtil = (function (window, document) {
}
return openedWindow;
}
},
withReferralInviteCode,
referralRegisterUrl
};
})(window, document);
+4 -59
View File
@@ -114,21 +114,6 @@
<button class="action-card-btn btn-apply-dist" id="fzlj" type="button">复制链接</button>
<button class="action-card-btn btn-apply-expert" id="tgewm" type="button">推广二维码</button>
</div>
<div class="action-card">
<div class="action-card-title">
<i class="layui-icon layui-icon-group"></i> 申请分销
</div>
<div class="action-card-desc">
成为分销商,推广赚佣金。邀请好友注册即可获得分销收益,多级返佣,轻松赚钱。
</div>
<button
class="action-card-btn btn-apply-dist"
id="btnApplyDist"
onclick="applyDistribution()"
>
申请分销
</button>
</div>
<div class="action-card">
<div class="action-card-title">
<i class="layui-icon layui-icon-star"></i> 申请专家
@@ -277,15 +262,12 @@
: $("#backTop").removeClass("is-visible");
});
function getApiBaseUrl() {
return (ApiClient.baseUrl || (window.CONFIG && CONFIG.API_BASE_URL) || window.location.origin || "").replace(/\/$/, "");
}
function normalizeShareLink(data) {
var affUrl = (data && (data.affUrl || data.shareUrl || data.inviteUrl || data.url)) || "";
if (!affUrl) return "";
if (/^https?:\/\//i.test(affUrl)) return affUrl;
return getApiBaseUrl() + "/html/reg.html?affUrl=" + String(affUrl).replace(/^\//, "");
return NavigationUtil.referralRegisterUrl(
String(affUrl).trim(),
data && data.inviteCode,
);
}
function getAffInfo() {
@@ -333,9 +315,6 @@
.then(function (res) {
if (res.code !== 0 || !res.data) throw new Error(res.msg || "获取推广信息失败");
var shareLink = normalizeShareLink(res.data);
if (res.data.affCodeUrl && res.data.affUrl) {
shareLink = String(res.data.affCodeUrl).replace(/\/$/, "") + "/" + String(res.data.affUrl).replace(/^\//, "");
}
if (!shareLink) throw new Error("接口未返回推广二维码链接");
createCustomModal(shareLink);
})
@@ -431,40 +410,6 @@
);
}
// Apply for distribution
window.applyDistribution = function () {
CommonUtil.requireAuth(function () {
layer.confirm(
"确定要申请成为分销商吗?",
{
title: "申请分销",
btn: ["确定申请", "取消"],
btnAlign: "c",
},
function (index) {
layer.close(index);
ApiClient.post(ApiClient.API.referralBind, {}, { headers: CommonUtil.authHeaders() })
.then(function (res) {
if (res.code === 0) {
layer.msg(
"申请成功!",
{ icon: 1, time: 2000 },
function () {
loadUserDetail();
},
);
} else {
layer.msg(res.msg || "申请失败", { icon: 2 });
}
})
.catch(function (err) {
layer.msg("网络错误,请稍后重试", { icon: 2 });
});
},
);
});
};
// Apply for expert
window.applyExpert = function () {
CommonUtil.requireAuth(function () {
+10 -11
View File
@@ -51,7 +51,7 @@
<div class="error-message" id="passwordError"></div>
</div>
<div class="form-group" id="captchaGroup">
<div class="form-group" id="captchaGroup" style="display: none">
<label for="captchaInput">验证码</label>
<div class="captcha-row">
<input
@@ -119,6 +119,7 @@
let layerInstance = null;
let currentCaptchaId = "";
let currentVerifyType = "captcha";
let currentSlideToken = "";
let currentSlideUuid = "";
let currentSlideX = 0;
@@ -147,6 +148,7 @@
}
function refreshCaptcha() {
$("#captchaGroup").show();
currentCaptchaId = "";
currentSlideUuid = "";
currentSlideX = 0;
@@ -191,11 +193,13 @@
function completeSlideCaptcha(result) {
const data = result || {};
const nested = data.data || {};
currentSlideToken =
data.slideToken || data.token || nested.slideToken || nested.token || "";
currentSlideUuid =
data.slideUuid || data.uuid || nested.slideUuid || nested.uuid || "";
currentSlideX =
Number(data.slideX || data.x || nested.slideX || nested.x || 0) || 0;
if (!currentSlideUuid) {
if (!currentSlideToken && !currentSlideUuid) {
layerInstance.msg("滑动验证未返回凭证,请重试", { icon: 2 });
renderSlideCaptchaEntry();
return;
@@ -216,6 +220,7 @@
headers: ApiClient.publicHeaders(),
onSuccess: completeSlideCaptcha,
onCancel: function () {
currentSlideToken = "";
currentSlideUuid = "";
currentSlideX = 0;
},
@@ -276,12 +281,13 @@
function getVerifyParams(show) {
if (currentVerifyType === "slide") {
if (!currentSlideUuid) {
if (!currentSlideToken && !currentSlideUuid) {
if (show) layerInstance.msg("请先完成滑动验证", { icon: 2 });
return null;
}
return {
verifyType: "slide",
slideToken: currentSlideToken,
slideUuid: currentSlideUuid,
slideX: currentSlideX,
};
@@ -319,12 +325,6 @@
NavigationUtil.open(getLoginRedirectUrl());
}
function bindReferralThenRedirect() {
AuthPageUtil.bindPendingReferralInviteCode()
.then(redirectAfterLogin)
.catch(redirectAfterLogin);
}
function submitLogin() {
const payload = Object.assign(
{
@@ -351,7 +351,7 @@
layerInstance.msg(
"登录成功,即将跳转到首页",
{ icon: 1, time: 1200 },
bindReferralThenRedirect,
redirectAfterLogin,
);
return;
}
@@ -376,7 +376,6 @@
layui.use(["layer", "jquery"], function () {
layerInstance = layui.layer;
AuthPageUtil.captureReferralInviteFromUrl();
loadVerifyConfig().then(refreshCaptcha);
$("#loginForm").on("submit", function (event) {
event.preventDefault();
+23 -14
View File
@@ -49,7 +49,7 @@
<div class="error-message" id="phoneError"></div>
</div>
<div class="form-group" id="captchaGroup">
<div class="form-group" id="captchaGroup" style="visibility: hidden">
<label for="captchaInput">滑动验证</label>
<div class="captcha-row">
<input
@@ -146,6 +146,7 @@
let layerInstance = null;
let currentCaptchaId = "";
let currentVerifyType = "captcha";
let currentSlideToken = "";
let currentSlideUuid = "";
let currentSlideX = 0;
let pendingSmsAfterVerify = false;
@@ -176,6 +177,7 @@
}
function refreshCaptcha() {
$("#captchaGroup").css("visibility", "visible");
if (currentVerifyType === "none") {
currentCaptchaId = "";
currentSlideUuid = "";
@@ -194,8 +196,10 @@
$("#captchaGroup").removeClass("is-slide-mode");
if (currentVerifyType === "slide") {
renderSlideCaptchaEntry();
$("#captchaGroup").hide();
return;
}
$("#captchaGroup").show();
$("#captchaInput").show();
$("#captchaRefreshLink").show().text("看不清?换一张");
$("#captchaContainer")
@@ -227,11 +231,13 @@
function completeSlideCaptcha(result) {
const data = result || {};
const nested = data.data || {};
currentSlideToken =
data.slideToken || data.token || nested.slideToken || nested.token || "";
currentSlideUuid =
data.slideUuid || data.uuid || nested.slideUuid || nested.uuid || "";
currentSlideX =
Number(data.slideX || data.x || nested.slideX || nested.x || 0) || 0;
if (!currentSlideUuid) {
if (!currentSlideToken && !currentSlideUuid) {
layerInstance.msg("滑动验证未返回凭证,请重试", { icon: 2 });
renderSlideCaptchaEntry();
return;
@@ -257,6 +263,7 @@
headers: ApiClient.publicHeaders(),
onSuccess: completeSlideCaptcha,
onCancel: function () {
currentSlideToken = "";
currentSlideUuid = "";
currentSlideX = 0;
},
@@ -359,8 +366,11 @@
function handlePhoneInput() {
const phone = $("#phone").val().trim();
if (smsCodeIssuedPhone && smsCodeIssuedPhone !== phone) {
smsCodeIssuedPhone = "";
$("#smsCode").val("");
clearError("smsCode");
$("#captchaGroup").show();
refreshCaptcha();
}
}
@@ -375,9 +385,10 @@
function getOptionalGraphVerifyParams() {
if (hasIssuedSmsCodeForCurrentPhone()) return {};
if (currentVerifyType === "slide" && currentSlideUuid) {
if (currentVerifyType === "slide" && (currentSlideToken || currentSlideUuid)) {
return {
verifyType: "slide",
slideToken: currentSlideToken,
slideUuid: currentSlideUuid,
slideX: currentSlideX,
};
@@ -393,7 +404,7 @@
function getGraphVerifyParams(show) {
if (currentVerifyType === "slide") {
if (!currentSlideUuid) {
if (!currentSlideToken && !currentSlideUuid) {
if (show) {
layerInstance.msg("请先完成滑动验证后获取短信验证码", {
icon: 2,
@@ -403,6 +414,7 @@
}
return {
verifyType: "slide",
slideToken: currentSlideToken,
slideUuid: currentSlideUuid,
slideX: currentSlideX,
};
@@ -558,7 +570,7 @@
function sendSmsCode() {
if (!validatePhone(true)) return;
if (currentVerifyType === "slide" && !currentSlideUuid) {
if (currentVerifyType === "slide" && !currentSlideToken && !currentSlideUuid) {
pendingSmsAfterVerify = true;
openSlideCaptcha();
return;
@@ -593,6 +605,7 @@
.then(function (res) {
if (ApiClient.isSuccess(res)) {
smsCodeIssuedPhone = $("#phone").val().trim();
$("#captchaGroup").hide();
layerInstance.msg("短信验证码已发送", { icon: 1 });
AuthPageUtil.startSmsCountdown("#sendSmsBtn");
return;
@@ -629,7 +642,7 @@
}
function buildRegisterData() {
return Object.assign(
const registerData = Object.assign(
{
phoneNumber: $("#phone").val().trim(),
password: hex_md5($("#password").val()),
@@ -638,6 +651,9 @@
},
getOptionalGraphVerifyParams(),
);
const inviteCode = AuthPageUtil.getReferralInviteCodeFromUrl();
if (inviteCode) registerData.inviteCode = inviteCode;
return registerData;
}
function saveRegisterTokenIfPresent(res) {
@@ -673,13 +689,7 @@
hasToken ? "注册成功,即将跳转到首页" : "注册成功,即将前往登录",
{ icon: 1, time: 1200 },
function () {
AuthPageUtil.bindPendingReferralInviteCode()
.then(function () {
redirectAfterRegister(hasToken);
})
.catch(function () {
redirectAfterRegister(hasToken);
});
redirectAfterRegister(hasToken);
},
);
}
@@ -710,7 +720,6 @@
layui.use(["layer", "jquery"], function () {
layerInstance = layui.layer;
AuthPageUtil.captureReferralInviteFromUrl();
loadVerifyConfig().then(refreshCaptcha);
$("#sendSmsBtn").on("click", sendSmsCode);
$("#registerForm").on("submit", function (event) {
+10 -4
View File
@@ -37,7 +37,7 @@
<div class="error-message" id="phoneError"></div>
</div>
<div class="form-group" id="captchaGroup">
<div class="form-group" id="captchaGroup" style="visibility: hidden">
<label for="captchaInput">滑动验证</label>
<div class="captcha-row">
<input
@@ -127,6 +127,7 @@
let layerInstance = null;
let currentCaptchaId = "";
let currentVerifyType = "captcha";
let currentSlideToken = "";
let currentSlideUuid = "";
let currentSlideX = 0;
let pendingSmsAfterVerify = false;
@@ -157,6 +158,7 @@
}
function refreshCaptcha() {
$("#captchaGroup").css("visibility", "visible");
currentCaptchaId = "";
currentSlideUuid = "";
currentSlideX = 0;
@@ -199,11 +201,13 @@
function completeSlideCaptcha(result) {
const data = result || {};
const nested = data.data || {};
currentSlideToken =
data.slideToken || data.token || nested.slideToken || nested.token || "";
currentSlideUuid =
data.slideUuid || data.uuid || nested.slideUuid || nested.uuid || "";
currentSlideX =
Number(data.slideX || data.x || nested.slideX || nested.x || 0) || 0;
if (!currentSlideUuid) {
if (!currentSlideToken && !currentSlideUuid) {
layerInstance.msg("滑动验证未返回凭证,请重试", { icon: 2 });
renderSlideCaptchaEntry();
return;
@@ -229,6 +233,7 @@
headers: ApiClient.publicHeaders(),
onSuccess: completeSlideCaptcha,
onCancel: function () {
currentSlideToken = "";
currentSlideUuid = "";
currentSlideX = 0;
},
@@ -332,12 +337,13 @@
function getVerifyParams(show) {
if (currentVerifyType === "slide") {
if (!currentSlideUuid) {
if (!currentSlideToken && !currentSlideUuid) {
if (show) layerInstance.msg("请先完成滑动验证", { icon: 2 });
return null;
}
return {
verifyType: "slide",
slideToken: currentSlideToken,
slideUuid: currentSlideUuid,
slideX: currentSlideX,
};
@@ -447,7 +453,7 @@
function sendSmsCode() {
if (!validatePhone(true)) return;
if (currentVerifyType === "slide" && !currentSlideUuid) {
if (currentVerifyType === "slide" && !currentSlideToken && !currentSlideUuid) {
pendingSmsAfterVerify = true;
openSlideCaptcha();
return;
+9 -28
View File
@@ -486,33 +486,14 @@
);
}
function fullShareLink(url, code) {
if (url && /^https?:\/\//.test(url)) return url;
if (url) {
if (url.indexOf("/html/reg.html") >= 0) {
return ApiClient.baseUrl.replace(/\/$/, "") + "/" + url.replace(/^\//, "");
}
return (
ApiClient.baseUrl.replace(/\/$/, "") +
"/html/reg.html?affUrl=" +
encodeURIComponent(url.replace(/^\//, ""))
);
}
return (
location.origin +
"/html/reg.html" +
(code ? "?inviteCode=" + encodeURIComponent(code) : "")
);
}
// Load promotion info (link + QR code)
function loadPromoInfo() {
ApiClient.get(ApiClient.API.referralShareInfo)
.then(function (res) {
if (isSuccess(res)) {
var data = pickData(res, {}) || {};
// Build share link
var shareLink = fullShareLink(
// 推广链接由接口完整返回,前端仅展示和生成二维码。
var shareLink = String(
firstDefined(
data.affUrl,
data.shareUrl,
@@ -521,14 +502,14 @@
data.promoteUrl,
data.referralUrl,
data.url,
),
firstDefined(
data.inviteCode,
data.referralCode,
data.affCode,
data.code,
),
"",
) || "",
).trim();
shareLink = NavigationUtil.referralRegisterUrl(
shareLink,
firstDefined(data.inviteCode, data.referralCode, data.affCode, data.code, ""),
);
if (!shareLink) throw new Error("接口未返回有效邀请码");
$("#promoLink").val(shareLink);
// Generate QR code
+46
View File
@@ -109,6 +109,13 @@
<button class="uc-btn uc-btn-edit" onclick="openEditProfile()">
编辑资料
</button>
<button
class="uc-btn uc-btn-edit"
id="referralBindButton"
onclick="openReferralBindPrompt()"
>
绑定邀请码
</button>
<button
class="uc-btn uc-btn-expert"
id="expertApplyBtn"
@@ -820,6 +827,45 @@
});
}
function bindReferralInviteCode(inviteCode) {
var $button = $("#referralBindButton");
$button.prop("disabled", true).text("绑定中...");
ApiClient.post(ApiClient.API.referralBind, { inviteCode: inviteCode })
.then(function (res) {
if (!ApiClient.isSuccess(res)) {
throw new Error((res && res.msg) || "邀请码绑定失败");
}
$button.text("已绑定");
layui.layer.msg("邀请码绑定成功", { icon: 1 });
})
.catch(function (error) {
$button.prop("disabled", false).text("绑定邀请码");
layui.layer.msg(error.message || "邀请码绑定失败,请稍后重试", { icon: 2 });
});
}
function openReferralBindPrompt() {
layui.layer.prompt(
{ title: "请输入邀请人的邀请码", formType: 0, btn: ["下一步", "取消"] },
function (value, promptIndex) {
var inviteCode = String(value || "").trim();
if (!inviteCode) {
layui.layer.msg("请输入邀请码", { icon: 2 });
return;
}
layui.layer.close(promptIndex);
layui.layer.confirm(
"每个账号只能绑定一个邀请人,绑定后不能更换。确认继续吗?",
{ title: "确认绑定", btn: ["确认绑定", "取消"] },
function (confirmIndex) {
layui.layer.close(confirmIndex);
bindReferralInviteCode(inviteCode);
},
);
},
);
}
// ====== Sign-in Records ======
function loadSignInRecords(pageNum) {
signInPageNum = pageNum || 1;
+68
View File
@@ -0,0 +1,68 @@
const assert = require("assert");
const fs = require("fs");
const path = require("path");
const vm = require("vm");
const root = path.resolve(__dirname, "..");
const authSource = fs.readFileSync(path.join(root, "utils", "AuthPageUtil.js"), "utf8");
const configSource = fs.readFileSync(path.join(root, "config.js"), "utf8");
const login = fs.readFileSync(path.join(root, "html", "login.html"), "utf8");
const register = fs.readFileSync(path.join(root, "html", "reg.html"), "utf8");
const usercenter = fs.readFileSync(path.join(root, "html", "usercenter.html"), "utf8");
const promo = fs.readFileSync(path.join(root, "html", "tuiguang.html"), "utf8");
const distribution = fs.readFileSync(path.join(root, "html", "fenxiao.html"), "utf8");
const resetPassword = fs.readFileSync(path.join(root, "html", "repwd.html"), "utf8");
[login, register, resetPassword].forEach(function (page) {
Array.from(page.matchAll(/<script(?:\s[^>]*)?>([\s\S]*?)<\/script>/gi), function (match) {
return match[1];
}).filter(Boolean).forEach(function (source) {
new Function(source);
});
});
const context = { URLSearchParams, window: { location: { search: "?inviteCode=invite-001" } } };
vm.runInNewContext(`${authSource}\nthis.AuthPageUtilForTest = AuthPageUtil;`, context);
assert.strictEqual(context.AuthPageUtilForTest.getReferralInviteCodeFromUrl(), "invite-001");
assert.strictEqual(context.AuthPageUtilForTest.getReferralInviteCodeFromUrl("?referralCode=legacy"), "");
assert(register.includes("registerData.inviteCode = inviteCode"), "registration must send a non-empty inviteCode");
assert(register.includes('$("#captchaGroup").hide();'), "registration verification must hide after SMS is sent");
assert(register.includes('$("#captchaGroup").show();'), "registration verification must return after the phone changes");
assert(/currentVerifyType === "slide"[\s\S]*?renderSlideCaptchaEntry\(\);[\s\S]*?#captchaGroup"\)\.hide\(\)/.test(register), "slide mode must not render an inline verification row");
assert(!login.includes("bindPendingReferralInviteCode"), "login must not bind referrals automatically");
assert(!register.includes("bindPendingReferralInviteCode"), "registration success must not issue a second bind request");
assert(usercenter.includes("ApiClient.API.referralBind, { inviteCode: inviteCode }"), "user center must provide manual binding");
assert(promo.includes("NavigationUtil.referralRegisterUrl"), "promotion page must normalize returned links to registration");
assert(login.includes('id="captchaGroup" style="display: none"'));
assert(login.includes('$("#captchaGroup").show();'));
[register, resetPassword].forEach(function (page) {
assert(page.includes('id="captchaGroup" style="visibility: hidden"'));
assert(page.includes('$("#captchaGroup").css("visibility", "visible");'));
});
const configContext = {
URL,
MutationObserver: function () {},
location: { hostname: "example.com", port: "", href: "https://example.com/html/index.html?inviteCode=invite-001" },
document: { readyState: "loading", addEventListener() {} },
window: { location: { href: "https://example.com/html/index.html?inviteCode=invite-001" }, open() { return null; } },
};
vm.runInNewContext(configSource, configContext);
assert.strictEqual(
configContext.window.NavigationUtil.referralRegisterUrl("https://example.com/app?inviteCode=invite-001"),
"https://example.com/html/reg.html?inviteCode=invite-001",
);
assert(!distribution.includes("applyDistribution"), "the obsolete empty bind entry must be removed");
context.ApiClient = {
API: { authVerifyConfig: "/api/web/auth/verify-config" },
get() { return Promise.reject(new Error("network unavailable")); },
};
context.AuthPageUtilForTest.loadVerifyType().then(function (type) {
assert.strictEqual(type, "slide", "verify-config failure must not show image captcha");
console.log("referral register contract checks passed");
}).catch(function (error) {
console.error(error);
process.exitCode = 1;
});
-2
View File
@@ -44,7 +44,6 @@ const ApiClient = {
referralSummary: '/api/web/referral/summary',
referralInviteList: '/api/web/referral/invite-list',
referralRebateList: '/api/web/referral/rebate-list',
referralBindPreview: '/api/web/referral/bind-preview',
referralBind: '/api/web/referral/bind',
accountInfo: '/api/web/account/info',
accountProfile: '/api/web/account/profile',
@@ -610,7 +609,6 @@ const ApiClient = {
'/api/web/rebate/withdraw': { url: '/api/web/wallet/withdraw', method: 'POST', data },
'/api/web/rebate/rebateToBalance': { url: '/api/web/wallet/transfer-to-account', method: 'POST', data },
'/api/web/distribution/getPageList': { url: '/api/web/referral/invite-list', method: 'GET', data: pageParams },
'/api/web/user/applyDistribution': { url: '/api/web/referral/bind', method: 'POST', data },
'/api/web/user/applyExpert': { url: '/api/web/expert/apply', method: 'POST', data },
'/api/web/user/expert/apply': { url: '/api/web/expert/apply', method: 'POST', data },
'/api/web/user/updateInfo': { url: '/api/web/account/profile', method: 'PUT', data },
+2 -79
View File
@@ -4,14 +4,6 @@ const AuthPageUtil = {
slideX: 0,
slideToken: '',
slideCaptchaViewportCleanup: null,
referralInviteSessionKey: 'pendingReferralInviteCode',
getSessionStorage() {
if (typeof sessionStorage !== 'undefined') return sessionStorage;
if (typeof window !== 'undefined' && window.sessionStorage) return window.sessionStorage;
return null;
},
normalizeReferralInviteCode(inviteCode) {
return String(inviteCode || '').trim();
},
@@ -31,82 +23,13 @@ const AuthPageUtil = {
try {
const params = new Params(query || '');
return this.normalizeReferralInviteCode(
params.get('inviteCode') || params.get('referralCode') || '',
params.get('inviteCode') || '',
);
} catch (error) {
return '';
}
},
setPendingReferralInviteCode(inviteCode) {
const code = this.normalizeReferralInviteCode(inviteCode);
const storage = this.getSessionStorage();
if (code && storage) {
storage.setItem(this.referralInviteSessionKey, code);
}
return code;
},
getPendingReferralInviteCode() {
const storage = this.getSessionStorage();
if (!storage) return '';
return this.normalizeReferralInviteCode(storage.getItem(this.referralInviteSessionKey));
},
clearPendingReferralInviteCode() {
const storage = this.getSessionStorage();
if (storage) storage.removeItem(this.referralInviteSessionKey);
},
captureReferralInviteFromUrl(search) {
const code = this.getReferralInviteCodeFromUrl(search);
if (code) {
this.setPendingReferralInviteCode(code);
}
return code;
},
bindPendingReferralInviteCode() {
const inviteCode = this.getPendingReferralInviteCode();
if (!inviteCode) {
return Promise.resolve({ skipped: true, reason: 'empty' });
}
if (
typeof ApiClient === 'undefined' ||
!ApiClient.API ||
!ApiClient.API.referralBind ||
typeof ApiClient.post !== 'function'
) {
return Promise.resolve({ skipped: true, reason: 'missing-api' });
}
if (typeof ApiClient.token === 'function' && !ApiClient.token()) {
return Promise.resolve({ skipped: true, reason: 'unauthenticated' });
}
return ApiClient.post(ApiClient.API.referralBind, { inviteCode })
.then((res) => {
const isSuccess =
typeof ApiClient.isSuccess === 'function'
? ApiClient.isSuccess(res)
: !!(res && (res.success === true || Number(res.code) === 0 || Number(res.code) === 200));
if (isSuccess) {
this.clearPendingReferralInviteCode();
return { skipped: false, success: true, res };
}
return { skipped: false, success: false, res };
})
.catch((error) => ({ skipped: false, success: false, error }));
},
isPhone(phone) {
return /^1[3-9]\d{9}$/.test(String(phone || '').trim());
},
@@ -133,7 +56,7 @@ const AuthPageUtil = {
}
return 'captcha';
})
.catch(() => 'captcha');
.catch(() => 'slide');
},
buildSmsParams(options = {}) {