修改完成
This commit is contained in:
@@ -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
@@ -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
@@ -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();
|
||||
|
||||
+22
-13
@@ -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);
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
@@ -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
@@ -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 = {}) {
|
||||
|
||||
Reference in New Issue
Block a user