/** * OmniCard AI (CRMmp) - 统一身份认证登录业务驱动层 * 第一版可用骨架:不接真实 Google / Apple SDK,不伪造成功登录 */ import { getCurrentLocale, getOmniText, OmniLocale } from '../../common/locale.uts'; import { setAuthToken, setTenantId } from '../../common/request.uts'; export type LoginTab = 'phone' | 'email'; export type SocialProvider = 'google' | 'apple'; export type LoginCopyKey = | 'title' | 'brandTag' | 'subtitle' | 'desc' | 'tabPhone' | 'tabEmail' | 'countryCode' | 'phonePlaceholder' | 'sendCode' | 'smsCode' | 'login' | 'magicLink' | 'emailPlaceholder' | 'orContinueWith' | 'google' | 'apple' | 'comingSoon' | 'phoneRequired' | 'emailRequired' | 'codeRequired' | 'termsNotice' | 'termsOfService' | 'privacyPolicy' | 'and' | 'countdownSuffix' | 'loginSuccess'; export type LoginState = { tab: LoginTab; countryCode: string; phone: string; smsCode: string; email: string; submitting: boolean; errorMessage: string; countdown: number; }; function isZhLocale(): boolean { return getCurrentLocale() === 'zh-CN'; } /** * 登录文案:能复用 locale.uts 的走词典,缺 key 时中英简单分支 */ export function resolveLoginText(key: LoginCopyKey | string, targetLocale?: string): string { const loc = targetLocale != null && targetLocale !== '' ? targetLocale : getCurrentLocale(); if (key === 'loginSuccess') { return getOmniText(loc as OmniLocale, 'common.success'); } const zh = loc === 'zh-CN'; if (key === 'title') { return zh ? '登录 OmniCard' : 'Sign in to OmniCard'; } if (key === 'brandTag') { return zh ? '全球智能数字名片' : 'Global Digital Identity'; } if (key === 'subtitle') { return zh ? '极简出海商务,连接全球商机' : 'Minimalist global commerce & identity'; } if (key === 'tabPhone') { return zh ? '手机号' : 'Phone'; } if (key === 'tabEmail') { return zh ? '邮箱' : 'Email'; } if (key === 'desc') { return zh ? '使用国际手机号或邮箱继续' : 'Continue with your phone or email'; } if (key === 'countryCode') { return zh ? '区号' : 'Code'; } if (key === 'phonePlaceholder') { return zh ? '手机号' : 'Phone number'; } if (key === 'sendCode') { return zh ? '发送验证码' : 'Send code'; } if (key === 'smsCode') { return zh ? '验证码' : 'Verification code'; } if (key === 'login') { return zh ? '登录' : 'Sign in'; } if (key === 'magicLink') { return zh ? '发送登录链接' : 'Send sign-in link'; } if (key === 'emailPlaceholder') { return zh ? '工作邮箱' : 'Work email'; } if (key === 'orContinueWith') { return zh ? '或通过以下方式继续' : 'Or continue with'; } if (key === 'google') { return zh ? 'Google' : 'Google'; } if (key === 'apple') { return zh ? 'Apple' : 'Apple'; } if (key === 'comingSoon') { return zh ? '即将开放' : 'Coming soon'; } if (key === 'phoneRequired') { return zh ? '请填写手机号' : 'Enter your phone number'; } if (key === 'emailRequired') { return zh ? '请填写邮箱' : 'Enter your email'; } if (key === 'codeRequired') { return zh ? '请填写验证码' : 'Enter the verification code'; } if (key === 'termsNotice') { return zh ? '登录即代表您已同意' : 'By continuing, you agree to our'; } if (key === 'termsOfService') { return zh ? '服务条款' : 'Terms of Service'; } if (key === 'privacyPolicy') { return zh ? '隐私政策' : 'Privacy Policy'; } if (key === 'and') { return zh ? '与' : 'and'; } if (key === 'countdownSuffix') { return zh ? '秒后重发' : 's'; } return ''; } function toastNone(title: string): void { uni.showToast({ title, icon: 'none', }); } function finishAfterLogin(): void { if (typeof uni.switchTab === 'function') { uni.switchTab({ url: '/pages/owner/card/index', }); } else if (typeof uni.reLaunch === 'function') { uni.reLaunch({ url: '/pages/owner/card/index', }); } } export function createLoginState(): LoginState { return { tab: 'phone', countryCode: '+86', phone: '', smsCode: '', email: '', submitting: false, errorMessage: '', countdown: 0, }; } export function switchLoginTab(state: LoginState, tab: LoginTab): void { state.tab = tab; state.errorMessage = ''; } /** * 倒计时推进函数 */ export function tickCountdown(state: LoginState): void { if (state.countdown > 0) { state.countdown -= 1; } } /** * 登录成功路径:写入 token / 可选 tenantId,再返回上一页或 toast */ export function completeLogin(token: string, tenantId?: string): boolean { const safeToken = token != null ? token.trim() : ''; if (safeToken === '') { return false; } setAuthToken(safeToken); const safeTenant = tenantId != null ? tenantId.trim() : ''; if (safeTenant !== '') { setTenantId(safeTenant); } finishAfterLogin(); return true; } export function sendSmsCode(state: LoginState): boolean { if (state.countdown > 0) { return false; } const phone = state.phone != null ? state.phone.trim() : ''; if (phone === '') { state.errorMessage = resolveLoginText('phoneRequired'); toastNone(state.errorMessage); return false; } state.errorMessage = ''; state.countdown = 60; toastNone(resolveLoginText('comingSoon')); return true; } /** * 国际手机号验证码登录。空手机号不提交;第一版不伪造成功登录 */ export function submitPhoneLogin(state: LoginState): boolean { const phone = state.phone != null ? state.phone.trim() : ''; if (phone === '') { state.errorMessage = resolveLoginText('phoneRequired'); toastNone(state.errorMessage); return false; } const smsCode = state.smsCode != null ? state.smsCode.trim() : ''; if (smsCode === '') { state.errorMessage = resolveLoginText('codeRequired'); toastNone(state.errorMessage); return false; } if (state.submitting) { return false; } state.errorMessage = ''; toastNone(resolveLoginText('comingSoon')); return false; } /** * 邮箱 Magic Link。空邮箱不提交;第一版不伪造成功登录 */ export function sendMagicLink(state: LoginState): boolean { const email = state.email != null ? state.email.trim() : ''; if (email === '') { state.errorMessage = resolveLoginText('emailRequired'); toastNone(state.errorMessage); return false; } if (state.submitting) { return false; } state.errorMessage = ''; toastNone(resolveLoginText('comingSoon')); return false; } /** * Google / Apple 仅展示即将开放,不写凭证 */ export function tapSocialLogin(_provider: SocialProvider): void { toastNone(resolveLoginText('comingSoon')); }