feat(admin): 从已有玩家升级代理、修复 i18n 与过期 .js 冲突
- 新建一级代理改为选择已有玩家;新建用户可选一级代理 - 操作日志/注单等扁平 key 翻译;清理 src 内误生成 .js,Vite 优先解析 .ts Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
42
apps/admin/src/components/AdminLocaleFlag.vue
Normal file
42
apps/admin/src/components/AdminLocaleFlag.vue
Normal file
@@ -0,0 +1,42 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import type { AdminLocale } from '../i18n/admin-messages';
|
||||
|
||||
const LOCALE_COUNTRY: Record<AdminLocale, string> = {
|
||||
'zh-CN': 'cn',
|
||||
'en-US': 'us',
|
||||
'ms-MY': 'my',
|
||||
};
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{ locale: AdminLocale | string; size?: number }>(),
|
||||
{ size: 18 },
|
||||
);
|
||||
|
||||
const countryCode = computed(() => {
|
||||
const code = props.locale as AdminLocale;
|
||||
return LOCALE_COUNTRY[code] ?? 'us';
|
||||
});
|
||||
|
||||
const src = computed(() => `/flags/${countryCode.value}.svg`);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<img
|
||||
:src="src"
|
||||
:width="size"
|
||||
:height="Math.round(size * 0.67)"
|
||||
class="admin-locale-flag-img"
|
||||
:alt="countryCode"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.admin-locale-flag-img {
|
||||
display: block;
|
||||
flex-shrink: 0;
|
||||
border-radius: 2px;
|
||||
object-fit: cover;
|
||||
box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
</style>
|
||||
@@ -1,11 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useAdminLocale, type AdminLocale } from '../composables/useAdminLocale';
|
||||
import AdminLocaleFlag from './AdminLocaleFlag.vue';
|
||||
|
||||
const { locale, locales, setLocale, t } = useAdminLocale();
|
||||
|
||||
const current = computed(() => locales.find((l) => l.code === locale.value) ?? locales[0]);
|
||||
|
||||
function onChange(e: Event) {
|
||||
setLocale((e.target as HTMLSelectElement).value as AdminLocale);
|
||||
}
|
||||
@@ -13,10 +11,10 @@ function onChange(e: Event) {
|
||||
|
||||
<template>
|
||||
<label class="admin-locale" :title="t('lang')">
|
||||
<span class="admin-locale-flag" aria-hidden="true">{{ current.flag }}</span>
|
||||
<AdminLocaleFlag :locale="locale" :size="20" />
|
||||
<select :value="locale" class="admin-locale-select" :aria-label="t('lang')" @change="onChange">
|
||||
<option v-for="l in locales" :key="l.code" :value="l.code">
|
||||
{{ l.flag }} {{ l.label }}
|
||||
{{ l.label }}
|
||||
</option>
|
||||
</select>
|
||||
</label>
|
||||
@@ -26,22 +24,18 @@ function onChange(e: Event) {
|
||||
.admin-locale {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.admin-locale-flag {
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
flex-shrink: 0;
|
||||
gap: 8px;
|
||||
}
|
||||
.admin-locale-select {
|
||||
background: #0d0d0d;
|
||||
color: var(--green-text);
|
||||
border: 1px solid var(--green-border);
|
||||
border-radius: 6px;
|
||||
padding: 4px 8px 4px 4px;
|
||||
padding: 5px 24px 5px 8px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
min-width: 108px;
|
||||
min-width: 120px;
|
||||
cursor: pointer;
|
||||
line-height: 1.2;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user