Files
thebet365/apps/player/src/composables/useAppLocale.ts
Mars 312c3c5816 feat(player): 注册账号、登录双模式与移动端性能优化
注册必填 7-32 位账号,手机号区号/本地号分存;登录默认账号模式并支持切换手机号登录;Player i18n 拆包与赛事接口优化。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-12 10:56:51 +08:00

73 lines
2.3 KiB
TypeScript

import { useI18n } from 'vue-i18n';
import { SUPPORTED_LOCALES, LOCALE_UI_LABELS, type Locale } from '@thebet365/shared';
import api from '../api';
import { useAuthStore } from '../stores/auth';
import { ensurePlayerLocale } from '../i18n';
const STORAGE_KEY = 'locale';
const COOKIE_MAX_AGE = 365 * 24 * 60 * 60;
export const APP_LOCALES = SUPPORTED_LOCALES.map((code) => ({
code,
label: LOCALE_UI_LABELS[code] ?? code,
}));
function persistLocale(code: string) {
localStorage.setItem(STORAGE_KEY, code);
document.cookie = `${STORAGE_KEY}=${encodeURIComponent(code)};path=/;max-age=${COOKIE_MAX_AGE};SameSite=Lax`;
}
export function useAppLocale() {
const i18n = useI18n({ useScope: 'global' });
const { locale } = i18n;
const auth = useAuthStore();
function applyLocale(code: string) {
if (!(SUPPORTED_LOCALES as readonly string[]).includes(code)) return;
locale.value = code;
persistLocale(code);
}
async function setLocale(code: string) {
if (!(SUPPORTED_LOCALES as readonly string[]).includes(code)) return;
if (locale.value === code) return;
if (auth.token) {
try {
await api.post('/player/language', { locale: code });
if (auth.user) {
auth.user = { ...auth.user, locale: code };
localStorage.setItem('user', JSON.stringify(auth.user));
}
} catch {
/* 离线或 token 过期时仍保留本地语言 */
}
}
await ensurePlayerLocale(i18n, code as Locale);
applyLocale(code);
}
/** 将当前语言同步到后端,仅在有 token 时执行,不修改本地 locale */
async function syncLocaleToBackend() {
if (!auth.token) return;
try {
await api.post('/player/language', { locale: locale.value });
if (auth.user) {
auth.user = { ...auth.user, locale: locale.value };
localStorage.setItem('user', JSON.stringify(auth.user));
}
} catch {
/* ignore */
}
}
async function initFromUser(userLocale?: string | null) {
if (userLocale && (SUPPORTED_LOCALES as readonly string[]).includes(userLocale)) {
await ensurePlayerLocale(i18n, userLocale as Locale);
applyLocale(userLocale);
}
}
return { locales: APP_LOCALES, setLocale, applyLocale, initFromUser, syncLocaleToBackend };
}