mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-05 07:28:37 +08:00
feat:发现内容聚合
This commit is contained in:
+32
-377
File diff suppressed because it is too large
Load Diff
@@ -1,90 +0,0 @@
|
|||||||
<script lang="ts" setup>
|
|
||||||
import personIcon from '@images/misc/person-icon.png'
|
|
||||||
import type { BangumiPerson } from '@/api/types'
|
|
||||||
|
|
||||||
const personProps = defineProps({
|
|
||||||
person: Object as PropType<BangumiPerson>,
|
|
||||||
width: String,
|
|
||||||
height: String,
|
|
||||||
})
|
|
||||||
|
|
||||||
// 当前人物
|
|
||||||
const personInfo = ref(personProps.person)
|
|
||||||
|
|
||||||
// 人物图片是否加载
|
|
||||||
const isImageLoaded = ref(false)
|
|
||||||
|
|
||||||
// 人物图片地址
|
|
||||||
function getPersonImage() {
|
|
||||||
if (!personInfo.value?.images) return personIcon
|
|
||||||
return personInfo.value?.images?.medium
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用、拼装人物角色
|
|
||||||
function getPersonCharacter() {
|
|
||||||
if (!personInfo.value?.career) return ''
|
|
||||||
return personInfo.value?.career.join('、')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 打开人物详情
|
|
||||||
function goPersonDetail() {
|
|
||||||
if (!personInfo.value?.id) return
|
|
||||||
window.open(`https://bangumi.tv/person/${personInfo.value?.id}`, '_blank')
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<VHover>
|
|
||||||
<template #default="hover">
|
|
||||||
<VCard
|
|
||||||
v-bind="hover.props"
|
|
||||||
:height="personProps.height"
|
|
||||||
:width="personProps.width"
|
|
||||||
class="rounded-lg"
|
|
||||||
:class="{
|
|
||||||
'transition transform-cpu duration-300 scale-105': hover.isHovering,
|
|
||||||
}"
|
|
||||||
@click.stop="goPersonDetail"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="person-card relative transform-gpu cursor-pointer rounded shadow transition duration-150 ease-in-out scale-100 ring-gray-700"
|
|
||||||
>
|
|
||||||
<div style="padding-block-end: 150%">
|
|
||||||
<div class="absolute inset-0 flex h-full w-full flex-col items-center p-2">
|
|
||||||
<div class="relative mt-2 mb-4 flex h-1/2 w-full justify-center">
|
|
||||||
<VAvatar
|
|
||||||
size="120"
|
|
||||||
:class="{
|
|
||||||
'ring-1 ring-gray-700': isImageLoaded,
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<VImg v-img :src="getPersonImage()" cover @load="isImageLoaded = true" />
|
|
||||||
</VAvatar>
|
|
||||||
</div>
|
|
||||||
<div class="w-full truncate text-center font-bold">
|
|
||||||
{{ personInfo?.name }}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="overflow-hidden whitespace-normal text-center text-sm"
|
|
||||||
style="display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2"
|
|
||||||
>
|
|
||||||
{{ getPersonCharacter() }}
|
|
||||||
</div>
|
|
||||||
<div class="absolute bottom-0 left-0 right-0 h-12 rounded-b" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</VCard>
|
|
||||||
</template>
|
|
||||||
</VHover>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.person-card {
|
|
||||||
background-image: linear-gradient(45deg, rgb(var(--v-theme-background)), rgb(var(--v-theme-surface)) 60%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.person-card:hover {
|
|
||||||
background-image: linear-gradient(45deg, rgb(var(--v-theme-background)), rgb(var(--v-custom-background)) 60%);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
<script lang="ts" setup>
|
|
||||||
import personIcon from '@images/misc/person-icon.png'
|
|
||||||
import type { DoubanPerson } from '@/api/types'
|
|
||||||
|
|
||||||
const personProps = defineProps({
|
|
||||||
person: Object as PropType<DoubanPerson>,
|
|
||||||
width: String,
|
|
||||||
height: String,
|
|
||||||
})
|
|
||||||
|
|
||||||
// 当前人物
|
|
||||||
const personInfo = ref(personProps.person)
|
|
||||||
|
|
||||||
// 人物图片是否加载
|
|
||||||
const isImageLoaded = ref(false)
|
|
||||||
|
|
||||||
// 人物图片地址
|
|
||||||
function getPersonImage() {
|
|
||||||
if (!personInfo.value?.avatar) return personIcon
|
|
||||||
return personInfo.value?.avatar?.large
|
|
||||||
}
|
|
||||||
|
|
||||||
// 打开人物详情
|
|
||||||
function goPersonDetail() {
|
|
||||||
if (!personInfo.value?.id) return
|
|
||||||
window.open(`https://movie.douban.com/celebrity/${personInfo.value?.id}/`, '_blank')
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<VHover>
|
|
||||||
<template #default="hover">
|
|
||||||
<VCard
|
|
||||||
v-bind="hover.props"
|
|
||||||
:height="personProps.height"
|
|
||||||
:width="personProps.width"
|
|
||||||
class="rounded-lg"
|
|
||||||
:class="{
|
|
||||||
'transition transform-cpu duration-300 scale-105': hover.isHovering,
|
|
||||||
}"
|
|
||||||
@click.stop="goPersonDetail"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="person-card relative transform-gpu cursor-pointer rounded shadow transition duration-150 ease-in-out scale-100 ring-gray-700"
|
|
||||||
>
|
|
||||||
<div style="padding-block-end: 150%">
|
|
||||||
<div class="absolute inset-0 flex h-full w-full flex-col items-center p-2">
|
|
||||||
<div class="relative mt-2 mb-4 flex h-1/2 w-full justify-center">
|
|
||||||
<VAvatar
|
|
||||||
size="120"
|
|
||||||
:class="{
|
|
||||||
'ring-1 ring-gray-700': isImageLoaded,
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<VImg v-img :src="getPersonImage()" cover @load="isImageLoaded = true" />
|
|
||||||
</VAvatar>
|
|
||||||
</div>
|
|
||||||
<div class="w-full truncate text-center font-bold">
|
|
||||||
{{ personInfo?.name }}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="overflow-hidden whitespace-normal text-center text-sm"
|
|
||||||
style="display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2"
|
|
||||||
>
|
|
||||||
{{ personInfo?.character }}
|
|
||||||
</div>
|
|
||||||
<div class="absolute bottom-0 left-0 right-0 h-12 rounded-b" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</VCard>
|
|
||||||
</template>
|
|
||||||
</VHover>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.person-card {
|
|
||||||
background-image: linear-gradient(45deg, rgb(var(--v-theme-background)), rgb(var(--v-theme-surface)) 60%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.person-card:hover {
|
|
||||||
background-image: linear-gradient(45deg, rgb(var(--v-theme-background)), rgb(var(--v-custom-background)) 60%);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import personIcon from '@images/misc/person-icon.png'
|
import personIcon from '@images/misc/person-icon.png'
|
||||||
import type { TmdbPerson } from '@/api/types'
|
import type { Person } from '@/api/types'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
|
|
||||||
const personProps = defineProps({
|
const personProps = defineProps({
|
||||||
person: Object as PropType<TmdbPerson>,
|
person: Object as PropType<Person>,
|
||||||
width: String,
|
width: String,
|
||||||
height: String,
|
height: String,
|
||||||
})
|
})
|
||||||
@@ -17,8 +17,37 @@ const isImageLoaded = ref(false)
|
|||||||
|
|
||||||
// 人物图片地址
|
// 人物图片地址
|
||||||
function getPersonImage() {
|
function getPersonImage() {
|
||||||
if (!personInfo.value?.profile_path) return personIcon
|
if (personProps.person?.source === 'themoviedb') {
|
||||||
return `https://image.tmdb.org/t/p/w600_and_h900_bestv2${personInfo.value?.profile_path}`
|
if (!personInfo.value?.profile_path) return personIcon
|
||||||
|
return `https://image.tmdb.org/t/p/w600_and_h900_bestv2${personInfo.value?.profile_path}`
|
||||||
|
} else if (personProps.person?.source === 'douban') {
|
||||||
|
if (!personInfo.value?.avatar) return personIcon
|
||||||
|
if (typeof personInfo.value?.avatar === 'object') {
|
||||||
|
return personInfo.value?.avatar?.normal
|
||||||
|
} else {
|
||||||
|
return personInfo.value?.avatar
|
||||||
|
}
|
||||||
|
} else if (personProps.person?.source === 'bangumi') {
|
||||||
|
if (!personInfo.value?.images) return personIcon
|
||||||
|
return personInfo.value?.images?.medium
|
||||||
|
} else {
|
||||||
|
return personIcon
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 人物姓名
|
||||||
|
function getPersonName() {
|
||||||
|
return personInfo.value?.name
|
||||||
|
}
|
||||||
|
|
||||||
|
// 人物角色
|
||||||
|
function getPersonCharacter() {
|
||||||
|
if (personProps.person?.source === 'bangumi') {
|
||||||
|
if (!personInfo.value?.career) return ''
|
||||||
|
return personInfo.value?.career.join('、')
|
||||||
|
} else {
|
||||||
|
return personInfo.value?.character
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 人物详情
|
// 人物详情
|
||||||
@@ -28,6 +57,7 @@ function goPersonDetail() {
|
|||||||
path: '/person',
|
path: '/person',
|
||||||
query: {
|
query: {
|
||||||
personid: personInfo.value?.id,
|
personid: personInfo.value?.id,
|
||||||
|
source: personInfo.value?.source,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -62,13 +92,13 @@ function goPersonDetail() {
|
|||||||
</VAvatar>
|
</VAvatar>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full truncate text-center font-bold">
|
<div class="w-full truncate text-center font-bold">
|
||||||
{{ personInfo?.name }}
|
{{ getPersonName() }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="overflow-hidden whitespace-normal text-center text-sm"
|
class="overflow-hidden whitespace-normal text-center text-sm"
|
||||||
style="display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2"
|
style="display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2"
|
||||||
>
|
>
|
||||||
{{ personInfo?.character }}
|
{{ getPersonCharacter() }}
|
||||||
</div>
|
</div>
|
||||||
<div class="absolute bottom-0 left-0 right-0 h-12 rounded-b" />
|
<div class="absolute bottom-0 left-0 right-0 h-12 rounded-b" />
|
||||||
</div>
|
</div>
|
||||||
+1
-30
@@ -19,35 +19,11 @@ let title = route.query?.title?.toString()
|
|||||||
const type = route.query?.type?.toString()
|
const type = route.query?.type?.toString()
|
||||||
if (type === 'person') title = '演员:' + title
|
if (type === 'person') title = '演员:' + title
|
||||||
|
|
||||||
// 识别类型
|
|
||||||
const RecognizeType = ref('themoviedb')
|
|
||||||
|
|
||||||
// 计算人物类型
|
|
||||||
const PersonType = computed(() => {
|
|
||||||
if (RecognizeType.value === 'douban') return 'douban'
|
|
||||||
else if (RecognizeType.value === 'bangumi') return 'bangumi'
|
|
||||||
else return 'tmdb'
|
|
||||||
})
|
|
||||||
|
|
||||||
// 计算API路径
|
// 计算API路径
|
||||||
function getApiPath(paths: string[] | string) {
|
function getApiPath(paths: string[] | string) {
|
||||||
if (Array.isArray(paths)) return paths.join('/')
|
if (Array.isArray(paths)) return paths.join('/')
|
||||||
else return paths
|
else return paths
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载系统设计
|
|
||||||
async function loadSystemSettings() {
|
|
||||||
try {
|
|
||||||
const result: { [key: string]: any } = await api.get('system/env')
|
|
||||||
if (result.success) RecognizeType.value = result.data?.RECOGNIZE_SOURCE
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
if (type === 'person') await loadSystemSettings()
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -62,12 +38,7 @@ onMounted(async () => {
|
|||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<PersonCardListView
|
<PersonCardListView v-if="type === 'person'" :apipath="getApiPath(props.paths || '')" :params="route.query" />
|
||||||
v-if="type === 'person'"
|
|
||||||
:apipath="getApiPath(props.paths || '')"
|
|
||||||
:type="PersonType"
|
|
||||||
:params="route.query"
|
|
||||||
/>
|
|
||||||
<MediaCardListView v-else :apipath="getApiPath(props.paths || '')" :params="route.query" />
|
<MediaCardListView v-else :apipath="getApiPath(props.paths || '')" :params="route.query" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -7,15 +7,15 @@ const route = useRoute()
|
|||||||
// Person Id
|
// Person Id
|
||||||
const personid = route.query?.personid?.toString()
|
const personid = route.query?.personid?.toString()
|
||||||
|
|
||||||
|
// 来源
|
||||||
|
const source = route.query?.source?.toString()
|
||||||
|
|
||||||
// 类型
|
// 类型
|
||||||
const type = route.query?.type?.toString()
|
const type = route.query?.type?.toString()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<PersonDetailView
|
<PersonDetailView :personid="personid" :type="type" :source="source" />
|
||||||
:personid="personid"
|
|
||||||
:type="type"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import DoubanPersonCard from '@/components/cards/DoubanPersonCard.vue'
|
import PersonCard from '@/components/cards/PersonCard.vue'
|
||||||
import TmdbPersonCard from '@/components/cards/TmdbPersonCard.vue'
|
|
||||||
import BangumiPersonCard from '@/components/cards/BangumiPersonCard.vue'
|
|
||||||
import NoDataFound from '@/components/NoDataFound.vue'
|
import NoDataFound from '@/components/NoDataFound.vue'
|
||||||
|
|
||||||
// 输入参数
|
// 输入参数
|
||||||
@@ -115,14 +113,8 @@ async function fetchData({ done }: { done: any }) {
|
|||||||
<VInfiniteScroll mode="intersect" side="end" :items="dataList" class="overflow-hidden" @load="fetchData">
|
<VInfiniteScroll mode="intersect" side="end" :items="dataList" class="overflow-hidden" @load="fetchData">
|
||||||
<template #loading />
|
<template #loading />
|
||||||
<template #empty />
|
<template #empty />
|
||||||
<div v-if="dataList.length > 0 && props.type === 'tmdb'" class="grid gap-4 grid-media-card mx-3" tabindex="0">
|
<div v-if="dataList.length > 0" class="grid gap-4 grid-media-card mx-3" tabindex="0">
|
||||||
<TmdbPersonCard v-for="data in dataList" :key="data.id" :person="data" />
|
<PersonCard v-for="data in dataList" :key="data.id" :person="data" />
|
||||||
</div>
|
|
||||||
<div v-if="dataList.length > 0 && props.type === 'douban'" class="grid gap-4 grid-media-card mx-3" tabindex="0">
|
|
||||||
<DoubanPersonCard v-for="data in dataList" :key="data.id" :person="data" />
|
|
||||||
</div>
|
|
||||||
<div v-if="dataList.length > 0 && props.type === 'bangumi'" class="grid gap-4 grid-media-card mx-3" tabindex="0">
|
|
||||||
<BangumiPersonCard v-for="data in dataList" :key="data.id" :person="data" />
|
|
||||||
</div>
|
</div>
|
||||||
<NoDataFound
|
<NoDataFound
|
||||||
v-if="dataList.length === 0 && isRefreshed"
|
v-if="dataList.length === 0 && isRefreshed"
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import TmdbPersonCard from '@/components/cards/TmdbPersonCard.vue'
|
import PersonCard from '@/components/cards/PersonCard.vue'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import SlideView from '@/components/slide/SlideView.vue'
|
import SlideView from '@/components/slide/SlideView.vue'
|
||||||
import DoubanPersonCard from '@/components/cards/DoubanPersonCard.vue'
|
|
||||||
import BangumiPersonCard from '@/components/cards/BangumiPersonCard.vue'
|
|
||||||
|
|
||||||
// 输入参数
|
// 输入参数
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -13,7 +11,7 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
})
|
})
|
||||||
|
|
||||||
provide('rankingPropsKey', reactive({...props}))
|
provide('rankingPropsKey', reactive({ ...props }))
|
||||||
|
|
||||||
// 组件加载完成
|
// 组件加载完成
|
||||||
const componentLoaded = ref(false)
|
const componentLoaded = ref(false)
|
||||||
@@ -24,14 +22,11 @@ const dataList = ref<any>([])
|
|||||||
// 获取订阅列表数据
|
// 获取订阅列表数据
|
||||||
async function fetchData() {
|
async function fetchData() {
|
||||||
try {
|
try {
|
||||||
if (!props.apipath)
|
if (!props.apipath) return
|
||||||
return
|
|
||||||
|
|
||||||
dataList.value = await api.get(props.apipath)
|
dataList.value = await api.get(props.apipath)
|
||||||
if (dataList.value.length > 0)
|
if (dataList.value.length > 0) componentLoaded.value = true
|
||||||
componentLoaded.value = true
|
} catch (error) {
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -41,32 +36,10 @@ onMounted(fetchData)
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<SlideView
|
<SlideView v-if="componentLoaded">
|
||||||
v-if="componentLoaded"
|
|
||||||
>
|
|
||||||
<template #content>
|
<template #content>
|
||||||
<template
|
<template v-for="data in dataList" :key="data.id">
|
||||||
v-for="data in dataList"
|
<PersonCard :person="data" height="15rem" width="10rem" />
|
||||||
:key="data.id"
|
|
||||||
>
|
|
||||||
<TmdbPersonCard
|
|
||||||
v-if="props.type === 'tmdb'"
|
|
||||||
:person="data"
|
|
||||||
height="15rem"
|
|
||||||
width="10rem"
|
|
||||||
/>
|
|
||||||
<DoubanPersonCard
|
|
||||||
v-if="props.type === 'douban'"
|
|
||||||
:person="data"
|
|
||||||
height="15rem"
|
|
||||||
width="10rem"
|
|
||||||
/>
|
|
||||||
<BangumiPersonCard
|
|
||||||
v-if="props.type === 'bangumi'"
|
|
||||||
:person="data"
|
|
||||||
height="15rem"
|
|
||||||
width="10rem"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</SlideView>
|
</SlideView>
|
||||||
|
|||||||
@@ -2,17 +2,18 @@
|
|||||||
import MediaCardListView from './MediaCardListView.vue'
|
import MediaCardListView from './MediaCardListView.vue'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import personIcon from '@images/misc/person.png'
|
import personIcon from '@images/misc/person.png'
|
||||||
import type { TmdbPerson } from '@/api/types'
|
import type { Person } from '@/api/types'
|
||||||
import NoDataFound from '@/components/NoDataFound.vue'
|
import NoDataFound from '@/components/NoDataFound.vue'
|
||||||
|
|
||||||
// 输入参数
|
// 输入参数
|
||||||
const personProps = defineProps({
|
const personProps = defineProps({
|
||||||
personid: String,
|
personid: String,
|
||||||
type: String,
|
type: String,
|
||||||
|
source: String,
|
||||||
})
|
})
|
||||||
|
|
||||||
// 媒体详情
|
// 媒体详情
|
||||||
const personDetail = ref<TmdbPerson>({} as TmdbPerson)
|
const personDetail = ref<Person>({} as Person)
|
||||||
|
|
||||||
// 是否已加载完成
|
// 是否已加载完成
|
||||||
const isRefreshed = ref(false)
|
const isRefreshed = ref(false)
|
||||||
@@ -23,21 +24,67 @@ const isImageLoaded = ref(false)
|
|||||||
// 调用API查询详情
|
// 调用API查询详情
|
||||||
async function getPersonDetail() {
|
async function getPersonDetail() {
|
||||||
if (personProps.personid) {
|
if (personProps.personid) {
|
||||||
personDetail.value = await api.get(`tmdb/person/${personProps.personid}`)
|
if (personProps.source === 'themoviedb') {
|
||||||
|
personDetail.value = await api.get(`tmdb/person/${personProps.personid}`)
|
||||||
|
} else if (personProps.source === 'douban') {
|
||||||
|
personDetail.value = await api.get(`douban/person/${personProps.personid}`)
|
||||||
|
} else if (personProps.source === 'bangumi') {
|
||||||
|
personDetail.value = await api.get(`bangumi/person/${personProps.personid}`)
|
||||||
|
}
|
||||||
isRefreshed.value = true
|
isRefreshed.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 人物图片地址
|
// 人物图片地址
|
||||||
function getPersonImage() {
|
function getPersonImage() {
|
||||||
if (!personDetail.value?.profile_path) return personIcon
|
if (personProps.source === 'themoviedb') {
|
||||||
return `https://image.tmdb.org/t/p/w600_and_h900_bestv2${personDetail.value?.profile_path}`
|
if (!personDetail.value?.profile_path) return personIcon
|
||||||
|
return `https://image.tmdb.org/t/p/w600_and_h900_bestv2${personDetail.value?.profile_path}`
|
||||||
|
} else if (personProps.source === 'douban') {
|
||||||
|
if (!personDetail.value?.avatar) return personIcon
|
||||||
|
if (typeof personDetail.value?.avatar === 'object') {
|
||||||
|
return personDetail.value?.avatar?.normal
|
||||||
|
} else {
|
||||||
|
return personDetail.value?.avatar
|
||||||
|
}
|
||||||
|
} else if (personProps.source === 'bangumi') {
|
||||||
|
if (!personDetail.value?.images) return personIcon
|
||||||
|
return personDetail.value?.images?.medium
|
||||||
|
} else {
|
||||||
|
return personIcon
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将别名数组拆分为、分隔的字符串
|
// 将别名数组拆分为、分隔的字符串
|
||||||
function getAlsoKnownAs() {
|
function getAlsoKnownAs() {
|
||||||
if (!personDetail.value?.also_known_as) return ''
|
if (!personDetail.value?.also_known_as) return ''
|
||||||
return personDetail.value.also_known_as.join('、')
|
if (personProps.source === 'themoviedb') {
|
||||||
|
return '别名:' + personDetail.value.also_known_as.join('、')
|
||||||
|
} else {
|
||||||
|
return personDetail.value.also_known_as.join(',')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 参演作品路由地址
|
||||||
|
function getPersonCreditsPath() {
|
||||||
|
let apipath = 'tmdb'
|
||||||
|
if (personProps.source === 'douban') {
|
||||||
|
apipath = 'douban'
|
||||||
|
} else if (personProps.source === 'bangumi') {
|
||||||
|
apipath = 'bangumi'
|
||||||
|
}
|
||||||
|
return `/browse/${apipath}/person/credits/${personDetail.value.id}?title=参演作品`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 参演作品API路径
|
||||||
|
function getPersonCreditsApiPath() {
|
||||||
|
let apipath = 'tmdb'
|
||||||
|
if (personProps.source === 'douban') {
|
||||||
|
apipath = 'douban'
|
||||||
|
} else if (personProps.source === 'bangumi') {
|
||||||
|
apipath = 'bangumi'
|
||||||
|
}
|
||||||
|
return `${apipath}/person/credits/${personDetail.value.id}`
|
||||||
}
|
}
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
@@ -67,7 +114,7 @@ onBeforeMount(() => {
|
|||||||
<span v-if="personDetail.place_of_birth"> | </span>
|
<span v-if="personDetail.place_of_birth"> | </span>
|
||||||
<span v-if="personDetail.place_of_birth">{{ personDetail.place_of_birth }}</span>
|
<span v-if="personDetail.place_of_birth">{{ personDetail.place_of_birth }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="personDetail.also_known_as">别名:{{ getAlsoKnownAs() }}</div>
|
<div v-if="personDetail.also_known_as">{{ getAlsoKnownAs() }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -80,12 +127,12 @@ onBeforeMount(() => {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="slider-header">
|
<div class="slider-header">
|
||||||
<RouterLink :to="`/browse/tmdb/person/credits/${personDetail.id}?title=参演作品`" class="slider-title">
|
<RouterLink :to="getPersonCreditsPath()" class="slider-title">
|
||||||
<span>参演作品</span>
|
<span>参演作品</span>
|
||||||
<VIcon icon="mdi-arrow-right-circle-outline" class="ms-1" />
|
<VIcon icon="mdi-arrow-right-circle-outline" class="ms-1" />
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</div>
|
</div>
|
||||||
<MediaCardListView :apipath="`tmdb/person/credits/${personDetail.id}`" />
|
<MediaCardListView :apipath="getPersonCreditsApiPath()" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<NoDataFound
|
<NoDataFound
|
||||||
|
|||||||
Reference in New Issue
Block a user