init
49
client/src/App.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div class="main">
|
||||
<router-view></router-view>
|
||||
<Util/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
|
||||
import Util from "./components/Util.vue";
|
||||
</script>
|
||||
|
||||
<style>
|
||||
html, body, #app {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/*背景色切换*/
|
||||
|
||||
|
||||
#app, .main {
|
||||
max-width: 100%;
|
||||
min-height: 100vh;
|
||||
/*background: #222;*/
|
||||
color: rgb(221, 221, 221);
|
||||
background: rgb(34, 34, 34);
|
||||
}
|
||||
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
||||
/*全局a标签默认样式去除*/
|
||||
a {
|
||||
color: #2d2e2f;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #888888;
|
||||
}
|
||||
</style>
|
||||
BIN
client/src/assets/image/404.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
client/src/assets/image/cartoon.png
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
BIN
client/src/assets/image/film.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
client/src/assets/image/play.png
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
BIN
client/src/assets/image/tv.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
1
client/src/assets/svg/cartoon.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1679472009425" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7100" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M 114.95 629.48 s -134.39 -197.75 80.63 -271.66 l 16.32 -9.6 s 8.64 -111.35 118.07 -142.07 c 0 0 68.16 -1.92 96.95 0 c 0 0 48.96 -99.83 174.71 -66.24 c 0 0 41.28 14.4 69.11 45.12 c 0 0 191.03 -62.4 181.43 124.79 c 0 0 -37.44 -173.75 -174.71 -79.67 c 0 0 -125.75 -135.35 -214.06 -19.2 l -20.16 32.64 s -171.83 -37.44 -207.35 137.27 c 0.01 -0.01 -203.49 31.67 -120.94 248.62 Z" fill="#1296db" p-id="7101"></path><path d="M 176.39 563.24 a 74.39 66.24 0 1 0 148.78 0 a 74.39 66.24 0 1 0 -148.78 0 Z" fill="#1296db" p-id="7102"></path><path d="M 383.25 414.93 m -69.12 0 a 69.12 69.12 0 1 0 138.24 0 a 69.12 69.12 0 1 0 -138.24 0 Z" fill="#1296db" p-id="7103"></path><path d="M 568.52 310.3 m -71.03 0 a 71.03 71.03 0 1 0 142.06 0 a 71.03 71.03 0 1 0 -142.06 0 Z" fill="#1296db" p-id="7104"></path><path d="M 673.15 329.5 a 61.44 70.07 0 1 0 122.88 0 a 61.44 70.07 0 1 0 -122.88 0 Z" fill="#1296db" p-id="7105"></path><path d="M 289.66 723.55 s 136.31 263.02 395.49 137.27 c 0 0 171.83 -88.31 136.31 -350.37 c 0 0 108.47 252.46 -122.87 383.97 c 0 0 -291.82 148.79 -408.93 -170.87 Z" fill="#1296db" p-id="7106"></path><path d="M 446.13 650.59 s 84.95 -139.67 239.02 -87.35 c 37.04 12.58 110.87 94.55 0 156.47 c -18.65 10.41 -43.2 7.68 -85.43 0 c 0 0 -29.76 63.36 -64.32 74.87 c 0 0 -134.39 57.6 -89.27 -143.99 Z" fill="#1296db" p-id="7107"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
1
client/src/assets/svg/film.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1679471653435" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="54082" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M799 832H224c-17.7 0-32 14.3-32 32s14.3 32 32 32h575c17.7 0 32-14.3 32-32s-14.3-32-32-32z m97-704H128c-35.3 0-64 28.7-64 64v511c0 35.3 28.7 64 64 64h768c35.3 0 64-28.7 64-64V192c0-35.3-28.7-64-64-64zM623.9 473.6l-197.6 98.5c-19.4 9.7-42.3-4.4-42.3-26v-197c0-21.6 22.9-35.7 42.3-26l197.6 98.5c21.5 10.7 21.5 41.3 0 52z" fill="#45C6FD" p-id="54083"></path></svg>
|
||||
|
After Width: | Height: | Size: 694 B |
1
client/src/assets/svg/tv.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1679472049358" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8204" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M464 496H272c-17.6 0-32-14.4-32-32s14.4-32 32-32h192c17.6 0 32 14.4 32 32s-14.4 32-32 32z" fill="#1296db" p-id="8205"></path><path d="M368 720c-17.6 0-32-14.4-32-32V464c0-17.6 14.4-32 32-32s32 14.4 32 32v224c0 17.6-14.4 32-32 32zM656 720c-12.8 0-24-8-28.8-19.2l-96-224c-6.4-16 0-35.2 16-41.6 16-6.4 35.2 0 41.6 17.6L656 608l67.2-155.2c6.4-16 25.6-24 41.6-17.6 16 6.4 24 25.6 16 41.6l-96 224c-4.8 11.2-16 19.2-28.8 19.2z" fill="#1296db" p-id="8206"></path><path d="M848 928H176c-52.8 0-96-43.2-96-96V320c0-52.8 43.2-96 96-96h672c52.8 0 96 43.2 96 96v512c0 52.8-43.2 96-96 96zM176 288c-17.6 0-32 14.4-32 32v512c0 17.6 14.4 32 32 32h672c17.6 0 32-14.4 32-32V320c0-17.6-14.4-32-32-32H176z" fill="#1296db" p-id="8207"></path><path d="M448 288c-8 0-16-3.2-22.4-9.6l-160-160c-12.8-12.8-12.8-32 0-44.8 12.8-12.8 32-12.8 44.8 0l160 160c12.8 12.8 12.8 32 0 44.8-6.4 6.4-14.4 9.6-22.4 9.6zM576 288c-8 0-16-3.2-22.4-9.6-12.8-12.8-12.8-32 0-44.8l160-160c12.8-12.8 32-12.8 44.8 0 12.8 12.8 12.8 32 0 44.8l-160 160c-6.4 6.4-14.4 9.6-22.4 9.6z" fill="#1296db" p-id="8208"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
23
client/src/components/Footer.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<div class="custom-footer">
|
||||
本站所有内容均来自互联网分享站点所提供的公开引用资源,未提供资源上传、存储服务。
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.custom-footer {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
text-align: center;
|
||||
line-height: 15px;
|
||||
font-size: 15px;
|
||||
color: #888888;
|
||||
margin-top: 25px;
|
||||
}
|
||||
</style>
|
||||
203
client/src/components/Header.vue
Normal file
@@ -0,0 +1,203 @@
|
||||
<template>
|
||||
<div class="header">
|
||||
<!-- 左侧logo以及搜索 -->
|
||||
<div class="nav_left">
|
||||
<!-- <img class="logo" src="/src/assets/logo.png">-->
|
||||
<a href="/" style="font-weight: 600;font-style: italic;font-size: 24px;margin-right: 5px">Boat</a>
|
||||
<div class="search_group">
|
||||
<input v-model="keyword" placeholder="搜索 动漫,剧集,电影 " class="search"/>
|
||||
<el-button @click="searchFilm" :icon="Search"/>
|
||||
</div>
|
||||
</div>
|
||||
<!--右侧顶级分类导航 -->
|
||||
<div class="nav_right">
|
||||
<el-link :underline="false" href="/">首页</el-link>
|
||||
<el-link :underline="false" :href="`/categoryFilm?pid=${nav.film.id}`">电影</el-link>
|
||||
<el-link :underline="false" :href="`/categoryFilm?pid=${nav.tv.id}`">剧集</el-link>
|
||||
<el-link :underline="false" :href="`/categoryFilm?pid=${nav.cartoon.id}`">动漫</el-link>
|
||||
<el-link :underline="false" :href="`/categoryFilm?pid=${nav.variety.id}`">综艺</el-link>
|
||||
<!-- <span style="color:#777; font-weight: bold">|</span>-->
|
||||
<el-link href="/search" class="hidden-md-and-up" :underline="false">
|
||||
<el-icon style="font-size: 18px">
|
||||
<Search/>
|
||||
</el-icon>
|
||||
</el-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {onMounted, reactive, ref, watch} from "vue";
|
||||
import {useRouter} from "vue-router";
|
||||
import {Search, CircleClose} from '@element-plus/icons-vue'
|
||||
import {ElMessage} from "element-plus";
|
||||
import {ApiGet} from "../utils/request";
|
||||
|
||||
//
|
||||
const keyword = ref<string>('')
|
||||
|
||||
|
||||
// 从父组件获取当前路由对象
|
||||
const router = useRouter()
|
||||
// 影片搜索
|
||||
const searchFilm = () => {
|
||||
if (keyword.value.length <= 0) {
|
||||
ElMessage.error({message: "请先输入影片名称关键字再进行搜索", duration: 1500})
|
||||
return
|
||||
}
|
||||
location.href = `/search?search=${keyword.value}`
|
||||
// router.push({path: '/search', query:{search: keyword.value}, replace: true})
|
||||
}
|
||||
|
||||
// 导航栏挂载完毕时发送一次请求拿到对应的分类id数据
|
||||
const nav = reactive({
|
||||
cartoon: {},
|
||||
film: {},
|
||||
tv: {},
|
||||
variety: {},
|
||||
})
|
||||
onMounted(() => {
|
||||
ApiGet('/navCategory').then((resp: any) => {
|
||||
if (resp.status === 'ok') {
|
||||
nav.tv = resp.data.tv
|
||||
nav.film = resp.data.film
|
||||
nav.cartoon = resp.data.cartoon
|
||||
nav.variety = resp.data.variety
|
||||
} else {
|
||||
ElMessage.error({message: "请先输入影片名称关键字再进行搜索", duration: 1000})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<!--移动端适配-->
|
||||
<style>
|
||||
/*小尺寸时隐藏状态栏*/
|
||||
@media (max-width: 650px) {
|
||||
.nav_right {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
/*display: none!important;*/
|
||||
}
|
||||
|
||||
.nav_right a {
|
||||
color: #ffffff;
|
||||
flex-basis: calc(19% - 5px);
|
||||
padding: 0 10px;
|
||||
line-height: 40px;
|
||||
/*border-radius: 5px;*/
|
||||
/*border: 1px solid rebeccapurple;*/
|
||||
|
||||
}
|
||||
|
||||
.nav_right a:hover {
|
||||
color: #ffffff;
|
||||
/*background-color: transparent;*/
|
||||
}
|
||||
|
||||
.header {
|
||||
width: 100% !important;
|
||||
height: 40px;
|
||||
background: radial-gradient(circle, #d275cd, rgba(155, 73, 231, 0.72), #4ad1e5);
|
||||
}
|
||||
|
||||
.nav_left {
|
||||
display: none !important;
|
||||
width: 90% !important;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
|
||||
|
||||
@media (min-width: 650px) {
|
||||
.header {
|
||||
width: 78%;
|
||||
z-index: 0;
|
||||
max-height: 40px;
|
||||
line-height: 60px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.nav_left {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/*搜索栏*/
|
||||
.search_group {
|
||||
width: 80%;
|
||||
margin: 10px auto;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.search {
|
||||
flex: 10;
|
||||
background-color: #2e2e2e !important;
|
||||
border: none !important;
|
||||
height: 40px;
|
||||
border-radius: 6px 0 0 6px;
|
||||
padding-left: 20px;
|
||||
color: #c9c4c4;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
line-height: 60px;
|
||||
}
|
||||
|
||||
.search::placeholder {
|
||||
font-size: 15px;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.search:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.search_group button {
|
||||
flex: 1;
|
||||
margin: 0;
|
||||
background-color: #2e2e2e;
|
||||
color: rgb(171, 44, 68);
|
||||
border: none !important;
|
||||
height: 40px;
|
||||
border-radius: 0 6px 6px 0;
|
||||
font-size: 20px;
|
||||
/*margin-bottom: 2px*/
|
||||
}
|
||||
|
||||
.nav_right {
|
||||
display: flex;
|
||||
height: 60px;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.nav_right a {
|
||||
min-width: 60px;
|
||||
height: 40px;
|
||||
line-height: 60px;
|
||||
margin: 10px 10px;
|
||||
font-size: 15px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.nav_right a:hover {
|
||||
color: orange;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 40px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
154
client/src/components/RelateList.vue
Normal file
@@ -0,0 +1,154 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<h2 class="title">相关影片</h2>
|
||||
<div class="content">
|
||||
<div class="item" v-for="m in relateList">
|
||||
<a :href="`/filmDetail?link=${m.id}`" class="cus_content_link"
|
||||
:style="{backgroundImage: `url('${m.picture}')`}">
|
||||
<span class="cus_tag hidden-md-and-down">{{ m.year }}</span>
|
||||
<span class="cus_tag hidden-md-and-down">{{ m.cName }}</span>
|
||||
<span class="cus_tag hidden-md-and-down">{{ m.area }}</span>
|
||||
<span class="cus_remark hidden-md-and-up">{{ m.remarks }}</span>
|
||||
</a>
|
||||
<a :href="`/filmDetail?link=${m.id}`"
|
||||
class=" content_text_tag">{{ m.name }}</a>
|
||||
<span class="cus_remark hidden-md-and-down">{{ m.remarks }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
defineProps({
|
||||
relateList : []
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@media (min-width: 650px) {
|
||||
.container {
|
||||
width: 100%;
|
||||
margin-top: 36px;
|
||||
}
|
||||
.title {
|
||||
padding: 0 0 5px 10px;
|
||||
text-align: left;
|
||||
border-bottom: 2px solid #777777;
|
||||
}
|
||||
.content {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-flow: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.container .item {
|
||||
width: calc(14% - 18px);
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.cus_content_link {
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
padding-top: 125%;
|
||||
background-size: cover;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cus_tag {
|
||||
text-align: center;
|
||||
color: rgb(255, 255, 255);
|
||||
padding: 0 3px;
|
||||
margin: 0 0 10px 8px;
|
||||
background: rgba(0, 0, 0, 0.55);
|
||||
font-size: 12px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.content_text_tag {
|
||||
display: block;
|
||||
font-size: 13px !important;
|
||||
color: rgb(221, 221, 221);
|
||||
padding: 2px 2px 2px 2px !important;
|
||||
text-align: left;
|
||||
max-width: 80%;
|
||||
max-height: 20px;
|
||||
white-space: nowrap; /* 禁止换行 */
|
||||
overflow: hidden; /* 超出部分隐藏 */
|
||||
text-overflow: ellipsis; /* 使用省略号表示被截断的部分 */
|
||||
}
|
||||
.cus_remark {
|
||||
display: block;
|
||||
color: #888888;
|
||||
width: 100%;
|
||||
font-size: 12px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: 650px) {
|
||||
.container {
|
||||
width: 100%;
|
||||
margin-top: 36px;
|
||||
}
|
||||
.title {
|
||||
padding: 0 0 5px 10px;
|
||||
text-align: left;
|
||||
border-bottom: 2px solid #777777;
|
||||
}
|
||||
.content {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-flow: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.container .item {
|
||||
width: calc(33% - 5px);
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.cus_content_link {
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
padding-top: 125%;
|
||||
background-size: cover;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cus_tag {
|
||||
text-align: center;
|
||||
color: rgb(255, 255, 255);
|
||||
padding: 0 3px;
|
||||
margin: 0 0 10px 8px;
|
||||
background: rgba(0, 0, 0, 0.55);
|
||||
font-size: 12px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.content_text_tag {
|
||||
font-size: 12px !important;
|
||||
color: rgb(221, 221, 221);
|
||||
width: 100%;
|
||||
padding: 2px 0 2px 0 !important;
|
||||
text-align: left;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.cus_remark {
|
||||
display: block;
|
||||
width: 100%;
|
||||
font-size: 12px;
|
||||
color: #c2c2c2;
|
||||
text-align: center;
|
||||
background: rgba(0,0,0,0.55);
|
||||
border-radius: 0 0 5px 5px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
105
client/src/components/Util.vue
Normal file
@@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<div class="util">
|
||||
<el-collapse-transition>
|
||||
<div v-show="control.show">
|
||||
<a href="javascript:;" @click="changeStyle('top')">
|
||||
<el-icon>
|
||||
<ArrowUp />
|
||||
</el-icon>
|
||||
</a>
|
||||
<a v-if="control.darkTheme" href="javascript:;" @click="changeStyle('light')">
|
||||
<el-icon>
|
||||
<Sunny/>
|
||||
</el-icon>
|
||||
</a>
|
||||
<a v-if="!control.darkTheme" href="javascript:;" @click="changeStyle('dark')">
|
||||
<el-icon>
|
||||
<Moon/>
|
||||
</el-icon>
|
||||
</a>
|
||||
</div>
|
||||
</el-collapse-transition>
|
||||
<a href="javascript:;" @click="changeStyle('more')" class="more">
|
||||
<el-icon>
|
||||
<MoreFilled/>
|
||||
</el-icon>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {ArrowUp,Sunny, Moon, MoreFilled} from '@element-plus/icons-vue'
|
||||
import {onBeforeMount, onMounted, onUnmounted, reactive} from "vue";
|
||||
|
||||
const control = reactive({
|
||||
show: false,
|
||||
darkTheme: true,
|
||||
})
|
||||
|
||||
//
|
||||
onMounted(()=>{
|
||||
|
||||
changeStyle(localStorage.getItem("theme")+'')
|
||||
})
|
||||
|
||||
|
||||
const changeStyle = (type:string)=>{
|
||||
switch (type) {
|
||||
case 'top':
|
||||
let top = document.documentElement.scrollTop
|
||||
if (top > 0) {
|
||||
// 创建定时器,平滑滚动
|
||||
const interval = setInterval(() => {
|
||||
document.documentElement.scrollTop -= 10;
|
||||
if (document.documentElement.scrollTop === 0) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
}, 5);
|
||||
}
|
||||
break
|
||||
case 'light':
|
||||
control.darkTheme = false
|
||||
localStorage.setItem("theme", 'light')
|
||||
document.getElementsByClassName('main')[0].style.background = `radial-gradient(circle, #C147E9, #810CA8, #2D033B)`
|
||||
break
|
||||
case 'dark':
|
||||
control.darkTheme = true
|
||||
localStorage.setItem("theme", 'dark')
|
||||
document.getElementsByClassName('main')[0].style.background = `rgb(34,34,34)`
|
||||
break
|
||||
case 'more':
|
||||
control.show = !control.show
|
||||
break
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/*窗口工具栏设置*/
|
||||
.util {
|
||||
position: fixed;
|
||||
right: 10px;
|
||||
bottom: 15%;
|
||||
width: 35px;
|
||||
}
|
||||
.util a {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-bottom: 3px;
|
||||
height: 35px;
|
||||
border-radius: 50%;
|
||||
background: rgba(0,0,0,0.35);
|
||||
}
|
||||
.util a:hover{
|
||||
background: #d329a4;
|
||||
}
|
||||
:deep(.el-icon) {
|
||||
font-size: 18px;
|
||||
height: 100%;
|
||||
color: #ffffff;
|
||||
}
|
||||
.more {
|
||||
background: rgb(238, 150, 0) !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
20
client/src/main.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import {createApp} from 'vue'
|
||||
import './style.css'
|
||||
import App from './App.vue'
|
||||
import { router} from "./router/router";
|
||||
// 引入elementPlus
|
||||
import ElementPlus from 'element-plus'
|
||||
import 'element-plus/dist/index.css'
|
||||
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
|
||||
app.use(ElementPlus)
|
||||
// 引入路由
|
||||
app.use(router)
|
||||
|
||||
|
||||
app.mount('#app')
|
||||
|
||||
|
||||
43
client/src/router/router.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
import {
|
||||
createRouter,
|
||||
createWebHistory,
|
||||
} from "vue-router";
|
||||
|
||||
|
||||
// 1.定义路由组件
|
||||
import IndexHome from "../views/IndexHome.vue";
|
||||
import Home from "../views/index/Home.vue";
|
||||
import FilmDetails from "../views/index/FilmDetails.vue";
|
||||
import Play from "../views/index/Play.vue";
|
||||
import SearchFilm from "../views/index/SearchFilm.vue";
|
||||
import CategoryFilm from "../views/index/CategoryFilm.vue";
|
||||
import NotFound from '../views/error/Error404.vue'
|
||||
|
||||
|
||||
// 2. 定义一个路由
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
component: IndexHome,
|
||||
redirect: '/index',
|
||||
children: [
|
||||
{path: 'index', component: Home},
|
||||
{path: 'filmDetail', component: FilmDetails},
|
||||
{path: 'play', component: Play},
|
||||
{path: 'search', component: SearchFilm},
|
||||
{path: 'CategoryFilm', component: CategoryFilm},
|
||||
]
|
||||
},
|
||||
{path: `/:pathMatch(.*)*`, component: NotFound},
|
||||
]
|
||||
|
||||
// 创建路由实例并传递 routes配置
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes
|
||||
})
|
||||
|
||||
|
||||
export {router}
|
||||
|
||||
80
client/src/style.css
Normal file
@@ -0,0 +1,80 @@
|
||||
:root {
|
||||
font-family: Inter, Avenir, Helvetica, Arial, system-ui, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
}
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
#app {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
||||
83
client/src/utils/request.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import axios from "axios";
|
||||
import {ElMessage, ElLoading } from "element-plus";
|
||||
|
||||
// 定义加载动画对象
|
||||
let loading:any
|
||||
const startLoading = ()=>{
|
||||
loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: `请求发送中...`,
|
||||
background: `rgba(255,255,255,0.5)`,
|
||||
// target: document.querySelector(`.content`)
|
||||
})
|
||||
}
|
||||
const closeLoading = ()=>{
|
||||
loading.close()
|
||||
}
|
||||
|
||||
const http = (options: any) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// create an axios instance
|
||||
const service = axios.create({
|
||||
// baseURL: import.meta.env.VITE_URL_BASE, // api 的 base_url 注意 vue3
|
||||
baseURL: `/api`, // api 的 base_url 注意 vue3
|
||||
// baseURL: 'https://www.baidu.com/api', // 固定api
|
||||
timeout: 80000, // request timeout
|
||||
});
|
||||
|
||||
// request interceptor
|
||||
service.interceptors.request.use(
|
||||
(config: any) => {
|
||||
// 开启loading动画
|
||||
startLoading()
|
||||
// let token: string = ""; //此处换成自己获取回来的token,通常存在在cookie或者store里面
|
||||
// if (token) {
|
||||
// // 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
|
||||
// config.headers["X-Token"] = token;
|
||||
//
|
||||
// config.headers.Authorization = +token;
|
||||
// }
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
// Do something with request error
|
||||
Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// response interceptor
|
||||
service.interceptors.response.use(
|
||||
(response) => {
|
||||
closeLoading()
|
||||
|
||||
return response.data;
|
||||
},
|
||||
(error) => {
|
||||
closeLoading()
|
||||
if (error.response.status == 403) {
|
||||
ElMessage.error("请求异常: ", error)
|
||||
} else {
|
||||
ElMessage.error("服务器繁忙,请稍后再试");
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
// 请求处理
|
||||
service(options)
|
||||
.then((res) => {
|
||||
resolve(res);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const ApiGet = (url:string, params?:any)=>{
|
||||
return http({url, method:`get`, params,})
|
||||
}
|
||||
const ApiPost = (url:string, data:any) =>{
|
||||
return http({url, method:`post`, data,})
|
||||
}
|
||||
|
||||
export {http, ApiPost, ApiGet};
|
||||
95
client/src/views/IndexHome.vue
Normal file
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<Header/>
|
||||
</el-header>
|
||||
<el-main>
|
||||
<router-view></router-view>
|
||||
</el-main>
|
||||
<el-footer>
|
||||
<Footer/>
|
||||
</el-footer>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Header from "../components/Header.vue";
|
||||
import Footer from "../components/Footer.vue";
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
|
||||
:deep(.el-main) {
|
||||
padding-top: 70px !important;
|
||||
padding-bottom: 30px !important;
|
||||
min-height: 85vh;
|
||||
}
|
||||
|
||||
:deep(.el-header) {
|
||||
padding: 0 !important;
|
||||
position: fixed !important;
|
||||
width: 100% !important;
|
||||
min-height: 60px;
|
||||
transform: translateZ(0);
|
||||
z-index: 1000;
|
||||
background-color: rgba(0, 0, 0, 0.85);
|
||||
top: 0;
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: 650px) {
|
||||
.el-main {
|
||||
margin: 0 auto;
|
||||
padding: 100px 0;
|
||||
/*padding-top: 100px!important;*/
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 650px) {
|
||||
.el-main {
|
||||
/*margin: 0 auto;*/
|
||||
padding: 60px 0;
|
||||
/*padding-top: 100px!important;*/
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-menu--horizontal) {
|
||||
border-bottom: 1px solid rgb(46, 46, 46);
|
||||
}
|
||||
|
||||
/*@media (min-width: 768px){ //>=768的设备 }*/
|
||||
/*@media (min-width: 992px){ //>=992的设备 }*/
|
||||
/*@media (min-width: 1200){ //>=1200的设备 }*/
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.el-main {
|
||||
width: 1023px
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 990px) {
|
||||
.el-main {
|
||||
width: 970px
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.el-main {
|
||||
width: 1180px
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1400px) {
|
||||
.el-main {
|
||||
width: 1400px
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1560px) {
|
||||
.el-main {
|
||||
width: 1500px
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
21
client/src/views/error/Error404.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<el-empty style="height: 100%; line-height: 100%; font-size: 20px" :image-size="400"
|
||||
image="/src/assets/image/404.png">
|
||||
<template #description>
|
||||
<p style="font-size: 32px;width: 100%;color: #a574b7">你好像走错地方了哦!!!</p>
|
||||
</template>
|
||||
</el-empty>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
height: 100vh;
|
||||
|
||||
}
|
||||
</style>
|
||||
443
client/src/views/index/CategoryFilm.vue
Normal file
@@ -0,0 +1,443 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<p>{{ d.category.name }}</p>
|
||||
<div class="c_header">
|
||||
<a :class="`nav ${d.list.length >0 && d.list[0].cid == c.id?'active':''}`" href="javascript:;" @click="changeCategory(c.id)"
|
||||
v-for="c in d.category.children">{{ c.name }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="c_content" >
|
||||
<div class="item" v-for="item in d.list">
|
||||
<a :href="`/filmDetail?link=${item.id}`" :style="{backgroundImage: `url('${item.picture}')`}">
|
||||
<span class="cus_tag ">{{ item.year }}</span>
|
||||
<span class="cus_tag ">{{ item.cName }}</span>
|
||||
<span class="cus_tag ">{{ item.area }}</span>
|
||||
<span class="cus_remark hidden-md-and-up">{{ item.remarks }}</span>
|
||||
</a>
|
||||
<a :href="`/filmDetail?link=${item.id}`" class="content_text_tag">{{ item.name.split("[")[0] }}</a>
|
||||
<span class="cus_remark hidden-md-and-down">{{ item.remarks }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pagination_container ">
|
||||
<el-pagination background layout="prev, pager, next"
|
||||
v-model:current-page="d.page.current"
|
||||
@current-change="changeCurrent"
|
||||
:pager-count="5"
|
||||
:background="true"
|
||||
:page-size="d.page.pageSize"
|
||||
:total="d.page.total"
|
||||
:prev-icon="ArrowLeftBold"
|
||||
:next-icon="ArrowRightBold"
|
||||
hide-on-single-page
|
||||
class="pagination"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
|
||||
import {onMounted, reactive} from "vue";
|
||||
import {useRouter} from "vue-router";
|
||||
import {ApiGet} from "../../utils/request";
|
||||
import {ElMessage} from "element-plus";
|
||||
import {ArrowRightBold, ArrowLeftBold} from '@element-plus/icons-vue'
|
||||
|
||||
// 页面所需数据
|
||||
const d = reactive({
|
||||
category: {},
|
||||
list: [],
|
||||
page: {
|
||||
current: 0,
|
||||
},
|
||||
|
||||
})
|
||||
// 获取路由参数查询对应数据
|
||||
const router = useRouter()
|
||||
|
||||
// 点击分页按钮事件 current-change
|
||||
const changeCurrent = (currentVal: number) => {
|
||||
let query = router.currentRoute.value.query
|
||||
// router.push({path: '/categoryFilm', query:{pid: query.pid, cid: query.cid, current: currentVal}})
|
||||
if (query.cid && query.cid != "") {
|
||||
location.href = `/categoryFilm?pid=${query.pid}&cid=${query.cid}¤t=${currentVal}`
|
||||
} else {
|
||||
location.href = `/categoryFilm?pid=${query.pid}&¤t=${currentVal}`
|
||||
}
|
||||
}
|
||||
|
||||
// 点击分类事件
|
||||
const changeCategory = (cid: any) => {
|
||||
let params = new URLSearchParams(location.search)
|
||||
// location.href = `/categoryFilm?pid=${params.get('pid')}&cid=${cid}¤t=${params.get('current')?params.get('current'):1}`
|
||||
location.href = `/categoryFilm?pid=${params.get('pid')}&cid=${cid}¤t=1`
|
||||
}
|
||||
|
||||
|
||||
const getFilmData = (param: any) => {
|
||||
ApiGet('/filmCategory', {pid: param.pid, cid: param.cid, current: param.current}).then((resp: any) => {
|
||||
if (resp.status === 'ok') {
|
||||
d.category = resp.data.category
|
||||
d.list = resp.data.list
|
||||
d.page = resp.page
|
||||
} else {
|
||||
ElMessage.error({message: "请先输入影片名称关键字再进行搜索", duration: 1000})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
let query = router.currentRoute.value.query
|
||||
getFilmData({pid: query.pid, cid: query.cid, current: query.current})
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<!--移动端修改-->
|
||||
<style scoped>
|
||||
@media (max-width: 650px) {
|
||||
.container {
|
||||
padding: 0 10px;
|
||||
|
||||
}
|
||||
/*顶部内容区域*/
|
||||
.header {
|
||||
width: 100%;
|
||||
margin-bottom: 150px;
|
||||
background: none!important;
|
||||
}
|
||||
.header p {
|
||||
text-align: left;
|
||||
font-weight: 600;
|
||||
font-size: 24px;
|
||||
color: #c9c4c4;
|
||||
margin-top: 0;
|
||||
padding-left: 10px;
|
||||
height: 100%;
|
||||
/*background: rgb(34, 34, 34);*/
|
||||
}
|
||||
|
||||
.c_header {
|
||||
max-width: 100%;
|
||||
display: flex;
|
||||
/*justify-content: start;*/
|
||||
flex-wrap: nowrap;
|
||||
overflow-x: scroll;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.c_header a {
|
||||
white-space: nowrap;
|
||||
margin-right: 10px;
|
||||
color: #000;
|
||||
font-weight: 400;
|
||||
background: rgba(255, 255, 255, 0.94);
|
||||
padding: 6px 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.c_header a:hover {
|
||||
color: orange;
|
||||
}
|
||||
|
||||
.nav:before {
|
||||
width: 36px;
|
||||
height: 4px;
|
||||
background: orange;
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 35%;
|
||||
bottom: 12px;
|
||||
border-radius: 50px;
|
||||
transform: scaleX(0);
|
||||
transition: transform 0.5s ease-out;
|
||||
}
|
||||
|
||||
.nav:hover:before {
|
||||
width: 36px;
|
||||
height: 4px;
|
||||
background: orange;
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 35%;
|
||||
bottom: 12px;
|
||||
border-radius: 50px;
|
||||
transform: scaleX(1);
|
||||
}
|
||||
.active {
|
||||
background: rgb(249 230 195)!important;
|
||||
color: #e52424!important;
|
||||
}
|
||||
|
||||
|
||||
/*展示区域*/
|
||||
.c_content {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-flow: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.c_content .item {
|
||||
flex-basis: calc(33% - 5px);
|
||||
max-width: 33%;
|
||||
margin-bottom: 20px;
|
||||
/*width: 100px;*/
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.item a {
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
padding-top: 125%;
|
||||
background-size: cover;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cus_tag {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.content_text_tag {
|
||||
font-size: 12px !important;
|
||||
color: rgb(221, 221, 221);
|
||||
width: 100%;
|
||||
padding: 2px 0 2px 0 !important;
|
||||
text-align: left;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.cus_remark {
|
||||
display: block;
|
||||
width: 100%;
|
||||
font-size: 12px;
|
||||
color: #c2c2c2;
|
||||
text-align: center;
|
||||
background: rgba(0,0,0,0.55);
|
||||
border-radius: 0 0 5px 5px;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
max-width: 100vw;
|
||||
}
|
||||
@media (min-width: 650px) {
|
||||
|
||||
/*顶部内容区域*/
|
||||
.header {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.header p {
|
||||
text-align: left;
|
||||
font-weight: 800;
|
||||
font-size: 32px;
|
||||
color: #c9c4c4;
|
||||
margin-top: 0;
|
||||
/*border-bottom: 2px solid #ffffff;*/
|
||||
/*padding-bottom: 30px;*/
|
||||
}
|
||||
|
||||
.c_header {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
/*justify-content: start;*/
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.c_header a {
|
||||
/*flex-basis: calc(14% - 16px);*/
|
||||
margin-right: 20px;
|
||||
color: #000;
|
||||
font-weight: 800;
|
||||
background: rgba(255, 255, 255, 0.94);
|
||||
padding: 20px 40px;
|
||||
border-radius: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.c_header a:hover {
|
||||
color: orange;
|
||||
}
|
||||
|
||||
.nav:before {
|
||||
width: 36px;
|
||||
height: 4px;
|
||||
background: orange;
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 35%;
|
||||
bottom: 12px;
|
||||
border-radius: 50px;
|
||||
transform: scaleX(0);
|
||||
transition: transform 0.5s ease-out;
|
||||
}
|
||||
|
||||
.nav:hover:before {
|
||||
width: 36px;
|
||||
height: 4px;
|
||||
background: orange;
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 35%;
|
||||
bottom: 12px;
|
||||
border-radius: 50px;
|
||||
transform: scaleX(1);
|
||||
}
|
||||
.active {
|
||||
background: rgb(249 230 195)!important;
|
||||
color: #e52424!important;
|
||||
}
|
||||
|
||||
|
||||
.c_content {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-flow: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.c_content .item {
|
||||
flex-basis: calc(14% - 16px);
|
||||
max-width: 14%;
|
||||
margin-bottom: 20px;
|
||||
/*width: 100px;*/
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.item a {
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
/*position: relative;*/
|
||||
padding-top: 125%;
|
||||
background-size: cover;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cus_tag {
|
||||
text-align: center;
|
||||
color: rgb(255, 255, 255);
|
||||
padding: 0 3px;
|
||||
margin: 0 0 10px 8px;
|
||||
background: rgba(0, 0, 0, 0.55);
|
||||
font-size: 12px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.content_text_tag {
|
||||
font-size: 14px !important;
|
||||
color: rgb(221, 221, 221);
|
||||
width: 96%;
|
||||
padding: 2px 10px 2px 2px !important;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.cus_remark {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding-left: 3px;
|
||||
font-size: 12px;
|
||||
color: #999999;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
/*分页插件区域*/
|
||||
.pagination_container {
|
||||
width: 100%;
|
||||
margin-top: 30px;
|
||||
/*background: deepskyblue;*/
|
||||
text-align: center;
|
||||
/*display: flex;*/
|
||||
}
|
||||
|
||||
:deep(.el-pagination) {
|
||||
width: 100% !important;
|
||||
margin: 0 auto !important;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/*分页器样式修改*/
|
||||
:deep(.number) {
|
||||
font-weight: bold;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
background: #2e2e2e !important;
|
||||
color: #ffffff;
|
||||
border-radius: 50%;
|
||||
/*margin: 0 3px!important;*/
|
||||
}
|
||||
|
||||
:deep(.number:hover) {
|
||||
color: #67d9e8;
|
||||
}
|
||||
|
||||
:deep(.btn-prev) {
|
||||
font-weight: bold;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
background: #2e2e2e !important;
|
||||
color: #ffffff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
:deep(.btn-next) {
|
||||
font-weight: bold;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
background: #2e2e2e !important;
|
||||
color: #ffffff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
:deep(.more) {
|
||||
font-weight: bold;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
background: #2e2e2e !important;
|
||||
color: #ffffff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
:deep(.is-active) {
|
||||
background: #67d9e8 !important;
|
||||
}
|
||||
/*移动端缩小*/
|
||||
@media (max-width: 650px) {
|
||||
:deep(.number){
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
}
|
||||
:deep(.btn-prev) {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
}
|
||||
:deep(.btn-next) {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
}
|
||||
:deep(.more) {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
383
client/src/views/index/FilmDetails.vue
Normal file
@@ -0,0 +1,383 @@
|
||||
<template>
|
||||
<div class="film">
|
||||
<!-- hidden-sm-and-up 移动端title -->
|
||||
<div class="hidden-sm-and-up">
|
||||
<div class="title_mt ">
|
||||
<a class="picture_mt" href="" :style="{backgroundImage: `url('${data.detail.picture}')`}"></a>
|
||||
<div class="title_mt_right">
|
||||
<h3>{{ data.detail.name }}</h3>
|
||||
<ul class="tags">
|
||||
<li style="margin: 2px 0">{{ `${data.detail.descriptor.classTag}`.replaceAll(",", " | ") }}</li>
|
||||
</ul>
|
||||
<p><span>导演:</span> {{ data.detail.descriptor.director }}</p>
|
||||
<p><span>主演:</span>
|
||||
{{ `${data.detail.descriptor.actor}`.split(",")[0] + " " + `${data.detail.descriptor.actor}`.split(",")[1] + " " + `${data.detail.descriptor.actor}`.split(",")[2] }}
|
||||
</p>
|
||||
<p><span>上映:</span> {{ data.detail.descriptor.releaseDate }}</p>
|
||||
<p><span>地区:</span> {{ data.detail.descriptor.area }}</p>
|
||||
<p v-if="data.detail.descriptor.remark"><span>连载:</span>{{ data.detail.descriptor.remark }}</p>
|
||||
<p><span>评分:</span><b id="score">{{ data.detail.descriptor.dbScore }}</b></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt_content">
|
||||
<p v-html="`${data.detail.descriptor.content}`.replaceAll(' ', '')"></p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- pc端title-->
|
||||
<div class="title hidden-sm-and-down ">
|
||||
<a class="picture" href="" :style="{backgroundImage: `url('${data.detail.picture}')`}"></a>
|
||||
<h2>{{ data.detail.name }}</h2>
|
||||
<ul class="tags">
|
||||
<li class="t_c">
|
||||
<el-icon>
|
||||
<Promotion/>
|
||||
</el-icon>
|
||||
{{ data.detail.descriptor.cName }}
|
||||
</li>
|
||||
<li>{{ `${data.detail.descriptor.classTag}`.replaceAll(",", " ") }}</li>
|
||||
<li>{{ data.detail.descriptor.year }}</li>
|
||||
<li>{{ data.detail.descriptor.area }}</li>
|
||||
</ul>
|
||||
<p><span>导演:</span> {{ data.detail.descriptor.director }}</p>
|
||||
<p><span>主演:</span> {{ data.detail.descriptor.actor }}</p>
|
||||
<p><span>上映:</span> {{ data.detail.descriptor.releaseDate }}</p>
|
||||
<p v-if="data.detail.descriptor.remark"><span>连载:</span>{{ data.detail.descriptor.remark }}</p>
|
||||
<p><span>评分:</span><b id="score">{{ data.detail.descriptor.dbScore }}</b></p>
|
||||
<div class="cus_wap">
|
||||
<p style="min-width: 40px"><span>剧情:</span></p>
|
||||
<p ref="textContent" class="text_content">
|
||||
<el-button v-if="`${data.detail.descriptor.content}`.length > 120" class="multi_text"
|
||||
style="color:#a574b7;"
|
||||
@click="showContent(multiBtn.state)" link>{{ multiBtn.text }}
|
||||
</el-button>
|
||||
<span class="cus_info" v-html="`${data.detail.descriptor.content}`.replaceAll(' ', '')"></span>
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
<el-button type="warning" class="player" size="large" @click="play({episode:0,source:0})" round>
|
||||
<el-icon>
|
||||
<CaretRight/>
|
||||
</el-icon>
|
||||
立即播放
|
||||
</el-button>
|
||||
</p>
|
||||
</div>
|
||||
<div class="play_list">
|
||||
<h2 class="hidden-md-and-down">播放列表:(右侧切换播放源)</h2>
|
||||
<el-tabs type="card" class="plya_tabs" tab-transition="fade" tab-animation="300" lazy>
|
||||
<el-tab-pane v-for="(p,i) in data.detail.playList" :label="`播放地址${i+1}`" >
|
||||
<div class="play_content">
|
||||
<a v-for="(item,index) in p" href="javascript:;"
|
||||
@click="play({source: i, episode: index})">{{ item.episode }}</a>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<div class="correlation">
|
||||
<RelateList :relate-list="data.relate" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {useRouter} from "vue-router";
|
||||
import {onMounted, reactive, ref,} from "vue";
|
||||
import {ApiGet} from "../../utils/request";
|
||||
import {ElMessage} from 'element-plus'
|
||||
import {Promotion, CaretRight} from "@element-plus/icons-vue";
|
||||
import RelateList from "../../components/RelateList.vue";
|
||||
const show = ref(false)
|
||||
|
||||
// 获取路由对象
|
||||
const router = useRouter()
|
||||
|
||||
const data = reactive({
|
||||
detail: {descriptor: {}},
|
||||
relate: [],
|
||||
})
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
let link = router.currentRoute.value.query.link
|
||||
ApiGet('/filmDetail', {id: link}).then((resp: any) => {
|
||||
if (resp.status === "ok") {
|
||||
data.detail = resp.data.detail
|
||||
data.relate = resp.data.relate
|
||||
} else {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
dangerouslyUseHTMLString: true,
|
||||
message: resp.message,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
// 选集播放点击事件
|
||||
const play = (change: { source: number, episode: number }) => {
|
||||
router.push({path: `/play`, query: {id: `${router.currentRoute.value.query.link}`, ...change}})
|
||||
}
|
||||
|
||||
// 内容展开收起效果
|
||||
const multiBtn = ref({state: false, text: '展开'})
|
||||
const textContent = ref()
|
||||
const showContent = (flag: boolean) => {
|
||||
if (flag) {
|
||||
multiBtn.value = {state: !flag, text: '展开'}
|
||||
textContent.value.style.webkitLineClamp = 2
|
||||
return
|
||||
}
|
||||
multiBtn.value = {state: !flag, text: '收起'}
|
||||
textContent.value.style.webkitLineClamp = 8
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<!--移动端适配-->
|
||||
<style>
|
||||
@media (max-width: 650px) {
|
||||
.title_mt {
|
||||
padding: 0 3px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-flow: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.picture_mt {
|
||||
width: 100%;
|
||||
height: 175px;
|
||||
margin-right: 12px;
|
||||
border-radius: 8px;
|
||||
background-size: cover;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.title_mt_right {
|
||||
flex: 1.8;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.title_mt_right h3 {
|
||||
margin: 0 0 5px 0;
|
||||
}
|
||||
|
||||
.title_mt_right p {
|
||||
font-size: 12px;
|
||||
margin: 3px 2px;
|
||||
}
|
||||
|
||||
.mt_content {
|
||||
margin-top: 5px;
|
||||
border-top: 1px solid #777777;
|
||||
border-bottom: 1px solid #777777;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.mt_content p {
|
||||
font-size: 12px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
.correlation {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.film {
|
||||
width: 100%;
|
||||
padding: 0 1%;
|
||||
}
|
||||
|
||||
/*影片播放列表信息展示*/
|
||||
.play_list {
|
||||
width: 100%;
|
||||
border-radius: 10px;
|
||||
background: #2e2e2e;
|
||||
margin-top: 50px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.play_content {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
padding: 20px 10px 20px 18px;
|
||||
|
||||
}
|
||||
|
||||
.play_list > h2 {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: -10px;
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
.play_content a {
|
||||
font-size: 12px;
|
||||
min-width: 65px;
|
||||
padding: 6px 15px;
|
||||
color: #ffffff;
|
||||
border-radius: 6px;
|
||||
margin: 8px 8px;
|
||||
background: #888888;
|
||||
}
|
||||
|
||||
.plya_tabs {
|
||||
background: #2e2e2e;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__nav-scroll) {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__header) {
|
||||
/*border-bottom: 1px solid #888888!important;*/
|
||||
margin-bottom: 0;
|
||||
border-bottom: none !important;
|
||||
background: rgb(34, 34, 34);
|
||||
height: 65px !important;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__nav) {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__item.is-active) {
|
||||
color: #ee9600;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__item:hover) {
|
||||
color: orange;
|
||||
background: #484646;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__item) {
|
||||
height: 65px;
|
||||
line-height: 65px;
|
||||
margin-left: 2px;
|
||||
border-radius: 8px 8px 0 0;
|
||||
border: none !important;
|
||||
color: #ffffff;
|
||||
background: #2e2e2e;
|
||||
}
|
||||
|
||||
:deep(.el-tab-pane) {
|
||||
}
|
||||
|
||||
/*顶部影片信息显示区域*/
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
border-radius: 10px;
|
||||
background: #2e2e2e;
|
||||
padding: 5px 30px 30px 30px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.title > h2 {
|
||||
text-align: left;
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
.picture {
|
||||
position: absolute;
|
||||
width: 190px;
|
||||
height: 270px;
|
||||
right: 30px;
|
||||
top: 30px;
|
||||
border-radius: 8px;
|
||||
background-size: cover;
|
||||
|
||||
}
|
||||
|
||||
|
||||
.tags {
|
||||
list-style-type: none;
|
||||
display: flex;
|
||||
justify-content: left;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.tags > li {
|
||||
padding: 6px 10px;
|
||||
border-radius: 5px;
|
||||
background: rgba(66, 66, 66);
|
||||
margin: 0 8px;
|
||||
font-size: 12px;
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
.tags > .t_c {
|
||||
background: rgba(155, 73, 231, 0.72);
|
||||
color: #c4c2c2;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.title p {
|
||||
text-align: left;
|
||||
font-size: 14px;
|
||||
margin: 20px 0;
|
||||
max-width: 60%;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.title p span {
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
color: #888888;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
#score {
|
||||
color: #1cbeb9;
|
||||
}
|
||||
|
||||
.cus_wap {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.title .text_content {
|
||||
max-width: 70%;
|
||||
line-height: 22.5px;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
vertical-align: top;
|
||||
margin-top: 5px;
|
||||
|
||||
}
|
||||
|
||||
.text_content::before {
|
||||
content: '';
|
||||
float: right;
|
||||
width: 0; /*设置为0,或者不设置宽度*/
|
||||
height: calc(100% - 20px); /*先随便设置一个高度*/
|
||||
}
|
||||
|
||||
.text_content .cus_info {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
font-size: 15px !important;
|
||||
font-weight: normal;
|
||||
|
||||
}
|
||||
|
||||
|
||||
.multi_text {
|
||||
float: right;
|
||||
clear: both;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
247
client/src/views/index/Home.vue
Normal file
@@ -0,0 +1,247 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="content_item" v-for="item in data.info.content">
|
||||
<template v-if="item.nav.name !='综艺' & item.nav.name !='综艺片'">
|
||||
<el-row class="row-bg cus_nav" justify="space-between">
|
||||
<el-col :span="12" class="title">
|
||||
<span :class="`iconfont ${item.nav.name.search('电影') != -1?'icon-film':item.nav.name.search('剧') != -1?'icon-tv':'icon-cartoon'}`"
|
||||
style="color: #79bbff;font-size: 32px;margin-right: 10px; line-height: 130%" />
|
||||
<a :href="`/categoryFilm?pid=${item.nav.id}`">{{ item.nav.name }}</a>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<ul class="nav_ul">
|
||||
<li v-for="c in item.nav.children" class="nav_category hidden-md-and-down"><a
|
||||
:href="`/categoryFilm?pid=${c.pid}&cid=${c.id}`">{{ c.name }}</a></li>
|
||||
<li class=" hidden-md-and-down">更多 ></li>
|
||||
</ul>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row class="cus_content">
|
||||
<el-col :md="24" :lg="20" :xl="20" class="cus_content">
|
||||
<el-row style="max-width: 100%">
|
||||
<template v-for=" (m,i) in item.movies">
|
||||
<el-col :md="4" :sm="6" :xs="8" v-if="i <12" class="cus_content_item">
|
||||
<a :href="`/filmDetail?link=${m.id}`" class="cus_content_link"
|
||||
@error="handleImgError"
|
||||
:style="{backgroundImage: `url('${m.picture}')`}">
|
||||
<span class="cus_tag hidden-md-and-down">{{ m.year }}</span>
|
||||
<span class="cus_tag hidden-md-and-down">{{ m.cName }}</span>
|
||||
<span class="cus_tag hidden-md-and-down">{{ m.area }}</span>
|
||||
</a>
|
||||
<a :href="`/filmDetail?link=${m.id}`"
|
||||
class="content_text content_text_tag">{{ m.name }}</a>
|
||||
<span class="cus_remark">{{ m.remarks }}</span>
|
||||
</el-col>
|
||||
</template>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :md="0" :lg="4" :xl="4" class="hidden-md-and-down content_right">
|
||||
<template v-for="(m,i) in item.movies">
|
||||
<div class="content_right_item">
|
||||
<a :href="`/filmDetail?link=${m.id}`"><b class="top_item">{{ i + 1 + '.' }}</b>
|
||||
<span>{{ m.name }}</span></a>
|
||||
</div>
|
||||
</template>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import 'element-plus/theme-chalk/display.css'
|
||||
import {onBeforeMount, onMounted, reactive} from "vue";
|
||||
import {ApiGet} from "../../utils/request";
|
||||
|
||||
const data = reactive({
|
||||
info: {}
|
||||
})
|
||||
onBeforeMount(() => {
|
||||
ApiGet('/index').then((resp: any) => {
|
||||
data.info = resp.data
|
||||
})
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.content_item {
|
||||
padding: 10px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
text-align: left;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.title > a {
|
||||
min-width: 40px;
|
||||
color: rgb(221, 221, 221)
|
||||
}
|
||||
|
||||
a {
|
||||
color: #333;
|
||||
padding-top: 10px;
|
||||
text-decoration: none;
|
||||
outline: none;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
.cus_nav {
|
||||
border-bottom: 1px solid rgb(46, 46, 46);
|
||||
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.nav_ul {
|
||||
list-style-type: none;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: end;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.nav_category > a {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.nav_category > a:hover {
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.nav_ul > li {
|
||||
min-width: 60px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/*svg图标*/
|
||||
embed {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
margin-right: 8px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
/*影片简介区域*/
|
||||
.cus_content {
|
||||
display: flex;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.cus_content_link {
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
/*position: relative;*/
|
||||
padding-top: 125%;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.cus_tag {
|
||||
text-align: center;
|
||||
color: rgb(255, 255, 255);
|
||||
padding: 0 3px;
|
||||
margin: 0 0 10px 8px;
|
||||
background: rgba(0, 0, 0, 0.55);
|
||||
font-size: 12px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.content_text_tag {
|
||||
font-size: 15px !important;
|
||||
color: rgb(221, 221, 221);
|
||||
padding: 2px 10px 2px 2px !important;
|
||||
}
|
||||
|
||||
.cus_remark {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding-left: 3px;
|
||||
font-size: 12px;
|
||||
color: #999999;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.content_text {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 2px 10px 10px 2px;
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.content_right {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.content_right_item {
|
||||
display: flex;
|
||||
padding-left: 10px;
|
||||
border-bottom: 1px solid rgb(46, 46, 46);
|
||||
}
|
||||
|
||||
.content_right_item > a {
|
||||
padding: 10px 15px 10px 0;
|
||||
color: hsla(0, 0%, 100%, .87);
|
||||
display: block;
|
||||
flex-grow: 1;
|
||||
text-align: left;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
||||
:deep(.top_item) {
|
||||
color: red;
|
||||
/*font-style: oblique 10deg;*/
|
||||
font-style: italic;
|
||||
/*font-family: Inter;*/
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.content_right_item a span:hover {
|
||||
color: orange;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
<!--移动端修改-->
|
||||
<style scoped>
|
||||
@media (min-width: 650px) {
|
||||
.cus_content_item {
|
||||
padding: 10px;
|
||||
overflow: hidden;
|
||||
/*margin-bottom: 10px;*/
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 650px) {
|
||||
.cus_content_item {
|
||||
padding: 0 6px 0 0;
|
||||
margin-bottom: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.nav_ul {
|
||||
justify-content: end;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
355
client/src/views/index/Play.vue
Normal file
@@ -0,0 +1,355 @@
|
||||
<template>
|
||||
|
||||
<div class="player_area">
|
||||
<!-- 视频播放区域-->
|
||||
<div class="player_p">
|
||||
<iframe ref="iframe" class="player" :src="data.current.link"
|
||||
:name="data.detail.name"
|
||||
marginheight="0"
|
||||
marginwidth="0"
|
||||
framespacing="0"
|
||||
vspale="0"
|
||||
frameborder="0" allowfullscreen="true" scolling="no"
|
||||
sandbox="allow-scripts allow-same-origin allow-downloads">
|
||||
</iframe>
|
||||
</div>
|
||||
<div class="current_play_info">
|
||||
<div class="play_info_left">
|
||||
<h3 class="current_play_title">{{ `${data.detail.name} ${data.current.episode}` }}</h3>
|
||||
<div class="tags">
|
||||
<b>
|
||||
<el-icon>
|
||||
<Promotion/>
|
||||
</el-icon>
|
||||
{{ data.detail.descriptor.cName }}</b>
|
||||
<span>{{ data.detail.descriptor.classTag }}</span>
|
||||
<span>{{ data.detail.descriptor.year }}</span>
|
||||
<span>{{ data.detail.descriptor.area }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- 播放选集 -->
|
||||
<div class="play_list">
|
||||
<h2 class="hidden-md-and-down">播放列表:(右侧切换播放源)</h2>
|
||||
<el-tabs type="card" v-model="data.currentTabName" class="plya_tabs" @tab-change="changeSource">
|
||||
<el-tab-pane v-for="(p,i) in data.detail.playList"
|
||||
:name="`tab-${i}`"
|
||||
:label="`播放地址${i+1}`">
|
||||
<div class="play_content">
|
||||
<a v-for="(item,index) in p" href="javascript:void(false)" @click="playChange(item)"
|
||||
:class="data.current.link.search(item.link) !== -1?'play_active':''">{{ item.episode }}</a>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<div class="correlation">
|
||||
<RelateList :relate-list="data.relate"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
import {onMounted, reactive, ref, withDirectives} from "vue";
|
||||
import {useRouter} from "vue-router";
|
||||
import {ApiGet} from "../../utils/request";
|
||||
import RelateList from "../../components/RelateList.vue";
|
||||
import {Promotion} from "@element-plus/icons-vue";
|
||||
|
||||
// 播放页所需数据
|
||||
const data = reactive({
|
||||
detail: {descriptor: {}, playList: [[{episode: '', link: ''}]]},
|
||||
current: {episode: '', link: ''},
|
||||
currentTabName: '',
|
||||
currentPlayFrom: 0,
|
||||
currentEpisode: 0,
|
||||
relate: [],
|
||||
|
||||
})
|
||||
|
||||
// 获取路由信息
|
||||
const router = useRouter()
|
||||
onMounted(() => {
|
||||
let query = router.currentRoute.value.query
|
||||
ApiGet(`/filmPlayInfo`, {id: query.id, playFrom: query.source, episode: query.episode}).then((resp: any) => {
|
||||
if (resp.status === 'ok') {
|
||||
data.detail = resp.data.detail
|
||||
resp.data.current.link = converLink(resp.data.current.link)
|
||||
data.current = resp.data.current
|
||||
data.currentPlayFrom = resp.data.currentPlayFrom
|
||||
data.currentEpisode = resp.data.currentEpisode
|
||||
data.relate = resp.data.relate
|
||||
// 设置当前选中的播放源
|
||||
data.currentTabName = `tab-${query.source}`
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// ===============================视频播放处理=======================================
|
||||
// 视频解析接口地址, 默认使用第一个
|
||||
const resolver = [
|
||||
// m3u8使用此解析
|
||||
'https://jx.jsonplayer.com/player/?url=',
|
||||
// 'https://jx.m3u8.tv/jiexi/?url=',
|
||||
|
||||
|
||||
// 'https://jx.jsonplayer.com/player/?url=',
|
||||
// 'https://vip.bljiex.com/?url=',
|
||||
// 'https://jx.bozrc.com:4433/player/?url=',
|
||||
// html视频使用此解析
|
||||
'http://www.82190555.com/index/qqvod.php?url=',
|
||||
// 'https://jx.bozrc.com:4433/player/?url=',
|
||||
// 'https://vip.bljiex.com/?url=',
|
||||
|
||||
// Google上随便找的
|
||||
'https://vip.bljiex.com/?url=',
|
||||
'https://jx.kingtail.xyz/?url=',
|
||||
'http://www.82190555.com/index/qqvod.php?url=',
|
||||
'https://www.nxflv.com/?url=',
|
||||
'http://www.wmxz.wang/video.php?url=',
|
||||
'https://www.feisuplayer.com/m3u8/?url=',
|
||||
// tampermonkey 脚本使用的解析
|
||||
'https://jx.bozrc.com:4433/player/?url=',
|
||||
'https://z1.m1907.top/?jx=',
|
||||
'https://jx.aidouer.net/?url=',
|
||||
'https://www.gai4.com/?url=',
|
||||
'https://okjx.cc/?url=',
|
||||
'https://jx.rdhk.net/?v=',
|
||||
'https://jx.blbo.cc:4433/?url=',
|
||||
'https://jsap.attakids.com/?url=',
|
||||
'https://jx.dj6u.com/?url=',
|
||||
]
|
||||
|
||||
// 添加视频解析前缀
|
||||
const converLink = (link: string): string => {
|
||||
// 视频统一使用第三方解析
|
||||
if (link.search("m3u8") != -1) {
|
||||
return `${resolver[0] + link}`
|
||||
}
|
||||
// return `${resolver[1]+link}`
|
||||
return `${link}`
|
||||
}
|
||||
|
||||
// 点击播放对应影片
|
||||
const playChange = (info: { link: string, episode: string }) => {
|
||||
// 判断是否是m3u8播放器, 如果是则添加前缀
|
||||
data.current.link = converLink(info.link)
|
||||
data.current.episode = info.episode
|
||||
}
|
||||
// 点击播放源标签事件
|
||||
const changeSource = (tabName: any) => {
|
||||
data.currentTabName = tabName
|
||||
data.detail.playList.find((item, index) => {
|
||||
if (tabName.split("-")[1] - index == 0) {
|
||||
item.find(i => {
|
||||
if (i.episode == data.current.episode) {
|
||||
data.current.link = converLink(i.link)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 测试滑动音量调节
|
||||
const iframe = ref()
|
||||
// document.querySelector('#brightnessSlider').addEventListener('change', function() {
|
||||
// // 获取滑块的值
|
||||
// var brightness = this.value;
|
||||
//
|
||||
// // 设置亮度为滑块的值
|
||||
// iframe.style.filter = 'brightness(' + brightness + '%)';
|
||||
// })
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/*当前播放的影片信息展示*/
|
||||
.current_play_info {
|
||||
width: 100%;
|
||||
padding: 15px 5px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.current_play_title {
|
||||
font-weight: 500;
|
||||
color: rgb(201, 196, 196);
|
||||
margin: 0 0 5px 0;
|
||||
}
|
||||
|
||||
|
||||
/* 播放区域*/
|
||||
.player_area {
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
/*height: 1400px;*/
|
||||
/*background: red;*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: 650px) {
|
||||
.player_area {
|
||||
padding: 10px 6%;
|
||||
}
|
||||
|
||||
.tags b {
|
||||
padding: 5px 10px;
|
||||
background-color: rgba(155, 73, 231, 0.72);
|
||||
font-size: 13px;
|
||||
border-radius: 6px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.tags span {
|
||||
padding: 6px 12px;
|
||||
background-color: #404042;
|
||||
color: #b5b2b2;
|
||||
border-radius: 5px;
|
||||
margin: 0 8px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
.player_p {
|
||||
width: 100%;
|
||||
min-height: 200px;
|
||||
margin: 0;
|
||||
padding-bottom: 56.25% !important;
|
||||
/*padding-bottom: 42.25% !important;*/
|
||||
position: relative;
|
||||
background-image: url("/src/assets/image/play.png");
|
||||
background-size: cover;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border-radius: 6px;
|
||||
left: 0;
|
||||
width: 100%; /* 设置iframe元素的宽度为父容器的100% */
|
||||
height: 100%; /* 设置iframe元素的高度为0,以便自适应高度 */
|
||||
/*padding-bottom: 56.25%; !* 使用padding-bottom属性计算iframe元素的高度,这里假设视频的宽高比为16:9 *!*/
|
||||
/*border: none; !* 去除iframe元素的边框 *!*/
|
||||
/*transform: scale(1);*/
|
||||
position: absolute;
|
||||
|
||||
}
|
||||
|
||||
/*右侧播放源选择区域*/
|
||||
/*影片播放列表信息展示*/
|
||||
/*影片播放列表信息展示*/
|
||||
.play_list {
|
||||
width: 100%;
|
||||
border-radius: 10px;
|
||||
background: #2e2e2e;
|
||||
margin-top: 50px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.play_content {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
padding: 10px 10px 10px 18px;
|
||||
|
||||
}
|
||||
|
||||
.play_list > h2 {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: -10px;
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
.play_content a {
|
||||
font-size: 12px;
|
||||
min-width: 65px;
|
||||
padding: 6px 15px;
|
||||
color: #ffffff;
|
||||
border-radius: 6px;
|
||||
margin: 8px 8px;
|
||||
background: #888888;
|
||||
}
|
||||
|
||||
/*集数选中效果*/
|
||||
.play_active {
|
||||
color: orange !important;
|
||||
background: #424242 !important;
|
||||
}
|
||||
|
||||
.play_content .play_tabs {
|
||||
background: #2e2e2e;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__nav-scroll) {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__header) {
|
||||
/*border-bottom: 1px solid #888888!important;*/
|
||||
margin-bottom: 0;
|
||||
border-bottom: none !important;
|
||||
background: rgb(34, 34, 34);
|
||||
height: 50px !important;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__nav) {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__item.is-active) {
|
||||
color: #ee9600;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__item:hover) {
|
||||
color: orange;
|
||||
background: #484646;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__item) {
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
margin-left: 2px;
|
||||
border-radius: 8px 8px 0 0;
|
||||
border: none !important;
|
||||
color: #ffffff;
|
||||
background: #2e2e2e;
|
||||
}
|
||||
|
||||
/*推荐列表区域*/
|
||||
.correlation {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<!--移动端-->
|
||||
<style scoped>
|
||||
|
||||
/*适应小尺寸*/
|
||||
@media (max-width: 650px) {
|
||||
.player_area {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
.tags b {
|
||||
padding: 5px 10px;
|
||||
background-color: rgba(155, 73, 231, 0.72);
|
||||
font-size: 13px;
|
||||
border-radius: 6px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
.tags span {
|
||||
padding: 6px 10px;
|
||||
background-color: #404042;
|
||||
color: #b5b2b2;
|
||||
border-radius: 5px;
|
||||
margin: 0 3px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
459
client/src/views/index/SearchFilm.vue
Normal file
@@ -0,0 +1,459 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="search_group">
|
||||
<input v-model="data.search" placeholder="搜索 动漫,剧集,电影 " class="search"/>
|
||||
<el-button @click="searchMovie" :icon="Search" style="" />
|
||||
</div>
|
||||
<div v-if="data.list.length > 0 " class="search_res">
|
||||
<div class="title">
|
||||
<h2>{{ data.oldSearch }}</h2>
|
||||
<p>共找到{{ data.page.total }}部与"{{ data.oldSearch }}"相关的影视作品</p>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="film_item" v-for="m in data.list">
|
||||
<a :href="`/filmDetail?link=${m.id}`" :style="{backgroundImage: `url('${m.picture}')`}"></a>
|
||||
<div class="film_intro">
|
||||
<h3>{{ m.name }}</h3>
|
||||
<p class="tags">
|
||||
<span class="tag_c">{{ m.cName }}</span>
|
||||
<span>{{ m.year }}</span>
|
||||
<span>{{ m.area }}</span>
|
||||
</p>
|
||||
<p><em>导演:</em>{{ m.director }}</p>
|
||||
<p><em>主演:</em>{{ m.actor }}</p>
|
||||
<p class="blurb"><em>剧情:</em>{{ m.blurb.replaceAll(' ', '') }}</p>
|
||||
<el-button :icon="CaretRight" @click="play(m.id)">立即播放</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pagination_container">
|
||||
<el-pagination background layout="prev, pager, next"
|
||||
v-model:current-page="data.page.current"
|
||||
@current-change="changeCurrent"
|
||||
:pager-count="5"
|
||||
:background="true"
|
||||
:page-size="data.page.pageSize"
|
||||
:total="data.page.total"
|
||||
:prev-icon="ArrowLeftBold"
|
||||
:next-icon="ArrowRightBold"
|
||||
hide-on-single-page
|
||||
class="pagination"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-empty v-if="data.list.length == 0 " description="输入影片名称进行搜索"/>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
import {onMounted, reactive, watch} from "vue";
|
||||
import {useRoute, useRouter} from "vue-router";
|
||||
import {ApiGet} from "../../utils/request";
|
||||
import {ArrowLeftBold, ArrowRightBold, CaretRight, Search} from '@element-plus/icons-vue'
|
||||
import {ElMessage} from "element-plus";
|
||||
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const data = reactive({
|
||||
list: [],
|
||||
page: {
|
||||
current: 0,
|
||||
},
|
||||
oldSearch: '',
|
||||
search: '',
|
||||
})
|
||||
// 监听路由参数的变化
|
||||
watch(
|
||||
[route],
|
||||
(oldRoute, newRoute) => {
|
||||
refreshPage(router.currentRoute.value.query.search, router.currentRoute.value.query.current)
|
||||
},
|
||||
)
|
||||
|
||||
// 点击播放
|
||||
const play = (id: string | number) => {
|
||||
location.href = `/play?id=${id}&episode=0&source=0`
|
||||
}
|
||||
|
||||
// 搜索按钮事件
|
||||
const searchMovie = ()=>{
|
||||
if (data.search.length <=0) {
|
||||
ElMessage.error({message: '搜索信息不能为空', duration:1000})
|
||||
return
|
||||
}
|
||||
location.href = location.href = `/search?search=${data.search}`
|
||||
}
|
||||
|
||||
// 执行搜索请求
|
||||
const refreshPage = (keyword: any, current: any) => {
|
||||
ApiGet('/searchFilm', {keyword: keyword, current: current}).then((resp: any) => {
|
||||
data.list = resp.data.list
|
||||
data.page = resp.data.page
|
||||
data.oldSearch = keyword
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (router.currentRoute.value.query.search == null) {
|
||||
return
|
||||
}
|
||||
refreshPage(router.currentRoute.value.query.search + '', router.currentRoute.value.query.current)
|
||||
})
|
||||
// 分页器
|
||||
const changeCurrent = (currentVal: number) => {
|
||||
let query = router.currentRoute.value.query
|
||||
location.href = `/search?search=${query.search}¤t=${currentVal}`
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<!--移动端-->
|
||||
<style scoped>
|
||||
@media (max-width: 650px) {
|
||||
.title h2 {
|
||||
margin: 8px auto;
|
||||
}
|
||||
.film_item {
|
||||
flex-basis: calc(100% - 20px);
|
||||
margin: 0 10px;
|
||||
display: flex;
|
||||
background: #2e2e2e;
|
||||
padding: 10px;
|
||||
min-height: 180px;
|
||||
max-height: 200px;
|
||||
border-radius: 16px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
.film_item a {
|
||||
flex: 2;
|
||||
border-radius: 8px;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.film_intro {
|
||||
max-width: 60%;
|
||||
margin-left: 10px;
|
||||
flex: 3;
|
||||
text-align: left;
|
||||
padding: 0 10px;
|
||||
font-size: 15px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.film_intro h3 {
|
||||
font-size: 16px;
|
||||
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.film_item h3, p, button {
|
||||
margin: 2px 0 2px 0;
|
||||
}
|
||||
|
||||
.film_item p {
|
||||
max-width: 90%;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
font-size: 13px;
|
||||
|
||||
}
|
||||
|
||||
.film_item p em {
|
||||
font-weight: bold;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.film_item button {
|
||||
background-color: orange;
|
||||
border-radius: 20px;
|
||||
border: none !important;
|
||||
color: #ffffff;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
margin-bottom: 2px;
|
||||
bottom: 0;
|
||||
}
|
||||
.blurb{
|
||||
display: none!important;
|
||||
}
|
||||
.tags {
|
||||
display: flex;
|
||||
width: 90%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.tags .tag_c{
|
||||
background: rgba(155, 73, 231, 0.72);
|
||||
}
|
||||
.tags span {
|
||||
border-radius: 5px;
|
||||
padding: 3px 5px;
|
||||
background: rgba(66, 66, 66);
|
||||
color: #c9c4c4;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.search_group {
|
||||
width: 80%;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
}
|
||||
.search {
|
||||
flex: 10;
|
||||
background-color: #2e2e2e!important;
|
||||
border: none!important;
|
||||
height: 40px;
|
||||
border-radius: 6px 0 0 6px;
|
||||
padding-left: 20px;
|
||||
color: #c9c4c4;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.search::placeholder{
|
||||
font-size: 15px;
|
||||
color: #999999;
|
||||
}
|
||||
.search:focus {
|
||||
outline: none;
|
||||
}
|
||||
.search_group button {
|
||||
flex: 1;
|
||||
margin: 0;
|
||||
background-color: #2e2e2e;
|
||||
color: rgba(155,73,231,0.72);
|
||||
border: none!important;
|
||||
height: 40px;
|
||||
border-radius: 0 8px 8px 0;
|
||||
font-size: 20px;
|
||||
/*margin-bottom: 2px*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
<!--pc端-->
|
||||
<style scoped>
|
||||
|
||||
.title {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.search_res {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: 650px) {
|
||||
.film_item {
|
||||
flex-basis: calc(50% - 18px);
|
||||
max-width: 50%;
|
||||
display: flex;
|
||||
background: #2e2e2e;
|
||||
padding: 16px;
|
||||
min-height: 250px;
|
||||
max-height: 280px;
|
||||
border-radius: 16px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
.film_item a {
|
||||
flex: 1;
|
||||
border-radius: 8px;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.film_intro {
|
||||
max-width: 75%;
|
||||
margin-left: 10px;
|
||||
flex: 3;
|
||||
/*flex-grow: 4;*/
|
||||
text-align: left;
|
||||
padding: 0 10px;
|
||||
font-size: 15px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.film_item h3, p, button {
|
||||
margin: 3px 0 12px 0;
|
||||
}
|
||||
|
||||
.film_item p {
|
||||
max-width: 90%;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.film_item p em {
|
||||
font-weight: bold;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.film_item button {
|
||||
background-color: orange;
|
||||
border-radius: 20px;
|
||||
border: none !important;
|
||||
color: #ffffff;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
margin-bottom: 2px;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.tags {
|
||||
display: flex;
|
||||
width: 90%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.tags .tag_c{
|
||||
background: rgba(155, 73, 231, 0.72);
|
||||
}
|
||||
.tags span {
|
||||
border-radius: 5px;
|
||||
padding: 3px 5px;
|
||||
background: rgba(66, 66, 66);
|
||||
color: #c9c4c4;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.search_group {
|
||||
width: 45%;
|
||||
margin: 20px auto;
|
||||
display: flex;
|
||||
}
|
||||
.search {
|
||||
flex: 10;
|
||||
background-color: #2e2e2e!important;
|
||||
border: none!important;
|
||||
height: 40px;
|
||||
border-radius: 6px 0 0 6px;
|
||||
padding-left: 20px;
|
||||
color: #c9c4c4;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.search::placeholder{
|
||||
font-size: 15px;
|
||||
color: #999999;
|
||||
}
|
||||
.search:focus {
|
||||
outline: none;
|
||||
}
|
||||
.search_group button {
|
||||
flex: 1;
|
||||
margin: 0;
|
||||
background-color: #2e2e2e;
|
||||
color: rgba(155,73,231,0.72);
|
||||
border: none!important;
|
||||
height: 40px;
|
||||
border-radius: 0 6px 6px 0;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
<!--分页器-->
|
||||
<style scoped>
|
||||
/*分页插件区域*/
|
||||
.pagination_container {
|
||||
width: 100%;
|
||||
margin-top: 30px;
|
||||
/*background: deepskyblue;*/
|
||||
text-align: center;
|
||||
/*display: flex;*/
|
||||
}
|
||||
|
||||
:deep(.el-pagination) {
|
||||
width: 100% !important;
|
||||
margin: 0 auto !important;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/*分页器样式修改*/
|
||||
:deep(.number) {
|
||||
font-weight: bold;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
background: #2e2e2e !important;
|
||||
color: #ffffff;
|
||||
border-radius: 50%;
|
||||
/*margin: 0 3px!important;*/
|
||||
}
|
||||
|
||||
:deep(.number:hover) {
|
||||
color: #67d9e8;
|
||||
}
|
||||
|
||||
:deep(.btn-prev) {
|
||||
font-weight: bold;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
background: #2e2e2e !important;
|
||||
color: #ffffff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
:deep(.btn-next) {
|
||||
font-weight: bold;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
background: #2e2e2e !important;
|
||||
color: #ffffff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
:deep(.more) {
|
||||
font-weight: bold;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
background: #2e2e2e !important;
|
||||
color: #ffffff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
:deep(.is-active) {
|
||||
background: #67d9e8 !important;
|
||||
}
|
||||
|
||||
/*移动端缩小*/
|
||||
@media (max-width: 650px) {
|
||||
:deep(.number) {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
:deep(.btn-prev) {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
:deep(.btn-next) {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
:deep(.more) {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
1
client/src/vite-env.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
||||