mirror of
https://github.com/Silentely/eSIM-Tools.git
synced 2026-09-03 06:24:20 +08:00
✨ feat: 添加手机浏览器环境检测与警告功能
- 新增 browser-utils.js 模块,提供 isMobileBrowser 检测和 showMobileWarning 警告功能 - 实现会话级去重机制,避免重复显示手机环境警告通知 - 在 SimyoApp 的登录和设备更换流程中添加手机环境检测逻辑 - 在 GiffgaffApp 的 OAuth 登录流程中添加手机环境检测逻辑 - 添加多语言翻译支持,包括中文和英文版本的环境警告提示文本
This commit is contained in:
@@ -20,6 +20,7 @@ import {
|
||||
downloadQRCode
|
||||
} from './modules/utils.js';
|
||||
import { t, tl } from '../../js/modules/i18n.js';
|
||||
import { isMobileBrowser, showMobileWarning } from '../../js/modules/browser-utils.js';
|
||||
import captchaManager from '../../js/modules/captcha-manager.js';
|
||||
import Logger from '../../js/modules/logger.js';
|
||||
|
||||
@@ -428,6 +429,11 @@ class GiffgaffApp {
|
||||
const { elements } = uiController;
|
||||
console.log('[Giffgaff] === OAuth 登录开始 ===');
|
||||
|
||||
// 手机环境检测:非PC环境弹出提醒
|
||||
if (isMobileBrowser()) {
|
||||
showMobileWarning();
|
||||
}
|
||||
|
||||
// 检查服务时间
|
||||
if (!isServiceTimeAvailable()) {
|
||||
console.log('[Giffgaff] 服务时间外,显示警告');
|
||||
|
||||
32
src/js/modules/browser-utils.js
Normal file
32
src/js/modules/browser-utils.js
Normal file
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* 浏览器环境检测与提示工具
|
||||
* 提供手机浏览器检测和环境警告功能,支持会话级去重
|
||||
*/
|
||||
import { tl } from './i18n.js';
|
||||
import NotificationManager from './notification-manager.js';
|
||||
|
||||
const DEDUP_KEY = 'esim-mobile-warning-shown';
|
||||
|
||||
/**
|
||||
* 检测当前是否为手机浏览器
|
||||
* @returns {boolean} 是否为手机浏览器
|
||||
*/
|
||||
export function isMobileBrowser() {
|
||||
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示手机环境警告通知
|
||||
* 每个会话仅展示一次,避免重复点击造成通知堆叠
|
||||
*/
|
||||
export function showMobileWarning() {
|
||||
try {
|
||||
if (sessionStorage.getItem(DEDUP_KEY)) return;
|
||||
sessionStorage.setItem(DEDUP_KEY, '1');
|
||||
} catch (_) {}
|
||||
|
||||
NotificationManager.warning(
|
||||
tl('当前为手机浏览器环境,部分功能可能受限。如遇错误请切换到 PC 环境操作。'),
|
||||
7000
|
||||
);
|
||||
}
|
||||
@@ -689,6 +689,7 @@ export const TRANSLATIONS = {
|
||||
};
|
||||
|
||||
export const LITERAL_TRANSLATIONS = {
|
||||
'当前为手机浏览器环境,部分功能可能受限。如遇错误请切换到 PC 环境操作。': 'You are using a mobile browser. Some features may be limited. If you encounter errors, please switch to a PC.',
|
||||
'点击返回此步骤': 'Click to revisit this step',
|
||||
'请按顺序完成前序步骤': 'Complete earlier steps in order',
|
||||
'已选择OAuth 2.0登录方式': 'OAuth 2.0 login selected',
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
delay
|
||||
} from './modules/utils.js';
|
||||
import { t, tl } from '../../js/modules/i18n.js';
|
||||
import { isMobileBrowser, showMobileWarning } from '../../js/modules/browser-utils.js';
|
||||
import Logger from '../../js/modules/logger.js';
|
||||
|
||||
class SimyoApp {
|
||||
@@ -187,6 +188,11 @@ class SimyoApp {
|
||||
const loginStatus = document.getElementById('loginStatus');
|
||||
console.log('[Simyo] === 登录开始 ===');
|
||||
|
||||
// 手机环境检测:非PC环境弹出提醒
|
||||
if (isMobileBrowser()) {
|
||||
showMobileWarning();
|
||||
}
|
||||
|
||||
if (!phoneNumberEl || !passwordEl) {
|
||||
console.error('[Simyo] 登录表单元素未找到!');
|
||||
return;
|
||||
@@ -235,6 +241,11 @@ class SimyoApp {
|
||||
const statusEl = document.getElementById('applyNewEsimStatus');
|
||||
console.log('[Simyo] === 请求设备更换 ===');
|
||||
|
||||
// 手机环境检测:非PC环境弹出提醒
|
||||
if (isMobileBrowser()) {
|
||||
showMobileWarning();
|
||||
}
|
||||
|
||||
try {
|
||||
applyBtn.innerHTML = `<span class="loading"></span> ${tl('处理中...')}`;
|
||||
applyBtn.disabled = true;
|
||||
|
||||
@@ -8,6 +8,9 @@ describe('SimyoApp 设备更换主流程自动化', () => {
|
||||
let mockSkipDeviceChange;
|
||||
let mockApplyNewEsim;
|
||||
let mockVerifyCode;
|
||||
let mockIsMobileBrowser;
|
||||
let mockShowMobileWarning;
|
||||
let mockAuthLogin;
|
||||
|
||||
beforeEach(async () => {
|
||||
jest.resetModules();
|
||||
@@ -18,6 +21,8 @@ describe('SimyoApp 设备更换主流程自动化', () => {
|
||||
<button id="verifyCodeBtn" disabled></button>
|
||||
<div id="verifyCodeStatus"></div>
|
||||
<input id="validationCodeInput" />
|
||||
<input id="phoneNumber" />
|
||||
<input id="password" type="password" />
|
||||
<button id="loginBtn"></button>
|
||||
<div id="loginStatus"></div>
|
||||
<button id="getEsimBtn"></button>
|
||||
@@ -76,13 +81,16 @@ describe('SimyoApp 设备更换主流程自动化', () => {
|
||||
}
|
||||
}));
|
||||
|
||||
jest.doMock('../../src/simyo/js/modules/auth-handler.js', () => ({
|
||||
authHandler: {
|
||||
login: jest.fn(),
|
||||
isLoggedIn: jest.fn(() => true),
|
||||
getSessionToken: jest.fn(() => 'token')
|
||||
}
|
||||
}));
|
||||
jest.doMock('../../src/simyo/js/modules/auth-handler.js', () => {
|
||||
mockAuthLogin = jest.fn();
|
||||
return {
|
||||
authHandler: {
|
||||
login: mockAuthLogin,
|
||||
isLoggedIn: jest.fn(() => true),
|
||||
getSessionToken: jest.fn(() => 'token')
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
jest.doMock('../../src/simyo/js/modules/esim-service.js', () => ({
|
||||
esimService: {
|
||||
@@ -111,6 +119,15 @@ describe('SimyoApp 设备更换主流程自动化', () => {
|
||||
delay: jest.fn(() => Promise.resolve())
|
||||
}));
|
||||
|
||||
jest.doMock('../../src/js/modules/browser-utils.js', () => {
|
||||
mockIsMobileBrowser = jest.fn(() => false);
|
||||
mockShowMobileWarning = jest.fn();
|
||||
return {
|
||||
isMobileBrowser: mockIsMobileBrowser,
|
||||
showMobileWarning: mockShowMobileWarning
|
||||
};
|
||||
});
|
||||
|
||||
jest.doMock('../../src/js/modules/i18n.js', () => ({
|
||||
t: (key, params = {}) => {
|
||||
if (!params || Object.keys(params).length === 0) return key;
|
||||
@@ -161,5 +178,36 @@ describe('SimyoApp 设备更换主流程自动化', () => {
|
||||
expect(mockVerifyCode).toHaveBeenCalledWith('123456');
|
||||
expect(mockSkipDeviceChange).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('手机浏览器登录时应弹出环境警告', async () => {
|
||||
mockIsMobileBrowser.mockReturnValue(true);
|
||||
document.getElementById('phoneNumber').value = '0612345678';
|
||||
document.getElementById('password').value = 'pass';
|
||||
mockAuthLogin.mockResolvedValue({ success: true, mode: 'standard' });
|
||||
|
||||
await app.handleLogin();
|
||||
|
||||
expect(mockShowMobileWarning).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('手机浏览器设备更换时应弹出环境警告', async () => {
|
||||
mockIsMobileBrowser.mockReturnValue(true);
|
||||
mockApplyNewEsim.mockResolvedValueOnce({ success: true, message: 'ok' });
|
||||
|
||||
await app.handleApplyNewEsim();
|
||||
|
||||
expect(mockShowMobileWarning).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('PC浏览器登录时不应弹出环境警告', async () => {
|
||||
mockIsMobileBrowser.mockReturnValue(false);
|
||||
document.getElementById('phoneNumber').value = '0612345678';
|
||||
document.getElementById('password').value = 'pass';
|
||||
mockAuthLogin.mockResolvedValue({ success: true, mode: 'standard' });
|
||||
|
||||
await app.handleLogin();
|
||||
|
||||
expect(mockShowMobileWarning).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user