mirror of
https://github.com/ProudMuBai/GoFilm.git
synced 2026-06-12 21:33:10 +08:00
add pc film history test version v1
This commit is contained in:
2
client/components.d.ts
vendored
2
client/components.d.ts
vendored
@@ -21,6 +21,8 @@ declare module '@vue/runtime-core' {
|
|||||||
ElMain: typeof import('element-plus/es')['ElMain']
|
ElMain: typeof import('element-plus/es')['ElMain']
|
||||||
ElPagination: typeof import('element-plus/es')['ElPagination']
|
ElPagination: typeof import('element-plus/es')['ElPagination']
|
||||||
ElRow: typeof import('element-plus/es')['ElRow']
|
ElRow: typeof import('element-plus/es')['ElRow']
|
||||||
|
ElTimeline: typeof import('element-plus/es')['ElTimeline']
|
||||||
|
ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem']
|
||||||
FilmList: typeof import('./src/components/FilmList.vue')['default']
|
FilmList: typeof import('./src/components/FilmList.vue')['default']
|
||||||
Footer: typeof import('./src/components/Footer.vue')['default']
|
Footer: typeof import('./src/components/Footer.vue')['default']
|
||||||
Header: typeof import('./src/components/Header.vue')['default']
|
Header: typeof import('./src/components/Header.vue')['default']
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
<meta name="referrer" content="never">
|
<meta name="referrer" content="never">
|
||||||
<meta charset="UTF-8"/>
|
<meta charset="UTF-8"/>
|
||||||
<title>(╥﹏╥)</title>
|
<title>(╥﹏╥)</title>
|
||||||
<link rel="stylesheet" href="//at.alicdn.com/t/c/font_3992367_defpgksecpb.css">
|
<!--<link rel="stylesheet" href="//at.alicdn.com/t/c/font_3992367_defpgksecpb.css">-->
|
||||||
|
<link rel="stylesheet" href="//at.alicdn.com/t/c/font_3992367_v6qebj1yids.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|||||||
@@ -11,18 +11,40 @@
|
|||||||
</div>
|
</div>
|
||||||
<!--右侧顶级分类导航 -->
|
<!--右侧顶级分类导航 -->
|
||||||
<div class="nav_right">
|
<div class="nav_right">
|
||||||
<el-link :underline="false" href="/">首页</el-link>
|
<a href="/">首页</a>
|
||||||
<el-link :underline="false" :href="`/filmClassify?Pid=${nav.film.id}`">电影</el-link>
|
<a :href="`/filmClassify?Pid=${nav.film.id}`">电影</a>
|
||||||
<el-link :underline="false" :href="`/filmClassify?Pid=${nav.tv.id}`">剧集</el-link>
|
<a :href="`/filmClassify?Pid=${nav.tv.id}`">剧集</a>
|
||||||
<el-link :underline="false" :href="`/filmClassify?Pid=${nav.cartoon.id}`">动漫</el-link>
|
<a :href="`/filmClassify?Pid=${nav.cartoon.id}`">动漫</a>
|
||||||
<el-link :underline="false" :href="`/filmClassify?Pid=${nav.variety.id}`">综艺</el-link>
|
<a :href="`/filmClassify?Pid=${nav.variety.id}`">综艺</a>
|
||||||
|
|
||||||
|
<div class="history-link hidden-md-and-down" v-on:mouseenter="handleHistory(true)" v-on:mouseleave="handleHistory(false)">
|
||||||
|
<a :href="`/filmClassify?Pid=${nav.variety.id}`">
|
||||||
|
<b style="font-size: 22px;" class="iconfont icon-lishijilu"/>
|
||||||
|
</a>
|
||||||
|
<Transition name="fade-slide" duration="300">
|
||||||
|
<div v-if="data.historyFlag" class="dropdown-container">
|
||||||
|
<div class="history-h">
|
||||||
|
<b class="iconfont icon-lishijilu1 history-h-icon" />
|
||||||
|
<span class="history-h-title">历史观看记录</span>
|
||||||
|
</div>
|
||||||
|
<div class="history-c">
|
||||||
|
<a :href="h.link" class="history-c-item" v-for="h in data.historyList" >
|
||||||
|
<span class="history-c-item-t">{{ h.name }}
|
||||||
|
</span>
|
||||||
|
<span class="history-c-item-e">{{h.episode}}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Transition>
|
||||||
|
</div>
|
||||||
<!-- <span style="color:#777; font-weight: bold">|</span>-->
|
<!-- <span style="color:#777; font-weight: bold">|</span>-->
|
||||||
<el-link href="/search" class="hidden-md-and-up" :underline="false">
|
<a href="/search" class="hidden-md-and-up" :underline="false">
|
||||||
<el-icon style="font-size: 18px">
|
<el-icon style="font-size: 18px">
|
||||||
<Search/>
|
<Search/>
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</el-link>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
<!--弹窗模块,显示按钮对应信息-->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
@@ -33,9 +55,30 @@ import {useRouter} from "vue-router";
|
|||||||
import {Search, CircleClose} from '@element-plus/icons-vue'
|
import {Search, CircleClose} from '@element-plus/icons-vue'
|
||||||
import {ElMessage} from "element-plus";
|
import {ElMessage} from "element-plus";
|
||||||
import {ApiGet} from "../utils/request";
|
import {ApiGet} from "../utils/request";
|
||||||
|
import {cookieUtil,COOKIE_KEY_MAP} from "../utils/cookie";
|
||||||
//
|
// 搜索关键字
|
||||||
const keyword = ref<string>('')
|
const keyword = ref<string>('')
|
||||||
|
// 弹窗隐藏显示
|
||||||
|
const data = reactive({
|
||||||
|
historyFlag: false,
|
||||||
|
historyList: [{}],
|
||||||
|
})
|
||||||
|
//
|
||||||
|
const handleHistory = (flag:boolean)=>{
|
||||||
|
data.historyFlag = flag
|
||||||
|
if (flag) {
|
||||||
|
// 获取cookie中的filmHistory
|
||||||
|
let historyMap = cookieUtil.getCookie(COOKIE_KEY_MAP.FILM_HISTORY)?JSON.parse(cookieUtil.getCookie(COOKIE_KEY_MAP.FILM_HISTORY)):null
|
||||||
|
let arr = []
|
||||||
|
if (historyMap) {
|
||||||
|
for (let k in historyMap) {
|
||||||
|
arr.push(historyMap[k])
|
||||||
|
}
|
||||||
|
arr.sort((item1,item2)=> item2.timeStamp-item1.timeStamp)
|
||||||
|
}
|
||||||
|
data.historyList = arr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 从父组件获取当前路由对象
|
// 从父组件获取当前路由对象
|
||||||
@@ -69,11 +112,11 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--移动端适配-->
|
<!--移动端适配-->
|
||||||
<style>
|
<style>
|
||||||
/*小尺寸时隐藏状态栏*/
|
/*小尺寸时隐藏状态栏*/
|
||||||
@@ -114,6 +157,136 @@ onMounted(() => {
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.history-c {
|
||||||
|
max-height: 200px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
padding-top: 12px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
}
|
||||||
|
.history-c .history-c-item{
|
||||||
|
display: flex;
|
||||||
|
justify-content:space-between;
|
||||||
|
margin: 0 auto;
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-c-item::before{
|
||||||
|
content: '';
|
||||||
|
height: 10px;
|
||||||
|
width: 10px;
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
left: 22px;
|
||||||
|
border: 2px solid orangered;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
top: 15px;
|
||||||
|
}
|
||||||
|
.history-c-item::after{
|
||||||
|
content: '';
|
||||||
|
border-left: 1px solid #dbdee2;
|
||||||
|
position: absolute;
|
||||||
|
left: 28px;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
.history-c-item:hover:before{
|
||||||
|
content: '';
|
||||||
|
height: 10px;
|
||||||
|
width: 10px;
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
left: 22px;
|
||||||
|
border: 2px solid orangered;
|
||||||
|
background: #DC3BB6FF;
|
||||||
|
border-radius: 50%;
|
||||||
|
top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.history-c-item .history-c-item-t{
|
||||||
|
width: 100%;
|
||||||
|
text-align: left!important;
|
||||||
|
position: relative;
|
||||||
|
padding: 5px 5px 2px 55px;
|
||||||
|
margin: 0 10px;
|
||||||
|
flex: 2;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
-o-text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.history-c-item-e{
|
||||||
|
flex: 1;
|
||||||
|
color: rgba(255,255,255,0.38);
|
||||||
|
padding: 5px 0 2px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*历史记录标题域*/
|
||||||
|
.history-h {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: start;
|
||||||
|
border-bottom: 2px solid rgba(255,255,255,.15);
|
||||||
|
}
|
||||||
|
.history-h-icon{
|
||||||
|
flex: 1;
|
||||||
|
font-size: 24px;
|
||||||
|
color: orangered;
|
||||||
|
}
|
||||||
|
.history-h-icon::before{
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
.history-h-title{
|
||||||
|
flex: 4;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav_right a{
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-container{
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 50%;
|
||||||
|
font-size: 14px;
|
||||||
|
color: rgba(255,255,255,0.38);
|
||||||
|
margin-top: 12px;
|
||||||
|
min-width: 300px;
|
||||||
|
max-width: 330px;
|
||||||
|
height: auto;
|
||||||
|
z-index: 1000;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
background: rgba(0,0,0,0.85);
|
||||||
|
transform: translate3d(-50%,0,0);
|
||||||
|
|
||||||
|
}
|
||||||
|
.history-link{
|
||||||
|
position: relative;
|
||||||
|
min-width: 60px;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
margin: 10px 10px;
|
||||||
|
font-size: 15px;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-slide-enter-active,
|
||||||
|
.fade-slide-leave-active {
|
||||||
|
transition: all 0.8s linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-slide-enter,
|
||||||
|
.fade-slide-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translate3d(-50%,-10px,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
@@ -189,10 +362,10 @@ onMounted(() => {
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav_right a {
|
.nav_right> a {
|
||||||
min-width: 60px;
|
min-width: 60px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
line-height: 60px;
|
line-height: 40px;
|
||||||
margin: 10px 10px;
|
margin: 10px 10px;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|||||||
47
client/src/utils/cookie.ts
Normal file
47
client/src/utils/cookie.ts
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
const COOKIE_KEY_MAP = {
|
||||||
|
'FILM_HISTORY':'filmHistory'
|
||||||
|
}
|
||||||
|
|
||||||
|
const cookieUtil =
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 设置cookie值
|
||||||
|
* cname string cookie名称
|
||||||
|
* value any cookie值
|
||||||
|
* expire cookie保存天数
|
||||||
|
*/
|
||||||
|
setCookie(name: string, value: any, expire = 30) {
|
||||||
|
let d = new Date();
|
||||||
|
d.setTime(d.getTime() + (expire * 24 * 60 * 60 * 1000));
|
||||||
|
let expires = "expires=" + d.toUTCString();
|
||||||
|
document.cookie = name + "=" + encodeURIComponent(value) + "; " + expires + ': path=/';
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 获取cookie值
|
||||||
|
* name string cookie名称
|
||||||
|
*/
|
||||||
|
getCookie(name: string) {
|
||||||
|
let cookies = document.cookie.split('; ');
|
||||||
|
for (let i = 0; i < cookies.length; i++) {
|
||||||
|
let [k,v] = cookies[i].split("=")
|
||||||
|
if (k == name) {
|
||||||
|
return decodeURIComponent(v)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
*清除cookie值
|
||||||
|
* name string cookie名称
|
||||||
|
* 将expire 设置为已过期的时间
|
||||||
|
*/
|
||||||
|
clearCookie(name: string) {
|
||||||
|
let d = new Date();
|
||||||
|
d.setTime(-1);
|
||||||
|
let expires = "expires=" + d.toUTCString();
|
||||||
|
document.cookie = name + "=''; " + expires;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
export {cookieUtil, COOKIE_KEY_MAP};
|
||||||
@@ -48,6 +48,7 @@
|
|||||||
<div class="play-list">
|
<div class="play-list">
|
||||||
<div class="play-list-item" v-show="data.currentTabIndex == i" v-for="(l,i) in data.detail.playList">
|
<div class="play-list-item" v-show="data.currentTabIndex == i" v-for="(l,i) in data.detail.playList">
|
||||||
<a :class="`play-link ${item.link == data.current.link?'play-link-active':''}`" v-for="(item,index) in l"
|
<a :class="`play-link ${item.link == data.current.link?'play-link-active':''}`" v-for="(item,index) in l"
|
||||||
|
|
||||||
href="javascript:;"
|
href="javascript:;"
|
||||||
@click="playChange({sourceIndex: i, episodeIndex: index, target: this})">{{ item.episode }}</a>
|
@click="playChange({sourceIndex: i, episodeIndex: index, target: this})">{{ item.episode }}</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -59,17 +60,17 @@
|
|||||||
<RelateList :relateList="data.relate"/>
|
<RelateList :relateList="data.relate"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {computed, onBeforeMount, onMounted, reactive, ref, withDirectives} from "vue";
|
import {computed, onBeforeMount, onMounted, reactive, ref, watchEffect, withDirectives} from "vue";
|
||||||
import {useRouter} from "vue-router";
|
import {useRouter} from "vue-router";
|
||||||
import {ApiGet} from "../../utils/request";
|
import {ApiGet} from "../../utils/request";
|
||||||
import {ElMessage} from "element-plus";
|
import {ElMessage} from "element-plus";
|
||||||
import RelateList from "../../components/RelateList.vue";
|
import RelateList from "../../components/RelateList.vue";
|
||||||
import {Promotion} from "@element-plus/icons-vue";
|
import {Promotion} from "@element-plus/icons-vue";
|
||||||
import posterImg from '../../assets/image/play.png'
|
import posterImg from '../../assets/image/play.png'
|
||||||
|
import {cookieUtil,COOKIE_KEY_MAP} from '../../utils/cookie'
|
||||||
// 引入视频播放器组件
|
// 引入视频播放器组件
|
||||||
import {VideoPlayer} from '@videojs-player/vue'
|
import {VideoPlayer} from '@videojs-player/vue'
|
||||||
import 'video.js/dist/video-js.css'
|
import 'video.js/dist/video-js.css'
|
||||||
@@ -165,6 +166,7 @@ const playChange = (play: { sourceIndex: number, episodeIndex: number, target: a
|
|||||||
data.options.title = data.detail.name + " " + currPlay.episode
|
data.options.title = data.detail.name + " " + currPlay.episode
|
||||||
data.currentPlayFrom = play.sourceIndex
|
data.currentPlayFrom = play.sourceIndex
|
||||||
data.currentTabIndex = play.sourceIndex
|
data.currentTabIndex = play.sourceIndex
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// player相关事件
|
// player相关事件
|
||||||
@@ -231,6 +233,17 @@ const handleBtn = (e: any) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 监听播放url的变化, 触发历史记录的更新
|
||||||
|
watchEffect(()=>{
|
||||||
|
//将被点击的影片信息加入本地的观看历史中, 先获取cookie,已存在则追加,否则添加
|
||||||
|
if (data.options.src.length >0) {
|
||||||
|
let historys = cookieUtil.getCookie(COOKIE_KEY_MAP.FILM_HISTORY)? JSON.parse(cookieUtil.getCookie(COOKIE_KEY_MAP.FILM_HISTORY)) : {}
|
||||||
|
let link = `/play?id=${data.detail.id}&source=${data.currentPlayFrom}&episode=${data.currentEpisode}`
|
||||||
|
historys[data.detail.id] = { name:data.detail.name, link: link, episode: data.current.episode, timeStamp: (new Date()).valueOf()}
|
||||||
|
cookieUtil.setCookie(COOKIE_KEY_MAP.FILM_HISTORY, JSON.stringify(historys))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
Reference in New Issue
Block a user