mirror of
https://github.com/cuiocean/ZY-Player.git
synced 2026-02-14 16:06:48 +08:00
Compare commits
82 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef874d1831 | ||
|
|
bb9a8ca65d | ||
|
|
747abf3b26 | ||
|
|
1078cf3c63 | ||
|
|
22b877b0fb | ||
|
|
34e6b8bd08 | ||
|
|
4d039e9a63 | ||
|
|
16f3954959 | ||
|
|
17845e6ab4 | ||
|
|
292f932130 | ||
|
|
127ef9ad43 | ||
|
|
11f0ae27fd | ||
|
|
2599343943 | ||
|
|
0fb5903416 | ||
|
|
ce89720c55 | ||
|
|
8ff7fa588a | ||
|
|
8d5bbedfd8 | ||
|
|
713e0affae | ||
|
|
0f55f3b2ea | ||
|
|
c98e41201d | ||
|
|
2cfd31806d | ||
|
|
d54dab4e90 | ||
|
|
2af85fbfd1 | ||
|
|
15c542db82 | ||
|
|
1a3ccaa3ba | ||
|
|
3d01fd045f | ||
|
|
f6636a7864 | ||
|
|
dd108d3b09 | ||
|
|
0b24ded61f | ||
|
|
d21494cf86 | ||
|
|
76add8f87a | ||
|
|
5a115700e3 | ||
|
|
16e8ef2c4a | ||
|
|
483449aad8 | ||
|
|
2b7a425f6f | ||
|
|
a06c9e9d32 | ||
|
|
32a21952a2 | ||
|
|
ff01abe88c | ||
|
|
962f6b46c3 | ||
|
|
b16604add6 | ||
|
|
3028939ed9 | ||
|
|
1ffcb38b4b | ||
|
|
2ec05b6ab5 | ||
|
|
9cbd37d143 | ||
|
|
b9ab1b11f4 | ||
|
|
428f49a2e8 | ||
|
|
2e8941c6cc | ||
|
|
91e2fc56b7 | ||
|
|
e2b124e4ac | ||
|
|
6b37e3ebd5 | ||
|
|
5dcdb6a410 | ||
|
|
5d41f783bc | ||
|
|
28ad8f3313 | ||
|
|
c475fbdf46 | ||
|
|
ee622f88da | ||
|
|
1b2461c423 | ||
|
|
3044bfcbc4 | ||
|
|
4038e5e6be | ||
|
|
bea1ef4c73 | ||
|
|
7af9a6d76d | ||
|
|
2140d90a87 | ||
|
|
e86eef1b05 | ||
|
|
42dd8fe5e4 | ||
|
|
9fd8c60dd5 | ||
|
|
49c480061b | ||
|
|
022b1f4090 | ||
|
|
9c08a64524 | ||
|
|
90ec848c11 | ||
|
|
82270a702f | ||
|
|
61dcb1ec49 | ||
|
|
40b853361e | ||
|
|
57ff3325f0 | ||
|
|
c4283e2da0 | ||
|
|
7052bd7e05 | ||
|
|
64a12a06c4 | ||
|
|
3df3b385ce | ||
|
|
e77db4711e | ||
|
|
fb3fd26870 | ||
|
|
72790f5f3e | ||
|
|
ea2815969d | ||
|
|
e330cff7d4 | ||
|
|
da5b91535e |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "zy",
|
||||
"version": "2.5.4",
|
||||
"version": "2.6.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
|
||||
@@ -5,16 +5,7 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
<script>
|
||||
var _hmt = _hmt || [];
|
||||
(function() {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?62aeb2505bfa26a2461d2a7a3b485096";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
</script>
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
&.name{
|
||||
flex: 1;
|
||||
min-width: 100px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
margin-left: 10px;
|
||||
}
|
||||
&.type{
|
||||
@@ -170,6 +170,9 @@
|
||||
&.note{
|
||||
width: 10%;
|
||||
}
|
||||
&.info{
|
||||
width: 10%;
|
||||
}
|
||||
&.operate{
|
||||
.btn{
|
||||
width: 40px;
|
||||
@@ -206,44 +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;
|
||||
}
|
||||
}
|
||||
.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 {
|
||||
@@ -271,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%;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
|
||||
import { initUpdater } from './lib/update/update'
|
||||
const isDevelopment = process.env.NODE_ENV !== 'production'
|
||||
|
||||
// 允许跨域
|
||||
app.commandLine.appendSwitch('disable-features', 'OutOfBlinkCors')
|
||||
app.commandLine.appendSwitch('disable-features', 'OutOfBlinkCors') // 允许跨域
|
||||
// app.commandLine.appendSwitch('--ignore-certificate-errors', 'true') // 忽略证书相关错误
|
||||
|
||||
let win
|
||||
let mini
|
||||
@@ -52,6 +52,7 @@ function createMini () {
|
||||
frame: false,
|
||||
resizable: true,
|
||||
webPreferences: {
|
||||
sandbox: false,
|
||||
webSecurity: false,
|
||||
enableRemoteModule: true,
|
||||
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION
|
||||
@@ -76,6 +77,7 @@ if (process.platform === 'darwin') {
|
||||
}
|
||||
if (process.platform === 'Linux') {
|
||||
app.disableHardwareAcceleration()
|
||||
app.commandLine.appendSwitch('--no-sandbox') // linux 关闭沙盒模式
|
||||
}
|
||||
app.allowRendererProcessReuse = true
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -78,8 +85,6 @@ export default {
|
||||
this.detail = {
|
||||
show: false
|
||||
}
|
||||
const _hmt = window._hmt
|
||||
_hmt.push(['_trackEvent', 'page', 'view', e])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 () {
|
||||
@@ -326,9 +295,6 @@ export default {
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
const _hmt = window._hmt
|
||||
const name = this.detail.info.name
|
||||
_hmt.push(['_trackEvent', 'detail', 'view', name])
|
||||
}
|
||||
},
|
||||
created () {
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
<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.stop="addSite" icon="el-icon-document-add">新增</el-button>
|
||||
<el-button @click.stop="exportSites" icon="el-icon-upload2" >导出</el-button>
|
||||
<el-button @click.stop="importSites" icon="el-icon-download">导入</el-button>
|
||||
<el-button @click.stop="removeAllSites" icon="el-icon-delete-solid">清空</el-button>
|
||||
<el-button @click.stop="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"
|
||||
@selection-change="handleSelectionChange"
|
||||
@sort-change="handleSortChange">
|
||||
@@ -52,18 +52,33 @@
|
||||
<el-button type="text">{{scope.row.group}}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<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>
|
||||
检测中...
|
||||
</span>
|
||||
<span v-show="scope.row.status !== ''">{{scope.row.status}}</span>
|
||||
</template>
|
||||
</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">
|
||||
@@ -78,7 +93,9 @@
|
||||
<el-input v-model="siteInfo.download" :autosize="{ minRows: 2, maxRows: 4}" type="textarea" placeholder="请输入Download接口地址,可以空着"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="分组" prop='group'>
|
||||
<el-input v-model="siteInfo.group" :autosize="{ minRows: 2, maxRows: 4}" type="textarea" placeholder="请输入分组"/>
|
||||
<el-select v-model="siteInfo.group" allow-create filterable default-first-option placeholder="请输入分组">
|
||||
<el-option v-for="item in siteGroup" :key="item" :label="item" :value="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="源站标识" prop='key'>
|
||||
<el-input v-model="siteInfo.key" placeholder="请输入源站标识,如果为空,系统则自动生成" />
|
||||
@@ -90,13 +107,12 @@
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import { sites } from '../lib/dexie'
|
||||
import zy from '../lib/site/tools'
|
||||
import { remote } from 'electron'
|
||||
import { sites as defaultSites } from '../lib/dexie/initData'
|
||||
import fs from 'fs'
|
||||
@@ -118,6 +134,7 @@ export default {
|
||||
group: '',
|
||||
isActive: 1
|
||||
},
|
||||
siteGroup: [],
|
||||
rules: {
|
||||
name: [
|
||||
{ required: true, message: '源站名不能为空', trigger: 'blur' }
|
||||
@@ -132,7 +149,10 @@ export default {
|
||||
enableBatchEdit: false,
|
||||
batchGroupName: '',
|
||||
batchIsActive: 1,
|
||||
multipleSelection: []
|
||||
multipleSelection: [],
|
||||
tableKey: 1,
|
||||
checkAllSiteLoading: false,
|
||||
editeOldkey: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -192,8 +212,21 @@ export default {
|
||||
sites: res
|
||||
}
|
||||
})
|
||||
for (const i of this.sites) {
|
||||
delete i.status
|
||||
}
|
||||
},
|
||||
getSitesGroup () {
|
||||
const arr = []
|
||||
for (const i of this.sites) {
|
||||
if (arr.indexOf(i.group) < 0) {
|
||||
arr.push(i.group)
|
||||
}
|
||||
}
|
||||
this.siteGroup = arr
|
||||
},
|
||||
addSite () {
|
||||
this.getSitesGroup()
|
||||
this.dialogType = 'new'
|
||||
this.dialogVisible = true
|
||||
this.siteInfo = {
|
||||
@@ -206,15 +239,25 @@ export default {
|
||||
}
|
||||
},
|
||||
editSite (siteInfo) {
|
||||
this.getSitesGroup()
|
||||
if (this.checkAllSiteLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
return false
|
||||
}
|
||||
this.dialogType = 'edit'
|
||||
this.dialogVisible = true
|
||||
this.siteInfo = siteInfo
|
||||
this.editeOldkey = siteInfo.key
|
||||
},
|
||||
closeDialog () {
|
||||
this.dialogVisible = false
|
||||
this.getSites()
|
||||
},
|
||||
removeEvent (e) {
|
||||
if (this.checkAllSiteLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
return false
|
||||
}
|
||||
sites.remove(e.id).then(res => {
|
||||
this.getSites()
|
||||
}).catch(err => {
|
||||
@@ -232,10 +275,26 @@ export default {
|
||||
})
|
||||
})
|
||||
},
|
||||
checkSiteKey (e) {
|
||||
if (this.dialogType === 'edit' && this.editeOldkey === this.siteInfo.key) {
|
||||
return true
|
||||
} else {
|
||||
for (const i of this.sites) {
|
||||
if (i.key === this.siteInfo.key) {
|
||||
this.$message.warning(`源站标识: ${i.key} 已存在, 请勿重复填写.`)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
},
|
||||
addOrEditSite () {
|
||||
if (!this.siteInfo.name || !this.siteInfo.api) {
|
||||
this.$message.error('名称和API接口不能为空。')
|
||||
return
|
||||
return false
|
||||
}
|
||||
if (!this.checkSiteKey()) {
|
||||
return false
|
||||
}
|
||||
var randomstring = require('randomstring')
|
||||
var doc = {
|
||||
@@ -247,8 +306,6 @@ export default {
|
||||
group: this.siteInfo.group,
|
||||
isActive: this.siteInfo.isActive
|
||||
}
|
||||
const _hmt = window._hmt
|
||||
_hmt.push(['_trackEvent', 'site', 'add', `${this.siteInfo.name}: ${this.siteInfo.api}`])
|
||||
if (this.dialogType === 'edit') sites.remove(this.siteInfo.id)
|
||||
sites.add(doc).then(res => {
|
||||
this.siteInfo = {
|
||||
@@ -262,6 +319,7 @@ export default {
|
||||
this.dialogVisible = false
|
||||
this.getSites()
|
||||
})
|
||||
this.editeOldkey = ''
|
||||
},
|
||||
exportSites () {
|
||||
this.getSites()
|
||||
@@ -322,6 +380,10 @@ export default {
|
||||
this.$message.success('重置源成功')
|
||||
},
|
||||
moveToTopEvent (i) {
|
||||
if (this.checkAllSiteLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
return false
|
||||
}
|
||||
this.sites.sort(function (x, y) { return x.key === i.key ? -1 : y.key === i.key ? 1 : 0 })
|
||||
this.updateDatabase()
|
||||
},
|
||||
@@ -365,10 +427,41 @@ export default {
|
||||
_this.updateDatabase()
|
||||
}
|
||||
})
|
||||
},
|
||||
async checkAllSite () {
|
||||
this.checkAllSiteLoading = true
|
||||
for (const i of this.sites) {
|
||||
i.status = ''
|
||||
this.tableKey = Math.random()
|
||||
const flag = await zy.check(i.key)
|
||||
if (flag) {
|
||||
i.status = '可用'
|
||||
} else {
|
||||
i.status = '失效'
|
||||
i.isActive = 0
|
||||
}
|
||||
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 () {
|
||||
this.rowDrop()
|
||||
this.checkAllSiteLoading = false
|
||||
},
|
||||
created () {
|
||||
this.getSites()
|
||||
|
||||
@@ -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">
|
||||
@@ -13,7 +13,7 @@
|
||||
<div class="vs-placeholder" @click="show.classList = true">{{type.name}}</div>
|
||||
<div class="vs-options" v-show="show.classList">
|
||||
<ul class="zy-scroll" style="max-height: 600px;">
|
||||
<li :class="type.tid === i.tid ? 'active' : ''" v-for="i in classList" :key="i.tid" @click="classClick(i)">{{ i.name }}</li>
|
||||
<li :class="type.tid === i.tid ? 'active' : ''" v-for="i in classList" :key="i.tid" @click="classClick(i)">{{ i.name | classNameFilter }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -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,53 +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="site">{{i.site.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(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>
|
||||
@@ -184,6 +254,11 @@ export default {
|
||||
return this.$store.getters.getEditSites.sites // 需要监听的数据
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
classNameFilter: (name) => {
|
||||
return name.replace(/[^\u4e00-\u9fa5]/gi, '')
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
view () {
|
||||
this.changeView()
|
||||
@@ -214,8 +289,6 @@ export default {
|
||||
}
|
||||
})
|
||||
}
|
||||
const _hmt = window._hmt
|
||||
_hmt.push(['_trackEvent', 'site', 'change', e.name])
|
||||
},
|
||||
classClick (e) {
|
||||
this.show.classList = false
|
||||
@@ -226,8 +299,6 @@ export default {
|
||||
this.infiniteId += 1
|
||||
}
|
||||
})
|
||||
const _hmt = window._hmt
|
||||
_hmt.push(['_trackEvent', 'class', 'change', e.name])
|
||||
},
|
||||
getClass () {
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -328,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('收藏成功')
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
@@ -392,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
|
||||
@@ -410,8 +480,6 @@ export default {
|
||||
} else {
|
||||
this.searchSingleSiteEvent(this.site, wd)
|
||||
}
|
||||
const _hmt = window._hmt
|
||||
_hmt.push(['_trackEvent', 'film', 'search', wd])
|
||||
},
|
||||
searchAllSitesEvent (sites, wd) {
|
||||
this.searchTxt = wd
|
||||
@@ -431,13 +499,17 @@ export default {
|
||||
const type = Object.prototype.toString.call(res)
|
||||
if (type === '[object Array]') {
|
||||
res.forEach(element => {
|
||||
element.site = site
|
||||
this.searchContents.push(element)
|
||||
zy.detail(site.key, element.id).then(detailRes => {
|
||||
detailRes.site = site
|
||||
this.searchContents.push(detailRes)
|
||||
})
|
||||
})
|
||||
}
|
||||
if (type === '[object Object]') {
|
||||
res.site = site
|
||||
this.searchContents.push(res)
|
||||
zy.detail(site.key, res.id).then(detailRes => {
|
||||
detailRes.site = site
|
||||
this.searchContents.push(detailRes)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -493,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>
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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 () {
|
||||
}
|
||||
|
||||
@@ -3,23 +3,20 @@
|
||||
<div class="box">
|
||||
<div class="title">
|
||||
<span v-if="this.right.list.length > 1">『第 {{(video.info.index + 1)}} 集』</span>{{name}}
|
||||
<span v-if="video.key" class="right" @click="playWithExternalPalyerEvent" title="使用第三方播放器">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<polygon points="20 8 20 20 4 20 4 8"></polygon>
|
||||
<polyline stroke-linejoin="round" points="8 4 12 7.917 16 4"></polyline>
|
||||
</svg>
|
||||
</span>
|
||||
<span v-if="video.key" class="right" @click="issueEvent" title="复制调试信息">
|
||||
<svg t="1596338860607" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3127" width="24" height="24">
|
||||
<path d="M503.803829 63.578014c-247.050676 0-447.328072 200.277396-447.328072 447.327048 0 247.054769 200.277396 447.333188 447.328072 447.333188 247.054769 0 447.332165-200.278419 447.332165-447.333188C951.13497 263.85541 750.858598 63.578014 503.803829 63.578014L503.803829 63.578014zM503.803829 894.313336c-211.749682 0-383.408273-171.659615-383.408273-383.408273 0-211.749682 171.659615-383.40725 383.408273-383.40725 211.753775 0 383.412366 171.658591 383.412366 383.40725C887.216195 722.653721 715.557604 894.313336 503.803829 894.313336L503.803829 894.313336zM447.745069 255.897158l127.914298 0L575.659367 383.576095 447.745069 383.576095 447.745069 255.897158 447.745069 255.897158zM447.745069 425.470251l127.914298 0 0 342.058516L447.745069 767.528767 447.745069 425.470251 447.745069 425.470251zM447.745069 425.470251" p-id="3128"></path>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
<div class="player">
|
||||
<div id="xgplayer"></div>
|
||||
</div>
|
||||
<div class="more">
|
||||
<span class="zy-svg" @click="nextEvent" v-show="showNext">
|
||||
<span class="zy-svg" @click="otherEvent" v-show="name !== ''">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="coloursIconTitle">
|
||||
<title id="coloursIconTitle">换源</title>
|
||||
<circle cx="12" cy="9" r="5"></circle>
|
||||
<circle cx="9" cy="14" r="5"></circle>
|
||||
<circle cx="15" cy="14" r="5"></circle>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="zy-svg" @click="nextEvent" v-show="right.list.length > 1">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="forwardIconTitle">
|
||||
<title id="forwardIconTitle">下一集</title>
|
||||
<path d="M10 14.74L3 19V5l7 4.26V5l12 7-12 7v-4.26z"></path>
|
||||
@@ -58,8 +55,14 @@
|
||||
</svg>
|
||||
</span>
|
||||
<span class="zy-svg" @click="miniEvent" v-show="right.list.length > 0">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-labelledby="diamondIconTitle">
|
||||
<title id="diamondIconTitle">精简模式</title>
|
||||
<path d="M12 20L3 11M12 20L21 11M12 20L8 11M12 20L16 11M3 11L7 5M3 11H8M7 5L8 11M7 5H12M17 5L21 11M17 5L16 11M17 5H12M21 11H16M8 11H16M8 11L12 5M16 11L12 5"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="zy-svg" @click="playWithExternalPalyerEvent" 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="tvIconTitle">
|
||||
<title id="tvIconTitle">精简模式</title>
|
||||
<title id="tvIconTitle" >使用第三方播放器</title>
|
||||
<polygon points="20 8 20 20 4 20 4 8"></polygon>
|
||||
<polyline stroke-linejoin="round" points="8 4 12 7.917 16 4"></polyline>
|
||||
</svg>
|
||||
@@ -81,13 +84,30 @@
|
||||
<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>
|
||||
<path d="M12,12 L12,15"></path>
|
||||
<line x1="12" y1="9" x2="12" y2="9"></line>
|
||||
<circle cx="12" cy="12" r="10"></circle>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="last-tip" v-if="!video.key && right.history.length > 0" @click="historyItemEvent(right.history[0])">上次播放到【{{right.history[0].site}}】{{right.history[0].name}} 第{{right.history[0].index+1}}集</span>
|
||||
</div>
|
||||
</div>
|
||||
<transition name="slideX">
|
||||
<div v-if="right.show" class="list">
|
||||
<div class="list-top">
|
||||
<span class="list-top-title">{{ right.type === 'list' ? '播放列表' : '历史记录' }}</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>
|
||||
@@ -106,6 +126,13 @@
|
||||
<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.name}}]</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
@@ -113,7 +140,7 @@
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import { star, history, setting, shortcut, mini, iptv } from '../lib/dexie'
|
||||
import { star, history, setting, shortcut, mini, iptv, sites } from '../lib/dexie'
|
||||
import zy from '../lib/site/tools'
|
||||
import Player from 'xgplayer'
|
||||
import Hls from 'xgplayer-hls.js'
|
||||
@@ -171,7 +198,9 @@ export default {
|
||||
show: false,
|
||||
type: '',
|
||||
list: [],
|
||||
history: []
|
||||
history: [],
|
||||
shortcut: [],
|
||||
other: []
|
||||
},
|
||||
config: {
|
||||
id: 'xgplayer',
|
||||
@@ -202,7 +231,6 @@ export default {
|
||||
length: 0,
|
||||
timer: null,
|
||||
scroll: false,
|
||||
showNext: false,
|
||||
isStar: false,
|
||||
isTop: false,
|
||||
mini: {},
|
||||
@@ -288,6 +316,9 @@ export default {
|
||||
methods: {
|
||||
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
|
||||
async getUrls () {
|
||||
if (this.video.key === '') {
|
||||
return false
|
||||
}
|
||||
this.name = ''
|
||||
if (this.timer !== null) {
|
||||
clearInterval(this.timer)
|
||||
@@ -302,8 +333,6 @@ export default {
|
||||
this.playUrl(this.video.iptv.url)
|
||||
this.name = this.video.iptv.name
|
||||
this.getIptvList()
|
||||
const _hmt = window._hmt
|
||||
_hmt.push(['_trackEvent', 'IPTV', 'play', this.name])
|
||||
} else {
|
||||
const index = this.video.info.index | 0
|
||||
let time = 0
|
||||
@@ -323,7 +352,6 @@ export default {
|
||||
playVideo (index = 0, time = 0) {
|
||||
this.fetchM3u8List().then(m3u8Arr => {
|
||||
this.xg.src = m3u8Arr[index]
|
||||
this.showNext = m3u8Arr.length > 1
|
||||
|
||||
if (time !== 0) {
|
||||
this.xg.play()
|
||||
@@ -350,12 +378,9 @@ export default {
|
||||
if (VIDEO_DETAIL_CACHE[cacheKey]) {
|
||||
this.name = VIDEO_DETAIL_CACHE[cacheKey].name
|
||||
resolve(VIDEO_DETAIL_CACHE[cacheKey].list)
|
||||
return
|
||||
}
|
||||
zy.detail(this.video.key, this.video.info.id).then(res => {
|
||||
this.name = res.name
|
||||
const _hmt = window._hmt
|
||||
_hmt.push(['_trackEvent', 'film', 'play', res.name])
|
||||
const dd = res.dl.dd
|
||||
const type = Object.prototype.toString.call(dd)
|
||||
let m3u8Txt = []
|
||||
@@ -520,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
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
@@ -720,6 +744,42 @@ export default {
|
||||
this.$message.warning('删除历史记录失败, 错误信息: ' + err)
|
||||
})
|
||||
},
|
||||
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]') {
|
||||
searchRes.forEach(async item => {
|
||||
const detailRes = item
|
||||
detailRes.key = siteItem.key
|
||||
detailRes.site = siteItem
|
||||
this.right.other.push(detailRes)
|
||||
})
|
||||
}
|
||||
if (type === '[object Object]') {
|
||||
const detailRes = searchRes
|
||||
detailRes.key = siteItem.key
|
||||
detailRes.site = siteItem
|
||||
this.right.other.push(detailRes)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
otherEvent (m) {
|
||||
this.right.type = 'other'
|
||||
this.getOtherSites()
|
||||
this.right.show = true
|
||||
},
|
||||
async otherItemEvent (e) {
|
||||
// 打开当前播放的剧集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 = ''
|
||||
},
|
||||
mtEvent () {
|
||||
setting.find().then(res => {
|
||||
if (res.shortcut) {
|
||||
@@ -1000,18 +1060,17 @@ export default {
|
||||
let timerID
|
||||
ev.forEach(item => {
|
||||
this.xg.root.addEventListener(item, () => {
|
||||
if (!this.xg.fullscreen) {
|
||||
return
|
||||
if (this.xg && this.xg.fullscreen) {
|
||||
const videoTitle = document.querySelector('.xg-view-videoTitle')
|
||||
videoTitle.style.display = 'block'
|
||||
clearTimeout(timerID)
|
||||
timerID = setTimeout(() => {
|
||||
// 播放中自动消失
|
||||
if (this.xg && !this.xg.paused) {
|
||||
videoTitle.style.display = 'none'
|
||||
}
|
||||
}, 3000)
|
||||
}
|
||||
const videoTitle = document.querySelector('.xg-view-videoTitle')
|
||||
videoTitle.style.display = 'block'
|
||||
clearTimeout(timerID)
|
||||
timerID = setTimeout(() => {
|
||||
// 播放中自动消失
|
||||
if (this.xg && !this.xg.paused) {
|
||||
videoTitle.style.display = 'none'
|
||||
}
|
||||
}, 3000)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1023,13 +1082,15 @@ export default {
|
||||
if (this.xg.fullscreen) {
|
||||
this.xg.exitFullscreen()
|
||||
}
|
||||
clearInterval(this.timer)
|
||||
this.video.key = ''
|
||||
this.xg.src = ''
|
||||
this.config.src = ''
|
||||
this.xg.destroy(false)
|
||||
this.xg = null
|
||||
this.name = ''
|
||||
this.right.list = []
|
||||
this.showNext = false
|
||||
this.getAllhistory()
|
||||
setTimeout(() => {
|
||||
this.xg = new Hls(this.config)
|
||||
this.playerInstall()
|
||||
@@ -1075,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 () {
|
||||
|
||||
307
src/components/Recommandation.vue
Normal file
307
src/components/Recommandation.vue
Normal 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>
|
||||
@@ -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>
|
||||
@@ -145,7 +172,6 @@ import { setting, sites, shortcut } from '../lib/dexie'
|
||||
import { sites as defaultSites } from '../lib/dexie/initData'
|
||||
import { shell, clipboard, remote, ipcRenderer } from 'electron'
|
||||
import db from '../lib/dexie/dexie'
|
||||
const _hmt = window._hmt
|
||||
export default {
|
||||
name: 'setting',
|
||||
data () {
|
||||
@@ -156,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: {
|
||||
@@ -211,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
|
||||
})
|
||||
},
|
||||
@@ -257,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)
|
||||
},
|
||||
@@ -301,16 +306,52 @@ 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
|
||||
this.updateSettingEvent()
|
||||
_hmt.push(['_trackEvent', 'setting', 'theme', e])
|
||||
},
|
||||
changeShortcut (e) {
|
||||
this.d.shortcut = e
|
||||
@@ -335,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()
|
||||
@@ -364,6 +413,7 @@ export default {
|
||||
})
|
||||
},
|
||||
quitAndInstall () {
|
||||
this.$message.success('已开始下载更新,下载完毕后,将自动退出安装。')
|
||||
ipcRenderer.send('quitAndInstall')
|
||||
},
|
||||
createContextMenu () {
|
||||
@@ -520,9 +570,9 @@ export default {
|
||||
line-height: 32px;
|
||||
}
|
||||
.clearTips{
|
||||
margin: 10px 0 0 20px;
|
||||
font-size: 12px;
|
||||
color: #ff000088;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
.Tips{
|
||||
|
||||
@@ -69,8 +69,6 @@ export default {
|
||||
const id = this.share.info.ids || this.share.info.id
|
||||
zy.detail(this.share.key, id).then(res => {
|
||||
if (res) {
|
||||
const _hmt = window._hmt
|
||||
_hmt.push(['_trackEvent', 'film', 'share', res.name])
|
||||
this.pic = res.pic
|
||||
var m3u8List = {}
|
||||
const dd = res.dl.dd
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
1670
src/lib/dexie/iniData/Iptv.json
Normal file
1670
src/lib/dexie/iniData/Iptv.json
Normal file
File diff suppressed because it is too large
Load Diff
6363
src/lib/dexie/iniData/Recommandations.json
Normal file
6363
src/lib/dexie/iniData/Recommandations.json
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
28
src/lib/dexie/recommandation.js
Normal file
28
src/lib/dexie/recommandation.js
Normal 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()
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import Vue from 'vue'
|
||||
import { Message, Button, Table, TableColumn, Tag, Input, Dialog, Form, FormItem, Switch } from 'element-ui'
|
||||
import { Message, Button, Table, TableColumn, Tag, Input, Dialog, Form, FormItem, Switch, Select, Option } from 'element-ui'
|
||||
import Plugin from 'v-fit-columns'
|
||||
Vue.use(Button)
|
||||
Vue.use(Table)
|
||||
@@ -11,4 +11,6 @@ Vue.use(Form)
|
||||
Vue.use(FormItem)
|
||||
Vue.use(Switch)
|
||||
Vue.use(Plugin)
|
||||
Vue.use(Select)
|
||||
Vue.use(Option)
|
||||
Vue.prototype.$message = Message
|
||||
|
||||
@@ -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,
|
||||
@@ -193,6 +195,69 @@ const zy = {
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 检查资源
|
||||
* @param {*} key 资源网 key
|
||||
* @returns boolean
|
||||
*/
|
||||
async check (key, id) {
|
||||
try {
|
||||
const cls = await this.class(key)
|
||||
if (cls) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} 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)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -395,8 +395,6 @@ export default {
|
||||
this.xg = new Hls(this.config)
|
||||
this.mtEvent()
|
||||
this.getUrls()
|
||||
const _hmt = window._hmt
|
||||
_hmt.push(['_trackEvent', 'page', 'view', 'mini'])
|
||||
},
|
||||
beforeDestroy () {
|
||||
clearInterval(this.timer)
|
||||
@@ -421,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;
|
||||
@@ -457,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;
|
||||
}
|
||||
@@ -482,9 +486,6 @@ html,body{
|
||||
&.close{
|
||||
background-color: #ff5f56;
|
||||
}
|
||||
&.top{
|
||||
background-color: #f3bab7;
|
||||
}
|
||||
&:hover{
|
||||
animation: heartbeat 3s ease-in-out infinite both;
|
||||
}
|
||||
@@ -515,7 +516,7 @@ html,body{
|
||||
}
|
||||
}
|
||||
}
|
||||
.bottom{
|
||||
.footer{
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
.xgplayer-start{
|
||||
|
||||
Reference in New Issue
Block a user