parent
ba8991a034
commit
a580cedcb1
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -6,6 +6,20 @@ Project versioning adheres to [Semantic Versioning](http://semver.org/).
|
||||||
Commit convention is based on [Conventional Commits](http://conventionalcommits.org).
|
Commit convention is based on [Conventional Commits](http://conventionalcommits.org).
|
||||||
Change log format is based on [Keep a Changelog](http://keepachangelog.com/).
|
Change log format is based on [Keep a Changelog](http://keepachangelog.com/).
|
||||||
|
|
||||||
|
## [0.1.4](https://github.com/lyswhut/lx-music-desktop/compare/v0.1.3...v0.1.4) - 2019-08-18
|
||||||
|
|
||||||
|
### 新增
|
||||||
|
|
||||||
|
- 新增音乐来源切换,可到设置页面-基本设置 look look !
|
||||||
|
- 为搜索结果列表添加多选功能。
|
||||||
|
P.S:暂时没想好多选后的操作按钮放哪...
|
||||||
|
|
||||||
|
### 优化
|
||||||
|
|
||||||
|
- 重构与改进checkbox组件,使其支持不定选中状态
|
||||||
|
- 完善上一个版本的http请求封装并切换部分请求到该方法上
|
||||||
|
- 优化其他一些细节
|
||||||
|
|
||||||
## [0.1.3](https://github.com/lyswhut/lx-music-desktop/compare/v0.1.2...v0.1.3) - 2019-08-17
|
## [0.1.3](https://github.com/lyswhut/lx-music-desktop/compare/v0.1.2...v0.1.3) - 2019-08-17
|
||||||
|
|
||||||
### 新增
|
### 新增
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "lx-music-desktop",
|
"name": "lx-music-desktop",
|
||||||
"version": "0.1.3",
|
"version": "0.1.4",
|
||||||
"description": "一个免费的音乐下载助手",
|
"description": "一个免费的音乐下载助手",
|
||||||
"main": "./dist/electron/main.js",
|
"main": "./dist/electron/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
### 新增
|
||||||
|
|
||||||
|
- 新增音乐来源切换,可到设置页面-基本设置 look look !
|
||||||
|
- 为搜索结果列表添加多选功能。
|
||||||
|
P.S:暂时没想好多选后的操作按钮放哪...
|
||||||
|
|
||||||
### 优化
|
### 优化
|
||||||
|
|
||||||
- 重构checkbox组件
|
- 重构与改进checkbox组件,使其支持不定选中状态
|
||||||
|
- 完善上一个版本的http请求封装并切换部分请求到该方法上
|
||||||
|
- 优化其他一些细节
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
|
{
|
||||||
|
"version": "0.1.4",
|
||||||
|
"desc": "<h3>新增</h3>\n<ul>\n<li>新增音乐来源切换,可到设置页面-基本设置 look look !</li>\n<li>为搜索结果列表添加多选功能。<br>\nP.S:暂时没想好多选后的操作按钮放哪…</li>\n</ul>\n<h3>优化</h3>\n<ul>\n<li>重构与改进checkbox组件,使其支持不定选中状态</li>\n<li>完善上一个版本的http请求封装并切换部分请求到该方法上</li>\n<li>优化其他一些细节</li>\n</ul>\n",
|
||||||
|
"history": [
|
||||||
{
|
{
|
||||||
"version": "0.1.3",
|
"version": "0.1.3",
|
||||||
"desc": "<h3>新增</h3>\n<ul>\n<li>新增win32应用构建</li>\n</ul>\n<h3>修复</h3>\n<ul>\n<li>修复安装包许可协议乱码问题</li>\n<li><strong>messoer 提供的接口已挂</strong>,暂时切换到临时接口!</li>\n</ul>\n<h3>移除</h3>\n<ul>\n<li>由于messoer接口无法使用,QQ音乐排行榜直接播放/下载功能暂时关闭</li>\n</ul>\n",
|
"desc": "<h3>新增</h3>\n<ul>\n<li>新增win32应用构建</li>\n</ul>\n<h3>修复</h3>\n<ul>\n<li>修复安装包许可协议乱码问题</li>\n<li><strong>messoer 提供的接口已挂</strong>,暂时切换到临时接口!</li>\n</ul>\n<h3>移除</h3>\n<ul>\n<li>由于messoer接口无法使用,QQ音乐排行榜直接播放/下载功能暂时关闭</li>\n</ul>\n"
|
||||||
"history": [
|
},
|
||||||
{
|
{
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"desc": "<h3>修复</h3>\n<ul>\n<li>修复更新弹窗的内容显示问题</li>\n</ul>\n"
|
"desc": "<h3>修复</h3>\n<ul>\n<li>修复更新弹窗的内容显示问题</li>\n</ul>\n"
|
||||||
|
|
|
@ -28,6 +28,9 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isProd: process.env.NODE_ENV === 'production',
|
isProd: process.env.NODE_ENV === 'production',
|
||||||
|
globalObj: {
|
||||||
|
apiSource: 'messoer',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -59,12 +62,20 @@ export default {
|
||||||
},
|
},
|
||||||
deep: true,
|
deep: true,
|
||||||
},
|
},
|
||||||
|
'globalObj.apiSource'(n) {
|
||||||
|
if (n != this.setting.apiSource) {
|
||||||
|
this.setSetting(Object.assign({}, this.setting, {
|
||||||
|
apiSource: n,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['getVersionInfo']),
|
...mapActions(['getVersionInfo']),
|
||||||
...mapMutations(['setNewVersion', 'setVersionVisible']),
|
...mapMutations(['setNewVersion', 'setVersionVisible']),
|
||||||
...mapMutations('list', ['initDefaultList']),
|
...mapMutations('list', ['initDefaultList']),
|
||||||
...mapMutations('download', ['updateDownloadList']),
|
...mapMutations('download', ['updateDownloadList']),
|
||||||
|
...mapMutations(['setSetting']),
|
||||||
init() {
|
init() {
|
||||||
if (this.isProd) {
|
if (this.isProd) {
|
||||||
body.addEventListener('mouseenter', this.dieableIgnoreMouseEvents)
|
body.addEventListener('mouseenter', this.dieableIgnoreMouseEvents)
|
||||||
|
@ -80,6 +91,8 @@ export default {
|
||||||
})
|
})
|
||||||
|
|
||||||
this.initData()
|
this.initData()
|
||||||
|
this.globalObj.apiSource = this.setting.apiSource
|
||||||
|
window.globalObj = this.globalObj
|
||||||
},
|
},
|
||||||
enableIgnoreMouseEvents() {
|
enableIgnoreMouseEvents() {
|
||||||
win.setIgnoreMouseEvents(false)
|
win.setIgnoreMouseEvents(false)
|
||||||
|
|
|
@ -90,6 +90,9 @@ export default {
|
||||||
// return 50
|
// return 50
|
||||||
return this.nowPlayTime / this.maxPlayTime || 0
|
return this.nowPlayTime / this.maxPlayTime || 0
|
||||||
},
|
},
|
||||||
|
isAPITemp() {
|
||||||
|
return this.setting.apiSource == 'temp'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.setProgessWidth()
|
this.setProgessWidth()
|
||||||
|
@ -249,7 +252,8 @@ export default {
|
||||||
},
|
},
|
||||||
handleNext() {
|
handleNext() {
|
||||||
// if (this.list.listName === null) return
|
// if (this.list.listName === null) return
|
||||||
if (!this.list.length) return
|
const list = this.isAPITemp ? this.list.filter(s => s.source == 'kw') : this.list
|
||||||
|
if (!list.length) return
|
||||||
let index
|
let index
|
||||||
switch (this.setting.player.togglePlayMethod) {
|
switch (this.setting.player.togglePlayMethod) {
|
||||||
case 'listLoop':
|
case 'listLoop':
|
||||||
|
@ -267,14 +271,17 @@ export default {
|
||||||
if (index < 0) return
|
if (index < 0) return
|
||||||
this.setPlayIndex(index)
|
this.setPlayIndex(index)
|
||||||
},
|
},
|
||||||
hanldeListLoop() {
|
hanldeListLoop(index = this.playIndex) {
|
||||||
return this.playIndex === this.list.length - 1 ? 0 : this.playIndex + 1
|
index = index === this.list.length - 1 ? 0 : index + 1
|
||||||
|
return this.isAPITemp && this.list[index].source != 'kw' ? this.hanldeListLoop(index) : index
|
||||||
},
|
},
|
||||||
hanldeListNext() {
|
hanldeListNext(index = this.playIndex) {
|
||||||
return this.playIndex === this.list.length - 1 ? -1 : this.playIndex + 1
|
index = index === this.list.length - 1 ? -1 : index + 1
|
||||||
|
return this.isAPITemp && this.list[index].source != 'kw' ? this.hanldeListNext(index) : index
|
||||||
},
|
},
|
||||||
hanldeListRandom() {
|
hanldeListRandom(index = this.playIndex) {
|
||||||
return getRandom(0, this.list.length)
|
index = getRandom(0, this.list.length)
|
||||||
|
return this.isAPITemp && this.list[index].source != 'kw' ? this.hanldeListRandom(index) : index
|
||||||
},
|
},
|
||||||
startPlay() {
|
startPlay() {
|
||||||
this.isPlay = true
|
this.isPlay = true
|
||||||
|
@ -314,6 +321,7 @@ export default {
|
||||||
setUrl(targetSong) {
|
setUrl(targetSong) {
|
||||||
let type = this.getPlayType(this.setting.player.highQuality, targetSong)
|
let type = this.getPlayType(this.setting.player.highQuality, targetSong)
|
||||||
this.musicInfo.url = targetSong.typeUrl[type]
|
this.musicInfo.url = targetSong.typeUrl[type]
|
||||||
|
this.status = '歌曲链接获取中...'
|
||||||
|
|
||||||
let urlP = this.musicInfo.url
|
let urlP = this.musicInfo.url
|
||||||
? Promise.resolve()
|
? Promise.resolve()
|
||||||
|
@ -323,6 +331,8 @@ export default {
|
||||||
|
|
||||||
urlP.then(() => {
|
urlP.then(() => {
|
||||||
this.audio.src = this.musicInfo.url
|
this.audio.src = this.musicInfo.url
|
||||||
|
}).catch(err => {
|
||||||
|
this.status = err.message
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
setImg(targetSong) {
|
setImg(targetSong) {
|
||||||
|
|
|
@ -8,7 +8,9 @@ const state = {
|
||||||
changePlay: false,
|
changePlay: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
let request
|
let urlRequest
|
||||||
|
let picRequest
|
||||||
|
let lrcRequest
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
const getters = {
|
const getters = {
|
||||||
|
@ -21,19 +23,32 @@ const getters = {
|
||||||
// actions
|
// actions
|
||||||
const actions = {
|
const actions = {
|
||||||
getUrl({ commit, state }, { musicInfo, type }) {
|
getUrl({ commit, state }, { musicInfo, type }) {
|
||||||
if (request && request.cancelHttp) request.cancelHttp()
|
if (urlRequest && urlRequest.cancelHttp) urlRequest.cancelHttp()
|
||||||
request = music[musicInfo.source].getMusicUrl(musicInfo, type)
|
urlRequest = music[musicInfo.source].getMusicUrl(musicInfo, type)
|
||||||
return request.promise.then(result => {
|
return urlRequest.promise.then(result => {
|
||||||
commit('setUrl', { musicInfo, url: result.url, type })
|
commit('setUrl', { musicInfo, url: result.url, type })
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
request = null
|
urlRequest = null
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getPic({ commit, state }, musicInfo) {
|
getPic({ commit, state }, musicInfo) {
|
||||||
return music[musicInfo.source].getPic(musicInfo).then(url => commit('getPic', { musicInfo, url }))
|
if (picRequest && picRequest.cancelHttp) picRequest.cancelHttp()
|
||||||
|
picRequest = music[musicInfo.source].getPic(musicInfo)
|
||||||
|
return picRequest.promise.then(url => {
|
||||||
|
console.log(url)
|
||||||
|
commit('getPic', { musicInfo, url })
|
||||||
|
}).finally(() => {
|
||||||
|
picRequest = null
|
||||||
|
})
|
||||||
},
|
},
|
||||||
getLrc({ commit, state }, musicInfo) {
|
getLrc({ commit, state }, musicInfo) {
|
||||||
return music[musicInfo.source].getLyric(musicInfo).then(lrc => commit('setLrc', { musicInfo, lrc }))
|
if (lrcRequest && lrcRequest.cancelHttp) lrcRequest.cancelHttp()
|
||||||
|
lrcRequest = music[musicInfo.source].getLyric(musicInfo)
|
||||||
|
return lrcRequest.promise.then(lrc => {
|
||||||
|
commit('setLrc', { musicInfo, lrc })
|
||||||
|
}).finally(() => {
|
||||||
|
lrcRequest = null
|
||||||
|
})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,7 +157,7 @@ export const isChildren = (parent, children) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updateSetting = setting => {
|
export const updateSetting = setting => {
|
||||||
const defaultVersion = '1.0.1'
|
const defaultVersion = '1.0.2'
|
||||||
const defaultSetting = {
|
const defaultSetting = {
|
||||||
version: defaultVersion,
|
version: defaultVersion,
|
||||||
player: {
|
player: {
|
||||||
|
@ -177,6 +177,7 @@ export const updateSetting = setting => {
|
||||||
},
|
},
|
||||||
themeId: 0,
|
themeId: 0,
|
||||||
sourceId: 'kw',
|
sourceId: 'kw',
|
||||||
|
apiSource: 'messoer',
|
||||||
randomAnimate: true,
|
randomAnimate: true,
|
||||||
}
|
}
|
||||||
const overwriteSetting = {
|
const overwriteSetting = {
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
import kw_api_messoer from './kw/api-messoer'
|
||||||
|
import kw_api_temp from './kw/api-temp'
|
||||||
|
import tx_api_messoer from './tx/api-messoer'
|
||||||
|
|
||||||
|
const apis = {
|
||||||
|
kw_api_messoer,
|
||||||
|
tx_api_messoer,
|
||||||
|
kw_api_temp,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const getAPI = source => {
|
||||||
|
switch (window.globalObj.apiSource) {
|
||||||
|
case 'messoer':
|
||||||
|
return apis[`${source}_api_messoer`]
|
||||||
|
case 'temp':
|
||||||
|
return apis[`${source}_api_temp`]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default source => {
|
||||||
|
switch (source) {
|
||||||
|
case 'tx':
|
||||||
|
return getAPI('tx')
|
||||||
|
default:
|
||||||
|
return getAPI('kw')
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { httpFatch } from '../../request'
|
||||||
|
|
||||||
|
const api_messoer = {
|
||||||
|
getMusicUrl(songInfo, type) {
|
||||||
|
const requestObj = httpFatch(`https://v1.itooi.cn/kuwo/url?id=${songInfo.songmid}&quality=${type.replace(/k$/, '')}&isRedirect=0`, {
|
||||||
|
method: 'get',
|
||||||
|
timeout: 5000,
|
||||||
|
})
|
||||||
|
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||||
|
return body.code === 200 ? Promise.resolve({ type, url: body.data }) : Promise.reject(new Error(body.msg))
|
||||||
|
})
|
||||||
|
return requestObj
|
||||||
|
},
|
||||||
|
getPic(songInfo) {
|
||||||
|
const requestObj = httpFatch(`https://v1.itooi.cn/kuwo/pic?id=${songInfo.songmid}&isRedirect=0`, {
|
||||||
|
method: 'get',
|
||||||
|
timeout: 5000,
|
||||||
|
})
|
||||||
|
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||||
|
return body.code === 200 ? Promise.resolve(body.data) : Promise.reject(new Error(body.msg))
|
||||||
|
})
|
||||||
|
return requestObj
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export default api_messoer
|
|
@ -0,0 +1,33 @@
|
||||||
|
import { httpFatch } from '../../request'
|
||||||
|
|
||||||
|
const api_temp = {
|
||||||
|
getMusicUrl(songInfo, type) {
|
||||||
|
const requestObj = httpFatch(`https://www.stsky.cn/api/temp/getMusicUrl.php?id=${songInfo.songmid}&type=${type}`, {
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||||
|
return body.code === 0 ? Promise.resolve({ type, url: body.data }) : Promise.reject(new Error(body.msg))
|
||||||
|
}).catch(err => {
|
||||||
|
console.log(err)
|
||||||
|
if (err.message === 'socket hang up') return Promise.reject(new Error('接口挂了'))
|
||||||
|
if (err.code === 'ENOTFOUND') return Promise.reject(new Error('无法连接网络'))
|
||||||
|
return Promise.reject(err)
|
||||||
|
})
|
||||||
|
return requestObj
|
||||||
|
},
|
||||||
|
getPic(songInfo) {
|
||||||
|
const requestObj = httpFatch(`https://www.stsky.cn/api/temp/getPic.php?size=320&songmid=${songInfo.songmid}`, {
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||||
|
return body.code === 0 ? Promise.resolve(body.data) : Promise.reject(new Error(body.msg))
|
||||||
|
}).catch(err => {
|
||||||
|
if (err.message === 'socket hang up') return Promise.reject(new Error('接口挂了'))
|
||||||
|
if (err.code === 'ENOTFOUND') return Promise.reject(new Error('无法连接网络'))
|
||||||
|
return Promise.reject(err)
|
||||||
|
})
|
||||||
|
return requestObj
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export default api_temp
|
|
@ -4,6 +4,7 @@ import musicSearch from './musicSearch'
|
||||||
import { formatSinger } from './util'
|
import { formatSinger } from './util'
|
||||||
import leaderboard from './leaderboard'
|
import leaderboard from './leaderboard'
|
||||||
import lyric from './lyric'
|
import lyric from './lyric'
|
||||||
|
import api_source from '../api-source'
|
||||||
|
|
||||||
const kw = {
|
const kw = {
|
||||||
_musicInfoRequestObj: null,
|
_musicInfoRequestObj: null,
|
||||||
|
@ -52,36 +53,7 @@ const kw = {
|
||||||
},
|
},
|
||||||
|
|
||||||
getMusicUrl(songInfo, type) {
|
getMusicUrl(songInfo, type) {
|
||||||
let requestObj
|
return api_source('kw').getMusicUrl(songInfo, type)
|
||||||
let cancelFn
|
|
||||||
const p = new Promise((resolve, reject) => {
|
|
||||||
cancelFn = reject
|
|
||||||
// requestObj = httpGet(`https://v1.itooi.cn/kuwo/url?id=${songInfo.songmid}&quality=${type.replace(/k$/, '')}&isRedirect=0`, (err, resp, body) => {
|
|
||||||
requestObj = httpGet(`https://www.stsky.cn/api/temp/getMusicUrl.php?id=${songInfo.songmid}&type=${type}`, (err, resp, body) => {
|
|
||||||
requestObj = null
|
|
||||||
cancelFn = null
|
|
||||||
if (err) {
|
|
||||||
if (err.message === 'socket hang up') return reject(new Error('接口挂了'))
|
|
||||||
const { promise, cancelHttp } = this.getMusicUrl(songInfo, type)
|
|
||||||
obj.cancelHttp = cancelHttp
|
|
||||||
return promise
|
|
||||||
}
|
|
||||||
// body.code === 200 ? resolve({ type, url: body.data }) : reject(new Error(body.msg))
|
|
||||||
body.code === 0 ? resolve({ type, url: body.data }) : reject(new Error(body.msg))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
const obj = {
|
|
||||||
promise: p,
|
|
||||||
cancelHttp() {
|
|
||||||
console.log('cancel')
|
|
||||||
if (!requestObj) return
|
|
||||||
cancelHttp(requestObj)
|
|
||||||
cancelFn(new Error('取消http请求'))
|
|
||||||
requestObj = null
|
|
||||||
cancelFn = null
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return obj
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getMusicInfo(songInfo) {
|
getMusicInfo(songInfo) {
|
||||||
|
@ -119,24 +91,7 @@ const kw = {
|
||||||
},
|
},
|
||||||
|
|
||||||
getPic(songInfo) {
|
getPic(songInfo) {
|
||||||
if (this._musicPicRequestObj != null) {
|
return api_source('kw').getPic(songInfo)
|
||||||
cancelHttp(this._musicPicRequestObj)
|
|
||||||
this._musicPicPromiseCancelFn(new Error('取消http请求'))
|
|
||||||
}
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this._musicPicPromiseCancelFn = reject
|
|
||||||
// this._musicPicRequestObj = httpGet(`https://v1.itooi.cn/kuwo/pic?id=${songInfo.songmid}&isRedirect=0`, (err, resp, body) => {
|
|
||||||
this._musicPicRequestObj = httpGet(`https://www.stsky.cn/api/temp/getPic.php?size=320&songmid=${songInfo.songmid}`, (err, resp, body) => {
|
|
||||||
this._musicPicRequestObj = null
|
|
||||||
this._musicPicPromiseCancelFn = null
|
|
||||||
if (err) {
|
|
||||||
console.log(err)
|
|
||||||
reject(err)
|
|
||||||
}
|
|
||||||
// body.code === 200 ? resolve(body.data) : reject(new Error(body.msg))
|
|
||||||
body.code === 0 ? resolve(body.data) : reject(new Error(body.msg))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,7 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
filterData(rawList, rawList2) {
|
filterData(rawList, rawList2) {
|
||||||
|
// console.log(rawList.length, rawList2.length)
|
||||||
return rawList.map((item, inedx) => {
|
return rawList.map((item, inedx) => {
|
||||||
let formats = item.formats.split('|')
|
let formats = item.formats.split('|')
|
||||||
let types = []
|
let types = []
|
||||||
|
@ -148,7 +149,7 @@ export default {
|
||||||
albumId: item.albumid,
|
albumId: item.albumid,
|
||||||
songmid: item.id,
|
songmid: item.id,
|
||||||
source: 'kw',
|
source: 'kw',
|
||||||
interval: formatPlayTime(rawList2[inedx].duration),
|
interval: rawList2[inedx] && formatPlayTime(rawList2[inedx].duration),
|
||||||
img: item.pic,
|
img: item.pic,
|
||||||
lrc: null,
|
lrc: null,
|
||||||
types,
|
types,
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import { httpGet, cancelHttp } from '../../request'
|
import { httpFatch } from '../../request'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
_musicLrcRequestObj: null,
|
|
||||||
_musicLrcPromiseCancelFn: null,
|
|
||||||
formatTime(time) {
|
formatTime(time) {
|
||||||
let m = parseInt(time / 60)
|
let m = parseInt(time / 60)
|
||||||
let s = (time % 60).toFixed(2)
|
let s = (time % 60).toFixed(2)
|
||||||
|
@ -12,23 +10,10 @@ export default {
|
||||||
return `[ti:${songinfo.songName}]\n[ar:${songinfo.artist}]\n[al:${songinfo.album}]\n[by:]\n[offset:0]\n${lrclist ? lrclist.map(l => `[${this.formatTime(l.time)}]${l.lineLyric}\n`).join('') : '暂无歌词'}`
|
return `[ti:${songinfo.songName}]\n[ar:${songinfo.artist}]\n[al:${songinfo.album}]\n[by:]\n[offset:0]\n${lrclist ? lrclist.map(l => `[${this.formatTime(l.time)}]${l.lineLyric}\n`).join('') : '暂无歌词'}`
|
||||||
},
|
},
|
||||||
getLyric(songId) {
|
getLyric(songId) {
|
||||||
if (this._musicLrcRequestObj != null) {
|
const requestObj = httpFatch(`http://m.kuwo.cn/newh5/singles/songinfoandlrc?musicId=${songId}`)
|
||||||
cancelHttp(this._musicLrcRequestObj)
|
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||||
this._musicLrcPromiseCancelFn(new Error('取消http请求'))
|
return this.transformLrc(body.data)
|
||||||
}
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this._musicLrcPromiseCancelFn = reject
|
|
||||||
// this._musicLrcRequestObj = httpGet(`https://v1.itooi.cn/kuwo/lrc?id=${songId}`, (err, resp, body) => {
|
|
||||||
this._musicLrcRequestObj = httpGet(`http://m.kuwo.cn/newh5/singles/songinfoandlrc?musicId=${songId}`, (err, resp, body) => {
|
|
||||||
this._musicLrcRequestObj = null
|
|
||||||
this._musicLrcPromiseCancelFn = null
|
|
||||||
if (err) {
|
|
||||||
console.log(err)
|
|
||||||
reject(err)
|
|
||||||
}
|
|
||||||
// resolve(body)
|
|
||||||
resolve(this.transformLrc(body.data))
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
return requestObj
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { httpFatch } from '../../request'
|
||||||
|
|
||||||
|
const api_messoer = {
|
||||||
|
getMusicUrl(songInfo, type) {
|
||||||
|
const requestObj = httpFatch(`https://v1.itooi.cn/tencent/url?id=${songInfo.strMediaMid}&quality=${type.replace(/k$/, '')}&isRedirect=0`, {
|
||||||
|
method: 'get',
|
||||||
|
timeout: 5000,
|
||||||
|
})
|
||||||
|
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||||
|
return body.code === 200 ? Promise.resolve({ type, url: body.data }) : Promise.reject(new Error(body.msg))
|
||||||
|
})
|
||||||
|
return requestObj
|
||||||
|
},
|
||||||
|
getPic(songInfo) {
|
||||||
|
return {
|
||||||
|
promise: Promise.resolve(`https://y.gtimg.cn/music/photo_new/T002R500x500M000${songInfo.albumId}.jpg`),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export default api_messoer
|
|
@ -1,46 +1,19 @@
|
||||||
import { httpGet, cancelHttp } from '../../request'
|
|
||||||
import leaderboard from './leaderboard'
|
import leaderboard from './leaderboard'
|
||||||
import lyric from './lyric'
|
import lyric from './lyric'
|
||||||
|
import api_source from '../api-source'
|
||||||
|
|
||||||
const tx = {
|
const tx = {
|
||||||
leaderboard,
|
leaderboard,
|
||||||
|
|
||||||
getMusicUrl(songInfo, type) {
|
getMusicUrl(songInfo, type) {
|
||||||
let requestObj
|
return api_source('tx').getMusicUrl(songInfo, type)
|
||||||
let cancelFn
|
|
||||||
const p = new Promise((resolve, reject) => {
|
|
||||||
cancelFn = reject
|
|
||||||
requestObj = httpGet(`https://v1.itooi.cn/tencent/url?id=${songInfo.strMediaMid}&quality=${type.replace(/k$/, '')}&isRedirect=0`, (err, resp, body) => {
|
|
||||||
requestObj = null
|
|
||||||
cancelFn = null
|
|
||||||
if (err) {
|
|
||||||
console.log(err)
|
|
||||||
const { promise, cancelHttp } = this.getMusicUrl(songInfo, type)
|
|
||||||
obj.cancelHttp = cancelHttp
|
|
||||||
return promise
|
|
||||||
}
|
|
||||||
body.code === 200 ? resolve({ type, url: body.data }) : reject(new Error(body.msg))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
const obj = {
|
|
||||||
promise: p,
|
|
||||||
cancelHttp() {
|
|
||||||
console.log('cancel')
|
|
||||||
if (!requestObj) return
|
|
||||||
cancelHttp(requestObj)
|
|
||||||
cancelFn(new Error('取消http请求'))
|
|
||||||
requestObj = null
|
|
||||||
cancelFn = null
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return obj
|
|
||||||
},
|
},
|
||||||
getLyric(songInfo) {
|
getLyric(songInfo) {
|
||||||
// let singer = songInfo.singer.indexOf('、') > -1 ? songInfo.singer.split('、')[0] : songInfo.singer
|
// let singer = songInfo.singer.indexOf('、') > -1 ? songInfo.singer.split('、')[0] : songInfo.singer
|
||||||
return lyric.getLyric(songInfo.songmid)
|
return lyric.getLyric(songInfo.songmid)
|
||||||
},
|
},
|
||||||
getPic(songInfo) {
|
getPic(songInfo) {
|
||||||
return Promise.resolve(`https://y.gtimg.cn/music/photo_new/T002R500x500M000${songInfo.albumId}.jpg`)
|
return api_source('tx').getPic(songInfo)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,32 +1,19 @@
|
||||||
import { httpGet, cancelHttp } from '../../request'
|
import { httpFatch } from '../../request'
|
||||||
import { b64DecodeUnicode } from '../../index'
|
import { b64DecodeUnicode } from '../../index'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
_musicLrcRequestObj: null,
|
|
||||||
_musicLrcPromiseCancelFn: null,
|
|
||||||
regexps: {
|
regexps: {
|
||||||
matchLrc: /.+"lyric":"([\w=+/]*)".+/,
|
matchLrc: /.+"lyric":"([\w=+/]*)".+/,
|
||||||
},
|
},
|
||||||
getLyric(songmid) {
|
getLyric(songmid) {
|
||||||
if (this._musicLrcRequestObj != null) {
|
const requestObj = httpFatch(`https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg?songmid=${songmid}&g_tk=2001461048&loginUin=0&hostUin=0&format=jsonp&inCharset=utf8&outCharset=utf-8&platform=yqq`, {
|
||||||
cancelHttp(this._musicLrcRequestObj)
|
|
||||||
this._musicLrcPromiseCancelFn(new Error('取消http请求'))
|
|
||||||
}
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this._musicLrcPromiseCancelFn = reject
|
|
||||||
this._musicLrcRequestObj = httpGet(`https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg?songmid=${songmid}&g_tk=2001461048&loginUin=0&hostUin=0&format=jsonp&inCharset=utf8&outCharset=utf-8&platform=yqq`, {
|
|
||||||
headers: {
|
headers: {
|
||||||
Referer: 'https://y.qq.com/portal/player.html',
|
Referer: 'https://y.qq.com/portal/player.html',
|
||||||
},
|
},
|
||||||
}, (err, resp, body) => {
|
|
||||||
this._musicLrcRequestObj = null
|
|
||||||
this._musicLrcPromiseCancelFn = null
|
|
||||||
if (err) {
|
|
||||||
console.log(err)
|
|
||||||
reject(err)
|
|
||||||
}
|
|
||||||
resolve(b64DecodeUnicode(body.replace(this.regexps.matchLrc, '$1')))
|
|
||||||
})
|
})
|
||||||
|
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||||
|
return b64DecodeUnicode(body.replace(this.regexps.matchLrc, '$1'))
|
||||||
})
|
})
|
||||||
|
return requestObj
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,17 +3,26 @@ import request from 'request'
|
||||||
import { debugRequest } from './env'
|
import { debugRequest } from './env'
|
||||||
// import fs from 'fs'
|
// import fs from 'fs'
|
||||||
|
|
||||||
|
const headers = {
|
||||||
|
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
|
||||||
|
}
|
||||||
|
|
||||||
const fatchData = (url, method, options, callback) => {
|
const fatchData = (url, method, options, callback) => {
|
||||||
|
console.log(url, options)
|
||||||
// console.log('---start---', url)
|
// console.log('---start---', url)
|
||||||
return request(url, {
|
return request(url, {
|
||||||
method,
|
method,
|
||||||
headers: options.headers,
|
headers: Object.assign({}, headers, options.headers || {}),
|
||||||
Origin: options.origin,
|
Origin: options.origin,
|
||||||
data: options.data,
|
data: options.data,
|
||||||
// timeout: 5000,
|
timeout: options.timeout || 10000,
|
||||||
json: options.format === undefined || options.format === 'json',
|
json: options.format === undefined || options.format === 'json',
|
||||||
}, (err, resp, body) => {
|
}, (err, resp, body) => {
|
||||||
if (err) return callback(err, null)
|
if (err) {
|
||||||
|
if (err.message === 'socket hang up') window.globalObj.apiSource = 'temp'
|
||||||
|
return callback(err, null)
|
||||||
|
}
|
||||||
|
|
||||||
// console.log('---end---', url)
|
// console.log('---end---', url)
|
||||||
callback(null, resp, body)
|
callback(null, resp, body)
|
||||||
})
|
})
|
||||||
|
@ -24,7 +33,7 @@ const fatchData = (url, method, options, callback) => {
|
||||||
* @param {*} url
|
* @param {*} url
|
||||||
* @param {*} options
|
* @param {*} options
|
||||||
*/
|
*/
|
||||||
export const httpFatch = (url, options = { method: 'get' }) => {
|
const buildHttpPromose = (url, options) => {
|
||||||
let requestObj
|
let requestObj
|
||||||
let cancelFn
|
let cancelFn
|
||||||
const p = new Promise((resolve, reject) => {
|
const p = new Promise((resolve, reject) => {
|
||||||
|
@ -37,12 +46,13 @@ export const httpFatch = (url, options = { method: 'get' }) => {
|
||||||
requestObj = null
|
requestObj = null
|
||||||
cancelFn = null
|
cancelFn = null
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log(err)
|
console.log(err.code)
|
||||||
if (err.code === 'ETIMEDOUT') {
|
if (err.code === 'ETIMEDOUT' || err.code == 'ESOCKETTIMEDOUT') {
|
||||||
const { promise, cancelHttp } = httpFatch(url, options)
|
const { promise, cancelHttp } = httpFatch(url, options)
|
||||||
obj.cancelHttp = cancelHttp
|
obj.cancelHttp = cancelHttp
|
||||||
return promise
|
promise.then()
|
||||||
}
|
}
|
||||||
|
return reject(err)
|
||||||
}
|
}
|
||||||
resolve(resp)
|
resolve(resp)
|
||||||
})
|
})
|
||||||
|
@ -61,6 +71,27 @@ export const httpFatch = (url, options = { method: 'get' }) => {
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求超时自动重试
|
||||||
|
* @param {*} url
|
||||||
|
* @param {*} options
|
||||||
|
*/
|
||||||
|
export const httpFatch = (url, options = { method: 'get' }) => {
|
||||||
|
const requestObj = buildHttpPromose(url, options)
|
||||||
|
requestObj.promise = requestObj.promise.catch(err => {
|
||||||
|
if (err.code === 'ETIMEDOUT' || err.code == 'ESOCKETTIMEDOUT') {
|
||||||
|
const { promise, cancelHttp } = httpFatch(url, options)
|
||||||
|
requestObj.cancelHttp()
|
||||||
|
requestObj.cancelHttp = cancelHttp
|
||||||
|
return promise
|
||||||
|
}
|
||||||
|
if (err.message === 'socket hang up') return Promise.reject(new Error('哦No😱...接口挂了!已帮你切换到临时接口,重试下看能不能播放吧~'))
|
||||||
|
if (err.code === 'ENOTFOUND') return Promise.reject(new Error('无法连接网络'))
|
||||||
|
return Promise.reject(err)
|
||||||
|
})
|
||||||
|
return requestObj
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 取消请求
|
* 取消请求
|
||||||
* @param {*} index
|
* @param {*} index
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
td.break(style="width: 20%;") {{item.singer}}
|
td.break(style="width: 20%;") {{item.singer}}
|
||||||
td.break(style="width: 25%;") {{item.albumName}}
|
td.break(style="width: 25%;") {{item.albumName}}
|
||||||
td(style="width: 18%;")
|
td(style="width: 18%;")
|
||||||
material-list-buttons(:index="index" :search-btn="true" :play-btn="item.source == 'kw'" :download-btn="item.source == 'kw'" :remove-btn="false" @btn-click="handleBtnClick")
|
material-list-buttons(:index="index" :search-btn="true" :play-btn="item.source == 'kw' || (!isAPITemp && item.source == 'tx')" :download-btn="item.source == 'kw' || (!isAPITemp && item.source == 'tx')" :remove-btn="false" @btn-click="handleBtnClick")
|
||||||
//- button.btn-info(type='button' v-if="item._types['128k'] || item._types['192k'] || item._types['320k'] || item._types.flac" @click.stop='openDownloadModal(index)') 下载
|
//- button.btn-info(type='button' v-if="item._types['128k'] || item._types['192k'] || item._types['320k'] || item._types.flac" @click.stop='openDownloadModal(index)') 下载
|
||||||
//- button.btn-secondary(type='button' v-if="item._types['128k'] || item._types['192k'] || item._types['320k']" @click.stop='testPlay(index)') 试听
|
//- button.btn-secondary(type='button' v-if="item._types['128k'] || item._types['192k'] || item._types['320k']" @click.stop='testPlay(index)') 试听
|
||||||
//- button.btn-success(type='button' v-if="(item._types['128k'] || item._types['192k'] || item._types['320k']) && userInfo" @click.stop='showListModal(index)') +
|
//- button.btn-success(type='button' v-if="(item._types['128k'] || item._types['192k'] || item._types['320k']) && userInfo" @click.stop='showListModal(index)') +
|
||||||
|
@ -59,6 +59,9 @@ export default {
|
||||||
types() {
|
types() {
|
||||||
return this.source ? this.sourceInfo.sourceList[this.source] : []
|
return this.source ? this.sourceInfo.sourceList[this.source] : []
|
||||||
},
|
},
|
||||||
|
isAPITemp() {
|
||||||
|
return this.setting.apiSource == 'temp'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
tabId(n, o) {
|
tabId(n, o) {
|
||||||
|
@ -94,7 +97,7 @@ export default {
|
||||||
this.clickIndex = index
|
this.clickIndex = index
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
(this.source == 'kw') ? this.testPlay(index) : this.handleSearch(index)
|
(this.source == 'kw' || (!this.isAPITemp && this.source == 'tx')) ? this.testPlay(index) : this.handleSearch(index)
|
||||||
this.clickTime = 0
|
this.clickTime = 0
|
||||||
this.clickIndex = -1
|
this.clickIndex = -1
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,7 +14,8 @@
|
||||||
div.scroll(:class="$style.tbody")
|
div.scroll(:class="$style.tbody")
|
||||||
table
|
table
|
||||||
tbody
|
tbody
|
||||||
tr(v-for='(item, index) in list' :key='item.songmid' @click="handleDoubleClick(index)" :class="isPlayList && playIndex === index ? $style.active : ''")
|
tr(v-for='(item, index) in list' :key='item.songmid'
|
||||||
|
@click="handleDoubleClick(index)" :class="[isPlayList && playIndex === index ? $style.active : '', isAPITemp && item.source != 'kw' ? $style.disabled : '']")
|
||||||
td.break(style="width: 25%;") {{item.name}}
|
td.break(style="width: 25%;") {{item.name}}
|
||||||
//- span.badge.badge-light(v-if="item._types['128k']") 128K
|
//- span.badge.badge-light(v-if="item._types['128k']") 128K
|
||||||
//- span.badge.badge-light(v-if="item._types['192k']") 192K
|
//- span.badge.badge-light(v-if="item._types['192k']") 192K
|
||||||
|
@ -61,6 +62,9 @@ export default {
|
||||||
? this.defaultList.list
|
? this.defaultList.list
|
||||||
: this.userList.find(l => l._id == this.$route.query.id) || []
|
: this.userList.find(l => l._id == this.$route.query.id) || []
|
||||||
},
|
},
|
||||||
|
isAPITemp() {
|
||||||
|
return this.setting.apiSource == 'temp'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
// beforeRouteUpdate(to, from, next) {
|
// beforeRouteUpdate(to, from, next) {
|
||||||
// // if (to.query.id === undefined) return
|
// // if (to.query.id === undefined) return
|
||||||
|
@ -105,6 +109,7 @@ export default {
|
||||||
this.clickIndex = -1
|
this.clickIndex = -1
|
||||||
},
|
},
|
||||||
testPlay(index) {
|
testPlay(index) {
|
||||||
|
if (this.isAPITemp && this.list[index].source != 'kw') return
|
||||||
this.setList({ list: this.list, listId: 'test', index })
|
this.setList({ list: this.list, listId: 'test', index })
|
||||||
},
|
},
|
||||||
handleRemove(index) {
|
handleRemove(index) {
|
||||||
|
@ -178,6 +183,10 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.disabled {
|
||||||
|
opacity: .5;
|
||||||
|
}
|
||||||
|
|
||||||
each(@themes, {
|
each(@themes, {
|
||||||
:global(#container.@{value}) {
|
:global(#container.@{value}) {
|
||||||
.tbody {
|
.tbody {
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
thead
|
thead
|
||||||
tr
|
tr
|
||||||
th.nobreak.center(style="width: 37px;")
|
th.nobreak.center(style="width: 37px;")
|
||||||
material-checkbox(id="search_select_all" v-model="isSelectAll" @change="handleSelectAllData" :indeterminate="isIndeterminate")
|
material-checkbox(id="search_select_all" v-model="isSelectAll" @change="handleSelectAllData"
|
||||||
|
:indeterminate="isIndeterminate" :title="isSelectAll && !isIndeterminate ? '全不选' : '全选'")
|
||||||
th.nobreak(style="width: 25%;") 歌曲名
|
th.nobreak(style="width: 25%;") 歌曲名
|
||||||
th.nobreak(style="width: 20%;") 歌手
|
th.nobreak(style="width: 20%;") 歌手
|
||||||
th.nobreak(style="width: 25%;") 专辑
|
th.nobreak(style="width: 25%;") 专辑
|
||||||
|
|
|
@ -15,11 +15,17 @@ div.scroll(:class="$style.setting")
|
||||||
div
|
div
|
||||||
material-checkbox(id="setting_animate" v-model="current_setting.randomAnimate" label="是否启用")
|
material-checkbox(id="setting_animate" v-model="current_setting.randomAnimate" label="是否启用")
|
||||||
|
|
||||||
|
dd(title='选择音乐来源')
|
||||||
|
h3 音乐来源
|
||||||
|
div
|
||||||
|
material-checkbox(v-for="item in apiSources" :id="`setting_api_source_${item.id}`" @change="handleAPISourceChange(item.id)" :class="$style.gapTop"
|
||||||
|
need v-model="current_setting.apiSource" :value="item.id" :label="item.label" :key="item.id")
|
||||||
|
|
||||||
dt 播放设置
|
dt 播放设置
|
||||||
dd(title="都不选时播放完当前歌曲就停止播放")
|
dd(title="都不选时播放完当前歌曲就停止播放")
|
||||||
h3 歌曲切换方式
|
h3 歌曲切换方式
|
||||||
div
|
div
|
||||||
material-checkbox(:id="`setting_player_togglePlay_${item.value}`" :class="$style.gap" :value="item.value" :key="item.value"
|
material-checkbox(:id="`setting_player_togglePlay_${item.value}`" :class="$style.gapLeft" :value="item.value" :key="item.value"
|
||||||
v-model="current_setting.player.togglePlayMethod" v-for="item in togglePlayMethods" :label="item.name")
|
v-model="current_setting.player.togglePlayMethod" v-for="item in togglePlayMethods" :label="item.name")
|
||||||
dd(title='启用时将优先播放320K品质的歌曲')
|
dd(title='启用时将优先播放320K品质的歌曲')
|
||||||
h3 优先播放高品质音乐
|
h3 优先播放高品质音乐
|
||||||
|
@ -37,7 +43,7 @@ div.scroll(:class="$style.setting")
|
||||||
dd(title='下载歌曲时的命名方式')
|
dd(title='下载歌曲时的命名方式')
|
||||||
h3 文件命名方式
|
h3 文件命名方式
|
||||||
div
|
div
|
||||||
material-checkbox(:id="`setting_download_musicName_${item.value}`" :class="$style.gap" name="setting_download_musicName" :value="item.value" :key="item.value" need
|
material-checkbox(:id="`setting_download_musicName_${item.value}`" :class="$style.gapLeft" name="setting_download_musicName" :value="item.value" :key="item.value" need
|
||||||
v-model="current_setting.download.fileName" v-for="item in musicNames" :label="item.name")
|
v-model="current_setting.download.fileName" v-for="item in musicNames" :label="item.name")
|
||||||
dt 列表设置
|
dt 列表设置
|
||||||
dd(title='播放列表是否显示专辑栏')
|
dd(title='播放列表是否显示专辑栏')
|
||||||
|
@ -48,15 +54,15 @@ div.scroll(:class="$style.setting")
|
||||||
dd
|
dd
|
||||||
h3 部分数据
|
h3 部分数据
|
||||||
div
|
div
|
||||||
material-btn(:class="[$style.btn, $style.gap]" min @click="handleImportPlayList") 导入列表
|
material-btn(:class="[$style.btn, $style.gapLeft]" min @click="handleImportPlayList") 导入列表
|
||||||
material-btn(:class="[$style.btn, $style.gap]" min @click="handleExportPlayList") 导出列表
|
material-btn(:class="[$style.btn, $style.gapLeft]" min @click="handleExportPlayList") 导出列表
|
||||||
material-btn(:class="[$style.btn, $style.gap]" min @click="handleImportSetting") 导入设置
|
material-btn(:class="[$style.btn, $style.gapLeft]" min @click="handleImportSetting") 导入设置
|
||||||
material-btn(:class="[$style.btn, $style.gap]" min @click="handleExportSetting") 导出设置
|
material-btn(:class="[$style.btn, $style.gapLeft]" min @click="handleExportSetting") 导出设置
|
||||||
dd
|
dd
|
||||||
h3 所有数据(设置与试听列表)
|
h3 所有数据(设置与试听列表)
|
||||||
div
|
div
|
||||||
material-btn(:class="[$style.btn, $style.gap]" min @click="handleImportAllData") 导入
|
material-btn(:class="[$style.btn, $style.gapLeft]" min @click="handleImportAllData") 导入
|
||||||
material-btn(:class="[$style.btn, $style.gap]" min @click="handleExportAllData") 导出
|
material-btn(:class="[$style.btn, $style.gapLeft]" min @click="handleExportAllData") 导出
|
||||||
dt 关于洛雪音乐
|
dt 关于洛雪音乐
|
||||||
dd
|
dd
|
||||||
p.small
|
p.small
|
||||||
|
@ -113,6 +119,7 @@ export default {
|
||||||
themeId: 0,
|
themeId: 0,
|
||||||
sourceId: 0,
|
sourceId: 0,
|
||||||
randomAnimate: true,
|
randomAnimate: true,
|
||||||
|
apiSource: 'messoer',
|
||||||
},
|
},
|
||||||
togglePlayMethods: [
|
togglePlayMethods: [
|
||||||
{
|
{
|
||||||
|
@ -132,6 +139,16 @@ export default {
|
||||||
value: 'singleLoop',
|
value: 'singleLoop',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
apiSources: [
|
||||||
|
{
|
||||||
|
id: 'messoer',
|
||||||
|
label: '由 messoer 提供的接口(推荐,软件的所有功能都可用)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'temp',
|
||||||
|
label: '临时接口(软件的某些功能将不可用,建议在messoer不可用时再切换到本选项)',
|
||||||
|
},
|
||||||
|
],
|
||||||
musicNames: [
|
musicNames: [
|
||||||
{
|
{
|
||||||
name: '歌名 - 歌手',
|
name: '歌名 - 歌手',
|
||||||
|
@ -310,6 +327,11 @@ export default {
|
||||||
handleOpenUrl(url) {
|
handleOpenUrl(url) {
|
||||||
openUrl(url)
|
openUrl(url)
|
||||||
},
|
},
|
||||||
|
handleAPISourceChange(id) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
window.globalObj.apiSource = id
|
||||||
|
})
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -357,11 +379,16 @@ export default {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.gap {
|
.gap-left {
|
||||||
+ .gap {
|
+ .gap-left {
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.gap-top {
|
||||||
|
+ .gap-top {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.theme {
|
.theme {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
Loading…
Reference in New Issue