feat(mpuniapp): 重构登录页面为瑞士国际主义极简品牌感,优化宽屏居中与移动端自适应

这个提交包含在:
wikiboss
2026-09-21 10:43:10 +08:00
父节点 41b2596761
当前提交 a7e20c9c5a
共有 3 个文件被更改,包括 52 次插入 和 6 次删除

查看文件

@@ -32,6 +32,7 @@ type LoginState = {
email: string; email: string;
submitting: boolean; submitting: boolean;
errorMessage: string; errorMessage: string;
countdown: number;
}; };
type UseLoginModule = { type UseLoginModule = {
@@ -41,6 +42,8 @@ type UseLoginModule = {
sendMagicLink: (state: LoginState) => boolean; sendMagicLink: (state: LoginState) => boolean;
sendSmsCode: (state: LoginState) => boolean; sendSmsCode: (state: LoginState) => boolean;
tapSocialLogin: (provider: 'google' | 'apple') => void; tapSocialLogin: (provider: 'google' | 'apple') => void;
resolveLoginText: (key: string) => string;
tickCountdown: (state: LoginState) => void;
}; };
describe('OmniCard AI 用户端统一登录业务逻辑测试 (useLogin.uts)', () => { describe('OmniCard AI 用户端统一登录业务逻辑测试 (useLogin.uts)', () => {
@@ -49,6 +52,7 @@ describe('OmniCard AI 用户端统一登录业务逻辑测试 (useLogin.uts)', (
let lastRequestOptions: UniRequestOption | null; let lastRequestOptions: UniRequestOption | null;
let requestCallCount: number; let requestCallCount: number;
let navigateBackCount: number; let navigateBackCount: number;
let switchTabCount: number;
beforeEach(() => { beforeEach(() => {
storageMap = new Map(); storageMap = new Map();
@@ -56,6 +60,7 @@ describe('OmniCard AI 用户端统一登录业务逻辑测试 (useLogin.uts)', (
lastRequestOptions = null; lastRequestOptions = null;
requestCallCount = 0; requestCallCount = 0;
navigateBackCount = 0; navigateBackCount = 0;
switchTabCount = 0;
jest.resetModules(); jest.resetModules();
(global as { uni?: Record<string, unknown> }).uni = { (global as { uni?: Record<string, unknown> }).uni = {
@@ -66,6 +71,9 @@ describe('OmniCard AI 用户端统一登录业务逻辑测试 (useLogin.uts)', (
toastCalls.push(options); toastCalls.push(options);
}, },
reLaunch: jest.fn(), reLaunch: jest.fn(),
switchTab: (_options: { url: string }) => {
switchTabCount += 1;
},
navigateBack: () => { navigateBack: () => {
navigateBackCount += 1; navigateBackCount += 1;
}, },
@@ -98,13 +106,14 @@ describe('OmniCard AI 用户端统一登录业务逻辑测试 (useLogin.uts)', (
} }
describe('1. completeLogin 写入本地凭证', () => { describe('1. completeLogin 写入本地凭证', () => {
it('1.1 completeLogin 会 setStorage token', () => { it('1.1 completeLogin 会 setStorage token 并跳转名片页', () => {
const { completeLogin } = loadUseLogin(); const { completeLogin } = loadUseLogin();
const ok = completeLogin('mock_jwt_login_t09'); const ok = completeLogin('mock_jwt_login_t09');
expect(ok).toBe(true); expect(ok).toBe(true);
expect(storageMap.get('token')).toBe('mock_jwt_login_t09'); expect(storageMap.get('token')).toBe('mock_jwt_login_t09');
expect(switchTabCount).toBe(1);
}); });
it('1.2 传入 tenantId 时同步写入 tenant_id', () => { it('1.2 传入 tenantId 时同步写入 tenant_id', () => {
@@ -114,6 +123,7 @@ describe('OmniCard AI 用户端统一登录业务逻辑测试 (useLogin.uts)', (
expect(storageMap.get('token')).toBe('mock_jwt_login_t09'); expect(storageMap.get('token')).toBe('mock_jwt_login_t09');
expect(storageMap.get('tenant_id')).toBe('tenant_omni_88'); expect(storageMap.get('tenant_id')).toBe('tenant_omni_88');
expect(switchTabCount).toBe(1);
}); });
it('1.3 未传 tenantId 时不写入 tenant_id', () => { it('1.3 未传 tenantId 时不写入 tenant_id', () => {
@@ -123,6 +133,7 @@ describe('OmniCard AI 用户端统一登录业务逻辑测试 (useLogin.uts)', (
expect(storageMap.get('token')).toBe('mock_jwt_only_token'); expect(storageMap.get('token')).toBe('mock_jwt_only_token');
expect(storageMap.has('tenant_id')).toBe(false); expect(storageMap.has('tenant_id')).toBe(false);
expect(switchTabCount).toBe(1);
}); });
}); });
@@ -175,4 +186,38 @@ describe('OmniCard AI 用户端统一登录业务逻辑测试 (useLogin.uts)', (
expect(toastCalls[1].title).toContain('即将开放'); expect(toastCalls[1].title).toContain('即将开放');
}); });
}); });
describe('4. 极简品牌感文案与国际化解析', () => {
it('4.1 正确解析品牌感文案,杜绝空字符串与硬编码', () => {
const { resolveLoginText } = loadUseLogin();
expect(resolveLoginText('brandTag').length).toBeGreaterThan(0);
expect(resolveLoginText('subtitle').length).toBeGreaterThan(0);
expect(resolveLoginText('orContinueWith').length).toBeGreaterThan(0);
expect(resolveLoginText('termsNotice').length).toBeGreaterThan(0);
expect(resolveLoginText('termsOfService').length).toBeGreaterThan(0);
expect(resolveLoginText('privacyPolicy').length).toBeGreaterThan(0);
});
});
describe('5. 验证码倒计时机制', () => {
it('5.1 手机号合法时发送验证码触发 60s 倒计时', () => {
const { createLoginState, sendSmsCode, tickCountdown } = loadUseLogin();
const state = createLoginState();
state.phone = '13800138000';
sendSmsCode(state);
expect(state.countdown).toBe(60);
// 递减一次
tickCountdown(state);
expect(state.countdown).toBe(59);
// 倒计时中不能重复触发
const again = sendSmsCode(state);
expect(again).toBe(false);
expect(state.countdown).toBe(59);
});
});
}); });

查看文件

@@ -190,7 +190,7 @@ const isRtlMode = computed((): boolean => {
}); });
function t(key: LoginCopyKey | string): string { function t(key: LoginCopyKey | string): string {
return resolveLoginText(key); return resolveLoginText(key, currentLang.value);
} }
const codeButtonText = computed((): string => { const codeButtonText = computed((): string => {

查看文件

@@ -3,7 +3,7 @@
* 第一版可用骨架:不接真实 Google / Apple SDK,不伪造成功登录 * 第一版可用骨架:不接真实 Google / Apple SDK,不伪造成功登录
*/ */
import { getCurrentLocale, getOmniText } from '../../common/locale.uts'; import { getCurrentLocale, getOmniText, OmniLocale } from '../../common/locale.uts';
import { setAuthToken, setTenantId } from '../../common/request.uts'; import { setAuthToken, setTenantId } from '../../common/request.uts';
export type LoginTab = 'phone' | 'email'; export type LoginTab = 'phone' | 'email';
@@ -55,12 +55,13 @@ function isZhLocale(): boolean {
/** /**
* 登录文案:能复用 locale.uts 的走词典,缺 key 时中英简单分支 * 登录文案:能复用 locale.uts 的走词典,缺 key 时中英简单分支
*/ */
export function resolveLoginText(key: LoginCopyKey | string): string { export function resolveLoginText(key: LoginCopyKey | string, targetLocale?: string): string {
const loc = targetLocale != null && targetLocale !== '' ? targetLocale : getCurrentLocale();
if (key === 'loginSuccess') { if (key === 'loginSuccess') {
return getOmniText(getCurrentLocale(), 'common.success'); return getOmniText(loc as OmniLocale, 'common.success');
} }
const zh = isZhLocale(); const zh = loc === 'zh-CN';
if (key === 'title') { if (key === 'title') {
return zh ? '登录 OmniCard' : 'Sign in to OmniCard'; return zh ? '登录 OmniCard' : 'Sign in to OmniCard';
} }