重构搜索页面逻辑

pull/96/head
lyswhut 2019-09-20 22:09:18 +08:00
parent a16c4c3657
commit c12bbc7f0f
15 changed files with 276 additions and 32 deletions

View File

@ -34,11 +34,14 @@ export default {
} }
}, },
computed: { computed: {
...mapGetters(['source', 'route', 'setting']), ...mapGetters(['route', 'setting']),
...mapGetters('search', ['info']), ...mapGetters('search', ['searchText']),
isAutoClearInput() { isAutoClearInput() {
return this.setting.odc.isAutoClearSearchInput return this.setting.odc.isAutoClearSearchInput
}, },
source() {
return this.setting.search.tempSearchSource
},
}, },
watch: { watch: {
list(n) { list(n) {
@ -46,7 +49,7 @@ export default {
this.listStyle.height = this.$refs.dom_list.scrollHeight + 'px' this.listStyle.height = this.$refs.dom_list.scrollHeight + 'px'
}) })
}, },
'info.text'(n) { 'searchText'(n) {
if (n !== this.text) this.text = n if (n !== this.text) this.text = n
}, },
route(n) { route(n) {
@ -81,11 +84,11 @@ export default {
handleInput() { handleInput() {
if (this.text === '') { if (this.text === '') {
this.list.splice(0, this.list.length) this.list.splice(0, this.list.length)
music[this.source.id].tempSearch.cancelTempSearch() music[this.source].tempSearch.cancelTempSearch()
return return
} }
if (!this.isShow) this.showList() if (!this.isShow) this.showList()
music[this.source.id].tempSearch.search(this.text).then(list => { music[this.source].tempSearch.search(this.text).then(list => {
this.list = list this.list = list
}).catch(() => {}) }).catch(() => {})
}, },

View File

@ -1,28 +1,65 @@
import music from '../../utils/music' import music from '../../utils/music'
const sources = [{
id: 'all',
name: '聚合搜索',
}]
const sourceList = {
all: {
page: 1,
allPage: 0,
limit: 30,
total: 0,
list: [],
},
}
const sourceMaxPage = {}
for (const source of music.sources) {
const musicSearch = music[source.id].musicSearch
if (!musicSearch) continue
sources.push(source)
sourceList[source.id] = {
page: 1,
allPage: 0,
limit: 30,
total: 0,
list: [],
}
sourceMaxPage[source.id] = 0
}
// state // state
const state = { const state = {
sourceList,
list: [], list: [],
text: '', text: '',
page: 1, page: 1,
limit: 30, limit: 30,
allPage: 1, allPage: 1,
total: 0, total: 0,
sourceMaxPage,
} }
// getters // getters
const getters = { const getters = {
list: state => state.list || [], sources: () => sources,
limit: state => state.limit, sourceList: state => state.sourceList || [],
info: state => ({ page: state.page, text: state.text }), searchText: state => state.text,
listInfo: state => ({ allPage: state.allPage, total: state.total }), allList: state => ({ list: state.list, allPage: state.allPage, total: state.total, limit: state.limit, sourceMaxPage: state.sourceMaxPage }),
} }
// actions // actions
const actions = { const actions = {
search({ commit, rootState }, { text, page, limit }) { search({ commit, rootState }, { text, page, limit }) {
return music[rootState.setting.sourceId].musicSearch.search(text, page, limit) if (rootState.setting.search.searchSource == 'all') {
.then(data => commit('setList', { list: data.list, allPage: data.allPage, total: data.total, text, page })) let task = []
for (const source of sources) task.push(music[source.id].musicSearch.search(text, page, limit))
Promise.all(task).then((...results) => {
commit('setLists', { results, text, page })
})
} else {
return music[rootState.setting.search.searchSource].musicSearch.search(text, page, limit)
.then(data => commit('setList', { list: data.list, allPage: data.allPage, total: data.total, text, page }))
}
}, },
} }
@ -35,11 +72,31 @@ const mutations = {
state.page = datas.page state.page = datas.page
state.text = datas.text state.text = datas.text
}, },
setLists(state, { results, text, page }) {
let pages = []
let total = 0
let limit = 0
for (const source of results) {
state[source.source].list = source.list
state[source.source].total = source.total
state[source.source].allPage = source.allPage
state[source.source].page = page
pages.push(source.allPage)
total += source.total
limit += source.limit
}
state.allPage = Math.max(...pages)
state.total = total
state.limit = limit
state.text = text
},
clearList(state) { clearList(state) {
state.list.length = 0 for (const source of state.list) {
state.page = 0 source.list.length = 0
state.allPage = 0 source.list.page = 0
state.total = 0 source.list.allPage = 0
source.list.total = 0
}
state.text = '' state.text = ''
}, },
} }

View File

@ -2,8 +2,9 @@ export default {
setTheme(state, val) { setTheme(state, val) {
state.setting.themeId = val state.setting.themeId = val
}, },
setSource(state, val) { setSearchSource(state, { searchSource, tempSearchSource }) {
state.setting.sourceId = val if (searchSource != null) state.setting.search.searchSource = searchSource
if (tempSearchSource != null) state.setting.search.tempSearchSource = tempSearchSource
}, },
setSetting(state, val) { setSetting(state, val) {
state.setting = val state.setting = val

View File

@ -163,7 +163,7 @@ export const isChildren = (parent, children) => {
* @param {*} setting * @param {*} setting
*/ */
export const updateSetting = setting => { export const updateSetting = setting => {
const defaultVersion = '1.0.8' const defaultVersion = '1.0.9'
const defaultSetting = { const defaultSetting = {
version: defaultVersion, version: defaultVersion,
player: { player: {
@ -197,6 +197,10 @@ export const updateSetting = setting => {
odc: { odc: {
isAutoClearSearchInput: false, isAutoClearSearchInput: false,
}, },
search: {
searchSource: 'kw',
tempSearchSource: 'kw',
},
network: { network: {
proxy: { proxy: {
enable: false, enable: false,
@ -214,7 +218,6 @@ export const updateSetting = setting => {
} }
const overwriteSetting = { const overwriteSetting = {
version: defaultVersion, version: defaultVersion,
sourceId: 'kw',
} }

View File

@ -126,6 +126,7 @@ export default {
list, list,
limit: this.limit, limit: this.limit,
page: parseInt(info[3]), page: parseInt(info[3]),
source: 'bd',
} }
}) })
}, },

View File

@ -0,0 +1,144 @@
// import '../../polyfill/array.find'
// import jshtmlencode from 'js-htmlencode'
import { httpGet, cancelHttp } from '../../request'
import { formatPlayTime, decodeName } from '../../index'
// import { debug } from '../../utils/env'
import { formatSinger } from './util'
export default {
regExps: {
mInfo: /bitrate:(\d+),format:(\w+),size:([\w.]+)/,
},
_musicSearchRequestObj: null,
_musicSearchPromiseCancelFn: null,
limit: 30,
total: 0,
page: 0,
allPage: 1,
// cancelFn: null,
musicSearch(str, page) {
if (this._musicSearchRequestObj != null) {
cancelHttp(this._musicSearchRequestObj)
this._musicSearchPromiseCancelFn(new Error('取消http请求'))
}
return new Promise((resolve, reject) => {
this._musicSearchPromiseCancelFn = reject
this._musicSearchRequestObj = httpGet(`http://search.kuwo.cn/r.s?client=kt&all=${encodeURIComponent(str)}&pn=${page - 1}&rn=${this.limit}&uid=794762570&ver=kwplayer_ar_9.2.2.1&vipver=1&show_copyright_off=1&newver=1&ft=music&cluster=0&strategy=2012&encoding=utf8&rformat=json&vermerge=1&mobi=1&issubtitle=1`, (err, resp, body) => {
this._musicSearchRequestObj = null
this._musicSearchPromiseCancelFn = null
if (err) {
console.log(err)
reject(err)
}
resolve(body)
})
})
},
// getImg(songId) {
// return httpGet(`http://player.kuwo.cn/webmusic/sj/dtflagdate?flag=6&rid=MUSIC_${songId}`)
// },
// getLrc(songId) {
// return httpGet(`http://mobile.kuwo.cn/mpage/html5/songinfoandlrc?mid=${songId}&flag=0`)
// },
handleResult(rawData) {
const result = []
for (let i = 0; i < rawData.length; i++) {
const info = rawData[i]
let songId = info.MUSICRID.replace('MUSIC_', '')
// const format = (info.FORMATS || info.formats).split('|')
if (!info.MINFO) {
console.log('mInfo is undefined')
return null
}
const types = []
const _types = {}
let infoArr = info.MINFO.split(';')
infoArr.forEach(info => {
info = info.match(this.regExps.mInfo)
if (info) {
switch (info[2]) {
case 'flac':
types.push({ type: 'flac', size: info[3] })
_types.flac = {
size: info[3].toLocaleUpperCase(),
}
break
case 'ape':
types.push({ type: 'ape', size: info[3] })
_types.ape = {
size: info[3].toLocaleUpperCase(),
}
break
case 'mp3':
switch (info[1]) {
case '320':
types.push({ type: '320k', size: info[3] })
_types['320k'] = {
size: info[3].toLocaleUpperCase(),
}
break
case '192':
types.push({ type: '192k', size: info[3] })
_types['192k'] = {
size: info[3].toLocaleUpperCase(),
}
break
case '128':
types.push({ type: '128k', size: info[3] })
_types['128k'] = {
size: info[3].toLocaleUpperCase(),
}
break
}
break
}
}
})
types.reverse()
let interval = parseInt(info.DURATION)
result.push({
name: decodeName(info.SONGNAME),
singer: formatSinger(decodeName(info.ARTIST)),
source: 'kw',
// img = (info.album.name === '' || info.album.name === '空')
// ? `http://player.kuwo.cn/webmusic/sj/dtflagdate?flag=6&rid=MUSIC_160911.jpg`
// : `https://y.gtimg.cn/music/photo_new/T002R500x500M000${info.album.mid}.jpg`
songmid: songId,
albumId: decodeName(info.ALBUMID || ''),
interval: Number.isNaN(interval) ? 0 : formatPlayTime(interval),
albumName: info.ALBUM ? decodeName(info.ALBUM) : '',
lyric: null,
img: null,
types,
_types,
typeUrl: {},
})
}
return result
},
search(str, page = 1, { limit }) {
if (limit != null) this.limit = limit
// http://newlyric.kuwo.cn/newlyric.lrc?62355680
return this.musicSearch(str, page).then(result => {
if (!result || (result.TOTAL !== '0' && result.SHOW === '0')) return this.search(str, page, { limit })
let list = this.handleResult(result.abslist)
if (list == null) return this.search(str, page, { limit })
this.total = parseInt(result.TOTAL)
this.page = page
this.allPage = Math.ceil(this.total / this.limit)
return Promise.resolve({
list,
allPage: this.allPage,
total: this.total,
})
})
},
}

View File

@ -116,6 +116,7 @@ export default {
return { return {
hotTag: this.filterInfoHotTag(body.result.hot), hotTag: this.filterInfoHotTag(body.result.hot),
tags: this.filterTagInfo(body.result.tags), tags: this.filterTagInfo(body.result.tags),
source: 'bd',
} }
}) })
}, },
@ -123,6 +124,7 @@ export default {
return rawList.map(item => ({ return rawList.map(item => ({
name: item, name: item,
id: item, id: item,
source: 'bd',
})) }))
}, },
filterTagInfo(rawList) { filterTagInfo(rawList) {
@ -133,6 +135,7 @@ export default {
parent_name: type.first, parent_name: type.first,
id: item, id: item,
name: item, name: item,
source: 'bd',
})), })),
})) }))
}, },
@ -150,6 +153,7 @@ export default {
total: body.nums, total: body.nums,
page, page,
limit: this.limit_list, limit: this.limit_list,
source: 'bd',
} }
}) })
}, },
@ -174,6 +178,7 @@ export default {
img: item.list_pic_large || item.list_pic, img: item.list_pic_large || item.list_pic,
grade: item.grade, grade: item.grade,
desc: item.desc || item.tag, desc: item.desc || item.tag,
source: 'bd',
})) }))
}, },
@ -191,6 +196,7 @@ export default {
page, page,
limit: this.limit_song, limit: this.limit_song,
total: body.result.song_num, total: body.result.song_num,
source: 'bd',
} }
}) })
}, },

View File

@ -159,6 +159,7 @@ export default {
list: listData, list: listData,
limit, limit,
page, page,
source: 'kg',
} }
}) })
}, },

View File

@ -80,6 +80,7 @@ export default {
parent_name: tag.pname, parent_name: tag.pname,
id: tag.id, id: tag.id,
name: tag.name, name: tag.name,
source: 'kg',
})), })),
}) })
} }
@ -133,6 +134,7 @@ export default {
img: item.img || item.imgurl, img: item.img || item.imgurl,
grade: item.grade, grade: item.grade,
desc: item.intro, desc: item.intro,
source: 'kg',
})) }))
}, },
@ -147,6 +149,7 @@ export default {
page: 1, page: 1,
limit: 10000, limit: 10000,
total: listData.length, total: listData.length,
source: 'kg',
} }
}) })
}, },
@ -215,6 +218,7 @@ export default {
limit: body.data.params.pagesize, limit: body.data.params.pagesize,
page: body.data.params.p, page: body.data.params.p,
total: body.data.params.total, total: body.data.params.total,
source: 'kg',
} }
}) })
}, },
@ -250,6 +254,7 @@ export default {
return { return {
hotTag: this.filterInfoHotTag(body.data.hotTag), hotTag: this.filterInfoHotTag(body.data.hotTag),
tags: this.filterTagInfo(body.data.tagids), tags: this.filterTagInfo(body.data.tagids),
source: 'kg',
} }
}) })
}, },

View File

@ -187,6 +187,7 @@ export default {
list, list,
limit: this.limit, limit: this.limit,
page, page,
source: 'kw',
} }
}) })
}, },

View File

@ -138,6 +138,7 @@ export default {
list, list,
allPage: this.allPage, allPage: this.allPage,
total: this.total, total: this.total,
source: 'kw',
}) })
}) })
}, },

View File

@ -59,6 +59,7 @@ export default {
return rawList.map(item => ({ return rawList.map(item => ({
id: `${item.id}-${item.digest}`, id: `${item.id}-${item.digest}`,
name: item.name, name: item.name,
source: 'kw',
})) }))
}, },
filterTagInfo(rawList) { filterTagInfo(rawList) {
@ -69,6 +70,7 @@ export default {
parent_name: type.name, parent_name: type.name,
id: `${item.id}-${item.digest}`, id: `${item.id}-${item.digest}`,
name: item.name, name: item.name,
source: 'kw',
})), })),
})) }))
}, },
@ -94,6 +96,7 @@ export default {
total: body.data.total, total: body.data.total,
page: body.data.pn, page: body.data.pn,
limit: body.data.rn, limit: body.data.rn,
source: 'kw',
} }
} else if (!body.length) { } else if (!body.length) {
return this.getListUrl({ sortId, id, type, page }) return this.getListUrl({ sortId, id, type, page })
@ -103,6 +106,7 @@ export default {
total: 1000, total: 1000,
page, page,
limit: 1000, limit: 1000,
source: 'kw',
} }
}) })
}, },
@ -127,6 +131,7 @@ export default {
img: item.img, img: item.img,
grade: item.favorcnt / 10, grade: item.favorcnt / 10,
desc: item.desc, desc: item.desc,
source: 'kw',
})) }))
}, },
filterList2(rawData) { filterList2(rawData) {
@ -160,6 +165,7 @@ export default {
page, page,
limit: body.rn, limit: body.rn,
total: body.total, total: body.total,
source: 'kw',
} }
}) })
}, },

View File

@ -196,6 +196,7 @@ export default {
list: this.filterData(data.toplist.data.songInfoList), list: this.filterData(data.toplist.data.songInfoList),
limit: this.limit, limit: this.limit,
page: 1, page: 1,
source: 'tx',
} }
}) })
}) })

View File

@ -155,6 +155,7 @@ export default {
list, list,
limit: this.limit, limit: this.limit,
page, page,
source: 'tx',
} }
}) })
}, },

View File

@ -1,7 +1,9 @@
<template lang="pug"> <template lang="pug">
div(:class="$style.search") div(:class="$style.search")
//- transition //- transition
div(v-if="list.length" :class="$style.list") div(v-if="listInfo.list.length" :class="$style.list")
div(:class="$style.header")
material-tab(:class="$style.tab" :list="sources" align="left" item-key="id" item-name="name" v-model="searchSourceId")
div(:class="$style.thead") div(:class="$style.thead")
table table
thead thead
@ -17,7 +19,7 @@
div.scroll(:class="$style.tbody" ref="dom_scrollContent") div.scroll(:class="$style.tbody" ref="dom_scrollContent")
table table
tbody tbody
tr(v-for='(item, index) in list' :key='item.songmid' @click="handleDoubleClick(index)") tr(v-for='(item, index) in listInfo.list' :key='item.songmid' @click="handleDoubleClick(index)")
td.nobreak.center(style="width: 37px;" @click.stop) td.nobreak.center(style="width: 37px;" @click.stop)
material-checkbox(:id="index.toString()" v-model="selectdData" :value="item") material-checkbox(:id="index.toString()" v-model="selectdData" :value="item")
td.break(style="width: 25%;") td.break(style="width: 25%;")
@ -30,7 +32,7 @@
material-list-buttons(:index="index" :remove-btn="false" @btn-click="handleListBtnClick") material-list-buttons(:index="index" :remove-btn="false" @btn-click="handleListBtnClick")
td(style="width: 10%;") {{item.interval}} td(style="width: 10%;") {{item.interval}}
div(:class="$style.pagination") div(:class="$style.pagination")
material-pagination(:count="listInfo.total" :limit="limit" :page="page" @btn-click="handleTogglePage") material-pagination(:count="info.total" :limit="limit" :page="page" @btn-click="handleTogglePage")
div(v-else :class="$style.noitem") div(v-else :class="$style.noitem")
p 搜我所想~~😉 p 搜我所想~~😉
material-download-modal(:show="isShowDownload" :musicInfo="musicInfo" @select="handleAddDownload" @close="isShowDownload = false") material-download-modal(:show="isShowDownload" :musicInfo="musicInfo" @select="handleAddDownload" @close="isShowDownload = false")
@ -57,6 +59,7 @@ export default {
isIndeterminate: false, isIndeterminate: false,
isShowEditBtn: false, isShowEditBtn: false,
isShowDownloadMultiple: false, isShowDownloadMultiple: false,
searchSourceId: null,
} }
}, },
beforeRouteUpdate(to, from, next) { beforeRouteUpdate(to, from, next) {
@ -72,10 +75,10 @@ export default {
}, },
mounted() { mounted() {
// console.log('mounted') // console.log('mounted')
this.searchSourceId = this.setting.search.searchSource
if (this.$route.query.text === undefined) { if (this.$route.query.text === undefined) {
let info = this.$store.getters['search/info'] this.text = this.$store.getters['search/text']
this.text = info.text this.page = this.listInfo.page
this.page = info.page
} else if (this.$route.query.text === '') { } else if (this.$route.query.text === '') {
this.clearList() this.clearList()
} else { } else {
@ -89,23 +92,33 @@ export default {
const len = n.length const len = n.length
if (len) { if (len) {
this.isSelectAll = true this.isSelectAll = true
this.isIndeterminate = len !== this.list.length this.isIndeterminate = len !== this.listInfo.list.length
this.isShowEditBtn = true this.isShowEditBtn = true
} else { } else {
this.isSelectAll = false this.isSelectAll = false
this.isShowEditBtn = false this.isShowEditBtn = false
} }
}, },
list() { 'listInfo.list'() {
this.resetSelect() this.resetSelect()
}, },
searchSourceId(n) {
if (n === this.setting.search.searchSource) return
this.setSearchSource({
searchSource: n,
})
},
}, },
computed: { computed: {
...mapGetters(['userInfo']), ...mapGetters(['userInfo', 'setting']),
...mapGetters('search', ['list', 'limit', 'listInfo']), ...mapGetters('search', ['sourceList', 'allList', 'sources']),
...mapGetters('list', ['defaultList']), ...mapGetters('list', ['defaultList']),
listInfo() {
return this.setting.search.searchSource == 'all' ? this.allList : this.sourceList[this.setting.search.searchSource]
},
}, },
methods: { methods: {
...mapMutations(['setSearchSource']),
...mapActions('search', ['search']), ...mapActions('search', ['search']),
...mapActions('download', ['createDownload', 'createDownloadMultiple']), ...mapActions('download', ['createDownload', 'createDownloadMultiple']),
...mapMutations('search', ['clearList', 'setPage']), ...mapMutations('search', ['clearList', 'setPage']),
@ -135,7 +148,7 @@ export default {
handleListBtnClick(info) { handleListBtnClick(info) {
switch (info.action) { switch (info.action) {
case 'download': case 'download':
this.musicInfo = this.list[info.index] this.musicInfo = this.listInfo.list[info.index]
this.$nextTick(() => { this.$nextTick(() => {
this.isShowDownload = true this.isShowDownload = true
}) })
@ -153,7 +166,7 @@ export default {
targetSong = this.selectdData[0] targetSong = this.selectdData[0]
this.defaultListAddMultiple(this.selectdData) this.defaultListAddMultiple(this.selectdData)
} else { } else {
targetSong = this.list[index] targetSong = this.listInfo.list[index]
this.defaultListAdd(targetSong) this.defaultListAdd(targetSong)
} }
let targetIndex = this.defaultList.list.findIndex( let targetIndex = this.defaultList.list.findIndex(
@ -180,7 +193,7 @@ export default {
this.isShowDownloadMultiple = false this.isShowDownloadMultiple = false
}, },
handleSelectAllData(isSelect) { handleSelectAllData(isSelect) {
this.selectdData = isSelect ? [...this.list] : [] this.selectdData = isSelect ? [...this.listInfo.list] : []
}, },
resetSelect() { resetSelect() {
this.isSelectAll = false this.isSelectAll = false