From a035a2525a7be94e4617390140485e0cf8cc13d6 Mon Sep 17 00:00:00 2001 From: lyswhut Date: Wed, 4 Sep 2019 00:03:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=AD=8C=E5=8D=95=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/components/core/Player.vue | 2 +- src/renderer/components/material/SongList.vue | 82 +++++++------ src/renderer/components/material/TagList.vue | 26 +++- src/renderer/store/modules/songList.js | 12 +- src/renderer/utils/index.js | 4 +- src/renderer/utils/music/bd/songList.js | 2 +- src/renderer/utils/music/kg/songList.js | 2 +- src/renderer/utils/music/kw/songList.js | 82 ++++++++++--- src/renderer/views/SongList.vue | 115 +++++++++++++++--- 9 files changed, 248 insertions(+), 79 deletions(-) diff --git a/src/renderer/components/core/Player.vue b/src/renderer/components/core/Player.vue index 6ce8070b..686bb401 100644 --- a/src/renderer/components/core/Player.vue +++ b/src/renderer/components/core/Player.vue @@ -283,7 +283,7 @@ export default { } }, checkDelayNextTimeout() { - console.log(this.delayNextTimeout) + // console.log(this.delayNextTimeout) if (this.delayNextTimeout) { clearTimeout(this.delayNextTimeout) this.delayNextTimeout = null diff --git a/src/renderer/components/material/SongList.vue b/src/renderer/components/material/SongList.vue index c9681c40..7e9ffacf 100644 --- a/src/renderer/components/material/SongList.vue +++ b/src/renderer/components/material/SongList.vue @@ -1,40 +1,41 @@ @@ -111,6 +112,7 @@ export default { }, list(n) { this.resetSelect() + if (!this.list.length) return this.$nextTick(() => scrollTo(this.$refs.dom_scrollContent, 0)) }, }, @@ -143,6 +145,7 @@ export default { }, handleSelectAllData(isSelect) { this.selectdList = isSelect ? [...this.list] : [] + this.$emit('input', [...this.selectdList]) }, resetSelect() { this.selectdList = false @@ -183,6 +186,7 @@ export default { } .thead { flex: none; + background-color: @color-theme_2; } .tbody { flex: auto; @@ -220,4 +224,12 @@ export default { } } +each(@themes, { + :global(#container.@{value}) { + .thead { + background-color: ~'@color-@{value}-theme_2'; + } + } +}) + diff --git a/src/renderer/components/material/TagList.vue b/src/renderer/components/material/TagList.vue index 20020ac0..e8ca659c 100644 --- a/src/renderer/components/material/TagList.vue +++ b/src/renderer/components/material/TagList.vue @@ -3,7 +3,7 @@ div(:class="$style.label" ref="dom_btn" @click="handleShow") {{value.name}} div.scroll(:class="$style.list" @click.stop ref="dom_list" :style="listStyle") div(:class="$style.tag" @click="handleClick(null)") 全部 - dl(:class="$style.type" v-for="type in list") + dl(v-for="type in list") dt(:class="$style.type") {{type.name}} dd(:class="$style.tag" v-for="tag in type.list" @click="handleClick(tag)") {{tag.name}} @@ -114,7 +114,7 @@ export default { .list { position: absolute; top: 100%; - width: 644px; + width: 646px; left: 0; border-bottom: 2px solid @color-tab-border-bottom; border-right: 2px solid @color-tab-border-bottom; @@ -125,6 +125,8 @@ export default { transition: .25s ease; transition-property: height, opacity; z-index: 10; + padding: 10px; + box-sizing: border-box; li { cursor: pointer; @@ -145,11 +147,18 @@ export default { } } +.type { + padding-top: 10px; + padding-bottom: 3px; + color: #999; +} + .tag { display: inline-block; margin: 5px; background-color: @color-btn-background; - padding: 5px; + padding: 8px 10px; + border-radius: @radius-progress-border; cursor: pointer; &:hover { background-color: @color-theme_2-hover; @@ -176,6 +185,7 @@ each(@themes, { .list { border-bottom-color: ~'@{color-@{value}-tab-border-bottom}'; + border-right-color: ~'@{color-@{value}-tab-border-bottom}'; // border-left-color: ~'@{color-@{value}-tab-border-bottom}'; li { // color: ~'@{color-@{value}-btn}'; @@ -188,6 +198,16 @@ each(@themes, { } } } + + .tag { + background-color: ~'@{color-@{value}-btn-background}'; + &:hover { + background-color: ~'@{color-@{value}-theme_2-hover}'; + } + &:active { + background-color: ~'@{color-@{value}-theme_2-active}'; + } + } } }) diff --git a/src/renderer/store/modules/songList.js b/src/renderer/store/modules/songList.js index 961f344d..e94873e3 100644 --- a/src/renderer/store/modules/songList.js +++ b/src/renderer/store/modules/songList.js @@ -25,6 +25,7 @@ const state = { limit: 30, key: null, }, + selectListInfo: {}, isVisibleListDetail: false, } @@ -38,6 +39,7 @@ const getters = { sourceInfo: () => ({ sources, sortList }), tags: state => state.tags, isVisibleListDetail: state => state.isVisibleListDetail, + selectListInfo: state => state.selectListInfo, listData(state) { return state.list }, @@ -56,7 +58,7 @@ const actions = { let source = rootState.setting.songList.source let tabId = rootState.setting.songList.tagInfo.id let sortId = rootState.setting.songList.sortId - console.log(sortId) + // console.log(sortId) let key = `${source}${sortId}${tabId}${page}` if (state.list.list.length && state.list.key == key) return true return music[source].songList.getList(sortId, tabId, page).then(result => commit('setList', { result, key, page })) @@ -65,7 +67,7 @@ const actions = { let source = rootState.setting.songList.source let key = `${source}${id}${page}` if (state.listDetail.list.length && state.listDetail.key == key) return true - console.log(id, page) + commit('clearListDetail') return music[source].songList.getListDetail(id, page).then(result => commit('setListDetail', { result, key, page })) }, } @@ -92,6 +94,12 @@ const mutations = { setVisibleListDetail(state, bool) { state.isVisibleListDetail = bool }, + setSelectListInfo(state, info) { + state.selectListInfo = info + }, + clearListDetail(state) { + state.listDetail.list = [] + }, } export default { diff --git a/src/renderer/utils/index.js b/src/renderer/utils/index.js index 4e9a8127..d6997758 100644 --- a/src/renderer/utils/index.js +++ b/src/renderer/utils/index.js @@ -184,8 +184,8 @@ export const updateSetting = setting => { tabId: 'kwbiaosb', }, songList: { - source: 'kw', - sortId: 'hot', + source: 'kg', + sortId: '5', tagInfo: { name: '全部', id: null, diff --git a/src/renderer/utils/music/bd/songList.js b/src/renderer/utils/music/bd/songList.js index 95da24ca..b1240d04 100644 --- a/src/renderer/utils/music/bd/songList.js +++ b/src/renderer/utils/music/bd/songList.js @@ -144,7 +144,7 @@ export default { this.getListUrl(sortId, tagId, page) ) return this._requestObj_list.promise.then(({ body }) => { - if (body.error_code !== this.successCode) return this.getSongList(sortId, tagId, page) + if (body.error_code !== this.successCode) return this.getList(sortId, tagId, page) return { list: this.filterList(body.diyInfo), total: body.nums, diff --git a/src/renderer/utils/music/kg/songList.js b/src/renderer/utils/music/kg/songList.js index e16de429..fd79249b 100644 --- a/src/renderer/utils/music/kg/songList.js +++ b/src/renderer/utils/music/kg/songList.js @@ -231,7 +231,7 @@ export default { return info }) ) - if (!tagId) tasks.push(this.getSongListRecommend()) // 如果是所有类别,则顺便获取推荐列表 + if (!tagId && page === 1) tasks.push(this.getSongListRecommend()) // 如果是所有类别,则顺便获取推荐列表 return Promise.all(tasks).then(([list, info, recommendList]) => { if (recommendList) list.unshift(...recommendList) return { diff --git a/src/renderer/utils/music/kw/songList.js b/src/renderer/utils/music/kw/songList.js index 4d40f800..e34bc159 100644 --- a/src/renderer/utils/music/kw/songList.js +++ b/src/renderer/utils/music/kw/songList.js @@ -7,31 +7,37 @@ export default { _requestObj_hotTags: null, _requestObj_list: null, _requestObj_listDetail: null, - limit_list: 100, - limit_song: 25, + limit_list: 25, + limit_song: 100, successCode: 200, sortList: [ - { - name: '最热', - id: 'hot', - }, { name: '最新', id: 'new', }, + { + name: '最热', + id: 'hot', + }, ], tagsUrl: 'http://wapi.kuwo.cn/api/pc/classify/playlist/getTagList?cmd=rcm_keyword_playlist&user=0&prod=kwplayer_pc_9.0.5.0&vipver=9.0.5.0&source=kwplayer_pc_9.0.5.0&loginUid=0&loginSid=0&appUid=76039576', hotTagUrl: 'http://wapi.kuwo.cn/api/pc/classify/playlist/getRcmTagList?loginUid=0&loginSid=0&appUid=76039576', - getListUrl({ sortId, id, page }) { - return id - ? `http://wapi.kuwo.cn/api/pc/classify/playlist/getTagPlayList?loginUid=0&loginSid=0&appUid=76039576&id=${id}&pn=${page}&rn=${this.limit_list}` - : `http://wapi.kuwo.cn/api/pc/classify/playlist/getRcmPlayList?loginUid=0&loginSid=0&appUid=76039576&pn=${page}&rn=${this.limit_list}&order=${sortId}` + getListUrl({ sortId, id, type, page }) { + console.log(id, type) + if (!id) return `http://wapi.kuwo.cn/api/pc/classify/playlist/getRcmPlayList?loginUid=0&loginSid=0&appUid=76039576&&pn=${page}&rn=${this.limit_list}&order=${sortId}` + switch (type) { + case '10000': return `http://wapi.kuwo.cn/api/pc/classify/playlist/getTagPlayList?loginUid=0&loginSid=0&appUid=76039576&pn=${page}&id=${id}&rn=${this.limit_list}` + case '43': return `http://mobileinterfaces.kuwo.cn/er.s?type=get_pc_qz_data&f=web&id=${id}&prod=pc` + } + // http://wapi.kuwo.cn/api/pc/classify/playlist/getTagPlayList?loginUid=0&loginSid=0&appUid=76039576&id=173&pn=1&rn=100 }, getListDetailUrl(id, page) { + // http://nplserver.kuwo.cn/pl.svc?op=getlistinfo&pid=2858093057&pn=0&rn=100&encode=utf8&keyset=pl2012&identity=kuwo&pcmp4=1&vipver=MUSIC_9.0.5.0_W1&newver=1 return `http://nplserver.kuwo.cn/pl.svc?op=getlistinfo&pid=${id}&pn=${page - 1}&rn=${this.limit_song}&encode=utf8&keyset=pl2012&identity=kuwo&pcmp4=1&vipver=MUSIC_9.0.5.0_W1&newver=1` + // http://mobileinterfaces.kuwo.cn/er.s?type=get_pc_qz_data&f=web&id=140&prod=pc }, - + // http://nplserver.kuwo.cn/pl.svc?op=getlistinfo&pid=2849349915&pn=0&rn=100&encode=utf8&keyset=pl2012&identity=kuwo&pcmp4=1&vipver=MUSIC_9.0.5.0_W1&newver=1 // 获取标签 getTag() { if (this._requestObj_tags) this._requestObj_tags.cancelHttp() @@ -52,7 +58,7 @@ export default { }, filterInfoHotTag(rawList) { return rawList.map(item => ({ - id: item.id, + id: `${item.id}-${item.digest}`, name: item.name, })) }, @@ -62,7 +68,7 @@ export default { list: type.data.map(item => ({ parent_id: type.id, parent_name: type.name, - id: item.id, + id: `${item.id}-${item.digest}`, name: item.name, })), })) @@ -71,14 +77,34 @@ export default { // 获取列表数据 getList(sortId, tagId, page) { if (this._requestObj_list) this._requestObj_list.cancelHttp() - this._requestObj_list = httpFatch(this.getListUrl({ sortId, id: tagId, page })) + let id + let type + if (tagId) { + let arr = tagId.split('-') + id = arr[0] + type = arr[1] + } else { + id = null + } + console.log(id, type) + this._requestObj_list = httpFatch(this.getListUrl({ sortId, id, type, page })) return this._requestObj_list.promise.then(({ body }) => { - if (body.code !== this.successCode) return this.getListUrl({ sortId, id: tagId, page }) + if (!id || type == '10000') { + if (body.code !== this.successCode) return this.getListUrl({ sortId, id, type, page }) + return { + list: this.filterList(body.data.data), + total: body.data.total, + page: body.data.pn, + limit: body.data.rn, + } + } else if (!body.length) { + return this.getListUrl({ sortId, id, type, page }) + } return { - list: this.filterList(body.data.data), - total: body.data.total, - page: body.data.pn, - limit: body.data.rn, + list: this.filterList2(body), + total: 1000, + page, + limit: 1000, } }) }, @@ -105,6 +131,24 @@ export default { desc: item.desc, })) }, + filterList2(rawData) { + const list = [] + rawData.forEach(item => { + if (!item.label) return + list.push(...item.list.map(item => ({ + play_count: item.play_count === undefined ? null : this.formatPlayCount(item.listencnt), + id: item.id, + author: item.uname, + name: item.name, + // time: item.publish_time, + img: item.img, + grade: item.favorcnt / 10, + desc: item.desc, + }))) + }) + console.log(list) + return list + }, // 获取歌曲列表内的音乐 getListDetail(id, page) { diff --git a/src/renderer/views/SongList.vue b/src/renderer/views/SongList.vue index 9001b77b..2222fbaf 100644 --- a/src/renderer/views/SongList.vue +++ b/src/renderer/views/SongList.vue @@ -5,8 +5,18 @@ material-tab(:class="$style.tab" :list="sorts" item-key="id" item-name="name" v-model="sortId") material-select(:class="$style.select" :list="sourceInfo.sources" item-key="id" item-name="name" v-model="source") div(:class="$style.container") - div(:class="$style.materialSongList" v-show="isVisibleListDetail") - material-song-list(v-model="selectdData" @action="handleSongListAction" :source="source" :page="listDetail.page" :limit="listDetail.limit" :total="listDetail.total" :list="listDetail.list") + transition(enter-active-class="animated-fast fadeIn" leave-active-class="animated-fast fadeOut") + div(:class="$style.materialSongList" v-show="isVisibleListDetail") + div(:class="$style.songListHeader") + div(:class="$style.songListHeaderLeft") + img(:src="selectListInfo.img") + span(:class="$style.playNum" v-if="selectListInfo.play_count") {{selectListInfo.play_count}} + div(:class="$style.songListHeaderMiddle") + h3(:title="selectListInfo.name") {{selectListInfo.name}} + p(:title="selectListInfo.desc") {{selectListInfo.desc}} + div(:class="$style.songListHeaderRight") + material-btn(:class="$style.closeDetailButton" @click="hideListDetail") 返回 + material-song-list(v-model="selectdData" @action="handleSongListAction" :source="source" :page="listDetail.page" :limit="listDetail.limit" :total="listDetail.total" :list="listDetail.list") div.scroll(:class="$style.content" ref="dom_scrollContent" v-show="!isVisibleListDetail") ul li(:class="$style.item" v-for="(item, index) in listData.list" @click="handleItemClick(index)") @@ -15,6 +25,7 @@ div(:class="$style.right" :src="item.img") h4(:title="item.name") {{item.name}} p(:title="item.desc") {{item.desc}} + li(:class="$style.item" style="cursor: default;" v-if="listData.list && listData.list.length && listData.list.length % 3 == 2") div(:class="$style.pagination") material-pagination(:count="listData.total" :limit="listData.limit" :page="listData.page" @btn-click="handleTogglePage") material-download-modal(:show="isShowDownload" :musicInfo="musicInfo" @select="handleAddDownload" @close="isShowDownload = false") @@ -44,7 +55,7 @@ export default { }, computed: { ...mapGetters(['setting']), - ...mapGetters('songList', ['sourceInfo', 'tags', 'listData', 'isVisibleListDetail', 'listDetail']), + ...mapGetters('songList', ['sourceInfo', 'tags', 'listData', 'isVisibleListDetail', 'selectListInfo', 'listDetail']), ...mapGetters('list', ['defaultList']), sorts() { return this.source ? this.sourceInfo.sortList[this.source] : [] @@ -60,11 +71,14 @@ export default { sortId(n, o) { this.setSongList({ sortId: n }) if (o === undefined && this.listData.page !== 1) return - this.getList(1).then(() => { - this.$nextTick(() => { - scrollTo(this.$refs.dom_scrollContent, 0) + this.$nextTick(() => { + this.getList(1).then(() => { + this.$nextTick(() => { + scrollTo(this.$refs.dom_scrollContent, 0) + }) }) }) + // if (this.isVisibleListDetail) this.setVisibleListDetail(false) }, tagInfo(n, o) { this.setSongList({ tagInfo: n }) @@ -73,11 +87,14 @@ export default { this.isToggleSource = false return } - this.getList(1).then(() => { - this.$nextTick(() => { - scrollTo(this.$refs.dom_scrollContent, 0) + this.$nextTick(() => { + this.getList(1).then(() => { + this.$nextTick(() => { + scrollTo(this.$refs.dom_scrollContent, 0) + }) }) }) + // if (this.isVisibleListDetail) this.setVisibleListDetail(false) }, source(n, o) { this.setSongList({ source: n }) @@ -101,7 +118,7 @@ export default { methods: { ...mapMutations(['setSongList']), ...mapActions('songList', ['getTags', 'getList', 'getListDetail']), - ...mapMutations('songList', ['setVisibleListDetail']), + ...mapMutations('songList', ['setVisibleListDetail', 'setSelectListInfo']), ...mapActions('download', ['createDownload', 'createDownloadMultiple']), ...mapMutations('list', ['defaultListAdd', 'defaultListAddMultiple']), ...mapMutations('player', ['setList']), @@ -175,8 +192,9 @@ export default { this.isShowDownloadMultiple = false }, handleItemClick(index) { + this.setSelectListInfo(this.listData.list[index]) this.setVisibleListDetail(true) - this.getListDetail({ id: this.listData.list[index].id, page: 1 }) + this.getListDetail({ id: this.selectListInfo.id, page: 1 }) }, handleFlowBtnClick(action) { switch (action) { @@ -209,6 +227,9 @@ export default { resetSelect() { this.selectdData = [] }, + hideListDetail() { + setTimeout(() => this.setVisibleListDetail(false), 50) + }, }, } @@ -240,37 +261,101 @@ export default { .container { flex: auto; overflow: hidden; + // position: relative; } -.materialSongList { +.song-list-header { + background-color: @color-theme_2; + display: flex; + flex-flow: row nowrap; + height: 60px; +} +.song-list-header-left { + flex: none; + margin-left: 5px; + width: 60px; + position: relative; + img { + max-width: 100%; + max-height: 100%; + } + .play-num { + position: absolute; + bottom: 0; + left: 0; + right: 0; + padding: 2px; + background-color: rgba(0, 0, 0, 0.4); + color: #fff; + font-size: 11px; + text-align: right; + .mixin-ellipsis-1; + } +} + +.song_list_header_middle { + flex: auto; + padding: 5px 7px; + h3 { + .mixin-ellipsis-1; + line-height: 1.2; + padding-bottom: 5px; + } + p { + .mixin-ellipsis-2; + font-size: 12px; + line-height: 1.2; + color: #888; + } +} +.song-list-header-right { + flex: none; + display: flex; + align-items: center; + padding-right: 15px; +} + +.material-song-list { position: absolute; width: 100%; height: 100%; top: 0; left: 0; + display: flex; + flex-flow: column nowrap; } .content { height: 100%; overflow-y: auto; padding: 0 15px; + background-color: #fff; ul { display: flex; flex-flow: row wrap; + justify-content: space-between; } } .item { - width: 100% / 3; + width: 32%; box-sizing: border-box; display: flex; - padding-top: 15px; + margin-top: 15px; + cursor: pointer; + transition: opacity @transition-theme; + &:hover { + opacity: .7; + } } .left { flex: none; - width: 30%; + width: 66px; + height: 66px; display: flex; + img { max-width: 100%; + max-height: 100%; } } .right {