样式修改完成,待测试

This commit is contained in:
rain
2026-07-07 17:07:34 +08:00
parent 0f6ed0cad3
commit 8a6a8acab7
32 changed files with 2097 additions and 505 deletions
+333 -2
View File
@@ -3,6 +3,109 @@ const AuthPageUtil = {
slideUuid: '',
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();
},
getReferralInviteCodeFromUrl(search) {
const query =
search != null
? search
: (typeof window !== 'undefined' && window.location && window.location.search) || '';
const Params =
typeof URLSearchParams !== 'undefined'
? URLSearchParams
: typeof window !== 'undefined' && window.URLSearchParams;
if (!Params) return '';
try {
const params = new Params(query || '');
return this.normalizeReferralInviteCode(
params.get('inviteCode') || params.get('referralCode') || '',
);
} 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());
@@ -122,6 +225,234 @@ const AuthPageUtil = {
}
},
blurActiveElement() {
if (typeof document === 'undefined') return;
const activeElement = document.activeElement;
if (activeElement && activeElement !== document.body && typeof activeElement.blur === 'function') {
activeElement.blur();
}
},
ensureSlideCaptchaMobileCenterStyle() {
if (typeof document === 'undefined' || document.getElementById('auth-slide-captcha-mobile-center-style')) {
return;
}
const style = document.createElement('style');
style.id = 'auth-slide-captcha-mobile-center-style';
style.textContent = `
@media (max-width: 640px) {
#rvplus-slide-captcha-root.rvplus-slide-mask {
box-sizing: border-box !important;
align-items: center !important;
justify-content: center !important;
width: 100vw;
max-width: 100vw;
min-height: 100vh;
min-height: 100dvh;
padding: 12px !important;
}
#rvplus-slide-captcha-root .rvplus-slide-modal {
box-sizing: border-box;
max-width: calc(100vw - 24px);
max-height: calc(100vh - 24px);
max-height: calc(100dvh - 24px);
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
}
`;
document.head.appendChild(style);
},
getSlideCaptchaViewport() {
const fallbackWidth =
(typeof window !== 'undefined' && window.innerWidth) ||
(typeof document !== 'undefined' && document.documentElement && document.documentElement.clientWidth) ||
0;
const fallbackHeight =
(typeof window !== 'undefined' && window.innerHeight) ||
(typeof document !== 'undefined' && document.documentElement && document.documentElement.clientHeight) ||
0;
const viewport = typeof window !== 'undefined' ? window.visualViewport : null;
const screenWidth = (typeof window !== 'undefined' && window.screen && window.screen.width) || 0;
const screenHeight = (typeof window !== 'undefined' && window.screen && window.screen.height) || 0;
const width = Math.round((viewport && viewport.width) || fallbackWidth);
const height = Math.round((viewport && viewport.height) || fallbackHeight);
let scale = Number(viewport && viewport.scale) || 1;
if (screenWidth && screenWidth <= 640 && width > screenWidth && scale === 1) {
scale = screenWidth / width;
}
return {
width,
height,
offsetLeft: Math.round((viewport && viewport.offsetLeft) || 0),
offsetTop: Math.round((viewport && viewport.offsetTop) || 0),
scale,
displayWidth: Math.round(width * scale),
displayHeight: Math.round(height * scale),
screenWidth,
screenHeight,
};
},
isCompactSlideCaptchaViewport(viewport) {
return viewport.displayWidth <= 640 || (viewport.screenWidth > 0 && viewport.screenWidth <= 640);
},
centerSlideCaptchaDialog() {
if (typeof document === 'undefined') return false;
const root = document.getElementById('rvplus-slide-captcha-root');
if (!root) return false;
const viewport = this.getSlideCaptchaViewport();
if (!viewport.width || !viewport.height) return true;
const compact = this.isCompactSlideCaptchaViewport(viewport);
const visualPadding = compact ? 12 : 20;
const padding = visualPadding / (viewport.scale || 1);
const modalWidth = Math.max(0, Math.round(viewport.width - padding * 2));
const modalHeight = Math.max(0, Math.round(viewport.height - padding * 2));
root.style.position = 'fixed';
root.style.inset = 'auto';
root.style.left = viewport.offsetLeft + 'px';
root.style.top = viewport.offsetTop + 'px';
root.style.width = viewport.width + 'px';
root.style.height = viewport.height + 'px';
root.style.display = 'flex';
root.style.alignItems = 'center';
root.style.justifyContent = 'center';
root.style.boxSizing = 'border-box';
root.style.padding = padding + 'px';
const modal = root.querySelector && root.querySelector('.rvplus-slide-modal');
if (modal) {
modal.style.boxSizing = 'border-box';
modal.style.maxWidth = modalWidth + 'px';
modal.style.maxHeight = modalHeight + 'px';
modal.style.overflowY = 'auto';
modal.style.webkitOverflowScrolling = 'touch';
modal.style.width = compact ? modalWidth + 'px' : '';
}
return true;
},
clearSlideCaptchaViewportCentering() {
if (typeof this.slideCaptchaViewportCleanup !== 'function') return;
const cleanup = this.slideCaptchaViewportCleanup;
this.slideCaptchaViewportCleanup = null;
cleanup();
},
scheduleSlideCaptchaCentering(callback) {
if (typeof window !== 'undefined' && typeof window.requestAnimationFrame === 'function') {
window.requestAnimationFrame(callback);
return;
}
callback();
},
bindSlideCaptchaViewportCentering() {
if (typeof window === 'undefined') return;
this.clearSlideCaptchaViewportCentering();
const cleanups = [];
const recenter = () => {
if (!this.centerSlideCaptchaDialog()) {
this.clearSlideCaptchaViewportCentering();
}
};
const schedule = () => this.scheduleSlideCaptchaCentering(recenter);
const addListener = (target, type) => {
if (target && typeof target.addEventListener === 'function') {
target.addEventListener(type, schedule);
cleanups.push(() => target.removeEventListener(type, schedule));
}
};
addListener(window.visualViewport, 'resize');
addListener(window.visualViewport, 'scroll');
addListener(window, 'resize');
addListener(window, 'orientationchange');
this.slideCaptchaViewportCleanup = () => {
cleanups.forEach((cleanup) => cleanup());
};
schedule();
if (typeof window.setTimeout === 'function') {
window.setTimeout(schedule, 80);
window.setTimeout(schedule, 260);
}
},
deferClearSlideCaptchaViewportCentering() {
const clear = () => this.clearSlideCaptchaViewportCentering();
if (typeof window !== 'undefined' && typeof window.setTimeout === 'function') {
window.setTimeout(clear, 320);
return;
}
clear();
},
wrapSlideCaptchaCallbacks(options = {}) {
const wrapped = { ...options };
const wrap = (callback) => (...args) => {
try {
if (typeof callback === 'function') {
return callback(...args);
}
} finally {
this.deferClearSlideCaptchaViewportCentering();
}
return undefined;
};
wrapped.onSuccess = wrap(options.onSuccess);
wrapped.onCancel = wrap(options.onCancel);
return wrapped;
},
patchSlideCaptchaMobileCentering(SlideCaptcha) {
if (!SlideCaptcha || SlideCaptcha.__authPageMobileCentered || typeof SlideCaptcha.open !== 'function') {
return SlideCaptcha;
}
const nativeOpen = SlideCaptcha.open.bind(SlideCaptcha);
const nativeClose = typeof SlideCaptcha.close === 'function' ? SlideCaptcha.close.bind(SlideCaptcha) : null;
SlideCaptcha.open = (options = {}) => {
this.blurActiveElement();
this.ensureSlideCaptchaMobileCenterStyle();
const result = nativeOpen(this.wrapSlideCaptchaCallbacks(options));
this.bindSlideCaptchaViewportCentering();
return result;
};
if (nativeClose) {
SlideCaptcha.close = (...args) => {
this.clearSlideCaptchaViewportCentering();
return nativeClose(...args);
};
}
SlideCaptcha.__authPageMobileCentered = true;
return SlideCaptcha;
},
startSmsCountdown(buttonSelector, seconds = 60) {
const $button = layui.$(buttonSelector);
let left = seconds;
@@ -140,7 +471,7 @@ const AuthPageUtil = {
loadSlideCaptchaScript() {
this.installSlideCaptchaTenantHeader();
if (window.SlideCaptcha) return Promise.resolve(window.SlideCaptcha);
if (window.SlideCaptcha) return Promise.resolve(this.patchSlideCaptchaMobileCentering(window.SlideCaptcha));
if (window.__slideCaptchaLoading) return window.__slideCaptchaLoading;
window.__slideCaptchaLoading = new Promise((resolve, reject) => {
const script = document.createElement('script');
@@ -148,7 +479,7 @@ const AuthPageUtil = {
script.dataset.apiBase = ApiClient.baseUrl || '';
script.dataset.tenantId = ApiClient.tenantId || '936208';
script.onload = () => {
if (window.SlideCaptcha) resolve(window.SlideCaptcha);
if (window.SlideCaptcha) resolve(this.patchSlideCaptchaMobileCentering(window.SlideCaptcha));
else reject(new Error('滑动验证组件加载失败'));
};
script.onerror = () => reject(new Error('滑动验证组件加载失败'));