This commit is contained in:
jxxghp
2023-06-29 19:29:01 +08:00
parent aa00106cfe
commit 76cd494bdf
6 changed files with 125 additions and 106 deletions

View File

@@ -10,9 +10,9 @@ const getChipColor = (type: string) => {
if (type === "电影") {
return "border-blue-500 bg-blue-600";
} else if (type === "电视剧") {
return "border-purple-600 bg-purple-600";
return " bg-green-500 border-green-600";
} else {
return "gray";
return "border-purple-600 bg-purple-600";
}
};
@@ -43,7 +43,8 @@ const getChipColor = (type: string) => {
<VChip
variant="elevated"
size="small"
class="absolute right-2 top-2 bg-opacity-80 shadow-md bg-green-500 border-green-600 text-white font-bold">
:class="getChipColor(props.media?.type||'')"
class="absolute right-2 top-2 bg-opacity-80 shadow-md text-white font-bold">
{{ props.media?.vote_average }}
</VChip>
<VCardText

View File

@@ -0,0 +1,93 @@
<script lang="ts" setup>
import { Subscribe } from "@/api/types";
import { formatSeason } from "@core/utils/formatters";
// 输入参数
const props = defineProps({
media: Object as PropType<Subscribe>
});
// 根据 type 返回不同的图标
const getIcon = (type: string) => {
if (type === "电影") {
return "mdi-movie";
} else if (type === "电视剧") {
return "mdi-television-classic";
} else {
return "mdi-help-circle";
}
};
// 计算百分比
const getPercentage = (total: number, lack: number) => {
if (total === 0) {
return 0;
}
return Math.round(((total - lack) / total) * 100);
};
</script>
<template>
<VCard
:key="props.media?.id"
:image="props.media?.backdrop || props.media?.poster"
class="card-with-overlay">
<VCardItem>
<template #prepend>
<VIcon
size="1.9rem"
color="white"
:icon="getIcon(props.media?.type||'')"
/>
</template>
<VCardTitle class="text-white">
{{ props.media?.name }} {{ formatSeason(props.media?.season ? props.media?.season.toString() : "") }}
</VCardTitle>
<template #append>
<div class="me-n3">
<MoreBtn color="white"/>
</div>
</template>
</VCardItem>
<VCardText>
<p class="clamp-text text-white mb-0">
{{ props.media?.description }}
</p>
</VCardText>
<VCardText
class="d-flex justify-space-between align-center flex-wrap"
>
<div class="d-flex align-center">
<IconBtn icon="mdi-star" color="white" class="me-1" />
<span class="text-subtitle-2 text-white me-4">{{ props.media?.vote }}</span>
<IconBtn
icon="mdi-progress-clock"
color="white"
class="me-1"
v-if="props.media?.total_episode"
/>
<span class="text-subtitle-2 text-white" v-if="props.media?.season"
>{{ (props.media?.total_episode || 0) - (props.media?.lack_episode || 0) }} /
{{ props.media?.total_episode }}</span
>
</div>
</VCardText>
<VProgressLinear
v-if="props.media?.total_episode || 0 > 0"
:model-value="getPercentage(props.media?.total_episode || 0, props.media?.lack_episode || 0)"
bg-color="success"
color="success"
/>
</VCard>
</template>
<style lang="scss">
.card-with-overlay img{
@apply brightness-50;
}
</style>

15
src/pages/browse.vue Normal file
View File

@@ -0,0 +1,15 @@
<script setup lang="ts">
import MediaCardListView from '@/views/discover/MediaCardListView.vue';
// 输入参数
const props = defineProps({
type: String,
});
</script>
<template>
<div>
<MediaCardListView :apipath="props.type"/>
</div>
</template>

View File

@@ -1,16 +1,9 @@
<script setup lang="ts">
import MediaCardListView from '@/views/discover/MediaCardListView.vue';
import MediaCardSlideView from '@/views/discover/MediaCardSlideView.vue';
</script>
<template>
<div>
<p class="text-2xl font-weight-medium my-5">
TMDB电影
</p>
<MediaCardListView apipath="/tmdb/movies"/>
<p class="text-2xl font-weight-medium my-5">
TMDB流行趋势
</p>

View File

@@ -86,6 +86,14 @@ const router = createRouter({
requiresAuth: true,
},
},
{
path: 'browse/:type',
component: () => import('../pages/browse.vue'),
props: true,
meta: {
requiresAuth: true,
},
},
],
},
{

View File

@@ -1,7 +1,7 @@
<script lang="ts" setup>
import api from "@/api";
import type { Subscribe } from "@/api/types";
import { formatSeason } from "@core/utils/formatters";
import SubscribeCard from "@/components/cards/SubscribeCard.vue";
// 输入参数
const props = defineProps({
@@ -28,105 +28,14 @@ const filteredDataList = computed(() => {
return dataList.value.filter((data) => data.type === props.type);
});
// 根据 type 返回不同的图标
const getIcon = (type: string) => {
if (type === "电影") {
return "mdi-movie";
} else if (type === "电视剧") {
return "mdi-television-classic";
} else {
return "mdi-help-circle";
}
};
// 计算百分比
const getPercentage = (total: number, lack: number) => {
if (total === 0) {
return 0;
}
return Math.round(((total - lack) / total) * 100);
};
</script>
<template>
<div class="grid gap-3 grid-subscribe-card">
<VCard v-for="data in filteredDataList"
:key="data.id"
:image="data.backdrop || data.poster"
class="card-with-overlay">
<VCardItem>
<template #prepend>
<VIcon
size="1.9rem"
color="white"
:icon="getIcon(data.type)"
class="overlay-text"
/>
</template>
<VCardTitle class="text-white overlay-text">
{{ data.name }} {{ formatSeason(data.season ? data.season.toString() : "") }}
</VCardTitle>
<template #append>
<div class="me-n3">
<MoreBtn color="white" class="overlay-text"/>
</div>
</template>
</VCardItem>
<VCardText class="overlay-text">
<p class="clamp-text text-white mb-0">
{{ data.description }}
</p>
</VCardText>
<VCardText
class="d-flex justify-space-between align-center flex-wrap overlay-text"
>
<div class="d-flex align-center">
<IconBtn icon="mdi-star" color="white" class="me-1" />
<span class="text-subtitle-2 text-white me-4">{{ data.vote }}</span>
<IconBtn
icon="mdi-progress-clock"
color="white"
class="me-1"
v-if="data.total_episode"
/>
<span class="text-subtitle-2 text-white" v-if="data.season"
>{{ (data.total_episode || 0) - (data.lack_episode || 0) }} /
{{ data.total_episode }}</span
>
</div>
</VCardText>
<VProgressLinear
v-if="data.total_episode || 0 > 0"
:model-value="getPercentage(data.total_episode || 0, data.lack_episode || 0)"
bg-color="success"
color="success"
/>
</VCard>
<SubscribeCard v-for="data in filteredDataList"
:key="data.id"
:media="data"
/>
</div>
</template>
<style lang="scss">
.card-with-overlay {
position: relative;
}
.card-with-overlay::before {
position: absolute;
z-index: 1;
background-color: rgba(0, 0, 0, 40%); /* 背景遮罩的颜色和透明度 */
block-size: 100%;
content: "";
inline-size: 100%;
inset-block-start: 0;
inset-inline-start: 0;
}
.overlay-text {
position: relative;
z-index: 2;
}
</style>