mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-05-16 09:17:38 +08:00
need fix
This commit is contained in:
@@ -182,7 +182,7 @@ export interface MediaInfo {
|
||||
poster_path?: string
|
||||
|
||||
// 评分
|
||||
vote_average: number
|
||||
vote_average?: number
|
||||
|
||||
// 描述
|
||||
overview?: string
|
||||
|
||||
@@ -271,21 +271,10 @@ async function checkSeasonsNotExists() {
|
||||
doneNProgress()
|
||||
}
|
||||
|
||||
// 检查电影是否存在
|
||||
async function checkMovieExists() {
|
||||
try {
|
||||
const result: NotExistMediaInfo[] = await api.post('download/notexists', props.media)
|
||||
return !result || result.length === 0
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
// 查询TMDB的所有季信息
|
||||
async function getMediaSeasons() {
|
||||
try {
|
||||
seasonInfos.value = await api.get(`tmdb/${props.media?.tmdb_id}/seasons`)
|
||||
seasonInfos.value = await api.get(`tmdb/seasons/${props.media?.tmdb_id}`)
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error)
|
||||
@@ -343,7 +332,17 @@ function getExistText(season: number) {
|
||||
|
||||
// 打开详情页
|
||||
function openDetailWindow() {
|
||||
window.open(getDetailLink(), '_blank')
|
||||
router.push({
|
||||
path: '/media',
|
||||
query: {
|
||||
mediaid: `${
|
||||
props.media?.tmdb_id
|
||||
? `tmdb:${props.media?.tmdb_id}`
|
||||
: `douban:${props.media?.douban_id}`
|
||||
}`,
|
||||
type: props.media?.type,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 开始搜索
|
||||
|
||||
@@ -222,7 +222,7 @@ const dropdownItems = ref([
|
||||
<VCard
|
||||
v-if="cardState"
|
||||
:key="props.media?.id"
|
||||
:class="`${subscribeForm.best_version ? 'outline-dotted' : ''}`"
|
||||
:class="`${subscribeForm.best_version ? 'outline-dashed outline-1' : ''}`"
|
||||
@click="editSubscribeDialog"
|
||||
>
|
||||
<template #image>
|
||||
|
||||
21
src/pages/media.vue
Normal file
21
src/pages/media.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import MediaDetailView from '@/views/discover/MediaDetailView.vue'
|
||||
|
||||
// 路由参数
|
||||
const route = useRoute()
|
||||
|
||||
// TMDBID
|
||||
const mediaid = route.query?.mediaid?.toString()
|
||||
|
||||
// 类型
|
||||
const type = route.query?.type?.toString()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<MediaDetailView
|
||||
:mediaid="mediaid"
|
||||
:type="type"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -98,6 +98,13 @@ const router = createRouter({
|
||||
requiresAuth: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/media',
|
||||
component: () => import('../pages/media.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
296
src/views/discover/MediaDetailView.vue
Normal file
296
src/views/discover/MediaDetailView.vue
Normal file
@@ -0,0 +1,296 @@
|
||||
<script setup lang="ts">
|
||||
import MediaCardSlideView from './MediaCardSlideView.vue'
|
||||
import api from '@/api'
|
||||
import type { MediaInfo } from '@/api/types'
|
||||
|
||||
// 输入参数
|
||||
const mediaProps = defineProps({
|
||||
mediaid: String,
|
||||
type: String,
|
||||
})
|
||||
|
||||
// 媒体详情
|
||||
const mediaDetail = ref<MediaInfo>({} as MediaInfo)
|
||||
|
||||
// 调用API查询详情
|
||||
async function getMediaDetail() {
|
||||
if (mediaProps.mediaid && mediaProps.type) {
|
||||
const result: MediaInfo = await api.get(`tmdb/${mediaProps.mediaid}`, {
|
||||
params: {
|
||||
type_name: mediaProps.type,
|
||||
},
|
||||
})
|
||||
mediaDetail.value = result
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getMediaDetail()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="max-w-8xl mx-auto px-4">
|
||||
<div class="media-page">
|
||||
<div class="media-page-bg-image">
|
||||
<VImg cover :src="mediaDetail.backdrop_path" class="absolute inset-0 w-full h-full object-cover object-center" />
|
||||
<div
|
||||
class="absolute inset-0"
|
||||
style="background-image: linear-gradient(180deg, rgba(17, 24, 39, 47%) 0%, rgba(17, 24, 39, 100%) 100%);"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="media-header">
|
||||
<div class="media-poster">
|
||||
<VImg :src="mediaDetail.poster_path" cover />
|
||||
</div>
|
||||
<div class="media-title">
|
||||
<div class="media-status" />
|
||||
<h1 class="media-title">
|
||||
{{ mediaDetail.title }}
|
||||
<span class="media-year">
|
||||
({{ mediaDetail.year }})
|
||||
</span>
|
||||
</h1>
|
||||
<span class="media-attributes">
|
||||
<span>分级</span>
|
||||
<span>时长</span>
|
||||
<span>风格</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="media-actions" />
|
||||
</div>
|
||||
<div class="media-overview">
|
||||
<div class="media-overview-left">
|
||||
<div class="tagline">
|
||||
标签
|
||||
</div>
|
||||
<h2>简介</h2>
|
||||
<p>{{ mediaDetail.overview }}</p>
|
||||
</div>
|
||||
<div class="media-overview-right" />
|
||||
</div>
|
||||
<div v-if="mediaDetail.tmdb_id">
|
||||
<MediaCardSlideView :apipath="`tmdb/credits/${mediaDetail.tmdb_id}/${mediaProps.type}`">
|
||||
<template #title="{ loaded }">
|
||||
<div v-if="loaded" class="slider-header mt-3 ms-1">
|
||||
<RouterLink to="" class="slider-title">
|
||||
<span>演员阵容</span>
|
||||
<VIcon icon="mdi-arrow-right-circle-outline" class="ms-1" />
|
||||
</RouterLink>
|
||||
</div>
|
||||
</template>
|
||||
</MediaCardSlideView>
|
||||
</div>
|
||||
<div v-if="mediaDetail.tmdb_id">
|
||||
<MediaCardSlideView :apipath="`tmdb/recommend/${mediaDetail.tmdb_id}/${mediaProps.type}`">
|
||||
<template #title="{ loaded }">
|
||||
<div v-if="loaded" class="slider-header mt-3 ms-1">
|
||||
<RouterLink to="" class="slider-title">
|
||||
<span>推荐</span>
|
||||
<VIcon icon="mdi-arrow-right-circle-outline" class="ms-1" />
|
||||
</RouterLink>
|
||||
</div>
|
||||
</template>
|
||||
</MediaCardSlideView>
|
||||
</div>
|
||||
<div v-if="mediaDetail.tmdb_id">
|
||||
<MediaCardSlideView :apipath="`tmdb/similar/${mediaDetail.tmdb_id}/${mediaProps.type}`">
|
||||
<template #title="{ loaded }">
|
||||
<div v-if="loaded" class="slider-header mt-3 ms-1">
|
||||
<RouterLink to="" class="slider-title">
|
||||
<span>类似</span>
|
||||
<VIcon icon="mdi-arrow-right-circle-outline" class="ms-1" />
|
||||
</RouterLink>
|
||||
</div>
|
||||
</template>
|
||||
</MediaCardSlideView>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.media-page {
|
||||
position: relative;
|
||||
background-position: 50%;
|
||||
background-size: cover;
|
||||
margin-block-start: calc(-4rem - env(safe-area-inset-top));
|
||||
margin-inline: -1rem;
|
||||
padding-block-start: calc(4rem + env(safe-area-inset-top));
|
||||
padding-inline: 1rem;
|
||||
}
|
||||
|
||||
.media-page-bg-image {
|
||||
position: absolute;
|
||||
z-index: -10;
|
||||
block-size: 100%;
|
||||
inline-size: 100%;
|
||||
inset: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.media-header {
|
||||
flex-direction: row;
|
||||
align-items: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
.media-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding-block-start: 1rem;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.media-overview {
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.media-poster {
|
||||
margin-right: 1rem;
|
||||
width: 13rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.media-poster {
|
||||
width: 11rem;
|
||||
border-radius: .5rem;
|
||||
--tw-shadow: 0 25px 50px -12px rgba(0, 0, 0, .25);
|
||||
--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||
}
|
||||
}
|
||||
|
||||
.media-poster {
|
||||
width: 8rem;
|
||||
overflow: hidden;
|
||||
border-radius: .25rem;
|
||||
--tw-shadow: 0 1px 3px 0 rgba(0, 0, 0, .1), 0 1px 2px -1px rgba(0, 0, 0, .1);
|
||||
--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.media-title {
|
||||
margin-right: 1rem;
|
||||
margin-top: 0;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.media-title {
|
||||
margin-top: 1rem;
|
||||
display: flex;
|
||||
flex: 1 1 0%;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(255 255 255/var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
ul.media-crew {
|
||||
grid-template-columns: repeat(3,minmax(0,1fr));
|
||||
}
|
||||
}
|
||||
|
||||
ul.media-crew {
|
||||
margin-top: 1.5rem;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2,minmax(0,1fr));
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.media-status {
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.media-attributes {
|
||||
margin-top: 0;
|
||||
justify-content: flex-start;
|
||||
font-size: 1rem;
|
||||
line-height: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.media-attributes {
|
||||
font-size: .875rem;
|
||||
line-height: 1.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
.media-attributes {
|
||||
font-size: .75rem;
|
||||
line-height: 1rem;
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(209 213 219/var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.media-attributes {
|
||||
margin-top: .25rem;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.media-actions {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.media-actions {
|
||||
flex-wrap: nowrap;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
.media-actions {
|
||||
position: relative;
|
||||
margin-top: 1rem;
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.media-overview {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-top: 2rem;
|
||||
padding-bottom: 1rem;
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(255 255 255/var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.media-overview-left {
|
||||
margin-right: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.media-overview-left {
|
||||
flex: 1 1 0%;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.media-overview-right {
|
||||
margin-top: 0;
|
||||
width: 20rem;
|
||||
}
|
||||
}
|
||||
|
||||
.media-overview-right {
|
||||
margin-top: 2rem;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user