重构搜索页面逻辑

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

View File

@ -1,28 +1,65 @@
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
const state = {
sourceList,
list: [],
text: '',
page: 1,
limit: 30,
allPage: 1,
total: 0,
sourceMaxPage,
}
// getters
const getters = {
list: state => state.list || [],
limit: state => state.limit,
info: state => ({ page: state.page, text: state.text }),
listInfo: state => ({ allPage: state.allPage, total: state.total }),
sources: () => sources,
sourceList: state => state.sourceList || [],
searchText: state => state.text,
allList: state => ({ list: state.list, allPage: state.allPage, total: state.total, limit: state.limit, sourceMaxPage: state.sourceMaxPage }),
}
// actions
const actions = {
search({ commit, rootState }, { text, page, limit }) {
return music[rootState.setting.sourceId].musicSearch.search(text, page, limit)
.then(data => commit('setList', { list: data.list, allPage: data.allPage, total: data.total, text, page }))
if (rootState.setting.search.searchSource == 'all') {
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.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) {
state.list.length = 0
state.page = 0
state.allPage = 0
state.total = 0
for (const source of state.list) {
source.list.length = 0
source.list.page = 0
source.list.allPage = 0
source.list.total = 0
}
state.text = ''
},
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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