mirror of
https://github.com/cuiocean/ZY-Player.git
synced 2026-02-14 16:06:48 +08:00
Compare commits
175 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26bcdd4101 | ||
|
|
5104f9a85d | ||
|
|
d61ee76e58 | ||
|
|
b1a683a8db | ||
|
|
5d0dc1bed7 | ||
|
|
3481a5346e | ||
|
|
c957fe33e2 | ||
|
|
51aa21e551 | ||
|
|
a887968458 | ||
|
|
380d31c0d3 | ||
|
|
46b5f82348 | ||
|
|
675622e9ee | ||
|
|
9a67821984 | ||
|
|
e457574755 | ||
|
|
50f5154628 | ||
|
|
9da7ffc451 | ||
|
|
35adae51cc | ||
|
|
fe75edd738 | ||
|
|
362dccb167 | ||
|
|
08e95611ea | ||
|
|
739b3fe30f | ||
|
|
3ba2dc9993 | ||
|
|
6543d8baf0 | ||
|
|
a1c9c657e3 | ||
|
|
9306adb60e | ||
|
|
682c706618 | ||
|
|
02c04c3d46 | ||
|
|
17c78522bb | ||
|
|
7af6c73084 | ||
|
|
d31e0daca9 | ||
|
|
9a7534ba57 | ||
|
|
a73e679b72 | ||
|
|
4f6c248345 | ||
|
|
68a0226759 | ||
|
|
e72af95c75 | ||
|
|
559e85785f | ||
|
|
2bf69fb0b9 | ||
|
|
c082986e09 | ||
|
|
05d71a62aa | ||
|
|
bb537d789d | ||
|
|
11baacc778 | ||
|
|
9dbc0e00dc | ||
|
|
23e5c569b1 | ||
|
|
59a89e280b | ||
|
|
b72886fbe6 | ||
|
|
75bac6582c | ||
|
|
7cc7e4e0e6 | ||
|
|
b1707f88d6 | ||
|
|
9ca946eb66 | ||
|
|
76ed091c78 | ||
|
|
5965c55773 | ||
|
|
6631b8f568 | ||
|
|
b7bb5f85a3 | ||
|
|
c8795e2aa9 | ||
|
|
2d7f012180 | ||
|
|
95ae729df8 | ||
|
|
40218521ac | ||
|
|
f4396cb69f | ||
|
|
2dfbc8a8a2 | ||
|
|
f94e8f0bec | ||
|
|
a9011abdf0 | ||
|
|
843a8dd1fc | ||
|
|
9b5aae095e | ||
|
|
24e890d1ab | ||
|
|
959f515f55 | ||
|
|
f97d63cf68 | ||
|
|
c2f3a60198 | ||
|
|
9128f407ce | ||
|
|
c5c6e5e34f | ||
|
|
b12cdf25d5 | ||
|
|
7c08627e6f | ||
|
|
68c3687da3 | ||
|
|
00d6f2d218 | ||
|
|
a918713bf7 | ||
|
|
ae7aaec623 | ||
|
|
81476e0f20 | ||
|
|
4136b0f3ce | ||
|
|
c3a4cf5cc5 | ||
|
|
d2263f3f76 | ||
|
|
71df73fbd3 | ||
|
|
ba6f3df9b1 | ||
|
|
35c205fd86 | ||
|
|
30796af5f8 | ||
|
|
fde5dbb89d | ||
|
|
df3b43d8ac | ||
|
|
8f94a5604d | ||
|
|
c6a39591d5 | ||
|
|
051d6b7701 | ||
|
|
51ba1d87ad | ||
|
|
9af55df310 | ||
|
|
d82251fb02 | ||
|
|
4d192a4c3a | ||
|
|
1f25219cdc | ||
|
|
25d65866ae | ||
|
|
11559ca164 | ||
|
|
6c82178604 | ||
|
|
029d1d9b49 | ||
|
|
c10f7b98d9 | ||
|
|
48d4b369a8 | ||
|
|
42d2b5c20f | ||
|
|
ccbafaae39 | ||
|
|
fb3b908fe8 | ||
|
|
4c4cc6d81b | ||
|
|
9ccfefaafb | ||
|
|
15a38f1b9c | ||
|
|
967657e0ac | ||
|
|
cd08e9e14b | ||
|
|
7e5bd534ef | ||
|
|
dce2e36ef0 | ||
|
|
8a72b30f79 | ||
|
|
bbe0d157f4 | ||
|
|
f44f8ea6cf | ||
|
|
cd6f9f1f53 | ||
|
|
74d084cb7b | ||
|
|
e60962a0f5 | ||
|
|
459a54382f | ||
|
|
e08a90d87a | ||
|
|
c676159cc7 | ||
|
|
0fc8e54d26 | ||
|
|
fe858a0cd9 | ||
|
|
2238ddd109 | ||
|
|
cc1c100075 | ||
|
|
81ba6de6cb | ||
|
|
28baca56c4 | ||
|
|
3493831729 | ||
|
|
42fce7d137 | ||
|
|
c7a4b389e1 | ||
|
|
5f47789a1a | ||
|
|
7591c30b59 | ||
|
|
dd43c18491 | ||
|
|
6949eb16d6 | ||
|
|
4a369a755e | ||
|
|
e1b1742424 | ||
|
|
de31c4c0bb | ||
|
|
c85910edd0 | ||
|
|
b8d78bab10 | ||
|
|
9eed5ce0b7 | ||
|
|
4b11cab4bf | ||
|
|
6ffbc2a63c | ||
|
|
c6f4917cdc | ||
|
|
fe37b32a0f | ||
|
|
7fb295d34c | ||
|
|
e8c5c0ec72 | ||
|
|
64dc9c98d2 | ||
|
|
ca36841f5d | ||
|
|
59d33d201c | ||
|
|
bf3b6d4088 | ||
|
|
bf2567bfde | ||
|
|
3499fb5937 | ||
|
|
dec12c77d0 | ||
|
|
17be5d45f1 | ||
|
|
f493fcd24e | ||
|
|
d040bc01fc | ||
|
|
6644c97811 | ||
|
|
68960ab5bb | ||
|
|
46de044214 | ||
|
|
0cbf9ca7fb | ||
|
|
6fa40af9bd | ||
|
|
7343f1824a | ||
|
|
3df0665950 | ||
|
|
022b1b28ad | ||
|
|
55d1740354 | ||
|
|
9d71991103 | ||
|
|
361e24ecad | ||
|
|
53f80d2cce | ||
|
|
880dd9ff35 | ||
|
|
42c89120da | ||
|
|
d990aa92b0 | ||
|
|
e117564ecb | ||
|
|
99592e3fcb | ||
|
|
adc8fd4329 | ||
|
|
579caddaeb | ||
|
|
1d5344f292 | ||
|
|
22dc74ea3a | ||
|
|
72d7c91540 |
@@ -29,6 +29,7 @@
|
||||
### ✨特性
|
||||
|
||||
- 🍕 全平台支持. Windows, Mac, Linux
|
||||
- 🍥 支持 IPTV, 卫视直播
|
||||
- 🍔 视频源支持自定义, 支持导入, 导出
|
||||
- 🍟 支持海报模式和列表模式浏览资源
|
||||
- 🌭 播放历史, 自动跳转历史进度
|
||||
@@ -84,9 +85,3 @@
|
||||
| :----------------------------------------------------------: | :----------------------------------------------------------: |
|
||||
| <img width="120" src="https://avatars2.githubusercontent.com/u/15273630?s=460&u=48cf3299e2a842c0252233d8be42ef4c5d792138&v=4"/> | <img width="120" src="https://avatars0.githubusercontent.com/u/5760235?s=460&u=9d969dd8d83f069ce7ebd60516770c93ac07a330&v=4" /> |
|
||||
| 💻 🎨 🐛 | 💻 🐛 |
|
||||
|
||||
|
||||
|
||||
### 🧧 赞助
|
||||
|
||||
[](https://latopay.com/@Hunlongyu)
|
||||
|
||||
24
package.json
24
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "zy",
|
||||
"version": "2.6.1",
|
||||
"version": "2.6.5",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
@@ -17,29 +17,33 @@
|
||||
},
|
||||
"main": "background.js",
|
||||
"dependencies": {
|
||||
"axios": "^0.20.0",
|
||||
"axios": "^0.21.0",
|
||||
"cheerio": "^1.0.0-rc.3",
|
||||
"child_process": "^1.0.2",
|
||||
"core-js": "^3.6.5",
|
||||
"core-js": "^3.7.0",
|
||||
"cors": "^2.8.5",
|
||||
"dexie": "^3.0.2",
|
||||
"electron-localshortcut": "^3.2.1",
|
||||
"electron-proxy-agent": "^1.2.0",
|
||||
"electron-updater": "^4.3.5",
|
||||
"element-ui": "^2.13.2",
|
||||
"element-ui": "^2.14.0",
|
||||
"express": "^4.17.1",
|
||||
"fast-xml-parser": "^3.17.4",
|
||||
"html2canvas": "^1.0.0-rc.7",
|
||||
"iptv-playlist-parser": "^0.5.0",
|
||||
"m3u": "0.0.2",
|
||||
"m3u8-parser": "^4.5.0",
|
||||
"memcached": "^2.2.2",
|
||||
"modern-normalize": "^1.0.0",
|
||||
"mousetrap": "^1.6.5",
|
||||
"qrcode.vue": "^1.7.0",
|
||||
"randomstring": "^1.1.5",
|
||||
"session": "^0.1.0",
|
||||
"v-fit-columns": "^0.2.0",
|
||||
"vue": "^2.6.12",
|
||||
"vue-clickaway": "^2.2.2",
|
||||
"vue-infinite-loading": "^2.4.5",
|
||||
"vue-waterfall-plugin": "^1.1.0",
|
||||
"vuedraggable": "^2.24.2",
|
||||
"vuedraggable": "^2.24.3",
|
||||
"vuex": "^3.5.1",
|
||||
"xgplayer": "^2.13.0",
|
||||
"xgplayer-hls.js": "^2.2.5"
|
||||
@@ -52,15 +56,15 @@
|
||||
"@vue/eslint-config-standard": "^5.1.2",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-plugin-component": "^1.1.1",
|
||||
"electron": "^10.1.4",
|
||||
"electron": "^10.1.5",
|
||||
"electron-devtools-installer": "^3.1.0",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-import": "^2.20.2",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.0",
|
||||
"eslint-plugin-standard": "^4.0.2",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"sass": "^1.26.5",
|
||||
"sass": "^1.29.0",
|
||||
"sass-loader": "^8.0.2",
|
||||
"vue-cli-plugin-electron-builder": "2.0.0-rc.4",
|
||||
"vue-template-compiler": "^2.6.12"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<History v-show="view === 'History'" />
|
||||
<Setting v-show="view === 'Setting'" />
|
||||
<EditSites v-if="view === 'EditSites'"/>
|
||||
<Recommandation v-show="view === 'Recommandation'" />
|
||||
<Recommendation v-show="view === 'Recommendation'" />
|
||||
</div>
|
||||
<transition name="slide">
|
||||
<Detail v-if="detail.show"/>
|
||||
@@ -45,8 +45,8 @@ export default {
|
||||
editSites () {
|
||||
return this.$store.getters.getEditSites
|
||||
},
|
||||
recommandation () {
|
||||
return this.$store.getters.recommandation
|
||||
recommendation () {
|
||||
return this.$store.getters.recommendation
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
@@ -98,91 +98,6 @@
|
||||
.zy-highlighted{
|
||||
color: var(--highlight-color);
|
||||
}
|
||||
// table
|
||||
.zy-table{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
font-size: 15px;
|
||||
.tHeader{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 50px;
|
||||
min-height: 50px;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid;
|
||||
.btn{
|
||||
user-select: none;
|
||||
margin-left: 15px;
|
||||
margin-right: 15px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
.tBody{
|
||||
flex: 1;
|
||||
border-bottom: 1px solid;
|
||||
overflow: auto;
|
||||
.el-table__row td{
|
||||
border: none;
|
||||
}
|
||||
.el-table::before{
|
||||
height: 0px;
|
||||
}
|
||||
ul{
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
li{
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
height: 50px;
|
||||
border-bottom: 1px solid;
|
||||
cursor: pointer;
|
||||
span{
|
||||
display: flex;
|
||||
font-size: 13px;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
overflow: hidden;
|
||||
margin-right: 5px;
|
||||
&.name{
|
||||
flex: 1;
|
||||
min-width: 100px;
|
||||
overflow: hidden;
|
||||
margin-left: 10px;
|
||||
}
|
||||
&.type{
|
||||
width: 10%;
|
||||
}
|
||||
&.time{
|
||||
width: 10%;
|
||||
}
|
||||
&.last{
|
||||
width: 10%;
|
||||
}
|
||||
&.site{
|
||||
width: 10%;
|
||||
}
|
||||
&.note{
|
||||
width: 10%;
|
||||
}
|
||||
&.info{
|
||||
width: 10%;
|
||||
}
|
||||
&.operate{
|
||||
.btn{
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// scroll
|
||||
.zy-scroll{
|
||||
&::-webkit-scrollbar{
|
||||
@@ -231,12 +146,39 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.el-autocomplete{
|
||||
.el-input-group__prepend{
|
||||
border: none;
|
||||
.el-select{
|
||||
width: 100px;
|
||||
.el-input, .el-input__inner{
|
||||
width: 100%;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-input .el-input__inner{
|
||||
width: 200px;
|
||||
}
|
||||
.el-input-group__append{
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
.is-loading:before {
|
||||
background-color: none !important;
|
||||
}
|
||||
.el-input{
|
||||
font-size: 1rem;
|
||||
width: 200px;
|
||||
}
|
||||
.popper {
|
||||
font-size: 1rem;;
|
||||
border: none;
|
||||
li {
|
||||
font-size: 1rem;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.listpage-body{
|
||||
height: calc(100% - 60px);
|
||||
@@ -293,7 +235,7 @@
|
||||
transform: scale(1.02);
|
||||
}
|
||||
.el-table .highlight{
|
||||
color: var(--highlight-color) !important;
|
||||
background-color: var(--highlight-color) !important; // 改为背景色,原来某些主题下看不清字
|
||||
}
|
||||
.el-button{
|
||||
font-size: 1rem;
|
||||
@@ -306,6 +248,12 @@
|
||||
.card{
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: 0.2s;
|
||||
&:hover {
|
||||
top: -3px;
|
||||
}
|
||||
.img{
|
||||
position: relative;
|
||||
min-height: 40px;
|
||||
@@ -328,6 +276,19 @@
|
||||
text-align: center;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.progress{
|
||||
position: absolute;
|
||||
bottom: 10%;
|
||||
left: 0%;
|
||||
width: 40%;
|
||||
background-color: #111111aa;
|
||||
color: #f8df70;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
font-size: 14px;
|
||||
font-weight: bolder;
|
||||
text-align: left;
|
||||
}
|
||||
.update{
|
||||
position: absolute;
|
||||
top: 5%;
|
||||
@@ -373,7 +334,6 @@
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
.info{
|
||||
display: flex;
|
||||
@@ -435,4 +395,4 @@
|
||||
box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,40 +41,6 @@
|
||||
color: var(--d-fc-1);
|
||||
}
|
||||
}
|
||||
.zy-checkbox{
|
||||
color: var(--d-fc-1);
|
||||
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
|
||||
}
|
||||
.zy-table{
|
||||
color: var(--d-fc-2);
|
||||
.tHeader{
|
||||
border-bottom-color: var(--d-c-3);
|
||||
.btn{
|
||||
&:hover{
|
||||
color: var(--d-fc-3)
|
||||
}
|
||||
}
|
||||
}
|
||||
.tBody{
|
||||
border-bottom-color: var(--d-c-3);
|
||||
ul{
|
||||
li{
|
||||
border-bottom-color: var(--d-c-2);
|
||||
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
|
||||
&:hover{
|
||||
box-shadow: var(--d-bsc);
|
||||
background-color: var(--d-bgc-2);
|
||||
color: #fff;
|
||||
}
|
||||
span{
|
||||
&.btn:hover{
|
||||
color: var(--d-fc-3)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.zy-scroll{
|
||||
&:hover{
|
||||
&::-webkit-scrollbar-thumb {
|
||||
@@ -339,31 +305,49 @@
|
||||
.listpage{
|
||||
color: var(--d-fc-2);
|
||||
.listpage-header{
|
||||
border-bottom-color: var(--d-c-3);
|
||||
.btn{
|
||||
&:hover{
|
||||
color: var(--d-fc-3)
|
||||
}
|
||||
border-bottom-color: var(--d-c-3);
|
||||
.btn{
|
||||
&:hover{
|
||||
color: var(--d-fc-3)
|
||||
}
|
||||
.el-button{
|
||||
background-color: var(--d-bgc-2);
|
||||
}
|
||||
.el-button{
|
||||
background-color: var(--d-bgc-2);
|
||||
color: var(--d-fc-2);
|
||||
&:hover{
|
||||
color: var(--d-fc-3)
|
||||
}
|
||||
}
|
||||
.el-input{
|
||||
input{
|
||||
background-color: var(--d-bgc-1);
|
||||
border: 1px solid var(--d-bgc-1);
|
||||
color: var(--d-fc-2);
|
||||
}
|
||||
}
|
||||
.el-input-group__prepend{
|
||||
background-color: var(--d-bgc-1);
|
||||
}
|
||||
.popper {
|
||||
color: var(--d-fc-1);
|
||||
background-color: var(--d-bgc-1);
|
||||
box-shadow: var(--d-bsc);
|
||||
li {
|
||||
color: var(--d-fc-1);
|
||||
background-color: var(--d-bgc-1);
|
||||
&:hover{
|
||||
color: var(--d-fc-3)
|
||||
}
|
||||
}
|
||||
.el-input{
|
||||
input{
|
||||
background-color: var(--d-bgc-1);
|
||||
border: 1px solid var(--d-bgc-1);
|
||||
color: var(--d-fc-2);
|
||||
background-color: var(--d-bgc-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
.popper__arrow, .popper__arrow::after{
|
||||
border-bottom-color: var(--d-bgc-1);
|
||||
}
|
||||
}
|
||||
.listpage-body{
|
||||
color: var(--d-fc-1);
|
||||
background-color: var(--d-bgc-1);
|
||||
&:hover{
|
||||
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);
|
||||
@@ -373,8 +357,8 @@
|
||||
background: var(--d-bgc-1);
|
||||
}
|
||||
}
|
||||
/* 设置el-table的样式*/
|
||||
.show-table{
|
||||
/* 设置el-table的样式*/
|
||||
.el-table{
|
||||
color: var(--d-fc-1);
|
||||
background-color: var(--d-bgc-1);
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
}
|
||||
}
|
||||
.vs-input{
|
||||
color: var(--g-fc-1);
|
||||
background-color: var(--g-bgc-1);
|
||||
input{
|
||||
color: var(--g-fc-1);
|
||||
&::-webkit-input-placeholder{
|
||||
@@ -37,38 +39,6 @@
|
||||
background-color: var(--g-bgc-1);
|
||||
input{
|
||||
color: var(--g-fc-1);
|
||||
background-color: var(--g-bgc-1);
|
||||
}
|
||||
}
|
||||
.zy-checkbox{
|
||||
color: var(--g-fc-1);
|
||||
}
|
||||
.zy-table{
|
||||
color: var(--g-fc-2);
|
||||
.tHeader{
|
||||
border-bottom-color: var(--g-c-3);
|
||||
.btn{
|
||||
&:hover{
|
||||
color: var(--g-fc-3)
|
||||
}
|
||||
}
|
||||
}
|
||||
.tBody{
|
||||
border-bottom-color: var(--g-c-3);
|
||||
ul{
|
||||
li{
|
||||
border-bottom-color: var(--g-c-2);
|
||||
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
|
||||
&:hover{
|
||||
box-shadow: var(--g-bsc-hover);
|
||||
}
|
||||
span{
|
||||
&.btn:hover{
|
||||
color: var(--g-fc-3)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.zy-scroll{
|
||||
@@ -330,30 +300,49 @@
|
||||
background-color: var(--g-bgc-1);
|
||||
box-shadow: var(--g-bsc);
|
||||
}
|
||||
|
||||
// Page of list using table and picture
|
||||
.listpage{
|
||||
color: var(--g-fc-2);
|
||||
.listpage-header{
|
||||
border-bottom-color: var(--g-c-3);
|
||||
.btn{
|
||||
&:hover{
|
||||
color: var(--g-fc-3)
|
||||
}
|
||||
border-bottom-color: var(--g-c-3);
|
||||
.btn{
|
||||
&:hover{
|
||||
color: var(--g-fc-3)
|
||||
}
|
||||
.el-button{
|
||||
background-color: var(--g-bgc-2);
|
||||
}
|
||||
.el-button{
|
||||
background-color: var(--g-bgc-2);
|
||||
color: var(--g-fc-2);
|
||||
&:hover{
|
||||
color: var(--g-fc-3)
|
||||
}
|
||||
}
|
||||
.el-input{
|
||||
input{
|
||||
background-color: var(--g-bgc-1);
|
||||
border: 1px solid var(--g-bgc-1);
|
||||
color: var(--g-fc-2);
|
||||
}
|
||||
}
|
||||
.el-input-group__prepend{
|
||||
background-color: var(--g-bgc-1);
|
||||
}
|
||||
.popper {
|
||||
color: var(--g-fc-1);
|
||||
background-color: var(--g-bgc-1);
|
||||
box-shadow: var(--g-bsc);
|
||||
li {
|
||||
color: var(--g-fc-1);
|
||||
background-color: var(--g-bgc-1);
|
||||
&:hover{
|
||||
color: var(--g-fc-3)
|
||||
}
|
||||
}
|
||||
.el-input{
|
||||
input{
|
||||
background-color: var(--g-bgc-1);
|
||||
border: 1px solid var(--g-bgc-1);
|
||||
color: var(--g-fc-2);
|
||||
background-color: var(--g-bgc-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
.popper__arrow, .popper__arrow::after{
|
||||
border-bottom-color: var(--g-bgc-1);
|
||||
}
|
||||
}
|
||||
.listpage-body{
|
||||
color: var(--g-fc-1);
|
||||
@@ -368,8 +357,8 @@
|
||||
background: var(--g-bgc-1);
|
||||
}
|
||||
}
|
||||
/* 设置el-table的样式*/
|
||||
.show-table{
|
||||
/* 设置el-table的样式*/
|
||||
.el-table{
|
||||
color: var(--g-fc-1);
|
||||
background-color: var(--g-bgc-1);
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
}
|
||||
}
|
||||
.vs-input{
|
||||
color: var(--l-fc-1);
|
||||
background-color: var(--l-bgc-1);
|
||||
input{
|
||||
color: var(--l-fc-1);
|
||||
&::-webkit-input-placeholder{
|
||||
@@ -37,38 +39,6 @@
|
||||
background-color: var(--l-bgc-1);
|
||||
input{
|
||||
color: var(--l-fc-1);
|
||||
background-color: var(--l-bgc-1);
|
||||
}
|
||||
}
|
||||
.zy-checkbox{
|
||||
color: var(--l-fc-1);
|
||||
}
|
||||
.zy-table{
|
||||
color: var(--l-fc-2);
|
||||
.tHeader{
|
||||
border-bottom-color: var(--l-c-3);
|
||||
.btn{
|
||||
&:hover{
|
||||
color: var(--l-fc-3)
|
||||
}
|
||||
}
|
||||
}
|
||||
.tBody{
|
||||
border-bottom-color: var(--l-c-3);
|
||||
ul{
|
||||
li{
|
||||
border-bottom-color: var(--l-c-2);
|
||||
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
|
||||
&:hover{
|
||||
box-shadow: var(--l-bsc-hover);
|
||||
}
|
||||
span{
|
||||
&.btn:hover{
|
||||
color: var(--l-fc-3)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.zy-scroll{
|
||||
@@ -330,30 +300,49 @@
|
||||
background-color: var(--l-bgc-1);
|
||||
box-shadow: var(--l-bsc);
|
||||
}
|
||||
|
||||
// Page of list using table and picture
|
||||
.listpage{
|
||||
color: var(--l-fc-2);
|
||||
.listpage-header{
|
||||
border-bottom-color: var(--l-c-3);
|
||||
.btn{
|
||||
&:hover{
|
||||
color: var(--l-fc-3)
|
||||
}
|
||||
border-bottom-color: var(--l-c-3);
|
||||
.btn{
|
||||
&:hover{
|
||||
color: var(--l-fc-3)
|
||||
}
|
||||
.el-button{
|
||||
background-color: var(--l-bgc-2);
|
||||
}
|
||||
.el-button{
|
||||
background-color: var(--l-bgc-2);
|
||||
color: var(--l-fc-2);
|
||||
&:hover{
|
||||
color: var(--l-fc-3)
|
||||
}
|
||||
}
|
||||
.el-input{
|
||||
input{
|
||||
background-color: var(--l-bgc-1);
|
||||
border: 1px solid var(--l-bgc-1);
|
||||
color: var(--l-fc-2);
|
||||
}
|
||||
}
|
||||
.el-input-group__prepend{
|
||||
background-color: var(--l-bgc-1);
|
||||
}
|
||||
.popper {
|
||||
color: var(--l-fc-1);
|
||||
background-color: var(--l-bgc-1);
|
||||
box-shadow: var(--l-bsc);
|
||||
li {
|
||||
color: var(--l-fc-1);
|
||||
background-color: var(--l-bgc-1);
|
||||
&:hover{
|
||||
color: var(--l-fc-3)
|
||||
}
|
||||
}
|
||||
.el-input{
|
||||
input{
|
||||
background-color: var(--l-bgc-1);
|
||||
border: 1px solid var(--l-bgc-1);
|
||||
color: var(--l-fc-2);
|
||||
background-color: var(--l-bgc-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
.popper__arrow, .popper__arrow::after{
|
||||
border-bottom-color: var(--l-bgc-1);
|
||||
}
|
||||
}
|
||||
.listpage-body{
|
||||
color: var(--l-fc-1);
|
||||
@@ -368,8 +357,8 @@
|
||||
background: var(--l-bgc-1);
|
||||
}
|
||||
}
|
||||
/* 设置el-table的样式*/
|
||||
.show-table{
|
||||
/* 设置el-table的样式*/
|
||||
.el-table{
|
||||
color: var(--l-fc-1);
|
||||
background-color: var(--l-bgc-1);
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
}
|
||||
}
|
||||
.vs-input{
|
||||
color: var(--p-fc-1);
|
||||
background-color: var(--p-bgc-1);
|
||||
input{
|
||||
color: var(--p-fc-1);
|
||||
&::-webkit-input-placeholder{
|
||||
@@ -39,37 +41,6 @@
|
||||
color: var(--p-fc-1);
|
||||
}
|
||||
}
|
||||
.zy-checkbox{
|
||||
color: var(--p-fc-1);
|
||||
}
|
||||
.zy-table{
|
||||
color: var(--p-fc-2);
|
||||
.tHeader{
|
||||
border-bottom-color: var(--p-c-3);
|
||||
.btn{
|
||||
&:hover{
|
||||
color: var(--p-fc-3)
|
||||
}
|
||||
}
|
||||
}
|
||||
.tBody{
|
||||
border-bottom-color: var(--p-c-3);
|
||||
ul{
|
||||
li{
|
||||
border-bottom-color: var(--p-c-2);
|
||||
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
|
||||
&:hover{
|
||||
box-shadow: var(--p-bsc-hover);
|
||||
}
|
||||
span{
|
||||
&.btn:hover{
|
||||
color: var(--p-fc-3)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.zy-scroll{
|
||||
&:hover{
|
||||
&::-webkit-scrollbar-thumb {
|
||||
@@ -329,30 +300,49 @@
|
||||
background-color: var(--p-bgc-1);
|
||||
box-shadow: var(--p-bsc);
|
||||
}
|
||||
|
||||
// Page of list using table and picture
|
||||
.listpage{
|
||||
color: var(--p-fc-2);
|
||||
.listpage-header{
|
||||
border-bottom-color: var(--p-c-3);
|
||||
.btn{
|
||||
&:hover{
|
||||
color: var(--p-fc-3)
|
||||
}
|
||||
border-bottom-color: var(--p-c-3);
|
||||
.btn{
|
||||
&:hover{
|
||||
color: var(--p-fc-3)
|
||||
}
|
||||
.el-button{
|
||||
background-color: var(--p-bgc-2);
|
||||
}
|
||||
.el-button{
|
||||
background-color: var(--p-bgc-2);
|
||||
color: var(--p-fc-2);
|
||||
&:hover{
|
||||
color: var(--p-fc-3)
|
||||
}
|
||||
}
|
||||
.el-input{
|
||||
input{
|
||||
background-color: var(--p-bgc-1);
|
||||
border: 1px solid var(--p-bgc-1);
|
||||
color: var(--p-fc-2);
|
||||
}
|
||||
}
|
||||
.el-input-group__prepend{
|
||||
background-color: var(--p-bgc-1);
|
||||
}
|
||||
.popper {
|
||||
color: var(--p-fc-1);
|
||||
background-color: var(--p-bgc-1);
|
||||
box-shadow: var(--p-bsc);
|
||||
li {
|
||||
color: var(--p-fc-1);
|
||||
background-color: var(--p-bgc-1);
|
||||
&:hover{
|
||||
color: var(--p-fc-3)
|
||||
}
|
||||
}
|
||||
.el-input{
|
||||
input{
|
||||
background-color: var(--p-bgc-1);
|
||||
border: 1px solid var(--p-bgc-1);
|
||||
color: var(--p-fc-2);
|
||||
background-color: var(--p-bgc-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
.popper__arrow, .popper__arrow::after{
|
||||
border-bottom-color: var(--p-bgc-1);
|
||||
}
|
||||
}
|
||||
.listpage-body{
|
||||
color: var(--p-fc-1);
|
||||
@@ -367,8 +357,8 @@
|
||||
background: var(--p-bgc-1);
|
||||
}
|
||||
}
|
||||
/* 设置el-table的样式*/
|
||||
.show-table{
|
||||
/* 设置el-table的样式*/
|
||||
.el-table{
|
||||
color: var(--p-fc-1);
|
||||
background-color: var(--p-bgc-1);
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</g>
|
||||
</svg>
|
||||
</span>
|
||||
<span :class="[view === 'Recommandation' ? 'active ': ''] + 'zy-svg'" @click="changeView('Recommandation')">
|
||||
<span :class="[view === 'Recommendation' ? 'active ': ''] + 'zy-svg'" @click="changeView('Recommendation')">
|
||||
<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"/>
|
||||
|
||||
@@ -128,33 +128,23 @@ export default {
|
||||
close () {
|
||||
this.detail.show = false
|
||||
},
|
||||
m3u8Parse (e) {
|
||||
const dd = e.dl.dd
|
||||
const type = Object.prototype.toString.call(dd)
|
||||
if (type === '[object Array]') {
|
||||
for (const i of dd) {
|
||||
if (i._flag.indexOf('m3u8') >= 0) {
|
||||
this.m3u8List = i._t.split('#')
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.m3u8List = dd._t.split('#')
|
||||
}
|
||||
},
|
||||
async playEvent (n) {
|
||||
if (!this.playOnline) {
|
||||
console.log(this.detail)
|
||||
const db = await history.find({ site: this.detail.key, ids: this.detail.info.id })
|
||||
if (db) {
|
||||
this.video = { key: db.site, info: { id: db.ids, name: db.name, index: n, site: this.detail.site } }
|
||||
} else {
|
||||
this.video = { key: this.detail.key, info: { id: this.detail.info.id, name: this.detail.info.name, index: n, site: this.detail.site } }
|
||||
}
|
||||
this.video.detail = this.info
|
||||
this.view = 'Play'
|
||||
this.detail.show = false
|
||||
} else {
|
||||
const db = await history.find({ site: this.detail.key, ids: this.detail.info.id })
|
||||
if (db) {
|
||||
db.index = n
|
||||
db.detail = this.info
|
||||
history.update(db.id, db)
|
||||
} else {
|
||||
const doc = {
|
||||
@@ -164,7 +154,8 @@ export default {
|
||||
type: this.detail.info.type,
|
||||
year: this.detail.info.year,
|
||||
index: n,
|
||||
time: ''
|
||||
time: '',
|
||||
detail: this.info
|
||||
}
|
||||
history.add(doc)
|
||||
}
|
||||
@@ -256,25 +247,9 @@ export default {
|
||||
}
|
||||
},
|
||||
doubanLinkEvent () {
|
||||
const open = require('open')
|
||||
const axios = require('axios')
|
||||
const cheerio = require('cheerio')
|
||||
const name = this.detail.info.name.trim()
|
||||
// 豆瓣搜索链接
|
||||
var doubanSearchLink = 'https://www.douban.com/search?q=' + name
|
||||
var link = doubanSearchLink
|
||||
axios.get(doubanSearchLink).then(res => {
|
||||
const $ = cheerio.load(res.data)
|
||||
// 比较第一和第二豆瓣搜索结果, 如果名字相符, 就打开该链接,否则打开搜索页面
|
||||
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')
|
||||
}
|
||||
}
|
||||
zy.doubanLink(name).then(link => {
|
||||
const open = require('open')
|
||||
open(link)
|
||||
})
|
||||
},
|
||||
@@ -290,7 +265,7 @@ export default {
|
||||
if (res) {
|
||||
this.info = res
|
||||
this.$set(this.info, 'rate', '')
|
||||
this.m3u8Parse(res)
|
||||
this.m3u8List = res.m3u8List
|
||||
this.getDoubanRate()
|
||||
this.loading = false
|
||||
}
|
||||
|
||||
@@ -2,24 +2,26 @@
|
||||
<div class="listpage" id="sites">
|
||||
<div class="listpage-header" v-show="!enableBatchEdit">
|
||||
<el-switch v-model="enableBatchEdit" active-text="批处理分组">></el-switch>
|
||||
<el-checkbox v-model="setting.excludeR18Films" @change="excludeR18FilmsChangeEvent">屏蔽福利片</el-checkbox>
|
||||
<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="checkAllSite" icon="el-icon-refresh" :loading="checkAllSitesLoading">检测{{ this.checkAllSitesLoading ? this.checkProgress + '/' + this.sites.length : '' }}</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-switch v-model="batchIsActive" active-text="启用"></el-switch>
|
||||
<el-button type="primary" icon="el-icon-edit" @click.stop="saveBatchEdit">保存</el-button>
|
||||
<el-button @click="removeSelectedSites" icon="el-icon-delete-solid">删除</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"
|
||||
:data="sites"
|
||||
@select="selectionCellClick"
|
||||
@selection-change="handleSelectionChange"
|
||||
@sort-change="handleSortChange">
|
||||
<el-table-column
|
||||
@@ -32,13 +34,14 @@
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="isActive"
|
||||
label="自选源">
|
||||
width="120"
|
||||
:filters = "[{text:'启用', value: true}, {text:'停用', value: false}]"
|
||||
:filter-method="(value, row) => value === row.isActive"
|
||||
label="启用">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.isActive"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
@change='isActiveChangeEvent'>
|
||||
@click.native.stop='isActiveChangeEvent(scope.row)'>
|
||||
</el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -46,11 +49,8 @@
|
||||
prop="group"
|
||||
label="分组"
|
||||
:filters="getFilters"
|
||||
:filter-method="filterHandle"
|
||||
:filter-method="(value, row) => value === row.group"
|
||||
filter-placement="bottom-end">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text">{{scope.row.group}}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="状态"
|
||||
@@ -58,21 +58,23 @@
|
||||
:sort-by="['status']"
|
||||
width="120">
|
||||
<template slot-scope="scope">
|
||||
<span v-show="scope.row.status === ''">
|
||||
<span v-if="scope.row.status === ' '">
|
||||
<i class="el-icon-loading"></i>
|
||||
检测中...
|
||||
</span>
|
||||
<span v-show="scope.row.status !== ''">{{scope.row.status}}</span>
|
||||
<span v-else>{{scope.row.status}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
header-align="center"
|
||||
align="right">
|
||||
align="right"
|
||||
:width="sites.every(site => site.status) && !checkAllSitesLoading ? 200 : 150">
|
||||
<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" v-if="sites.every(site => site.status)" v-show="!checkAllSitesLoading" @click.stop="checkSingleSite(scope.row)" type="text">检测</el-button>
|
||||
<el-button size="mini" @click.stop="removeEvent(scope.row)" type="text">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -111,7 +113,7 @@
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import { sites } from '../lib/dexie'
|
||||
import { sites, setting } from '../lib/dexie'
|
||||
import zy from '../lib/site/tools'
|
||||
import { remote } from 'electron'
|
||||
import { sites as defaultSites } from '../lib/dexie/initData'
|
||||
@@ -132,7 +134,7 @@ export default {
|
||||
api: '',
|
||||
download: '',
|
||||
group: '',
|
||||
isActive: 1
|
||||
isActive: true
|
||||
},
|
||||
siteGroup: [],
|
||||
rules: {
|
||||
@@ -141,18 +143,19 @@ export default {
|
||||
],
|
||||
api: [
|
||||
{ required: true, message: 'API地址不能为空', trigger: 'blur' }
|
||||
],
|
||||
download: [
|
||||
{ required: false, trigger: 'blur' }
|
||||
]
|
||||
},
|
||||
enableBatchEdit: false,
|
||||
batchGroupName: '',
|
||||
batchIsActive: 1,
|
||||
batchIsActive: true,
|
||||
shiftDown: false,
|
||||
selectionBegin: '',
|
||||
selectionEnd: '',
|
||||
multipleSelection: [],
|
||||
tableKey: 1,
|
||||
checkAllSiteLoading: false,
|
||||
editeOldkey: ''
|
||||
checkAllSitesLoading: false,
|
||||
checkProgress: 0,
|
||||
stopFlag: false,
|
||||
editOldkey: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -164,14 +167,6 @@ export default {
|
||||
this.SET_SETTING(val)
|
||||
}
|
||||
},
|
||||
editSites: {
|
||||
get () {
|
||||
return this.$store.getters.getEditSites
|
||||
},
|
||||
set (val) {
|
||||
this.SET_EDITSITES(val)
|
||||
}
|
||||
},
|
||||
getFilters () {
|
||||
const groups = [...new Set(this.sites.map(site => site.group))]
|
||||
var filters = []
|
||||
@@ -185,15 +180,48 @@ export default {
|
||||
return filters
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
enableBatchEdit () {
|
||||
if (this.checkAllSitesLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
this.enableBatchEdit = false
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_SETTING', 'SET_EDITSITES']),
|
||||
filterHandle (value, row) {
|
||||
return row.group === value
|
||||
...mapMutations(['SET_SETTING']),
|
||||
excludeR18FilmsChangeEvent () {
|
||||
setting.find().then(res => {
|
||||
res.excludeR18Films = this.setting.excludeR18Films
|
||||
setting.update(res)
|
||||
})
|
||||
},
|
||||
selectionCellClick (selection, row) {
|
||||
if (this.shiftDown && this.selectionBegin !== '' && selection.includes(row)) {
|
||||
this.selectionEnd = row.id
|
||||
const start = Math.min(this.selectionBegin, this.selectionEnd) - 1
|
||||
const end = Math.max(this.selectionBegin, this.selectionEnd)
|
||||
const selections = this.sites.slice(start, end)
|
||||
this.$nextTick(() => {
|
||||
selections.forEach(e => this.$refs.editSitesTable.toggleRowSelection(e, true))
|
||||
})
|
||||
this.selectionBegin = this.selectionEnd = ''
|
||||
return
|
||||
}
|
||||
if (selection.includes(row)) {
|
||||
this.selectionBegin = row.id
|
||||
} else {
|
||||
this.selectionBegin = ''
|
||||
}
|
||||
},
|
||||
handleSelectionChange (rows) {
|
||||
this.multipleSelection = rows
|
||||
},
|
||||
handleSortChange (column, prop, order) {
|
||||
if (this.checkAllSitesLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
return false
|
||||
}
|
||||
this.updateDatabase(this.sites)
|
||||
},
|
||||
saveBatchEdit () {
|
||||
@@ -208,13 +236,7 @@ export default {
|
||||
getSites () {
|
||||
sites.all().then(res => {
|
||||
this.sites = res
|
||||
this.editSites = {
|
||||
sites: res
|
||||
}
|
||||
})
|
||||
for (const i of this.sites) {
|
||||
delete i.status
|
||||
}
|
||||
},
|
||||
getSitesGroup () {
|
||||
const arr = []
|
||||
@@ -226,6 +248,10 @@ export default {
|
||||
this.siteGroup = arr
|
||||
},
|
||||
addSite () {
|
||||
if (this.checkAllSitesLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
return false
|
||||
}
|
||||
this.getSitesGroup()
|
||||
this.dialogType = 'new'
|
||||
this.dialogVisible = true
|
||||
@@ -235,26 +261,26 @@ export default {
|
||||
api: '',
|
||||
download: '',
|
||||
group: '',
|
||||
isActive: 1
|
||||
isActive: true
|
||||
}
|
||||
},
|
||||
editSite (siteInfo) {
|
||||
this.getSitesGroup()
|
||||
if (this.checkAllSiteLoading) {
|
||||
if (this.checkAllSitesLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
return false
|
||||
}
|
||||
this.getSitesGroup()
|
||||
this.dialogType = 'edit'
|
||||
this.dialogVisible = true
|
||||
this.siteInfo = siteInfo
|
||||
this.editeOldkey = siteInfo.key
|
||||
this.editOldkey = siteInfo.key
|
||||
},
|
||||
closeDialog () {
|
||||
this.dialogVisible = false
|
||||
this.getSites()
|
||||
},
|
||||
removeEvent (e) {
|
||||
if (this.checkAllSiteLoading) {
|
||||
if (this.checkAllSitesLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
return false
|
||||
}
|
||||
@@ -264,19 +290,8 @@ export default {
|
||||
this.$message.warning('删除源失败, 错误信息: ' + err)
|
||||
})
|
||||
},
|
||||
listUpdatedEvent () {
|
||||
sites.clear().then(res1 => {
|
||||
// 重新排序
|
||||
var id = 1
|
||||
this.sites.forEach(element => {
|
||||
element.id = id
|
||||
sites.add(element)
|
||||
id += 1
|
||||
})
|
||||
})
|
||||
},
|
||||
checkSiteKey (e) {
|
||||
if (this.dialogType === 'edit' && this.editeOldkey === this.siteInfo.key) {
|
||||
if (this.dialogType === 'edit' && this.editOldkey === this.siteInfo.key) {
|
||||
return true
|
||||
} else {
|
||||
for (const i of this.sites) {
|
||||
@@ -319,7 +334,7 @@ export default {
|
||||
this.dialogVisible = false
|
||||
this.getSites()
|
||||
})
|
||||
this.editeOldkey = ''
|
||||
this.editOldkey = ''
|
||||
},
|
||||
exportSites () {
|
||||
this.getSites()
|
||||
@@ -342,6 +357,10 @@ export default {
|
||||
})
|
||||
},
|
||||
importSites () {
|
||||
if (this.checkAllSitesLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
return false
|
||||
}
|
||||
const options = {
|
||||
filters: [
|
||||
{ name: 'JSON file', extensions: ['json'] },
|
||||
@@ -359,7 +378,7 @@ export default {
|
||||
if (ele.api && this.sites.filter(x => x.key === ele.key).length === 0 && this.sites.filter(x => x.name === ele.name && x.api === ele.api).length === 0) {
|
||||
// 不含该key 同时也不含名字和url一样的
|
||||
if (ele.isActive === undefined) {
|
||||
ele.isActive = 1
|
||||
ele.isActive = true
|
||||
}
|
||||
if (ele.group === undefined) {
|
||||
ele.group = '导入'
|
||||
@@ -376,11 +395,16 @@ export default {
|
||||
})
|
||||
},
|
||||
resetSitesEvent () {
|
||||
this.stopFlag = true
|
||||
if (this.checkAllSitesLoading) {
|
||||
this.$message.info('部分检测还未完全终止, 请稍等...')
|
||||
return
|
||||
}
|
||||
sites.clear().then(sites.bulkAdd(defaultSites).then(this.getSites()))
|
||||
this.$message.success('重置源成功')
|
||||
},
|
||||
moveToTopEvent (i) {
|
||||
if (this.checkAllSiteLoading) {
|
||||
if (this.checkAllSitesLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
return false
|
||||
}
|
||||
@@ -388,12 +412,13 @@ export default {
|
||||
this.updateDatabase()
|
||||
},
|
||||
syncTableData () {
|
||||
if (this.$refs.editSitesTable.tableData && this.$refs.editSitesTable.tableData.length === this.sites.length) {
|
||||
if (this.$refs.editSitesTable.tableData) {
|
||||
this.sites = this.$refs.editSitesTable.tableData
|
||||
}
|
||||
},
|
||||
isActiveChangeEvent (row) {
|
||||
this.updateDatabase()
|
||||
sites.remove(row.id)
|
||||
sites.add(row)
|
||||
},
|
||||
resetId (inArray) {
|
||||
var id = 1
|
||||
@@ -414,10 +439,18 @@ export default {
|
||||
sites.bulkAdd(this.sites).then(this.getSites())
|
||||
})
|
||||
},
|
||||
removeAllSites () {
|
||||
sites.clear().then(this.getSites())
|
||||
removeSelectedSites () {
|
||||
this.multipleSelection.forEach(e => sites.remove(e.id))
|
||||
this.$refs.editSitesTable.clearFilter()
|
||||
this.getSites()
|
||||
this.updateDatabase()
|
||||
this.enableBatchEdit = false
|
||||
},
|
||||
rowDrop () {
|
||||
if (this.checkAllSitesLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
return false
|
||||
}
|
||||
const tbody = document.getElementById('sites-table').querySelector('.el-table__body-wrapper tbody')
|
||||
var _this = this
|
||||
Sortable.create(tbody, {
|
||||
@@ -429,39 +462,40 @@ export default {
|
||||
})
|
||||
},
|
||||
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()
|
||||
this.checkAllSitesLoading = true
|
||||
this.stopFlag = false
|
||||
this.checkProgress = 0
|
||||
const uncheckedList = this.sites.filter(e => e.status === undefined || e.status === ' ') // 未检测过的优先
|
||||
const other = this.sites.filter(e => !uncheckedList.includes(e))
|
||||
await Promise.all(uncheckedList.map(site => this.checkSingleSite(site)))
|
||||
await Promise.all(other.map(site => this.checkSingleSite(site))).then(res => {
|
||||
this.checkAllSitesLoading = false
|
||||
this.getSites()
|
||||
})
|
||||
},
|
||||
async checkSimpleSite (row) {
|
||||
this.checkAllSiteLoading = true
|
||||
async checkSingleSite (row) {
|
||||
row.status = ' '
|
||||
if (this.stopFlag) {
|
||||
this.checkProgress += 1
|
||||
return row.status
|
||||
}
|
||||
const flag = await zy.check(row.key)
|
||||
this.checkProgress += 1
|
||||
if (flag) {
|
||||
row.status = '可用'
|
||||
} else {
|
||||
row.status = '失效'
|
||||
row.isActive = 0
|
||||
row.isActive = false
|
||||
}
|
||||
this.updateDatabase()
|
||||
this.tableKey = Math.random()
|
||||
this.checkAllSiteLoading = false
|
||||
sites.remove(row.id)
|
||||
sites.add(row)
|
||||
return row.status
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.rowDrop()
|
||||
this.checkAllSiteLoading = false
|
||||
addEventListener('keydown', code => { if (code.keyCode === 16) this.shiftDown = true })
|
||||
addEventListener('keyup', code => { if (code.keyCode === 16) this.shiftDown = false })
|
||||
},
|
||||
created () {
|
||||
this.getSites()
|
||||
|
||||
@@ -1,37 +1,65 @@
|
||||
<template>
|
||||
<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">
|
||||
<ul class="zy-scroll" style="max-height: 600px;">
|
||||
<li :class="site.key === i.key ? 'active' : ''" v-for="i in sites" :key="i.key" @click="siteClick(i)">{{ i.name }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="zy-select" @mouseleave="show.classList = false" v-show="show.class">
|
||||
<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 | classNameFilter }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="zy-select" @mouseleave="show.search = false">
|
||||
<div class="vs-input" @click="show.search = true"><input v-model.trim="searchTxt" type="text" placeholder="搜索" @keyup.enter="searchEvent(searchTxt)"></div>
|
||||
<div class="vs-options" v-show="show.search">
|
||||
<ul class="zy-scroll" style="max-height: 600px">
|
||||
<li v-for="(i, j) in searchList" :key="j" @click="searchEvent(i.keywords)">{{i.keywords}}</li>
|
||||
<li v-show="searchList.length >= 1" @click="clearSearch">清空历史记录</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<el-select v-model="selectedSiteName" size="small" placeholder="源站" :popper-append-to-body="false" popper-class="popper" @change="siteClick">
|
||||
<el-option
|
||||
v-for="item in sites"
|
||||
:key="item.key"
|
||||
:label="item.name"
|
||||
:value="item.name">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-select v-model="selectedClassName" size="small" placeholder="类型" :popper-append-to-body="false" popper-class="popper" @change="classClick" v-show="show.class">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.tid"
|
||||
:label="item.name"
|
||||
:value="item.name">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-autocomplete
|
||||
clearable
|
||||
size="small"
|
||||
v-model.trim="searchTxt"
|
||||
value-key="keywords"
|
||||
:fetch-suggestions="querySearch"
|
||||
:popper-append-to-body="false"
|
||||
popper-class="popper"
|
||||
placeholder="搜索"
|
||||
@keyup.enter.native="searchAndRecord"
|
||||
@select="searchEvent"
|
||||
@change="searchChangeEvent">
|
||||
<el-select v-model="searchGroup" size="small" slot="prepend"
|
||||
:popper-append-to-body="false"
|
||||
popper-class="popper"
|
||||
default-first-option placeholder="请选择"
|
||||
@change="searchEvent">
|
||||
<el-option
|
||||
v-for="item in searchGroups"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<!--方便触屏-->
|
||||
<el-button icon="el-icon-search" @click.stop="searchEvent" slot="append" />
|
||||
</el-autocomplete>
|
||||
</div>
|
||||
<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"
|
||||
:breakpoints="{
|
||||
1200: { //当屏幕宽度小于等于1200
|
||||
rowPerView: 4,
|
||||
},
|
||||
800: { //当屏幕宽度小于等于800
|
||||
rowPerView: 3,
|
||||
},
|
||||
500: { //当屏幕宽度小于等于500
|
||||
rowPerView: 2,
|
||||
}
|
||||
}"
|
||||
animationEffect="fadeIn"
|
||||
backgroundColor="rgba(0, 0, 0, 0)">
|
||||
<template slot="item" slot-scope="props">
|
||||
<div class="card" v-show="!setting.excludeR18Films || !containsR18Keywords(props.data.type)">
|
||||
@@ -47,6 +75,7 @@
|
||||
</div>
|
||||
<div class="name" @click="detailEvent(site, props.data)">{{props.data.name}}</div>
|
||||
<div class="info">
|
||||
<span>{{props.data.area}}</span>
|
||||
<span>{{props.data.year}}</span>
|
||||
<span>{{props.data.note}}</span>
|
||||
<span>{{props.data.type}}</span>
|
||||
@@ -57,121 +86,142 @@
|
||||
<infinite-loading force-use-infinite-wrapper :identifier="infiniteId" @infinite="infiniteHandler"></infinite-loading>
|
||||
</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>
|
||||
<el-table
|
||||
size="mini"
|
||||
:data="list.filter(res => !setting.excludeR18Films || !containsR18Keywords(res.type))"
|
||||
height="100%"
|
||||
:empty-text="statusText"
|
||||
@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="地区"
|
||||
width="100">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="lang"
|
||||
label="语言"
|
||||
width="100">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="note"
|
||||
label="备注"
|
||||
width="120">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="last"
|
||||
label="最近更新"
|
||||
:formatter="dateFormat"
|
||||
align="left">
|
||||
</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>
|
||||
ref="searchResultTable"
|
||||
:data="searchContents.filter(res => !setting.excludeR18Films || (res.type !== undefined && !containsR18Keywords(res.type)))"
|
||||
height="100%"
|
||||
:empty-text="statusText"
|
||||
@filter-change="filterChange"
|
||||
@row-click="(row) => detailEvent(row.site, row)"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
sortable
|
||||
:sort-method="(a , b) => sortByLocaleCompare(a.name, b.name)"
|
||||
prop="name"
|
||||
label="片名">
|
||||
</el-table-column>
|
||||
<el-table-column v-if="searchGroup !== '站内'"
|
||||
sortable
|
||||
:sort-method="(a , b) => sortByLocaleCompare(a.site.name, b.site.name)"
|
||||
:filters="getFilters('siteName')"
|
||||
:filter-method="(value, row, column) => { this.currentColumn = column; return value === row.site.name }"
|
||||
prop="site"
|
||||
label="源站"
|
||||
width="120">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.site.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="type"
|
||||
:filters="getFilters('type')"
|
||||
:filter-method="(value, row, column) => { this.currentColumn = column; return value === row.type }"
|
||||
label="类型"
|
||||
width="90">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
sortable
|
||||
prop="year"
|
||||
label="上映"
|
||||
width="90">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="area"
|
||||
:filters="getFilters('area')"
|
||||
:filter-method="(value, row, column) => { this.currentColumn = column; return value === row.area }"
|
||||
label="地区"
|
||||
width="90">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:filters="getFilters('lang')"
|
||||
:filter-method="(value, row, column) => { this.currentColumn = column; return value === row.lang }"
|
||||
prop="lang"
|
||||
label="语言"
|
||||
width="70">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
sortable
|
||||
prop="note"
|
||||
label="备注"
|
||||
width="120">
|
||||
</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>
|
||||
@@ -179,7 +229,7 @@
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import { star, history, search, sites } from '../lib/dexie'
|
||||
import { star, history, search, sites, setting } from '../lib/dexie'
|
||||
import zy from '../lib/site/tools'
|
||||
import Waterfall from 'vue-waterfall-plugin'
|
||||
import InfiniteLoading from 'vue-infinite-loading'
|
||||
@@ -193,19 +243,25 @@ export default {
|
||||
site: false,
|
||||
class: false,
|
||||
classList: false,
|
||||
search: false,
|
||||
find: false
|
||||
},
|
||||
sites: [],
|
||||
site: {},
|
||||
classList: [],
|
||||
type: {},
|
||||
selectedClassName: '最新',
|
||||
selectedSiteName: '',
|
||||
pagecount: 0,
|
||||
list: [],
|
||||
statusText: ' ',
|
||||
infiniteId: +new Date(),
|
||||
searchID: 0,
|
||||
searchList: [],
|
||||
searchTxt: '',
|
||||
searchContents: [],
|
||||
currentColumn: '',
|
||||
searchGroup: '',
|
||||
searchGroups: [],
|
||||
// 福利片关键词
|
||||
r18KeyWords: ['伦理', '论理', '倫理', '福利', '激情', '理论', '写真', '情色', '美女', '街拍', '赤足', '性感', '里番']
|
||||
}
|
||||
@@ -247,16 +303,22 @@ export default {
|
||||
this.SET_SHARE(val)
|
||||
}
|
||||
},
|
||||
setting () {
|
||||
return this.$store.getters.getSetting
|
||||
setting: {
|
||||
get () {
|
||||
return this.$store.getters.getSetting
|
||||
},
|
||||
set (val) {
|
||||
this.SET_SETTING(val)
|
||||
}
|
||||
},
|
||||
sitesList () {
|
||||
return this.$store.getters.getEditSites.sites // 需要监听的数据
|
||||
filterSettings () {
|
||||
return this.$store.getters.getSetting.excludeR18Films // 需要监听的数据
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
classNameFilter: (name) => {
|
||||
return name.replace(/[^\u4e00-\u9fa5]/gi, '')
|
||||
const clsName = name.toString()
|
||||
return clsName.replace(/[^\u4e00-\u9fa5]/gi, '')
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -264,36 +326,64 @@ export default {
|
||||
this.changeView()
|
||||
},
|
||||
searchTxt () {
|
||||
this.searchChangeEvent()
|
||||
if (this.searchTxt === '清除历史记录...') {
|
||||
this.clearSearchHistory()
|
||||
this.searchTxt = ''
|
||||
this.searchChangeEvent()
|
||||
}
|
||||
},
|
||||
sitesList () {
|
||||
this.getAllsites()
|
||||
filterSettings () {
|
||||
this.siteClick(this.site.name)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
|
||||
siteClick (e) {
|
||||
this.list = []
|
||||
this.site = e
|
||||
this.show.site = false
|
||||
this.show.class = false
|
||||
if (this.searchTxt.length > 0) {
|
||||
this.searchSingleSiteEvent(this.site, this.searchTxt)
|
||||
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE', 'SET_SETTING']),
|
||||
sortByLocaleCompare (a, b) {
|
||||
return a.localeCompare(b, 'zh')
|
||||
},
|
||||
dateFormat (row, column) {
|
||||
var date = row[column.property]
|
||||
if (date === undefined) {
|
||||
return ''
|
||||
}
|
||||
return date.split(/\s/)[0]
|
||||
},
|
||||
getFilters (column) {
|
||||
const searchContents = this.searchContents.filter(res => !this.setting.excludeR18Films || (res.type !== undefined && !this.containsR18Keywords(res.type)))
|
||||
if (column === 'siteName') return [...new Set(searchContents.map(row => row.site.name))].map(e => { return { text: e, value: e } }) // 有方法合并这两行吗?
|
||||
return [...new Set(searchContents.map(row => row[column]))].map(e => { return { text: e, value: e } })
|
||||
},
|
||||
filterChange (filters) {
|
||||
// 一次只能一列
|
||||
if (Object.values(filters)[0].length) {
|
||||
const otherColumns = this.$refs.searchResultTable.columns.filter(col => col.id !== this.currentColumn.id)
|
||||
otherColumns.forEach(col => { col.filterable = false })
|
||||
} else {
|
||||
const filterLabels = ['源站', '类型', '地区', '语言']
|
||||
const columns = this.$refs.searchResultTable.columns.filter(col => filterLabels.includes(col.label))
|
||||
columns.forEach(col => { col.filterable = true })
|
||||
}
|
||||
},
|
||||
siteClick (siteName) {
|
||||
this.list = []
|
||||
this.site = this.sites.find(x => x.name === siteName)
|
||||
if (this.searchTxt.length > 0 && this.searchGroup === '站内') {
|
||||
this.searchEvent()
|
||||
} else {
|
||||
this.searchTxt = ''
|
||||
this.show.find = false
|
||||
this.classList = []
|
||||
this.type = {}
|
||||
this.getClass().then(res => {
|
||||
if (res) {
|
||||
this.show.class = true
|
||||
this.infiniteId += 1
|
||||
}
|
||||
this.infiniteId += 1
|
||||
this.classClick(this.classList[0].name)
|
||||
})
|
||||
}
|
||||
},
|
||||
classClick (e) {
|
||||
classClick (className) {
|
||||
this.show.classList = false
|
||||
this.list = []
|
||||
this.type = e
|
||||
this.type = this.classList.find(x => x.name === className)
|
||||
this.getPage().then(res => {
|
||||
if (res) {
|
||||
this.infiniteId += 1
|
||||
@@ -353,8 +443,10 @@ export default {
|
||||
const key = this.site.key
|
||||
const type = this.type.tid
|
||||
const page = this.pagecount
|
||||
if (page < 1) {
|
||||
this.statusText = ' '
|
||||
if (key && page < 1) { // OK资源前几类硬是去不掉
|
||||
$state.complete()
|
||||
this.statusText = '暂无数据'
|
||||
return false
|
||||
}
|
||||
zy.list(key, page, type).then(res => {
|
||||
@@ -374,6 +466,7 @@ export default {
|
||||
$state.loaded()
|
||||
} else {
|
||||
$state.complete()
|
||||
this.statusText = '暂无数据'
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -392,6 +485,9 @@ export default {
|
||||
} else {
|
||||
this.video = { key: site.key, info: { id: e.id, name: e.name, index: 0, site: site } }
|
||||
}
|
||||
zy.detail(site.key, e.id).then(detailRes => {
|
||||
this.video.detail = detailRes
|
||||
})
|
||||
this.view = 'Play'
|
||||
},
|
||||
async starEvent (site, e) {
|
||||
@@ -420,9 +516,9 @@ export default {
|
||||
info: e
|
||||
}
|
||||
},
|
||||
downloadEvent (site, e) {
|
||||
zy.download(site.key, e.id).then(res => {
|
||||
if (res && res.length > 0 && res.dl && res.dl.dd) {
|
||||
downloadEvent (site, row) {
|
||||
zy.download(site.key, row.id).then(res => {
|
||||
if (res && res.length > 0) {
|
||||
const text = res.dl.dd._t
|
||||
if (text) {
|
||||
const list = text.split('#')
|
||||
@@ -438,7 +534,7 @@ export default {
|
||||
}
|
||||
} else {
|
||||
let m3u8List = []
|
||||
const dd = res.dl.dd
|
||||
const dd = row.dl.dd
|
||||
const type = Object.prototype.toString.call(dd)
|
||||
if (type === '[object Array]') {
|
||||
for (const i of dd) {
|
||||
@@ -449,7 +545,7 @@ export default {
|
||||
} else {
|
||||
m3u8List = dd._t.split('#')
|
||||
}
|
||||
let downloadUrl = e.name + '\n'
|
||||
let downloadUrl = row.name + '\n'
|
||||
for (const i of m3u8List) {
|
||||
const url = encodeURI(i.split('$')[1])
|
||||
downloadUrl += (url + '\n')
|
||||
@@ -461,76 +557,107 @@ export default {
|
||||
},
|
||||
changeView () {
|
||||
if (this.view === 'Film') {
|
||||
this.getAllSites()
|
||||
if (this.setting.view === 'picture') {
|
||||
this.$refs.filmWaterfall.refresh()
|
||||
if (this.$refs.filmWaterfall) {
|
||||
this.$refs.filmWaterfall.refresh()
|
||||
}
|
||||
this.getPage().then(() => {
|
||||
this.infiniteId += 1
|
||||
})
|
||||
}
|
||||
this.getPage().then(() => {
|
||||
this.infiniteId += 1
|
||||
})
|
||||
}
|
||||
},
|
||||
getAllSearch () {
|
||||
search.all().then(res => {
|
||||
this.searchList = res.reverse()
|
||||
})
|
||||
querySearch (queryString, cb) {
|
||||
if (this.searchList.length === 0) return
|
||||
var searchList = this.searchList.slice(0, -1)
|
||||
var results = queryString ? searchList.filter(this.createFilter(queryString)) : this.searchList
|
||||
// 调用 callback 返回建议列表的数据
|
||||
cb(results)
|
||||
},
|
||||
searchEvent (wd) {
|
||||
if (this.setting.searchAllSites) {
|
||||
this.searchAllSitesEvent(this.sites, wd)
|
||||
} else {
|
||||
this.searchSingleSiteEvent(this.site, wd)
|
||||
createFilter (queryString) {
|
||||
return (item) => {
|
||||
return (item.keywords.toLowerCase().indexOf(queryString.toLowerCase()) === 0)
|
||||
}
|
||||
},
|
||||
searchAllSitesEvent (sites, wd) {
|
||||
this.searchTxt = wd
|
||||
this.searchContents = []
|
||||
this.pagecount = 0
|
||||
this.show.search = false
|
||||
this.show.find = true
|
||||
addSearchRecord () {
|
||||
const wd = this.searchTxt
|
||||
if (wd) {
|
||||
search.find({ keywords: wd }).then(res => {
|
||||
if (!res) {
|
||||
search.add({ keywords: wd })
|
||||
}
|
||||
this.getAllSearch()
|
||||
this.getSearchHistory()
|
||||
})
|
||||
sites.forEach(site => {
|
||||
}
|
||||
},
|
||||
clearSearchHistory () {
|
||||
search.clear().then(res => {
|
||||
this.getSearchHistory()
|
||||
})
|
||||
},
|
||||
getSearchHistory () {
|
||||
search.all().then(res => {
|
||||
this.searchList = res.reverse()
|
||||
this.searchList.push({ id: this.searchList.length + 1, keywords: '清除历史记录...' })
|
||||
})
|
||||
},
|
||||
searchEvent () {
|
||||
const wd = this.searchTxt
|
||||
if (this.setting.searchGroup !== this.searchGroup) {
|
||||
this.setting.searchGroup = this.searchGroup
|
||||
setting.update(this.setting)
|
||||
}
|
||||
if (!wd) return
|
||||
this.searchID += 1
|
||||
var searchSites = []
|
||||
if (this.searchGroup === '站内') searchSites.push(this.site)
|
||||
if (this.searchGroup === '全站') searchSites = this.sites
|
||||
if (!searchSites.length) {
|
||||
searchSites = this.sites.filter(site => site.group === this.searchGroup)
|
||||
}
|
||||
this.searchContents = []
|
||||
this.pagecount = 0
|
||||
this.show.find = true
|
||||
this.show.class = false
|
||||
this.statusText = ' '
|
||||
if (wd) {
|
||||
searchSites.forEach(site => {
|
||||
const id = this.searchID
|
||||
zy.search(site.key, wd).then(res => {
|
||||
if (id !== this.searchID) return
|
||||
const type = Object.prototype.toString.call(res)
|
||||
if (type === '[object Array]') {
|
||||
res.forEach(element => {
|
||||
zy.detail(site.key, element.id).then(detailRes => {
|
||||
detailRes.site = site
|
||||
if (id !== this.searchID) return
|
||||
this.searchContents.push(detailRes)
|
||||
this.searchContents.sort(function (a, b) {
|
||||
return a.site.id - b.site.id
|
||||
})
|
||||
this.statusText = '暂无数据'
|
||||
})
|
||||
})
|
||||
}
|
||||
if (type === '[object Object]') {
|
||||
zy.detail(site.key, res.id).then(detailRes => {
|
||||
detailRes.site = site
|
||||
if (id !== this.searchID) return
|
||||
this.searchContents.push(detailRes)
|
||||
this.searchContents.sort(function (a, b) {
|
||||
return a.site.id - b.site.id
|
||||
})
|
||||
this.statusText = '暂无数据'
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.show.find = false
|
||||
this.getClass().then(res => {
|
||||
if (res) {
|
||||
this.infiniteId += 1
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
searchSingleSiteEvent (site, wd) {
|
||||
var sites = []
|
||||
sites.push(this.site)
|
||||
this.searchAllSitesEvent(sites, wd)
|
||||
},
|
||||
clearSearch () {
|
||||
search.clear().then(res => {
|
||||
this.getAllSearch()
|
||||
})
|
||||
searchAndRecord () {
|
||||
this.addSearchRecord()
|
||||
this.searchEvent()
|
||||
},
|
||||
searchChangeEvent () {
|
||||
if (this.searchTxt.length >= 1) {
|
||||
@@ -539,29 +666,53 @@ export default {
|
||||
this.show.class = true
|
||||
this.searchContents = []
|
||||
this.show.find = false
|
||||
if (this.setting.view === 'picture') {
|
||||
this.$refs.waterfall.refresh()
|
||||
if (this.setting.view === 'picture' && this.$refs.filmWaterfall) {
|
||||
this.$refs.filmWaterfall.refresh()
|
||||
} else {
|
||||
this.getClass().then(res => {
|
||||
if (res) {
|
||||
this.infiniteId += 1
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
getAllsites () {
|
||||
getAllSites () {
|
||||
sites.all().then(res => {
|
||||
if (res.length <= 0) {
|
||||
this.site = {}
|
||||
this.type = {}
|
||||
this.list = []
|
||||
} else {
|
||||
this.sites = res.filter((item, index, self) => {
|
||||
return self.indexOf(item) >= 0 && item.isActive
|
||||
})
|
||||
this.site = this.sites[0]
|
||||
this.siteClick(this.site)
|
||||
this.sites = res.filter(item => item.isActive)
|
||||
if (this.site === undefined || !this.sites.some(x => x.key === this.site.key)) {
|
||||
this.site = this.sites[0]
|
||||
this.selectedSiteName = this.sites[0].name
|
||||
}
|
||||
}
|
||||
this.searchGroups = [...new Set(this.sites.map(site => site.group))]
|
||||
if (this.searchGroups.length === 1) this.searchGroups = []
|
||||
this.searchGroups.unshift('站内')
|
||||
this.searchGroups.push('全站')
|
||||
this.searchGroup = this.setting.searchGroup
|
||||
if (this.searchGroup === undefined) setting.find().then(res => { this.searchGroup = res.searchGroup })
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.getAllSearch()
|
||||
this.getAllSites()
|
||||
this.getSearchHistory()
|
||||
},
|
||||
mounted () {
|
||||
window.addEventListener('resize', () => {
|
||||
if (this.$refs.filmWaterfall && this.view === 'Film') {
|
||||
this.$refs.filmWaterfall.resize()
|
||||
this.$refs.filmWaterfall.refresh()
|
||||
setTimeout(() => {
|
||||
this.$refs.filmWaterfall.refresh()
|
||||
}, 500)
|
||||
}
|
||||
}, false)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
<template>
|
||||
<div class="listpage" id="history">
|
||||
<div class="listpage-header" id="history-header">
|
||||
<el-switch v-model="viewMode" active-text="海报" active-value="picture" inactive-text="列表" inactive-value="list" @change="updateViewMode"></el-switch>
|
||||
<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-body">
|
||||
<div class="show-table" id="history-table" >
|
||||
<div class="show-table" id="history-table" v-show="viewMode === 'list'">
|
||||
<el-table size="mini" fit height="100%" :data="history" row-key="id" @row-click="detailEvent">
|
||||
<el-table-column
|
||||
prop="name"
|
||||
@@ -22,35 +23,87 @@
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="index"
|
||||
width="120"
|
||||
width="180"
|
||||
label="观看至">
|
||||
<template slot-scope="scope">
|
||||
<span>第{{ scope.row.index + 1 }}集</span>
|
||||
<span v-if="scope.row.detail && scope.row.detail.m3u8List && scope.row.detail.m3u8List.length > 1">
|
||||
第{{ scope.row.index + 1 }}集(共{{scope.row.detail.m3u8List.length}}集)
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="history.some(e => e.time)"
|
||||
width="150"
|
||||
label="时间进度">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.time && scope.row.duration">{{fmtMSS(scope.row.time.toFixed(0))}}/{{fmtMSS(scope.row.duration.toFixed(0))}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
header-align="right"
|
||||
width="200"
|
||||
header-align="center"
|
||||
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="removeHistoryItem(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="historyWaterfall" :list="history" :gutter="20" :width="240"
|
||||
:breakpoints="{
|
||||
1200: { //当屏幕宽度小于等于1200
|
||||
rowPerView: 4,
|
||||
},
|
||||
800: { //当屏幕宽度小于等于800
|
||||
rowPerView: 3,
|
||||
},
|
||||
500: { //当屏幕宽度小于等于500
|
||||
rowPerView: 2,
|
||||
}
|
||||
}"
|
||||
animationDuration="0.5s"
|
||||
backgroundColor="rgba(0, 0, 0, 0)">
|
||||
<template slot="item" slot-scope="props">
|
||||
<div class="card">
|
||||
<div class="img">
|
||||
<img v-if="props.data.detail && props.data.detail.pic" style="width: 100%" :src="props.data.detail.pic" alt="" @load="$refs.historyWaterfall.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 v-if="props.data.time && props.data.duration">
|
||||
{{fmtMSS(props.data.time.toFixed(0))}}/{{fmtMSS(props.data.duration.toFixed(0))}}
|
||||
</span>
|
||||
<span v-if="props.data.detail && props.data.detail.m3u8List !== undefined && props.data.detail.m3u8List.length > 1">
|
||||
第{{ props.data.index + 1 }}集(共{{props.data.detail.m3u8List.length}}集)
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Waterfall>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import { history, sites } from '../lib/dexie'
|
||||
import { history, sites, setting } from '../lib/dexie'
|
||||
import zy from '../lib/site/tools'
|
||||
import Sortable from 'sortablejs'
|
||||
import { remote } from 'electron'
|
||||
import fs from 'fs'
|
||||
import Waterfall from 'vue-waterfall-plugin'
|
||||
const { clipboard } = require('electron')
|
||||
|
||||
export default {
|
||||
@@ -58,9 +111,13 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
history: [],
|
||||
sites: []
|
||||
sites: [],
|
||||
viewMode: setting.historyViewMode
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Waterfall
|
||||
},
|
||||
computed: {
|
||||
view: {
|
||||
get () {
|
||||
@@ -99,10 +156,16 @@ export default {
|
||||
view () {
|
||||
this.getAllhistory()
|
||||
this.getAllsites()
|
||||
if (this.$refs.historyWaterfall) {
|
||||
this.$refs.historyWaterfall.refresh()
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
|
||||
fmtMSS (s) {
|
||||
return (s - (s %= 60)) / 60 + (s > 9 ? ':' : ':0') + s
|
||||
},
|
||||
detailEvent (e) {
|
||||
this.detail = {
|
||||
show: true,
|
||||
@@ -120,6 +183,9 @@ export default {
|
||||
} else {
|
||||
this.video = { key: e.site, info: { id: e.ids, name: e.name, index: 0 } }
|
||||
}
|
||||
zy.detail(e.site, e.ids).then(detailRes => {
|
||||
this.video.detail = detailRes
|
||||
})
|
||||
this.view = 'Play'
|
||||
},
|
||||
shareEvent (e) {
|
||||
@@ -230,7 +296,7 @@ export default {
|
||||
return site.name
|
||||
}
|
||||
},
|
||||
removeHistoryItem (e) {
|
||||
deleteEvent (e) {
|
||||
history.remove(e.id).then(res => {
|
||||
this.getAllhistory()
|
||||
}).catch(err => {
|
||||
@@ -257,13 +323,34 @@ export default {
|
||||
_this.updateDatabase(_this.history)
|
||||
}
|
||||
})
|
||||
},
|
||||
getViewMode () {
|
||||
setting.find().then(res => {
|
||||
this.viewMode = res.historyViewMode
|
||||
})
|
||||
},
|
||||
updateViewMode () {
|
||||
setting.find().then(res => {
|
||||
res.historyViewMode = this.viewMode
|
||||
setting.update(res)
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.rowDrop()
|
||||
window.addEventListener('resize', () => {
|
||||
if (this.$refs.historyWaterfall && this.view === 'History') {
|
||||
this.$refs.historyWaterfall.resize()
|
||||
this.$refs.historyWaterfall.refresh()
|
||||
setTimeout(() => {
|
||||
this.$refs.historyWaterfall.refresh()
|
||||
}, 500)
|
||||
}
|
||||
}, false)
|
||||
},
|
||||
created () {
|
||||
this.getAllhistory()
|
||||
this.getViewMode()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -4,13 +4,15 @@
|
||||
<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="checkAllChannels" icon="el-icon-refresh" :loading="checkAllChannelsLoading">检测{{ this.checkAllChannelsLoading ? this.checkProgress + '/' + this.iptvList.length : '' }}</el-button>
|
||||
<el-button @click.stop="resetChannelsEvent" icon="el-icon-refresh-left">重置</el-button>
|
||||
</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-switch v-model="batchIsActive" active-text="启用"></el-switch>
|
||||
<el-button type="primary" icon="el-icon-edit" @click.stop="saveBatchEdit">保存</el-button>
|
||||
<el-button @click.stop="removeSelectedChannels" icon="el-icon-delete-solid">删除</el-button>
|
||||
</div>
|
||||
<div class="listpage-body" id="iptv-table">
|
||||
<div class="show-table" id="iptv-table">
|
||||
@@ -19,6 +21,7 @@
|
||||
size="mini" fit height="100%" row-key="id"
|
||||
:data="filteredTableData"
|
||||
@row-click="playEvent"
|
||||
@select="selectionCellClick"
|
||||
@selection-change="handleSelectionChange"
|
||||
@sort-change="handleSortChange">>
|
||||
<el-table-column
|
||||
@@ -39,27 +42,55 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
sort-by="['group', 'name']"
|
||||
prop="isActive"
|
||||
width="120"
|
||||
align="center"
|
||||
:filters = "[{text:'启用', value: true}, {text:'停用', value: false}]"
|
||||
:filter-method="(value, row) => value === row.isActive"
|
||||
label="启用">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.isActive"
|
||||
@click.native.stop='isActiveChangeEvent(scope.row)'>
|
||||
</el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
sortable
|
||||
:sort-method="sortByGroup"
|
||||
:sort-method="(a , b) => sortByLocaleCompare(a.group, b.group)"
|
||||
prop="group"
|
||||
label="分组"
|
||||
:filters="getFilters"
|
||||
:filter-method="filterHandle"
|
||||
:filter-method="(value, row) => value === row.group"
|
||||
filter-placement="bottom-end">
|
||||
<template slot-scope="scope">
|
||||
<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-if="scope.row.status === ' '">
|
||||
<i class="el-icon-loading"></i>
|
||||
检测中...
|
||||
</span>
|
||||
<span v-else>{{scope.row.status}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
header-align="right"
|
||||
align="right">
|
||||
align="right"
|
||||
:width="200">
|
||||
<template #header>
|
||||
<span>总频道数:{{ iptvList.length }}</span>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<el-button @click.stop="moveToTopEvent(scope.row)" type="text">置顶</el-button>
|
||||
<!-- 检测时先强制批量检测一遍,如果不强制直接单个检测时第一次不会显示“检测中”-->
|
||||
<el-button size="mini" v-if="iptvList.every(channel => channel.status)" v-show="!checkAllChannelsLoading" @click.stop="checkSingleChannel(scope.row)" type="text">检测</el-button>
|
||||
<el-button @click.stop="removeEvent(scope.row)" type="text">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -71,7 +102,8 @@
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import { iptv, iptvSearch } from '../lib/dexie'
|
||||
import { iptv as defaultSites } from '../lib/dexie/initData'
|
||||
import { iptv as defaultChannels } from '../lib/dexie/initData'
|
||||
import zy from '../lib/site/tools'
|
||||
import { remote } from 'electron'
|
||||
import fs from 'fs'
|
||||
import Sortable from 'sortablejs'
|
||||
@@ -84,7 +116,14 @@ export default {
|
||||
searchRecordList: [],
|
||||
enableBatchEdit: false,
|
||||
batchGroupName: '',
|
||||
batchIsActive: true,
|
||||
shiftDown: false,
|
||||
selectionBegin: '',
|
||||
selectionEnd: '',
|
||||
multipleSelection: [],
|
||||
checkAllChannelsLoading: false,
|
||||
checkProgress: 0,
|
||||
stopFlag: false,
|
||||
show: {
|
||||
search: false
|
||||
}
|
||||
@@ -136,34 +175,58 @@ export default {
|
||||
this.getChannels()
|
||||
}
|
||||
},
|
||||
searchTxt () {
|
||||
enableBatchEdit () {
|
||||
if (this.checkAllChannelsLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
this.enableBatchEdit = false
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
|
||||
sortByGroup (a, b) {
|
||||
return a.group.localeCompare(b.group, 'zh')
|
||||
sortByLocaleCompare (a, b) {
|
||||
return a.localeCompare(b, 'zh')
|
||||
},
|
||||
selectionCellClick (selection, row) {
|
||||
if (this.shiftDown && this.selectionBegin !== '' && selection.includes(row)) {
|
||||
this.selectionEnd = row.id
|
||||
const start = Math.min(this.selectionBegin, this.selectionEnd) - 1
|
||||
const end = Math.max(this.selectionBegin, this.selectionEnd)
|
||||
const selections = this.iptvList.slice(start, end)
|
||||
this.$nextTick(() => {
|
||||
selections.forEach(e => this.$refs.iptvTable.toggleRowSelection(e, true))
|
||||
})
|
||||
this.selectionBegin = this.selectionEnd = ''
|
||||
return
|
||||
}
|
||||
if (selection.includes(row)) {
|
||||
this.selectionBegin = row.id
|
||||
} else {
|
||||
this.selectionBegin = ''
|
||||
}
|
||||
},
|
||||
handleSelectionChange (rows) {
|
||||
this.multipleSelection = rows
|
||||
},
|
||||
handleSortChange (column, prop, order) {
|
||||
this.updateDatabase()
|
||||
},
|
||||
saveBatchEdit () {
|
||||
if (this.multipleSelection && this.batchGroupName) {
|
||||
this.multipleSelection.forEach(ele => {
|
||||
ele.group = this.batchGroupName
|
||||
})
|
||||
if (this.checkAllChannelsLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
this.enableBatchEdit = false
|
||||
}
|
||||
this.updateDatabase()
|
||||
},
|
||||
playEvent (e) {
|
||||
this.video = { iptv: { name: e.name, url: e.url } }
|
||||
this.view = 'Play'
|
||||
saveBatchEdit () {
|
||||
this.multipleSelection.forEach(ele => {
|
||||
if (this.batchGroupName) {
|
||||
ele.group = this.batchGroupName
|
||||
}
|
||||
ele.isActive = this.batchIsActive
|
||||
})
|
||||
this.updateDatabase()
|
||||
},
|
||||
filterHandle (value, row) {
|
||||
return row.group === value
|
||||
playEvent (e) {
|
||||
this.video = { iptv: { name: e.name, url: e.url, id: e.id } }
|
||||
this.view = 'Play'
|
||||
},
|
||||
containsearchTxt (i) {
|
||||
if (this.searchTxt) {
|
||||
@@ -173,23 +236,16 @@ export default {
|
||||
}
|
||||
},
|
||||
removeEvent (e) {
|
||||
if (this.checkAllChannelsLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
return false
|
||||
}
|
||||
iptv.remove(e.id).then(res => {
|
||||
this.getChannels()
|
||||
}).catch(err => {
|
||||
this.$message.warning('删除频道失败, 错误信息: ' + err)
|
||||
})
|
||||
},
|
||||
listUpdatedEvent () {
|
||||
iptv.clear().then(res1 => {
|
||||
// 重新排序
|
||||
var id = 1
|
||||
this.iptvList.forEach(element => {
|
||||
element.id = id
|
||||
iptv.add(element)
|
||||
id += 1
|
||||
})
|
||||
})
|
||||
},
|
||||
exportChannels () {
|
||||
const options = {
|
||||
filters: [
|
||||
@@ -218,6 +274,10 @@ export default {
|
||||
})
|
||||
},
|
||||
importChannels () {
|
||||
if (this.checkAllChannelsLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
return false
|
||||
}
|
||||
const options = {
|
||||
filters: [
|
||||
{ name: 'm3u file', extensions: ['m3u', 'm3u8'] },
|
||||
@@ -228,7 +288,7 @@ export default {
|
||||
remote.dialog.showOpenDialog(options).then(result => {
|
||||
if (!result.canceled) {
|
||||
var docs = this.iptvList
|
||||
var id = docs.length
|
||||
var id = docs.length + 1
|
||||
result.filePaths.forEach(file => {
|
||||
if (file.endsWith('m3u') || file.endsWith('m3u8')) {
|
||||
const parser = require('iptv-playlist-parser')
|
||||
@@ -240,6 +300,7 @@ export default {
|
||||
id: id,
|
||||
name: ele.name,
|
||||
url: ele.url,
|
||||
isActive: true,
|
||||
group: this.determineGroup(ele.name)
|
||||
}
|
||||
id += 1
|
||||
@@ -256,6 +317,7 @@ export default {
|
||||
id: id,
|
||||
name: ele.name,
|
||||
url: ele.url,
|
||||
isActive: ele.isActive === undefined ? true : ele.isActive,
|
||||
group: this.determineGroup(ele.name)
|
||||
}
|
||||
id += 1
|
||||
@@ -265,9 +327,9 @@ export default {
|
||||
}
|
||||
})
|
||||
// 获取name不重复的列表
|
||||
const uniqueList = [...new Map(docs.map(item => [item.name, item])).values()]
|
||||
// const uniqueList = [...new Map(docs.map(item => [item.name, item])).values()]
|
||||
iptv.clear().then(res => {
|
||||
iptv.bulkAdd(uniqueList).then(e => {
|
||||
iptv.bulkAdd(docs).then(e => { // 支持导入同名频道,群里反馈
|
||||
this.getChannels()
|
||||
this.$message.success('导入成功')
|
||||
})
|
||||
@@ -291,19 +353,27 @@ export default {
|
||||
}
|
||||
},
|
||||
resetChannelsEvent () {
|
||||
this.resetChannels(defaultSites)
|
||||
this.stopFlag = true
|
||||
if (this.checkAllChannelsLoading) {
|
||||
this.$message.info('部分检测还未完全终止, 请稍等...')
|
||||
return
|
||||
}
|
||||
iptv.clear().then(iptv.bulkAdd(defaultChannels).then(this.getChannels()))
|
||||
},
|
||||
resetChannels (newSites) {
|
||||
this.resetId(newSites)
|
||||
iptv.clear().then(iptv.bulkAdd(newSites).then(this.getChannels()))
|
||||
},
|
||||
removeAllChannels () {
|
||||
iptv.clear().then(res => {
|
||||
this.getChannels()
|
||||
})
|
||||
removeSelectedChannels () {
|
||||
this.multipleSelection.forEach(e => iptv.remove(e.id))
|
||||
this.$refs.iptvTable.clearFilter()
|
||||
this.getChannels()
|
||||
this.updateDatabase()
|
||||
this.enableBatchEdit = false
|
||||
},
|
||||
getChannels () {
|
||||
iptv.all().then(res => {
|
||||
res.forEach(ele => {
|
||||
if (ele.isActive === undefined) {
|
||||
ele.isActive = true
|
||||
}
|
||||
})
|
||||
this.iptvList = res
|
||||
})
|
||||
},
|
||||
@@ -330,11 +400,15 @@ export default {
|
||||
}
|
||||
},
|
||||
moveToTopEvent (i) {
|
||||
if (this.checkAllChannelsLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
return false
|
||||
}
|
||||
this.iptvList.sort(function (x, y) { return (x.name === i.name && x.url === i.url) ? -1 : (y.name === i.name && y.url === i.url) ? 1 : 0 })
|
||||
this.updateDatabase()
|
||||
},
|
||||
syncTableData () {
|
||||
if (this.$refs.iptvTable.tableData && this.$refs.iptvTable.tableData.length === this.iptvList.length) {
|
||||
if (this.$refs.iptvTable.tableData) {
|
||||
this.iptvList = this.$refs.iptvTable.tableData
|
||||
}
|
||||
},
|
||||
@@ -353,6 +427,10 @@ export default {
|
||||
})
|
||||
},
|
||||
rowDrop () {
|
||||
if (this.checkAllChannelsLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
return false
|
||||
}
|
||||
const tbody = document.getElementById('iptv-table').querySelector('.el-table__body-wrapper tbody')
|
||||
const _this = this
|
||||
Sortable.create(tbody, {
|
||||
@@ -362,10 +440,64 @@ export default {
|
||||
_this.updateDatabase()
|
||||
}
|
||||
})
|
||||
},
|
||||
isActiveChangeEvent (row) {
|
||||
iptv.remove(row.id)
|
||||
iptv.add(row)
|
||||
},
|
||||
async checkAllChannels () {
|
||||
this.checkAllChannelsLoading = true
|
||||
this.stopFlag = false
|
||||
this.checkProgress = 0
|
||||
const uncheckedList = this.iptvList.filter(e => e.status === undefined || e.status === ' ') // 未检测过的优先
|
||||
const other = this.iptvList.filter(e => !uncheckedList.includes(e))
|
||||
await this.checkChannelList(uncheckedList)
|
||||
await this.checkChannelList(other).then(res => {
|
||||
this.checkAllChannelsLoading = false
|
||||
this.getChannels()
|
||||
})
|
||||
},
|
||||
async checkChannelList (channelList) {
|
||||
var siteList = {}
|
||||
channelList.forEach(channel => {
|
||||
const site = channel.url.split('/')[2]
|
||||
if (siteList[site]) {
|
||||
siteList[site].push(channel)
|
||||
} else {
|
||||
siteList[site] = [channel]
|
||||
}
|
||||
})
|
||||
await Promise.all(Object.values(siteList).map(site => this.checkSingleSite(site)))
|
||||
},
|
||||
async checkSingleSite (channelArray) {
|
||||
for (const c of channelArray) {
|
||||
if (this.stopFlag) return false
|
||||
await this.checkSingleChannel(c)
|
||||
}
|
||||
},
|
||||
async checkSingleChannel (row) {
|
||||
row.status = ' '
|
||||
if (this.stopFlag) {
|
||||
this.checkProgress += 1
|
||||
return row.status
|
||||
}
|
||||
const flag = await zy.checkChannel(row.url)
|
||||
this.checkProgress += 1
|
||||
if (flag) {
|
||||
row.status = '可用'
|
||||
} else {
|
||||
row.status = '失效'
|
||||
row.isActive = false
|
||||
}
|
||||
iptv.remove(row.id)
|
||||
iptv.add(row)
|
||||
return row.status
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.rowDrop()
|
||||
addEventListener('keydown', code => { if (code.keyCode === 16) this.shiftDown = true })
|
||||
addEventListener('keyup', code => { if (code.keyCode === 16) this.shiftDown = false })
|
||||
},
|
||||
created () {
|
||||
this.getChannels()
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<div class="player">
|
||||
<div id="xgplayer"></div>
|
||||
</div>
|
||||
<div class="more">
|
||||
<div class="more" v-if="!video.iptv" :key="Boolean(video.iptv)">
|
||||
<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>
|
||||
@@ -100,14 +100,44 @@
|
||||
</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 class="more" v-if="video.iptv" :key="Boolean(video.iptv)">
|
||||
<span class="zy-svg" @click="otherEvent" v-if="right.otherChannels.length">
|
||||
<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="miniEvent">
|
||||
<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">
|
||||
<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>
|
||||
<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 class="zy-svg" @click="showShortcutEvent">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<transition name="slideX">
|
||||
<div v-if="right.show" class="list">
|
||||
<div class="list-top">
|
||||
<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-title" v-if="right.type === 'shortcut'">快捷键指南{{ this.video.iptv ? '(直播时部分功能不可用)' : '' }}</span>
|
||||
<span class="list-top-title" v-if="right.type === 'other'">同组其他源的视频</span>
|
||||
<span class="list-top-title" v-if="right.type === 'otherChannels'">该频道其它源</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>
|
||||
@@ -116,23 +146,27 @@
|
||||
</span>
|
||||
</div>
|
||||
<div class="list-body zy-scroll" :style="{overflowY:scroll? 'auto' : 'hidden',paddingRight: scroll ? '0': '5px' }" @mouseenter="scroll = true" @mouseleave="scroll = false">
|
||||
<ul v-show="right.type === 'list'" class="list-item">
|
||||
<li v-show="right.list.length > 0" @click="exportM3u8">导出</li>
|
||||
<li v-show="right.list.length === 0">无数据</li>
|
||||
<ul v-if="right.type === 'list'" class="list-item" v-on-clickaway="closeListEvent">
|
||||
<li v-if="right.list.length > 0" @click="exportM3u8">导出</li>
|
||||
<li v-if="right.list.length === 0">无数据</li>
|
||||
<li @click="listItemEvent(j)" :class="video.info.index === j ? 'active' : ''" v-for="(i, j) in right.list" :key="j">{{i | ftName(j)}}</li>
|
||||
</ul>
|
||||
<ul v-show="right.type === 'history'" class="list-history">
|
||||
<li v-show="right.history.length > 0" @click="clearAllHistory">清空</li>
|
||||
<li v-show="right.history.length === 0">无数据</li>
|
||||
<ul v-if="right.type === 'history'" class="list-history" v-on-clickaway="closeListEvent">
|
||||
<li v-if="right.history.length > 0" @click="clearAllHistory">清空</li>
|
||||
<li v-if="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">
|
||||
<ul v-if="right.type === 'shortcut'" class="list-shortcut" v-on-clickaway="closeListEvent">
|
||||
<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>
|
||||
<ul v-if="right.type === 'other'" class="list-other" v-on-clickaway="closeListEvent">
|
||||
<li v-if="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>
|
||||
<ul v-if="right.type === 'otherChannels'" class="list-other" v-on-clickaway="closeListEvent">
|
||||
<li v-if="right.otherChannels.length === 0">无数据</li>
|
||||
<li @click="playChannel(channel)" v-for="(channel, index) in right.otherChannels" :key="index"><span class="title">{{channel.name}}</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
@@ -145,6 +179,9 @@ import zy from '../lib/site/tools'
|
||||
import Player from 'xgplayer'
|
||||
import Hls from 'xgplayer-hls.js'
|
||||
import mt from 'mousetrap'
|
||||
import { directive as onClickaway } from 'vue-clickaway'
|
||||
import { exec, execFile } from 'child_process'
|
||||
|
||||
const { remote, ipcRenderer, clipboard } = require('electron')
|
||||
|
||||
const VIDEO_DETAIL_CACHE = {}
|
||||
@@ -200,7 +237,9 @@ export default {
|
||||
list: [],
|
||||
history: [],
|
||||
shortcut: [],
|
||||
other: []
|
||||
other: [],
|
||||
otherChannels: [],
|
||||
currentTime: 0
|
||||
},
|
||||
config: {
|
||||
id: 'xgplayer',
|
||||
@@ -221,7 +260,8 @@ export default {
|
||||
videoStop: true,
|
||||
showList: true,
|
||||
showHistory: true,
|
||||
videoTitle: true
|
||||
videoTitle: true,
|
||||
airplay: true
|
||||
},
|
||||
state: {
|
||||
showList: false,
|
||||
@@ -247,6 +287,9 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
directives: {
|
||||
onClickaway: onClickaway
|
||||
},
|
||||
computed: {
|
||||
view: {
|
||||
get () {
|
||||
@@ -330,23 +373,27 @@ export default {
|
||||
|
||||
if (this.video.iptv) {
|
||||
// 是直播源,直接播放
|
||||
this.playUrl(this.video.iptv.url)
|
||||
this.name = this.video.iptv.name
|
||||
this.getIptvList()
|
||||
this.playChannel(this.video.iptv)
|
||||
} else {
|
||||
const index = this.video.info.index | 0
|
||||
let time = 0
|
||||
const db = await history.find({ site: this.video.key, ids: this.video.info.id })
|
||||
if (db) {
|
||||
if (db.index === index) {
|
||||
time = db.time
|
||||
var time = this.video.info.time
|
||||
if (!time) {
|
||||
// 如果video.info.time没有设定的话,从历史中读取时间进度
|
||||
const db = await history.find({ site: this.video.key, ids: this.video.info.id })
|
||||
if (db) {
|
||||
if (db.index === index) {
|
||||
time = db.time
|
||||
}
|
||||
}
|
||||
}
|
||||
this.playVideo(index, time)
|
||||
}
|
||||
},
|
||||
playUrl (url) {
|
||||
this.xg.src = url
|
||||
playChannel (channel) {
|
||||
this.getIptvList()
|
||||
this.video.iptv = channel
|
||||
this.name = channel.name
|
||||
this.xg.src = channel.url
|
||||
this.xg.play()
|
||||
},
|
||||
playVideo (index = 0, time = 0) {
|
||||
@@ -428,10 +475,10 @@ export default {
|
||||
type: db.type,
|
||||
year: db.year,
|
||||
index: this.video.info.index,
|
||||
time: db.time
|
||||
time: db.time,
|
||||
detail: this.video.detail
|
||||
}
|
||||
history.remove(db.id)
|
||||
history.add(doc)
|
||||
history.update(db.id, doc)
|
||||
} else {
|
||||
const doc = {
|
||||
site: this.video.key,
|
||||
@@ -440,7 +487,8 @@ export default {
|
||||
type: this.video.info.type,
|
||||
year: this.video.info.year,
|
||||
index: this.video.info.index,
|
||||
time: ''
|
||||
time: '',
|
||||
detail: this.video.detail
|
||||
}
|
||||
history.add(doc)
|
||||
}
|
||||
@@ -448,15 +496,23 @@ export default {
|
||||
this.timerEvent()
|
||||
},
|
||||
changeVideo () {
|
||||
const win = remote.getCurrentWindow()
|
||||
win.setProgressBar(-1)
|
||||
this.checkStar()
|
||||
this.checkTop()
|
||||
},
|
||||
timerEvent () {
|
||||
this.timer = setInterval(async () => {
|
||||
const endTime = this.xg.duration
|
||||
const currentTime = this.xg.currentTime
|
||||
const progress = parseFloat((currentTime / endTime).toFixed(2))
|
||||
const win = remote.getCurrentWindow()
|
||||
win.setProgressBar(progress)
|
||||
const db = await history.find({ site: this.video.key, ids: this.video.info.id })
|
||||
if (db) {
|
||||
const doc = { ...db }
|
||||
doc.time = this.xg.currentTime
|
||||
doc.duration = this.xg.duration
|
||||
delete doc.id
|
||||
history.update(db.id, doc)
|
||||
}
|
||||
@@ -467,8 +523,7 @@ export default {
|
||||
var index = this.iptvList.findIndex(obj => obj.name === this.video.iptv.name && obj.url === this.video.iptv.url)
|
||||
if (index >= 1) {
|
||||
var channel = this.iptvList[index - 1]
|
||||
this.video.iptv = channel
|
||||
this.playUrl(channel.url)
|
||||
this.playChannel(channel)
|
||||
} else {
|
||||
this.$message.warning('这已经是第一个频道了。')
|
||||
}
|
||||
@@ -486,8 +541,7 @@ export default {
|
||||
var index = this.iptvList.findIndex(obj => obj.name === this.video.iptv.name && obj.url === this.video.iptv.url)
|
||||
if (index < (this.iptvList.length - 1)) {
|
||||
var channel = this.iptvList[index + 1]
|
||||
this.video.iptv = channel
|
||||
this.playUrl(channel.url)
|
||||
this.playChannel(channel)
|
||||
} else {
|
||||
this.$message.warning('这已经是最后一个频道了。')
|
||||
}
|
||||
@@ -572,13 +626,23 @@ export default {
|
||||
this.xg.pause()
|
||||
}
|
||||
mini.find().then(res => {
|
||||
const doc = {
|
||||
id: 0,
|
||||
site: this.video.key,
|
||||
ids: this.video.info.id,
|
||||
name: this.video.info.name,
|
||||
index: this.video.info.index,
|
||||
time: this.xg.currentTime
|
||||
var doc = {}
|
||||
if (!this.video.iptv) {
|
||||
doc = {
|
||||
id: 0,
|
||||
mode: 'video',
|
||||
site: this.video.key,
|
||||
ids: this.video.info.id,
|
||||
name: this.video.info.name,
|
||||
index: this.video.info.index,
|
||||
time: this.xg.currentTime
|
||||
}
|
||||
} else {
|
||||
doc = {
|
||||
id: 0,
|
||||
mode: 'iptv',
|
||||
url: this.video.iptv.url
|
||||
}
|
||||
}
|
||||
if (res) {
|
||||
mini.update(doc)
|
||||
@@ -612,8 +676,21 @@ export default {
|
||||
this.$message.success('视频信息复制成功')
|
||||
},
|
||||
playWithExternalPalyerEvent () {
|
||||
const fs = require('fs')
|
||||
if (this.video.iptv) {
|
||||
var externalPlayer = this.setting.externalPlayer
|
||||
if (!externalPlayer) {
|
||||
this.$message.error('请设置第三方播放器路径')
|
||||
return
|
||||
}
|
||||
if (fs.existsSync(externalPlayer)) {
|
||||
execFile(externalPlayer, [this.video.iptv.url])
|
||||
} else {
|
||||
exec(externalPlayer, [this.video.iptv.url])
|
||||
}
|
||||
return
|
||||
}
|
||||
this.fetchM3u8List().then(m3u8Arr => {
|
||||
const fs = require('fs')
|
||||
var externalPlayer = this.setting.externalPlayer
|
||||
if (!externalPlayer) {
|
||||
this.$message.error('请设置第三方播放器路径')
|
||||
@@ -624,10 +701,8 @@ export default {
|
||||
} else {
|
||||
var m3uFile = this.generateM3uFile(this.video.info.name, m3u8Arr, this.video.info.index)
|
||||
if (fs.existsSync(externalPlayer)) {
|
||||
var execFile = require('child_process').execFile
|
||||
execFile(externalPlayer, [m3uFile])
|
||||
} else {
|
||||
var exec = require('child_process').exec
|
||||
exec(externalPlayer, [m3uFile])
|
||||
}
|
||||
}
|
||||
@@ -710,10 +785,8 @@ export default {
|
||||
listItemEvent (n) {
|
||||
if (this.video.iptv) {
|
||||
var channel = this.iptvList[n]
|
||||
this.video.iptv = channel
|
||||
this.name = this.video.iptv.name
|
||||
// 是直播源,直接播放
|
||||
this.playUrl(channel.url)
|
||||
this.playChannel(channel)
|
||||
} else {
|
||||
this.video.info.time = 0
|
||||
this.video.info.index = n
|
||||
@@ -746,9 +819,10 @@ export default {
|
||||
},
|
||||
async getOtherSites () {
|
||||
this.right.other = []
|
||||
const currentSite = await sites.find({ key: this.video.key })
|
||||
sites.all().then(sitesRes => {
|
||||
// 排除已关闭的源和当前源
|
||||
for (const siteItem of sitesRes.filter(x => x.isActive && x.key !== this.video.key)) {
|
||||
for (const siteItem of sitesRes.filter(x => x.isActive && x.group === currentSite.group && x.key !== this.video.key)) {
|
||||
zy.search(siteItem.key, this.name).then(searchRes => {
|
||||
const type = Object.prototype.toString.call(searchRes)
|
||||
if (type === '[object Array]') {
|
||||
@@ -770,15 +844,18 @@ export default {
|
||||
})
|
||||
},
|
||||
otherEvent (m) {
|
||||
this.right.type = 'other'
|
||||
this.getOtherSites()
|
||||
if (!this.video.iptv) {
|
||||
this.right.type = 'other'
|
||||
this.getOtherSites()
|
||||
this.right.currentTime = this.xg.currentTime
|
||||
} else {
|
||||
this.right.type = 'otherChannels'
|
||||
}
|
||||
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 = ''
|
||||
this.video = { key: e.key, info: { id: e.id, name: e.name, site: e.site, index: this.video.info.index, time: this.right.currentTime } }
|
||||
},
|
||||
mtEvent () {
|
||||
setting.find().then(res => {
|
||||
@@ -806,6 +883,8 @@ export default {
|
||||
if (this.xg) {
|
||||
if (this.xg.paused) {
|
||||
this.xg.play()
|
||||
// 继续播放时,隐藏进度条
|
||||
remote.getCurrentWindow().setProgressBar(-1)
|
||||
} else {
|
||||
this.xg.pause()
|
||||
}
|
||||
@@ -956,6 +1035,7 @@ export default {
|
||||
let li = ''
|
||||
if (this.video.iptv) {
|
||||
// 直播频道列表
|
||||
this.getIptvList()
|
||||
let index = 0
|
||||
this.iptvList.forEach(e => {
|
||||
if (e.name === this.video.iptv.name && e.url === this.video.iptv.url) {
|
||||
@@ -1032,7 +1112,20 @@ export default {
|
||||
},
|
||||
getIptvList () {
|
||||
iptv.all().then(res => {
|
||||
this.iptvList = res
|
||||
this.iptvList = res.filter(e => e.isActive)
|
||||
this.right.otherChannels = []
|
||||
const iptvList = JSON.parse(JSON.stringify(this.iptvList))
|
||||
var currentChannelName = this.video.iptv.name.trim().replace(/[- ]?(1080p|蓝光|超清|高清|标清|hd|cq|4k)(\d{1,2})?/i, '')
|
||||
if (currentChannelName.match(/cctv/i)) currentChannelName = currentChannelName.replace('-', '')
|
||||
const matchRule = new RegExp(`${currentChannelName}(1080p|4k|(?!\\d))`, 'i')
|
||||
for (var i = 0; i < iptvList.length; i++) {
|
||||
if (iptvList[i].name.match(/cctv/i)) {
|
||||
iptvList[i].name = iptvList[i].name.replace('-', '')
|
||||
}
|
||||
if (matchRule.test(iptvList[i].name) && iptvList[i].id !== this.video.iptv.id) {
|
||||
this.right.otherChannels.push(this.iptvList[i])
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
bindEvent () {
|
||||
@@ -1079,6 +1172,8 @@ export default {
|
||||
})
|
||||
},
|
||||
videoStop () {
|
||||
const win = remote.getCurrentWindow()
|
||||
win.setProgressBar(-1)
|
||||
if (this.xg.fullscreen) {
|
||||
this.xg.exitFullscreen()
|
||||
}
|
||||
@@ -1142,7 +1237,6 @@ export default {
|
||||
shortcut.all().then(res => {
|
||||
this.right.type = 'shortcut'
|
||||
this.right.shortcut = res
|
||||
console.log(res)
|
||||
})
|
||||
}
|
||||
},
|
||||
@@ -1172,6 +1266,14 @@ export default {
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.xgplayer-skin-default .xgplayer-live {
|
||||
width: 100px;
|
||||
position: absolute;
|
||||
top:50%;
|
||||
left:50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 18px !important;
|
||||
}
|
||||
.xgplayer-skin-default .xg-btn-playPrev,
|
||||
.xgplayer-skin-default .xg-btn-playNextOne,
|
||||
.xgplayer-skin-default .xg-btn-showList,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div class="listpage" id="recommandataions">
|
||||
<div class="listpage-header" id="recommandataions-header">
|
||||
<div class="listpage" id="recommendataions">
|
||||
<div class="listpage-header" id="recommendataions-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-button type="text">视频数:{{ recommendations.length }}</el-button>
|
||||
<el-select v-model="selectedAreas" size="small" multiple collapse-tags placeholder="地区" popper-class="popper" :popper-append-to-body="false">
|
||||
<el-option
|
||||
v-for="item in areas"
|
||||
:key="item"
|
||||
@@ -11,7 +11,7 @@
|
||||
:value="item">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-select size="mini" v-model="selectedTypes" multiple collapse-tags style="margin-left: 20px;" placeholder="类型">
|
||||
<el-select v-model="selectedTypes" size="small" multiple collapse-tags placeholder="类型" popper-class="popper" :popper-append-to-body="false">
|
||||
<el-option
|
||||
v-for="item in types"
|
||||
:key="item"
|
||||
@@ -19,13 +19,21 @@
|
||||
:value="item">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-select v-model="sortKeyword" size="small" placeholder="排序" popper-class="popper" :popper-append-to-body="false">
|
||||
<el-option
|
||||
v-for="item in sortKeywords"
|
||||
: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="listpage-body" id="recommendataions-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"
|
||||
ref="recommendataionsTable"
|
||||
:data="filteredRecommendations"
|
||||
@row-click="detailEvent">
|
||||
<el-table-column
|
||||
prop="name"
|
||||
@@ -47,20 +55,21 @@
|
||||
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)"
|
||||
<el-table-column v-if="filteredRecommendations.some(e => e.rate)"
|
||||
prop="rate"
|
||||
width="120"
|
||||
align="center"
|
||||
width="100"
|
||||
label="豆瓣评分">
|
||||
</el-table-column>
|
||||
<el-table-column v-if="filteredRecommendations.some(e => e.detail.note)"
|
||||
prop="detail.note"
|
||||
label="备注">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
header-align="right"
|
||||
align="right">
|
||||
header-align="center"
|
||||
align="right"
|
||||
width="200">
|
||||
<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>
|
||||
@@ -71,9 +80,19 @@
|
||||
</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"
|
||||
<Waterfall ref="recommendataionsWaterfall" :list="filteredRecommendations" :gutter="20" :width="240"
|
||||
:breakpoints="{
|
||||
1200: { //当屏幕宽度小于等于1200
|
||||
rowPerView: 4,
|
||||
},
|
||||
800: { //当屏幕宽度小于等于800
|
||||
rowPerView: 3,
|
||||
},
|
||||
500: { //当屏幕宽度小于等于500
|
||||
rowPerView: 2,
|
||||
}
|
||||
}"
|
||||
animationDuration="0.5s"
|
||||
backgroundColor="rgba(0, 0, 0, 0)">
|
||||
<template slot="item" slot-scope="props">
|
||||
<div class="card">
|
||||
@@ -81,7 +100,7 @@
|
||||
<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)">
|
||||
<img style="width: 100%" :src="props.data.detail.pic" alt="" @load="$refs.recommendataionsWaterfall.refresh()" @click="detailEvent(props.data)">
|
||||
<div class="operate">
|
||||
<div class="operate-wrap">
|
||||
<span class="o-play" @click="playEvent(props.data)">播放</span>
|
||||
@@ -107,22 +126,24 @@
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import { history, recommandation, setting } from '../lib/dexie'
|
||||
import { history, recommendation, setting } from '../lib/dexie'
|
||||
import zy from '../lib/site/tools'
|
||||
import Waterfall from 'vue-waterfall-plugin'
|
||||
const { clipboard } = require('electron')
|
||||
export default {
|
||||
name: 'recommandations',
|
||||
name: 'recommendations',
|
||||
data () {
|
||||
return {
|
||||
recommandations: [],
|
||||
recommendations: [],
|
||||
sites: [],
|
||||
viewMode: 'picture',
|
||||
loading: false,
|
||||
types: [],
|
||||
selectedTypes: [],
|
||||
areas: [],
|
||||
selectedAreas: []
|
||||
selectedAreas: [],
|
||||
sortKeyword: '',
|
||||
sortKeywords: ['上映', '评分', '默认']
|
||||
}
|
||||
},
|
||||
components: {
|
||||
@@ -161,17 +182,40 @@ export default {
|
||||
this.SET_SHARE(val)
|
||||
}
|
||||
},
|
||||
filteredRecommandations () {
|
||||
var filteredData = this.recommandations.filter(x => (this.selectedAreas.length === 0) || this.selectedAreas.includes(x.detail.area))
|
||||
filteredRecommendations () {
|
||||
var filteredData = this.recommendations.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()
|
||||
if (this.view === 'Recommendation') {
|
||||
this.getRecommendations()
|
||||
if (this.$refs.recommendataionsWaterfall) {
|
||||
this.$refs.recommendataionsWaterfall.refresh()
|
||||
}
|
||||
}
|
||||
},
|
||||
sortKeyword () {
|
||||
switch (this.sortKeyword) {
|
||||
case '上映':
|
||||
this.recommendations = this.recommendations.sort(function (a, b) {
|
||||
return b.detail.year - a.detail.year
|
||||
})
|
||||
break
|
||||
case '评分':
|
||||
this.recommendations.sort(function (a, b) {
|
||||
return b.rate - a.rate
|
||||
})
|
||||
break
|
||||
case '默认':
|
||||
this.recommendations.sort(function (a, b) {
|
||||
return b.id - a.id
|
||||
})
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -188,41 +232,43 @@ export default {
|
||||
}
|
||||
},
|
||||
updateEvent () {
|
||||
const url = 'https://raw.githubusercontent.com/Hunlongyu/ZY-Player/master/src/lib/dexie/iniData/Recommandations.json'
|
||||
const url = 'https://raw.githubusercontent.com/Hunlongyu/ZY-Player/master/src/lib/dexie/iniData/Recommendations.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) {
|
||||
this.recommendations = res.data.sort(function (a, b) {
|
||||
return b.detail.year - a.detail.year
|
||||
})
|
||||
recommandation.clear().then(recommandation.bulkAdd(this.recommandations))
|
||||
recommendation.clear().then(recommendation.bulkAdd(this.recommendations))
|
||||
this.getFilterData()
|
||||
this.$message.success('更新推荐成功')
|
||||
}
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(error => {
|
||||
this.loading = false
|
||||
this.$message.error('更新推荐失败. ' + error)
|
||||
})
|
||||
},
|
||||
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 } }
|
||||
this.video = { key: e.key, info: { id: db.ids, name: db.name, index: db.index }, detail: db.detail }
|
||||
} else {
|
||||
this.video = { key: e.key, info: { id: e.ids, name: e.name, index: 0 } }
|
||||
this.video = { key: e.key, info: { id: e.ids, name: e.name, index: 0 }, detail: e.detail }
|
||||
}
|
||||
this.view = 'Play'
|
||||
},
|
||||
deleteEvent (e) {
|
||||
recommandation.remove(e.id).then(res => {
|
||||
recommendation.remove(e.id).then(res => {
|
||||
if (res) {
|
||||
this.$message.warning('删除失败')
|
||||
} else {
|
||||
this.$message.success('删除成功')
|
||||
}
|
||||
this.getRecommandations()
|
||||
this.getRecommendations()
|
||||
})
|
||||
},
|
||||
shareEvent (e) {
|
||||
@@ -274,34 +320,44 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
getRecommandations () {
|
||||
recommandation.all().then(res => {
|
||||
this.recommandations = res
|
||||
this.recommandations.sort(function (a, b) {
|
||||
return b.detail.year - a.detail.year
|
||||
getRecommendations () {
|
||||
recommendation.all().then(res => {
|
||||
this.recommendations = res.sort(function (a, b) {
|
||||
return b.id - a.id
|
||||
})
|
||||
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)
|
||||
this.types = [...new Set(this.recommendations.map(ele => ele.detail.type))].filter(x => x)
|
||||
this.areas = [...new Set(this.recommendations.map(ele => ele.detail.area))].filter(x => x)
|
||||
},
|
||||
getViewMode () {
|
||||
setting.find().then(res => {
|
||||
this.viewMode = res.recommandationViewMode
|
||||
this.viewMode = res.recommendationViewMode
|
||||
})
|
||||
},
|
||||
updateViewMode () {
|
||||
setting.find().then(res => {
|
||||
res.recommandationViewMode = this.viewMode
|
||||
res.recommendationViewMode = this.viewMode
|
||||
setting.update(res)
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.getRecommandations()
|
||||
this.getRecommendations()
|
||||
this.getViewMode()
|
||||
},
|
||||
mounted () {
|
||||
window.addEventListener('resize', () => {
|
||||
if (this.$refs.recommendataionsWaterfall && this.view === 'Recommendation') {
|
||||
this.$refs.recommendataionsWaterfall.resize()
|
||||
this.$refs.recommendataionsWaterfall.refresh()
|
||||
setTimeout(() => {
|
||||
this.$refs.recommendataionsWaterfall.refresh()
|
||||
}, 500)
|
||||
}
|
||||
}, false)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -56,12 +56,6 @@
|
||||
左/右方向键:<input style="width:50px" type="number" v-model = "d.forwardTimeInSec" @change="updateSettingEvent">秒
|
||||
</div>
|
||||
</div>
|
||||
<div class='search'>
|
||||
<div class="title">搜索</div>
|
||||
<div class="zy-input" @click="toggleSearchAllSites">
|
||||
<input type="checkbox" v-model = "d.searchAllSites" @change="updateSettingEvent"> 搜索所有资源
|
||||
</div>
|
||||
</div>
|
||||
<div class='site'>
|
||||
<div class="title">第三方播放</div>
|
||||
<div class="site-box">
|
||||
@@ -87,9 +81,21 @@
|
||||
<div class="zy-input" @click="toggleExcludeRootClasses">
|
||||
<input type="checkbox" v-model = "d.excludeRootClasses" @change="updateSettingEvent"> 屏蔽主分类
|
||||
</div>
|
||||
<div class="zy-input" @click="toggleExcludeR18Films">
|
||||
<input type="checkbox" v-model = "d.excludeR18Films" @change="updateSettingEvent"> 屏蔽福利片
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="site">
|
||||
<div class="title">网络</div>
|
||||
<div class="site-box">
|
||||
<div class="zy-select" @mouseleave="show.proxy = false">
|
||||
<div class="vs-placeholder" @click="show.proxy = true">代理设置</div>
|
||||
<div class="vs-options" v-if="show.proxy">
|
||||
<ul class="zy-scroll">
|
||||
<li :class="d.proxy.type === 'none' ? 'active' : ''" @click="changeProxyType('none')">不使用代理</li>
|
||||
<!-- <li :class="d.proxy.type === 'system' ? 'active' : ''" @click="changeProxyType('system')">使用系统代理</li> -->
|
||||
<li :class="d.proxy.type === 'manual' ? 'active' : ''" @click="changeProxyType('manual')">手动指定代理</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="theme">
|
||||
@@ -163,6 +169,33 @@
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
<div> <!-- 代理设置界面 -->
|
||||
<el-dialog :visible.sync="show.proxyDialog" :append-to-body="true" @close="closeDialog" width="400px">
|
||||
<el-form label-width="50px" label-position="left" size="small">
|
||||
<el-form-item label="协议: " prop='scheme'>
|
||||
<el-col :span="15">
|
||||
<el-select v-model="proxy.scheme" placeholder="请选择协议类型">
|
||||
<el-option label="http" value="http"></el-option>
|
||||
<el-option label="socks5" value="socks5"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="地址: " prop='url'>
|
||||
<el-col :span="15">
|
||||
<el-input v-model="proxy.url" placeholder="地址" />
|
||||
</el-col>
|
||||
<el-col class="line" :span="2" style="text-align: center;">:</el-col>
|
||||
<el-col :span="7">
|
||||
<el-input v-model="proxy.port" placeholder="端口" width="80px" />
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="closeDialog">取消</el-button>
|
||||
<el-button type="primary" @click="proxyConfirm">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
@@ -172,12 +205,12 @@ 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'
|
||||
import zy from '../lib/site/tools'
|
||||
export default {
|
||||
name: 'setting',
|
||||
data () {
|
||||
return {
|
||||
pkg: pkg,
|
||||
sitesList: [],
|
||||
shortcutList: [],
|
||||
show: {
|
||||
site: false,
|
||||
@@ -185,12 +218,20 @@ export default {
|
||||
view: false,
|
||||
editPlayerPath: false,
|
||||
checkPasswordDialog: false,
|
||||
changePasswordDialog: false
|
||||
changePasswordDialog: false,
|
||||
proxy: false,
|
||||
proxyDialog: false
|
||||
},
|
||||
d: { },
|
||||
latestVersion: pkg.version,
|
||||
inputPassword: '',
|
||||
action: ''
|
||||
action: '',
|
||||
proxy: {
|
||||
type: '',
|
||||
scheme: '',
|
||||
url: '',
|
||||
port: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -209,18 +250,10 @@ export default {
|
||||
set (val) {
|
||||
this.SET_SETTING(val)
|
||||
}
|
||||
},
|
||||
editSites: {
|
||||
get () {
|
||||
return this.$store.getters.getEditSites
|
||||
},
|
||||
set (val) {
|
||||
this.SET_EDITSITES(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_SETTING', 'SET_VIEW', 'SET_EDITSITES']),
|
||||
...mapMutations(['SET_SETTING', 'SET_VIEW']),
|
||||
linkOpen (e) {
|
||||
shell.openExternal(e)
|
||||
},
|
||||
@@ -235,11 +268,6 @@ export default {
|
||||
if (res.length <= 0) {
|
||||
this.$message.warning('检测到视频源未能正常加载, 即将重置源.')
|
||||
sites.clear().then(sites.bulkAdd(defaultSites).then(this.getSites()))
|
||||
} else {
|
||||
this.sitesList = res
|
||||
this.editSites = {
|
||||
sites: res
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -266,10 +294,6 @@ export default {
|
||||
this.setting = this.d
|
||||
setting.update(this.d)
|
||||
},
|
||||
toggleSearchAllSites () {
|
||||
this.d.searchAllSites = !this.d.searchAllSites
|
||||
this.updateSettingEvent()
|
||||
},
|
||||
toggleExcludeR18Films () {
|
||||
this.d.excludeR18Films = !this.d.excludeR18Films
|
||||
this.updateSettingEvent()
|
||||
@@ -317,9 +341,16 @@ export default {
|
||||
this.view = 'EditSites'
|
||||
}
|
||||
},
|
||||
closeDialog () {
|
||||
async closeDialog () {
|
||||
this.show.checkPasswordDialog = false
|
||||
this.show.changePasswordDialog = false
|
||||
if (this.show.proxyDialog) {
|
||||
this.show.proxyDialog = false
|
||||
this.setting.proxy.type = 'none'
|
||||
await this.updateSettingEvent()
|
||||
this.$message.info('取消使用代理')
|
||||
zy.proxy()
|
||||
}
|
||||
this.inputPassword = ''
|
||||
},
|
||||
checkPasswordEvent () {
|
||||
@@ -375,6 +406,27 @@ export default {
|
||||
})
|
||||
})
|
||||
},
|
||||
async changeProxyType (e) {
|
||||
this.d.proxy.type = e
|
||||
if (e === 'manual') {
|
||||
this.show.proxyDialog = true
|
||||
this.proxy.scheme = this.setting.proxy.scheme
|
||||
this.proxy.url = this.setting.proxy.url
|
||||
this.proxy.port = this.setting.proxy.port
|
||||
}
|
||||
await this.updateSettingEvent()
|
||||
this.show.proxy = false
|
||||
zy.proxy()
|
||||
},
|
||||
async proxyConfirm () {
|
||||
this.d.proxy.scheme = this.proxy.scheme
|
||||
this.d.proxy.url = this.proxy.url
|
||||
this.d.proxy.port = this.proxy.port
|
||||
await this.updateSettingEvent()
|
||||
this.show.proxyDialog = false
|
||||
zy.proxy()
|
||||
this.$message.info('开始使用代理')
|
||||
},
|
||||
clearDBEvent () {
|
||||
if (this.d.password) {
|
||||
this.action = 'CleanDB'
|
||||
@@ -481,11 +533,6 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
.search{
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.site{
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="share" id="share" @click="shareClickEvent">
|
||||
<div class="share" id="share" @click="shareClickEvent" v-on-clickaway="shareClickEvent">
|
||||
<div class="left">
|
||||
<img :src="pic" alt="" @load="picLoadEvent">
|
||||
</div>
|
||||
@@ -22,6 +22,7 @@ import { mapMutations } from 'vuex'
|
||||
import QrcodeVue from 'qrcode.vue'
|
||||
import html2canvas from 'html2canvas'
|
||||
import zy from '../lib/site/tools'
|
||||
import { directive as onClickaway } from 'vue-clickaway'
|
||||
const { clipboard, nativeImage } = require('electron')
|
||||
export default {
|
||||
name: 'share',
|
||||
@@ -56,6 +57,9 @@ export default {
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
directives: {
|
||||
onClickaway: onClickaway
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_SHARE']),
|
||||
shareClickEvent () {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
@sort-change="handleSortChange">
|
||||
<el-table-column
|
||||
sortable
|
||||
:sort-method="sortByName"
|
||||
:sort-method="(a , b) => sortByLocaleCompare(a.name, b.name)"
|
||||
prop="name"
|
||||
label="片名">
|
||||
</el-table-column>
|
||||
@@ -30,9 +30,8 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:sort-by="['detail.type', 'name']"
|
||||
sortable
|
||||
:sort-method="sortByType"
|
||||
:sort-method="(a , b) => sortByLocaleCompare(a.detail.type, b.detail.type)"
|
||||
prop="detail.type"
|
||||
label="类型"
|
||||
width="100">
|
||||
@@ -42,17 +41,19 @@
|
||||
:sort-by="['detail.year', 'name']"
|
||||
prop="detail.year"
|
||||
label="上映"
|
||||
width="100"
|
||||
align="center">
|
||||
width="100">
|
||||
</el-table-column>
|
||||
<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)"
|
||||
<el-table-column v-if="list.some(e => e.rate && e.rate !== '暂无评分')"
|
||||
sortable
|
||||
sort-by="rate"
|
||||
prop="rate"
|
||||
width="120"
|
||||
align="center"
|
||||
label="豆瓣评分">
|
||||
</el-table-column>
|
||||
<el-table-column v-if="list.some(e => e.index >= 0)"
|
||||
@@ -65,8 +66,9 @@
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
header-align="right"
|
||||
align="right">
|
||||
header-align="center"
|
||||
align="right"
|
||||
width="200">
|
||||
<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>
|
||||
@@ -78,8 +80,18 @@
|
||||
</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"
|
||||
:breakpoints="{
|
||||
1200: { //当屏幕宽度小于等于1200
|
||||
rowPerView: 4,
|
||||
},
|
||||
800: { //当屏幕宽度小于等于800
|
||||
rowPerView: 3,
|
||||
},
|
||||
500: { //当屏幕宽度小于等于500
|
||||
rowPerView: 2,
|
||||
}
|
||||
}"
|
||||
animationEffect="fadeIn"
|
||||
backgroundColor="rgba(0, 0, 0, 0)">
|
||||
<template slot="item" slot-scope="props">
|
||||
<div class="card">
|
||||
@@ -90,6 +102,11 @@
|
||||
<div class="update" v-if="props.data.hasUpdate">
|
||||
<span>有更新</span>
|
||||
</div>
|
||||
<div class="progress" v-if="props.data.index && props.data.detail && props.data.detail.m3u8List !== undefined && props.data.detail.m3u8List.length > 1">
|
||||
<span>
|
||||
看至第{{ props.data.index + 1 }}集
|
||||
</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">
|
||||
@@ -102,6 +119,7 @@
|
||||
</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>
|
||||
@@ -128,7 +146,8 @@ export default {
|
||||
return {
|
||||
list: [],
|
||||
sites: [],
|
||||
viewMode: 'picture'
|
||||
viewMode: 'picture',
|
||||
numNoUpdate: 0
|
||||
}
|
||||
},
|
||||
components: {
|
||||
@@ -173,7 +192,16 @@ export default {
|
||||
if (this.view === 'Star') {
|
||||
this.getAllsites()
|
||||
this.getFavorites()
|
||||
this.$refs.starWaterfall.refresh()
|
||||
if (this.$refs.starWaterfall) {
|
||||
this.$refs.starWaterfall.refresh()
|
||||
}
|
||||
}
|
||||
},
|
||||
numNoUpdate () {
|
||||
// 如果所有收藏都没有更新的话
|
||||
if (this.numNoUpdate === this.list.length) {
|
||||
this.numNoUpdate = 0
|
||||
this.$message.warning('未查询到任何更新')
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -182,11 +210,8 @@ export default {
|
||||
handleSortChange (column, prop, order) {
|
||||
this.updateDatabase()
|
||||
},
|
||||
sortByName (a, b) {
|
||||
return a.name.localeCompare(b.name, 'zh')
|
||||
},
|
||||
sortByType (a, b) {
|
||||
return a.type.localeCompare(b.type)
|
||||
sortByLocaleCompare (a, b) {
|
||||
return a.localeCompare(b, 'zh')
|
||||
},
|
||||
detailEvent (e) {
|
||||
this.detail = {
|
||||
@@ -203,9 +228,9 @@ export default {
|
||||
},
|
||||
async playEvent (e) {
|
||||
if (e.index) {
|
||||
this.video = { key: e.key, info: { id: e.ids, name: e.name, index: e.index } }
|
||||
this.video = { key: e.key, info: { id: e.ids, name: e.name, index: e.index }, detail: e.detail }
|
||||
} else {
|
||||
this.video = { key: e.key, info: { id: e.ids, name: e.name, index: 0 } }
|
||||
this.video = { key: e.key, info: { id: e.ids, name: e.name, index: 0 }, detail: e.detail }
|
||||
}
|
||||
if (e.hasUpdate) {
|
||||
this.clearHasUpdateFlag(e)
|
||||
@@ -254,11 +279,12 @@ export default {
|
||||
index: e.index
|
||||
}
|
||||
star.get(e.id).then(resStar => {
|
||||
var msg = ''
|
||||
if (e.detail.last !== detailRes.last) {
|
||||
if (!e.hasUpdate && e.detail.last !== detailRes.last) {
|
||||
doc.hasUpdate = true
|
||||
msg = `同步"${e.name}"成功, 检查到更新。`
|
||||
var msg = `同步"${e.name}"成功, 检查到更新。`
|
||||
this.$message.success(msg)
|
||||
} else {
|
||||
this.numNoUpdate += 1
|
||||
}
|
||||
star.update(e.id, doc)
|
||||
this.getFavorites()
|
||||
@@ -269,6 +295,7 @@ export default {
|
||||
})
|
||||
},
|
||||
updateAllEvent () {
|
||||
this.numNoUpdate = 0
|
||||
this.list.forEach(e => {
|
||||
this.updateEvent(e)
|
||||
})
|
||||
@@ -334,7 +361,9 @@ export default {
|
||||
},
|
||||
getFavorites () {
|
||||
star.all().then(res => {
|
||||
this.list = res.reverse()
|
||||
this.list = res.sort(function (a, b) {
|
||||
return b.id - a.id
|
||||
})
|
||||
})
|
||||
},
|
||||
getAllsites () {
|
||||
@@ -355,7 +384,7 @@ export default {
|
||||
remote.dialog.showSaveDialog(options).then(result => {
|
||||
if (!result.canceled) {
|
||||
fs.writeFileSync(result.filePath, str)
|
||||
this.$message.success('已保存成功')
|
||||
this.$message.success('导出收藏成功')
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err)
|
||||
@@ -372,14 +401,16 @@ export default {
|
||||
}
|
||||
remote.dialog.showOpenDialog(options).then(result => {
|
||||
if (!result.canceled) {
|
||||
var starList = this.list
|
||||
var starList = Array.from(this.list)
|
||||
var id = this.list.length + 1
|
||||
result.filePaths.forEach(file => {
|
||||
var str = fs.readFileSync(file)
|
||||
const json = JSON.parse(str)
|
||||
json.forEach(ele => {
|
||||
const starExists = starList.includes(x => x.key === ele.key && x.ids === ele.ids)
|
||||
json.reverse().forEach(ele => {
|
||||
const starExists = starList.some(x => x.key === ele.key && x.ids === ele.ids)
|
||||
if (!starExists) {
|
||||
var doc = {
|
||||
id: id,
|
||||
key: ele.key,
|
||||
ids: ele.ids,
|
||||
site: ele.site === undefined ? ele.site = this.sites.find(x => x.key === ele.key) : ele.site,
|
||||
@@ -398,6 +429,7 @@ export default {
|
||||
note: ele.note
|
||||
} : ele.detail
|
||||
}
|
||||
id += 1
|
||||
starList.push(doc)
|
||||
}
|
||||
})
|
||||
@@ -455,12 +487,21 @@ export default {
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.rowDrop()
|
||||
},
|
||||
created () {
|
||||
this.getFavorites()
|
||||
this.getViewMode()
|
||||
},
|
||||
mounted () {
|
||||
this.rowDrop()
|
||||
window.addEventListener('resize', () => {
|
||||
if (this.$refs.starWaterfall && this.view === 'Star') {
|
||||
this.$refs.starWaterfall.resize()
|
||||
this.$refs.starWaterfall.refresh()
|
||||
setTimeout(() => {
|
||||
this.$refs.starWaterfall.refresh()
|
||||
}, 500)
|
||||
}
|
||||
}, false)
|
||||
}
|
||||
}
|
||||
</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'
|
||||
import Recommendation from './Recommendation'
|
||||
export default {
|
||||
registerComponents () {
|
||||
Vue.component('Aside', Aside)
|
||||
@@ -24,6 +24,6 @@ export default {
|
||||
Vue.component('History', History)
|
||||
Vue.component('EditSites', EditSites)
|
||||
Vue.component('IPTV', IPTV)
|
||||
Vue.component('Recommandation', Recommandation)
|
||||
Vue.component('Recommendation', Recommendation)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import Dexie from 'dexie'
|
||||
import { setting, sites, localKey, iptv, recommandations } from './initData'
|
||||
import { setting, sites, localKey, iptv, recommendations } 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, starViewMode, recommandationViewMode, password',
|
||||
setting: 'id, theme, site, shortcut, view, externalPlayer, searchGroup, excludeRootClasses, excludeR18Films, forwardTimeInSec, starViewMode, recommandationViewMode, password, proxy',
|
||||
shortcut: 'name, key, desc',
|
||||
star: '++id, [key+ids], site, name, detail, index, rate, hasUpdate',
|
||||
recommandation: '++id, [key+ids], site, name, detail, index, rate, hasUpdate',
|
||||
recommendation: '++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',
|
||||
iptv: '++id, name, url, group'
|
||||
history: '++id, [site+ids], name, type, year, index, time, duration, detail',
|
||||
mini: 'id, mode, site, ids, name, index, time, url',
|
||||
iptv: '++id, name, url, group, isActive'
|
||||
})
|
||||
|
||||
db.on('populate', () => {
|
||||
@@ -21,7 +21,7 @@ db.on('populate', () => {
|
||||
db.sites.bulkAdd(sites)
|
||||
db.shortcut.bulkAdd(localKey)
|
||||
db.iptv.bulkAdd(iptv)
|
||||
db.recommandation.bulkAdd(recommandations)
|
||||
db.recommendation.bulkAdd(recommendations)
|
||||
})
|
||||
|
||||
db.open()
|
||||
|
||||
@@ -7,7 +7,7 @@ import sites from './sites'
|
||||
import search from './search'
|
||||
import iptvSearch from './iptvSearch'
|
||||
import iptv from './iptv'
|
||||
import recommandation from './recommandation'
|
||||
import recommendation from './recommendation'
|
||||
|
||||
export {
|
||||
history,
|
||||
@@ -19,5 +19,5 @@ export {
|
||||
iptv,
|
||||
search,
|
||||
iptvSearch,
|
||||
recommandation
|
||||
recommendation
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
272
src/lib/dexie/iniData/Sites.json
Normal file
272
src/lib/dexie/iniData/Sites.json
Normal file
@@ -0,0 +1,272 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"key": "mahuazy",
|
||||
"name": "麻花资源",
|
||||
"api": "https://www.mhapi123.com/inc/api.php",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"key": "niuniucj",
|
||||
"name": "牛牛资源",
|
||||
"api": "http://v.niuniucj.com/inc/api.php",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"key": "88zyw",
|
||||
"name": "88 影视资源站",
|
||||
"api": "http://www.88zyw.net/inc/api.php",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"key": "apibdzy",
|
||||
"name": "百度云资源",
|
||||
"api": "https://api.apibdzy.com/api.php/provide/vod/at/xml",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"key": "mbo",
|
||||
"name": "秒播资源",
|
||||
"api": "http://caiji.mb77.vip/inc/api.php",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"key": "zuidazy",
|
||||
"name": "最大资源网",
|
||||
"api": "http://www.zdziyuan.com/inc/api.php",
|
||||
"download": "http://www.zdziyuan.com/inc/apidown.php",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"key": "123ku",
|
||||
"name": "123 资源",
|
||||
"api": "http://cj.123ku2.com:12315/inc/api.php",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"key": "okzy",
|
||||
"name": "OK 资源网",
|
||||
"api": "http://cj.okzy.tv/inc/api.php",
|
||||
"download": "http://cj.okzy.tv/inc/apidown.php",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"key": "kuyunzy",
|
||||
"name": "酷云资源",
|
||||
"api": "http://caiji.kuyun98.com/inc/ldg_api.php",
|
||||
"download": "http://caiji.kuyun98.com/inc/apidown.php",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"key": "kubozy",
|
||||
"name": "酷播资源",
|
||||
"api": "http://api.kbzyapi.com/inc/api.php",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"key": "yongjiuzy",
|
||||
"name": "永久资源",
|
||||
"api": "http://cj.yongjiuzyw.com/inc/api.php",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"key": "rrzy",
|
||||
"name": "人人资源",
|
||||
"api": "https://www.rrzyw.cc/api.php/provide/vod/from/rrm3u8/at/xml/",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"key": "bbkdj",
|
||||
"name": "步步高顶尖资源网",
|
||||
"api": "http://api.bbkdj.com/api",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"key": "solezy",
|
||||
"name": "搜乐资源网",
|
||||
"api": "https://www.caijizy.vip/api.php/provide/vod/at/xml/",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"key": "zuixinzy",
|
||||
"name": "最新资源",
|
||||
"api": "http://api.zuixinapi.com/inc/api.php",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"key": "605zy",
|
||||
"name": "605资源",
|
||||
"api": "http://www.605zy.net/inc/seacmsapi.php",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"key": "subo988",
|
||||
"name": "速播资源站",
|
||||
"api": "https://www.subo988.com/inc/api.php",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"key": "1886zy",
|
||||
"name": "1886 资源",
|
||||
"api": "http://cj.1886zy.co/inc/api.php",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"key": "doubanzy",
|
||||
"name": "豆瓣电影资源",
|
||||
"api": "http://v.1988cj.com/inc/api.php",
|
||||
"download": "http://v.1988cj.com/inc/apidown.php",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"key": "135zy",
|
||||
"name": "135 资源网",
|
||||
"api": "http://cj.zycjw1.com/inc/api.php",
|
||||
"download": "http://cj.zycjw1.com/inc/apidown.php",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"key": "mgtvzy",
|
||||
"name": "芒果 TV 资源网",
|
||||
"api": "https://api.shijiapi.com/api.php/provide/vod/at/xml/",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"key": "209zy",
|
||||
"name": "209 资源",
|
||||
"api": "http://cj.1156zy.com/inc/api.php",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"key": "kkzy",
|
||||
"name": "快快资源",
|
||||
"api": "https://api.kkzy.tv/inc/api.php",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"key": "wolongzy",
|
||||
"name": "卧龙资源",
|
||||
"api": "http://cj.wlzy.tv/inc/api_mac.php",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"key": "mokazy",
|
||||
"name": "魔卡资源网",
|
||||
"api": "https://cj.heiyap.com/api.php/provide/vod/at/xml/",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 26,
|
||||
"key": "158zy",
|
||||
"name": "壹伍捌资源网",
|
||||
"api": "http://cj.158zyz.net:158/inc/api.php",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
},
|
||||
{
|
||||
"id": 27,
|
||||
"key": "kyzy",
|
||||
"name": "快影资源站",
|
||||
"api": "https://www.kyzy.tv/api.php/kyyun/vod/at/xml/",
|
||||
"download": "",
|
||||
"group": "默认",
|
||||
"isActive": true,
|
||||
"status": "可用"
|
||||
}
|
||||
]
|
||||
@@ -5,241 +5,20 @@ const setting = [
|
||||
shortcut: true,
|
||||
view: 'picture',
|
||||
externalPlayer: '',
|
||||
searchAllSites: true,
|
||||
searchGroup: '全站',
|
||||
excludeRootClasses: true,
|
||||
excludeR18Films: true,
|
||||
forwardTimeInSec: 5,
|
||||
starViewMode: 'picture',
|
||||
recommandationViewMode: 'picture',
|
||||
password: ''
|
||||
}
|
||||
]
|
||||
|
||||
const sites = [
|
||||
{
|
||||
id: 1,
|
||||
key: 'okzy',
|
||||
name: 'OK 资源网',
|
||||
api: 'http://cj.okzy.tv/inc/api.php',
|
||||
download: 'http://cj.okzy.tv/inc/apidown.php',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
key: 'zuidazy',
|
||||
name: '最大资源网',
|
||||
api: 'http://www.zdziyuan.com/inc/api.php',
|
||||
download: 'http://www.zdziyuan.com/inc/apidown.php',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
key: 'doubanzy',
|
||||
name: '豆瓣电影资源',
|
||||
api: 'http://v.1988cj.com/inc/api.php',
|
||||
download: 'http://v.1988cj.com/inc/apidown.php',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
key: '135zy',
|
||||
name: '135 资源网',
|
||||
api: 'http://cj.zycjw1.com/inc/api.php',
|
||||
download: 'http://cj.zycjw1.com/inc/apidown.php',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
key: 'kuyunzy',
|
||||
name: '酷云资源',
|
||||
api: 'http://caiji.kuyun98.com/inc/ldg_api.php',
|
||||
download: 'http://caiji.kuyun98.com/inc/apidown.php',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
key: 'mgtvzy',
|
||||
name: '芒果 TV 资源网',
|
||||
api: 'https://api.shijiapi.com/api.php/provide/vod/at/xml/',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
key: 'subo988',
|
||||
name: '速播资源站',
|
||||
api: 'https://www.subo988.com/inc/api.php',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
key: '209zy',
|
||||
name: '209 资源',
|
||||
api: 'http://cj.1156zy.com/inc/api.php',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
key: 'zuixinzy',
|
||||
name: '最新资源',
|
||||
api: 'http://api.zuixinapi.com/inc/api.php',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
key: 'kubozy',
|
||||
name: '酷播资源',
|
||||
api: 'http://api.kbzyapi.com/inc/api.php',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 11,
|
||||
key: 'yongjiuzy',
|
||||
name: '永久资源',
|
||||
api: 'http://cj.yongjiuzyw.com/inc/api.php',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
key: '123ku',
|
||||
name: '123 资源',
|
||||
api: 'http://cj.123ku2.com:12315/inc/api.php',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 13,
|
||||
key: '88zyw',
|
||||
name: '88 影视资源站',
|
||||
api: 'http://www.88zyw.net/inc/api.php',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 14,
|
||||
key: 'wolongzy',
|
||||
name: '卧龙资源',
|
||||
api: 'http://cj.wlzy.tv/inc/api_mac.php',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 15,
|
||||
key: 'mahuazy',
|
||||
name: '麻花资源',
|
||||
api: 'https://www.mhapi123.com/inc/api.php',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 16,
|
||||
key: 'kkzy',
|
||||
name: '快快资源',
|
||||
api: 'https://api.kkzy.tv/inc/api.php',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 17,
|
||||
key: '158zy',
|
||||
name: '壹伍捌资源网',
|
||||
api: 'http://cj.158zyz.net:158/inc/api.php',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 18,
|
||||
key: 'rrzy',
|
||||
name: '人人资源',
|
||||
api: 'https://www.rrzyw.cc/api.php/provide/vod/from/rrm3u8/at/xml/',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 19,
|
||||
key: 'mokazy',
|
||||
name: '魔卡资源网',
|
||||
api: 'https://cj.heiyap.com/api.php/provide/vod/at/xml/',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 20,
|
||||
key: 'kyzy',
|
||||
name: '快影资源站',
|
||||
api: 'https://www.kyzy.tv/api.php/kyyun/vod/at/xml/',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 21,
|
||||
key: 'solezy',
|
||||
name: '搜乐资源网',
|
||||
api: 'https://www.caijizy.vip/api.php/provide/vod/at/xml/',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 22,
|
||||
key: 'bbkdj',
|
||||
name: '步步高顶尖资源网',
|
||||
api: 'http://api.bbkdj.com/api',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 23,
|
||||
key: '1886zy',
|
||||
name: '1886 资源',
|
||||
api: 'http://cj.1886zy.co/inc/api.php',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 24,
|
||||
key: 'mbo',
|
||||
name: '秒播资源',
|
||||
api: 'http://caiji.mb77.vip/inc/api.php',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
},
|
||||
{
|
||||
id: 25,
|
||||
key: '605zy',
|
||||
name: '605资源',
|
||||
api: 'http://www.605zy.net/inc/seacmsapi.php',
|
||||
download: '',
|
||||
isActive: 1,
|
||||
group: '默认'
|
||||
recommendationViewMode: 'picture',
|
||||
historyViewMode: 'picture',
|
||||
password: '',
|
||||
proxy: {
|
||||
type: 'none',
|
||||
scheme: '',
|
||||
url: '',
|
||||
port: ''
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -344,13 +123,14 @@ const getSite = (key) => {
|
||||
}
|
||||
}
|
||||
|
||||
const sites = require('./iniData/Sites.json')
|
||||
const iptv = require('./iniData/Iptv.json')
|
||||
const recommandations = require('./iniData/Recommandations.json')
|
||||
const recommendations = require('./iniData/Recommendations.json')
|
||||
export {
|
||||
setting,
|
||||
sites,
|
||||
iptv,
|
||||
recommandations,
|
||||
recommendations,
|
||||
localKey,
|
||||
getSite
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
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()
|
||||
}
|
||||
}
|
||||
28
src/lib/dexie/recommendation.js
Normal file
28
src/lib/dexie/recommendation.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import db from './dexie'
|
||||
const { recommendation } = db
|
||||
export default {
|
||||
async add (doc) {
|
||||
return await recommendation.add(doc)
|
||||
},
|
||||
async bulkAdd (doc) {
|
||||
return await recommendation.bulkAdd(doc)
|
||||
},
|
||||
async find (doc) {
|
||||
return await recommendation.where(doc).first()
|
||||
},
|
||||
async update (id, docs) {
|
||||
return await recommendation.update(id, docs)
|
||||
},
|
||||
async all () {
|
||||
return await recommendation.toArray()
|
||||
},
|
||||
async remove (id) {
|
||||
return await recommendation.delete(id)
|
||||
},
|
||||
async get (id) {
|
||||
return await recommendation.get(id)
|
||||
},
|
||||
async clear () {
|
||||
return await recommendation.clear()
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
import Vue from 'vue'
|
||||
import { Message, Button, Table, TableColumn, Tag, Input, Dialog, Form, FormItem, Switch, Select, Option } from 'element-ui'
|
||||
import { Message, Button, Table, TableColumn, Tag, Input, Dialog, Form, FormItem, Switch, Select, Option, Checkbox, Autocomplete, Col } from 'element-ui'
|
||||
import Plugin from 'v-fit-columns'
|
||||
Vue.use(Button)
|
||||
Vue.use(Col)
|
||||
Vue.use(Table)
|
||||
Vue.use(TableColumn)
|
||||
Vue.use(Tag)
|
||||
@@ -13,4 +14,6 @@ Vue.use(Switch)
|
||||
Vue.use(Plugin)
|
||||
Vue.use(Select)
|
||||
Vue.use(Option)
|
||||
Vue.use(Checkbox)
|
||||
Vue.use(Autocomplete)
|
||||
Vue.prototype.$message = Message
|
||||
|
||||
@@ -1,7 +1,63 @@
|
||||
import { sites } from '../dexie'
|
||||
import { sites, setting } from '../dexie'
|
||||
import axios from 'axios'
|
||||
import parser from 'fast-xml-parser'
|
||||
import cheerio from 'cheerio'
|
||||
import { Parser as M3u8Parser } from 'm3u8-parser'
|
||||
|
||||
// axios使用系统代理 https://evandontje.com/2020/04/02/automatic-system-proxy-configuration-for-electron-applications/
|
||||
// xgplayer使用chromium代理设置,浏览器又默认使用系统代理 https://www.chromium.org/developers/design-documents/network-settings
|
||||
// 要在设置中添加代理设置,可参考https://stackoverflow.com/questions/37393248/how-connect-to-proxy-in-electron-webview
|
||||
var http = require('http')
|
||||
var https = require('http')
|
||||
const { remote } = require('electron')
|
||||
var win = remote.getCurrentWindow()
|
||||
var session = win.webContents.session
|
||||
var ElectronProxyAgent = require('electron-proxy-agent')
|
||||
|
||||
// 请求超时时限
|
||||
axios.defaults.timeout = 10000 // 可能使用代理,增长超时
|
||||
|
||||
// 重试次数,共请求3次
|
||||
axios.defaults.retry = 2
|
||||
|
||||
// 请求的间隙
|
||||
axios.defaults.retryDelay = 1000
|
||||
|
||||
// 添加响应拦截器
|
||||
axios.interceptors.response.use(function (response) {
|
||||
// 对响应数据做些事
|
||||
if (response.status && response.status === 200 && response.request.responseURL.includes('api.php') && !response.data.startsWith('<?xml')) {
|
||||
}
|
||||
return response
|
||||
}, function (err) { // 请求错误时做些事
|
||||
// 请求超时的之后,抛出 err.code = ECONNABORTED的错误..错误信息是 timeout of xxx ms exceeded
|
||||
if (err.code === 'ECONNABORTED' && err.message.indexOf('timeout') !== -1) {
|
||||
var config = err.config
|
||||
config.__retryCount = config.__retryCount || 0
|
||||
|
||||
if (config.__retryCount >= config.retry) {
|
||||
err.message = '多次请求均超时'
|
||||
return Promise.reject(err)
|
||||
}
|
||||
|
||||
config.__retryCount += 1
|
||||
|
||||
var backoff = new Promise(function (resolve) {
|
||||
setTimeout(function () {
|
||||
resolve()
|
||||
}, config.retryDelay || 1)
|
||||
})
|
||||
|
||||
return backoff.then(function () {
|
||||
return axios(config)
|
||||
})
|
||||
} else {
|
||||
if (err && !err.response) {
|
||||
err.message = '连接服务器失败!'
|
||||
}
|
||||
return Promise.reject(err)
|
||||
}
|
||||
})
|
||||
|
||||
const zy = {
|
||||
xmlConfig: { // XML 转 JSON 配置
|
||||
@@ -161,6 +217,20 @@ const zy = {
|
||||
const data = res.data
|
||||
const json = parser.parse(data, this.xmlConfig)
|
||||
const videoList = json.rss.list.video
|
||||
// Parse m3u8List
|
||||
var m3u8List = []
|
||||
const dd = videoList.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('#')
|
||||
}
|
||||
videoList.m3u8List = m3u8List
|
||||
resolve(videoList)
|
||||
}).catch(err => {
|
||||
reject(err)
|
||||
@@ -180,8 +250,8 @@ const zy = {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.getSite(key).then(res => {
|
||||
const site = res
|
||||
const url = `${site.download}?ac=videolist&ids=${id}&ct=1`
|
||||
if (url) {
|
||||
if (site.download) {
|
||||
const url = `${site.download}?ac=videolist&ids=${id}&ct=1`
|
||||
axios.post(url).then(res => {
|
||||
const data = res.data
|
||||
const json = parser.parse(data, this.xmlConfig)
|
||||
@@ -214,11 +284,34 @@ const zy = {
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 获取豆瓣评分
|
||||
* @param {*} name 视频名称
|
||||
* @returns 豆瓣评分
|
||||
* 检查直播源
|
||||
* @param {*} channel 直播频道 url
|
||||
* @returns boolean
|
||||
*/
|
||||
doubanRate (name) {
|
||||
async checkChannel (channel) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios.get(channel).then(res => {
|
||||
const manifest = res.data
|
||||
var parser = new M3u8Parser()
|
||||
parser.push(manifest)
|
||||
parser.end()
|
||||
var parsedManifest = parser.manifest
|
||||
if (parsedManifest.segments.length) {
|
||||
resolve(true)
|
||||
} else {
|
||||
resolve(false)
|
||||
}
|
||||
}).catch(e => {
|
||||
resolve(false)
|
||||
})
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 获取豆瓣页面链接
|
||||
* @param {*} name 视频名称
|
||||
* @returns 豆瓣页面链接,如果没有搜到该视频,返回搜索页面链接
|
||||
*/
|
||||
doubanLink (name) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 豆瓣搜索链接
|
||||
var nameToSearch = name.replace(/\s/g, '')
|
||||
@@ -229,36 +322,77 @@ const zy = {
|
||||
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)) {
|
||||
if (nameToSearch === nameInDouban) {
|
||||
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)) {
|
||||
if (nameToSearch === nameInDouban) {
|
||||
link = linkInDouban.attr('href')
|
||||
}
|
||||
}
|
||||
// 如果找到链接,就打开该链接获取评分
|
||||
if (link) {
|
||||
resolve(link)
|
||||
} else {
|
||||
// 如果没找到符合的链接,返回搜索页面
|
||||
resolve(doubanSearchLink)
|
||||
}
|
||||
}).catch(err => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 获取豆瓣评分
|
||||
* @param {*} name 视频名称
|
||||
* @returns 豆瓣评分
|
||||
*/
|
||||
doubanRate (name) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var nameToSearch = name.replace(/\s/g, '')
|
||||
this.doubanLink(nameToSearch).then(link => {
|
||||
if (link.includes('https://www.douban.com/search')) {
|
||||
resolve('暂无评分')
|
||||
} else {
|
||||
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())
|
||||
resolve(rating.text().replace(/\s/g, ''))
|
||||
} else {
|
||||
resolve('暂无评分')
|
||||
}
|
||||
}).catch(err => {
|
||||
reject(err)
|
||||
})
|
||||
} else {
|
||||
resolve('暂无评分')
|
||||
}
|
||||
}).catch(err => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
async proxy () {
|
||||
return new Promise((resolve, reject) => {
|
||||
setting.find().then(db => {
|
||||
if (db.proxy) {
|
||||
if (db.proxy.type === 'none') {
|
||||
session.setProxy({ proxyRules: 'direct://' })
|
||||
http.globalAgent = https.globalAgent = new ElectronProxyAgent(session)
|
||||
} else if (db.proxy.type === 'manual') {
|
||||
if (db.proxy.scheme && db.proxy.url && db.proxy.port) {
|
||||
const proxyURL = db.proxy.scheme + '://' + db.proxy.url.trim() + ':' + db.proxy.port.trim()
|
||||
session.setProxy({ proxyRules: proxyURL })
|
||||
http.globalAgent = https.globalAgent = new ElectronProxyAgent(session)
|
||||
}
|
||||
}
|
||||
}
|
||||
// 不要删了,留着测试用
|
||||
// axios.get('https://api.my-ip.io/ip').then(res => console.log(res))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
zy.proxy()
|
||||
|
||||
export default zy
|
||||
|
||||
@@ -107,6 +107,11 @@ export default {
|
||||
},
|
||||
getUrls () {
|
||||
mini.find().then(res => {
|
||||
if (res.mode === 'iptv') {
|
||||
this.xg.src = res.url
|
||||
this.xg.play()
|
||||
return
|
||||
}
|
||||
this.video = res
|
||||
this.fetchM3u8List(res).then(m3u8Arr => {
|
||||
this.m3u8Arr = m3u8Arr
|
||||
@@ -198,6 +203,9 @@ export default {
|
||||
const currentTime = this.xg.currentTime
|
||||
const progress = (currentTime / endTime) * 100
|
||||
this.progress = progress.toFixed(2)
|
||||
const percent = parseFloat((currentTime / endTime).toFixed(2))
|
||||
const win = remote.getCurrentWindow()
|
||||
win.setProgressBar(percent)
|
||||
const db = await history.find({ site: this.video.site, ids: this.video.ids })
|
||||
if (db) {
|
||||
const v = db
|
||||
|
||||
375
yarn.lock
375
yarn.lock
@@ -803,6 +803,13 @@
|
||||
core-js-pure "^3.0.0"
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.5.5":
|
||||
version "7.12.5"
|
||||
resolved "https://registry.npm.taobao.org/@babel/runtime/download/@babel/runtime-7.12.5.tgz?cache=0&sync_timestamp=1604441208794&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fruntime%2Fdownload%2F%40babel%2Fruntime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e"
|
||||
integrity sha1-QQ5+SHRB4bNgwpvnFdhw2bmFiC4=
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.8.4", "@babel/runtime@^7.9.6":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz#a6724f1a6b8d2f6ea5236dbfe58c7d7ea9c5eb99"
|
||||
@@ -963,6 +970,11 @@
|
||||
dependencies:
|
||||
defer-to-connect "^1.0.1"
|
||||
|
||||
"@tootallnate/once@1":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.npm.taobao.org/@tootallnate/once/download/@tootallnate/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
|
||||
integrity sha1-zLkURTYBeaBOf+av94wA/8Hur4I=
|
||||
|
||||
"@types/color-name@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
|
||||
@@ -1040,6 +1052,15 @@
|
||||
dependencies:
|
||||
"@types/yargs-parser" "*"
|
||||
|
||||
"@videojs/vhs-utils@^2.2.1":
|
||||
version "2.2.1"
|
||||
resolved "https://registry.npm.taobao.org/@videojs/vhs-utils/download/@videojs/vhs-utils-2.2.1.tgz#78ecea26652268646d5003b1b1a705c9b544f8a2"
|
||||
integrity sha1-eOzqJmUiaGRtUAOxsacFybVE+KI=
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.5.5"
|
||||
global "^4.3.2"
|
||||
url-toolkit "^2.1.6"
|
||||
|
||||
"@vue/babel-helper-vue-jsx-merge-props@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0.tgz#048fe579958da408fb7a8b2a3ec050b50a661040"
|
||||
@@ -1466,6 +1487,21 @@ address@^1.1.2:
|
||||
resolved "https://registry.npmjs.org/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6"
|
||||
integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==
|
||||
|
||||
agent-base@2:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.npm.taobao.org/agent-base/download/agent-base-2.1.1.tgz?cache=0&sync_timestamp=1603480011934&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fagent-base%2Fdownload%2Fagent-base-2.1.1.tgz#d6de10d5af6132d5bd692427d46fc538539094c7"
|
||||
integrity sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=
|
||||
dependencies:
|
||||
extend "~3.0.0"
|
||||
semver "~5.0.1"
|
||||
|
||||
agent-base@6:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.npm.taobao.org/agent-base/download/agent-base-6.0.2.tgz?cache=0&sync_timestamp=1603480011934&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fagent-base%2Fdownload%2Fagent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
|
||||
integrity sha1-Sf/1hXfP7j83F2/qtMIuAPhtf3c=
|
||||
dependencies:
|
||||
debug "4"
|
||||
|
||||
aggregate-error@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0"
|
||||
@@ -1814,10 +1850,10 @@ aws4@^1.8.0:
|
||||
resolved "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2"
|
||||
integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==
|
||||
|
||||
axios@^0.20.0:
|
||||
version "0.20.0"
|
||||
resolved "https://registry.npm.taobao.org/axios/download/axios-0.20.0.tgz#057ba30f04884694993a8cd07fa394cff11c50bd"
|
||||
integrity sha1-BXujDwSIRpSZOozQf6OUz/EcUL0=
|
||||
axios@^0.21.0:
|
||||
version "0.21.0"
|
||||
resolved "https://registry.npm.taobao.org/axios/download/axios-0.21.0.tgz?cache=0&sync_timestamp=1603468783865&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.21.0.tgz#26df088803a2350dff2c27f96fef99fe49442aca"
|
||||
integrity sha1-Jt8IiAOiNQ3/LCf5b++Z/klEKso=
|
||||
dependencies:
|
||||
follow-redirects "^1.10.0"
|
||||
|
||||
@@ -2447,11 +2483,6 @@ cheerio@^1.0.0-rc.3:
|
||||
lodash "^4.15.0"
|
||||
parse5 "^3.0.1"
|
||||
|
||||
child_process@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/child_process/-/child_process-1.0.2.tgz#b1f7e7fc73d25e7fd1d455adc94e143830182b5a"
|
||||
integrity sha1-sffn/HPSXn/R1FWtyU4UODAYK1o=
|
||||
|
||||
"chokidar@>=2.0.0 <4.0.0", chokidar@^3.0.2, chokidar@^3.4.0:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz#b30611423ce376357c765b9b8f904b9fba3c0be8"
|
||||
@@ -2791,6 +2822,11 @@ connect-history-api-fallback@^1.6.0:
|
||||
resolved "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc"
|
||||
integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==
|
||||
|
||||
connection-parse@0.0.x:
|
||||
version "0.0.7"
|
||||
resolved "https://registry.npm.taobao.org/connection-parse/download/connection-parse-0.0.7.tgz#18e7318aab06a699267372b10c5226d25a1c9a69"
|
||||
integrity sha1-GOcxiqsGppkmc3KxDFIm0locmmk=
|
||||
|
||||
console-browserify@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336"
|
||||
@@ -2900,6 +2936,11 @@ core-js@^3.6.5:
|
||||
resolved "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a"
|
||||
integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==
|
||||
|
||||
core-js@^3.7.0:
|
||||
version "3.7.0"
|
||||
resolved "https://registry.npm.taobao.org/core-js/download/core-js-3.7.0.tgz?cache=0&sync_timestamp=1604675690423&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js%2Fdownload%2Fcore-js-3.7.0.tgz#b0a761a02488577afbf97179e4681bf49568520f"
|
||||
integrity sha1-sKdhoCSIV3r7+XF55Ggb9JVoUg8=
|
||||
|
||||
core-util-is@1.0.2, core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
@@ -3202,18 +3243,30 @@ dashdash@^1.12.0:
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
|
||||
data-uri-to-buffer@0:
|
||||
version "0.0.4"
|
||||
resolved "https://registry.npm.taobao.org/data-uri-to-buffer/download/data-uri-to-buffer-0.0.4.tgz?cache=0&sync_timestamp=1590800007667&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdata-uri-to-buffer%2Fdownload%2Fdata-uri-to-buffer-0.0.4.tgz#46e13ab9da8e309745c8d01ce547213ebdb2fe3f"
|
||||
integrity sha1-RuE6udqOMJdFyNAc5UchPr2y/j8=
|
||||
|
||||
de-indent@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d"
|
||||
integrity sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=
|
||||
|
||||
debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9:
|
||||
debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
|
||||
resolved "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1600502824188&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
integrity sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@4, debug@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502824188&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1"
|
||||
integrity sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E=
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
debug@^3.1.1, debug@^3.2.5:
|
||||
version "3.2.6"
|
||||
resolved "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
|
||||
@@ -3228,13 +3281,6 @@ debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1"
|
||||
integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
decamelize@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
|
||||
@@ -3393,6 +3439,11 @@ dexie@^3.0.2:
|
||||
resolved "https://registry.npm.taobao.org/dexie/download/dexie-3.0.2.tgz#4b979904d739e0530b68352005f175a82633a075"
|
||||
integrity sha1-S5eZBNc54FMLaDUgBfF1qCYzoHU=
|
||||
|
||||
diff@^4.0.1:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.npm.taobao.org/diff/download/diff-4.0.2.tgz?cache=0&sync_timestamp=1604803633979&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdiff%2Fdownload%2Fdiff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
|
||||
integrity sha1-YPOuy4nV+uUgwRqhnvwruYKq3n0=
|
||||
|
||||
diffie-hellman@^5.0.0:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
|
||||
@@ -3479,6 +3530,11 @@ dom-serializer@~0.1.1:
|
||||
domelementtype "^1.3.0"
|
||||
entities "^1.1.1"
|
||||
|
||||
dom-walk@^0.1.0:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.npm.taobao.org/dom-walk/download/dom-walk-0.1.2.tgz?cache=0&sync_timestamp=1585908356502&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdom-walk%2Fdownload%2Fdom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84"
|
||||
integrity sha1-DFSL7wSPTR8qlySQAiNgYNqj/YQ=
|
||||
|
||||
domain-browser@^1.1.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
|
||||
@@ -3651,6 +3707,19 @@ electron-localshortcut@^3.2.1:
|
||||
keyboardevent-from-electron-accelerator "^2.0.0"
|
||||
keyboardevents-areequal "^0.2.1"
|
||||
|
||||
electron-proxy-agent@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npm.taobao.org/electron-proxy-agent/download/electron-proxy-agent-1.2.0.tgz#35bdbaf80d466cb7f71f20ddf0c11ad7b0aefdb9"
|
||||
integrity sha1-Nb26+A1GbLf3HyDd8MEa17Cu/bk=
|
||||
dependencies:
|
||||
agent-base "2"
|
||||
debug "2"
|
||||
extend "3"
|
||||
get-uri "1"
|
||||
http-proxy-agent "^4.0.1"
|
||||
https-proxy-agent "^5.0.0"
|
||||
socks-proxy-agent "2"
|
||||
|
||||
electron-publish@22.7.0:
|
||||
version "22.7.0"
|
||||
resolved "https://registry.npmjs.org/electron-publish/-/electron-publish-22.7.0.tgz#d92ba7c4007c9ac1dd070593e48028184fb2dc19"
|
||||
@@ -3683,19 +3752,19 @@ electron-updater@^4.3.5:
|
||||
lodash.isequal "^4.5.0"
|
||||
semver "^7.3.2"
|
||||
|
||||
electron@^10.1.4:
|
||||
version "10.1.4"
|
||||
resolved "https://registry.npm.taobao.org/electron/download/electron-10.1.4.tgz?cache=0&sync_timestamp=1603157068707&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Felectron%2Fdownload%2Felectron-10.1.4.tgz#5462c5fac5b4728691042d0f62133ea2c133e6fd"
|
||||
integrity sha1-VGLF+sW0coaRBC0PYhM+osEz5v0=
|
||||
electron@^10.1.5:
|
||||
version "10.1.5"
|
||||
resolved "https://registry.npm.taobao.org/electron/download/electron-10.1.5.tgz#f2b161310f627063e73fbac44efcb35dece83a90"
|
||||
integrity sha1-8rFhMQ9icGPnP7rETvyzXezoOpA=
|
||||
dependencies:
|
||||
"@electron/get" "^1.0.1"
|
||||
"@types/node" "^12.0.12"
|
||||
extract-zip "^1.0.3"
|
||||
|
||||
element-ui@^2.13.2:
|
||||
version "2.13.2"
|
||||
resolved "https://registry.npmjs.org/element-ui/-/element-ui-2.13.2.tgz#582bf47aaaaaafe23ea1958fae217a687ad06447"
|
||||
integrity sha512-r761DRPssMPKDiJZWFlG+4e4vr0cRG/atKr3Eqr8Xi0tQMNbtmYU1QXvFnKiFPFFGkgJ6zS6ASkG+sellcoHlQ==
|
||||
element-ui@^2.14.0:
|
||||
version "2.14.0"
|
||||
resolved "https://registry.npm.taobao.org/element-ui/download/element-ui-2.14.0.tgz#dcff2718fb485542ea5b5a1f5c0daf1113477b24"
|
||||
integrity sha1-3P8nGPtIVULqW1ofXA2vERNHeyQ=
|
||||
dependencies:
|
||||
async-validator "~1.8.1"
|
||||
babel-helper-vue-jsx-merge-props "^2.0.0"
|
||||
@@ -3890,7 +3959,7 @@ eslint-config-standard@^14.1.0:
|
||||
resolved "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz#830a8e44e7aef7de67464979ad06b406026c56ea"
|
||||
integrity sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg==
|
||||
|
||||
eslint-import-resolver-node@^0.3.3:
|
||||
eslint-import-resolver-node@^0.3.3, eslint-import-resolver-node@^0.3.4:
|
||||
version "0.3.4"
|
||||
resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz#85ffa81942c25012d8231096ddf679c03042c717"
|
||||
integrity sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==
|
||||
@@ -3941,17 +4010,17 @@ eslint-plugin-es@^3.0.0:
|
||||
eslint-utils "^2.0.0"
|
||||
regexpp "^3.0.0"
|
||||
|
||||
eslint-plugin-import@^2.20.2:
|
||||
version "2.22.0"
|
||||
resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.0.tgz#92f7736fe1fde3e2de77623c838dd992ff5ffb7e"
|
||||
integrity sha512-66Fpf1Ln6aIS5Gr/55ts19eUuoDhAbZgnr6UxK5hbDx6l/QgQgx61AePq+BV4PP2uXQFClgMVzep5zZ94qqsxg==
|
||||
eslint-plugin-import@^2.22.1:
|
||||
version "2.22.1"
|
||||
resolved "https://registry.npm.taobao.org/eslint-plugin-import/download/eslint-plugin-import-2.22.1.tgz#0896c7e6a0cf44109a2d97b95903c2bb689d7702"
|
||||
integrity sha1-CJbH5qDPRBCaLZe5WQPCu2iddwI=
|
||||
dependencies:
|
||||
array-includes "^3.1.1"
|
||||
array.prototype.flat "^1.2.3"
|
||||
contains-path "^0.1.0"
|
||||
debug "^2.6.9"
|
||||
doctrine "1.5.0"
|
||||
eslint-import-resolver-node "^0.3.3"
|
||||
eslint-import-resolver-node "^0.3.4"
|
||||
eslint-module-utils "^2.6.0"
|
||||
has "^1.0.3"
|
||||
minimatch "^3.0.4"
|
||||
@@ -3977,10 +4046,10 @@ eslint-plugin-promise@^4.2.1:
|
||||
resolved "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a"
|
||||
integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==
|
||||
|
||||
eslint-plugin-standard@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz#ff0519f7ffaff114f76d1bd7c3996eef0f6e20b4"
|
||||
integrity sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ==
|
||||
eslint-plugin-standard@^4.0.2:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.npm.taobao.org/eslint-plugin-standard/download/eslint-plugin-standard-4.1.0.tgz#0c3bf3a67e853f8bbbc580fb4945fbf16f41b7c5"
|
||||
integrity sha1-DDvzpn6FP4u7xYD7SUX78W9Bt8U=
|
||||
|
||||
eslint-plugin-vue@^6.2.2:
|
||||
version "6.2.2"
|
||||
@@ -4293,10 +4362,10 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2:
|
||||
assign-symbols "^1.0.0"
|
||||
is-extendable "^1.0.1"
|
||||
|
||||
extend@~3.0.2:
|
||||
extend@3, extend@~3.0.0, extend@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||
resolved "https://registry.npm.taobao.org/extend/download/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||
integrity sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo=
|
||||
|
||||
external-editor@^3.0.3:
|
||||
version "3.1.0"
|
||||
@@ -4341,6 +4410,11 @@ extsprintf@^1.2.0:
|
||||
resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
|
||||
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
|
||||
|
||||
eyes@~0.1.6:
|
||||
version "0.1.8"
|
||||
resolved "https://registry.npm.taobao.org/eyes/download/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0"
|
||||
integrity sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=
|
||||
|
||||
fast-deep-equal@^3.1.1:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||
@@ -4421,6 +4495,11 @@ file-loader@^4.2.0:
|
||||
loader-utils "^1.2.3"
|
||||
schema-utils "^2.5.0"
|
||||
|
||||
file-uri-to-path@0:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.npm.taobao.org/file-uri-to-path/download/file-uri-to-path-0.0.2.tgz#37cdd1b5b905404b3f05e1b23645be694ff70f82"
|
||||
integrity sha1-N83RtbkFQEs/BeGyNkW+aU/3D4I=
|
||||
|
||||
file-uri-to-path@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
|
||||
@@ -4687,6 +4766,14 @@ fsevents@~2.1.2:
|
||||
resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e"
|
||||
integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==
|
||||
|
||||
ftp@~0.3.5:
|
||||
version "0.3.10"
|
||||
resolved "https://registry.npm.taobao.org/ftp/download/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d"
|
||||
integrity sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=
|
||||
dependencies:
|
||||
readable-stream "1.1.x"
|
||||
xregexp "2.0.0"
|
||||
|
||||
function-bind@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||
@@ -4731,6 +4818,18 @@ get-stream@^5.0.0, get-stream@^5.1.0:
|
||||
dependencies:
|
||||
pump "^3.0.0"
|
||||
|
||||
get-uri@1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npm.taobao.org/get-uri/download/get-uri-1.1.0.tgz#7375d04daf7fcb584b3632679cbdf339b51bb149"
|
||||
integrity sha1-c3XQTa9/y1hLNjJnnL3zObUbsUk=
|
||||
dependencies:
|
||||
data-uri-to-buffer "0"
|
||||
debug "2"
|
||||
extend "3"
|
||||
file-uri-to-path "0"
|
||||
ftp "~0.3.5"
|
||||
readable-stream "2"
|
||||
|
||||
get-value@^2.0.3, get-value@^2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
|
||||
@@ -4805,6 +4904,14 @@ global-tunnel-ng@^2.7.1:
|
||||
npm-conf "^1.1.3"
|
||||
tunnel "^0.0.6"
|
||||
|
||||
global@^4.3.2:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.npm.taobao.org/global/download/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406"
|
||||
integrity sha1-PnsQUXkAajI+1xqvyj6cV6XMZAY=
|
||||
dependencies:
|
||||
min-document "^2.19.0"
|
||||
process "^0.11.10"
|
||||
|
||||
globals@^11.1.0:
|
||||
version "11.12.0"
|
||||
resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
|
||||
@@ -5001,6 +5108,14 @@ hash.js@^1.0.0, hash.js@^1.0.3:
|
||||
inherits "^2.0.3"
|
||||
minimalistic-assert "^1.0.1"
|
||||
|
||||
hashring@3.2.x:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.npm.taobao.org/hashring/download/hashring-3.2.0.tgz#fda4efde8aa22cdb97fb1d2a65e88401e1c144ce"
|
||||
integrity sha1-/aTv3oqiLNuX+x0qZeiEAeHBRM4=
|
||||
dependencies:
|
||||
connection-parse "0.0.x"
|
||||
simple-lru-cache "0.0.x"
|
||||
|
||||
he@1.2.x, he@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||
@@ -5169,6 +5284,15 @@ http-parser-js@>=0.5.1:
|
||||
resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.2.tgz#da2e31d237b393aae72ace43882dd7e270a8ff77"
|
||||
integrity sha512-opCO9ASqg5Wy2FNo7A0sxy71yGbbkJJXLdgMK04Tcypw9jr2MgWbyubb0+WdmDmGnFflO7fRbqbaihh/ENDlRQ==
|
||||
|
||||
http-proxy-agent@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.npm.taobao.org/http-proxy-agent/download/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a"
|
||||
integrity sha1-ioyO9/WTLM+VPClsqCkblap0qjo=
|
||||
dependencies:
|
||||
"@tootallnate/once" "1"
|
||||
agent-base "6"
|
||||
debug "4"
|
||||
|
||||
http-proxy-middleware@0.19.1:
|
||||
version "0.19.1"
|
||||
resolved "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a"
|
||||
@@ -5202,6 +5326,14 @@ https-browserify@^1.0.0:
|
||||
resolved "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
|
||||
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
|
||||
|
||||
https-proxy-agent@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.npm.taobao.org/https-proxy-agent/download/https-proxy-agent-5.0.0.tgz?cache=0&sync_timestamp=1600349079392&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttps-proxy-agent%2Fdownload%2Fhttps-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2"
|
||||
integrity sha1-4qkFQqu2inYuCghQ9sntrf2FBrI=
|
||||
dependencies:
|
||||
agent-base "6"
|
||||
debug "4"
|
||||
|
||||
human-signals@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
|
||||
@@ -5398,9 +5530,9 @@ ip-regex@^2.1.0:
|
||||
resolved "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9"
|
||||
integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=
|
||||
|
||||
ip@^1.1.0, ip@^1.1.5:
|
||||
ip@^1.1.0, ip@^1.1.4, ip@^1.1.5:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
|
||||
resolved "https://registry.npm.taobao.org/ip/download/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
|
||||
integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
|
||||
|
||||
ipaddr.js@1.9.1, ipaddr.js@^1.9.0:
|
||||
@@ -5724,6 +5856,11 @@ is-yarn-global@^0.3.0:
|
||||
resolved "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232"
|
||||
integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==
|
||||
|
||||
isarray@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.npm.taobao.org/isarray/download/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
|
||||
integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
|
||||
|
||||
isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
@@ -5756,6 +5893,13 @@ isstream@~0.1.2:
|
||||
resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
||||
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
|
||||
|
||||
jackpot@>=0.0.6:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.npm.taobao.org/jackpot/download/jackpot-0.0.6.tgz#3cff064285cbf66f4eab2593c90bce816a821849"
|
||||
integrity sha1-PP8GQoXL9m9OqyWTyQvOgWqCGEk=
|
||||
dependencies:
|
||||
retry "0.6.0"
|
||||
|
||||
jake@^10.6.1:
|
||||
version "10.8.2"
|
||||
resolved "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz#ebc9de8558160a66d82d0eadc6a2e58fbc500a7b"
|
||||
@@ -6149,10 +6293,10 @@ loglevel@^1.6.8:
|
||||
resolved "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz#8a25fb75d092230ecd4457270d80b54e28011171"
|
||||
integrity sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==
|
||||
|
||||
loose-envify@^1.0.0:
|
||||
loose-envify@^1.0.0, loose-envify@^1.2.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
||||
resolved "https://registry.npm.taobao.org/loose-envify/download/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||
integrity sha1-ce5R+nvkyuwaY4OffmgtgTLTDK8=
|
||||
dependencies:
|
||||
js-tokens "^3.0.0 || ^4.0.0"
|
||||
|
||||
@@ -6186,6 +6330,15 @@ lru-cache@^5.1.1:
|
||||
dependencies:
|
||||
yallist "^3.0.2"
|
||||
|
||||
m3u8-parser@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.npm.taobao.org/m3u8-parser/download/m3u8-parser-4.5.0.tgz#9c30b32c9b69cc3f81b5e6789717fa84b9fdb9aa"
|
||||
integrity sha1-nDCzLJtpzD+BteZ4lxf6hLn9uao=
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.5.5"
|
||||
"@videojs/vhs-utils" "^2.2.1"
|
||||
global "^4.3.2"
|
||||
|
||||
m3u@0.0.2:
|
||||
version "0.0.2"
|
||||
resolved "https://mirrors.huaweicloud.com/repository/npm/m3u/-/m3u-0.0.2.tgz#cb971743b434efd8c77b3cc3a47fc0411a903df7"
|
||||
@@ -6251,6 +6404,14 @@ media-typer@0.3.0:
|
||||
resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
|
||||
|
||||
memcached@^2.2.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.npm.taobao.org/memcached/download/memcached-2.2.2.tgz#68f86ccfd84bcf93cc25ed46d6d7fc0c7521c9d5"
|
||||
integrity sha1-aPhsz9hLz5PMJe1G1tf8DHUhydU=
|
||||
dependencies:
|
||||
hashring "3.2.x"
|
||||
jackpot ">=0.0.6"
|
||||
|
||||
memory-fs@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz#f2bb25368bc121e391c2520de92969caee0a0290"
|
||||
@@ -6363,6 +6524,13 @@ mimic-response@^1.0.0, mimic-response@^1.0.1:
|
||||
resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
|
||||
integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
|
||||
|
||||
min-document@^2.19.0:
|
||||
version "2.19.0"
|
||||
resolved "https://registry.npm.taobao.org/min-document/download/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
|
||||
integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=
|
||||
dependencies:
|
||||
dom-walk "^0.1.0"
|
||||
|
||||
mini-css-extract-plugin@^0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz#47f2cf07aa165ab35733b1fc97d4c46c0564339e"
|
||||
@@ -7893,10 +8061,10 @@ read-pkg@^5.1.1:
|
||||
parse-json "^5.0.0"
|
||||
type-fest "^0.6.0"
|
||||
|
||||
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6:
|
||||
"readable-stream@1 || 2", readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6:
|
||||
version "2.3.7"
|
||||
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
|
||||
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
|
||||
resolved "https://registry.npm.taobao.org/readable-stream/download/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
|
||||
integrity sha1-Hsoc9xGu+BTAT2IlKjamL2yyO1c=
|
||||
dependencies:
|
||||
core-util-is "~1.0.0"
|
||||
inherits "~2.0.3"
|
||||
@@ -7906,6 +8074,16 @@ read-pkg@^5.1.1:
|
||||
string_decoder "~1.1.1"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
readable-stream@1.1.x:
|
||||
version "1.1.14"
|
||||
resolved "https://registry.npm.taobao.org/readable-stream/download/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
|
||||
integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk=
|
||||
dependencies:
|
||||
core-util-is "~1.0.0"
|
||||
inherits "~2.0.1"
|
||||
isarray "0.0.1"
|
||||
string_decoder "~0.10.x"
|
||||
|
||||
readable-stream@^3.0.0, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
|
||||
@@ -8163,6 +8341,11 @@ ret@~0.1.10:
|
||||
resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
|
||||
integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==
|
||||
|
||||
retry@0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.npm.taobao.org/retry/download/retry-0.6.0.tgz#1c010713279a6fd1e8def28af0c3ff1871caa537"
|
||||
integrity sha1-HAEHEyeab9Ho3vKK8MP/GHHKpTc=
|
||||
|
||||
retry@^0.12.0:
|
||||
version "0.12.0"
|
||||
resolved "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b"
|
||||
@@ -8278,10 +8461,10 @@ sass-loader@^8.0.2:
|
||||
schema-utils "^2.6.1"
|
||||
semver "^6.3.0"
|
||||
|
||||
sass@^1.26.5:
|
||||
version "1.26.10"
|
||||
resolved "https://registry.npmjs.org/sass/-/sass-1.26.10.tgz#851d126021cdc93decbf201d1eca2a20ee434760"
|
||||
integrity sha512-bzN0uvmzfsTvjz0qwccN1sPm2HxxpNI/Xa+7PlUEMS+nQvbyuEK7Y0qFqxlPHhiNHb1Ze8WQJtU31olMObkAMw==
|
||||
sass@^1.29.0:
|
||||
version "1.29.0"
|
||||
resolved "https://registry.npm.taobao.org/sass/download/sass-1.29.0.tgz?cache=0&sync_timestamp=1604536692062&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsass%2Fdownload%2Fsass-1.29.0.tgz#ec4e1842c146d8ea9258c28c141b8c2b7c6ab7f1"
|
||||
integrity sha1-7E4YQsFG2OqSWMKMFBuMK3xqt/E=
|
||||
dependencies:
|
||||
chokidar ">=2.0.0 <4.0.0"
|
||||
|
||||
@@ -8352,6 +8535,11 @@ semver@^7.2.1, semver@^7.3.2:
|
||||
resolved "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
|
||||
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
|
||||
|
||||
semver@~5.0.1:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.npm.taobao.org/semver/download/semver-5.0.3.tgz#77466de589cd5d3c95f138aa78bc569a3cb5d27a"
|
||||
integrity sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=
|
||||
|
||||
send@0.17.1:
|
||||
version "0.17.1"
|
||||
resolved "https://registry.npmjs.org/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8"
|
||||
@@ -8420,6 +8608,13 @@ serve-static@1.14.1:
|
||||
parseurl "~1.3.3"
|
||||
send "0.17.1"
|
||||
|
||||
session@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.npm.taobao.org/session/download/session-0.1.0.tgz#6ae9aa6f26093be31ed2005bcd426ae80aa3a085"
|
||||
integrity sha1-aumqbyYJO+Me0gBbzUJq6AqjoIU=
|
||||
dependencies:
|
||||
vows "*"
|
||||
|
||||
set-blocking@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
|
||||
@@ -8509,6 +8704,11 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
|
||||
resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
|
||||
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
|
||||
|
||||
simple-lru-cache@0.0.x:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.npm.taobao.org/simple-lru-cache/download/simple-lru-cache-0.0.2.tgz#d59cc3a193c1a5d0320f84ee732f6e4713e511dd"
|
||||
integrity sha1-1ZzDoZPBpdAyD4Tucy9uRxPlEd0=
|
||||
|
||||
simple-swizzle@^0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
|
||||
@@ -8535,6 +8735,11 @@ slice-ansi@^2.1.0:
|
||||
astral-regex "^1.0.0"
|
||||
is-fullwidth-code-point "^2.0.0"
|
||||
|
||||
smart-buffer@^1.0.13:
|
||||
version "1.1.15"
|
||||
resolved "https://registry.npm.taobao.org/smart-buffer/download/smart-buffer-1.1.15.tgz#7f114b5b65fab3e2a35aa775bb12f0d1c649bf16"
|
||||
integrity sha1-fxFLW2X6s+KjWqd1uxLw0cZJvxY=
|
||||
|
||||
snapdragon-node@^2.0.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
|
||||
@@ -8586,6 +8791,23 @@ sockjs@0.3.20:
|
||||
uuid "^3.4.0"
|
||||
websocket-driver "0.6.5"
|
||||
|
||||
socks-proxy-agent@2:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.npm.taobao.org/socks-proxy-agent/download/socks-proxy-agent-2.1.1.tgz?cache=0&sync_timestamp=1580846156853&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsocks-proxy-agent%2Fdownload%2Fsocks-proxy-agent-2.1.1.tgz#86ebb07193258637870e13b7bd99f26c663df3d3"
|
||||
integrity sha1-huuwcZMlhjeHDhO3vZnybGY989M=
|
||||
dependencies:
|
||||
agent-base "2"
|
||||
extend "3"
|
||||
socks "~1.1.5"
|
||||
|
||||
socks@~1.1.5:
|
||||
version "1.1.10"
|
||||
resolved "https://registry.npm.taobao.org/socks/download/socks-1.1.10.tgz?cache=0&sync_timestamp=1603684981912&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsocks%2Fdownload%2Fsocks-1.1.10.tgz#5b8b7fc7c8f341c53ed056e929b7bf4de8ba7b5a"
|
||||
integrity sha1-W4t/x8jzQcU+0FbpKbe/Tei6e1o=
|
||||
dependencies:
|
||||
ip "^1.1.4"
|
||||
smart-buffer "^1.0.13"
|
||||
|
||||
sort-keys@^1.0.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad"
|
||||
@@ -8593,10 +8815,10 @@ sort-keys@^1.0.0:
|
||||
dependencies:
|
||||
is-plain-obj "^1.0.0"
|
||||
|
||||
sortablejs@^1.10.1:
|
||||
version "1.12.0"
|
||||
resolved "https://registry.yarnpkg.com/sortablejs/-/sortablejs-1.12.0.tgz#ee6d7ece3598c2af0feb1559d98595e5ea37cbd6"
|
||||
integrity sha512-bPn57rCjBRlt2sC24RBsu40wZsmLkSo2XeqG8k6DC1zru5eObQUIPPZAQG7W2SJ8FZQYq+BEJmvuw1Zxb3chqg==
|
||||
sortablejs@1.10.2:
|
||||
version "1.10.2"
|
||||
resolved "https://registry.npm.taobao.org/sortablejs/download/sortablejs-1.10.2.tgz#6e40364d913f98b85a14f6678f92b5c1221f5290"
|
||||
integrity sha1-bkA2TZE/mLhaFPZnj5K1wSIfUpA=
|
||||
|
||||
source-list-map@^2.0.0:
|
||||
version "2.0.1"
|
||||
@@ -8861,6 +9083,11 @@ string_decoder@^1.0.0, string_decoder@^1.1.1:
|
||||
dependencies:
|
||||
safe-buffer "~5.2.0"
|
||||
|
||||
string_decoder@~0.10.x:
|
||||
version "0.10.31"
|
||||
resolved "https://registry.npm.taobao.org/string_decoder/download/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
|
||||
integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
|
||||
|
||||
string_decoder@~1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
|
||||
@@ -9541,6 +9768,11 @@ url-parse@^1.4.3:
|
||||
querystringify "^2.1.1"
|
||||
requires-port "^1.0.0"
|
||||
|
||||
url-toolkit@^2.1.6:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.npm.taobao.org/url-toolkit/download/url-toolkit-2.2.1.tgz#89009ed3d62a3574de079532a7266c14d2cc1c4f"
|
||||
integrity sha1-iQCe09YqNXTeB5UypyZsFNLMHE8=
|
||||
|
||||
url@^0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.npmjs.org/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
|
||||
@@ -9653,6 +9885,15 @@ vm-browserify@^1.0.1:
|
||||
resolved "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
|
||||
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
|
||||
|
||||
vows@*:
|
||||
version "0.8.3"
|
||||
resolved "https://registry.npm.taobao.org/vows/download/vows-0.8.3.tgz#36e353c2bca3a93902fc32eb8c5baab2e3a93f10"
|
||||
integrity sha1-NuNTwryjqTkC/DLrjFuqsuOpPxA=
|
||||
dependencies:
|
||||
diff "^4.0.1"
|
||||
eyes "~0.1.6"
|
||||
glob "^7.1.2"
|
||||
|
||||
vue-cli-plugin-electron-builder@2.0.0-rc.4:
|
||||
version "2.0.0-rc.4"
|
||||
resolved "https://registry.npmjs.org/vue-cli-plugin-electron-builder/-/vue-cli-plugin-electron-builder-2.0.0-rc.4.tgz#c819279e00fe6771912f5f0468ee26f279750a5b"
|
||||
@@ -9678,6 +9919,13 @@ vue-cli-plugin-electron-builder@2.0.0-rc.4:
|
||||
webpack-merge "^4.2.2"
|
||||
yargs "^15.3.1"
|
||||
|
||||
vue-clickaway@^2.2.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.npm.taobao.org/vue-clickaway/download/vue-clickaway-2.2.2.tgz#cecf6839575e8b2afc5d3edb3efb616d293dbb44"
|
||||
integrity sha1-zs9oOVdeiyr8XT7bPvthbSk9u0Q=
|
||||
dependencies:
|
||||
loose-envify "^1.2.0"
|
||||
|
||||
vue-eslint-parser@^7.0.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.1.0.tgz#9cdbcc823e656b087507a1911732b867ac101e83"
|
||||
@@ -9742,12 +9990,12 @@ vue@^2.6.12:
|
||||
resolved "https://registry.npm.taobao.org/vue/download/vue-2.6.12.tgz?cache=0&sync_timestamp=1602778254831&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue%2Fdownload%2Fvue-2.6.12.tgz#f5ebd4fa6bd2869403e29a896aed4904456c9123"
|
||||
integrity sha1-9evU+mvShpQD4pqJau1JBEVskSM=
|
||||
|
||||
vuedraggable@^2.24.2:
|
||||
version "2.24.2"
|
||||
resolved "https://registry.npm.taobao.org/vuedraggable/download/vuedraggable-2.24.2.tgz#cd98faec99905238469e9b4d235fba5a59fb7da2"
|
||||
integrity sha1-zZj67JmQUjhGnptNI1+6Wln7faI=
|
||||
vuedraggable@^2.24.3:
|
||||
version "2.24.3"
|
||||
resolved "https://registry.npm.taobao.org/vuedraggable/download/vuedraggable-2.24.3.tgz?cache=0&sync_timestamp=1603590834453&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvuedraggable%2Fdownload%2Fvuedraggable-2.24.3.tgz#43c93849b746a24ce503e123d5b259c701ba0d19"
|
||||
integrity sha1-Q8k4SbdGokzlA+Ej1bJZxwG6DRk=
|
||||
dependencies:
|
||||
sortablejs "^1.10.1"
|
||||
sortablejs "1.10.2"
|
||||
|
||||
vuex@^3.5.1:
|
||||
version "3.5.1"
|
||||
@@ -10052,6 +10300,11 @@ xgplayer@^2.13.0:
|
||||
pasition "^1.0.1"
|
||||
request-frame "^1.5.3"
|
||||
|
||||
xregexp@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npm.taobao.org/xregexp/download/xregexp-2.0.0.tgz?cache=0&sync_timestamp=1604008197739&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fxregexp%2Fdownload%2Fxregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943"
|
||||
integrity sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=
|
||||
|
||||
xregexp@^4.2.4:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz#7e92e73d9174a99a59743f67a4ce879a04b5ae50"
|
||||
|
||||
Reference in New Issue
Block a user