Compare commits

...

69 Commits

Author SHA1 Message Date
haiyangcui
ef874d1831 v2.6.1 2020-11-01 18:36:08 +01:00
haiyangcui
bb9a8ca65d 获取其他源时,排除当前源 2020-11-01 18:03:33 +01:00
haiyangcui
747abf3b26 设置密码对话框的宽度 2020-11-01 17:41:20 +01:00
haiyangcui
1078cf3c63 修复自动更新功能 2020-11-01 17:29:57 +01:00
haiyangcui
22b877b0fb 定义不同的waterfall的ref 2020-11-01 17:24:29 +01:00
haiyangcui
34e6b8bd08 更新推荐 2020-11-01 14:02:11 +01:00
haiyangcui
4d039e9a63 更新推荐后刷新分类过滤数据 2020-11-01 14:01:48 +01:00
haiyangcui
16f3954959 删除无用的style 2020-11-01 12:17:20 +01:00
haiyangcui
17845e6ab4 改进换源功能,在新源中打开当前剧集和时间进度 2020-11-01 12:07:54 +01:00
hunlongyu
292f932130 Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player 2020-11-01 15:29:24 +08:00
hunlongyu
127ef9ad43 ⛸ 设置界面样式微调 2020-11-01 15:26:31 +08:00
cuiocean
11f0ae27fd v2.6.0 2020-11-01 08:22:24 +01:00
hunlongyu
2599343943 样式优化, 修复film table 错误提示 2020-11-01 14:57:49 +08:00
haiyangcui
0fb5903416 v2.5.9 2020-10-31 22:56:40 +01:00
haiyangcui
ce89720c55 调换收藏页面'源站'列的位置 2020-10-31 22:51:37 +01:00
haiyangcui
8ff7fa588a 恢复el-table滚动条 2020-10-31 22:45:19 +01:00
haiyangcui
8d5bbedfd8 解决el-table刷新自动跳到顶端的问题 2020-10-31 22:40:52 +01:00
haiyangcui
713e0affae 更新推荐 2020-10-31 22:31:25 +01:00
haiyangcui
0f55f3b2ea 显示推荐视频总数 2020-10-31 22:12:58 +01:00
haiyangcui
c98e41201d 不显示导演信息,有时导演名字字符太多 2020-10-31 22:12:45 +01:00
haiyangcui
2cfd31806d 修复搜索后打开详情页错误的问题 2020-10-31 22:06:33 +01:00
haiyangcui
d54dab4e90 改进豆瓣评分样式 2020-10-31 22:04:25 +01:00
haiyangcui
2af85fbfd1 Film页面,列表视图用el-table实现,感谢buvta贡献 2020-10-31 21:44:05 +01:00
haiyangcui
15c542db82 Film页面搜索用el-table实现 2020-10-31 21:34:32 +01:00
haiyangcui
1a3ccaa3ba 统一editsite页面的格式 2020-10-31 21:23:55 +01:00
haiyangcui
3d01fd045f 统一优化listpage格式 2020-10-31 12:28:36 +01:00
haiyangcui
f6636a7864 重置软件也受密码保护 2020-10-30 23:06:24 +01:00
haiyangcui
dd108d3b09 避免不必要的刷新 2020-10-30 18:27:04 +01:00
haiyangcui
0b24ded61f 同步时,如果没有更新,不再提示 2020-10-30 18:17:13 +01:00
haiyangcui
d21494cf86 集中在style中定义pictureView的格式 2020-10-30 18:13:12 +01:00
haiyangcui
76add8f87a "编辑源"可以设置密码 2020-10-30 17:48:10 +01:00
haiyangcui
5a115700e3 收藏视图添加有更新提示,优化格式 2020-10-30 15:16:05 +01:00
haiyangcui
16e8ef2c4a 收藏页面播放,无需再查看历史记录,收藏数据已包含 2020-10-30 13:52:09 +01:00
haiyangcui
483449aad8 v2.5.8 2020-10-30 11:52:31 +01:00
haiyangcui
2b7a425f6f 影视推荐位置上移,更靠近Film页面 2020-10-30 11:50:17 +01:00
haiyangcui
a06c9e9d32 缩小地区和类型的按钮大小 2020-10-30 11:28:35 +01:00
haiyangcui
32a21952a2 推荐页面,视图添加地区信息 2020-10-30 11:25:47 +01:00
haiyangcui
ff01abe88c 改进推荐页面的过滤功能 2020-10-30 11:22:09 +01:00
haiyangcui
962f6b46c3 推荐页面,支持地区,类型的过滤 2020-10-30 10:58:31 +01:00
haiyangcui
b16604add6 更新推荐列表 2020-10-30 10:03:47 +01:00
haiyangcui
3028939ed9 改进豆瓣评分获取的算法 2020-10-30 09:43:04 +01:00
haiyangcui
1ffcb38b4b 优化'豆瓣评分'样式 2020-10-30 09:11:12 +01:00
Hunlongyu
2ec05b6ab5 🎳 移除request, 使用已有同样功能的axios重写.优化豆瓣评分样式 2020-10-30 10:05:45 +08:00
Hunlongyu
9cbd37d143 Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player into master 2020-10-30 09:30:59 +08:00
Hunlongyu
b9ab1b11f4 🎱 关闭有可能导致安全软件报警的代码 2020-10-30 09:30:53 +08:00
haiyangcui
428f49a2e8 更新推荐电影 2020-10-29 23:50:29 +01:00
haiyangcui
2e8941c6cc 记录推荐页的视图模式 2020-10-29 23:12:40 +01:00
haiyangcui
91e2fc56b7 添加recommandation数据库,支持更新推荐 2020-10-29 22:55:14 +01:00
haiyangcui
e2b124e4ac 添加“影视推荐”页面 2020-10-29 21:51:34 +01:00
haiyangcui
6b37e3ebd5 定义pictureView样式并复用 2020-10-29 21:36:12 +01:00
haiyangcui
5dcdb6a410 记录sartViewMode 2020-10-29 18:29:23 +01:00
haiyangcui
5d41f783bc 统一海报视图的格式 2020-10-29 15:47:12 +01:00
haiyangcui
28ad8f3313 详情页面收藏的话,如果收藏已存在,更新收藏信息 2020-10-29 12:49:30 +01:00
haiyangcui
c475fbdf46 收藏视图页面添加豆瓣评分信息 2020-10-29 12:46:06 +01:00
Hunlongyu
ee622f88da 🏉 收藏新增海报模式. 2020-10-29 18:12:54 +08:00
haiyangcui
1b2461c423 Merge branch 'master' of https://github.com/Hunlongyu/ZY-Player 2020-10-29 10:10:37 +01:00
Hunlongyu
3044bfcbc4 🏈 mini 界面优化 2020-10-29 16:59:25 +08:00
haiyangcui
4038e5e6be Merge branch 'dev_improveStar' 2020-10-29 09:32:28 +01:00
haiyangcui
bea1ef4c73 收藏页面添加视图开关 2020-10-29 09:12:33 +01:00
Hunlongyu
7af9a6d76d 🏐 编辑源增加状态排序, 修复换源功能里源的标识问题. 优化搜索结果样式变形 2020-10-29 15:32:56 +08:00
Hunlongyu
2140d90a87 🏀 源编辑,加入单个源检测功能. 2020-10-29 14:45:46 +08:00
Hunlongyu
e86eef1b05 添加快捷键指南, 修复换源功能阻塞问题 2020-10-29 14:35:58 +08:00
haiyangcui
42dd8fe5e4 star添加豆瓣评分记录 2020-10-29 00:09:29 +01:00
haiyangcui
9fd8c60dd5 "获取豆瓣评分"功能到tools.js 2020-10-28 23:29:39 +01:00
haiyangcui
49c480061b 收藏数据里记录detail所有内容 2020-10-28 18:09:10 +01:00
hunlongyu
022b1f4090 紧急修复视频源检测bug, 以及增加手动更新提示。 2020-10-28 22:44:53 +08:00
hunlongyu
9c08a64524 💎 手动更新提示 2020-10-28 22:11:41 +08:00
hunlongyu
90ec848c11 v2.5.6 2020-10-28 21:45:48 +08:00
hunlongyu
82270a702f v2.5.5 2020-10-28 21:39:29 +08:00
26 changed files with 7554 additions and 615 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "zy",
"version": "2.5.4",
"version": "2.6.1",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",

View File

@@ -10,6 +10,7 @@
<History v-show="view === 'History'" />
<Setting v-show="view === 'Setting'" />
<EditSites v-if="view === 'EditSites'"/>
<Recommandation v-show="view === 'Recommandation'" />
</div>
<transition name="slide">
<Detail v-if="detail.show"/>
@@ -43,6 +44,9 @@ export default {
},
editSites () {
return this.$store.getters.getEditSites
},
recommandation () {
return this.$store.getters.recommandation
}
},
watch: {

View File

@@ -152,7 +152,7 @@
&.name{
flex: 1;
min-width: 100px;
white-space: nowrap;
overflow: hidden;
margin-left: 10px;
}
&.type{
@@ -209,47 +209,69 @@
width: calc(100% - 100px);
height: calc(100% - 60px);
border-radius: 5px;
.listpage-content{
height: 100%;
position: relative;
font-size: 1rem;
.listpage-header{
display: flex;
flex-direction: column;
.listpage-header{
height: 60px;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
z-index: 10;
.header-box{
height: 100%;
width: 100%;
height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
padding-left: 50px;
padding-right: 50px;
.el-button{
font-size: 1rem;
border: none;
&:hover{
cursor: pointer;
}
}
.is-loading:before {
background-color: none !important;
}
.el-input{
width: 200px;
}
.el-button{
font-size: 1rem;
border: none;
&:hover{
cursor: pointer;
}
}
.listpage-body{
height: calc(100% - 40px);
overflow-y: auto;
.is-loading:before {
background-color: none !important;
}
.el-input{
width: 200px;
}
}
.listpage-body{
height: calc(100% - 60px);
overflow-y: auto;
position: relative;
font-size: 1rem;
&::-webkit-scrollbar{
width: 5px;
height: 1px;
}
&::-webkit-scrollbar-thumb {
border-radius: 10px;
position: absolute;
}
&::-webkit-scrollbar-track {
border-radius: 10px;
position: absolute;
}
.show-table{
height: 100%;
width: 100%;
.el-table::before{
height: 0px;
}
.el-table{
height: 100%;
width: 100%;
overflow-y: auto;
overflow: hidden;
font-size: 1rem;
}
.el-table__body-wrapper{
height: 100%;
width: 100%;
&::-webkit-scrollbar{
width: 10px;
width: 5px;
height: 1px;
}
&::-webkit-scrollbar-thumb {
@@ -277,8 +299,98 @@
font-size: 1rem;
}
}
.show-picture{
height: 100%;
width: 100%;
padding: 10px;
.card{
border-radius: 6px;
overflow: hidden;
.img{
position: relative;
min-height: 40px;
img{
width: 100%;
height: auto;
cursor: pointer;
}
.rate{
position: absolute;
top: 3%;
right: -40%;
width: 100%;
background-color: #111111aa;
color:#2f90b9;
height: 30px;
line-height: 30px;
font-size: 14px;
font-weight: bolder;
text-align: center;
transform: rotate(45deg);
}
.update{
position: absolute;
top: 5%;
left: -40%;
width: 100%;
background-color: #68b88e;
color: #cdcdcd;
height: 30px;
line-height: 30px;
font-size: 14px;
text-align: center;
transform: rotate(-45deg);
}
.operate{
display: none;
position: absolute;
left: 0;
bottom: 0;
background-color: #111111aa;
width: 100%;
font-size: 13px;
.operate-wrap{
display: flex;
justify-content: space-between;
.o-play, .o-star, .o-share{
cursor: pointer;
display: inline-block;
width: 80px;
height: 36px;
text-align: center;
line-height: 36px;
color: #cdcdcd;
&:hover{
background-color: #111;
}
}
}
}
}
.name{
font-size: 16px;
padding: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
}
.info{
display: flex;
justify-content: space-between;
font-size: 12px;
padding: 10px;
}
&:hover{
.operate{
display: block;
}
}
}
}
}
}
// loading
.zy-loading{
width: 100%;

View File

@@ -170,23 +170,6 @@
}
}
}
.film{
.body{
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
.show-img{
color: var(--d-fc-1);
.card{
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--d-bsc-hover);
}
}
}
}
}
.play{
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
@@ -286,10 +269,6 @@
}
}
}
.star{
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
}
.setting{
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
@@ -355,11 +334,11 @@
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
}
// Page of list using el-table
// Page of list using table and picture
.listpage{
color: var(--d-fc-2);
.listpage-content{
.listpage-header{
.listpage-header{
border-bottom-color: var(--d-c-3);
.btn{
&:hover{
@@ -380,24 +359,25 @@
color: var(--d-fc-2);
}
}
}
.listpage-body{
color: var(--d-fc-1);
background-color: var(--d-bgc-1);
&:hover{
&::-webkit-scrollbar-thumb {
box-shadow: var(--d-bsc-scroll);
background: var(--d-c-5);
}
&::-webkit-scrollbar-track {
box-shadow: var(--d-bsc-scroll);
background: var(--d-bgc-1);
}
}
.listpage-body{
/* 设置el-table的样式*/
.show-table{
/* 设置el-table的样式*/
.el-table{
color: var(--d-fc-1);
background-color: var(--d-bgc-1);
}
.el-input{
input{
background-color: var(--d-bgc-2);
border: 1px solid var(--d-bgc-2);
color: var(--d-fc-1);
}
}
.el-table__header th, .el-table__header tr, .el-table__body td,.el-table__body th{
color: var(--d-fc-1);
background-color: var(--d-bgc-1);
border-bottom-color: var(--d-c-2);
}
.el-table__body-wrapper{
&:hover{
@@ -411,6 +391,18 @@
}
}
}
.el-input{
input{
background-color: var(--d-bgc-2);
border: 1px solid var(--d-bgc-2);
color: var(--d-fc-1);
}
}
.el-table__header th, .el-table__header tr, .el-table__body td,.el-table__body th{
color: var(--d-fc-1);
background-color: var(--d-bgc-1);
border-bottom-color: var(--d-c-2);
}
.el-table--enable-row-hover .el-table__body tr:hover>td{
background-color: var(--d-bgc-2);
}
@@ -421,6 +413,17 @@
}
}
}
.show-picture{
color: var(--d-fc-1);
.card{
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--d-bsc-hover);
}
}
}
}
}
}

View File

@@ -166,23 +166,6 @@
}
}
}
.film{
.body{
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
.show-img{
color: var(--g-fc-1);
.card{
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--g-bsc-hover);
}
}
}
}
}
.play{
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
@@ -282,10 +265,6 @@
}
}
}
.star{
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
}
.setting{
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
@@ -351,11 +330,10 @@
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
}
// Page of list using el-table
// Page of list using table and picture
.listpage{
color: var(--g-fc-2);
.listpage-content{
.listpage-header{
.listpage-header{
border-bottom-color: var(--g-c-3);
.btn{
&:hover{
@@ -376,24 +354,25 @@
color: var(--g-fc-2);
}
}
}
.listpage-body{
color: var(--g-fc-1);
background-color: var(--g-bgc-1);
&:hover{
&::-webkit-scrollbar-thumb {
box-shadow: var(--g-bsc-scroll);
background: var(--g-c-5);
}
&::-webkit-scrollbar-track {
box-shadow: var(--g-bsc-scroll);
background: var(--g-bgc-1);
}
}
.listpage-body{
/* 设置el-table的样式*/
.show-table{
/* 设置el-table的样式*/
.el-table{
color: var(--g-fc-1);
background-color: var(--g-bgc-1);
}
.el-input{
input{
background-color: var(--g-bgc-2);
border: 1px solid var(--g-bgc-2);
color: var(--g-fc-1);
}
}
.el-table__header th, .el-table__header tr, .el-table__body td,.el-table__body th{
color: var(--g-fc-1);
background-color: var(--g-bgc-1);
border-bottom-color: var(--g-c-2);
}
.el-table__body-wrapper{
&:hover{
@@ -407,6 +386,18 @@
}
}
}
.el-input{
input{
background-color: var(--g-bgc-2);
border: 1px solid var(--g-bgc-2);
color: var(--g-fc-1);
}
}
.el-table__header th, .el-table__header tr, .el-table__body td,.el-table__body th{
color: var(--g-fc-1);
background-color: var(--g-bgc-1);
border-bottom-color: var(--g-c-2);
}
.el-table--enable-row-hover .el-table__body tr:hover>td{
background-color: var(--g-bgc-2);
}
@@ -417,6 +408,17 @@
}
}
}
.show-picture{
color: var(--g-fc-1);
.card{
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--g-bsc-hover);
}
}
}
}
}
}

View File

@@ -166,23 +166,6 @@
}
}
}
.film{
.body{
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
.show-img{
color: var(--l-fc-1);
.card{
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--l-bsc-hover);
}
}
}
}
}
.play{
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
@@ -282,10 +265,6 @@
}
}
}
.star{
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
}
.setting{
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
@@ -351,11 +330,10 @@
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
}
// Page of list using el-table
// Page of list using table and picture
.listpage{
color: var(--l-fc-2);
.listpage-content{
.listpage-header{
.listpage-header{
border-bottom-color: var(--l-c-3);
.btn{
&:hover{
@@ -376,24 +354,25 @@
color: var(--l-fc-2);
}
}
}
.listpage-body{
color: var(--l-fc-1);
background-color: var(--l-bgc-1);
&:hover{
&::-webkit-scrollbar-thumb {
box-shadow: var(--l-bsc-scroll);
background: var(--l-c-5);
}
&::-webkit-scrollbar-track {
box-shadow: var(--l-bsc-scroll);
background: var(--l-bgc-1);
}
}
.listpage-body{
/* 设置el-table的样式*/
.show-table{
/* 设置el-table的样式*/
.el-table{
color: var(--l-fc-1);
background-color: var(--l-bgc-1);
}
.el-input{
input{
background-color: var(--l-bgc-2);
border: 1px solid var(--l-bgc-2);
color: var(--l-fc-1);
}
}
.el-table__header th, .el-table__header tr, .el-table__body td,.el-table__body th{
color: var(--l-fc-1);
background-color: var(--l-bgc-1);
border-bottom-color: var(--l-c-2);
}
.el-table__body-wrapper{
&:hover{
@@ -407,6 +386,18 @@
}
}
}
.el-input{
input{
background-color: var(--l-bgc-2);
border: 1px solid var(--l-bgc-2);
color: var(--l-fc-1);
}
}
.el-table__header th, .el-table__header tr, .el-table__body td,.el-table__body th{
color: var(--l-fc-1);
background-color: var(--l-bgc-1);
border-bottom-color: var(--l-c-2);
}
.el-table--enable-row-hover .el-table__body tr:hover>td{
background-color: var(--l-bgc-2);
}
@@ -417,6 +408,17 @@
}
}
}
.show-picture{
color: var(--l-fc-1);
.card{
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--l-bsc-hover);
}
}
}
}
}
}

View File

@@ -165,23 +165,6 @@
}
}
}
.film{
.body{
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
.show-img{
color: var(--p-fc-1);
.card{
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--p-bsc-hover);
}
}
}
}
}
.play{
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
@@ -281,10 +264,6 @@
}
}
}
.star{
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
}
.setting{
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
@@ -350,11 +329,10 @@
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
}
// Page of list using el-table
// Page of list using table and picture
.listpage{
color: var(--p-fc-2);
.listpage-content{
.listpage-header{
.listpage-header{
border-bottom-color: var(--p-c-3);
.btn{
&:hover{
@@ -375,24 +353,25 @@
color: var(--p-fc-2);
}
}
}
.listpage-body{
color: var(--p-fc-1);
background-color: var(--p-bgc-1);
&:hover{
&::-webkit-scrollbar-thumb {
box-shadow: var(--p-bsc-scroll);
background: var(--p-c-5);
}
&::-webkit-scrollbar-track {
box-shadow: var(--p-bsc-scroll);
background: var(--p-bgc-1);
}
}
.listpage-body{
/* 设置el-table的样式*/
.show-table{
/* 设置el-table的样式*/
.el-table{
color: var(--p-fc-1);
background-color: var(--p-bgc-1);
}
.el-input{
input{
background-color: var(--p-bgc-2);
border: 1px solid var(--p-bgc-2);
color: var(--p-fc-1);
}
}
.el-table__header th, .el-table__header tr, .el-table__body td,.el-table__body th{
color: var(--p-fc-1);
background-color: var(--p-bgc-1);
border-bottom-color: var(--p-c-2);
}
.el-table__body-wrapper{
&:hover{
@@ -406,6 +385,18 @@
}
}
}
.el-input{
input{
background-color: var(--p-bgc-2);
border: 1px solid var(--p-bgc-2);
color: var(--p-fc-1);
}
}
.el-table__header th, .el-table__header tr, .el-table__body td,.el-table__body th{
color: var(--p-fc-1);
background-color: var(--p-bgc-1);
border-bottom-color: var(--p-c-2);
}
.el-table--enable-row-hover .el-table__body tr:hover>td{
background-color: var(--p-bgc-2);
}
@@ -416,6 +407,17 @@
}
}
}
.show-picture{
color: var(--p-fc-1);
.card{
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--p-bsc-hover);
}
}
}
}
}
}

View File

@@ -8,7 +8,7 @@ import { initUpdater } from './lib/update/update'
const isDevelopment = process.env.NODE_ENV !== 'production'
app.commandLine.appendSwitch('disable-features', 'OutOfBlinkCors') // 允许跨域
app.commandLine.appendSwitch('--ignore-certificate-errors', 'true') // 忽略证书相关错误
// app.commandLine.appendSwitch('--ignore-certificate-errors', 'true') // 忽略证书相关错误
let win
let mini

View File

@@ -14,6 +14,13 @@
</g>
</svg>
</span>
<span :class="[view === 'Recommandation' ? 'active ': ''] + 'zy-svg'" @click="changeView('Recommandation')">
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="48px" height="48px" viewBox="0 0 24 24" aria-labelledby="thumbUpIconTitle" stroke="#2329D6" stroke-width="1" stroke-linecap="square" stroke-linejoin="miter" fill="none" color="#2329D6">
<title id="thumbUpIconTitle">影视推荐</title>
<path d="M8,8.73984815 C8,8.26242561 8.17078432,7.80075162 8.4814868,7.43826541 L13.2723931,1.84887469 C13.7000127,1.34998522 14.4122932,1.20614658 15,1.5 C15.5737957,1.78689785 15.849314,2.45205792 15.6464466,3.06066017 L14,8 L18.6035746,8 C18.7235578,8 18.8432976,8.01079693 18.9613454,8.03226018 C20.0480981,8.22985158 20.7689058,9.27101818 20.5713144,10.3577709 L19.2985871,17.3577709 C19.1256814,18.3087523 18.2974196,19 17.3308473,19 L10,19 C8.8954305,19 8,18.1045695 8,17 L8,8.73984815 Z"/>
<path d="M4,18 L4,9"/>
</svg>
</span>
<span :class="[view === 'IPTV' ? 'active ': ''] + 'zy-svg'" @click="changeView('IPTV')">
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="tvIconTitle">
<title id="tvIconTitle">电视直播</title>

View File

@@ -173,21 +173,19 @@ export default {
},
async starEvent () {
const db = await star.find({ key: this.detail.key, ids: this.info.id })
const doc = {
key: this.detail.key,
ids: this.info.id,
site: this.detail.site,
name: this.info.name,
detail: this.info,
rate: this.info.rate
}
if (db) {
this.$message.info('该影片已被收藏')
star.update(db.id, doc)
this.$message.success('收藏更新成功')
} else {
const docs = {
key: this.detail.key,
ids: this.info.id,
site: this.detail.site,
name: this.info.name,
type: this.info.type,
year: this.info.year,
note: this.info.note,
last: this.info.last
}
star.add(docs).then(res => {
star.add(doc).then(res => {
this.$message.success('收藏成功')
})
}
@@ -281,38 +279,9 @@ export default {
})
},
getDoubanRate () {
const axios = require('axios')
const cheerio = require('cheerio')
const name = this.detail.info.name.trim()
// 豆瓣搜索链接
var doubanSearchLink = 'https://www.douban.com/search?q=' + name
axios.get(doubanSearchLink).then(res => {
const $ = cheerio.load(res.data)
// 比较第一和第二给豆瓣搜索结果, 看名字是否相符
var link = ''
var nameInDouban = $($('div.result')[0]).find('div>div>h3>a').first()
if (name.replace(/\s/g, '') === nameInDouban.text().replace(/\s/g, '')) {
link = nameInDouban.attr('href')
} else {
nameInDouban = $($('div.result')[1]).find('div>div>h3>a').first()
if (name.replace(/\s/g, '') === nameInDouban.text().replace(/\s/g, '')) {
link = nameInDouban.attr('href')
}
}
// 如果找到链接,就打开该链接获取评分
if (link) {
axios.get(link).then(response => {
const parsedHtml = cheerio.load(response.data)
var rating = parsedHtml('body').find('#interest_sectl').first().find('strong').first()
if (rating.text()) {
this.info.rate = rating.text()
} else {
this.info.rate = '暂无评分'
}
})
} else {
this.info.rate = '暂无评分'
}
zy.doubanRate(name).then(res => {
this.info.rate = res
})
},
getDetailInfo () {

View File

@@ -1,27 +1,25 @@
<template>
<div class="listpage" id="editSites">
<div class="listpage-content">
<div class="listpage-header" v-show="!enableBatchEdit">
<el-switch v-model="enableBatchEdit" active-text="批处理分组">></el-switch>
<el-button @click="addSite" icon="el-icon-document-add">新增</el-button>
<el-button @click="exportSites" icon="el-icon-upload2" ></el-button>
<el-button @click="importSites" icon="el-icon-download">导入</el-button>
<el-button @click="checkAllSite" icon="el-icon-refresh" :loading="checkAllSiteLoading">检测</el-button>
<el-button @click="removeAllSites" icon="el-icon-delete-solid">清空</el-button>
<el-button @click="resetSitesEvent" icon="el-icon-refresh-left">重置</el-button>
</div>
<div class="listpage-header" v-show="enableBatchEdit">
<el-switch v-model="enableBatchEdit" active-text="批处理分组"></el-switch>
<el-input placeholder="新组名" v-model="batchGroupName"></el-input>
<el-switch v-model="batchIsActive" :active-value="1" :inactive-value="0" active-text="自选源"></el-switch>
<el-button type="primary" icon="el-icon-edit" @click.stop="saveBatchEdit">保存</el-button>
</div>
<div class="listpage-body" id="sites-table">
<el-table
<div class="listpage" id="sites">
<div class="listpage-header" v-show="!enableBatchEdit">
<el-switch v-model="enableBatchEdit" active-text="批处理分组">></el-switch>
<el-button @click="addSite" icon="el-icon-document-add">新增</el-button>
<el-button @click="exportSites" icon="el-icon-upload2" >导出</el-button>
<el-button @click="importSites" icon="el-icon-download"></el-button>
<el-button @click="checkAllSite" icon="el-icon-refresh" :loading="checkAllSiteLoading">检测</el-button>
<el-button @click="removeAllSites" icon="el-icon-delete-solid">清空</el-button>
<el-button @click="resetSitesEvent" icon="el-icon-refresh-left">重置</el-button>
</div>
<div class="listpage-header" v-show="enableBatchEdit">
<el-switch v-model="enableBatchEdit" active-text="批处理分组"></el-switch>
<el-input placeholder="新组名" v-model="batchGroupName"></el-input>
<el-switch v-model="batchIsActive" :active-value="1" :inactive-value="0" active-text="自选源"></el-switch>
<el-button type="primary" icon="el-icon-edit" @click.stop="saveBatchEdit">保存</el-button>
</div>
<div class="listpage-body" id="sites-body">
<div class="show-table" id="sites-table">
<el-table size="mini" fit height="100%" row-key="id"
ref="editSitesTable"
size="mini" fit height="100%" row-key="id"
:data="sites"
:key="tableKey"
@selection-change="handleSelectionChange"
@sort-change="handleSortChange">
<el-table-column
@@ -54,7 +52,11 @@
<el-button type="text">{{scope.row.group}}</el-button>
</template>
</el-table-column>
<el-table-column label="状态" width="120">
<el-table-column
label="状态"
sortable
:sort-by="['status']"
width="120">
<template slot-scope="scope">
<span v-show="scope.row.status === ''">
<i class="el-icon-loading"></i>
@@ -65,16 +67,18 @@
</el-table-column>
<el-table-column
label="操作"
header-align="right"
header-align="center"
align="right">
<template slot-scope="scope">
<el-button size="mini" @click.stop="moveToTopEvent(scope.row)" type="text">置顶</el-button>
<el-button size="mini" @click.stop="editSite(scope.row)" type="text">编辑</el-button>
<el-button size="mini" @click.stop="checkSimpleSite(scope.row)" type="text">检测</el-button>
<el-button size="mini" @click.stop="removeEvent(scope.row)" type="text">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
<!-- 编辑页面 -->
<div>
<el-dialog :visible.sync="dialogVisible" v-if='dialogVisible' :title="dialogType==='edit'?'编辑源':'新增源'" :append-to-body="true" @close="closeDialog">
@@ -103,7 +107,6 @@
</span>
</el-dialog>
</div>
</div>
</div>
</template>
<script>
@@ -440,6 +443,20 @@ export default {
this.tableKey = Math.random()
}
this.checkAllSiteLoading = false
this.updateDatabase()
},
async checkSimpleSite (row) {
this.checkAllSiteLoading = true
const flag = await zy.check(row.key)
if (flag) {
row.status = '可用'
} else {
row.status = '失效'
row.isActive = 0
}
this.updateDatabase()
this.tableKey = Math.random()
this.checkAllSiteLoading = false
}
},
mounted () {

View File

@@ -1,6 +1,6 @@
<template>
<div class="film">
<div class="header">
<div class="listpage" id="film">
<div class="listpage-header" id="film-header">
<div class="zy-select" @mouseleave="show.site = false">
<div class="vs-placeholder" @click="show.site = true">{{site.name}}</div>
<div class="vs-options" v-show="show.site">
@@ -27,17 +27,16 @@
</div>
</div>
</div>
<div class="body zy-scroll" infinite-wrapper>
<div class="body-box" v-show="!show.find">
<div class="show-img" v-if="setting.view === 'picture'">
<Waterfall ref="waterfall" :list="list" :gutter="20" :width="240"
<div class="listpage-body" id="film-body" infinite-wrapper>
<div class="show-picture" v-if="setting.view === 'picture' && !show.find">
<Waterfall ref="filmWaterfall" :list="list" :gutter="20" :width="240"
:breakpoints="{ 1200: { rowPerView: 4 } }"
animationEffect="fadeInUp"
backgroundColor="rgba(0, 0, 0, 0)">
<template slot="item" slot-scope="props">
<div class="card" v-show="!setting.excludeR18Films || !containsR18Keywords(props.data.type)">
<div class="img">
<img style="width: 100%" :src="props.data.pic" alt="" @load="$refs.waterfall.refresh()" @click="detailEvent(site, props.data)">
<img style="width: 100%" :src="props.data.pic" alt="" @load="$refs.filmWaterfall.refresh()" @click="detailEvent(site, props.data)">
<div class="operate">
<div class="operate-wrap">
<span class="o-play" @click="playEvent(site, props.data)">播放</span>
@@ -56,55 +55,124 @@
</template>
</Waterfall>
<infinite-loading force-use-infinite-wrapper :identifier="infiniteId" @infinite="infiniteHandler"></infinite-loading>
</div>
<div class="show-table" v-if="setting.view === 'table'">
<div class="zy-table">
<div class="tBody">
<ul>
<li v-for="(i, j) in list" :key="j" @click="detailEvent(site, i)" v-show="!setting.excludeR18Films || !containsR18Keywords(i.type)">
<span class="name">{{i.name}}</span>
<span class="type">{{i.type}}</span>
<span class="time">{{i.year}}</span>
<span class="note">{{i.note}}</span>
<span class="last">{{i.last}}</span>
<span class="operate">
<span class="btn" @click.stop="playEvent(site, i)">播放</span>
<span class="btn" @click.stop="starEvent(site, i)">收藏</span>
<span class="btn" @click.stop="shareEvent(site, i)">分享</span>
<span class="btn" @click.stop="downloadEvent(site, i)">下载</span>
</span>
</li>
</ul>
<infinite-loading force-use-infinite-wrapper :identifier="infiniteId" @infinite="infiniteHandler"></infinite-loading>
</div>
</div>
</div>
</div>
<div class="body-box" v-show="show.find">
<div class="show-table">
<div class="zy-table">
<div class="tBody zy-scroll">
<ul>
<li v-for="(i, j) in searchContents" :key="j" @click="detailEvent(i.site, i)">
<span class="name">{{i.name}}</span>
<span class="info">{{i.site.name}}</span>
<span class="info">{{i.director}}</span>
<span class="info">{{i.type}}</span>
<span class="info">{{i.area}}</span>
<span class="info">{{i.lang}}</span>
<span class="info">{{i.year}}</span>
<span class="info">{{i.note}}</span>
<span class="operate">
<span class="btn" @click.stop="playEvent(i.site, i)">播放</span>
<span class="btn" @click.stop="starEvent(i.site, i)">收藏</span>
<span class="btn" @click.stop="shareEvent(i.site, i)">分享</span>
<span class="btn" @click.stop="downloadEvent(i.site, i)">下载</span>
</span>
</li>
</ul>
</div>
</div>
</div>
<div class="show-table" v-if="setting.view === 'table' && !show.find">
<el-table size="mini"
:data="list.filter(res => !setting.excludeR18Films || !containsR18Keywords(res.type))"
height="100%"
@row-click="(row) => detailEvent(site, row)"
style="width: 100%">
<el-table-column
prop="name"
label="片名">
</el-table-column>
<el-table-column
prop="type"
label="类型"
width="100">
</el-table-column>
<el-table-column
prop="year"
label="上映"
align="center"
width="100">
</el-table-column>
<el-table-column
prop="area"
label="地区"
align="center"
width="100">
</el-table-column>
<el-table-column
prop="lang"
label="语言"
align="center"
width="100">
</el-table-column>
<el-table-column
prop="note"
label="备注">
</el-table-column>
<el-table-column
label="操作"
header-align="center"
align="right"
width="200">
<template slot-scope="scope">
<el-button @click.stop="playEvent(site, scope.row)" type="text">播放</el-button>
<el-button @click.stop="starEvent(site, scope.row)" type="text">收藏</el-button>
<el-button @click.stop="shareEvent(site, scope.row)" type="text">分享</el-button>
<el-button @click.stop="downloadEvent(site, scope.row)" type="text">下载</el-button>
</template>
</el-table-column>
<infinite-loading
slot="append"
:identifier="infiniteId"
@infinite="infiniteHandler"
force-use-infinite-wrapper=".el-table__body-wrapper">
<div slot="no-more">数据量过少时请重复操作一次,以防网站抽风</div>
</infinite-loading>
</el-table>
</div>
<div class="show-table" v-show="show.find">
<el-table size="mini"
:data="searchContents"
height="100%"
row-key="id"
@row-click="(row) => detailEvent(row.site, row)"
style="width: 100%">
<el-table-column
prop="name"
label="片名">
</el-table-column>
<el-table-column v-if="setting.searchAllSites"
prop="site"
label="源站"
width="120">
<template slot-scope="scope">
<span>{{ scope.row.site.name }}</span>
</template>
</el-table-column>
<el-table-column
prop="type"
label="类型"
width="100">
</el-table-column>
<el-table-column
prop="year"
label="上映"
align="center"
width="100">
</el-table-column>
<el-table-column
prop="area"
label="地区"
align="center"
width="100">
</el-table-column>
<el-table-column
prop="lang"
label="语言"
align="center"
width="100">
</el-table-column>
<el-table-column
prop="note"
label="备注">
</el-table-column>
<el-table-column
label="操作"
header-align="center"
align="right"
width="200">
<template slot-scope="scope">
<el-button @click.stop="playEvent(scope.row.site, scope.row)" type="text">播放</el-button>
<el-button @click.stop="starEvent(scope.row.site, scope.row)" type="text">收藏</el-button>
<el-button @click.stop="shareEvent(scope.row.site, scope.row)" type="text">分享</el-button>
<el-button @click.stop="downloadEvent(scope.row.site, scope.row)" type="text">下载</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
@@ -331,18 +399,17 @@ export default {
if (db) {
this.$message.info('已存在')
} else {
const docs = {
key: site.key,
ids: e.id,
site: site,
name: e.name,
type: e.type,
year: e.year,
last: e.last,
note: e.note
}
star.add(docs).then(res => {
this.$message.success('收藏成功')
zy.detail(site.key, e.id).then(detailRes => {
const docs = {
key: site.key,
ids: e.id,
site: site,
name: e.name,
detail: detailRes
}
star.add(docs).then(res => {
this.$message.success('收藏成功')
})
})
}
},
@@ -395,7 +462,7 @@ export default {
changeView () {
if (this.view === 'Film') {
if (this.setting.view === 'picture') {
this.$refs.waterfall.refresh()
this.$refs.filmWaterfall.refresh()
}
this.getPage().then(() => {
this.infiniteId += 1
@@ -498,104 +565,3 @@ export default {
}
}
</script>
<style lang="scss" scoped>
.film{
height: calc(100% - 40px);
width: 100%;
display: flex;
flex-direction: column;
.header{
height: 30px;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
z-index: 10;
}
.body{
margin-top: 20px;
flex: 1;
width: 100%;
border-radius: 0 0 5px 5px;
overflow-y: scroll;
&::-webkit-scrollbar{
width: 5px;
height: 1px;
}
&::-webkit-scrollbar-thumb {
border-radius: 10px;
position: absolute;
}
&::-webkit-scrollbar-track {
border-radius: 10px;
position: absolute;
}
.body-box{
height: 100%;
width: 100%;
}
.show-img{
height: 100%;
width: 100%;
padding: 10px;
.card{
border-radius: 6px;
overflow: hidden;
.img{
position: relative;
min-height: 40px;
img{
width: 100%;
height: auto;
cursor: pointer;
}
.operate{
display: none;
position: absolute;
left: 0;
bottom: 0;
background-color: #111111aa;
width: 100%;
font-size: 13px;
.operate-wrap{
display: flex;
justify-content: space-between;
.o-play, .o-star, .o-share{
cursor: pointer;
display: inline-block;
width: 80px;
height: 36px;
text-align: center;
line-height: 36px;
color: #cdcdcd;
&:hover{
background-color: #111;
}
}
}
}
}
.name{
font-size: 16px;
padding: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
}
.info{
display: flex;
justify-content: space-between;
font-size: 12px;
padding: 10px;
}
&:hover{
.operate{
display: block;
}
}
}
}
}
}
</style>

View File

@@ -1,12 +1,12 @@
<template>
<div class="listpage" id="history">
<div class="listpage-content">
<div class="listpage-header">
<div class="listpage-header" id="history-header">
<el-button @click.stop="exportHistory" icon="el-icon-upload2">导出</el-button>
<el-button @click.stop="importHistory" icon="el-icon-download">导入</el-button>
<el-button @click.stop="clearAllHistory" icon="el-icon-delete-solid">清空</el-button>
</div>
<div class="listpage-body" id="history-table">
</div>
<div class="listpage-body" id="history-body">
<div class="show-table" id="history-table" >
<el-table size="mini" fit height="100%" :data="history" row-key="id" @row-click="detailEvent">
<el-table-column
prop="name"
@@ -42,7 +42,7 @@
</el-table>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapMutations } from 'vuex'

View File

@@ -1,19 +1,19 @@
<template>
<div class="listpage" id="IPTV">
<div class="listpage-content">
<div class="listpage-header" v-show="!enableBatchEdit">
<div class="listpage" id="iptv">
<div class="listpage-header" id="iptv-header" v-show="!enableBatchEdit">
<el-switch v-model="enableBatchEdit" active-text="批处理分组"></el-switch>
<el-button @click.stop="exportChannels" icon="el-icon-upload2" >导出</el-button>
<el-button @click.stop="importChannels" icon="el-icon-download">导入</el-button>
<el-button @click.stop="removeAllChannels" icon="el-icon-delete-solid">清空</el-button>
<el-button @click.stop="resetChannelsEvent" icon="el-icon-refresh-left">重置</el-button>
</div>
<div class="listpage-header" v-show="enableBatchEdit">
</div>
<div class="listpage-header" id="iptv-header" v-show="enableBatchEdit">
<el-switch v-model="enableBatchEdit" active-text="批处理分组"></el-switch>
<el-input placeholder="新组名" v-model="batchGroupName"></el-input>
<el-button type="primary" icon="el-icon-edit" @click.stop="saveBatchEdit">保存</el-button>
</div>
<div class="listpage-body" id="iptv-table">
</div>
<div class="listpage-body" id="iptv-table">
<div class="show-table" id="iptv-table">
<el-table
ref="iptvTable"
size="mini" fit height="100%" row-key="id"
@@ -132,7 +132,9 @@ export default {
},
watch: {
view () {
this.getChannels()
if (this.view === 'IPTV') {
this.getChannels()
}
},
searchTxt () {
}

View File

@@ -84,6 +84,12 @@
<rect x="17" y="6" width="1" height="1"></rect>
</svg>
</span>
<span class="zy-svg" @click="showShortcutEvent" v-show="right.list.length > 0">
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="sendIconTitle">
<title id="sendIconTitle">快捷键指南</title>
<polygon points="21.368 12.001 3 21.609 3 14 11 12 3 9.794 3 2.394"></polygon>
</svg>
</span>
<span class="zy-svg" @click="issueEvent" v-show="right.list.length > 0">
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="infoIconTitle">
<title id="infoIconTitle">复制调试信息</title>
@@ -98,7 +104,10 @@
<transition name="slideX">
<div v-if="right.show" class="list">
<div class="list-top">
<span class="list-top-title">{{ right.type === 'list' ? '播放列表' : right.type === 'history' ? '历史记录' : '其他相同资源' }}</span>
<span class="list-top-title" v-if="right.type === 'list'">播放列表</span>
<span class="list-top-title" v-if="right.type === 'history'">历史记录</span>
<span class="list-top-title" v-if="right.type === 'shortcut'">快捷键指南</span>
<span class="list-top-title" v-if="right.type === 'other'">其他源的视频</span>
<span class="list-top-close zy-svg" @click="closeListEvent">
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="closeIconTitle">
<title id="closeIconTitle">关闭</title>
@@ -117,9 +126,12 @@
<li v-show="right.history.length === 0">无数据</li>
<li @click="historyItemEvent(m)" :class="video.info.id === m.ids ? 'active' : ''" v-for="(m, n) in right.history" :key="n"><span class="title" :title="'【' + m.site + '】' + m.name + ' 第' + (m.index+1) + '集'">【{{m.site}}】{{m.name}} 第{{m.index+1}}集</span><span @click.stop="removeHistoryItem(m)" class="detail-delete">删除</span></li>
</ul>
<ul v-show="right.type === 'shortcut'" class="list-shortcut">
<li v-for="(m, n) in right.shortcut" :key="n"><span class="title">{{m.desc}} -- [ {{m.key}} ]</span></li>
</ul>
<ul v-show="right.type === 'other'" class="list-other">
<li v-show="right.other.length === 0">无数据</li>
<li @click="otherItemEvent(m)" v-for="(m, n) in right.other" :key="n"><span class="title">{{m.name}} - [{{m.site}}]</span></li>
<li @click="otherItemEvent(m)" v-for="(m, n) in right.other" :key="n"><span class="title">{{m.name}} - [{{m.site.name}}]</span></li>
</ul>
</div>
</div>
@@ -185,9 +197,10 @@ export default {
right: {
show: false,
type: '',
other: [],
list: [],
history: []
history: [],
shortcut: [],
other: []
},
config: {
id: 'xgplayer',
@@ -532,19 +545,18 @@ export default {
}
})
} else {
const docs = {
key: this.video.key,
ids: info.id,
name: info.name,
type: info.type,
year: info.year,
last: info.last,
note: info.note,
index: info.index
}
star.add(docs).then(res => {
this.$message.success('收藏成功')
this.isStar = true
zy.detail(this.video.key, info.id).then(detailRes => {
const docs = {
key: this.video.key,
ids: info.id,
name: info.name,
detail: detailRes,
index: info.index
}
star.add(docs).then(res => {
this.$message.success('收藏成功')
this.isStar = true
})
})
}
},
@@ -732,67 +744,39 @@ export default {
this.$message.warning('删除历史记录失败, 错误信息: ' + err)
})
},
getAllsitestest () {
this.name = '喜宝'
sites.all().then(res => {
const sites = res
const arr = []
for (const i of sites) {
zy.search(i.key, this.name).then(res => {
const type = Object.prototype.toString.call(res)
async getOtherSites () {
this.right.other = []
sites.all().then(sitesRes => {
// 排除已关闭的源和当前源
for (const siteItem of sitesRes.filter(x => x.isActive && x.key !== this.video.key)) {
zy.search(siteItem.key, this.name).then(searchRes => {
const type = Object.prototype.toString.call(searchRes)
if (type === '[object Array]') {
res.forEach(element => {
zy.detail(i.key, element.id).then(detailRes => {
arr.push(detailRes)
})
searchRes.forEach(async item => {
const detailRes = item
detailRes.key = siteItem.key
detailRes.site = siteItem
this.right.other.push(detailRes)
})
}
if (type === '[object Object]') {
zy.detail(i.key, res.id).then(detailRes => {
arr.push(detailRes)
})
const detailRes = searchRes
detailRes.key = siteItem.key
detailRes.site = siteItem
this.right.other.push(detailRes)
}
})
}
console.log(arr, 'arr')
})
},
async getAllsites () {
const all = await sites.all()
this.right.other = []
for (const i of all) {
if (i.isActive) {
const searchRes = await zy.search(i.key, this.name)
const type = Object.prototype.toString.call(searchRes)
if (type === '[object Array]') {
searchRes.forEach(async element => {
const detailRes = await zy.detail(i.key, element.id)
detailRes.key = i.key
detailRes.site = i.name
this.right.other.push(detailRes)
})
}
if (type === '[object Object]') {
const detailRes = await zy.detail(i.key, searchRes.id)
detailRes.key = i.key
detailRes.site = i.name
this.right.other.push(detailRes)
}
}
}
},
otherEvent (m) {
this.right.type = 'other'
this.getAllsites()
this.getOtherSites()
this.right.show = true
},
async otherItemEvent (e) {
const db = await history.find({ site: e.key, ids: e.id })
if (db) {
this.video = { key: db.site, info: { id: db.ids, name: db.name, index: db.index, site: e.key } }
} else {
this.video = { key: e.key, info: { id: e.id, name: e.name, index: 0, site: e.key } }
}
// 打开当前播放的剧集index, 定位到当前的时间
this.video = { key: e.key, info: { id: e.id, name: e.name, site: e.site, index: this.video.info.index, time: this.video.info.time } }
this.right.show = false
this.right.type = ''
},
@@ -1152,6 +1136,14 @@ export default {
}
addPlayerView.bind(this, 'videoTitle', `<span>${title}</span>`, {})()
})
},
showShortcutEvent () {
this.right.show = !this.right.show
shortcut.all().then(res => {
this.right.type = 'shortcut'
this.right.shortcut = res
console.log(res)
})
}
},
created () {

View File

@@ -0,0 +1,307 @@
<template>
<div class="listpage" id="recommandataions">
<div class="listpage-header" id="recommandataions-header">
<el-switch v-model="viewMode" active-text="海报" active-value="picture" inactive-text="列表" inactive-value="list" @change="updateViewMode"></el-switch>
<el-button type="text">视频数{{ recommandations.length }}</el-button>
<el-select size="mini" v-model="selectedAreas" multiple collapse-tags style="margin-left: 20px;" placeholder="地区">
<el-option
v-for="item in areas"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
<el-select size="mini" v-model="selectedTypes" multiple collapse-tags style="margin-left: 20px;" placeholder="类型">
<el-option
v-for="item in types"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
<el-button :loading="loading" @click.stop="updateEvent" icon="el-icon-refresh">更新推荐</el-button>
</div>
<div class="listpage-body" id="recommandataions-body" >
<div class="show-table" id="star-table" v-show="viewMode === 'list'">
<el-table size="mini" fit height="100%" row-key="id"
ref="recommandataionsTable"
:data="filteredRecommandations"
@row-click="detailEvent">
<el-table-column
prop="name"
label="片名">
</el-table-column>
<el-table-column
prop="detail.area"
label="地区"
width="100">
</el-table-column>
<el-table-column
prop="detail.type"
label="类型"
width="100">
</el-table-column>
<el-table-column
prop="detail.year"
label="上映"
width="100"
align="center">
</el-table-column>
<el-table-column v-if="filteredRecommandations.some(e => e.detail.note)"
prop="detail.note"
width="120"
label="备注">
</el-table-column>
<el-table-column v-if="filteredRecommandations.some(e => e.rate)"
prop="rate"
width="120"
label="豆瓣评分">
</el-table-column>
<el-table-column
label="操作"
header-align="right"
align="right">
<template slot-scope="scope">
<el-button @click.stop="playEvent(scope.row)" type="text">播放</el-button>
<el-button @click.stop="shareEvent(scope.row)" type="text">分享</el-button>
<el-button @click.stop="downloadEvent(scope.row)" type="text">下载</el-button>
<el-button @click.stop="deleteEvent(scope.row)" type="text">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="show-picture" id="star-picture" v-show="viewMode === 'picture'">
<Waterfall ref="recommandataionsWaterfall" :list="filteredRecommandations" :gutter="20" :width="240"
:breakpoints="{ 1200: { rowPerView: 4 } }"
animationEffect="fadeInUp"
backgroundColor="rgba(0, 0, 0, 0)">
<template slot="item" slot-scope="props">
<div class="card">
<div class="img">
<div class="rate" v-if="props.data.rate && props.data.rate !== '暂无评分'">
<span>{{props.data.rate}}</span>
</div>
<img style="width: 100%" :src="props.data.detail.pic" alt="" @load="$refs.recommandataionsWaterfall.refresh()" @click="detailEvent(props.data)">
<div class="operate">
<div class="operate-wrap">
<span class="o-play" @click="playEvent(props.data)">播放</span>
<span class="o-share" @click="shareEvent(props.data)">分享</span>
<span class="o-star" @click="downloadEvent(props.data)">下载</span>
<span class="o-star" @click="deleteEvent(props.data)">删除</span>
</div>
</div>
</div>
<div class="name" @click="detailEvent(props.data)">{{props.data.name}}</div>
<div class="info">
<span>{{props.data.detail.area}}</span>
<span>{{props.data.detail.year}}</span>
<span>{{props.data.detail.note}}</span>
<span>{{props.data.detail.type}}</span>
</div>
</div>
</template>
</Waterfall>
</div>
</div>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
import { history, recommandation, setting } from '../lib/dexie'
import zy from '../lib/site/tools'
import Waterfall from 'vue-waterfall-plugin'
const { clipboard } = require('electron')
export default {
name: 'recommandations',
data () {
return {
recommandations: [],
sites: [],
viewMode: 'picture',
loading: false,
types: [],
selectedTypes: [],
areas: [],
selectedAreas: []
}
},
components: {
Waterfall
},
computed: {
view: {
get () {
return this.$store.getters.getView
},
set (val) {
this.SET_VIEW(val)
}
},
video: {
get () {
return this.$store.getters.getVideo
},
set (val) {
this.SET_VIDEO(val)
}
},
detail: {
get () {
return this.$store.getters.getDetail
},
set (val) {
this.SET_DETAIL(val)
}
},
share: {
get () {
return this.$store.getters.getShare
},
set (val) {
this.SET_SHARE(val)
}
},
filteredRecommandations () {
var filteredData = this.recommandations.filter(x => (this.selectedAreas.length === 0) || this.selectedAreas.includes(x.detail.area))
filteredData = filteredData.filter(x => (this.selectedTypes.length === 0) || this.selectedTypes.includes(x.detail.type))
return filteredData
}
},
watch: {
view () {
if (this.view === 'Recommandation') {
this.getRecommandations()
this.$refs.recommandataionsWaterfall.refresh()
}
}
},
methods: {
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
detailEvent (e) {
this.detail = {
show: true,
key: e.key,
info: {
id: e.ids,
name: e.name
}
}
},
updateEvent () {
const url = 'https://raw.githubusercontent.com/Hunlongyu/ZY-Player/master/src/lib/dexie/iniData/Recommandations.json'
this.loading = true
const axios = require('axios')
axios.get(url).then(res => {
if (res.status === 200) {
if (res.data.length > 0) {
this.recommandations = res.data
this.recommandations.sort(function (a, b) {
return b.detail.year - a.detail.year
})
recommandation.clear().then(recommandation.bulkAdd(this.recommandations))
this.getFilterData()
this.$message.success('更新推荐成功')
}
}
this.loading = false
})
},
async playEvent (e) {
const db = await history.find({ site: e.key, ids: e.ids })
if (db) {
this.video = { key: e.key, info: { id: db.ids, name: db.name, index: db.index } }
} else {
this.video = { key: e.key, info: { id: e.ids, name: e.name, index: 0 } }
}
this.view = 'Play'
},
deleteEvent (e) {
recommandation.remove(e.id).then(res => {
if (res) {
this.$message.warning('删除失败')
} else {
this.$message.success('删除成功')
}
this.getRecommandations()
})
},
shareEvent (e) {
this.share = {
show: true,
key: e.key,
info: e
}
},
downloadEvent (e) {
zy.download(e.key, e.ids).then(res => {
if (res && res.dl && res.dl.dd) {
const text = res.dl.dd._t
if (text) {
const list = text.split('#')
let downloadUrl = ''
for (const i of list) {
const url = encodeURI(i.split('$')[1])
downloadUrl += (url + '\n')
}
clipboard.writeText(downloadUrl)
this.$message.success('『MP4』格式的链接已复制, 快去下载吧!')
} else {
this.$message.warning('没有查询到下载链接.')
}
} else {
var m3u8List = {}
zy.detail(e.key, e.ids).then(res => {
const dd = res.dl.dd
const type = Object.prototype.toString.call(dd)
if (type === '[object Array]') {
for (const i of dd) {
if (i._flag.indexOf('m3u8') >= 0) {
m3u8List = i._t.split('#')
}
}
} else {
m3u8List = dd._t.split('#')
}
const list = [...m3u8List]
let downloadUrl = ''
for (const i of list) {
const url = encodeURI(i.split('$')[1])
downloadUrl += (url + '\n')
}
clipboard.writeText(downloadUrl)
this.$message.success('『M3U8』格式的链接已复制, 快去下载吧!')
})
}
})
},
getRecommandations () {
recommandation.all().then(res => {
this.recommandations = res
this.recommandations.sort(function (a, b) {
return b.detail.year - a.detail.year
})
this.getFilterData()
})
},
getFilterData () {
this.types = [...new Set(this.recommandations.map(ele => ele.detail.type))].filter(x => x)
this.areas = [...new Set(this.recommandations.map(ele => ele.detail.area))].filter(x => x)
},
getViewMode () {
setting.find().then(res => {
this.viewMode = res.recommandationViewMode
})
},
updateViewMode () {
setting.find().then(res => {
res.recommandationViewMode = this.viewMode
setting.update(res)
})
}
},
created () {
this.getRecommandations()
this.getViewMode()
}
}
</script>

View File

@@ -68,11 +68,11 @@
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="selectLocalPlayer">选择本地播放器</div>
</div>
<div class="zy-select" @click = "editPlayerPath = true">
<div class="vs-placeholder vs-noAfter" v-show = "editPlayerPath == false">
<div class="zy-select" @click = "show.editPlayerPath = true">
<div class="vs-placeholder vs-noAfter" v-show = "show.editPlayerPath == false">
<label>编辑</label>
</div>
<input class="zy-input" v-show = "editPlayerPath == true" v-model = "d.externalPlayer"
<input class="zy-input" v-show = "show.editPlayerPath == true" v-model = "d.externalPlayer"
@blur= "updateSettingEvent"
@keyup.enter = "updateSettingEvent">
</div>
@@ -130,12 +130,39 @@
</div>
<div class="clearDB">
<span @click="clearDBEvent" class="clearBtn">软件重置</span>
<span class="clearTips">如果新安装用户, 无法显示资源, 请点击软件重置. 如非必要, 切勿点击. 会清空用户数据, 恢复默认设置. 点击即软件重置, 并关闭软件.</span>
<span @click="changePasswordEvent" class="clearBtn">设置密码</span>
<div class="clearTips">如果新安装用户, 无法显示资源, 请点击软件重置. 如非必要, 切勿点击. 会清空用户数据, 恢复默认设置. 点击即软件重置, 并关闭软件.</div>
</div>
<div class="Tips">
<span>所有资源来自网上, 该软件不参与任何制作, 上传, 储存等内容, 禁止传播违法资源. 该软件仅供学习参考, 请于安装后24小时内删除.</span>
</div>
</div>
<div> <!-- 输入密码页面 -->
<el-dialog :visible.sync="show.checkPasswordDialog" v-if='show.checkPasswordDialog' :append-to-body="true" @close="closeDialog" width="300px">
<el-form label-width="75px" label-position="left">
<el-form-item label="当前密码" prop='name'>
<el-input v-model="inputPassword" placeholder="请输入您的当前密码" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="closeDialog">取消</el-button>
<el-button type="primary" @click="checkPasswordEvent">确定</el-button>
</span>
</el-dialog>
</div>
<div> <!-- 修改密码页面 -->
<el-dialog :visible.sync="show.changePasswordDialog" v-if='show.changePasswordDialog' :append-to-body="true" @close="closeDialog" width="300px">
<el-form label-width="75px" label-position="left">
<el-form-item label="新密码" prop='name'>
<el-input v-model="inputPassword" placeholder="请输入您的新密码" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="closeDialog">取消</el-button>
<el-button type="primary" @click="confirmedChangePasswordEvent">确定</el-button>
</span>
</el-dialog>
</div>
</div>
</template>
<script>
@@ -155,26 +182,15 @@ export default {
show: {
site: false,
shortcut: false,
view: false
},
externalPlayer: '',
editPlayerPath: false,
excludeR18Films: true,
latestVersion: pkg.version,
forwardTimeInSec: 5,
d: {
id: 0,
site: '',
theme: '',
shortcut: true,
searchAllSites: true,
view: 'picture',
externalPlayer: '',
view: false,
editPlayerPath: false,
excludeRootClasses: true,
excludeR18Films: true,
forwardTimeInSec: 5
}
checkPasswordDialog: false,
changePasswordDialog: false
},
d: { },
latestVersion: pkg.version,
inputPassword: '',
action: ''
}
},
computed: {
@@ -210,17 +226,7 @@ export default {
},
getSetting () {
setting.find().then(res => {
this.d = {
id: res.id,
theme: res.theme,
shortcut: res.shortcut,
view: res.view,
externalPlayer: res.externalPlayer,
searchAllSites: res.searchAllSites,
excludeRootClasses: res.excludeRootClasses,
excludeR18Films: res.excludeR18Films,
forwardTimeInSec: res.forwardTimeInSec
}
this.d = res
this.setting = this.d
})
},
@@ -256,7 +262,7 @@ export default {
this.$message.success(`清除缓存成功, 共清理 ${mb} MB`)
},
updateSettingEvent () {
this.editPlayerPath = false
this.show.editPlayerPath = false
this.setting = this.d
setting.update(this.d)
},
@@ -300,11 +306,48 @@ export default {
},
updatePlayerPath () {
this.$message.success('设定第三方播放器路径为:' + this.d.externalPlayer)
this.editPlayerPath = false
this.show.editPlayerPath = false
this.updateSettingEvent()
},
editSitesEvent () {
this.view = 'EditSites'
if (this.d.password) {
this.action = 'EditSites'
this.show.checkPasswordDialog = true
} else {
this.view = 'EditSites'
}
},
closeDialog () {
this.show.checkPasswordDialog = false
this.show.changePasswordDialog = false
this.inputPassword = ''
},
checkPasswordEvent () {
if (this.inputPassword === this.d.password) {
this.closeDialog()
if (this.action === 'EditSites') {
this.view = 'EditSites'
} else if (this.action === 'ChangePassword') {
this.show.changePasswordDialog = true
} else if (this.action === 'CleanDB') {
this.clearDB()
}
} else {
this.$message.error('您输入的密码错误,请重试')
}
},
changePasswordEvent () {
if (this.d.password) {
this.action = 'ChangePassword'
this.show.checkPasswordDialog = true
} else {
this.show.changePasswordDialog = true
}
},
confirmedChangePasswordEvent () {
this.d.password = this.inputPassword
this.updateSettingEvent()
this.closeDialog()
},
changeTheme (e) {
this.d.theme = e
@@ -333,6 +376,14 @@ export default {
})
},
clearDBEvent () {
if (this.d.password) {
this.action = 'CleanDB'
this.show.checkPasswordDialog = true
} else {
this.clearDB()
}
},
clearDB () {
db.delete().then(res => {
this.$message.success('重置成功')
const win = remote.getCurrentWindow()
@@ -362,6 +413,7 @@ export default {
})
},
quitAndInstall () {
this.$message.success('已开始下载更新,下载完毕后,将自动退出安装。')
ipcRenderer.send('quitAndInstall')
},
createContextMenu () {
@@ -518,9 +570,9 @@ export default {
line-height: 32px;
}
.clearTips{
margin: 10px 0 0 20px;
font-size: 12px;
color: #ff000088;
margin-left: 10px;
}
}
.Tips{

View File

@@ -1,13 +1,14 @@
<template>
<div class="listpage" id="star">
<div class="listpage-content">
<div class="listpage-header">
<div class="listpage-header" id="star-header">
<el-switch v-model="viewMode" active-text="海报" active-value="picture" inactive-text="列表" inactive-value="list" @change="updateViewMode"></el-switch>
<el-button @click.stop="exportFavoritesEvent" icon="el-icon-upload2">导出</el-button>
<el-button @click.stop="importFavoritesEvent" icon="el-icon-download">导入</el-button>
<el-button @click.stop="clearFavoritesEvent" icon="el-icon-delete-solid">清空</el-button>
<el-button @click.stop="updateAllEvent" icon="el-icon-refresh">同步所有收藏</el-button>
</div>
<div class="listpage-body" id="star-table">
</div>
<div class="listpage-body" id="star-body">
<div class="show-table" id="star-table" v-show="viewMode === 'list'">
<el-table size="mini" fit height="100%" row-key="id"
ref="starTable"
:data="list"
@@ -21,37 +22,39 @@
label="片名">
</el-table-column>
<el-table-column
:sort-by="['type', 'name']"
prop="site.name"
width="120"
label="源站">
<template slot-scope="scope">
<span>{{ getSiteName(scope.row) }}</span>
</template>
</el-table-column>
<el-table-column
:sort-by="['detail.type', 'name']"
sortable
:sort-method="sortByType"
prop="type"
prop="detail.type"
label="类型"
width="100">
</el-table-column>
<el-table-column
sortable
:sort-by="['year', 'name']"
prop="year"
:sort-by="['detail.year', 'name']"
prop="detail.year"
label="上映"
width="100"
align="center">
</el-table-column>
<el-table-column
:sort-by="['site', 'name']"
sortable
:sort-method="sortBySite"
prop="site"
width="120"
label="片源">
<template slot-scope="scope">
<span>{{ getSiteName(scope.row.key) }}</span>
</template>
</el-table-column>
<el-table-column v-if="list.some(e => e.note)"
prop="note"
<el-table-column v-if="list.some(e => e.detail.note)"
prop="detail.note"
width="120"
label="备注">
</el-table-column>
<el-table-column v-if="list.some(e => e.rate)"
prop="rate"
width="120"
label="豆瓣评分">
</el-table-column>
<el-table-column v-if="list.some(e => e.index >= 0)"
prop="index"
width="120"
@@ -73,25 +76,64 @@
</el-table-column>
</el-table>
</div>
<div class="show-picture" id="star-picture" v-show="viewMode === 'picture'">
<Waterfall ref="starWaterfall" :list="list" :gutter="20" :width="240"
:breakpoints="{ 1200: { rowPerView: 4 } }"
animationEffect="fadeInUp"
backgroundColor="rgba(0, 0, 0, 0)">
<template slot="item" slot-scope="props">
<div class="card">
<div class="img">
<div class="rate" v-if="props.data.rate && props.data.rate !== '暂无评分'">
<span>{{props.data.rate}}</span>
</div>
<div class="update" v-if="props.data.hasUpdate">
<span>有更新</span>
</div>
<img style="width: 100%" :src="props.data.detail.pic" alt="" @load="$refs.starWaterfall.refresh()" @click="detailEvent(props.data)">
<div class="operate">
<div class="operate-wrap">
<span class="o-play" @click="playEvent(props.data)">播放</span>
<span class="o-share" @click="shareEvent(props.data)">分享</span>
<span class="o-star" @click="downloadEvent(props.data)">下载</span>
<span class="o-star" @click="deleteEvent(props.data)">删除</span>
</div>
</div>
</div>
<div class="name" @click="detailEvent(props.data)">{{props.data.name}}</div>
<div class="info">
<span>{{props.data.detail.year}}</span>
<span>{{props.data.detail.note}}</span>
<span>{{props.data.detail.type}}</span>
</div>
</div>
</template>
</Waterfall>
</div>
</div>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
import { star, history, sites } from '../lib/dexie'
import { star, sites, setting } from '../lib/dexie'
import zy from '../lib/site/tools'
import { remote } from 'electron'
import fs from 'fs'
import Sortable from 'sortablejs'
import Waterfall from 'vue-waterfall-plugin'
const { clipboard } = require('electron')
export default {
name: 'star',
data () {
return {
list: [],
sites: []
sites: [],
viewMode: 'picture'
}
},
components: {
Waterfall
},
computed: {
view: {
get () {
@@ -128,8 +170,11 @@ export default {
},
watch: {
view () {
this.getAllsites()
this.getFavorites()
if (this.view === 'Star') {
this.getAllsites()
this.getFavorites()
this.$refs.starWaterfall.refresh()
}
}
},
methods: {
@@ -143,14 +188,6 @@ export default {
sortByType (a, b) {
return a.type.localeCompare(b.type)
},
sortBySite (a, b) {
const siteA = this.getSiteName(a.key)
if (!siteA) {
return -1
} else {
return siteA.localeCompare(this.getSiteName(b.key))
}
},
detailEvent (e) {
this.detail = {
show: true,
@@ -165,9 +202,8 @@ export default {
}
},
async playEvent (e) {
const db = await history.find({ site: e.key, ids: e.ids })
if (db) {
this.video = { key: e.key, info: { id: db.ids, name: db.name, index: db.index } }
if (e.index) {
this.video = { key: e.key, info: { id: e.ids, name: e.name, index: e.index } }
} else {
this.video = { key: e.key, info: { id: e.ids, name: e.name, index: 0 } }
}
@@ -207,27 +243,19 @@ export default {
}
},
updateEvent (e) {
zy.detail(e.key, e.ids).then(res => {
zy.detail(e.key, e.ids).then(detailRes => {
var doc = {
id: e.id,
key: e.key,
ids: res.id,
site: res.site,
name: res.name,
type: res.type,
year: res.year,
note: res.note,
index: res.index,
last: res.last,
hasUpdate: res.hasUpdate
ids: e.ids,
site: e.site,
name: e.name,
detail: detailRes,
index: e.index
}
star.get(e.id).then(resStar => {
doc.hasUpdate = resStar.hasUpdate
var msg = ''
if (e.last === res.last) {
msg = `同步"${e.name}"成功, 未查询到更新。`
this.$message.info(msg)
} else {
if (e.detail.last !== detailRes.last) {
doc.hasUpdate = true
msg = `同步"${e.name}"成功, 检查到更新。`
this.$message.success(msg)
@@ -287,10 +315,14 @@ export default {
}
})
},
getSiteName (key) {
var site = this.sites.find(e => e.key === key)
if (site) {
return site.name
getSiteName (row) {
if (row.site) {
return row.site.name
} else {
var site = this.sites.find(e => e.key === row.key)
if (site) {
return site.name
}
}
},
getHistoryNote (index) {
@@ -352,12 +384,19 @@ export default {
ids: ele.ids,
site: ele.site === undefined ? ele.site = this.sites.find(x => x.key === ele.key) : ele.site,
name: ele.name,
type: ele.type,
year: ele.year,
note: ele.note,
hasUpdate: ele.hasUpdate,
index: ele.index,
last: ele.last,
hasUpdate: ele.hasUpdate
rate: ele.rate,
detail: ele.detail === undefined ? {
director: ele.director,
actor: ele.actor,
type: ele.type,
area: ele.area,
lang: ele.lang,
year: ele.year,
last: ele.last,
note: ele.note
} : ele.detail
}
starList.push(doc)
}
@@ -403,6 +442,17 @@ export default {
_this.updateDatabase()
}
})
},
getViewMode () {
setting.find().then(res => {
this.viewMode = res.starViewMode
})
},
updateViewMode () {
setting.find().then(res => {
res.starViewMode = this.viewMode
setting.update(res)
})
}
},
mounted () {
@@ -410,6 +460,7 @@ export default {
},
created () {
this.getFavorites()
this.getViewMode()
}
}
</script>

View File

@@ -10,7 +10,7 @@ import Share from './Share'
import History from './History'
import EditSites from './EditSites'
import IPTV from './IPTV'
import Recommandation from './Recommandation'
export default {
registerComponents () {
Vue.component('Aside', Aside)
@@ -24,5 +24,6 @@ export default {
Vue.component('History', History)
Vue.component('EditSites', EditSites)
Vue.component('IPTV', IPTV)
Vue.component('Recommandation', Recommandation)
}
}

View File

@@ -1,14 +1,15 @@
import Dexie from 'dexie'
import { setting, sites, localKey, iptv } from './initData'
import { setting, sites, localKey, iptv, recommandations } from './initData'
const db = new Dexie('zy')
db.version(4).stores({
search: '++id, keywords',
iptvSearch: '++id, keywords',
setting: 'id, theme, site, shortcut, view, externalPlayer, searchAllSites, excludeRootClasses, excludeR18Films, forwardTimeInSec',
setting: 'id, theme, site, shortcut, view, externalPlayer, searchAllSites, excludeRootClasses, excludeR18Films, forwardTimeInSec, starViewMode, recommandationViewMode, password',
shortcut: 'name, key, desc',
star: '++id, [key+ids], site, name, type, year, note, index, last, hasUpdate',
star: '++id, [key+ids], site, name, detail, index, rate, hasUpdate',
recommandation: '++id, [key+ids], site, name, detail, index, rate, hasUpdate',
sites: '++id, key, name, api, download, isActive, group',
history: '++id, [site+ids], name, type, year, index, time',
mini: 'id, site, ids, name, index, time',
@@ -20,6 +21,7 @@ db.on('populate', () => {
db.sites.bulkAdd(sites)
db.shortcut.bulkAdd(localKey)
db.iptv.bulkAdd(iptv)
db.recommandation.bulkAdd(recommandations)
})
db.open()

View File

@@ -7,6 +7,7 @@ import sites from './sites'
import search from './search'
import iptvSearch from './iptvSearch'
import iptv from './iptv'
import recommandation from './recommandation'
export {
history,
@@ -17,5 +18,6 @@ export {
sites,
iptv,
search,
iptvSearch
iptvSearch,
recommandation
}

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,10 @@ const setting = [
searchAllSites: true,
excludeRootClasses: true,
excludeR18Films: true,
forwardTimeInSec: 5
forwardTimeInSec: 5,
starViewMode: 'picture',
recommandationViewMode: 'picture',
password: ''
}
]
@@ -342,11 +345,12 @@ const getSite = (key) => {
}
const iptv = require('./iniData/Iptv.json')
const recommandations = require('./iniData/Recommandations.json')
export {
setting,
sites,
iptv,
recommandations,
localKey,
getSite
}

View File

@@ -0,0 +1,28 @@
import db from './dexie'
const { recommandation } = db
export default {
async add (doc) {
return await recommandation.add(doc)
},
async bulkAdd (doc) {
return await recommandation.bulkAdd(doc)
},
async find (doc) {
return await recommandation.where(doc).first()
},
async update (id, docs) {
return await recommandation.update(id, docs)
},
async all () {
return await recommandation.toArray()
},
async remove (id) {
return await recommandation.delete(id)
},
async get (id) {
return await recommandation.get(id)
},
async clear () {
return await recommandation.clear()
}
}

View File

@@ -1,6 +1,8 @@
import { sites } from '../dexie'
import axios from 'axios'
import parser from 'fast-xml-parser'
import cheerio from 'cheerio'
const zy = {
xmlConfig: { // XML 转 JSON 配置
trimValues: true,
@@ -210,6 +212,52 @@ const zy = {
} catch (e) {
return false
}
},
/**
* 获取豆瓣评分
* @param {*} name 视频名称
* @returns 豆瓣评分
*/
doubanRate (name) {
return new Promise((resolve, reject) => {
// 豆瓣搜索链接
var nameToSearch = name.replace(/\s/g, '')
var doubanSearchLink = 'https://www.douban.com/search?q=' + nameToSearch
axios.get(doubanSearchLink).then(res => {
const $ = cheerio.load(res.data)
// 比较第一和第二给豆瓣搜索结果, 看名字是否相符
var link = ''
var linkInDouban = $($('div.result')[0]).find('div>div>h3>a').first()
var nameInDouban = linkInDouban.text().replace(/\s/g, '')
if (nameToSearch.includes(nameInDouban) || nameInDouban.includes(nameToSearch)) {
link = linkInDouban.attr('href')
} else {
linkInDouban = $($('div.result')[1]).find('div>div>h3>a').first()
nameInDouban = linkInDouban.text().replace(/\s/g, '')
if (nameToSearch.includes(nameInDouban) || nameInDouban.includes(nameToSearch)) {
link = linkInDouban.attr('href')
}
}
// 如果找到链接,就打开该链接获取评分
if (link) {
axios.get(link).then(response => {
const parsedHtml = cheerio.load(response.data)
var rating = parsedHtml('body').find('#interest_sectl').first().find('strong').first()
if (rating.text()) {
resolve(rating.text())
} else {
resolve('暂无评分')
}
}).catch(err => {
reject(err)
})
} else {
resolve('暂无评分')
}
}).catch(err => {
reject(err)
})
})
}
}

View File

@@ -1,6 +1,6 @@
<template>
<div class="mini">
<div class="top">
<div class="header">
<div class="left">
<span class="title">
<span v-if="m3u8Arr.length > 1"> {{(video.index + 1)}} </span>{{name}}
@@ -22,7 +22,7 @@
<span class="progress" v-show="progress > 0">播放进度: {{progress}}%</span>
</div>
<div class="right">
<span class="top" @click="frameClickEvent('top')" title="置顶">
<span class="topping" @click="frameClickEvent('top')" title="置顶">
<svg t="1595919317571" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1188" style="width:10px;height:14px"><path d="M43.072 974.72l380.864-301.952 151.936 161.6c0 0 63.424 17.28 67.328-30.72l-3.904-163.584 225.088-259.648 98.048-5.696c0 0 76.928-15.488 21.184-82.752l-275.072-276.928c0 0-74.944-9.6-69.248 59.584l0 75.008L383.552 367.104 225.856 376.64c0 0-57.728 19.2-36.608 69.248l148.16 146.176L43.072 974.72 43.072 974.72z" p-id="1189" :fill="isAlwaysOnTop ? '#555555' : '#ffffff'"></path></svg>
</span>
<span class="min" @click="frameClickEvent('min')" title="最小化">
@@ -31,12 +31,12 @@
<span class="max" @click="frameClickEvent('max')" title="最大化">
<svg t="1595917343956" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1540" style="width:8px;height:14px"><path d="M416 416 64.064 416C28.448 416 0 444.64 0 479.936L0 544.064C0 579.264 28.672 608 64.064 608L416 608 416 959.936C416 995.552 444.64 1024 479.936 1024L544.064 1024C579.264 1024 608 995.328 608 959.936L608 608 959.936 608C995.552 608 1024 579.36 1024 544.064L1024 479.936C1024 444.736 995.328 416 959.936 416L608 416 608 64.064C608 28.448 579.36 0 544.064 0L479.936 0C444.736 0 416 28.672 416 64.064L416 416Z" p-id="1541" fill="#ffffff"></path></svg>
</span>
<span class="close" @click="frameClickEvent('close')" title="关闭">
<span class="close" @click="frameClickEvent('close')" title="退出精简模式">
<svg t="1595917372551" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1685" style="width:8px;height:14px"><path d="M511.968 376.224 796.096 92.096C833.536 54.624 894.4 54.624 931.84 92.096 969.312 129.568 969.312 190.4 931.84 227.872L647.744 512 931.84 796.096C969.312 833.568 969.312 894.4 931.84 931.872 894.4 969.344 833.536 969.344 796.096 931.872L511.968 647.744 227.84 931.872C190.4 969.344 129.536 969.344 92.096 931.872 54.624 894.4 54.624 833.568 92.096 796.096L376.224 512 92.096 227.872C54.624 190.4 54.624 129.568 92.096 92.096 129.536 54.624 190.4 54.624 227.84 92.096L511.968 376.224Z" p-id="1686" fill="#ffffff"></path></svg>
</span>
</div>
</div>
<div class="bottom">
<div class="footer">
<div id="xg"></div>
</div>
</div>
@@ -419,9 +419,10 @@ html,body{
justify-content: center;
align-items: flex-start;
flex-direction: column;
.top{
.header{
width: 100%;
height: 30px;
min-height: 30px;
display: flex;
justify-content: space-between;
align-items: center;
@@ -455,22 +456,27 @@ html,body{
}
}
.right{
width: 80px;
width: 100px;
height: 100%;
display: flex;
justify-content: flex-end;
align-items: center;
span{
-webkit-app-region: no-drag;
display: inline-block;
width: 14px;
height: 14px;
display: flex;
align-items: center;
justify-content: center;
width: 15px;
height: 15px;
text-align: center;
line-height: 14px;
line-height: 15px;
border-radius: 50%;
margin-right: 10px;
cursor: pointer;
opacity: 0.4;
&.topping{
background-color: #f3bab7;
}
&.min{
background-color: #32dc36;
}
@@ -480,9 +486,6 @@ html,body{
&.close{
background-color: #ff5f56;
}
&.top{
background-color: #f3bab7;
}
&:hover{
animation: heartbeat 3s ease-in-out infinite both;
}
@@ -513,7 +516,7 @@ html,body{
}
}
}
.bottom{
.footer{
width: 100%;
flex: 1;
.xgplayer-start{