mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-04-03 14:20:50 +08:00
fix(i18n): 补全 MV/排行榜/歌单/搜索/专辑页面缺失的国际化
- 新增 comp.pages 命名空间,包含页面描述、地区分类、加载状态等 i18n 键 - toplist: 标题和描述文本国际化 - mv: 描述、加载状态、6 个地区分类标签国际化 - list: 描述、加载/无更多状态国际化,提取每日推荐常量 - search: 描述文本国际化 - album: 5 个地区分类标签国际化 - 覆盖全部 5 种语言 (zh-CN/en-US/ja-JP/ko-KR/zh-Hant)
This commit is contained in:
@@ -280,5 +280,39 @@ export default {
|
||||
home: 'Home',
|
||||
search: 'Search',
|
||||
album: 'Album',
|
||||
localMusic: 'Local Music'
|
||||
localMusic: 'Local Music',
|
||||
pages: {
|
||||
toplist: {
|
||||
desc: 'The most authoritative music charts, discover the hottest music'
|
||||
},
|
||||
mv: {
|
||||
desc: 'Explore amazing video content',
|
||||
loadingMore: 'Loading more...',
|
||||
noMore: '— All content loaded —',
|
||||
area: {
|
||||
all: 'All',
|
||||
mainland: 'Mainland',
|
||||
hktw: 'HK/TW',
|
||||
western: 'Western',
|
||||
japan: 'Japan',
|
||||
korea: 'Korea'
|
||||
}
|
||||
},
|
||||
list: {
|
||||
desc: 'Discover more great playlists',
|
||||
dailyRecommend: 'Daily Picks'
|
||||
},
|
||||
search: {
|
||||
desc: 'Explore the hottest search trends'
|
||||
},
|
||||
album: {
|
||||
area: {
|
||||
all: 'All',
|
||||
chinese: 'Chinese',
|
||||
western: 'Western',
|
||||
korea: 'Korea',
|
||||
japan: 'Japan'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -280,5 +280,39 @@ export default {
|
||||
home: 'ホーム',
|
||||
search: '検索',
|
||||
album: 'アルバム',
|
||||
localMusic: 'ローカル音楽'
|
||||
localMusic: 'ローカル音楽',
|
||||
pages: {
|
||||
toplist: {
|
||||
desc: '最も権威ある音楽チャート、今一番ホットな音楽を発見'
|
||||
},
|
||||
mv: {
|
||||
desc: '素晴らしい動画コンテンツを探索',
|
||||
loadingMore: 'もっと読み込み中...',
|
||||
noMore: '— すべて読み込みました —',
|
||||
area: {
|
||||
all: 'すべて',
|
||||
mainland: '中国大陸',
|
||||
hktw: '香港・台湾',
|
||||
western: '欧米',
|
||||
japan: '日本',
|
||||
korea: '韓国'
|
||||
}
|
||||
},
|
||||
list: {
|
||||
desc: 'もっと素敵なプレイリストを発見',
|
||||
dailyRecommend: 'デイリーおすすめ'
|
||||
},
|
||||
search: {
|
||||
desc: '今最もホットな検索トレンドを探索'
|
||||
},
|
||||
album: {
|
||||
area: {
|
||||
all: 'すべて',
|
||||
chinese: '中華圏',
|
||||
western: '欧米',
|
||||
korea: '韓国',
|
||||
japan: '日本'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -279,5 +279,39 @@ export default {
|
||||
home: '홈',
|
||||
search: '검색',
|
||||
album: '앨범',
|
||||
localMusic: '로컬 음악'
|
||||
localMusic: '로컬 음악',
|
||||
pages: {
|
||||
toplist: {
|
||||
desc: '가장 권위 있는 음악 차트, 지금 가장 핫한 음악을 발견하세요'
|
||||
},
|
||||
mv: {
|
||||
desc: '멋진 영상 콘텐츠 탐색',
|
||||
loadingMore: '더 불러오는 중...',
|
||||
noMore: '— 모든 콘텐츠 로드 완료 —',
|
||||
area: {
|
||||
all: '전체',
|
||||
mainland: '중국 대륙',
|
||||
hktw: '홍콩/대만',
|
||||
western: '서양',
|
||||
japan: '일본',
|
||||
korea: '한국'
|
||||
}
|
||||
},
|
||||
list: {
|
||||
desc: '더 많은 멋진 플레이리스트를 발견하세요',
|
||||
dailyRecommend: '오늘의 추천'
|
||||
},
|
||||
search: {
|
||||
desc: '지금 가장 핫한 검색 트렌드를 탐색하세요'
|
||||
},
|
||||
album: {
|
||||
area: {
|
||||
all: '전체',
|
||||
chinese: '중화권',
|
||||
western: '서양',
|
||||
korea: '한국',
|
||||
japan: '일본'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -272,5 +272,39 @@ export default {
|
||||
home: '首页',
|
||||
search: '搜索',
|
||||
album: '专辑',
|
||||
localMusic: '本地音乐'
|
||||
localMusic: '本地音乐',
|
||||
pages: {
|
||||
toplist: {
|
||||
desc: '最具权威的音乐榜单,发现当下最热门的音乐'
|
||||
},
|
||||
mv: {
|
||||
desc: '探索精彩视频内容',
|
||||
loadingMore: '加载更多中...',
|
||||
noMore: '— 已加载全部内容 —',
|
||||
area: {
|
||||
all: '全部',
|
||||
mainland: '内地',
|
||||
hktw: '港台',
|
||||
western: '欧美',
|
||||
japan: '日本',
|
||||
korea: '韩国'
|
||||
}
|
||||
},
|
||||
list: {
|
||||
desc: '发现更多好听的歌单',
|
||||
dailyRecommend: '每日推荐'
|
||||
},
|
||||
search: {
|
||||
desc: '探索当下最热门的搜索趋势'
|
||||
},
|
||||
album: {
|
||||
area: {
|
||||
all: '全部',
|
||||
chinese: '华语',
|
||||
western: '欧美',
|
||||
korea: '韩国',
|
||||
japan: '日本'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -272,5 +272,39 @@ export default {
|
||||
home: '首頁',
|
||||
search: '搜尋',
|
||||
album: '專輯',
|
||||
localMusic: '本地音樂'
|
||||
localMusic: '本地音樂',
|
||||
pages: {
|
||||
toplist: {
|
||||
desc: '最具權威的音樂榜單,發現當下最熱門的音樂'
|
||||
},
|
||||
mv: {
|
||||
desc: '探索精彩影片內容',
|
||||
loadingMore: '載入更多中...',
|
||||
noMore: '— 已載入全部內容 —',
|
||||
area: {
|
||||
all: '全部',
|
||||
mainland: '內地',
|
||||
hktw: '港台',
|
||||
western: '歐美',
|
||||
japan: '日本',
|
||||
korea: '韓國'
|
||||
}
|
||||
},
|
||||
list: {
|
||||
desc: '發現更多好聽的播放清單',
|
||||
dailyRecommend: '每日推薦'
|
||||
},
|
||||
search: {
|
||||
desc: '探索當下最熱門的搜尋趨勢'
|
||||
},
|
||||
album: {
|
||||
area: {
|
||||
all: '全部',
|
||||
chinese: '華語',
|
||||
western: '歐美',
|
||||
korea: '韓國',
|
||||
japan: '日本'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -133,13 +133,13 @@ const route = useRoute();
|
||||
|
||||
const TOTAL_ITEMS = 30; // 每页数量
|
||||
|
||||
const areas = [
|
||||
{ name: '全部', value: 'ALL' },
|
||||
{ name: '华语', value: 'ZH' },
|
||||
{ name: '欧美', value: 'EA' },
|
||||
{ name: '韩国', value: 'KR' },
|
||||
{ name: '日本', value: 'JP' }
|
||||
];
|
||||
const areas = computed(() => [
|
||||
{ name: t('comp.pages.album.area.all'), value: 'ALL' },
|
||||
{ name: t('comp.pages.album.area.chinese'), value: 'ZH' },
|
||||
{ name: t('comp.pages.album.area.western'), value: 'EA' },
|
||||
{ name: t('comp.pages.album.area.korea'), value: 'KR' },
|
||||
{ name: t('comp.pages.album.area.japan'), value: 'JP' }
|
||||
]);
|
||||
|
||||
const albumList = ref<any[]>([]);
|
||||
const page = ref(0);
|
||||
@@ -149,7 +149,8 @@ const loading = ref(false);
|
||||
|
||||
const currentArea = ref((route.query.area as string) || 'ALL');
|
||||
const currentAreaName = computed(
|
||||
() => areas.find((a) => a.value === currentArea.value)?.name || '全部'
|
||||
() =>
|
||||
areas.value.find((a) => a.value === currentArea.value)?.name || t('comp.pages.album.area.all')
|
||||
);
|
||||
|
||||
const contentScrollbarRef = ref();
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<h1 class="text-2xl md:text-3xl font-bold text-neutral-900 dark:text-white mb-2">
|
||||
{{ listTitle }}
|
||||
</h1>
|
||||
<p class="text-neutral-500 dark:text-neutral-400">发现更多好听的歌单</p>
|
||||
<p class="text-neutral-500 dark:text-neutral-400">{{ t('comp.pages.list.desc') }}</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-6">
|
||||
@@ -96,10 +96,10 @@
|
||||
<!-- 加载更多 -->
|
||||
<div v-if="isLoadingMore" class="flex justify-center items-center py-8">
|
||||
<n-spin size="small" />
|
||||
<span class="ml-2 text-neutral-500">加载中...</span>
|
||||
<span class="ml-2 text-neutral-500">{{ t('common.loading') }}</span>
|
||||
</div>
|
||||
<div v-if="!hasMore && recommendList.length > 0" class="text-center py-8 text-neutral-500">
|
||||
没有更多了
|
||||
{{ t('common.noMore') }}
|
||||
</div>
|
||||
</div>
|
||||
</n-scrollbar>
|
||||
@@ -108,6 +108,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, onDeactivated, onMounted, reactive, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import { getPlaylistCategory } from '@/api/home';
|
||||
@@ -121,6 +122,7 @@ defineOptions({
|
||||
name: 'List'
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
const TOTAL_ITEMS = 42; // 每页数量
|
||||
|
||||
const recommendList = ref<any[]>([]);
|
||||
@@ -142,7 +144,8 @@ const openPlaylist = (item: any) => {
|
||||
};
|
||||
|
||||
const route = useRoute();
|
||||
const listTitle = ref((route.query.type as string) || '每日推荐');
|
||||
const DEFAULT_CAT = '每日推荐';
|
||||
const listTitle = ref((route.query.type as string) || t('comp.pages.list.dailyRecommend'));
|
||||
|
||||
const loading = ref(false);
|
||||
const loadList = async (type: string, isLoadMore = false) => {
|
||||
@@ -159,7 +162,7 @@ const loadList = async (type: string, isLoadMore = false) => {
|
||||
|
||||
try {
|
||||
const params = {
|
||||
cat: type === '每日推荐' ? '' : type,
|
||||
cat: type === DEFAULT_CAT ? '' : type,
|
||||
limit: TOTAL_ITEMS,
|
||||
offset: page.value * TOTAL_ITEMS
|
||||
};
|
||||
@@ -190,7 +193,7 @@ const handleScroll = (e: any) => {
|
||||
|
||||
// 添加歌单分类相关的代码
|
||||
const playlistCategory = ref<IPlayListSort>();
|
||||
const currentType = ref((route.query.type as string) || '每日推荐');
|
||||
const currentType = ref((route.query.type as string) || DEFAULT_CAT);
|
||||
|
||||
const contentScrollbarRef = ref();
|
||||
|
||||
@@ -201,7 +204,7 @@ const loadPlaylistCategory = async () => {
|
||||
...data,
|
||||
sub: [
|
||||
{
|
||||
name: '每日推荐',
|
||||
name: DEFAULT_CAT,
|
||||
category: 0
|
||||
},
|
||||
...data.sub
|
||||
@@ -227,10 +230,10 @@ watch(
|
||||
() => route.query,
|
||||
async (newParams) => {
|
||||
if (route.path !== '/list') return;
|
||||
const newType = (newParams.type as string) || '每日推荐';
|
||||
const newType = (newParams.type as string) || DEFAULT_CAT;
|
||||
// 如果路由参数变化,且与当前类型不同,则重新加载
|
||||
if (newType !== currentType.value) {
|
||||
listTitle.value = newType;
|
||||
listTitle.value = newType === DEFAULT_CAT ? t('comp.pages.list.dailyRecommend') : newType;
|
||||
currentType.value = newType;
|
||||
loading.value = true;
|
||||
loadList(newType);
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
>
|
||||
MV
|
||||
</h1>
|
||||
<p class="text-neutral-500 dark:text-neutral-400">探索精彩视频内容</p>
|
||||
<p class="text-neutral-500 dark:text-neutral-400">{{ t('comp.pages.mv.desc') }}</p>
|
||||
</div>
|
||||
|
||||
<!-- MV Grid Container -->
|
||||
@@ -96,14 +96,14 @@
|
||||
<div v-if="loadingMore" class="flex flex-col items-center gap-4">
|
||||
<n-spin size="small" />
|
||||
<span class="text-xs text-neutral-400 font-medium tracking-widest uppercase">
|
||||
加载更多中...
|
||||
{{ t('comp.pages.mv.loadingMore') }}
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="!hasMore && !initLoading" class="text-center">
|
||||
<span
|
||||
class="text-xs text-neutral-400 font-medium tracking-widest uppercase opacity-50"
|
||||
>
|
||||
— 已加载全部内容 —
|
||||
{{ t('comp.pages.mv.noMore') }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -122,7 +122,8 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import { getAllMv, getTopMv } from '@/api/mv';
|
||||
@@ -137,6 +138,7 @@ defineOptions({
|
||||
name: 'Mv'
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
const showMv = ref(false);
|
||||
const mvList = ref<Array<IMvItem>>([]);
|
||||
const playMvItem = ref<IMvItem>();
|
||||
@@ -147,14 +149,14 @@ const offset = ref(0);
|
||||
const limit = ref(40); // 调整为40,方便4列布局 (10行)
|
||||
const hasMore = ref(true);
|
||||
|
||||
const categories = [
|
||||
{ label: '全部', value: '全部' },
|
||||
{ label: '内地', value: '内地' },
|
||||
{ label: '港台', value: '港台' },
|
||||
{ label: '欧美', value: '欧美' },
|
||||
{ label: '日本', value: '日本' },
|
||||
{ label: '韩国', value: '韩国' }
|
||||
];
|
||||
const categories = computed(() => [
|
||||
{ label: t('comp.pages.mv.area.all'), value: '全部' },
|
||||
{ label: t('comp.pages.mv.area.mainland'), value: '内地' },
|
||||
{ label: t('comp.pages.mv.area.hktw'), value: '港台' },
|
||||
{ label: t('comp.pages.mv.area.western'), value: '欧美' },
|
||||
{ label: t('comp.pages.mv.area.japan'), value: '日本' },
|
||||
{ label: t('comp.pages.mv.area.korea'), value: '韩国' }
|
||||
]);
|
||||
const selectedCategory = ref('全部');
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
>
|
||||
{{ t('search.title.hotSearch') }}
|
||||
</h1>
|
||||
<p class="text-neutral-500 dark:text-neutral-400">探索当下最热门的搜索趋势</p>
|
||||
<p class="text-neutral-500 dark:text-neutral-400">{{ t('comp.pages.search.desc') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
<h1
|
||||
class="text-3xl md:text-4xl font-bold tracking-tight text-neutral-900 dark:text-white mb-2"
|
||||
>
|
||||
排行榜
|
||||
{{ t('comp.toplist') }}
|
||||
</h1>
|
||||
<p class="text-neutral-500 dark:text-neutral-400">
|
||||
最具权威的音乐榜单,发现当下最热门的音乐
|
||||
{{ t('comp.pages.toplist.desc') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { getToplist } from '@/api/list';
|
||||
@@ -104,6 +105,7 @@ defineOptions({
|
||||
name: 'Toplist'
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
const router = useRouter();
|
||||
const topList = ref<any[]>([]);
|
||||
const loading = ref(false);
|
||||
|
||||
Reference in New Issue
Block a user