diff --git a/app/pages/phim/[slug].vue b/app/pages/phim/[slug].vue index a8994cf..c682aad 100644 --- a/app/pages/phim/[slug].vue +++ b/app/pages/phim/[slug].vue @@ -2,21 +2,31 @@ import { ChevronDown, Heart, Play, Plus, Share2, Star } from 'lucide-vue-next' const route = useRoute() +const requestedSource = computed(() => String(route.query.source || 'ophim')) const selectedServer = ref(0) const movieInfoOpen = ref(false) +const activeTab = ref<'episodes' | 'actors'>('episodes') +const sourceOptions = [ + { label: 'OPhim', value: 'ophim' }, + { label: 'NguonC', value: 'nguonc' }, +] -const { data: movie, pending, error } = await useFetch(`/api/movies/${route.params.slug}`, { - query: { - source: route.query.source, - }, +const { data: movie, pending, error } = await useFetch(() => `/api/movies/${route.params.slug}`, { + query: computed(() => ({ + source: requestedSource.value, + })), + watch: [requestedSource], }) const servers = computed(() => movie.value?.servers ?? []) const activeServer = computed(() => servers.value[selectedServer.value]) +const activeSource = computed(() => String(movie.value?.source || route.query.source || 'ophim')) +const actors = computed(() => movie.value?.actors ?? []) +const actorSummary = computed(() => actors.value.map((actor: any) => actor.name).filter(Boolean).slice(0, 6).join(', ')) const firstWatchLink = computed(() => ({ path: `/xem/${route.params.slug}`, query: { - source: route.query.source, + source: activeSource.value, server: selectedServer.value, ep: 1, }, @@ -27,13 +37,33 @@ function episodeLink(index: number) { return { path: `/xem/${route.params.slug}`, query: { - source: route.query.source, + source: activeSource.value, server: selectedServer.value, ep: index + 1, }, } } +function sourceLink(source: string) { + return { + path: `/phim/${route.params.slug}`, + query: { source }, + } +} + +function formatEpisodeName(name: string, index: number) { + const label = String(name || index + 1).trim() + return /^\d+$/.test(label) ? `Tập ${label}` : label +} + +function actorInitial(name: string) { + return name.trim().charAt(0).toUpperCase() +} + +watch(requestedSource, () => { + selectedServer.value = 0 +}) + useHead(() => ({ title: movie.value ? `${movie.value.name} - KR Phim` : 'Đang tải phim - KR Phim', meta: [ @@ -70,7 +100,7 @@ useHead(() => ({
-Quốc gia: {{ movie.countries.join(', ') }}
-Diễn viên: {{ - movie.actors.slice(0, 6).join(', ') }}
+Diễn viên: {{ + actorSummary }}
+Nguồn API
+{{ actor.name }}
++ {{ actor.originalName || 'Tên quốc tế đang cập nhật' }} +
++ {{ actor.role || 'Vai diễn đang cập nhật' }} +
++ Nguồn này chưa có dữ liệu diễn viên. +
+Quốc gia: {{ movie.countries.join(', ') }}
Năm: {{ movie.year }}
-Diễn viên: {{ - movie.actors.slice(0, 6).join(', ') }}
+Diễn viên: {{ + actorSummary }}
diff --git a/server/utils/movies.ts b/server/utils/movies.ts index 7231069..986b141 100644 --- a/server/utils/movies.ts +++ b/server/utils/movies.ts @@ -31,9 +31,16 @@ export interface NormalizedServer { episodes: NormalizedEpisode[] } +export interface NormalizedActor { + name: string + originalName?: string + role?: string + avatar?: string +} + export interface MovieDetail extends NormalizedMovie { content: string - actors: string[] + actors: NormalizedActor[] directors: string[] trailer?: string servers: NormalizedServer[] @@ -97,6 +104,23 @@ function stripHtml(value?: string) { .trim() } +function normalizeActor(actor: any): NormalizedActor | undefined { + if (typeof actor === 'string') { + const name = actor.trim() + return name ? { name } : undefined + } + + const name = text(actor?.name || actor?.actor_name || actor?.title).trim() + if (!name) return undefined + + return { + name, + originalName: text(actor?.original_name || actor?.origin_name || actor?.real_name) || undefined, + role: text(actor?.role || actor?.character || actor?.as || actor?.cast_name) || undefined, + avatar: joinImage('', actor?.avatar || actor?.image || actor?.thumb_url || actor?.poster_url) || undefined, + } +} + export function normalizeOphimMovie(movie: any, pathImage = OPHIM_IMAGE): NormalizedMovie { return { id: `ophim:${movie?._id ?? movie?.slug}`, @@ -239,7 +263,7 @@ export async function getOphimDetail(slug: string): Promise