mirror of
https://github.com/cuiocean/ZY-Player.git
synced 2026-02-15 00:16:26 +08:00
Compare commits
156 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
61dcb1ec49 | ||
|
|
40b853361e | ||
|
|
57ff3325f0 | ||
|
|
c4283e2da0 | ||
|
|
7052bd7e05 | ||
|
|
64a12a06c4 | ||
|
|
3df3b385ce | ||
|
|
e77db4711e | ||
|
|
fb3fd26870 | ||
|
|
72790f5f3e | ||
|
|
ea2815969d | ||
|
|
e330cff7d4 | ||
|
|
da5b91535e | ||
|
|
00c8f0c1e2 | ||
|
|
924fd439d9 | ||
|
|
ed039894c8 | ||
|
|
005bdf7ea6 | ||
|
|
19071faf70 | ||
|
|
176d9f6b5a | ||
|
|
31a8dd0f32 | ||
|
|
336ea08c69 | ||
|
|
8e4a0870a1 | ||
|
|
86130e6c53 | ||
|
|
e984d0a349 | ||
|
|
506991f3b1 | ||
|
|
04c35ba7a9 | ||
|
|
275b6757bf | ||
|
|
612930cc8b | ||
|
|
80e36fa99c | ||
|
|
f069044f28 | ||
|
|
c77ac7ea7f | ||
|
|
803181b4f7 | ||
|
|
ac2474903d | ||
|
|
04b7e139da | ||
|
|
b49e1b82bf | ||
|
|
dc00c690e7 | ||
|
|
44ba552435 | ||
|
|
8d84d1bf22 | ||
|
|
c78368dac9 | ||
|
|
11af5a7ecd | ||
|
|
ecfeecf45f | ||
|
|
455f5dae84 | ||
|
|
ffbffde74f | ||
|
|
0be0433355 | ||
|
|
cc2dc19e39 | ||
|
|
aa4583898a | ||
|
|
2e96812a1f | ||
|
|
6f52d73d52 | ||
|
|
a3ebba641f | ||
|
|
8ceffab2fe | ||
|
|
454d192141 | ||
|
|
a1423993c8 | ||
|
|
1c9a84dbc6 | ||
|
|
304b0d10b4 | ||
|
|
aff97f6d46 | ||
|
|
650c882f58 | ||
|
|
32fa465cf2 | ||
|
|
1fdfada14f | ||
|
|
5ed8b6e49a | ||
|
|
c2e2f1c490 | ||
|
|
7ad40ba375 | ||
|
|
c708292051 | ||
|
|
79932a74bc | ||
|
|
3f79f31550 | ||
|
|
1d33db0143 | ||
|
|
1dc7b38160 | ||
|
|
db7cdab787 | ||
|
|
d1e6ac1ae6 | ||
|
|
d63710afe6 | ||
|
|
8abe4b7ef8 | ||
|
|
98b4f5bc1d | ||
|
|
248c0994c9 | ||
|
|
2eba0523bc | ||
|
|
49589102d9 | ||
|
|
79b02df628 | ||
|
|
0f456fe7a8 | ||
|
|
850c8d5423 | ||
|
|
63cf367f52 | ||
|
|
bd43f06e7d | ||
|
|
2ed47e64c3 | ||
|
|
8817d39d49 | ||
|
|
b68525213a | ||
|
|
0efbc38137 | ||
|
|
cd2cb684a5 | ||
|
|
500dbfa1ee | ||
|
|
e970074266 | ||
|
|
9dc7ab4d1e | ||
|
|
ffe821d107 | ||
|
|
0f015b26e2 | ||
|
|
f031f9e7fd | ||
|
|
b38de7f393 | ||
|
|
8b5e8fd072 | ||
|
|
58e556554e | ||
|
|
cceed30d35 | ||
|
|
980b0a6e50 | ||
|
|
c98236222d | ||
|
|
6a7c2afb2d | ||
|
|
af482a450a | ||
|
|
42b81b98cf | ||
|
|
da7dfed5ba | ||
|
|
7d6c5482af | ||
|
|
11e7ffc554 | ||
|
|
4974d57fbf | ||
|
|
037bb1a2ff | ||
|
|
b19870d228 | ||
|
|
de0161c560 | ||
|
|
623a10bd13 | ||
|
|
c69eadbe3e | ||
|
|
5f48f46cbc | ||
|
|
694986d6c5 | ||
|
|
d4ad68e030 | ||
|
|
72089bf53f | ||
|
|
0401ce6d7e | ||
|
|
09e27d4f40 | ||
|
|
45de6650bf | ||
|
|
4e0fa4d980 | ||
|
|
7a0f8f9644 | ||
|
|
e43ef98ce7 | ||
|
|
2abbf41ed1 | ||
|
|
02139d3d24 | ||
|
|
d86a10d753 | ||
|
|
dc8bdb29dc | ||
|
|
98b019be5f | ||
|
|
e6d1698d62 | ||
|
|
6c1e6c511f | ||
|
|
1a1393615c | ||
|
|
5930690144 | ||
|
|
091493fa77 | ||
|
|
cd1c4eaffe | ||
|
|
1bb217d84f | ||
|
|
92eac6d2dd | ||
|
|
b067cfa143 | ||
|
|
99d21fd7fe | ||
|
|
b167f711d0 | ||
|
|
7d4ffeed87 | ||
|
|
7e94ef8025 | ||
|
|
1a36bc85b9 | ||
|
|
f7ed0e1c29 | ||
|
|
970a359aba | ||
|
|
be0441d042 | ||
|
|
3fc350e6d6 | ||
|
|
b26a4d4f27 | ||
|
|
454ea48891 | ||
|
|
d564d0928b | ||
|
|
2562119bad | ||
|
|
1a7aaa8dff | ||
|
|
583a768068 | ||
|
|
6216ad96d6 | ||
|
|
766b1d458f | ||
|
|
6a0699ec20 | ||
|
|
a6fd748e09 | ||
|
|
064ff38650 | ||
|
|
1c74174a3a | ||
|
|
0625c4945f | ||
|
|
d485a5733e | ||
|
|
5ab5cee6dc |
28
package.json
28
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "zy",
|
||||
"version": "2.5.2-1",
|
||||
"version": "2.5.4",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
@@ -17,30 +17,32 @@
|
||||
},
|
||||
"main": "background.js",
|
||||
"dependencies": {
|
||||
"axios": "^0.19.2",
|
||||
"axios": "^0.20.0",
|
||||
"cheerio": "^1.0.0-rc.3",
|
||||
"child_process": "^1.0.2",
|
||||
"core-js": "^3.6.5",
|
||||
"cors": "^2.8.5",
|
||||
"dexie": "^3.0.1",
|
||||
"dexie": "^3.0.2",
|
||||
"electron-localshortcut": "^3.2.1",
|
||||
"electron-updater": "^4.3.5",
|
||||
"element-ui": "^2.13.2",
|
||||
"express": "^4.17.1",
|
||||
"fast-xml-parser": "^3.17.4",
|
||||
"html2canvas": "^1.0.0-rc.5",
|
||||
"html2canvas": "^1.0.0-rc.7",
|
||||
"iptv-playlist-parser": "^0.5.0",
|
||||
"m3u": "0.0.2",
|
||||
"modern-normalize": "^0.6.0",
|
||||
"modern-normalize": "^1.0.0",
|
||||
"mousetrap": "^1.6.5",
|
||||
"qrcode.vue": "^1.7.0",
|
||||
"randomstring": "^1.1.5",
|
||||
"vue": "^2.6.11",
|
||||
"v-fit-columns": "^0.2.0",
|
||||
"vue": "^2.6.12",
|
||||
"vue-infinite-loading": "^2.4.5",
|
||||
"vue-waterfall-plugin": "^1.0.7",
|
||||
"vuedraggable": "^2.24.1",
|
||||
"vuex": "^3.4.0",
|
||||
"xgplayer": "^2.9.10",
|
||||
"xgplayer-hls.js": "^2.2.3"
|
||||
"vue-waterfall-plugin": "^1.1.0",
|
||||
"vuedraggable": "^2.24.2",
|
||||
"vuex": "^3.5.1",
|
||||
"xgplayer": "^2.13.0",
|
||||
"xgplayer-hls.js": "^2.2.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "~4.4.0",
|
||||
@@ -50,7 +52,7 @@
|
||||
"@vue/eslint-config-standard": "^5.1.2",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-plugin-component": "^1.1.1",
|
||||
"electron": "^9.3.1",
|
||||
"electron": "^10.1.4",
|
||||
"electron-devtools-installer": "^3.1.0",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-import": "^2.20.2",
|
||||
@@ -61,6 +63,6 @@
|
||||
"sass": "^1.26.5",
|
||||
"sass-loader": "^8.0.2",
|
||||
"vue-cli-plugin-electron-builder": "2.0.0-rc.4",
|
||||
"vue-template-compiler": "^2.6.11"
|
||||
"vue-template-compiler": "^2.6.12"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
|
||||
56
src/App.vue
56
src/App.vue
@@ -9,6 +9,7 @@
|
||||
<Star v-show="view === 'Star'" />
|
||||
<History v-show="view === 'History'" />
|
||||
<Setting v-show="view === 'Setting'" />
|
||||
<EditSites v-if="view === 'EditSites'"/>
|
||||
</div>
|
||||
<transition name="slide">
|
||||
<Detail v-if="detail.show"/>
|
||||
@@ -16,68 +17,15 @@
|
||||
<transition name="slide">
|
||||
<Share v-if="share.show"/>
|
||||
</transition>
|
||||
<transition name="slide">
|
||||
<EditSites v-if="editSites.show"/>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { setting } from './lib/dexie'
|
||||
const { remote } = require('electron')
|
||||
export default {
|
||||
name: 'App',
|
||||
data () {
|
||||
return {
|
||||
appTheme: 'theme-light',
|
||||
winSizePosition: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
// 窗口创建口,检查是否有窗口大小位置的记录,如果有的话,更新窗口位置及大小
|
||||
setting.find().then(res => {
|
||||
if (res.windowSizePosition) {
|
||||
var win = remote.getCurrentWindow()
|
||||
win.setBounds({
|
||||
x: res.windowSizePosition.x,
|
||||
y: res.windowSizePosition.y,
|
||||
width: res.windowSizePosition.width,
|
||||
height: res.windowSizePosition.height
|
||||
})
|
||||
}
|
||||
})
|
||||
var win = remote.getCurrentWindow()
|
||||
this.winSizePosition = {
|
||||
x: win.getPosition()[0],
|
||||
y: win.getPosition()[1],
|
||||
width: win.getSize()[0],
|
||||
height: win.getSize()[1]
|
||||
}
|
||||
},
|
||||
updated () {
|
||||
// 本来想hook up到beforedestroy, 但不工作
|
||||
// 每当窗口更新时,检查窗口大小及位置,记录到setting数据库中
|
||||
const win = remote.getCurrentWindow()
|
||||
var newWinSizePosition = {
|
||||
x: win.getPosition()[0],
|
||||
y: win.getPosition()[1],
|
||||
width: win.getSize()[0],
|
||||
height: win.getSize()[1]
|
||||
}
|
||||
if (newWinSizePosition.x !== this.winSizePosition.x ||
|
||||
newWinSizePosition.y !== this.winSizePosition.y ||
|
||||
newWinSizePosition.width !== this.winSizePosition.width ||
|
||||
newWinSizePosition.height !== this.winSizePosition.height) {
|
||||
this.winSizePosition = newWinSizePosition
|
||||
setting.find().then(res => {
|
||||
res.windowSizePosition = newWinSizePosition
|
||||
setting.update(res)
|
||||
})
|
||||
appTheme: 'theme-light'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
@@ -124,6 +124,12 @@
|
||||
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;
|
||||
@@ -164,6 +170,9 @@
|
||||
&.note{
|
||||
width: 10%;
|
||||
}
|
||||
&.info{
|
||||
width: 10%;
|
||||
}
|
||||
&.operate{
|
||||
.btn{
|
||||
width: 40px;
|
||||
@@ -177,7 +186,7 @@
|
||||
// scroll
|
||||
.zy-scroll{
|
||||
&::-webkit-scrollbar{
|
||||
width: 5px;
|
||||
width: 10px;
|
||||
height: 1px;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
@@ -189,6 +198,87 @@
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
// Page of list using el-table
|
||||
.listpage{
|
||||
position: absolute;
|
||||
left: 80px;
|
||||
right: 20px;
|
||||
top: 40px;
|
||||
bottom: 20px;
|
||||
width: calc(100% - 100px);
|
||||
height: calc(100% - 60px);
|
||||
border-radius: 5px;
|
||||
.listpage-content{
|
||||
height: 100%;
|
||||
position: relative;
|
||||
font-size: 1rem;
|
||||
.listpage-header{
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
.el-button{
|
||||
font-size: 1rem;
|
||||
border: none;
|
||||
&:hover{
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.is-loading:before {
|
||||
background-color: none !important;
|
||||
}
|
||||
.el-input{
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
.listpage-body{
|
||||
height: calc(100% - 40px);
|
||||
overflow-y: auto;
|
||||
.el-table::before{
|
||||
height: 0px;
|
||||
}
|
||||
.el-table{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
font-size: 1rem;
|
||||
}
|
||||
.el-table__body-wrapper{
|
||||
&::-webkit-scrollbar{
|
||||
width: 10px;
|
||||
height: 1px;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
position: absolute;
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
border-radius: 10px;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
.el-input{
|
||||
width: 200px;
|
||||
}
|
||||
.el-table__body td,.el-table__body th{
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
.el-table--enable-row-hover .el-table__body tr:hover>td{
|
||||
transform: scale(1.02);
|
||||
}
|
||||
.el-table .highlight{
|
||||
color: var(--highlight-color) !important;
|
||||
}
|
||||
.el-button{
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// loading
|
||||
.zy-loading{
|
||||
width: 100%;
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
--p-c-9: #f4f7f799;
|
||||
--p-fc-1: #ffffff;
|
||||
--p-fc-2: #FFFFF3;
|
||||
--p-fc-3: #f15c5c;
|
||||
--p-fc-3: #177ea7;
|
||||
--p-bgc-1: #ff8499;
|
||||
--p-bgc-2: #fea1b2;
|
||||
--p-bsc: 0 1px 3px #ef528533, 0 1px 2px #ef528544;
|
||||
|
||||
@@ -62,7 +62,9 @@
|
||||
border-bottom-color: var(--d-c-2);
|
||||
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
|
||||
&:hover{
|
||||
box-shadow: var(--d-bsc-hover);
|
||||
box-shadow: var(--d-bsc);
|
||||
background-color: var(--d-bgc-2);
|
||||
color: #fff;
|
||||
}
|
||||
span{
|
||||
&.btn:hover{
|
||||
@@ -353,4 +355,72 @@
|
||||
background-color: var(--d-bgc-1);
|
||||
box-shadow: var(--d-bsc);
|
||||
}
|
||||
// Page of list using el-table
|
||||
.listpage{
|
||||
color: var(--d-fc-2);
|
||||
.listpage-content{
|
||||
.listpage-header{
|
||||
border-bottom-color: var(--d-c-3);
|
||||
.btn{
|
||||
&:hover{
|
||||
color: var(--d-fc-3)
|
||||
}
|
||||
}
|
||||
.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
.listpage-body{
|
||||
/* 设置el-table的样式*/
|
||||
.el-table{
|
||||
color: var(--d-fc-1);
|
||||
background-color: var(--d-bgc-1);
|
||||
}
|
||||
.el-input{
|
||||
input{
|
||||
background-color: var(--d-bgc-2);
|
||||
border: 1px solid var(--d-bgc-2);
|
||||
color: var(--d-fc-1);
|
||||
}
|
||||
}
|
||||
.el-table__header th, .el-table__header tr, .el-table__body td,.el-table__body th{
|
||||
color: var(--d-fc-1);
|
||||
background-color: var(--d-bgc-1);
|
||||
border-bottom-color: var(--d-c-2);
|
||||
}
|
||||
.el-table__body-wrapper{
|
||||
&:hover{
|
||||
&::-webkit-scrollbar-thumb {
|
||||
box-shadow: var(--d-bsc-scroll);
|
||||
background: var(--d-c-5);
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
box-shadow: var(--d-bsc-scroll);
|
||||
background: var(--d-bgc-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-table--enable-row-hover .el-table__body tr:hover>td{
|
||||
background-color: var(--d-bgc-2);
|
||||
}
|
||||
.el-button{
|
||||
color: var(--d-fc-1);
|
||||
&:hover{
|
||||
color: var(--d-fc-3)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@
|
||||
color: var(--g-fc-3);
|
||||
}
|
||||
&:hover{
|
||||
background-color: var(--d-c-3);
|
||||
background-color: var(--g-c-3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -351,4 +351,72 @@
|
||||
background-color: var(--g-bgc-1);
|
||||
box-shadow: var(--g-bsc);
|
||||
}
|
||||
// Page of list using el-table
|
||||
.listpage{
|
||||
color: var(--g-fc-2);
|
||||
.listpage-content{
|
||||
.listpage-header{
|
||||
border-bottom-color: var(--g-c-3);
|
||||
.btn{
|
||||
&:hover{
|
||||
color: var(--g-fc-3)
|
||||
}
|
||||
}
|
||||
.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
.listpage-body{
|
||||
/* 设置el-table的样式*/
|
||||
.el-table{
|
||||
color: var(--g-fc-1);
|
||||
background-color: var(--g-bgc-1);
|
||||
}
|
||||
.el-input{
|
||||
input{
|
||||
background-color: var(--g-bgc-2);
|
||||
border: 1px solid var(--g-bgc-2);
|
||||
color: var(--g-fc-1);
|
||||
}
|
||||
}
|
||||
.el-table__header th, .el-table__header tr, .el-table__body td,.el-table__body th{
|
||||
color: var(--g-fc-1);
|
||||
background-color: var(--g-bgc-1);
|
||||
border-bottom-color: var(--g-c-2);
|
||||
}
|
||||
.el-table__body-wrapper{
|
||||
&:hover{
|
||||
&::-webkit-scrollbar-thumb {
|
||||
box-shadow: var(--g-bsc-scroll);
|
||||
background: var(--g-c-5);
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
box-shadow: var(--g-bsc-scroll);
|
||||
background: var(--g-bgc-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-table--enable-row-hover .el-table__body tr:hover>td{
|
||||
background-color: var(--g-bgc-2);
|
||||
}
|
||||
.el-button{
|
||||
color: var(--g-fc-1);
|
||||
&:hover{
|
||||
color: var(--g-fc-3)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@
|
||||
color: var(--l-fc-3);
|
||||
}
|
||||
&:hover{
|
||||
background-color: var(--d-c-3);
|
||||
background-color: var(--l-c-3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -351,4 +351,72 @@
|
||||
background-color: var(--l-bgc-1);
|
||||
box-shadow: var(--l-bsc);
|
||||
}
|
||||
// Page of list using el-table
|
||||
.listpage{
|
||||
color: var(--l-fc-2);
|
||||
.listpage-content{
|
||||
.listpage-header{
|
||||
border-bottom-color: var(--l-c-3);
|
||||
.btn{
|
||||
&:hover{
|
||||
color: var(--l-fc-3)
|
||||
}
|
||||
}
|
||||
.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
.listpage-body{
|
||||
/* 设置el-table的样式*/
|
||||
.el-table{
|
||||
color: var(--l-fc-1);
|
||||
background-color: var(--l-bgc-1);
|
||||
}
|
||||
.el-input{
|
||||
input{
|
||||
background-color: var(--l-bgc-2);
|
||||
border: 1px solid var(--l-bgc-2);
|
||||
color: var(--l-fc-1);
|
||||
}
|
||||
}
|
||||
.el-table__header th, .el-table__header tr, .el-table__body td,.el-table__body th{
|
||||
color: var(--l-fc-1);
|
||||
background-color: var(--l-bgc-1);
|
||||
border-bottom-color: var(--l-c-2);
|
||||
}
|
||||
.el-table__body-wrapper{
|
||||
&:hover{
|
||||
&::-webkit-scrollbar-thumb {
|
||||
box-shadow: var(--l-bsc-scroll);
|
||||
background: var(--l-c-5);
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
box-shadow: var(--l-bsc-scroll);
|
||||
background: var(--l-bgc-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-table--enable-row-hover .el-table__body tr:hover>td{
|
||||
background-color: var(--l-bgc-2);
|
||||
}
|
||||
.el-button{
|
||||
color: var(--l-fc-1);
|
||||
&:hover{
|
||||
color: var(--l-fc-3)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@
|
||||
color: var(--p-fc-3);
|
||||
}
|
||||
&:hover{
|
||||
background-color: var(--d-c-3);
|
||||
background-color: var(--p-c-3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -350,4 +350,72 @@
|
||||
background-color: var(--p-bgc-1);
|
||||
box-shadow: var(--p-bsc);
|
||||
}
|
||||
// Page of list using el-table
|
||||
.listpage{
|
||||
color: var(--p-fc-2);
|
||||
.listpage-content{
|
||||
.listpage-header{
|
||||
border-bottom-color: var(--p-c-3);
|
||||
.btn{
|
||||
&:hover{
|
||||
color: var(--p-fc-3)
|
||||
}
|
||||
}
|
||||
.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
.listpage-body{
|
||||
/* 设置el-table的样式*/
|
||||
.el-table{
|
||||
color: var(--p-fc-1);
|
||||
background-color: var(--p-bgc-1);
|
||||
}
|
||||
.el-input{
|
||||
input{
|
||||
background-color: var(--p-bgc-2);
|
||||
border: 1px solid var(--p-bgc-2);
|
||||
color: var(--p-fc-1);
|
||||
}
|
||||
}
|
||||
.el-table__header th, .el-table__header tr, .el-table__body td,.el-table__body th{
|
||||
color: var(--p-fc-1);
|
||||
background-color: var(--p-bgc-1);
|
||||
border-bottom-color: var(--p-c-2);
|
||||
}
|
||||
.el-table__body-wrapper{
|
||||
&:hover{
|
||||
&::-webkit-scrollbar-thumb {
|
||||
box-shadow: var(--p-bsc-scroll);
|
||||
background: var(--p-c-5);
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
box-shadow: var(--p-bsc-scroll);
|
||||
background: var(--p-bgc-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-table--enable-row-hover .el-table__body tr:hover>td{
|
||||
background-color: var(--p-bgc-2);
|
||||
}
|
||||
.el-button{
|
||||
color: var(--p-fc-1);
|
||||
&:hover{
|
||||
color: var(--p-fc-3)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,11 @@ import './lib/site/server'
|
||||
import { app, protocol, BrowserWindow, globalShortcut, ipcMain } from 'electron'
|
||||
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
|
||||
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
|
||||
import { initUpdater } from './lib/update/update'
|
||||
const isDevelopment = process.env.NODE_ENV !== 'production'
|
||||
|
||||
// 允许跨域
|
||||
app.commandLine.appendSwitch('disable-features', 'OutOfBlinkCors')
|
||||
app.commandLine.appendSwitch('disable-features', 'OutOfBlinkCors') // 允许跨域
|
||||
app.commandLine.appendSwitch('--ignore-certificate-errors', 'true') // 忽略证书相关错误
|
||||
|
||||
let win
|
||||
let mini
|
||||
@@ -22,6 +23,7 @@ function createWindow () {
|
||||
resizable: true,
|
||||
webPreferences: {
|
||||
webSecurity: false,
|
||||
enableRemoteModule: true,
|
||||
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION
|
||||
}
|
||||
})
|
||||
@@ -34,6 +36,8 @@ function createWindow () {
|
||||
win.loadURL('app://./index.html')
|
||||
}
|
||||
|
||||
initUpdater(win)
|
||||
|
||||
win.on('closed', () => {
|
||||
win = null
|
||||
})
|
||||
@@ -48,7 +52,9 @@ function createMini () {
|
||||
frame: false,
|
||||
resizable: true,
|
||||
webPreferences: {
|
||||
sandbox: false,
|
||||
webSecurity: false,
|
||||
enableRemoteModule: true,
|
||||
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION
|
||||
}
|
||||
})
|
||||
@@ -71,6 +77,7 @@ if (process.platform === 'darwin') {
|
||||
}
|
||||
if (process.platform === 'Linux') {
|
||||
app.disableHardwareAcceleration()
|
||||
app.commandLine.appendSwitch('--no-sandbox') // linux 关闭沙盒模式
|
||||
}
|
||||
app.allowRendererProcessReuse = true
|
||||
|
||||
|
||||
@@ -69,29 +69,15 @@ export default {
|
||||
set (val) {
|
||||
this.SET_DETAIL(val)
|
||||
}
|
||||
},
|
||||
editSites: {
|
||||
get () {
|
||||
return this.$store.getters.getEditSites
|
||||
},
|
||||
set (val) {
|
||||
this.SET_EDITSITES(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_EDITSITES']),
|
||||
...mapMutations(['SET_VIEW', 'SET_DETAIL']),
|
||||
changeView (e) {
|
||||
this.view = e
|
||||
// ChangeView 的时候关闭Detail和EditSites页面
|
||||
this.detail = {
|
||||
show: false
|
||||
}
|
||||
if (this.editSites.show === true) {
|
||||
this.editSites = {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,14 @@
|
||||
<div class="detail-header">
|
||||
<span class="detail-title">详情</span>
|
||||
<span class="detail-close zy-svg" @click="close">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="closeIconTitle">
|
||||
<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>
|
||||
<path d="M6.34314575 6.34314575L17.6568542 17.6568542M6.34314575 17.6568542L17.6568542 6.34314575"></path>
|
||||
</svg>
|
||||
@@ -44,7 +51,8 @@
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
<div class="desc" v-show="info.des">{{info.des}}</div>
|
||||
<div
|
||||
class="desc" v-show="info.des">{{info.des}}</div>
|
||||
<div class="m3u8">
|
||||
<div class="box">
|
||||
<span v-for="(i, j) in m3u8List" :key="j" @click="playEvent(j)">{{i | ftName}}</span>
|
||||
@@ -72,7 +80,7 @@ export default {
|
||||
info: {},
|
||||
playOnline: false,
|
||||
selectedOnlineSite: '哔嘀',
|
||||
onlineSites: ['哔嘀', '素白白', '简影', '1080影视']
|
||||
onlineSites: ['哔嘀', '素白白', '简影', '极品', '喜欢看', '1080影视']
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
@@ -133,59 +141,56 @@ export default {
|
||||
this.m3u8List = dd._t.split('#')
|
||||
}
|
||||
},
|
||||
playEvent (n) {
|
||||
async playEvent (n) {
|
||||
if (!this.playOnline) {
|
||||
history.find({ site: this.detail.key, ids: this.detail.info.id }).then(res => {
|
||||
if (res) {
|
||||
this.video = { key: res.site, info: { id: res.ids, name: res.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 } }
|
||||
}
|
||||
})
|
||||
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.view = 'Play'
|
||||
this.detail.show = false
|
||||
} else {
|
||||
history.find({ site: this.detail.key, ids: this.detail.info.id }).then(res => {
|
||||
if (res) {
|
||||
res.index = n
|
||||
history.update(res.id, res)
|
||||
} else {
|
||||
const doc = {
|
||||
site: this.detail.key,
|
||||
ids: this.detail.info.id,
|
||||
name: this.detail.info.name,
|
||||
type: this.detail.info.type,
|
||||
year: this.detail.info.year,
|
||||
index: n,
|
||||
time: ''
|
||||
}
|
||||
history.add(doc)
|
||||
const db = await history.find({ site: this.detail.key, ids: this.detail.info.id })
|
||||
if (db) {
|
||||
db.index = n
|
||||
history.update(db.id, db)
|
||||
} else {
|
||||
const doc = {
|
||||
site: this.detail.key,
|
||||
ids: this.detail.info.id,
|
||||
name: this.detail.info.name,
|
||||
type: this.detail.info.type,
|
||||
year: this.detail.info.year,
|
||||
index: n,
|
||||
time: ''
|
||||
}
|
||||
})
|
||||
this.playVideoOnline(this.detail.info.name, n)
|
||||
history.add(doc)
|
||||
}
|
||||
onlineVideo.playVideoOnline(this.selectedOnlineSite, this.detail.info.name, n)
|
||||
}
|
||||
},
|
||||
starEvent () {
|
||||
star.find({ key: this.detail.key, ids: this.info.id }).then(res => {
|
||||
if (res) {
|
||||
this.$message.info('该影片已被收藏')
|
||||
} else {
|
||||
const docs = {
|
||||
key: this.detail.key,
|
||||
ids: this.info.id,
|
||||
name: this.info.name,
|
||||
type: this.info.type,
|
||||
year: this.info.year,
|
||||
last: this.info.last,
|
||||
note: this.info.note
|
||||
}
|
||||
star.add(docs).then(res => {
|
||||
this.$message.success('收藏成功')
|
||||
})
|
||||
async starEvent () {
|
||||
const db = await star.find({ key: this.detail.key, ids: this.info.id })
|
||||
if (db) {
|
||||
this.$message.info('该影片已被收藏')
|
||||
} else {
|
||||
const docs = {
|
||||
key: this.detail.key,
|
||||
ids: this.info.id,
|
||||
site: this.detail.site,
|
||||
name: this.info.name,
|
||||
type: this.info.type,
|
||||
year: this.info.year,
|
||||
note: this.info.note,
|
||||
last: this.info.last
|
||||
|
||||
}
|
||||
}).catch(() => {
|
||||
this.$message.warning('收藏失败')
|
||||
})
|
||||
star.add(docs).then(res => {
|
||||
this.$message.success('收藏成功')
|
||||
})
|
||||
}
|
||||
},
|
||||
togglePlayOnlineEvent () {
|
||||
this.playOnline = !this.playOnline
|
||||
@@ -210,6 +215,9 @@ export default {
|
||||
case '简影':
|
||||
onlineVideo.playVideoOnSyrme(videoName, videoIndex)
|
||||
break
|
||||
case '极品':
|
||||
onlineVideo.playVideoOnJpysvip(videoName, videoIndex)
|
||||
break
|
||||
default:
|
||||
this.$message.console.error(`不支持该网站:${this.selectedOnlineSite}`)
|
||||
}
|
||||
@@ -326,7 +334,7 @@ export default {
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.detail{
|
||||
.detail {
|
||||
position: absolute;
|
||||
left: 80px;
|
||||
right: 20px;
|
||||
@@ -334,28 +342,28 @@ export default {
|
||||
width: calc(100% - 100px);
|
||||
height: calc(100% - 40px);
|
||||
z-index: 888;
|
||||
.detail-content{
|
||||
.detail-content {
|
||||
height: calc(100% - 10px);
|
||||
padding: 0 60px;
|
||||
position: relative;
|
||||
.detail-header{
|
||||
.detail-header {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
.detail-title{
|
||||
.detail-title {
|
||||
font-size: 16px;
|
||||
}
|
||||
.detail-close{
|
||||
.detail-close {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
.detail-body{
|
||||
.detail-body {
|
||||
height: calc(100% - 50px);
|
||||
overflow-y: auto;
|
||||
.info{
|
||||
.info {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
@@ -366,47 +374,54 @@ export default {
|
||||
border-radius: 2px;
|
||||
margin-bottom: 10px;
|
||||
height: auto;
|
||||
.info-left{
|
||||
.info-left {
|
||||
width: 200px;
|
||||
height: 100%;
|
||||
img{
|
||||
img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
.info-right{
|
||||
.info-right {
|
||||
flex: 1;
|
||||
margin-left: 20px;
|
||||
.name{
|
||||
.name {
|
||||
font-size: 20px;
|
||||
margin-bottom: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.director, .actor, .type, .area, .lang, .year, .last, .note{
|
||||
.director,
|
||||
.actor,
|
||||
.type,
|
||||
.area,
|
||||
.lang,
|
||||
.year,
|
||||
.last,
|
||||
.note {
|
||||
font-size: 14px;
|
||||
line-height: 26px;
|
||||
}
|
||||
.rate{
|
||||
.rate {
|
||||
font-size: 16px;
|
||||
line-height: 26px;
|
||||
font-weight: bolder;
|
||||
}
|
||||
}
|
||||
}
|
||||
.operate{
|
||||
.operate {
|
||||
border: 1px solid;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 2px;
|
||||
span{
|
||||
span {
|
||||
margin-right: 20px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
.desc{
|
||||
.desc {
|
||||
border: 1px solid;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
@@ -415,15 +430,15 @@ export default {
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.m3u8{
|
||||
.m3u8 {
|
||||
border: 1px solid;
|
||||
padding: 10px 0 10px 10px;
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 2px;
|
||||
.box{
|
||||
.box {
|
||||
width: 100%;
|
||||
span{
|
||||
span {
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
border: 1px solid;
|
||||
@@ -435,7 +450,7 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
.detail-mask{
|
||||
.detail-mask {
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
left: 0;
|
||||
@@ -457,28 +472,37 @@ export default {
|
||||
@keyframes load4 {
|
||||
0%,
|
||||
100% {
|
||||
box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
|
||||
box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em,
|
||||
0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
|
||||
}
|
||||
12.5% {
|
||||
box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
|
||||
box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em,
|
||||
0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
25% {
|
||||
box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
|
||||
box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0,
|
||||
0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
37.5% {
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em, 0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em,
|
||||
0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em, 0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em,
|
||||
0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
62.5% {
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em,
|
||||
0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
|
||||
}
|
||||
75% {
|
||||
box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0;
|
||||
box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em,
|
||||
2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em,
|
||||
-2em -2em 0 0;
|
||||
}
|
||||
87.5% {
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,100 +1,157 @@
|
||||
<template>
|
||||
<div class="detail">
|
||||
<div class="detail-content">
|
||||
<div class="detail-header">
|
||||
<div class="zy-select">
|
||||
<div class="vs-placeholder vs-noAfter" @click="openAddSite">添加新源</div>
|
||||
</div>
|
||||
<div class="zy-select">
|
||||
<div class="vs-placeholder vs-noAfter" @click="exportSites">导出</div>
|
||||
</div>
|
||||
<div class="zy-select">
|
||||
<div class="vs-placeholder vs-noAfter" @click="importSites">导入</div>
|
||||
</div>
|
||||
<div class="zy-select">
|
||||
<div class="vs-placeholder vs-noAfter" @click="resetSites">重置</div>
|
||||
</div>
|
||||
<span class="detail-close zy-svg" @click="close">
|
||||
<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>
|
||||
<path d="M6.34314575 6.34314575L17.6568542 17.6568542M6.34314575 17.6568542L17.6568542 6.34314575"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<div class="listpage" id="editSites">
|
||||
<div class="listpage-content">
|
||||
<div class="listpage-header" v-show="!enableBatchEdit">
|
||||
<el-switch v-model="enableBatchEdit" active-text="批处理分组">></el-switch>
|
||||
<el-button @click="addSite" icon="el-icon-document-add">新增</el-button>
|
||||
<el-button @click="exportSites" icon="el-icon-upload2" >导出</el-button>
|
||||
<el-button @click="importSites" icon="el-icon-download">导入</el-button>
|
||||
<el-button @click="checkAllSite" icon="el-icon-refresh" :loading="checkAllSiteLoading">检测</el-button>
|
||||
<el-button @click="removeAllSites" icon="el-icon-delete-solid">清空</el-button>
|
||||
<el-button @click="resetSitesEvent" icon="el-icon-refresh-left">重置</el-button>
|
||||
</div>
|
||||
<div class="detail-body zy-scroll">
|
||||
<div class="zy-table">
|
||||
<div class="tBody zy-scroll">
|
||||
<div class="addSites-box zy-scroll" v-show="showAddSite">
|
||||
<ul>
|
||||
<li >
|
||||
<span class="name">源名称</span>
|
||||
<span class="name">API接口</span>
|
||||
<span class="name">DOWNLOAD接口</span>
|
||||
<span class="operate">
|
||||
<span class="btn"></span>
|
||||
<span class="btn"></span>
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<span class="name" style="display:inline-block;vertical-align:middle">
|
||||
<input style="height: 30px" v-model="newSite.name">
|
||||
</span>
|
||||
<span class="name" style="display:inline-block;vertical-align:middle">
|
||||
<input style="height: 30px" v-model="newSite.api">
|
||||
</span>
|
||||
<span class="name" style="display:inline-block;vertical-align:middle">
|
||||
<input style="height: 30px" v-model="newSite.download" placeholder="可以为空">
|
||||
</span>
|
||||
<span class="operate">
|
||||
<span class="btn" @click="addNewSite">添加</span>
|
||||
<span class="btn" @click="closeAddSite">关闭</span>
|
||||
</span>
|
||||
</li>
|
||||
<li ></li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul>
|
||||
<draggable v-model="sites" @change="listUpdatedEvent">
|
||||
<transition-group>
|
||||
<li v-for="(i, j) in sites" :key="j">
|
||||
<span class="name">{{i.name}}</span>
|
||||
<span class="operate">
|
||||
<span class="btn" @click.stop="removeEvent(i)">删除</span>
|
||||
</span>
|
||||
</li>
|
||||
</transition-group>
|
||||
</draggable>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="listpage-header" v-show="enableBatchEdit">
|
||||
<el-switch v-model="enableBatchEdit" active-text="批处理分组"></el-switch>
|
||||
<el-input placeholder="新组名" v-model="batchGroupName"></el-input>
|
||||
<el-switch v-model="batchIsActive" :active-value="1" :inactive-value="0" active-text="自选源"></el-switch>
|
||||
<el-button type="primary" icon="el-icon-edit" @click.stop="saveBatchEdit">保存</el-button>
|
||||
</div>
|
||||
<div class="listpage-body" id="sites-table">
|
||||
<el-table
|
||||
ref="editSitesTable"
|
||||
size="mini" fit height="100%" row-key="id"
|
||||
:data="sites"
|
||||
:key="tableKey"
|
||||
@selection-change="handleSelectionChange"
|
||||
@sort-change="handleSortChange">
|
||||
<el-table-column
|
||||
type="selection"
|
||||
v-if="enableBatchEdit">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
label="资源名">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="isActive"
|
||||
label="自选源">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.isActive"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
@change='isActiveChangeEvent'>
|
||||
</el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="group"
|
||||
label="分组"
|
||||
:filters="getFilters"
|
||||
:filter-method="filterHandle"
|
||||
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="状态" width="120">
|
||||
<template slot-scope="scope">
|
||||
<span v-show="scope.row.status === ''">
|
||||
<i class="el-icon-loading"></i>
|
||||
检测中...
|
||||
</span>
|
||||
<span v-show="scope.row.status !== ''">{{scope.row.status}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
header-align="right"
|
||||
align="right">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" @click.stop="moveToTopEvent(scope.row)" type="text">置顶</el-button>
|
||||
<el-button size="mini" @click.stop="editSite(scope.row)" type="text">编辑</el-button>
|
||||
<el-button size="mini" @click.stop="removeEvent(scope.row)" type="text">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<!-- 编辑页面 -->
|
||||
<div>
|
||||
<el-dialog :visible.sync="dialogVisible" v-if='dialogVisible' :title="dialogType==='edit'?'编辑源':'新增源'" :append-to-body="true" @close="closeDialog">
|
||||
<el-form :model="siteInfo" ref='siteInfo' label-width="75px" label-position="left" :rules="rules">
|
||||
<el-form-item label="源站名" prop='name'>
|
||||
<el-input v-model="siteInfo.name" placeholder="请输入源站名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="API接口" prop='api'>
|
||||
<el-input v-model="siteInfo.api" :autosize="{ minRows: 2, maxRows: 4}" type="textarea" placeholder="请输入API接口地址"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="下载接口" prop='download'>
|
||||
<el-input v-model="siteInfo.download" :autosize="{ minRows: 2, maxRows: 4}" type="textarea" placeholder="请输入Download接口地址,可以空着"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="分组" prop='group'>
|
||||
<el-select v-model="siteInfo.group" allow-create filterable default-first-option placeholder="请输入分组">
|
||||
<el-option v-for="item in siteGroup" :key="item" :label="item" :value="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="源站标识" prop='key'>
|
||||
<el-input v-model="siteInfo.key" placeholder="请输入源站标识,如果为空,系统则自动生成" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="closeDialog">取消</el-button>
|
||||
<el-button type="primary" @click="addOrEditSite">保存</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import { sites, setting } from '../lib/dexie'
|
||||
import draggable from 'vuedraggable'
|
||||
import { sites } from '../lib/dexie'
|
||||
import zy from '../lib/site/tools'
|
||||
import { remote } from 'electron'
|
||||
import { sites as defaultSites } from '../lib/dexie/initData'
|
||||
import fs from 'fs'
|
||||
import Sortable from 'sortablejs'
|
||||
|
||||
export default {
|
||||
name: 'editSites',
|
||||
data () {
|
||||
return {
|
||||
show: false,
|
||||
sites: [],
|
||||
showAddSite: false,
|
||||
newSite: {
|
||||
dialogType: 'new',
|
||||
dialogVisible: false,
|
||||
siteInfo: {
|
||||
key: '',
|
||||
name: '',
|
||||
api: '',
|
||||
download: ''
|
||||
}
|
||||
download: '',
|
||||
group: '',
|
||||
isActive: 1
|
||||
},
|
||||
siteGroup: [],
|
||||
rules: {
|
||||
name: [
|
||||
{ required: true, message: '源站名不能为空', trigger: 'blur' }
|
||||
],
|
||||
api: [
|
||||
{ required: true, message: 'API地址不能为空', trigger: 'blur' }
|
||||
],
|
||||
download: [
|
||||
{ required: false, trigger: 'blur' }
|
||||
]
|
||||
},
|
||||
enableBatchEdit: false,
|
||||
batchGroupName: '',
|
||||
batchIsActive: 1,
|
||||
multipleSelection: [],
|
||||
tableKey: 1,
|
||||
checkAllSiteLoading: false,
|
||||
editeOldkey: ''
|
||||
}
|
||||
},
|
||||
components: {
|
||||
draggable
|
||||
},
|
||||
computed: {
|
||||
setting: {
|
||||
get () {
|
||||
@@ -111,19 +168,93 @@ export default {
|
||||
set (val) {
|
||||
this.SET_EDITSITES(val)
|
||||
}
|
||||
},
|
||||
getFilters () {
|
||||
const groups = [...new Set(this.sites.map(site => site.group))]
|
||||
var filters = []
|
||||
groups.forEach(g => {
|
||||
var doc = {
|
||||
text: g,
|
||||
value: g
|
||||
}
|
||||
filters.push(doc)
|
||||
})
|
||||
return filters
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_SETTING', 'SET_EDITSITES']),
|
||||
close () {
|
||||
this.editSites.show = false
|
||||
filterHandle (value, row) {
|
||||
return row.group === value
|
||||
},
|
||||
handleSelectionChange (rows) {
|
||||
this.multipleSelection = rows
|
||||
},
|
||||
handleSortChange (column, prop, order) {
|
||||
this.updateDatabase(this.sites)
|
||||
},
|
||||
saveBatchEdit () {
|
||||
this.multipleSelection.forEach(ele => {
|
||||
if (this.batchGroupName) {
|
||||
ele.group = this.batchGroupName
|
||||
}
|
||||
ele.isActive = this.batchIsActive
|
||||
})
|
||||
this.updateDatabase()
|
||||
},
|
||||
getSites () {
|
||||
sites.all().then(res => {
|
||||
this.sites = res
|
||||
this.editSites = {
|
||||
sites: res
|
||||
}
|
||||
})
|
||||
for (const i of this.sites) {
|
||||
delete i.status
|
||||
}
|
||||
},
|
||||
getSitesGroup () {
|
||||
const arr = []
|
||||
for (const i of this.sites) {
|
||||
if (arr.indexOf(i.group) < 0) {
|
||||
arr.push(i.group)
|
||||
}
|
||||
}
|
||||
this.siteGroup = arr
|
||||
},
|
||||
addSite () {
|
||||
this.getSitesGroup()
|
||||
this.dialogType = 'new'
|
||||
this.dialogVisible = true
|
||||
this.siteInfo = {
|
||||
key: '',
|
||||
name: '',
|
||||
api: '',
|
||||
download: '',
|
||||
group: '',
|
||||
isActive: 1
|
||||
}
|
||||
},
|
||||
editSite (siteInfo) {
|
||||
this.getSitesGroup()
|
||||
if (this.checkAllSiteLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
return false
|
||||
}
|
||||
this.dialogType = 'edit'
|
||||
this.dialogVisible = true
|
||||
this.siteInfo = siteInfo
|
||||
this.editeOldkey = siteInfo.key
|
||||
},
|
||||
closeDialog () {
|
||||
this.dialogVisible = false
|
||||
this.getSites()
|
||||
},
|
||||
removeEvent (e) {
|
||||
if (this.checkAllSiteLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
return false
|
||||
}
|
||||
sites.remove(e.id).then(res => {
|
||||
this.getSites()
|
||||
}).catch(err => {
|
||||
@@ -141,39 +272,56 @@ export default {
|
||||
})
|
||||
})
|
||||
},
|
||||
openAddSite () {
|
||||
this.showAddSite = true
|
||||
checkSiteKey (e) {
|
||||
if (this.dialogType === 'edit' && this.editeOldkey === this.siteInfo.key) {
|
||||
return true
|
||||
} else {
|
||||
for (const i of this.sites) {
|
||||
if (i.key === this.siteInfo.key) {
|
||||
this.$message.warning(`源站标识: ${i.key} 已存在, 请勿重复填写.`)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
},
|
||||
closeAddSite () {
|
||||
this.showAddSite = false
|
||||
},
|
||||
addNewSite () {
|
||||
if (!this.newSite.name || !this.newSite.api) {
|
||||
addOrEditSite () {
|
||||
if (!this.siteInfo.name || !this.siteInfo.api) {
|
||||
this.$message.error('名称和API接口不能为空。')
|
||||
return
|
||||
return false
|
||||
}
|
||||
if (!this.checkSiteKey()) {
|
||||
return false
|
||||
}
|
||||
var randomstring = require('randomstring')
|
||||
var doc = {
|
||||
key: randomstring.generate(6),
|
||||
id: this.sites[this.sites.length - 1].id + 1,
|
||||
name: this.newSite.name,
|
||||
api: this.newSite.api,
|
||||
download: this.newSite.download
|
||||
key: this.dialogType === 'edit' ? this.siteInfo.key : this.siteInfo.key ? this.siteInfo.key : randomstring.generate(6),
|
||||
id: this.dialogType === 'edit' ? this.siteInfo.id : this.sites[this.sites.length - 1].id + 1,
|
||||
name: this.siteInfo.name,
|
||||
api: this.siteInfo.api,
|
||||
download: this.siteInfo.download,
|
||||
group: this.siteInfo.group,
|
||||
isActive: this.siteInfo.isActive
|
||||
}
|
||||
if (this.dialogType === 'edit') sites.remove(this.siteInfo.id)
|
||||
sites.add(doc).then(res => {
|
||||
this.newSite = {
|
||||
this.siteInfo = {
|
||||
key: '',
|
||||
name: '',
|
||||
api: '',
|
||||
download: ''
|
||||
download: '',
|
||||
group: ''
|
||||
}
|
||||
this.$message.success('添加新源成功!')
|
||||
this.dialogType === 'edit' ? this.$message.success('修改成功!') : this.$message.success('新增源成功!')
|
||||
this.dialogVisible = false
|
||||
this.getSites()
|
||||
})
|
||||
this.editeOldkey = ''
|
||||
},
|
||||
exportSites () {
|
||||
this.getSites()
|
||||
const arr = [...this.sites]
|
||||
const str = JSON.stringify(arr, null, 4)
|
||||
const str = JSON.stringify(arr, null, 2)
|
||||
const options = {
|
||||
filters: [
|
||||
{ name: 'JSON file', extensions: ['json'] },
|
||||
@@ -197,72 +345,109 @@ export default {
|
||||
{ name: 'Normal text file', extensions: ['txt'] },
|
||||
{ name: 'All types', extensions: ['*'] }
|
||||
],
|
||||
properties: ['openFile']
|
||||
properties: ['openFile', 'multiSelections']
|
||||
}
|
||||
remote.dialog.showOpenDialog(options).then(result => {
|
||||
if (!result.canceled) {
|
||||
sites.clear()
|
||||
result.filePaths.forEach(file => {
|
||||
var str = fs.readFileSync(file)
|
||||
const json = JSON.parse(str)
|
||||
sites.bulkAdd(json).then(e => {
|
||||
this.getSites()
|
||||
this.d.site = json[0].key
|
||||
setting.update(this.d).then(res => {
|
||||
this.setting = this.d
|
||||
})
|
||||
json.forEach(ele => {
|
||||
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
|
||||
}
|
||||
if (ele.group === undefined) {
|
||||
ele.group = '导入'
|
||||
}
|
||||
this.sites.push(ele)
|
||||
}
|
||||
})
|
||||
this.resetId(this.sites)
|
||||
sites.clear().then(sites.bulkAdd(this.sites))
|
||||
this.$message.success('导入成功')
|
||||
}).catch(err => {
|
||||
this.$message.error(err)
|
||||
this.getSites()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
resetSites () {
|
||||
sites.clear()
|
||||
sites.bulkAdd(defaultSites).then(e => {
|
||||
this.getSites()
|
||||
this.$message.success('重置源成功')
|
||||
resetSitesEvent () {
|
||||
sites.clear().then(sites.bulkAdd(defaultSites).then(this.getSites()))
|
||||
this.$message.success('重置源成功')
|
||||
},
|
||||
moveToTopEvent (i) {
|
||||
if (this.checkAllSiteLoading) {
|
||||
this.$message.info('正在检测, 请勿操作.')
|
||||
return false
|
||||
}
|
||||
this.sites.sort(function (x, y) { return x.key === i.key ? -1 : y.key === i.key ? 1 : 0 })
|
||||
this.updateDatabase()
|
||||
},
|
||||
syncTableData () {
|
||||
if (this.$refs.editSitesTable.tableData && this.$refs.editSitesTable.tableData.length === this.sites.length) {
|
||||
this.sites = this.$refs.editSitesTable.tableData
|
||||
}
|
||||
},
|
||||
isActiveChangeEvent (row) {
|
||||
this.updateDatabase()
|
||||
},
|
||||
resetId (inArray) {
|
||||
var id = 1
|
||||
inArray.forEach(ele => {
|
||||
ele.id = id
|
||||
id += 1
|
||||
})
|
||||
},
|
||||
updateDatabase () {
|
||||
// 因为el-table的数据是单向绑定,我们先同步el-table里的数据和其绑定的数据
|
||||
this.syncTableData()
|
||||
sites.clear().then(res => {
|
||||
var id = 1
|
||||
this.sites.forEach(ele => {
|
||||
ele.id = id
|
||||
id += 1
|
||||
})
|
||||
sites.bulkAdd(this.sites).then(this.getSites())
|
||||
})
|
||||
},
|
||||
removeAllSites () {
|
||||
sites.clear().then(this.getSites())
|
||||
},
|
||||
rowDrop () {
|
||||
const tbody = document.getElementById('sites-table').querySelector('.el-table__body-wrapper tbody')
|
||||
var _this = this
|
||||
Sortable.create(tbody, {
|
||||
onEnd ({ newIndex, oldIndex }) {
|
||||
const currRow = _this.sites.splice(oldIndex, 1)[0]
|
||||
_this.sites.splice(newIndex, 0, currRow)
|
||||
_this.updateDatabase()
|
||||
}
|
||||
})
|
||||
},
|
||||
async checkAllSite () {
|
||||
this.checkAllSiteLoading = true
|
||||
for (const i of this.sites) {
|
||||
i.status = ''
|
||||
this.tableKey = Math.random()
|
||||
const flag = await zy.check(i.key)
|
||||
if (flag) {
|
||||
i.status = '可用'
|
||||
} else {
|
||||
i.status = '失效'
|
||||
i.isActive = 0
|
||||
}
|
||||
this.tableKey = Math.random()
|
||||
}
|
||||
this.checkAllSiteLoading = false
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.rowDrop()
|
||||
this.checkAllSiteLoading = false
|
||||
},
|
||||
created () {
|
||||
this.getSites()
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.detail{
|
||||
position: absolute;
|
||||
left: 80px;
|
||||
right: 20px;
|
||||
bottom: 0;
|
||||
width: calc(100% - 100px);
|
||||
height: calc(100% - 40px);
|
||||
z-index: 888;
|
||||
.detail-content{
|
||||
height: calc(100% - 10px);
|
||||
padding: 0 60px;
|
||||
position: relative;
|
||||
.detail-header{
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
.detail-title{
|
||||
font-size: 16px;
|
||||
}
|
||||
.detail-close{
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
.detail-body{
|
||||
height: calc(100% - 50px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<div class="vs-placeholder" @click="show.classList = true">{{type.name}}</div>
|
||||
<div class="vs-options" v-show="show.classList">
|
||||
<ul class="zy-scroll" style="max-height: 600px;">
|
||||
<li :class="type.tid === i.tid ? 'active' : ''" v-for="i in classList" :key="i.tid" @click="classClick(i)">{{ i.name }}</li>
|
||||
<li :class="type.tid === i.tid ? 'active' : ''" v-for="i in classList" :key="i.tid" @click="classClick(i)">{{ i.name | classNameFilter }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -65,7 +65,7 @@
|
||||
<span class="name">{{i.name}}</span>
|
||||
<span class="type">{{i.type}}</span>
|
||||
<span class="time">{{i.year}}</span>
|
||||
<span class="time">{{i.note}}</span>
|
||||
<span class="note">{{i.note}}</span>
|
||||
<span class="last">{{i.last}}</span>
|
||||
<span class="operate">
|
||||
<span class="btn" @click.stop="playEvent(site, i)">播放</span>
|
||||
@@ -75,7 +75,7 @@
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<infinite-loading force-use-infinite-wrapper="tBody" :identifier="infiniteId" @infinite="infiniteHandler"></infinite-loading>
|
||||
<infinite-loading force-use-infinite-wrapper :identifier="infiniteId" @infinite="infiniteHandler"></infinite-loading>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -87,10 +87,13 @@
|
||||
<ul>
|
||||
<li v-for="(i, j) in searchContents" :key="j" @click="detailEvent(i.site, i)">
|
||||
<span class="name">{{i.name}}</span>
|
||||
<span class="type">{{i.type}}</span>
|
||||
<span class="last">{{i.last}}</span>
|
||||
<span class="site">{{i.site.name}}</span>
|
||||
<span class="note">{{i.note}}</span>
|
||||
<span class="info">{{i.site.name}}</span>
|
||||
<span class="info">{{i.director}}</span>
|
||||
<span class="info">{{i.type}}</span>
|
||||
<span class="info">{{i.area}}</span>
|
||||
<span class="info">{{i.lang}}</span>
|
||||
<span class="info">{{i.year}}</span>
|
||||
<span class="info">{{i.note}}</span>
|
||||
<span class="operate">
|
||||
<span class="btn" @click.stop="playEvent(i.site, i)">播放</span>
|
||||
<span class="btn" @click.stop="starEvent(i.site, i)">收藏</span>
|
||||
@@ -123,8 +126,6 @@ export default {
|
||||
class: false,
|
||||
classList: false,
|
||||
search: false,
|
||||
img: true,
|
||||
table: false,
|
||||
find: false
|
||||
},
|
||||
sites: [],
|
||||
@@ -138,7 +139,7 @@ export default {
|
||||
searchTxt: '',
|
||||
searchContents: [],
|
||||
// 福利片关键词
|
||||
r18KeyWords: ['伦理', '倫理', '福利', '激情', '理论', '写真', '情色', '美女', '街拍', '赤足', '性感', '里番']
|
||||
r18KeyWords: ['伦理', '论理', '倫理', '福利', '激情', '理论', '写真', '情色', '美女', '街拍', '赤足', '性感', '里番']
|
||||
}
|
||||
},
|
||||
components: {
|
||||
@@ -180,6 +181,14 @@ export default {
|
||||
},
|
||||
setting () {
|
||||
return this.$store.getters.getSetting
|
||||
},
|
||||
sitesList () {
|
||||
return this.$store.getters.getEditSites.sites // 需要监听的数据
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
classNameFilter: (name) => {
|
||||
return name.replace(/[^\u4e00-\u9fa5]/gi, '')
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -189,7 +198,7 @@ export default {
|
||||
searchTxt () {
|
||||
this.searchChangeEvent()
|
||||
},
|
||||
'$store.state.editSites.sites': function () {
|
||||
sitesList () {
|
||||
this.getAllsites()
|
||||
}
|
||||
},
|
||||
@@ -308,37 +317,34 @@ export default {
|
||||
info: e
|
||||
}
|
||||
},
|
||||
playEvent (site, e) {
|
||||
history.find({ site: site.key, ids: e.id }).then(res => {
|
||||
if (res) {
|
||||
this.video = { key: res.site, info: { id: res.ids, name: res.name, index: res.index, site: site } }
|
||||
} else {
|
||||
this.video = { key: site.key, info: { id: e.id, name: e.name, index: 0, site: site } }
|
||||
}
|
||||
})
|
||||
async playEvent (site, e) {
|
||||
const db = await history.find({ site: site.key, ids: e.id })
|
||||
if (db) {
|
||||
this.video = { key: db.site, info: { id: db.ids, name: db.name, index: db.index, site: site } }
|
||||
} else {
|
||||
this.video = { key: site.key, info: { id: e.id, name: e.name, index: 0, site: site } }
|
||||
}
|
||||
this.view = 'Play'
|
||||
},
|
||||
starEvent (site, e) {
|
||||
star.find({ key: site.key, ids: e.id }).then(res => {
|
||||
if (res) {
|
||||
this.$message.info('已存在')
|
||||
} else {
|
||||
const docs = {
|
||||
key: site.key,
|
||||
ids: e.id,
|
||||
name: e.name,
|
||||
type: e.type,
|
||||
year: e.year,
|
||||
last: e.last,
|
||||
note: e.note
|
||||
}
|
||||
star.add(docs).then(res => {
|
||||
this.$message.success('收藏成功')
|
||||
})
|
||||
async starEvent (site, e) {
|
||||
const db = await star.find({ key: site.key, ids: e.id })
|
||||
if (db) {
|
||||
this.$message.info('已存在')
|
||||
} else {
|
||||
const docs = {
|
||||
key: site.key,
|
||||
ids: e.id,
|
||||
site: site,
|
||||
name: e.name,
|
||||
type: e.type,
|
||||
year: e.year,
|
||||
last: e.last,
|
||||
note: e.note
|
||||
}
|
||||
}).catch(() => {
|
||||
this.$message.warning('收藏失败')
|
||||
})
|
||||
star.add(docs).then(res => {
|
||||
this.$message.success('收藏成功')
|
||||
})
|
||||
}
|
||||
},
|
||||
shareEvent (site, e) {
|
||||
this.share = {
|
||||
@@ -388,13 +394,11 @@ export default {
|
||||
},
|
||||
changeView () {
|
||||
if (this.view === 'Film') {
|
||||
if (this.show.img) {
|
||||
if (this.setting.view === 'picture') {
|
||||
this.$refs.waterfall.refresh()
|
||||
}
|
||||
this.getPage().then(() => {
|
||||
this.infiniteId += 1
|
||||
if (this.show.img || this.show.table) {
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
@@ -403,6 +407,13 @@ export default {
|
||||
this.searchList = res.reverse()
|
||||
})
|
||||
},
|
||||
searchEvent (wd) {
|
||||
if (this.setting.searchAllSites) {
|
||||
this.searchAllSitesEvent(this.sites, wd)
|
||||
} else {
|
||||
this.searchSingleSiteEvent(this.site, wd)
|
||||
}
|
||||
},
|
||||
searchAllSitesEvent (sites, wd) {
|
||||
this.searchTxt = wd
|
||||
this.searchContents = []
|
||||
@@ -421,13 +432,17 @@ export default {
|
||||
const type = Object.prototype.toString.call(res)
|
||||
if (type === '[object Array]') {
|
||||
res.forEach(element => {
|
||||
element.site = site
|
||||
this.searchContents.push(element)
|
||||
zy.detail(site.key, element.id).then(detailRes => {
|
||||
detailRes.site = site
|
||||
this.searchContents.push(detailRes)
|
||||
})
|
||||
})
|
||||
}
|
||||
if (type === '[object Object]') {
|
||||
res.site = site
|
||||
this.searchContents.push(res)
|
||||
zy.detail(site.key, res.id).then(detailRes => {
|
||||
detailRes.site = site
|
||||
this.searchContents.push(detailRes)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -440,13 +455,6 @@ export default {
|
||||
})
|
||||
}
|
||||
},
|
||||
searchEvent (wd) {
|
||||
if (this.setting.searchAllSites) {
|
||||
this.searchAllSitesEvent(this.sites, wd)
|
||||
} else {
|
||||
this.searchSingleSiteEvent(this.site, wd)
|
||||
}
|
||||
},
|
||||
searchSingleSiteEvent (site, wd) {
|
||||
var sites = []
|
||||
sites.push(this.site)
|
||||
@@ -464,21 +472,28 @@ export default {
|
||||
this.show.class = true
|
||||
this.searchContents = []
|
||||
this.show.find = false
|
||||
if (this.show.img) {
|
||||
if (this.setting.view === 'picture') {
|
||||
this.$refs.waterfall.refresh()
|
||||
}
|
||||
}
|
||||
},
|
||||
getAllsites () {
|
||||
sites.all().then(res => {
|
||||
this.sites = res
|
||||
this.site = this.sites[0]
|
||||
this.siteClick(this.site)
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.getAllsites()
|
||||
this.getAllSearch()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +1,45 @@
|
||||
<template>
|
||||
<div class="history">
|
||||
<div class="body zy-scroll">
|
||||
<div class="zy-table">
|
||||
<div class="tHeader">
|
||||
<span class="btn"></span>
|
||||
<span class="btn" @click="clearAllHistory">清空</span>
|
||||
</div>
|
||||
<div class="tBody zy-scroll">
|
||||
<ul>
|
||||
<li v-show="this.history.length === 0">无数据</li>
|
||||
<li v-show="this.history.length > 0">
|
||||
<span class="name">名字</span>
|
||||
<span class="site">片源</span>
|
||||
<span class="note">观看至</span>
|
||||
<span class="operate">
|
||||
<span class="btn"></span>
|
||||
<span class="btn"></span>
|
||||
<span class="btn"></span>
|
||||
<span class="btn"></span>
|
||||
</span>
|
||||
</li>
|
||||
<li v-for="(i, j) in history" :key="j" @click="historyItemEvent(i)">
|
||||
<span class="name" @click.stop="detailEvent(i)">{{i.name}}</span>
|
||||
<span class="site">{{getSiteName(i.site)}}</span>
|
||||
<span class="note">第{{i.index+1}}集</span>
|
||||
<span class="operate">
|
||||
<span class="btn" @click.stop="playEvent(i)">播放</span>
|
||||
<span class="btn" @click.stop="shareEvent(i)">分享</span>
|
||||
<span class="btn" @click.stop="downloadEvent(i)">下载</span>
|
||||
<span class="btn" @click.stop="removeHistoryItem(i)">删除</span>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="listpage" id="history">
|
||||
<div class="listpage-content">
|
||||
<div class="listpage-header">
|
||||
<el-button @click.stop="exportHistory" icon="el-icon-upload2">导出</el-button>
|
||||
<el-button @click.stop="importHistory" icon="el-icon-download">导入</el-button>
|
||||
<el-button @click.stop="clearAllHistory" icon="el-icon-delete-solid">清空</el-button>
|
||||
</div>
|
||||
<div class="listpage-body" id="history-table">
|
||||
<el-table size="mini" fit height="100%" :data="history" row-key="id" @row-click="detailEvent">
|
||||
<el-table-column
|
||||
prop="name"
|
||||
label="片名">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="site"
|
||||
width="120"
|
||||
label="片源">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ getSiteName(scope.row.site) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="index"
|
||||
width="120"
|
||||
label="观看至">
|
||||
<template slot-scope="scope">
|
||||
<span>第{{ scope.row.index + 1 }}集</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
header-align="right"
|
||||
align="right">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click.stop="playEvent(scope.row)" type="text">播放</el-button>
|
||||
<el-button @click.stop="shareEvent(scope.row)" type="text">分享</el-button>
|
||||
<el-button @click.stop="downloadEvent(scope.row)" type="text">下载</el-button>
|
||||
<el-button @click.stop="removeHistoryItem(scope.row)" type="text">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -41,12 +48,16 @@
|
||||
import { mapMutations } from 'vuex'
|
||||
import { history, sites } from '../lib/dexie'
|
||||
import zy from '../lib/site/tools'
|
||||
import Sortable from 'sortablejs'
|
||||
import { remote } from 'electron'
|
||||
import fs from 'fs'
|
||||
const { clipboard } = require('electron')
|
||||
|
||||
export default {
|
||||
name: 'history',
|
||||
data () {
|
||||
return {
|
||||
history: history,
|
||||
history: [],
|
||||
sites: []
|
||||
}
|
||||
},
|
||||
@@ -102,14 +113,13 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
playEvent (e) {
|
||||
history.find({ site: e.site, ids: e.ids }).then(res => {
|
||||
if (res) {
|
||||
this.video = { key: res.site, info: { id: res.ids, name: res.name, index: res.index } }
|
||||
} else {
|
||||
this.video = { key: e.site, info: { id: e.ids, name: e.name, index: 0 } }
|
||||
}
|
||||
})
|
||||
async playEvent (e) {
|
||||
const db = await history.find({ site: e.site, ids: e.ids })
|
||||
if (db) {
|
||||
this.video = { key: db.site, info: { id: db.ids, name: db.name, index: db.index } }
|
||||
} else {
|
||||
this.video = { key: e.site, info: { id: e.ids, name: e.name, index: 0 } }
|
||||
}
|
||||
this.view = 'Play'
|
||||
},
|
||||
shareEvent (e) {
|
||||
@@ -161,6 +171,44 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
exportHistory () {
|
||||
this.getAllhistory()
|
||||
const arr = [...this.history]
|
||||
const str = JSON.stringify(arr, null, 2)
|
||||
const options = {
|
||||
filters: [
|
||||
{ name: 'JSON file', extensions: ['json'] }
|
||||
]
|
||||
}
|
||||
remote.dialog.showSaveDialog(options).then(result => {
|
||||
if (!result.canceled) {
|
||||
fs.writeFileSync(result.filePath, str)
|
||||
this.$message.success('已保存成功')
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err)
|
||||
})
|
||||
},
|
||||
importHistory () {
|
||||
const options = {
|
||||
filters: [
|
||||
{ name: 'JSON file', extensions: ['json'] }
|
||||
],
|
||||
properties: ['openFile', 'multiSelections']
|
||||
}
|
||||
remote.dialog.showOpenDialog(options).then(result => {
|
||||
if (!result.canceled) {
|
||||
result.filePaths.forEach(file => {
|
||||
var str = fs.readFileSync(file)
|
||||
const json = JSON.parse(str)
|
||||
history.bulkAdd(json).then(res => {
|
||||
this.$message.success('导入成功')
|
||||
this.getAllhistory()
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
clearAllHistory () {
|
||||
history.clear().then(res => {
|
||||
this.history = []
|
||||
@@ -182,44 +230,40 @@ export default {
|
||||
return site.name
|
||||
}
|
||||
},
|
||||
historyItemEvent (e) {
|
||||
this.video = {
|
||||
key: e.site,
|
||||
info: {
|
||||
id: e.ids,
|
||||
name: e.name,
|
||||
type: e.type,
|
||||
year: e.year,
|
||||
index: e.index,
|
||||
time: e.time
|
||||
}
|
||||
}
|
||||
},
|
||||
removeHistoryItem (e) {
|
||||
history.remove(e.id).then(res => {
|
||||
this.getAllhistory()
|
||||
}).catch(err => {
|
||||
this.$message.warning('删除历史记录失败, 错误信息: ' + err)
|
||||
})
|
||||
},
|
||||
updateDatabase (data) {
|
||||
history.clear().then(res => {
|
||||
var id = length
|
||||
data.forEach(ele => {
|
||||
ele.id = id
|
||||
id -= 1
|
||||
history.add(ele)
|
||||
})
|
||||
})
|
||||
},
|
||||
rowDrop () {
|
||||
const tbody = document.getElementById('history-table').querySelector('.el-table__body-wrapper tbody')
|
||||
const _this = this
|
||||
Sortable.create(tbody, {
|
||||
onEnd ({ newIndex, oldIndex }) {
|
||||
const currRow = _this.history.splice(oldIndex, 1)[0]
|
||||
_this.history.splice(newIndex, 0, currRow)
|
||||
_this.updateDatabase(_this.history)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.rowDrop()
|
||||
},
|
||||
created () {
|
||||
this.getAllhistory()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.history{
|
||||
position: relative;
|
||||
height: calc(100% - 40px);
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 5px;
|
||||
.body{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,54 +1,69 @@
|
||||
<template>
|
||||
<div class="detail">
|
||||
<div class="detail-content">
|
||||
<div class="detail-header">
|
||||
<div class="zy-select">
|
||||
<div class="vs-placeholder vs-noAfter" @click="exportSites">导出</div>
|
||||
</div>
|
||||
<div class="zy-select">
|
||||
<div class="vs-placeholder vs-noAfter" @click="importSites">导入</div>
|
||||
</div>
|
||||
<div class="zy-select">
|
||||
<div class="vs-placeholder vs-noAfter" @click="removeAllSites">清空</div>
|
||||
</div>
|
||||
<div class="zy-select">
|
||||
<div class="vs-placeholder vs-noAfter" @click="resetSites">重置</div>
|
||||
</div>
|
||||
<div style="width: 200px; height: 30px;">
|
||||
</div>
|
||||
<div class="listpage" id="IPTV">
|
||||
<div class="listpage-content">
|
||||
<div class="listpage-header" v-show="!enableBatchEdit">
|
||||
<el-switch v-model="enableBatchEdit" active-text="批处理分组"></el-switch>
|
||||
<el-button @click.stop="exportChannels" icon="el-icon-upload2" >导出</el-button>
|
||||
<el-button @click.stop="importChannels" icon="el-icon-download">导入</el-button>
|
||||
<el-button @click.stop="removeAllChannels" icon="el-icon-delete-solid">清空</el-button>
|
||||
<el-button @click.stop="resetChannelsEvent" icon="el-icon-refresh-left">重置</el-button>
|
||||
</div>
|
||||
<div class="detail-header">
|
||||
<div>
|
||||
<div class="vs-placeholder vs-noAfter" @click="exportSites">总频道数:{{iptvList.length}}</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>
|
||||
<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-button type="primary" icon="el-icon-edit" @click.stop="saveBatchEdit">保存</el-button>
|
||||
</div>
|
||||
<div class="detail-body zy-scroll">
|
||||
<div class="zy-table">
|
||||
<div class="tBody zy-scroll">
|
||||
<ul>
|
||||
<draggable v-model="iptvList" @change="listUpdatedEvent">
|
||||
<transition-group>
|
||||
<li v-for="(i, j) in iptvList" :key="j" @click.stop="playEvent(i)" v-show="containsearchTxt(i)">
|
||||
<span class="name">{{i.name}}</span>
|
||||
<span class="operate">
|
||||
<span class="btn" @click.stop="playEvent(i)">播放</span>
|
||||
<span class="btn" @click.stop="removeEvent(i)">删除</span>
|
||||
</span>
|
||||
</li>
|
||||
</transition-group>
|
||||
</draggable>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="listpage-body" id="iptv-table">
|
||||
<el-table
|
||||
ref="iptvTable"
|
||||
size="mini" fit height="100%" row-key="id"
|
||||
:data="filteredTableData"
|
||||
@row-click="playEvent"
|
||||
@selection-change="handleSelectionChange"
|
||||
@sort-change="handleSortChange">>
|
||||
<el-table-column
|
||||
type="selection"
|
||||
v-if="enableBatchEdit">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
default-sort="ascending"
|
||||
prop="name"
|
||||
label="频道名">
|
||||
<template #header>
|
||||
<el-input
|
||||
placeholder="搜索"
|
||||
size="mini"
|
||||
v-model.trim="searchTxt">
|
||||
<i slot="prefix" class="el-input__icon el-icon-search"></i>
|
||||
</el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
sort-by="['group', 'name']"
|
||||
sortable
|
||||
:sort-method="sortByGroup"
|
||||
prop="group"
|
||||
label="分组"
|
||||
:filters="getFilters"
|
||||
:filter-method="filterHandle"
|
||||
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="操作"
|
||||
header-align="right"
|
||||
align="right">
|
||||
<template #header>
|
||||
<span>总频道数:{{ iptvList.length }}</span>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<el-button @click.stop="moveToTopEvent(scope.row)" type="text">置顶</el-button>
|
||||
<el-button @click.stop="removeEvent(scope.row)" type="text">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -56,25 +71,25 @@
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import { iptv, iptvSearch } from '../lib/dexie'
|
||||
import draggable from 'vuedraggable'
|
||||
import { iptv as defaultSites } from '../lib/dexie/initData'
|
||||
import { remote } from 'electron'
|
||||
import fs from 'fs'
|
||||
import Sortable from 'sortablejs'
|
||||
export default {
|
||||
name: 'iptv',
|
||||
data () {
|
||||
return {
|
||||
iptvList: [],
|
||||
searchTxt: '',
|
||||
searchList: [],
|
||||
searchRecordList: [],
|
||||
enableBatchEdit: false,
|
||||
batchGroupName: '',
|
||||
multipleSelection: [],
|
||||
show: {
|
||||
search: false
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
draggable
|
||||
},
|
||||
computed: {
|
||||
view: {
|
||||
get () {
|
||||
@@ -94,21 +109,60 @@ export default {
|
||||
set (val) {
|
||||
this.SET_VIDEO(val)
|
||||
}
|
||||
},
|
||||
filteredTableData () {
|
||||
if (this.searchTxt) {
|
||||
return this.iptvList.filter(x => x.name.toLowerCase().includes(this.searchTxt.toLowerCase()))
|
||||
} else {
|
||||
return this.iptvList
|
||||
}
|
||||
},
|
||||
getFilters () {
|
||||
const groups = [...new Set(this.iptvList.map(iptv => iptv.group))]
|
||||
var filters = []
|
||||
groups.forEach(g => {
|
||||
var doc = {
|
||||
text: g,
|
||||
value: g
|
||||
}
|
||||
filters.push(doc)
|
||||
})
|
||||
return filters
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
view () {
|
||||
this.getAllSites()
|
||||
this.getChannels()
|
||||
},
|
||||
searchTxt () {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
|
||||
sortByGroup (a, b) {
|
||||
return a.group.localeCompare(b.group, 'zh')
|
||||
},
|
||||
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
|
||||
})
|
||||
}
|
||||
this.updateDatabase()
|
||||
},
|
||||
playEvent (e) {
|
||||
this.video = { iptv: { name: e.name, url: e.url } }
|
||||
this.view = 'Play'
|
||||
},
|
||||
filterHandle (value, row) {
|
||||
return row.group === value
|
||||
},
|
||||
containsearchTxt (i) {
|
||||
if (this.searchTxt) {
|
||||
return i.name.toLowerCase().includes(this.searchTxt.toLowerCase())
|
||||
@@ -118,7 +172,7 @@ export default {
|
||||
},
|
||||
removeEvent (e) {
|
||||
iptv.remove(e.id).then(res => {
|
||||
this.getAllSites()
|
||||
this.getChannels()
|
||||
}).catch(err => {
|
||||
this.$message.warning('删除频道失败, 错误信息: ' + err)
|
||||
})
|
||||
@@ -134,7 +188,7 @@ export default {
|
||||
})
|
||||
})
|
||||
},
|
||||
exportSites () {
|
||||
exportChannels () {
|
||||
const options = {
|
||||
filters: [
|
||||
{ name: 'm3u file', extensions: ['m3u'] },
|
||||
@@ -152,7 +206,7 @@ export default {
|
||||
this.$message.success('已保存成功')
|
||||
} else {
|
||||
const arr = [...this.iptvList]
|
||||
const str = JSON.stringify(arr, null, 4)
|
||||
const str = JSON.stringify(arr, null, 2)
|
||||
fs.writeFileSync(result.filePath, str)
|
||||
this.$message.success('已保存成功')
|
||||
}
|
||||
@@ -161,65 +215,104 @@ export default {
|
||||
this.$message.error(err)
|
||||
})
|
||||
},
|
||||
importSites () {
|
||||
importChannels () {
|
||||
const options = {
|
||||
filters: [
|
||||
{ name: 'm3u file', extensions: ['m3u', 'm3u8'] }
|
||||
{ name: 'm3u file', extensions: ['m3u', 'm3u8'] },
|
||||
{ name: 'JSON file', extensions: ['json'] }
|
||||
],
|
||||
properties: ['openFile', 'multiSelections']
|
||||
}
|
||||
remote.dialog.showOpenDialog(options).then(result => {
|
||||
if (!result.canceled) {
|
||||
var docs = this.iptvList
|
||||
var id = docs.length
|
||||
result.filePaths.forEach(file => {
|
||||
const parser = require('iptv-playlist-parser')
|
||||
const playlist = fs.readFileSync(file, { encoding: 'utf-8' })
|
||||
const result = parser.parse(playlist)
|
||||
result.items.forEach(ele => {
|
||||
if (ele.name && ele.url && ele.url.includes('.m3u8')) {
|
||||
var doc = {
|
||||
name: ele.name,
|
||||
url: ele.url
|
||||
if (file.endsWith('m3u') || file.endsWith('m3u8')) {
|
||||
const parser = require('iptv-playlist-parser')
|
||||
const playlist = fs.readFileSync(file, { encoding: 'utf-8' })
|
||||
const result = parser.parse(playlist)
|
||||
result.items.forEach(ele => {
|
||||
if (ele.name && ele.url && ele.url.endsWith('.m3u8')) {
|
||||
var doc = {
|
||||
id: id,
|
||||
name: ele.name,
|
||||
url: ele.url,
|
||||
group: this.determineGroup(ele.name)
|
||||
}
|
||||
id += 1
|
||||
docs.push(doc)
|
||||
}
|
||||
docs.push(doc)
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// Import Json file
|
||||
var str = fs.readFileSync(file)
|
||||
const json = JSON.parse(str)
|
||||
json.forEach(ele => {
|
||||
if (ele.name && ele.url && ele.url.endsWith('.m3u8')) {
|
||||
var doc = {
|
||||
id: id,
|
||||
name: ele.name,
|
||||
url: ele.url,
|
||||
group: this.determineGroup(ele.name)
|
||||
}
|
||||
id += 1
|
||||
docs.push(doc)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
// 获取url不重复的列表
|
||||
const uniqueList = [...new Map(docs.map(item => [item.url, item])).values()]
|
||||
// 获取name不重复的列表
|
||||
const uniqueList = [...new Map(docs.map(item => [item.name, item])).values()]
|
||||
iptv.clear().then(res => {
|
||||
iptv.bulkAdd(uniqueList).then(e => {
|
||||
this.getAllSites()
|
||||
this.getChannels()
|
||||
this.$message.success('导入成功')
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
resetSites () {
|
||||
iptv.clear()
|
||||
iptv.bulkAdd(defaultSites).then(e => {
|
||||
this.getAllSites()
|
||||
})
|
||||
determineGroup (name) {
|
||||
if (name.toLowerCase().includes('cctv') && (name.includes('蓝光') || name.includes('高清'))) {
|
||||
return '央视高清'
|
||||
} else if (name.toLowerCase().includes('cctv')) {
|
||||
return '央视'
|
||||
} else if (name.includes('卫视')) {
|
||||
return '卫视'
|
||||
} else if (name.includes('香港') || name.includes('澳门') || name.includes('台湾') || name.includes('凤凰')) {
|
||||
return '港澳台'
|
||||
} else if (name.includes('高清') || name.includes('蓝光') || name.includes('1080P')) {
|
||||
return '高清'
|
||||
} else {
|
||||
return '其他'
|
||||
}
|
||||
},
|
||||
removeAllSites () {
|
||||
resetChannelsEvent () {
|
||||
this.resetChannels(defaultSites)
|
||||
},
|
||||
resetChannels (newSites) {
|
||||
this.resetId(newSites)
|
||||
iptv.clear().then(iptv.bulkAdd(newSites).then(this.getChannels()))
|
||||
},
|
||||
removeAllChannels () {
|
||||
iptv.clear().then(res => {
|
||||
this.getAllSites()
|
||||
this.getChannels()
|
||||
})
|
||||
},
|
||||
getAllSites () {
|
||||
getChannels () {
|
||||
iptv.all().then(res => {
|
||||
this.iptvList = res
|
||||
})
|
||||
},
|
||||
getAllSearch () {
|
||||
getSearchRecordList () {
|
||||
iptvSearch.all().then(res => {
|
||||
this.searchList = res.reverse()
|
||||
this.searchRecordList = res.reverse()
|
||||
})
|
||||
},
|
||||
clearSearch () {
|
||||
iptvSearch.clear().then(res => {
|
||||
this.getAllSearch()
|
||||
this.getSearchRecordList()
|
||||
})
|
||||
},
|
||||
searchEvent (wd) {
|
||||
@@ -230,47 +323,51 @@ export default {
|
||||
if (!res) {
|
||||
iptvSearch.add({ keywords: wd })
|
||||
}
|
||||
this.getAllSearch()
|
||||
this.getSearchRecordList()
|
||||
})
|
||||
}
|
||||
},
|
||||
moveToTopEvent (i) {
|
||||
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) {
|
||||
this.iptvList = this.$refs.iptvTable.tableData
|
||||
}
|
||||
},
|
||||
updateDatabase () {
|
||||
this.syncTableData()
|
||||
iptv.clear().then(res => {
|
||||
this.resetId(this.iptvList)
|
||||
iptv.bulkAdd(this.iptvList)
|
||||
})
|
||||
},
|
||||
resetId (inArray) {
|
||||
var id = 1
|
||||
inArray.forEach(ele => {
|
||||
ele.id = id
|
||||
id += 1
|
||||
})
|
||||
},
|
||||
rowDrop () {
|
||||
const tbody = document.getElementById('iptv-table').querySelector('.el-table__body-wrapper tbody')
|
||||
const _this = this
|
||||
Sortable.create(tbody, {
|
||||
onEnd ({ newIndex, oldIndex }) {
|
||||
const currRow = _this.iptvList.splice(oldIndex, 1)[0]
|
||||
_this.iptvList.splice(newIndex, 0, currRow)
|
||||
_this.updateDatabase()
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.rowDrop()
|
||||
},
|
||||
created () {
|
||||
this.getAllSites()
|
||||
this.getAllSearch()
|
||||
this.getChannels()
|
||||
this.getSearchRecordList()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.detail{
|
||||
position: absolute;
|
||||
left: 80px;
|
||||
right: 20px;
|
||||
bottom: 0;
|
||||
width: calc(100% - 100px);
|
||||
height: calc(100% - 40px);
|
||||
z-index: 888;
|
||||
.detail-content{
|
||||
height: calc(100% - 10px);
|
||||
padding: 0 60px;
|
||||
position: relative;
|
||||
.detail-header{
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
.detail-title{
|
||||
font-size: 16px;
|
||||
}
|
||||
.detail-close{
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
.detail-body{
|
||||
height: calc(100% - 100px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -3,23 +3,20 @@
|
||||
<div class="box">
|
||||
<div class="title">
|
||||
<span v-if="this.right.list.length > 1">『第 {{(video.info.index + 1)}} 集』</span>{{name}}
|
||||
<span v-if="video.key" class="right" @click="playWithExternalPalyerEvent" title="使用第三方播放器">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<polygon points="20 8 20 20 4 20 4 8"></polygon>
|
||||
<polyline stroke-linejoin="round" points="8 4 12 7.917 16 4"></polyline>
|
||||
</svg>
|
||||
</span>
|
||||
<span v-if="video.key" class="right" @click="issueEvent" title="复制调试信息">
|
||||
<svg t="1596338860607" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3127" width="24" height="24">
|
||||
<path d="M503.803829 63.578014c-247.050676 0-447.328072 200.277396-447.328072 447.327048 0 247.054769 200.277396 447.333188 447.328072 447.333188 247.054769 0 447.332165-200.278419 447.332165-447.333188C951.13497 263.85541 750.858598 63.578014 503.803829 63.578014L503.803829 63.578014zM503.803829 894.313336c-211.749682 0-383.408273-171.659615-383.408273-383.408273 0-211.749682 171.659615-383.40725 383.408273-383.40725 211.753775 0 383.412366 171.658591 383.412366 383.40725C887.216195 722.653721 715.557604 894.313336 503.803829 894.313336L503.803829 894.313336zM447.745069 255.897158l127.914298 0L575.659367 383.576095 447.745069 383.576095 447.745069 255.897158 447.745069 255.897158zM447.745069 425.470251l127.914298 0 0 342.058516L447.745069 767.528767 447.745069 425.470251 447.745069 425.470251zM447.745069 425.470251" p-id="3128"></path>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
<div class="player">
|
||||
<div id="xgplayer"></div>
|
||||
</div>
|
||||
<div class="more">
|
||||
<span class="zy-svg" @click="nextEvent" v-show="showNext">
|
||||
<span class="zy-svg" @click="otherEvent" v-show="name !== ''">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="coloursIconTitle">
|
||||
<title id="coloursIconTitle">换源</title>
|
||||
<circle cx="12" cy="9" r="5"></circle>
|
||||
<circle cx="9" cy="14" r="5"></circle>
|
||||
<circle cx="15" cy="14" r="5"></circle>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="zy-svg" @click="nextEvent" v-show="right.list.length > 1">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="forwardIconTitle">
|
||||
<title id="forwardIconTitle">下一集</title>
|
||||
<path d="M10 14.74L3 19V5l7 4.26V5l12 7-12 7v-4.26z"></path>
|
||||
@@ -58,8 +55,14 @@
|
||||
</svg>
|
||||
</span>
|
||||
<span class="zy-svg" @click="miniEvent" v-show="right.list.length > 0">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-labelledby="diamondIconTitle">
|
||||
<title id="diamondIconTitle">精简模式</title>
|
||||
<path d="M12 20L3 11M12 20L21 11M12 20L8 11M12 20L16 11M3 11L7 5M3 11H8M7 5L8 11M7 5H12M17 5L21 11M17 5L16 11M17 5H12M21 11H16M8 11H16M8 11L12 5M16 11L12 5"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="zy-svg" @click="playWithExternalPalyerEvent" v-show="right.list.length > 0">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="tvIconTitle">
|
||||
<title id="tvIconTitle">精简模式</title>
|
||||
<title id="tvIconTitle" >使用第三方播放器</title>
|
||||
<polygon points="20 8 20 20 4 20 4 8"></polygon>
|
||||
<polyline stroke-linejoin="round" points="8 4 12 7.917 16 4"></polyline>
|
||||
</svg>
|
||||
@@ -81,13 +84,21 @@
|
||||
<rect x="17" y="6" width="1" height="1"></rect>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="zy-svg" @click="issueEvent" v-show="right.list.length > 0">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="infoIconTitle">
|
||||
<title id="infoIconTitle">复制调试信息</title>
|
||||
<path d="M12,12 L12,15"></path>
|
||||
<line x1="12" y1="9" x2="12" y2="9"></line>
|
||||
<circle cx="12" cy="12" r="10"></circle>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="last-tip" v-if="!video.key && right.history.length > 0" @click="historyItemEvent(right.history[0])">上次播放到【{{right.history[0].site}}】{{right.history[0].name}} 第{{right.history[0].index+1}}集</span>
|
||||
</div>
|
||||
</div>
|
||||
<transition name="slideX">
|
||||
<div v-if="right.show" class="list">
|
||||
<div class="list-top">
|
||||
<span class="list-top-title">{{ right.type === 'list' ? '播放列表' : '历史记录' }}</span>
|
||||
<span class="list-top-title">{{ right.type === 'list' ? '播放列表' : right.type === 'history' ? '历史记录' : '其他相同资源' }}</span>
|
||||
<span class="list-top-close zy-svg" @click="closeListEvent">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="closeIconTitle">
|
||||
<title id="closeIconTitle">关闭</title>
|
||||
@@ -106,6 +117,10 @@
|
||||
<li v-show="right.history.length === 0">无数据</li>
|
||||
<li @click="historyItemEvent(m)" :class="video.info.id === m.ids ? 'active' : ''" v-for="(m, n) in right.history" :key="n"><span class="title" :title="'【' + m.site + '】' + m.name + ' 第' + (m.index+1) + '集'">【{{m.site}}】{{m.name}} 第{{m.index+1}}集</span><span @click.stop="removeHistoryItem(m)" class="detail-delete">删除</span></li>
|
||||
</ul>
|
||||
<ul v-show="right.type === 'other'" class="list-other">
|
||||
<li v-show="right.other.length === 0">无数据</li>
|
||||
<li @click="otherItemEvent(m)" v-for="(m, n) in right.other" :key="n"><span class="title">{{m.name}} - [{{m.site}}]</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
@@ -113,7 +128,7 @@
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import { star, history, setting, shortcut, mini, iptv } from '../lib/dexie'
|
||||
import { star, history, setting, shortcut, mini, iptv, sites } from '../lib/dexie'
|
||||
import zy from '../lib/site/tools'
|
||||
import Player from 'xgplayer'
|
||||
import Hls from 'xgplayer-hls.js'
|
||||
@@ -170,6 +185,7 @@ export default {
|
||||
right: {
|
||||
show: false,
|
||||
type: '',
|
||||
other: [],
|
||||
list: [],
|
||||
history: []
|
||||
},
|
||||
@@ -189,6 +205,7 @@ export default {
|
||||
playbackRate: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 3, 4, 5],
|
||||
playPrev: true,
|
||||
playNextOne: true,
|
||||
videoStop: true,
|
||||
showList: true,
|
||||
showHistory: true,
|
||||
videoTitle: true
|
||||
@@ -201,7 +218,6 @@ export default {
|
||||
length: 0,
|
||||
timer: null,
|
||||
scroll: false,
|
||||
showNext: false,
|
||||
isStar: false,
|
||||
isTop: false,
|
||||
mini: {},
|
||||
@@ -286,32 +302,34 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
|
||||
getUrls () {
|
||||
async getUrls () {
|
||||
if (this.video.key === '') {
|
||||
return false
|
||||
}
|
||||
this.name = ''
|
||||
if (this.timer !== null) {
|
||||
clearInterval(this.timer)
|
||||
this.timer = null
|
||||
}
|
||||
if (this.xg) {
|
||||
if (this.xg.hasStart) {
|
||||
this.xg.pause()
|
||||
}
|
||||
if (this.xg && this.xg.hasStart) {
|
||||
this.xg.pause()
|
||||
}
|
||||
|
||||
if (this.video.iptv) {
|
||||
// 是直播源,直接播放
|
||||
this.playUrl(this.video.iptv.url)
|
||||
this.name = this.video.iptv.name
|
||||
this.getIptvList()
|
||||
} else {
|
||||
const index = this.video.info.index | 0
|
||||
let time = 0
|
||||
history.find({ site: this.video.key, ids: this.video.info.id }).then(res => {
|
||||
if (res) {
|
||||
if (res.index === index) {
|
||||
time = res.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)
|
||||
})
|
||||
}
|
||||
this.playVideo(index, time)
|
||||
}
|
||||
},
|
||||
playUrl (url) {
|
||||
@@ -321,7 +339,6 @@ export default {
|
||||
playVideo (index = 0, time = 0) {
|
||||
this.fetchM3u8List().then(m3u8Arr => {
|
||||
this.xg.src = m3u8Arr[index]
|
||||
this.showNext = m3u8Arr.length > 1
|
||||
|
||||
if (time !== 0) {
|
||||
this.xg.play()
|
||||
@@ -348,7 +365,6 @@ export default {
|
||||
if (VIDEO_DETAIL_CACHE[cacheKey]) {
|
||||
this.name = VIDEO_DETAIL_CACHE[cacheKey].name
|
||||
resolve(VIDEO_DETAIL_CACHE[cacheKey].list)
|
||||
return
|
||||
}
|
||||
zy.detail(this.video.key, this.video.info.id).then(res => {
|
||||
this.name = res.name
|
||||
@@ -388,34 +404,33 @@ export default {
|
||||
})
|
||||
})
|
||||
},
|
||||
videoPlaying () {
|
||||
async videoPlaying () {
|
||||
this.changeVideo()
|
||||
history.find({ site: this.video.key, ids: this.video.info.id }).then(res => {
|
||||
if (res) {
|
||||
const doc = {
|
||||
site: res.site,
|
||||
ids: res.ids,
|
||||
name: res.name,
|
||||
type: res.type,
|
||||
year: res.year,
|
||||
index: this.video.info.index,
|
||||
time: res.time
|
||||
}
|
||||
history.remove(res.id)
|
||||
history.add(doc)
|
||||
} else {
|
||||
const doc = {
|
||||
site: this.video.key,
|
||||
ids: this.video.info.id,
|
||||
name: this.video.info.name,
|
||||
type: this.video.info.type,
|
||||
year: this.video.info.year,
|
||||
index: this.video.info.index,
|
||||
time: ''
|
||||
}
|
||||
history.add(doc)
|
||||
const db = await history.find({ site: this.video.key, ids: this.video.info.id })
|
||||
if (db) {
|
||||
const doc = {
|
||||
site: db.site,
|
||||
ids: db.ids,
|
||||
name: db.name,
|
||||
type: db.type,
|
||||
year: db.year,
|
||||
index: this.video.info.index,
|
||||
time: db.time
|
||||
}
|
||||
})
|
||||
history.remove(db.id)
|
||||
history.add(doc)
|
||||
} else {
|
||||
const doc = {
|
||||
site: this.video.key,
|
||||
ids: this.video.info.id,
|
||||
name: this.video.info.name,
|
||||
type: this.video.info.type,
|
||||
year: this.video.info.year,
|
||||
index: this.video.info.index,
|
||||
time: ''
|
||||
}
|
||||
history.add(doc)
|
||||
}
|
||||
this.updateStar()
|
||||
this.timerEvent()
|
||||
},
|
||||
@@ -424,15 +439,14 @@ export default {
|
||||
this.checkTop()
|
||||
},
|
||||
timerEvent () {
|
||||
this.timer = setInterval(() => {
|
||||
history.find({ site: this.video.key, ids: this.video.info.id }).then(res => {
|
||||
if (res) {
|
||||
const doc = { ...res }
|
||||
doc.time = this.xg.currentTime
|
||||
delete doc.id
|
||||
history.update(res.id, doc)
|
||||
}
|
||||
})
|
||||
this.timer = setInterval(async () => {
|
||||
const db = await history.find({ site: this.video.key, ids: this.video.info.id })
|
||||
if (db) {
|
||||
const doc = { ...db }
|
||||
doc.time = this.xg.currentTime
|
||||
delete doc.id
|
||||
history.update(db.id, doc)
|
||||
}
|
||||
}, 10000)
|
||||
},
|
||||
prevEvent () {
|
||||
@@ -497,21 +511,28 @@ export default {
|
||||
this.right.history = res.reverse()
|
||||
})
|
||||
},
|
||||
updateStar () {
|
||||
async updateStar () {
|
||||
const info = this.video.info
|
||||
star.find({ key: this.video.key, ids: info.id }).then(res => {
|
||||
if (res) {
|
||||
res.index = info.index
|
||||
star.update(res.id, res)
|
||||
}
|
||||
}).catch(() => {
|
||||
this.$message.warning('检查收藏失败')
|
||||
})
|
||||
const db = await star.find({ key: this.video.key, ids: info.id })
|
||||
if (db) {
|
||||
db.index = info.index
|
||||
star.update(db.id, db)
|
||||
}
|
||||
},
|
||||
starEvent () {
|
||||
async starEvent () {
|
||||
const info = this.video.info
|
||||
star.find({ key: this.video.key, ids: info.id }).then(res => {
|
||||
const doc = {
|
||||
const db = await star.find({ key: this.video.key, ids: info.id })
|
||||
if (db) {
|
||||
star.remove(db.id).then(res => {
|
||||
if (res) {
|
||||
this.$message.warning('取消收藏失败')
|
||||
} else {
|
||||
this.$message.success('取消收藏成功')
|
||||
this.isStar = false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
const docs = {
|
||||
key: this.video.key,
|
||||
ids: info.id,
|
||||
name: info.name,
|
||||
@@ -521,17 +542,11 @@ export default {
|
||||
note: info.note,
|
||||
index: info.index
|
||||
}
|
||||
if (res) {
|
||||
star.update(res.id, doc)
|
||||
} else {
|
||||
star.add(doc).then(starRes => {
|
||||
this.$message.success('收藏成功')
|
||||
this.isStar = true
|
||||
})
|
||||
}
|
||||
}).catch(() => {
|
||||
this.$message.warning('检查收藏失败')
|
||||
})
|
||||
star.add(docs).then(res => {
|
||||
this.$message.success('收藏成功')
|
||||
this.isStar = true
|
||||
})
|
||||
}
|
||||
},
|
||||
detailEvent () {
|
||||
this.detail = {
|
||||
@@ -623,14 +638,13 @@ export default {
|
||||
fs.writeFileSync(filePath, str)
|
||||
return filePath
|
||||
},
|
||||
checkStar () {
|
||||
star.find({ key: this.video.key, ids: this.video.info.id }).then(res => {
|
||||
if (res) {
|
||||
this.isStar = true
|
||||
} else {
|
||||
this.isStar = false
|
||||
}
|
||||
})
|
||||
async checkStar () {
|
||||
const db = await star.find({ key: this.video.key, ids: this.video.info.id })
|
||||
if (db) {
|
||||
this.isStar = true
|
||||
} else {
|
||||
this.isStar = false
|
||||
}
|
||||
},
|
||||
checkTop () {
|
||||
const win = remote.getCurrentWindow()
|
||||
@@ -685,6 +699,7 @@ export default {
|
||||
if (this.video.iptv) {
|
||||
var channel = this.iptvList[n]
|
||||
this.video.iptv = channel
|
||||
this.name = this.video.iptv.name
|
||||
// 是直播源,直接播放
|
||||
this.playUrl(channel.url)
|
||||
} else {
|
||||
@@ -717,6 +732,70 @@ export default {
|
||||
this.$message.warning('删除历史记录失败, 错误信息: ' + err)
|
||||
})
|
||||
},
|
||||
getAllsitestest () {
|
||||
this.name = '喜宝'
|
||||
sites.all().then(res => {
|
||||
const sites = res
|
||||
const arr = []
|
||||
for (const i of sites) {
|
||||
zy.search(i.key, this.name).then(res => {
|
||||
const type = Object.prototype.toString.call(res)
|
||||
if (type === '[object Array]') {
|
||||
res.forEach(element => {
|
||||
zy.detail(i.key, element.id).then(detailRes => {
|
||||
arr.push(detailRes)
|
||||
})
|
||||
})
|
||||
}
|
||||
if (type === '[object Object]') {
|
||||
zy.detail(i.key, res.id).then(detailRes => {
|
||||
arr.push(detailRes)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
console.log(arr, 'arr')
|
||||
})
|
||||
},
|
||||
async getAllsites () {
|
||||
const all = await sites.all()
|
||||
this.right.other = []
|
||||
for (const i of all) {
|
||||
if (i.isActive) {
|
||||
const searchRes = await zy.search(i.key, this.name)
|
||||
const type = Object.prototype.toString.call(searchRes)
|
||||
if (type === '[object Array]') {
|
||||
searchRes.forEach(async element => {
|
||||
const detailRes = await zy.detail(i.key, element.id)
|
||||
detailRes.key = i.key
|
||||
detailRes.site = i.name
|
||||
this.right.other.push(detailRes)
|
||||
})
|
||||
}
|
||||
if (type === '[object Object]') {
|
||||
const detailRes = await zy.detail(i.key, searchRes.id)
|
||||
detailRes.key = i.key
|
||||
detailRes.site = i.name
|
||||
this.right.other.push(detailRes)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
otherEvent (m) {
|
||||
this.right.type = 'other'
|
||||
this.getAllsites()
|
||||
this.right.show = true
|
||||
},
|
||||
async otherItemEvent (e) {
|
||||
const db = await history.find({ site: e.key, ids: e.id })
|
||||
if (db) {
|
||||
this.video = { key: db.site, info: { id: db.ids, name: db.name, index: db.index, site: e.key } }
|
||||
} else {
|
||||
this.video = { key: e.key, info: { id: e.id, name: e.name, index: 0, site: e.key } }
|
||||
}
|
||||
this.right.show = false
|
||||
this.right.type = ''
|
||||
},
|
||||
mtEvent () {
|
||||
setting.find().then(res => {
|
||||
if (res.shortcut) {
|
||||
@@ -989,28 +1068,90 @@ export default {
|
||||
this.toggleHistory()
|
||||
})
|
||||
|
||||
this.xg.on('videoStop', () => {
|
||||
this.videoStop()
|
||||
})
|
||||
|
||||
const ev = ['click', 'touchend', 'mousemove']
|
||||
let timerID
|
||||
ev.forEach(item => {
|
||||
this.xg.root.addEventListener(item, () => {
|
||||
if (!this.xg.fullscreen) {
|
||||
return
|
||||
if (this.xg && this.xg.fullscreen) {
|
||||
const videoTitle = document.querySelector('.xg-view-videoTitle')
|
||||
videoTitle.style.display = 'block'
|
||||
clearTimeout(timerID)
|
||||
timerID = setTimeout(() => {
|
||||
// 播放中自动消失
|
||||
if (this.xg && !this.xg.paused) {
|
||||
videoTitle.style.display = 'none'
|
||||
}
|
||||
}, 3000)
|
||||
}
|
||||
const videoTitle = document.querySelector('.xg-view-videoTitle')
|
||||
videoTitle.style.display = 'block'
|
||||
clearTimeout(timerID)
|
||||
timerID = setTimeout(() => {
|
||||
// 播放中自动消失
|
||||
if (this.xg && !this.xg.paused) {
|
||||
videoTitle.style.display = 'none'
|
||||
}
|
||||
}, 3000)
|
||||
})
|
||||
})
|
||||
|
||||
this.xg.on('exitFullscreen', () => {
|
||||
document.querySelector('.xg-view-videoTitle').style.display = 'none'
|
||||
})
|
||||
},
|
||||
videoStop () {
|
||||
if (this.xg.fullscreen) {
|
||||
this.xg.exitFullscreen()
|
||||
}
|
||||
clearInterval(this.timer)
|
||||
this.video.key = ''
|
||||
this.xg.src = ''
|
||||
this.config.src = ''
|
||||
this.xg.destroy(false)
|
||||
this.xg = null
|
||||
this.name = ''
|
||||
this.right.list = []
|
||||
this.getAllhistory()
|
||||
setTimeout(() => {
|
||||
this.xg = new Hls(this.config)
|
||||
this.playerInstall()
|
||||
this.bindEvent()
|
||||
}, 1000)
|
||||
},
|
||||
minMaxEvent () {
|
||||
const win = remote.getCurrentWindow()
|
||||
win.on('minimize', () => {
|
||||
if (this.xg && this.xg.hasStart) {
|
||||
this.xg.pause()
|
||||
}
|
||||
})
|
||||
win.on('restore', () => {
|
||||
if (this.xg && this.config.src) {
|
||||
this.xg.play()
|
||||
}
|
||||
})
|
||||
},
|
||||
playerInstall () {
|
||||
Player.install('playPrev', function () {
|
||||
addPlayerBtn.bind(this, 'playPrev', '<svg t="1595866093990" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3657" style="width: 20px;height: 20px;margin-top: 11px;margin-left: 9px;" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M98.583851 3.180124h190.807453a31.801242 31.801242 0 0 1 31.801243 31.801242v387.021118L902.201242 10.176398l11.130435-7.632299A31.801242 31.801242 0 0 1 957.217391 31.801242v960.397516a31.801242 31.801242 0 0 1-43.885714 29.257143l-11.130435-7.632299L321.192547 601.997516V989.018634a31.801242 31.801242 0 0 1-31.801243 31.801242H98.583851a31.801242 31.801242 0 0 1-31.801242-31.801242v-954.037268a31.801242 31.801242 0 0 1 31.801242-31.801242z" p-id="3658" fill="#ffffff"></path></svg>', { title: '上一集' })()
|
||||
})
|
||||
Player.install('playNextOne', function () {
|
||||
addPlayerBtn.bind(this, 'playNextOne', '<svg t="1595866110378" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3946" style="width: 20px;height: 20px;margin-top: 11px;margin-left: 0px;" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M925.416149 3.180124h-190.807453a31.801242 31.801242 0 0 0-31.801243 31.801242v387.021118L121.798758 10.176398 110.668323 2.544099A31.801242 31.801242 0 0 0 98.583851 0a31.801242 31.801242 0 0 0-31.801242 31.801242v960.397516a31.801242 31.801242 0 0 0 31.801242 31.801242 31.801242 31.801242 0 0 0 12.084472-2.544099l11.130435-7.632299L702.807453 601.997516V989.018634a31.801242 31.801242 0 0 0 31.801243 31.801242h190.807453a31.801242 31.801242 0 0 0 31.801242-31.801242v-954.037268a31.801242 31.801242 0 0 0-31.801242-31.801242z" p-id="3947" fill="#ffffff"></path></svg>', { title: '下一集' })()
|
||||
})
|
||||
Player.install('videoStop', function () {
|
||||
addPlayerBtn.bind(this, 'videoStop', '<svg t="1603093629102" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3621" style="width: 25px;height: 25px;margin-top: 8px;margin-left: 0px;"><path d="M768 768H256V256h512v512z" p-id="3622" fill="#ffffff"></path></svg>', { title: '停止播放' })()
|
||||
})
|
||||
Player.install('showList', function () {
|
||||
addPlayerBtn.bind(this, 'showList', '<svg t="1595866128681" class="icon" viewBox="0 0 1316 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4187" style="width: 22px;height: 22px;margin-top: 9px;margin-left: 6px;" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M0 0h1316.571429v146.285714H0zM0 438.857143h1316.571429v146.285714H0zM0 877.714286h1316.571429v146.285714H0z" p-id="4188" fill="#ffffff"></path></svg>', { title: '播放列表' })()
|
||||
})
|
||||
Player.install('showHistory', function () {
|
||||
addPlayerBtn.bind(this, 'showHistory', '<svg t="1595866015473" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3282" style="width: 22px;height: 22px;margin-top: 9px;margin-left: 6px;" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M512 0a512 512 0 1 0 512 512A512 512 0 0 0 512 0z m0 910.222222a398.222222 398.222222 0 1 1 398.222222-398.222222 398.222222 398.222222 0 0 1-398.222222 398.222222z" p-id="3283" fill="#ffffff"></path><path d="M568.888889 227.555556h-113.777778v341.333333h227.555556v-113.777778h-113.777778V227.555556z" p-id="3284" fill="#ffffff"></path></svg>', { title: '播放历史' })()
|
||||
})
|
||||
const that = this
|
||||
Player.install('videoTitle', function () {
|
||||
let title
|
||||
if (that.right.list.length > 1) {
|
||||
title = `『第 ${that.video.info.index + 1} 集』${that.name}`
|
||||
} else {
|
||||
title = `${that.name}`
|
||||
}
|
||||
addPlayerView.bind(this, 'videoTitle', `<span>${title}</span>`, {})()
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
@@ -1018,42 +1159,20 @@ export default {
|
||||
this.mtEvent()
|
||||
},
|
||||
mounted () {
|
||||
Player.install('playPrev', function () {
|
||||
addPlayerBtn.bind(this, 'playPrev', '<svg t="1595866093990" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3657" style="width: 20px;height: 20px;margin-top: 11px;margin-left: 9px;" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M98.583851 3.180124h190.807453a31.801242 31.801242 0 0 1 31.801243 31.801242v387.021118L902.201242 10.176398l11.130435-7.632299A31.801242 31.801242 0 0 1 957.217391 31.801242v960.397516a31.801242 31.801242 0 0 1-43.885714 29.257143l-11.130435-7.632299L321.192547 601.997516V989.018634a31.801242 31.801242 0 0 1-31.801243 31.801242H98.583851a31.801242 31.801242 0 0 1-31.801242-31.801242v-954.037268a31.801242 31.801242 0 0 1 31.801242-31.801242z" p-id="3658" fill="#ffffff"></path></svg>', { title: '上一集' })()
|
||||
})
|
||||
Player.install('playNextOne', function () {
|
||||
addPlayerBtn.bind(this, 'playNextOne', '<svg t="1595866110378" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3946" style="width: 20px;height: 20px;margin-top: 11px;margin-left: 0px;" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M925.416149 3.180124h-190.807453a31.801242 31.801242 0 0 0-31.801243 31.801242v387.021118L121.798758 10.176398 110.668323 2.544099A31.801242 31.801242 0 0 0 98.583851 0a31.801242 31.801242 0 0 0-31.801242 31.801242v960.397516a31.801242 31.801242 0 0 0 31.801242 31.801242 31.801242 31.801242 0 0 0 12.084472-2.544099l11.130435-7.632299L702.807453 601.997516V989.018634a31.801242 31.801242 0 0 0 31.801243 31.801242h190.807453a31.801242 31.801242 0 0 0 31.801242-31.801242v-954.037268a31.801242 31.801242 0 0 0-31.801242-31.801242z" p-id="3947" fill="#ffffff"></path></svg>', { title: '下一集' })()
|
||||
})
|
||||
Player.install('showList', function () {
|
||||
addPlayerBtn.bind(this, 'showList', '<svg t="1595866128681" class="icon" viewBox="0 0 1316 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4187" style="width: 22px;height: 22px;margin-top: 9px;margin-left: 6px;" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M0 0h1316.571429v146.285714H0zM0 438.857143h1316.571429v146.285714H0zM0 877.714286h1316.571429v146.285714H0z" p-id="4188" fill="#ffffff"></path></svg>', { title: '播放列表' })()
|
||||
})
|
||||
Player.install('showHistory', function () {
|
||||
addPlayerBtn.bind(this, 'showHistory', '<svg t="1595866015473" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3282" style="width: 22px;height: 22px;margin-top: 9px;margin-left: 6px;" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M512 0a512 512 0 1 0 512 512A512 512 0 0 0 512 0z m0 910.222222a398.222222 398.222222 0 1 1 398.222222-398.222222 398.222222 398.222222 0 0 1-398.222222 398.222222z" p-id="3283" fill="#ffffff"></path><path d="M568.888889 227.555556h-113.777778v341.333333h227.555556v-113.777778h-113.777778V227.555556z" p-id="3284" fill="#ffffff"></path></svg>', { title: '播放历史' })()
|
||||
})
|
||||
const that = this
|
||||
Player.install('videoTitle', function () {
|
||||
let title
|
||||
if (that.right.list.length > 1) {
|
||||
title = `『第 ${that.video.info.index + 1} 集』${that.name}`
|
||||
} else {
|
||||
title = `${that.name}`
|
||||
}
|
||||
addPlayerView.bind(this, 'videoTitle', `<span>${title}</span>`, {})()
|
||||
})
|
||||
|
||||
this.playerInstall()
|
||||
this.xg = new Hls(this.config)
|
||||
ipcRenderer.on('miniClosed', () => {
|
||||
history.find({ site: this.video.key, ids: this.video.info.id }).then(res => {
|
||||
if (res) {
|
||||
if (this.video.info.index !== res.index) {
|
||||
this.video.info.index = res.index
|
||||
} else {
|
||||
this.getUrls()
|
||||
}
|
||||
ipcRenderer.on('miniClosed', async () => {
|
||||
const db = await history.find({ site: this.video.key, ids: this.video.info.id })
|
||||
if (db) {
|
||||
if (this.video.info.index !== db.index) {
|
||||
this.video.info.index = db.index
|
||||
} else {
|
||||
this.getUrls()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
this.bindEvent()
|
||||
this.minMaxEvent()
|
||||
},
|
||||
beforeDestroy () {
|
||||
clearInterval(this.timer)
|
||||
@@ -1061,7 +1180,11 @@ export default {
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.xgplayer-skin-default .xg-btn-playPrev {
|
||||
.xgplayer-skin-default .xg-btn-playPrev,
|
||||
.xgplayer-skin-default .xg-btn-playNextOne,
|
||||
.xgplayer-skin-default .xg-btn-showList,
|
||||
.xgplayer-skin-default .xg-btn-showHistory,
|
||||
.xgplayer-skin-default .xg-btn-videoStop {
|
||||
width: 32px;
|
||||
position: relative;
|
||||
-webkit-order: 0;
|
||||
@@ -1071,79 +1194,54 @@ export default {
|
||||
cursor: pointer;
|
||||
margin-left: 3px;
|
||||
}
|
||||
.xgplayer-skin-default .xg-btn-playPrev:hover {
|
||||
.xgplayer-skin-default .xg-btn-playPrev:hover,
|
||||
.xgplayer-skin-default .xg-btn-playNextOne:hover,
|
||||
.xgplayer-skin-default .xg-btn-showList:hover,
|
||||
.xgplayer-skin-default .xg-btn-showHistory:hover,
|
||||
.xgplayer-skin-default .xg-btn-videoStop:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
.xgplayer-skin-default .xg-btn-playNextOne {
|
||||
width: 32px;
|
||||
position: relative;
|
||||
-webkit-order: 2;
|
||||
-moz-box-ordinal-group: 1;
|
||||
order: 2;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
margin-left: 3px;
|
||||
}
|
||||
.xgplayer-skin-default .xg-btn-playNextOne:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
.xgplayer-skin-default .xgplayer-play, .xgplayer-skin-default .xgplayer-play-img {
|
||||
order: 1 !important;
|
||||
}
|
||||
.xgplayer-skin-default .xg-btn-showList {
|
||||
width: 32px;
|
||||
position: relative;
|
||||
-webkit-order: 4;
|
||||
-moz-box-ordinal-group: 1;
|
||||
order: 4;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
margin-right: 3px;
|
||||
.xgplayer-skin-default .xg-btn-videoStop {
|
||||
order: 2;
|
||||
}
|
||||
.xgplayer-skin-default .xg-btn-showList:hover {
|
||||
opacity: 0.8;
|
||||
.xgplayer-skin-default .xg-btn-showList {
|
||||
order: 4;
|
||||
}
|
||||
.xgplayer-skin-default .xg-btn-showHistory {
|
||||
width: 32px;
|
||||
position: relative;
|
||||
-webkit-order: 4;
|
||||
-moz-box-ordinal-group: 1;
|
||||
order: 4;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
margin-right: 3px;
|
||||
}
|
||||
.xgplayer-skin-default .xg-btn-showHistory:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
.xgplayer-skin-default .xg-btn-showList ul, .xgplayer-skin-default .xg-btn-showHistory ul {
|
||||
display: none;
|
||||
list-style: none;
|
||||
min-width: 85px;
|
||||
max-width: 300px;
|
||||
max-height: 60vh;
|
||||
overflow-y: scroll;
|
||||
background: rgba(0,0,0,.54);
|
||||
border-radius: 1px;
|
||||
position: absolute;
|
||||
bottom: 45px;
|
||||
left: 50%;
|
||||
-webkit-transform: translateX(-50%);
|
||||
-ms-transform: translateX(-50%);
|
||||
transform: translateX(-50%);
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
z-index: 26;
|
||||
cursor: pointer;
|
||||
display: none;
|
||||
list-style: none;
|
||||
min-width: 85px;
|
||||
max-width: 300px;
|
||||
max-height: 60vh;
|
||||
overflow-y: scroll;
|
||||
background: rgba(0,0,0,.54);
|
||||
border-radius: 1px;
|
||||
position: absolute;
|
||||
bottom: 45px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
z-index: 26;
|
||||
cursor: pointer;
|
||||
}
|
||||
.xgplayer-skin-default .xg-btn-showList ul li, .xgplayer-skin-default .xg-btn-showHistory ul li {
|
||||
opacity: .7;
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 13px;
|
||||
color: hsla(0,0%,100%,.8);
|
||||
position: relative;
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
opacity: .7;
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 13px;
|
||||
color: hsla(0,0%,100%,.8);
|
||||
position: relative;
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
.xgplayer-skin-default .xg-btn-showList ul li:first-child, .xgplayer-skin-default .xg-btn-showHistory ul li:first-child {
|
||||
position: relative;
|
||||
@@ -1153,26 +1251,26 @@ export default {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.xgplayer-skin-default .xg-btn-showList ul li.selected, .xgplayer-skin-default .xg-btn-showHistory ul li.selected, .xgplayer-skin-default .xg-btn-showList ul li:hover, .xgplayer-skin-default .xg-btn-showHistory ul li:hover {
|
||||
color: #fff;
|
||||
opacity: 1;
|
||||
color: #fff;
|
||||
opacity: 1;
|
||||
}
|
||||
.xgplayer-skin-default .xgplayer-volume {
|
||||
width: 32px !important;
|
||||
width: 32px !important;
|
||||
}
|
||||
.xgplayer-skin-default .xgplayer-playbackrate {
|
||||
width: 40px !important;
|
||||
width: 40px !important;
|
||||
}
|
||||
.xgplayer-skin-default .xgplayer-playbackrate .name {
|
||||
top: 10px !important;
|
||||
top: 10px !important;
|
||||
}
|
||||
.xgplayer-skin-default .xgplayer-playbackrate ul {
|
||||
bottom: 25px;
|
||||
}
|
||||
.xgplayer-skin-default .xgplayer-playbackrate ul li {
|
||||
font-size: 13px !important;
|
||||
font-size: 13px !important;
|
||||
}
|
||||
.xgplayer-skin-default .xgplayer-screenshot .name span {
|
||||
width: 40px !important;
|
||||
width: 40px !important;
|
||||
}
|
||||
.xgplayer-skin-default .xg-view-videoTitle {
|
||||
display: none;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<a @click="linkOpen('http://zyplayer.fun/')">官网</a>
|
||||
<a @click="linkOpen('https://github.com/Hunlongyu/ZY-Player')">Github</a>
|
||||
<a @click="linkOpen('https://github.com/Hunlongyu/ZY-Player/issues')">当前版本v{{pkg.version}} 反馈</a>
|
||||
<a style="color:#38dd77" @click="linkOpen('https://github.com/Hunlongyu/ZY-Player/releases/tag/v' + latestVersion)" v-show="latestVersion !== pkg.version" >最新版本v{{latestVersion}}</a>
|
||||
<a style="color:#38dd77" @click="quitAndInstall()" v-show="latestVersion !== pkg.version" >最新版本v{{latestVersion}}</a>
|
||||
</div>
|
||||
<div class="view">
|
||||
<div class="title">视图</div>
|
||||
@@ -42,6 +42,14 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="shortcut">
|
||||
<div class="title">缓存</div>
|
||||
<div class="shortcut-box">
|
||||
<div class="zy-select">
|
||||
<div class="vs-placeholder vs-noAfter" @click="clearCache">清理视频缓存</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="site">
|
||||
<div class="title">定位时间设置</div>
|
||||
<div class="zy-input">
|
||||
@@ -133,8 +141,9 @@
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import pkg from '../../package.json'
|
||||
import { setting, sites, shortcut, star } from '../lib/dexie'
|
||||
import { shell, clipboard, remote } from 'electron'
|
||||
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'
|
||||
export default {
|
||||
name: 'setting',
|
||||
@@ -143,7 +152,6 @@ export default {
|
||||
pkg: pkg,
|
||||
sitesList: [],
|
||||
shortcutList: [],
|
||||
favoritesList: [],
|
||||
show: {
|
||||
site: false,
|
||||
shortcut: false,
|
||||
@@ -170,6 +178,14 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
view: {
|
||||
get () {
|
||||
return this.$store.getters.getView
|
||||
},
|
||||
set (val) {
|
||||
this.SET_VIEW(val)
|
||||
}
|
||||
},
|
||||
setting: {
|
||||
get () {
|
||||
return this.$store.getters.getSetting
|
||||
@@ -188,7 +204,7 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_SETTING', 'SET_EDITSITES']),
|
||||
...mapMutations(['SET_SETTING', 'SET_VIEW', 'SET_EDITSITES']),
|
||||
linkOpen (e) {
|
||||
shell.openExternal(e)
|
||||
},
|
||||
@@ -210,7 +226,15 @@ export default {
|
||||
},
|
||||
getSites () {
|
||||
sites.all().then(res => {
|
||||
this.sitesList = res
|
||||
if (res.length <= 0) {
|
||||
this.$message.warning('检测到视频源未能正常加载, 即将重置源.')
|
||||
sites.clear().then(sites.bulkAdd(defaultSites).then(this.getSites()))
|
||||
} else {
|
||||
this.sitesList = res
|
||||
this.editSites = {
|
||||
sites: res
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
getShortcut () {
|
||||
@@ -218,16 +242,19 @@ export default {
|
||||
this.shortcutList = res
|
||||
})
|
||||
},
|
||||
getFavorites () {
|
||||
star.all().then(res => {
|
||||
this.favoritesList = res
|
||||
})
|
||||
},
|
||||
changeView (e) {
|
||||
this.d.view = e
|
||||
this.updateSettingEvent()
|
||||
this.show.view = false
|
||||
},
|
||||
async clearCache () {
|
||||
const win = remote.getCurrentWindow()
|
||||
const ses = win.webContents.session
|
||||
const size = await ses.getCacheSize() / 1024 / 1024
|
||||
const mb = size.toFixed(2)
|
||||
await ses.clearCache()
|
||||
this.$message.success(`清除缓存成功, 共清理 ${mb} MB`)
|
||||
},
|
||||
updateSettingEvent () {
|
||||
this.editPlayerPath = false
|
||||
this.setting = this.d
|
||||
@@ -277,10 +304,7 @@ export default {
|
||||
this.updateSettingEvent()
|
||||
},
|
||||
editSitesEvent () {
|
||||
this.editSites = {
|
||||
show: true,
|
||||
sites: this.sitesList
|
||||
}
|
||||
this.view = 'EditSites'
|
||||
},
|
||||
changeTheme (e) {
|
||||
this.d.theme = e
|
||||
@@ -293,7 +317,7 @@ export default {
|
||||
},
|
||||
expShortcut () {
|
||||
const arr = [...this.shortcutList]
|
||||
const str = JSON.stringify(arr, null, 4)
|
||||
const str = JSON.stringify(arr, null, 2)
|
||||
clipboard.writeText(str)
|
||||
this.$message.success('已复制到剪贴板')
|
||||
},
|
||||
@@ -326,14 +350,29 @@ export default {
|
||||
}
|
||||
},
|
||||
getLatestVersion () {
|
||||
const cheerio = require('cheerio')
|
||||
const axios = require('axios')
|
||||
var url = 'https://github.com/Hunlongyu/ZY-Player/releases'
|
||||
axios.get(url).then(res => {
|
||||
const $ = cheerio.load(res.data)
|
||||
var e = $('div.release-header')[0]
|
||||
var firstResult = $(e).find('div>div>a')
|
||||
this.latestVersion = firstResult.text()
|
||||
ipcRenderer.send('checkForUpdate')
|
||||
ipcRenderer.on('update-available', (e, info) => {
|
||||
this.latestVersion = info.version
|
||||
})
|
||||
ipcRenderer.on('update-error', () => {
|
||||
this.$message.warning = '更新出错.'
|
||||
})
|
||||
ipcRenderer.on('update-downloaded', () => {
|
||||
this.$message.info = '下载完毕, 退出安装'
|
||||
})
|
||||
},
|
||||
quitAndInstall () {
|
||||
ipcRenderer.send('quitAndInstall')
|
||||
},
|
||||
createContextMenu () {
|
||||
const { Menu, MenuItem } = remote
|
||||
const menu = new Menu()
|
||||
menu.append(new MenuItem({ label: '快速复制', role: 'copy' }))
|
||||
menu.append(new MenuItem({ label: '快速粘贴', role: 'paste' }))
|
||||
menu.append(new MenuItem({ label: '编辑', role: 'editMenu' }))
|
||||
window.addEventListener('contextmenu', e => {
|
||||
e.preventDefault()
|
||||
menu.popup(remote.getCurrentWindow())
|
||||
})
|
||||
}
|
||||
},
|
||||
@@ -341,8 +380,8 @@ export default {
|
||||
this.getSites()
|
||||
this.getSetting()
|
||||
this.getShortcut()
|
||||
this.getFavorites()
|
||||
this.getLatestVersion()
|
||||
this.createContextMenu()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -89,7 +89,7 @@ export default {
|
||||
})
|
||||
},
|
||||
picLoadEvent () {
|
||||
const dom = document.getElementById('right')
|
||||
const dom = document.getElementById('share')
|
||||
html2canvas(dom, { useCORS: true, allowTaint: true }).then(res => {
|
||||
const png = res.toDataURL('image/png')
|
||||
const p = nativeImage.createFromDataURL(png)
|
||||
|
||||
@@ -1,76 +1,77 @@
|
||||
<template>
|
||||
<div class="detail">
|
||||
<div class="detail-content">
|
||||
<div class="detail-header">
|
||||
<div class="zy-select">
|
||||
<div class="vs-placeholder vs-noAfter" @click="exportFavoritesEvent">
|
||||
导出
|
||||
</div>
|
||||
</div>
|
||||
<div class="zy-select">
|
||||
<div class="vs-placeholder vs-noAfter" @click="importFavoritesEvent">
|
||||
导入
|
||||
</div>
|
||||
</div>
|
||||
<div class="zy-select">
|
||||
<div class="vs-placeholder vs-noAfter" @click="clearFavoritesEvent">
|
||||
清空
|
||||
</div>
|
||||
</div>
|
||||
<div class="zy-select">
|
||||
<div class="vs-placeholder vs-noAfter" @click="updateAllEvent">
|
||||
同步所有收藏
|
||||
</div>
|
||||
</div>
|
||||
<div class="listpage" id="star">
|
||||
<div class="listpage-content">
|
||||
<div class="listpage-header">
|
||||
<el-button @click.stop="exportFavoritesEvent" icon="el-icon-upload2">导出</el-button>
|
||||
<el-button @click.stop="importFavoritesEvent" icon="el-icon-download">导入</el-button>
|
||||
<el-button @click.stop="clearFavoritesEvent" icon="el-icon-delete-solid">清空</el-button>
|
||||
<el-button @click.stop="updateAllEvent" icon="el-icon-refresh">同步所有收藏</el-button>
|
||||
</div>
|
||||
<div class="detail-body zy-scroll">
|
||||
<div class="zy-table">
|
||||
<div class="tBody zy-scroll">
|
||||
<ul>
|
||||
<li v-show="this.list.length > 0">
|
||||
<span class="name">名字</span>
|
||||
<span class="type">类型</span>
|
||||
<span class="time">上映</span>
|
||||
<span class="site">片源</span>
|
||||
<span class="note">备注</span>
|
||||
<span class="note">观看至</span>
|
||||
<span class="operate">
|
||||
<span class="btn"></span>
|
||||
<span class="btn"></span>
|
||||
<span class="btn"></span>
|
||||
<span class="btn"></span>
|
||||
<span class="btn"></span>
|
||||
</span>
|
||||
</li>
|
||||
<draggable v-model="list" @change="listUpdatedEvent">
|
||||
<transition-group>
|
||||
<li
|
||||
v-for="(i, j) in list"
|
||||
:key="j"
|
||||
@click="detailEvent(i)"
|
||||
:class="[i.hasUpdate ? 'zy-highlighted' : '']"
|
||||
>
|
||||
<span class="name">{{ i.name }}</span>
|
||||
<span class="type">{{ i.type }}</span>
|
||||
<span class="time">{{ i.year }}</span>
|
||||
<span class="site">{{ getSiteName(i.key) }}</span>
|
||||
<span class="note">{{ i.note }}</span>
|
||||
<span class="note">{{ getHistoryNote(i.index) }}</span>
|
||||
<span class="operate">
|
||||
<span class="btn" @click.stop="playEvent(i)">播放</span>
|
||||
<span class="btn" @click.stop="shareEvent(i)">分享</span>
|
||||
<span class="btn" @click.stop="updateEvent(i)">同步</span>
|
||||
<span class="btn" @click.stop="downloadEvent(i)"
|
||||
>下载</span
|
||||
>
|
||||
<span class="btn" @click.stop="deleteEvent(i)">删除</span>
|
||||
</span>
|
||||
</li>
|
||||
</transition-group>
|
||||
</draggable>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="listpage-body" id="star-table">
|
||||
<el-table size="mini" fit height="100%" row-key="id"
|
||||
ref="starTable"
|
||||
:data="list"
|
||||
:cell-class-name="checkUpdate"
|
||||
@row-click="detailEvent"
|
||||
@sort-change="handleSortChange">
|
||||
<el-table-column
|
||||
sortable
|
||||
:sort-method="sortByName"
|
||||
prop="name"
|
||||
label="片名">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:sort-by="['type', 'name']"
|
||||
sortable
|
||||
:sort-method="sortByType"
|
||||
prop="type"
|
||||
label="类型"
|
||||
width="100">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
sortable
|
||||
:sort-by="['year', 'name']"
|
||||
prop="year"
|
||||
label="上映"
|
||||
width="100"
|
||||
align="center">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:sort-by="['site', 'name']"
|
||||
sortable
|
||||
:sort-method="sortBySite"
|
||||
prop="site"
|
||||
width="120"
|
||||
label="片源">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ getSiteName(scope.row.key) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="list.some(e => e.note)"
|
||||
prop="note"
|
||||
width="120"
|
||||
label="备注">
|
||||
</el-table-column>
|
||||
<el-table-column v-if="list.some(e => e.index >= 0)"
|
||||
prop="index"
|
||||
width="120"
|
||||
label="观看至">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ getHistoryNote(scope.row.index) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
header-align="right"
|
||||
align="right">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click.stop="playEvent(scope.row)" type="text">播放</el-button>
|
||||
<el-button @click.stop="shareEvent(scope.row)" type="text">分享</el-button>
|
||||
<el-button @click.stop="downloadEvent(scope.row)" type="text">下载</el-button>
|
||||
<el-button @click.stop="deleteEvent(scope.row)" type="text">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -79,10 +80,9 @@
|
||||
import { mapMutations } from 'vuex'
|
||||
import { star, history, sites } from '../lib/dexie'
|
||||
import zy from '../lib/site/tools'
|
||||
import draggable from 'vuedraggable'
|
||||
import { remote } from 'electron'
|
||||
import fs from 'fs'
|
||||
|
||||
import Sortable from 'sortablejs'
|
||||
const { clipboard } = require('electron')
|
||||
export default {
|
||||
name: 'star',
|
||||
@@ -92,9 +92,6 @@ export default {
|
||||
sites: []
|
||||
}
|
||||
},
|
||||
components: {
|
||||
draggable
|
||||
},
|
||||
computed: {
|
||||
view: {
|
||||
get () {
|
||||
@@ -131,12 +128,29 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
view () {
|
||||
this.getFavorites()
|
||||
this.getAllsites()
|
||||
this.getFavorites()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
|
||||
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)
|
||||
},
|
||||
sortBySite (a, b) {
|
||||
const siteA = this.getSiteName(a.key)
|
||||
if (!siteA) {
|
||||
return -1
|
||||
} else {
|
||||
return siteA.localeCompare(this.getSiteName(b.key))
|
||||
}
|
||||
},
|
||||
detailEvent (e) {
|
||||
this.detail = {
|
||||
show: true,
|
||||
@@ -150,14 +164,13 @@ export default {
|
||||
this.clearHasUpdateFlag(e)
|
||||
}
|
||||
},
|
||||
playEvent (e) {
|
||||
history.find({ site: e.key, ids: e.ids }).then(res => {
|
||||
if (res) {
|
||||
this.video = { key: e.key, info: { id: res.ids, name: res.name, index: res.index } }
|
||||
} else {
|
||||
this.video = { key: e.key, info: { id: e.ids, name: e.name, index: 0 } }
|
||||
}
|
||||
})
|
||||
async playEvent (e) {
|
||||
const db = await history.find({ site: e.key, ids: e.ids })
|
||||
if (db) {
|
||||
this.video = { key: e.key, info: { id: db.ids, name: db.name, index: db.index } }
|
||||
} else {
|
||||
this.video = { key: e.key, info: { id: e.ids, name: e.name, index: 0 } }
|
||||
}
|
||||
if (e.hasUpdate) {
|
||||
this.clearHasUpdateFlag(e)
|
||||
}
|
||||
@@ -180,35 +193,33 @@ export default {
|
||||
info: e
|
||||
}
|
||||
},
|
||||
clearHasUpdateFlag (e) {
|
||||
star.find({ id: e.id }).then(res => {
|
||||
res.hasUpdate = false
|
||||
star.update(e.id, res)
|
||||
this.getFavorites()
|
||||
})
|
||||
checkUpdate ({ row, rowIndex }) {
|
||||
if (this.list[rowIndex].hasUpdate) {
|
||||
return 'highlight'
|
||||
}
|
||||
},
|
||||
listUpdatedEvent () {
|
||||
star.clear().then(res1 => {
|
||||
// 重新排序
|
||||
var id = this.list.length
|
||||
this.list.forEach(element => {
|
||||
element.id = id
|
||||
star.add(element)
|
||||
id -= 1
|
||||
})
|
||||
})
|
||||
async clearHasUpdateFlag (e) {
|
||||
const db = await star.find({ id: e.id })
|
||||
if (db) {
|
||||
db.hasUpdate = false
|
||||
star.update(e.id, db)
|
||||
this.getFavorites()
|
||||
}
|
||||
},
|
||||
updateEvent (e) {
|
||||
zy.detail(e.key, e.ids).then(res => {
|
||||
var doc = {
|
||||
key: e.key,
|
||||
id: e.id,
|
||||
key: e.key,
|
||||
ids: res.id,
|
||||
last: res.last,
|
||||
site: res.site,
|
||||
name: res.name,
|
||||
type: res.type,
|
||||
year: res.year,
|
||||
note: res.note
|
||||
note: res.note,
|
||||
index: res.index,
|
||||
last: res.last,
|
||||
hasUpdate: res.hasUpdate
|
||||
}
|
||||
star.get(e.id).then(resStar => {
|
||||
doc.hasUpdate = resStar.hasUpdate
|
||||
@@ -301,7 +312,7 @@ export default {
|
||||
},
|
||||
exportFavoritesEvent () {
|
||||
const arr = [...this.list]
|
||||
const str = JSON.stringify(arr, null, 4)
|
||||
const str = JSON.stringify(arr, null, 2)
|
||||
const options = {
|
||||
filters: [
|
||||
{ name: 'JSON file', extensions: ['json'] },
|
||||
@@ -329,84 +340,76 @@ export default {
|
||||
}
|
||||
remote.dialog.showOpenDialog(options).then(result => {
|
||||
if (!result.canceled) {
|
||||
var starList = this.list
|
||||
result.filePaths.forEach(file => {
|
||||
var str = fs.readFileSync(file)
|
||||
const json = JSON.parse(str)
|
||||
star.bulkAdd(json).then(e => {
|
||||
this.getFavorites()
|
||||
json.forEach(ele => {
|
||||
const starExists = starList.includes(x => x.key === ele.key && x.ids === ele.ids)
|
||||
if (!starExists) {
|
||||
var doc = {
|
||||
key: ele.key,
|
||||
ids: ele.ids,
|
||||
site: ele.site === undefined ? ele.site = this.sites.find(x => x.key === ele.key) : ele.site,
|
||||
name: ele.name,
|
||||
type: ele.type,
|
||||
year: ele.year,
|
||||
note: ele.note,
|
||||
index: ele.index,
|
||||
last: ele.last,
|
||||
hasUpdate: ele.hasUpdate
|
||||
}
|
||||
starList.push(doc)
|
||||
}
|
||||
})
|
||||
this.upgradeFavorites()
|
||||
})
|
||||
this.$message.success('导入收藏成功')
|
||||
star.clear().then(star.bulkAdd(starList).then(res => {
|
||||
this.getFavorites()
|
||||
this.$message.success('导入收藏成功')
|
||||
}))
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err)
|
||||
})
|
||||
},
|
||||
upgradeFavorites () {
|
||||
star.all().then(res => {
|
||||
res.forEach(element => {
|
||||
const docs = {
|
||||
key: element.key,
|
||||
ids: element.ids,
|
||||
name: element.name,
|
||||
type: element.type,
|
||||
year: element.year,
|
||||
last: element.last,
|
||||
note: element.note
|
||||
}
|
||||
star.find({ key: element.key, ids: element.ids }).then(res => {
|
||||
if (!res) {
|
||||
star.add(docs)
|
||||
}
|
||||
})
|
||||
})
|
||||
this.getFavorites()
|
||||
})
|
||||
},
|
||||
clearFavoritesEvent () {
|
||||
star.clear().then(e => {
|
||||
this.getFavorites()
|
||||
this.$message.success('清空所有收藏成功')
|
||||
})
|
||||
},
|
||||
syncTableData () {
|
||||
if (this.$refs.starTable.tableData && this.$refs.starTable.tableData.length === this.list.length) {
|
||||
this.list = this.$refs.starTable.tableData
|
||||
}
|
||||
},
|
||||
updateDatabase () {
|
||||
this.syncTableData()
|
||||
star.clear().then(res => {
|
||||
var id = this.list.length
|
||||
this.list.forEach(ele => {
|
||||
ele.id = id
|
||||
id -= 1
|
||||
})
|
||||
star.bulkAdd(this.list)
|
||||
})
|
||||
},
|
||||
rowDrop () {
|
||||
const tbody = document.getElementById('star-table').querySelector('.el-table__body-wrapper tbody')
|
||||
const _this = this
|
||||
Sortable.create(tbody, {
|
||||
onEnd ({ newIndex, oldIndex }) {
|
||||
const currRow = _this.list.splice(oldIndex, 1)[0]
|
||||
_this.list.splice(newIndex, 0, currRow)
|
||||
_this.updateDatabase()
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.rowDrop()
|
||||
},
|
||||
created () {
|
||||
this.getFavorites()
|
||||
window.Sortable = require('sortablejs').Sortable
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.detail{
|
||||
position: absolute;
|
||||
left: 80px;
|
||||
right: 20px;
|
||||
bottom: 0;
|
||||
width: calc(100% - 100px);
|
||||
height: calc(100% - 40px);
|
||||
z-index: 888;
|
||||
.detail-content{
|
||||
height: calc(100% - 10px);
|
||||
padding: 0 60px;
|
||||
position: relative;
|
||||
.detail-header{
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
.detail-title{
|
||||
font-size: 16px;
|
||||
}
|
||||
.detail-close{
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
.detail-body{
|
||||
height: calc(100% - 50px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -3,16 +3,16 @@ import { setting, sites, localKey, iptv } from './initData'
|
||||
|
||||
const db = new Dexie('zy')
|
||||
|
||||
db.version(3).stores({
|
||||
db.version(4).stores({
|
||||
search: '++id, keywords',
|
||||
iptvSearch: '++id, keywords',
|
||||
setting: 'id, theme, site, shortcut, view, externalPlayer, searchAllSites, excludeRootClasses, excludeR18Films, forwardTimeInSec',
|
||||
shortcut: 'name, key, desc',
|
||||
star: '++id, site, ids, name, type, year, index',
|
||||
sites: '++id, key, name, json, xml, down, level',
|
||||
history: '++id, site, ids, name, type, year, index, time',
|
||||
star: '++id, [key+ids], site, name, type, year, note, index, last, 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'
|
||||
iptv: '++id, name, url, group'
|
||||
})
|
||||
|
||||
db.on('populate', () => {
|
||||
|
||||
@@ -4,8 +4,11 @@ export default {
|
||||
async add (doc) {
|
||||
return await history.add(doc)
|
||||
},
|
||||
async bulkAdd (doc) {
|
||||
return await history.bulkAdd(doc)
|
||||
},
|
||||
async find (doc) {
|
||||
return await history.get(doc)
|
||||
return await history.where(doc).first()
|
||||
},
|
||||
async update (id, docs) {
|
||||
return await history.update(id, docs)
|
||||
|
||||
1670
src/lib/dexie/iniData/Iptv.json
Normal file
1670
src/lib/dexie/iniData/Iptv.json
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ export default {
|
||||
return await star.bulkAdd(doc)
|
||||
},
|
||||
async find (doc) {
|
||||
return await star.get(doc)
|
||||
return await star.where(doc).first()
|
||||
},
|
||||
async update (id, docs) {
|
||||
return await star.update(id, docs)
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
import Vue from 'vue'
|
||||
import { Message } from 'element-ui'
|
||||
import { Message, Button, Table, TableColumn, Tag, Input, Dialog, Form, FormItem, Switch, Select, Option } from 'element-ui'
|
||||
import Plugin from 'v-fit-columns'
|
||||
Vue.use(Button)
|
||||
Vue.use(Table)
|
||||
Vue.use(TableColumn)
|
||||
Vue.use(Tag)
|
||||
Vue.use(Input)
|
||||
Vue.use(Dialog)
|
||||
Vue.use(Form)
|
||||
Vue.use(FormItem)
|
||||
Vue.use(Switch)
|
||||
Vue.use(Plugin)
|
||||
Vue.use(Select)
|
||||
Vue.use(Option)
|
||||
Vue.prototype.$message = Message
|
||||
|
||||
@@ -3,6 +3,36 @@ import axios from 'axios'
|
||||
import cheerio from 'cheerio'
|
||||
|
||||
const onlineVideo = {
|
||||
playVideoOnline (selectedOnlineSite, videoName, videoIndex) {
|
||||
switch (selectedOnlineSite) {
|
||||
case '哔嘀':
|
||||
onlineVideo.playVideoOnBde4(videoName, videoIndex)
|
||||
break
|
||||
case '1080影视':
|
||||
onlineVideo.playVideoOnK1080(videoName, videoIndex)
|
||||
break
|
||||
case '素白白':
|
||||
onlineVideo.playVideoOnSubaibai(videoName, videoIndex)
|
||||
break
|
||||
case '哆咪动漫':
|
||||
onlineVideo.playVideoOndmdm2020(videoName, videoIndex)
|
||||
break
|
||||
case '樱花动漫':
|
||||
onlineVideo.playVideoOnYhdm(videoName, videoIndex)
|
||||
break
|
||||
case '简影':
|
||||
onlineVideo.playVideoOnSyrme(videoName, videoIndex)
|
||||
break
|
||||
case '极品':
|
||||
onlineVideo.playVideoOnJpysvip(videoName, videoIndex)
|
||||
break
|
||||
case '喜欢看':
|
||||
onlineVideo.playVideoOnXhkan(videoName, videoIndex)
|
||||
break
|
||||
default:
|
||||
this.$message.console.error(`不支持该网站:${this.selectedOnlineSite}`)
|
||||
}
|
||||
},
|
||||
playVideoOnBde4 (videoName, videoIndex) {
|
||||
videoName = videoName.replace(/\s/g, '')
|
||||
var url = `https://bde4.com/search/${videoName}`
|
||||
@@ -214,6 +244,74 @@ const onlineVideo = {
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
playVideoOnJpysvip (videoName, videoIndex) {
|
||||
videoName = videoName.replace(/\s/g, '')
|
||||
var url = `https://www.jpysvip.net/vodsearch/-------------.html?wd=${videoName}&submit=`
|
||||
axios.get(url).then(res => {
|
||||
const $ = cheerio.load(res.data)
|
||||
var e = $('#searchList')
|
||||
var searchResult = $(e).find('ul>li>div>a').toArray()
|
||||
// 获取第一个搜索结果的视频链接
|
||||
var detailPageLink = $(searchResult[0]).attr('href')
|
||||
// 获取第一个搜索结果的title
|
||||
var title = $(searchResult[0]).attr('title')
|
||||
if (title === null || title === undefined || !title.replace(/\s/g, '').includes(videoName)) {
|
||||
// 如果第一个搜索结果不符合,打开搜索页面
|
||||
open(url)
|
||||
} else {
|
||||
// 解析详情页面
|
||||
var detailPageFullLink = 'https://www.jpysvip.net' + detailPageLink
|
||||
axios.get(detailPageFullLink).then(res2 => {
|
||||
const $ = cheerio.load(res2.data)
|
||||
// 获取playlist1
|
||||
var e = $('#playlist1')
|
||||
// 获取所有视频链接
|
||||
var videoList = $(e).find('div>ul>li>a').toArray()
|
||||
// 获取index视频链接
|
||||
var videoFullLink = detailPageFullLink
|
||||
if (videoIndex < videoList.length) {
|
||||
var indexVideoLink = $(videoList[videoIndex]).attr('href')
|
||||
videoFullLink = 'https://www.jpysvip.net/' + indexVideoLink
|
||||
}
|
||||
open(videoFullLink)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
playVideoOnXhkan (videoName, videoIndex) {
|
||||
videoName = videoName.replace(/\s/g, '')
|
||||
var url = `https://www.xhkan.com/vodsearch.html?wd=${videoName}&submit=`
|
||||
axios.get(url).then(res => {
|
||||
const $ = cheerio.load(res.data)
|
||||
var e = $('#searchList')
|
||||
var searchResult = $(e).find('ul>li>div>a').toArray()
|
||||
// 获取第一个搜索结果的视频链接
|
||||
var detailPageLink = $(searchResult[0]).attr('href')
|
||||
// 获取第一个搜索结果的title
|
||||
var title = $(searchResult[0]).attr('title')
|
||||
if (title === null || title === undefined || !title.replace(/\s/g, '').includes(videoName)) {
|
||||
// 如果第一个搜索结果不符合,打开搜索页面
|
||||
open(url)
|
||||
} else {
|
||||
// 解析详情页面
|
||||
var detailPageFullLink = detailPageLink
|
||||
axios.get(detailPageFullLink).then(res2 => {
|
||||
const $ = cheerio.load(res2.data)
|
||||
// 获取playlist1
|
||||
var e = $('#playlist1')
|
||||
// 获取所有视频链接
|
||||
var videoList = $(e).find('div>ul>li>a').toArray()
|
||||
// 获取index视频链接
|
||||
var videoFullLink = detailPageFullLink
|
||||
if (videoIndex < videoList.length) {
|
||||
var indexVideoLink = $(videoList[videoIndex]).attr('href')
|
||||
videoFullLink = indexVideoLink
|
||||
}
|
||||
open(videoFullLink)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
export default onlineVideo
|
||||
|
||||
@@ -193,6 +193,23 @@ const zy = {
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 检查资源
|
||||
* @param {*} key 资源网 key
|
||||
* @returns boolean
|
||||
*/
|
||||
async check (key, id) {
|
||||
try {
|
||||
const cls = await this.class(key)
|
||||
if (cls) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
48
src/lib/update/update.js
Normal file
48
src/lib/update/update.js
Normal file
@@ -0,0 +1,48 @@
|
||||
import { BrowserWindow, ipcMain } from 'electron'
|
||||
import { autoUpdater } from 'electron-updater'
|
||||
|
||||
export function initUpdater (win = BrowserWindow) {
|
||||
autoUpdater.autoDownload = false
|
||||
autoUpdater.autoInstallOnAppQuit = false
|
||||
|
||||
// 主进程监听检查更新事件
|
||||
ipcMain.on('checkForUpdate', () => {
|
||||
autoUpdater.checkForUpdates()
|
||||
})
|
||||
|
||||
// 主进程监听退出并安装事件
|
||||
ipcMain.on('quitAndInstall', () => {
|
||||
autoUpdater.downloadUpdate()
|
||||
})
|
||||
|
||||
// 开始检测是否有更新
|
||||
autoUpdater.on('checking-for-update', () => {
|
||||
win.webContents.send('checking-for-update')
|
||||
})
|
||||
|
||||
// 检测到有可用的更新
|
||||
autoUpdater.on('update-available', (info) => {
|
||||
win.webContents.send('update-available', info)
|
||||
})
|
||||
|
||||
// 没有检测到有可用的更新
|
||||
autoUpdater.on('update-not-available', () => {
|
||||
win.webContents.send('update-not-available')
|
||||
})
|
||||
|
||||
// 更新出错
|
||||
autoUpdater.on('update-error', err => {
|
||||
win.webContents.send('update-error', err)
|
||||
})
|
||||
|
||||
// 下载更新进度
|
||||
autoUpdater.on('download-progress', (progressObj) => {
|
||||
win.webContents.send('download-progress', progressObj)
|
||||
})
|
||||
|
||||
// 下载完成并退出安装
|
||||
autoUpdater.on('update-downloaded', () => {
|
||||
win.webContents.send('update-downloaded')
|
||||
autoUpdater.quitAndInstall()
|
||||
})
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import store from './store'
|
||||
import 'modern-normalize'
|
||||
import Register from './components/register'
|
||||
import './lib/element/index'
|
||||
|
||||
Register.registerComponents()
|
||||
Vue.config.productionTip = false
|
||||
new Vue({
|
||||
|
||||
@@ -175,49 +175,48 @@ export default {
|
||||
})
|
||||
})
|
||||
},
|
||||
videoPlaying () {
|
||||
history.find({ site: this.video.site, ids: this.video.ids }).then(res => {
|
||||
if (res) {
|
||||
res.index = this.video.index
|
||||
history.update(res.id, res)
|
||||
} else {
|
||||
const doc = {
|
||||
site: this.video.site,
|
||||
ids: this.video.ids,
|
||||
name: this.video.name,
|
||||
index: this.video.index,
|
||||
time: 0
|
||||
}
|
||||
history.add(doc)
|
||||
async videoPlaying () {
|
||||
const db = await history.find({ site: this.video.site, ids: this.video.ids })
|
||||
if (db) {
|
||||
db.index = this.video.index
|
||||
history.update(db.id, db)
|
||||
} else {
|
||||
const doc = {
|
||||
site: this.video.site,
|
||||
ids: this.video.ids,
|
||||
name: this.video.name,
|
||||
index: this.video.index,
|
||||
time: 0
|
||||
}
|
||||
})
|
||||
history.add(doc)
|
||||
}
|
||||
this.timerEvent()
|
||||
},
|
||||
timerEvent () {
|
||||
this.timer = setInterval(() => {
|
||||
this.timer = setInterval(async () => {
|
||||
const endTime = this.xg.duration
|
||||
const currentTime = this.xg.currentTime
|
||||
const progress = (currentTime / endTime) * 100
|
||||
this.progress = progress.toFixed(2)
|
||||
history.find({ site: this.video.site, ids: this.video.ids }).then(res => {
|
||||
if (res) {
|
||||
const v = res
|
||||
v.time = this.xg.currentTime
|
||||
v.index = this.video.index
|
||||
const id = v.id
|
||||
delete v.id
|
||||
history.update(id, v)
|
||||
}
|
||||
})
|
||||
const db = await history.find({ site: this.video.site, ids: this.video.ids })
|
||||
if (db) {
|
||||
const v = db
|
||||
v.time = this.xg.currentTime
|
||||
v.index = this.video.index
|
||||
const id = v.id
|
||||
delete v.id
|
||||
history.update(id, v)
|
||||
}
|
||||
}, 10000)
|
||||
},
|
||||
prevEvent () {
|
||||
async prevEvent () {
|
||||
if (this.video.index === 0) {
|
||||
this.$message.info('已是第一集.')
|
||||
return false
|
||||
}
|
||||
history.find({ site: this.video.site, ids: this.video.ids }).then(res => {
|
||||
const v = res
|
||||
const db = await history.find({ site: this.video.site, ids: this.video.ids })
|
||||
if (db) {
|
||||
const v = db
|
||||
const id = v.id
|
||||
v.index--
|
||||
delete v.id
|
||||
@@ -225,15 +224,16 @@ export default {
|
||||
this.xg.src = this.m3u8Arr[v.index]
|
||||
this.video.index--
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
nextEvent () {
|
||||
async nextEvent () {
|
||||
if (this.video.index >= this.m3u8Arr.length - 1) {
|
||||
this.$message.info('已是最后一集.')
|
||||
return false
|
||||
}
|
||||
history.find({ site: this.video.site, ids: this.video.ids }).then(res => {
|
||||
const v = res
|
||||
const db = await history.find({ site: this.video.site, ids: this.video.ids })
|
||||
if (db) {
|
||||
const v = db
|
||||
v.index++
|
||||
const id = v.id
|
||||
delete v.id
|
||||
@@ -241,7 +241,7 @@ export default {
|
||||
this.xg.src = this.m3u8Arr[v.index]
|
||||
this.video.index++
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
playbackRateEvent (e) {
|
||||
let rate = this.xg.playbackRate
|
||||
|
||||
@@ -27,7 +27,6 @@ export default new Vuex.Store({
|
||||
info: {}
|
||||
},
|
||||
editSites: {
|
||||
show: false,
|
||||
sites: []
|
||||
}
|
||||
},
|
||||
|
||||
167
yarn.lock
167
yarn.lock
@@ -1023,6 +1023,11 @@
|
||||
resolved "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24"
|
||||
integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==
|
||||
|
||||
"@types/semver@^7.3.1":
|
||||
version "7.3.4"
|
||||
resolved "https://registry.npm.taobao.org/@types/semver/download/@types/semver-7.3.4.tgz#43d7168fec6fa0988bb1a513a697b29296721afb"
|
||||
integrity sha1-Q9cWj+xvoJiLsaUTppeykpZyGvs=
|
||||
|
||||
"@types/yargs-parser@*":
|
||||
version "15.0.0"
|
||||
resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d"
|
||||
@@ -1809,12 +1814,12 @@ aws4@^1.8.0:
|
||||
resolved "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2"
|
||||
integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==
|
||||
|
||||
axios@^0.19.2:
|
||||
version "0.19.2"
|
||||
resolved "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
|
||||
integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
|
||||
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=
|
||||
dependencies:
|
||||
follow-redirects "1.5.10"
|
||||
follow-redirects "^1.10.0"
|
||||
|
||||
babel-eslint@^10.1.0:
|
||||
version "10.1.0"
|
||||
@@ -2166,6 +2171,14 @@ builder-util-runtime@8.7.1:
|
||||
debug "^4.2.0"
|
||||
sax "^1.2.4"
|
||||
|
||||
builder-util-runtime@8.7.2:
|
||||
version "8.7.2"
|
||||
resolved "https://registry.npm.taobao.org/builder-util-runtime/download/builder-util-runtime-8.7.2.tgz#d93afc71428a12789b437e13850e1fa7da956d72"
|
||||
integrity sha1-2Tr8cUKKEnibQ34ThQ4fp9qVbXI=
|
||||
dependencies:
|
||||
debug "^4.1.1"
|
||||
sax "^1.2.4"
|
||||
|
||||
builder-util@22.7.0:
|
||||
version "22.7.0"
|
||||
resolved "https://registry.npmjs.org/builder-util/-/builder-util-22.7.0.tgz#0776a66e6d6e408a78bed7f17a7ad22516d9e7f0"
|
||||
@@ -3175,10 +3188,10 @@ d@1, d@^1.0.1:
|
||||
es5-ext "^0.10.50"
|
||||
type "^1.0.1"
|
||||
|
||||
danmu.js@^0.2.17:
|
||||
version "0.2.18"
|
||||
resolved "https://registry.npmjs.org/danmu.js/-/danmu.js-0.2.18.tgz#fd688e7df50367a8a68630d1a189a0132c08dd9c"
|
||||
integrity sha512-ALfB4o0eQoK5pceEQCwyHmmg2wcxOOGqOflxodVtuc9Prq9Fyb2MAiyrfA+q/4WV1E4CnjoCep/8YHKy1X9IQg==
|
||||
danmu.js@0.2.23:
|
||||
version "0.2.23"
|
||||
resolved "https://registry.npm.taobao.org/danmu.js/download/danmu.js-0.2.23.tgz#339b512152ed5a8253829be007c5be5bd3821856"
|
||||
integrity sha1-M5tRIVLtWoJTgpvgB8W+W9OCGFY=
|
||||
dependencies:
|
||||
event-emitter "^0.3.5"
|
||||
|
||||
@@ -3201,13 +3214,6 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9:
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@=3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@^3.1.1, debug@^3.2.5:
|
||||
version "3.2.6"
|
||||
resolved "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
|
||||
@@ -3382,10 +3388,10 @@ detect-node@^2.0.4:
|
||||
resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
|
||||
integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==
|
||||
|
||||
dexie@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.npmjs.org/dexie/-/dexie-3.0.1.tgz#faafeb94be0d5e18b25d700546a2c05725511cfc"
|
||||
integrity sha512-/s4KzlaerQnCad/uY1ZNdFckTrbdMVhLlziYQzz62Ff9Ick1lHGomvTXNfwh4ApEZATyXRyVk5F6/y8UU84B0w==
|
||||
dexie@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.npm.taobao.org/dexie/download/dexie-3.0.2.tgz#4b979904d739e0530b68352005f175a82633a075"
|
||||
integrity sha1-S5eZBNc54FMLaDUgBfF1qCYzoHU=
|
||||
|
||||
diffie-hellman@^5.0.0:
|
||||
version "5.0.3"
|
||||
@@ -3664,10 +3670,23 @@ electron-to-chromium@^1.3.488:
|
||||
resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.496.tgz#3f43d32930481d82ad3663d79658e7c59a58af0b"
|
||||
integrity sha512-TXY4mwoyowwi4Lsrq9vcTUYBThyc1b2hXaTZI13p8/FRhY2CTaq5lK+DVjhYkKiTLsKt569Xes+0J5JsVXFurQ==
|
||||
|
||||
electron@^9.3.1:
|
||||
version "9.3.1"
|
||||
resolved "https://registry.yarnpkg.com/electron/-/electron-9.3.1.tgz#e301932c5c0537d8c9a8850d216d3ba454dbf55c"
|
||||
integrity sha512-DScrhqBT4a54KfdF0EoipALpHmdQTn3m7SSCtbpTcEcG+UDUiXad2cOfW6DHeVH7N+CVDKDG12q2PhVJjXkFAA==
|
||||
electron-updater@^4.3.5:
|
||||
version "4.3.5"
|
||||
resolved "https://registry.npm.taobao.org/electron-updater/download/electron-updater-4.3.5.tgz?cache=0&sync_timestamp=1600328924432&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Felectron-updater%2Fdownload%2Felectron-updater-4.3.5.tgz#4fb36f593a031c87ea07ee141c9f064d5deffb15"
|
||||
integrity sha1-T7NvWToDHIfqB+4UHJ8GTV3v+xU=
|
||||
dependencies:
|
||||
"@types/semver" "^7.3.1"
|
||||
builder-util-runtime "8.7.2"
|
||||
fs-extra "^9.0.1"
|
||||
js-yaml "^3.14.0"
|
||||
lazy-val "^1.0.4"
|
||||
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=
|
||||
dependencies:
|
||||
"@electron/get" "^1.0.1"
|
||||
"@types/node" "^12.0.12"
|
||||
@@ -4121,6 +4140,11 @@ eventemitter3@^4.0.0:
|
||||
resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384"
|
||||
integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==
|
||||
|
||||
eventemitter3@^4.0.7:
|
||||
version "4.0.7"
|
||||
resolved "https://registry.npm.taobao.org/eventemitter3/download/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
||||
integrity sha1-Lem2j2Uo1WRO9cWVJqG0oHMGFp8=
|
||||
|
||||
events@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.npmjs.org/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59"
|
||||
@@ -4528,18 +4552,16 @@ flush-write-stream@^1.0.0:
|
||||
inherits "^2.0.3"
|
||||
readable-stream "^2.3.6"
|
||||
|
||||
follow-redirects@1.5.10:
|
||||
version "1.5.10"
|
||||
resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
|
||||
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
|
||||
dependencies:
|
||||
debug "=3.1.0"
|
||||
|
||||
follow-redirects@^1.0.0:
|
||||
version "1.12.1"
|
||||
resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.12.1.tgz#de54a6205311b93d60398ebc01cf7015682312b6"
|
||||
integrity sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg==
|
||||
|
||||
follow-redirects@^1.10.0:
|
||||
version "1.13.0"
|
||||
resolved "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db"
|
||||
integrity sha1-tC6Nk6Kn7qXtiGM2dtZZe8jjhNs=
|
||||
|
||||
for-in@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
||||
@@ -5081,10 +5103,10 @@ html-webpack-plugin@^3.2.0:
|
||||
toposort "^1.0.0"
|
||||
util.promisify "1.0.0"
|
||||
|
||||
html2canvas@^1.0.0-rc.5:
|
||||
version "1.0.0-rc.5"
|
||||
resolved "https://registry.npmjs.org/html2canvas/-/html2canvas-1.0.0-rc.5.tgz#4ee3cac9f6e20a0fa0c2f35a6f99c960ae7ec4c1"
|
||||
integrity sha512-DtNqPxJNXPoTajs+lVQzGS1SULRI4GQaROeU5R41xH8acffHukxRh/NBVcTBsfCkJSkLq91rih5TpbEwUP9yWA==
|
||||
html2canvas@^1.0.0-rc.7:
|
||||
version "1.0.0-rc.7"
|
||||
resolved "https://registry.npm.taobao.org/html2canvas/download/html2canvas-1.0.0-rc.7.tgz#70c159ce0e63954a91169531894d08ad5627ac98"
|
||||
integrity sha1-cMFZzg5jlUqRFpUxiU0IrVYnrJg=
|
||||
dependencies:
|
||||
css-line-break "1.1.1"
|
||||
|
||||
@@ -6070,6 +6092,11 @@ lodash.defaultsdeep@^4.6.1:
|
||||
resolved "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6"
|
||||
integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==
|
||||
|
||||
lodash.isequal@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.npm.taobao.org/lodash.isequal/download/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
||||
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
|
||||
|
||||
lodash.kebabcase@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36"
|
||||
@@ -6440,10 +6467,10 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
|
||||
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
||||
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
||||
|
||||
modern-normalize@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.npmjs.org/modern-normalize/-/modern-normalize-0.6.0.tgz#21a469988edfc7c9020348e7a3b5b3583a1c9406"
|
||||
integrity sha512-gzvL1uFLV4EErHhaKoqTcrx52/sea6AIcMFWz/GBCuFrDBp485wSgyX5M+MZsj+grfcuqYLQGfHjDRrCvvwZLw==
|
||||
modern-normalize@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npm.taobao.org/modern-normalize/download/modern-normalize-1.0.0.tgz#539d84a1e141338b01b346f3e27396d0ed17601e"
|
||||
integrity sha1-U52EoeFBM4sBs0bz4nOW0O0XYB4=
|
||||
|
||||
mousetrap@^1.6.5:
|
||||
version "1.6.5"
|
||||
@@ -9584,6 +9611,11 @@ uuid@^3.3.2, uuid@^3.4.0:
|
||||
resolved "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
|
||||
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
|
||||
|
||||
v-fit-columns@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.npm.taobao.org/v-fit-columns/download/v-fit-columns-0.2.0.tgz#4d75b0eb66fcd701025044f356cc00e8d6fec7a2"
|
||||
integrity sha1-TXWw62b81wECUETzVswA6Nb+x6I=
|
||||
|
||||
v8-compile-cache@^2.0.3:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745"
|
||||
@@ -9687,10 +9719,10 @@ vue-style-loader@^4.1.0, vue-style-loader@^4.1.2:
|
||||
hash-sum "^1.0.2"
|
||||
loader-utils "^1.0.2"
|
||||
|
||||
vue-template-compiler@^2.6.11:
|
||||
version "2.6.11"
|
||||
resolved "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz#c04704ef8f498b153130018993e56309d4698080"
|
||||
integrity sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA==
|
||||
vue-template-compiler@^2.6.12:
|
||||
version "2.6.12"
|
||||
resolved "https://registry.npm.taobao.org/vue-template-compiler/download/vue-template-compiler-2.6.12.tgz?cache=0&sync_timestamp=1602239010008&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-template-compiler%2Fdownload%2Fvue-template-compiler-2.6.12.tgz#947ed7196744c8a5285ebe1233fe960437fcc57e"
|
||||
integrity sha1-lH7XGWdEyKUoXr4SM/6WBDf8xX4=
|
||||
dependencies:
|
||||
de-indent "^1.0.2"
|
||||
he "^1.1.0"
|
||||
@@ -9700,27 +9732,27 @@ vue-template-es2015-compiler@^1.9.0:
|
||||
resolved "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825"
|
||||
integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==
|
||||
|
||||
vue-waterfall-plugin@^1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.npmjs.org/vue-waterfall-plugin/-/vue-waterfall-plugin-1.0.7.tgz#bd351e8d3015b9ce71320e00a88443929d63465f"
|
||||
integrity sha512-60JlBvrQbIOapGwc9AW9cXV064uzIEV1bjzc1ApNGt+MI4PI0Xs9aDvFgRMsGdynV9UlsLNtplX0bRwJ1syT9A==
|
||||
vue-waterfall-plugin@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npm.taobao.org/vue-waterfall-plugin/download/vue-waterfall-plugin-1.1.0.tgz#a4d87c74b72f1e36de5bbbadf1d645eb549ed592"
|
||||
integrity sha1-pNh8dLcvHjbeW7ut8dZF61Se1ZI=
|
||||
|
||||
vue@^2.6.11:
|
||||
version "2.6.11"
|
||||
resolved "https://registry.npmjs.org/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5"
|
||||
integrity sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ==
|
||||
vue@^2.6.12:
|
||||
version "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.1:
|
||||
version "2.24.1"
|
||||
resolved "https://registry.yarnpkg.com/vuedraggable/-/vuedraggable-2.24.1.tgz#304abd7644dde05c1f199a227bf9e9107f56197a"
|
||||
integrity sha512-G1fxO1oshx+WLdieSGl6jSJdlHOQFga1FpjuUpgXldbpKNzxpjsGn4xYNnRHVrOAqm8aG5FfpdQlh5LHesxCeA==
|
||||
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=
|
||||
dependencies:
|
||||
sortablejs "^1.10.1"
|
||||
|
||||
vuex@^3.4.0:
|
||||
vuex@^3.5.1:
|
||||
version "3.5.1"
|
||||
resolved "https://registry.npmjs.org/vuex/-/vuex-3.5.1.tgz#f1b8dcea649bc25254cf4f4358081dbf5da18b3d"
|
||||
integrity sha512-w7oJzmHQs0FM9LXodfskhw9wgKBiaB+totOdb8sNzbTB2KDCEEwEs29NzBZFh/lmEK1t5tDmM1vtsO7ubG1DFw==
|
||||
resolved "https://registry.npm.taobao.org/vuex/download/vuex-3.5.1.tgz#f1b8dcea649bc25254cf4f4358081dbf5da18b3d"
|
||||
integrity sha1-8bjc6mSbwlJUz09DWAgdv12hiz0=
|
||||
|
||||
watchpack-chokidar2@^2.0.0:
|
||||
version "2.0.0"
|
||||
@@ -9994,22 +10026,23 @@ xdg-basedir@^4.0.0:
|
||||
resolved "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"
|
||||
integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==
|
||||
|
||||
xgplayer-hls.js@^2.2.3:
|
||||
version "2.2.3"
|
||||
resolved "https://registry.yarnpkg.com/xgplayer-hls.js/-/xgplayer-hls.js-2.2.3.tgz#bf538911145346c447528d609fc95dd267a24d81"
|
||||
integrity sha512-CFsZanBHHRbqTmqYCFFONk76oWwJwbn+8LK/XkwBBrUrqGPQPmrXfjelGjKDDGfZ+w3xReC1nGom3IpN+lLoaQ==
|
||||
xgplayer-hls.js@^2.2.5:
|
||||
version "2.2.5"
|
||||
resolved "https://registry.npm.taobao.org/xgplayer-hls.js/download/xgplayer-hls.js-2.2.5.tgz?cache=0&sync_timestamp=1600935842683&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fxgplayer-hls.js%2Fdownload%2Fxgplayer-hls.js-2.2.5.tgz#8f90980cf2b6b4610b5449a3a55a4e7d87335cc8"
|
||||
integrity sha1-j5CYDPK2tGELVEmjpVpOfYczXMg=
|
||||
dependencies:
|
||||
deepmerge "2.0.1"
|
||||
event-emitter "^0.3.5"
|
||||
eventemitter3 "^4.0.7"
|
||||
|
||||
xgplayer@^2.9.10:
|
||||
version "2.9.10"
|
||||
resolved "https://registry.yarnpkg.com/xgplayer/-/xgplayer-2.9.10.tgz#4e79b889621f829b773c118ab93da55f829d4490"
|
||||
integrity sha512-5a7Xm0AY8qPRXZFxrPRErjzCERsENaskQ8Fq5Sy4ht13TMzYp0VIRREU7XF8efpJGcPsOOuFlCiMrqSpYEIAUA==
|
||||
xgplayer@^2.13.0:
|
||||
version "2.13.0"
|
||||
resolved "https://registry.npmjs.org/xgplayer/-/xgplayer-2.13.0.tgz#24df20fd527a87cccc5cee3db70937408eab86ed"
|
||||
integrity sha512-QMjwnpO6o8bd2ZywHtANaOqvey476UAmPS+hXC0im9wiESMKqxPsCmeqhIxFFVao/pUtIyopHADcor9ipai5Rg==
|
||||
dependencies:
|
||||
chalk "^2.3.2"
|
||||
commander "^2.15.1"
|
||||
danmu.js "^0.2.17"
|
||||
danmu.js "0.2.23"
|
||||
deepmerge "^1.5.0"
|
||||
downloadjs "1.4.7"
|
||||
draggabilly "^2.2.0"
|
||||
|
||||
Reference in New Issue
Block a user