├── .browserslistrc
├── docs
├── mvs_footer.jpg
├── mvs_page.jpg
└── pagination.jpg
├── public
├── favicon.png
└── index.html
├── src
├── assets
│ ├── test.jpg
│ ├── coverall.png
│ ├── img
│ │ ├── disc.png
│ │ ├── icon.png
│ │ ├── needle.png
│ │ ├── al_cover_mask.png
│ │ ├── default_avatar.png
│ │ ├── icon-next.svg
│ │ ├── icon-prev.svg
│ │ ├── back.svg
│ │ ├── icon-play.svg
│ │ ├── order_play.svg
│ │ ├── icon-stop.svg
│ │ ├── love_liked.svg
│ │ ├── 24gf-volumeCross.svg
│ │ ├── fanyi_full.svg
│ │ ├── love_like.svg
│ │ ├── random_play.svg
│ │ ├── pull_down.svg
│ │ ├── liked.svg
│ │ ├── like.svg
│ │ ├── fanyi.svg
│ │ ├── wan_sex_w.svg
│ │ ├── music.svg
│ │ ├── 24gf-volumeHigh.svg
│ │ ├── single_play.svg
│ │ └── collect.svg
│ └── css
│ │ ├── base.css
│ │ ├── effect.css
│ │ └── element_ui_style_cover.css
├── utils
│ ├── bus
│ │ ├── index.js
│ │ └── types.js
│ ├── audioer.js
│ ├── cookie.js
│ ├── request.js
│ ├── directive.js
│ ├── utils.js
│ └── filter.js
├── views
│ ├── pages
│ │ ├── TODO.vue
│ │ ├── SongsDetail.vue
│ │ ├── home
│ │ │ ├── PersonalRec.vue
│ │ │ ├── Discover.vue
│ │ │ ├── PlaylistCategory.vue
│ │ │ ├── NewSongs.vue
│ │ │ ├── TopList.vue
│ │ │ └── ArtistsCategory.vue
│ │ ├── Profile.vue
│ │ ├── MyCollects.vue
│ │ ├── AlbumDetail.vue
│ │ ├── Mv.vue
│ │ └── ArtistDetail.vue
│ ├── Footer.vue
│ ├── Aside.vue
│ ├── Header.vue
│ ├── Window.vue
│ └── PlayPreview.vue
├── components
│ ├── layout
│ │ ├── List.vue
│ │ ├── Grid.vue
│ │ └── Rendering.vue
│ ├── content
│ │ ├── label
│ │ │ ├── Album.vue
│ │ │ ├── Avatar.vue
│ │ │ ├── UserName.vue
│ │ │ ├── Artists.vue
│ │ │ └── Artist.vue
│ │ ├── complound
│ │ │ ├── CollectionArtists.vue
│ │ │ ├── ArtistAlbums.vue
│ │ │ ├── NewSongsGlance.vue
│ │ │ ├── ArtistDesc.vue
│ │ │ ├── ArtistVideos.vue
│ │ │ ├── CollectionAlbums.vue
│ │ │ ├── NewAlbumsGlance.vue
│ │ │ ├── BetterSongTrack.vue
│ │ │ ├── SongsSubscribers.vue
│ │ │ ├── CollectionVideos.vue
│ │ │ ├── pendant
│ │ │ │ └── RelatedVideo.vue
│ │ │ ├── UserPlaylist.vue
│ │ │ ├── CommentArea.vue
│ │ │ └── SongsListDetail.vue
│ │ ├── tracks
│ │ │ ├── BigVideoTrack.vue
│ │ │ ├── SongTracksDecorator.vue
│ │ │ ├── UserTrack.vue
│ │ │ ├── ArtistTrack.vue
│ │ │ ├── SongsTrack.vue
│ │ │ ├── AlbumTrack.vue
│ │ │ ├── CommentTrack.vue
│ │ │ └── DetailSongTrack.vue
│ │ ├── matrices
│ │ │ ├── ArtistMatrices.vue
│ │ │ ├── NormalSongsMatrices.vue
│ │ │ ├── CommonVideoMatrices.vue
│ │ │ ├── AlbumMatrices.vue
│ │ │ └── VideoMatrices.vue
│ │ ├── bannar
│ │ │ ├── MainBanner.vue
│ │ │ └── Banner.vue
│ │ ├── covers
│ │ │ ├── AlbumCoverStyle.vue
│ │ │ ├── ArtistCover.vue
│ │ │ ├── NormalSongsCover.vue
│ │ │ ├── AlbumCover.vue
│ │ │ ├── RelatedSongsCover.vue
│ │ │ ├── VideoCover.vue
│ │ │ ├── CoverTemplate.vue
│ │ │ └── CommonVideoCover.vue
│ │ └── clause
│ │ │ ├── ArtistCaluse.vue
│ │ │ ├── UserCaluse.vue
│ │ │ ├── SongsCaluse.vue
│ │ │ ├── AlbumCaluse.vue
│ │ │ ├── BigVideoCaluse.vue
│ │ │ ├── DetailedSongCaluse.vue
│ │ │ └── CommentClause.vue
│ ├── header
│ │ ├── Logo.vue
│ │ ├── HistoryMove.vue
│ │ ├── SearchSuggestPreview.vue
│ │ ├── LoginState.vue
│ │ ├── SearchHotPreview.vue
│ │ └── Search.vue
│ ├── common
│ │ ├── video
│ │ │ ├── icon
│ │ │ │ ├── play.svg
│ │ │ │ ├── stop.svg
│ │ │ │ ├── replay.svg
│ │ │ │ └── full-screen.svg
│ │ │ └── Slider.vue
│ │ ├── IconSwitch.vue
│ │ ├── ProgressBar.vue
│ │ ├── LightInput.vue
│ │ ├── Icon.vue
│ │ ├── BlurBackground.vue
│ │ ├── Volume.vue
│ │ ├── TextFold.vue
│ │ ├── SimpleRadio.vue
│ │ ├── LArea.vue
│ │ ├── Description.vue
│ │ └── Pagination.vue
│ ├── aside
│ │ ├── OwnSongList.vue
│ │ ├── CollectSongList.vue
│ │ ├── Recommendation.vue
│ │ └── MyMusic.vue
│ ├── play
│ │ ├── SongBaseInfo.vue
│ │ ├── Like.vue
│ │ ├── Discplayer.vue
│ │ └── Collect.vue
│ ├── main
│ │ └── Personalized.vue
│ └── pages
│ │ └── topinfo
│ │ ├── ArtistInfoShow.vue
│ │ ├── AlbumInfoShow.vue
│ │ └── ProfileShow.vue
├── store
│ ├── types.js
│ └── index.js
├── test.vue
├── network
│ ├── request_login.js
│ ├── resolved.js
│ ├── request_uesr.js
│ └── behavior.js
├── App.vue
├── main.js
└── router
│ └── index.js
├── .gitignore
├── babel.config.js
├── package.json
├── vue.config.js
├── LICENSE
└── plugins
└── UploadServerPlugin.js
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 | not dead
--------------------------------------------------------------------------------
/docs/mvs_footer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ColorlessWin/cloud_music/HEAD/docs/mvs_footer.jpg
--------------------------------------------------------------------------------
/docs/mvs_page.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ColorlessWin/cloud_music/HEAD/docs/mvs_page.jpg
--------------------------------------------------------------------------------
/docs/pagination.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ColorlessWin/cloud_music/HEAD/docs/pagination.jpg
--------------------------------------------------------------------------------
/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ColorlessWin/cloud_music/HEAD/public/favicon.png
--------------------------------------------------------------------------------
/src/assets/test.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ColorlessWin/cloud_music/HEAD/src/assets/test.jpg
--------------------------------------------------------------------------------
/src/utils/bus/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | const Bus = new Vue()
4 | export default Bus
5 |
--------------------------------------------------------------------------------
/src/assets/coverall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ColorlessWin/cloud_music/HEAD/src/assets/coverall.png
--------------------------------------------------------------------------------
/src/assets/img/disc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ColorlessWin/cloud_music/HEAD/src/assets/img/disc.png
--------------------------------------------------------------------------------
/src/assets/img/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ColorlessWin/cloud_music/HEAD/src/assets/img/icon.png
--------------------------------------------------------------------------------
/src/assets/img/needle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ColorlessWin/cloud_music/HEAD/src/assets/img/needle.png
--------------------------------------------------------------------------------
/src/assets/img/al_cover_mask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ColorlessWin/cloud_music/HEAD/src/assets/img/al_cover_mask.png
--------------------------------------------------------------------------------
/src/assets/img/default_avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ColorlessWin/cloud_music/HEAD/src/assets/img/default_avatar.png
--------------------------------------------------------------------------------
/src/utils/audioer.js:
--------------------------------------------------------------------------------
1 | const Audioer = {
2 | install(Vue) {
3 | Vue.prototype.$audioer = new Audio()
4 | }
5 | }
6 |
7 | export default Audioer
8 |
--------------------------------------------------------------------------------
/src/utils/cookie.js:
--------------------------------------------------------------------------------
1 | const cookie = { }
2 |
3 | Object.defineProperty(cookie, 'value', {
4 | get() {
5 | return localStorage.getItem('cookie')
6 | },
7 | set(v) {
8 | localStorage.setItem('cookie', v)
9 | }
10 | })
11 |
12 | export default cookie
13 |
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 | pnpm-debug.log*
14 |
15 | # Editor directories and files
16 | .idea
17 | .vscode
18 | *.suo
19 | *.ntvs*
20 | *.njsproj
21 | *.sln
22 | *.sw?
23 |
--------------------------------------------------------------------------------
/src/views/pages/TODO.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
TODO...
4 |
5 |
6 |
7 |
12 |
13 |
20 |
--------------------------------------------------------------------------------
/src/views/pages/SongsDetail.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
12 |
13 |
16 |
--------------------------------------------------------------------------------
/src/assets/img/icon-next.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/img/icon-prev.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset',
4 | ['@babel/preset-env', {
5 | "useBuiltIns": "entry",
6 | "corejs": "3"
7 | }
8 | ]
9 | ],
10 | "plugins": [
11 | [
12 | "component",
13 | {
14 | "libraryName": "element-ui",
15 | "styleLibraryName": "theme-chalk"
16 | }
17 | ]
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/src/views/Footer.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
16 |
17 |
22 |
--------------------------------------------------------------------------------
/src/utils/bus/types.js:
--------------------------------------------------------------------------------
1 | export default {
2 | USER_LOGIN: 'user_login',
3 | LOGIN_PANEL_CUTOVER : 'login_panel_cutover',
4 | AUDIO_PLAY: 'audio_play',
5 | AUDIO_CHANGE: 'audio_change',
6 | SINGLE_AUDIO_PLAY: 'single_audio_play',
7 | OPEN_PLAYING_PLANE: 'open_playing_plane',
8 | CLOSE_PLAYING_PLANE: 'close_playing_plane',
9 |
10 | PLACE_LOGIN: 'place_login'
11 | }
12 |
--------------------------------------------------------------------------------
/src/components/layout/List.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
16 |
17 |
20 |
--------------------------------------------------------------------------------
/src/components/content/label/Album.vue:
--------------------------------------------------------------------------------
1 |
2 | {{ name }}
3 |
4 |
5 |
14 |
15 |
20 |
--------------------------------------------------------------------------------
/src/assets/css/base.css:
--------------------------------------------------------------------------------
1 | span, div {
2 | font-family: 微软雅黑, Helvetica, Arial, sans-serif;
3 | -webkit-font-smoothing: antialiased;
4 | -moz-osx-font-smoothing: grayscale;
5 | }
6 |
7 | body, html {
8 | padding: 0;
9 | margin: 0;
10 | }
11 |
12 | .clearfix:before,
13 | .clearfix:after {
14 | display: table;
15 | content: "";
16 | }
17 |
18 | .clearfix:after {
19 | clear: both;
20 | }
21 |
22 | .clearfix {
23 | *zoom: 1;
24 | }
25 |
--------------------------------------------------------------------------------
/src/components/header/Logo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
11 |
12 |
21 |
--------------------------------------------------------------------------------
/src/store/types.js:
--------------------------------------------------------------------------------
1 | export default {
2 | UPDATE_LOGIN_STATUS: 'update_login_status',
3 | AUDIO_CHANGE: 'audio_change',
4 | AUDIO_PLAY: 'audio_play',
5 | AUDIO_STOP: 'audio_stop',
6 | AUDIO_INSERT: 'audio_insert',
7 | PLAYLIST: 'playlist',
8 | COLL_PLAYLIST: 'coll_playlist',
9 | LIKED_SONG: 'liked_song',
10 | LIKE_LIST_ADD: 'like_list_add',
11 | LIKE_LIST_DEL: 'like_list_del'
12 | }
13 |
--------------------------------------------------------------------------------
/src/components/common/video/icon/play.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/components/content/label/Avatar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
15 |
16 |
21 |
--------------------------------------------------------------------------------
/src/components/common/video/icon/stop.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/css/effect.css:
--------------------------------------------------------------------------------
1 | .effect-transition {
2 | transition-property: all;
3 | transition-duration: 0.4s;
4 | }
5 |
6 | .effect-hover-float:focus {
7 | box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1)
8 | }
9 |
10 |
11 | .effect-hover-float:hover {
12 | box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.2)
13 | }
14 |
15 | .eff-shadow {
16 | box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1)
17 | }
18 |
19 | .light-scroll::-webkit-scrollbar {
20 | width: 3px;
21 | }
22 |
23 | .light-scroll::-webkit-scrollbar-thumb {
24 | width: 3px;
25 | border-radius: 2px;
26 | background-color: #e0e0e0;
27 | }
28 |
--------------------------------------------------------------------------------
/src/components/content/label/UserName.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
20 |
21 |
27 |
--------------------------------------------------------------------------------
/src/assets/img/back.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/components/content/label/Artists.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | /
5 |
6 |
7 |
8 |
9 |
10 |
20 |
21 |
24 |
--------------------------------------------------------------------------------
/src/test.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
25 |
26 |
29 |
--------------------------------------------------------------------------------
/src/assets/img/icon-play.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/utils/request.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import cookie from "./cookie";
3 | const HOST = process.env.VUE_APP_HOST || 'http://localhost'
4 | const PORT = process.env.VUE_APP_PORT || 3000
5 |
6 | const instance = axios.create({
7 | baseURL: `${HOST}:${PORT}`,
8 | timeout: 5000
9 | })
10 |
11 | instance
12 | .interceptors
13 | .request
14 | .use(config => {
15 | if (!config.params) config.params = {}
16 | if (!config.params.cookie) config.params.cookie = cookie.value
17 | return config
18 | }, error => {
19 | console.log(error)
20 | })
21 |
22 | instance
23 | .interceptors
24 | .response
25 | .use(result => result.data)
26 |
27 | export default instance
28 |
--------------------------------------------------------------------------------
/src/components/aside/OwnSongList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 创建的歌单
5 | {{item.name.trim()}}
9 |
10 |
11 |
12 |
13 |
14 |
25 |
26 |
29 |
--------------------------------------------------------------------------------
/src/components/aside/CollectSongList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 收藏的歌单
5 | {{item.name}}
9 |
10 |
11 |
12 |
13 |
14 |
25 |
26 |
29 |
--------------------------------------------------------------------------------
/src/assets/img/order_play.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/layout/Grid.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
20 |
21 |
27 |
--------------------------------------------------------------------------------
/src/network/request_login.js:
--------------------------------------------------------------------------------
1 | import axios from '../utils/request'
2 | import md5 from 'js-md5'
3 | const request = axios
4 |
5 | //手机号登录
6 | export function login_cellphone( cellphone, password, hex = true ) {
7 | let params = { phone: cellphone }
8 | if (hex) params['md5_password'] = md5.hex(password)
9 | else params['password'] = password
10 |
11 | return request( { url: '/login/cellphone', params } )
12 | }
13 |
14 | //刷新登录状态
15 | export function login_refresh()
16 | { return request( { url: 'login/refresh' } ) }
17 |
18 |
19 | //获取登录状态
20 | export function login_status()
21 | { return request( { url: '/login/status' } ) }
22 |
23 |
24 | //退出登录
25 | export function logout()
26 | { return request( { url: '/logout' } ) }
27 |
--------------------------------------------------------------------------------
/src/components/content/complound/CollectionArtists.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
25 |
26 |
29 |
--------------------------------------------------------------------------------
/src/components/content/tracks/BigVideoTrack.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
21 |
22 |
25 |
--------------------------------------------------------------------------------
/src/utils/directive.js:
--------------------------------------------------------------------------------
1 | export default {
2 |
3 | install: function(Vue) {
4 |
5 | let text_to_html = function (el, binding) {
6 | for (let i = el.childNodes.length - 1; i >= 0; i--) {
7 | el.removeChild(el.childNodes[i])
8 | }
9 | if (!binding.value) return
10 |
11 | let texts = binding.value.split('\n')
12 | for (let i = 0; i < texts.length; i++) {
13 | let line = document.createElement('div')
14 | line.appendChild(document.createTextNode(texts[i]))
15 | if (!texts[i]) line.style.height = '1.1em'
16 | el.appendChild(line)
17 | }
18 | }
19 |
20 | Vue.directive('mline-text', {
21 | bind: text_to_html,
22 | update: text_to_html
23 | })
24 | }
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/src/components/content/matrices/ArtistMatrices.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
21 |
22 |
25 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cloud_music",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build"
8 | },
9 | "dependencies": {
10 | "axios": "^0.19.2",
11 | "core-js": "^3.6.5",
12 | "element-ui": "^2.13.2",
13 | "js-md5": "^0.7.3",
14 | "vue": "^2.6.11",
15 | "vue-router": "^3.2.0",
16 | "vuex": "^3.4.0"
17 | },
18 | "devDependencies": {
19 | "@vue/cli-plugin-babel": "~4.4.0",
20 | "@vue/cli-plugin-router": "~4.4.0",
21 | "@vue/cli-plugin-vuex": "~4.4.0",
22 | "@vue/cli-service": "~4.4.0",
23 | "babel-plugin-component": "^1.1.1",
24 | "vue-template-compiler": "^2.6.11",
25 | "webpack-cli": "^3.3.12"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | 网易云音乐(仿)
11 |
12 |
13 |
14 | We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/assets/img/icon-stop.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/components/content/bannar/MainBanner.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
31 |
32 |
35 |
--------------------------------------------------------------------------------
/src/components/content/covers/AlbumCoverStyle.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
17 |
18 |
35 |
--------------------------------------------------------------------------------
/src/views/pages/home/PersonalRec.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
32 |
33 |
36 |
--------------------------------------------------------------------------------
/src/components/header/HistoryMove.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
29 |
--------------------------------------------------------------------------------
/src/components/content/complound/ArtistAlbums.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
30 |
31 |
34 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | const UploadServerPlugin = require('./plugins/UploadServerPlugin')
2 |
3 | module.exports = {
4 | publicPath: process.env.NODE_ENV === 'production'? './' : '/',
5 | productionSourceMap: false,
6 |
7 | configureWebpack: {
8 |
9 | plugins: [
10 | /**
11 | * 项目build后自动将 dist 文件夹下的文件全部上传到服务器
12 | * option{address} 服务器地址
13 | * option{port} 端口
14 | * option{password} 密码, 服务器需要验证密码才能执行更新
15 | * */
16 | new UploadServerPlugin({
17 | address: process.env.ADDRESS || 'localhost',
18 | port: process.env.HOT_UPDATE_PORT || '80',
19 | password: process.env.MY_KEY || ''
20 | })
21 | ],
22 |
23 | resolve: {
24 | alias: {
25 | 'assets': '@/assets',
26 | 'components': '@/components',
27 | 'views': '@/views',
28 | }
29 | },
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/components/common/IconSwitch.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
30 |
31 |
36 |
--------------------------------------------------------------------------------
/src/components/content/complound/NewSongsGlance.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
31 |
32 |
35 |
--------------------------------------------------------------------------------
/src/assets/img/love_liked.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/content/complound/ArtistDesc.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
39 |
40 |
43 |
--------------------------------------------------------------------------------
/src/components/content/complound/ArtistVideos.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
31 |
32 |
35 |
--------------------------------------------------------------------------------
/src/components/aside/Recommendation.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 推荐
5 |
8 | 发现音乐
9 |
10 |
13 | 视频
14 |
15 |
19 | 朋友
20 |
21 |
25 | 私人FM
26 |
27 |
28 |
29 |
30 |
31 |
36 |
37 |
42 |
--------------------------------------------------------------------------------
/src/assets/img/24gf-volumeCross.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/content/label/Artist.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ name }}
4 | ({{ alia.join(' / ') }})
5 |
6 | {{ name }}
7 |
8 |
9 |
27 |
28 |
37 |
--------------------------------------------------------------------------------
/src/components/aside/MyMusic.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 我的音乐
5 |
9 | 每日推荐
10 |
11 |
15 | 我的音乐云盘
16 |
17 |
21 | 我的电台
22 |
23 |
27 | 我的收藏
28 |
29 |
30 |
31 |
32 |
33 |
38 |
39 |
42 |
--------------------------------------------------------------------------------
/src/components/common/ProgressBar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ value | timeLongFormat }}
4 |
5 | {{ duration | timeLongFormat }}
6 |
7 |
8 |
9 |
18 |
19 |
40 |
--------------------------------------------------------------------------------
/src/components/common/LightInput.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 | :
10 |
20 |
21 |
37 |
--------------------------------------------------------------------------------
/src/components/common/video/icon/replay.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/components/content/complound/CollectionAlbums.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
35 |
36 |
39 |
--------------------------------------------------------------------------------
/src/views/Aside.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
33 |
34 |
43 |
--------------------------------------------------------------------------------
/src/network/resolved.js:
--------------------------------------------------------------------------------
1 | import {
2 | song_detail,
3 | song_list_detail,
4 | comment_music,
5 | comment_playlist,
6 | comment_video, comment_album, comment_mv
7 | } from "@/network/request_show";
8 |
9 | export async function song_tracks(sid, offset, limit) {
10 | let result = await song_list_detail(sid)
11 | let songs = result['playlist']['trackIds'].slice(offset, offset + limit).map(value => value['id'])
12 | songs = await song_detail(songs.join(','))
13 | return {
14 | metadata: { id: sid, total: result['playlist']['trackCount']},
15 | data: songs
16 | }
17 | }
18 |
19 | export function get_comment_request(type) {
20 | let request = null
21 | if (type === 'playlist') request = comment_playlist
22 | if (type === 'music') request = comment_music
23 | if (type === 'video') request = comment_video
24 | if (type === 'album') request = comment_album
25 | if (type === 'mv') request = comment_mv
26 | if (!request) console.error('no type request')
27 | return request
28 | }
29 |
--------------------------------------------------------------------------------
/src/network/request_uesr.js:
--------------------------------------------------------------------------------
1 | import axios from '../utils/request'
2 | const request = axios
3 |
4 | //获取用户信息 , 歌单,收藏,mv, dj 数量
5 | export function user_subcount() {
6 | return request( { url: '/user/subcount' } )
7 | }
8 |
9 | //获取已收藏的歌曲列表
10 | export function artist_sublist() {
11 | return request( { url: '/artist/sublist' } )
12 | }
13 |
14 | //获取已收藏的专辑列表
15 | export function album_sublist(offset, limit) {
16 | return request( { url: '/album/sublist', params: { offset, limit } } )
17 | }
18 |
19 | //获取已收藏的MV列表
20 | export function mv_sublist() {
21 | return request( { url: '/mv/sublist' } )
22 | }
23 |
24 | //获取用户详情
25 | export function user_detail( uid ) {
26 | return request( { url: '/user/detail', params: { uid } } )
27 | }
28 |
29 |
30 | //获取用户歌单
31 | export function playlist( uid ) {
32 | return request( { url: '/user/playlist', params: { uid } } )
33 | }
34 |
35 |
36 | //获取用户喜欢的歌曲列表
37 | export function likelist(uid) {
38 | return request( { url: '/likelist', params: { uid } } )
39 | }
40 |
--------------------------------------------------------------------------------
/src/components/common/Icon.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
13 |
14 |
15 |
16 |
33 |
34 |
43 |
--------------------------------------------------------------------------------
/src/components/content/tracks/SongTracksDecorator.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
35 |
36 |
39 |
--------------------------------------------------------------------------------
/src/components/header/SearchSuggestPreview.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 | {{ suggest[index]['keyword'] }}
6 |
7 |
8 |
9 |
10 |
18 |
19 |
45 |
--------------------------------------------------------------------------------
/src/views/pages/Profile.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
44 |
45 |
48 |
--------------------------------------------------------------------------------
/src/components/content/complound/NewAlbumsGlance.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
40 |
41 |
44 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 ColorlessWin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/src/views/pages/MyCollects.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
37 |
38 |
41 |
--------------------------------------------------------------------------------
/src/components/content/complound/BetterSongTrack.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
43 |
44 |
47 |
--------------------------------------------------------------------------------
/src/components/layout/Rendering.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
12 |
13 |
14 |
23 |
24 |
25 |
26 |
45 |
46 |
51 |
--------------------------------------------------------------------------------
/src/views/Header.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
28 |
29 |
56 |
--------------------------------------------------------------------------------
/src/components/header/LoginState.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
未登录
6 |
7 |
8 |
9 |
{{$store.state.profile.name}}
10 |
11 |
12 |
13 |
14 |
29 |
30 |
50 |
--------------------------------------------------------------------------------
/src/assets/img/fanyi_full.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/img/love_like.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/img/random_play.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/content/covers/ArtistCover.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
{{ adapter.name(artist) }}
8 |
9 |
10 | 歌曲数量:
11 | {{ adapter.musicSize(artist) }}
12 | 专辑数量:
13 | {{ adapter.albumCount(artist) }}
14 |
15 |
16 |
17 |
18 |
29 |
30 |
39 |
--------------------------------------------------------------------------------
/src/components/play/SongBaseInfo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ song['name'] }}
4 |
专辑:
5 |
歌手:
6 |
7 |
8 |
9 |
33 |
34 |
51 |
--------------------------------------------------------------------------------
/src/assets/img/pull_down.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/main/Personalized.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
35 |
36 |
48 |
--------------------------------------------------------------------------------
/src/assets/img/liked.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/common/video/icon/full-screen.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/img/like.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/components/content/clause/ArtistCaluse.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{ adapter.name(artist) }}
5 |
6 | ({{ adapter.alias(artist).join(' / ') }})
7 |
8 |
9 |
10 |
11 |
20 |
21 |
53 |
--------------------------------------------------------------------------------
/src/components/content/complound/SongsSubscribers.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
13 |
41 |
42 |
53 |
--------------------------------------------------------------------------------
/src/components/content/tracks/UserTrack.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 |
13 |
35 |
36 |
45 |
--------------------------------------------------------------------------------
/src/components/content/covers/NormalSongsCover.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
{{ adapter.title(songs) }}
8 |
9 |
10 | by
11 | {{ adapter.author(songs)['name'] }}
12 |
13 |
14 | {{ adapter.playTime(songs) | logogram}}
15 |
16 |
17 |
18 |
19 |
31 |
32 |
37 |
--------------------------------------------------------------------------------
/src/components/content/matrices/NormalSongsMatrices.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 |
13 |
42 |
43 |
46 |
--------------------------------------------------------------------------------
/src/components/content/tracks/ArtistTrack.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
13 |
14 |
39 |
40 |
49 |
--------------------------------------------------------------------------------
/src/components/content/matrices/CommonVideoMatrices.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 |
13 |
41 |
42 |
45 |
--------------------------------------------------------------------------------
/src/components/common/BlurBackground.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
31 |
32 |
64 |
--------------------------------------------------------------------------------
/src/network/behavior.js:
--------------------------------------------------------------------------------
1 | import axios from '../utils/request'
2 | const request = axios
3 |
4 | /**
5 | * 传入 type, 资源 id, 和评论 id cid 和 是否点赞参数 t 即可给对 应评论点赞 ( 需要登录 )
6 | *
7 | * */
8 | export function comment_like( id, cid, type, t ) {
9 | let type_map = {
10 | music: 0,
11 | mv : 1,
12 | playlist: 2,
13 | album: 3,
14 | video: 5
15 | }
16 | return request({
17 | url: 'comment/like',
18 | params: {
19 | id, cid,
20 | type: type_map[type],
21 | t: (t + 0)
22 | }
23 | })
24 | }
25 |
26 | /**
27 | * 传入类型和歌单 id 可收藏歌单或者取消收藏歌单
28 | * @param {String | Number} id 歌单id
29 | * @param { Boolean } t true 收藏歌单 false取消收藏
30 | * */
31 | export function playlist_sub(id, t) {
32 | return request( { url: '/playlist/subscribe', params: { id, t: (t + 0) } } )
33 | }
34 |
35 | /**
36 | * 传入音乐 id, 可喜欢该音乐
37 | * @method like
38 | * @param {String | Number} id 歌曲id
39 | * @param {Boolean} like 默认为 true 即喜欢 , 若传 false, 则取消喜欢
40 | * */
41 | export function like(id, like = true) {
42 | return request( { url: '/like', params: { id, like } } )
43 | }
44 |
45 | /**
46 | * 可以添加歌曲到歌单或者从歌单删除某首歌曲 ( 需要登录 )
47 | * @method playlist_option
48 | * @param {String} op [ 'add' | 'del' ] 添加或删除
49 | * @param {String | Number} pid 歌单id
50 | * @param {String | Number} tracks 歌曲id
51 | * */
52 | export function playlist_option(op, pid, tracks) {
53 | return request( { url: '/playlist/tracks', params: { op, pid, tracks } } )
54 | }
55 |
--------------------------------------------------------------------------------
/src/components/content/clause/UserCaluse.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
{{ adapter.name(user) }}
6 |
7 |
8 |
{{ adapter.synopsis(user) }}
9 |
10 |
11 |
12 |
13 |
24 |
25 |
61 |
--------------------------------------------------------------------------------
/src/components/content/matrices/AlbumMatrices.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
13 |
14 |
46 |
47 |
50 |
--------------------------------------------------------------------------------
/src/components/pages/topinfo/ArtistInfoShow.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
16 |
17 |
单曲数:{{ artist['musicSize'] }}
18 |
专辑数:{{ artist['albumSize'] }}
19 |
MV数:{{ artist['mvSize'] }}
20 |
21 |
22 |
23 |
24 |
34 |
35 |
65 |
--------------------------------------------------------------------------------
/src/assets/img/fanyi.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/content/tracks/SongsTrack.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
11 |
12 |
40 |
41 |
50 |
--------------------------------------------------------------------------------
/src/components/content/tracks/AlbumTrack.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 |
13 |
42 |
43 |
52 |
--------------------------------------------------------------------------------
/src/components/content/covers/AlbumCover.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{ adapter.name(album) }}
5 |
8 | {{ adapter.publishTime(album) | dateTimeFormat('yyyy-MM-dd') }}
9 |
10 |
13 |
14 |
15 |
16 |
29 |
30 |
54 |
--------------------------------------------------------------------------------
/src/components/content/matrices/VideoMatrices.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 |
13 |
43 |
44 |
50 |
--------------------------------------------------------------------------------
/src/components/content/complound/CollectionVideos.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
49 |
50 |
53 |
--------------------------------------------------------------------------------
/src/components/pages/topinfo/AlbumInfoShow.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
{{ album['name'] }}
8 |
歌手:
12 |
13 |
发行时间:{{ album['publishTime'] | dateTimeFormat('yyyy-MM-dd') }}
14 |
发行公司:{{ album['company'] }}
15 |
16 |
17 |
18 |
19 |
30 |
31 |
58 |
--------------------------------------------------------------------------------
/src/assets/img/wan_sex_w.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/img/music.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/common/Volume.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
10 |
37 |
38 |
66 |
--------------------------------------------------------------------------------
/src/components/play/Like.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
55 |
56 |
59 |
--------------------------------------------------------------------------------
/src/components/content/complound/pendant/RelatedVideo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
51 |
52 |
55 |
--------------------------------------------------------------------------------
/src/components/content/clause/SongsCaluse.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
{{ adapter.name(songs) }}
6 |
7 |
8 | {{adapter.total(songs)}}首
9 | by
10 | {{ adapter.creator(songs)['name'] }}
11 |
12 |
13 |
14 |
15 |
26 |
27 |
68 |
--------------------------------------------------------------------------------
/src/components/common/TextFold.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
47 |
48 |
79 |
--------------------------------------------------------------------------------
/src/components/content/covers/RelatedSongsCover.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
{{songs['name']}}
7 |
{{ songs['copywriter'] }}
8 |
9 |
10 |
11 |
12 |
13 |
21 |
22 |
76 |
--------------------------------------------------------------------------------
/src/components/content/tracks/CommentTrack.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
44 |
45 |
50 |
--------------------------------------------------------------------------------
/src/assets/img/24gf-volumeHigh.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/common/SimpleRadio.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ option }}
8 | |
9 |
10 |
11 |
12 |
13 |
40 |
41 |
64 |
--------------------------------------------------------------------------------
/src/components/content/complound/UserPlaylist.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
58 |
59 |
64 |
--------------------------------------------------------------------------------
/src/components/common/LArea.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
47 |
48 |
81 |
--------------------------------------------------------------------------------
/src/components/content/covers/VideoCover.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
{{ adapter.title(video) }}
8 |
9 |
10 | by
11 | {{ adapter.author(video)['name'] }}
12 |
13 |
14 | {{ adapter.duration(video) | timeLongFormat(true) }}
15 |
16 | {{ adapter.play(video) | logogram}}
17 |
18 |
19 |
20 |
21 |
41 |
42 |
51 |
--------------------------------------------------------------------------------
/src/views/pages/home/Discover.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
59 |
60 |
66 |
--------------------------------------------------------------------------------
/src/components/content/clause/AlbumCaluse.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
{{ adapter.name(album) }}
8 |
9 |
16 |
17 |
18 |
19 |
31 |
32 |
70 |
--------------------------------------------------------------------------------
/src/components/common/Description.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
61 |
62 |
68 |
--------------------------------------------------------------------------------
/src/components/header/SearchHotPreview.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
热搜榜
4 |
5 |
{{ index + 1 }}
6 |
7 |
{{ item['searchWord'] }}
8 |
{{ item['score'] }}
9 |
10 |
{{ item['content'] }}
11 |
12 |
13 |
14 |
15 |
16 |
24 |
25 |
77 |
--------------------------------------------------------------------------------
/src/assets/img/single_play.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/views/pages/home/PlaylistCategory.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 热门标签:
5 |
6 | {{ tag['name'] }}
7 | |
8 |
9 |
10 |
11 |
19 |
20 |
21 |
22 |
59 |
60 |
76 |
--------------------------------------------------------------------------------
/src/components/play/Discplayer.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
19 |
20 |
84 |
--------------------------------------------------------------------------------
/src/assets/img/collect.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/content/bannar/Banner.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
{{item['typeTitle']}}
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
30 |
31 |
76 |
--------------------------------------------------------------------------------
/src/components/play/Collect.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
23 |
24 |
25 |
26 |
55 |
56 |
83 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
73 |
74 |
81 |
--------------------------------------------------------------------------------
/src/views/Window.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
58 |
59 |
95 |
--------------------------------------------------------------------------------
/src/components/content/covers/CoverTemplate.vue:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 |
38 |
39 |
78 |
--------------------------------------------------------------------------------
/src/utils/utils.js:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * 看起来很多余的一个方法 但其实是为了方便通过直接调用一个箭头函数来实现一些优雅方便的写法
4 | * 示例:
5 | * let arr = [
6 | * { n: '$', v: '-1' },
7 | * ...call(()=> {
8 | * let map = []
9 | * let str_code = String.fromCharCode
10 | * for (let i = 0; i < 26; i++) {
11 | * map.push({ 'n': str_code(65 + i), 'v': str_code(97 + i)})
12 | * } return map
13 | * }), { n: '#', v: '0' }
14 | * ]
15 | * 在数组初始化时就优雅的构造了一个复杂的数据:
16 | * arr: [ { n: '$', v: '-1' }, { n: A, v: a}, { n: B, v: b}, ... { n: Z, v: 'z }, { n: '#', v: '0' } ]
17 | * */
18 | export function call(func) { return func() }
19 |
20 |
21 | export function future(func, delay, _this) {
22 | setTimeout( () => {
23 | if (_this) func.call(_this)
24 | else func()
25 | }, delay)
26 | }
27 |
28 |
29 |
30 | export function str_empty(str) {
31 | if (!str) return true
32 | return str.replace(/(^s*)|(s*$)/g, "").length === 0
33 | }
34 |
35 |
36 | export function debounce(func, delay, _this) {
37 | let timer = null;
38 | return function (...args) {
39 | if (timer) clearTimeout(timer)
40 | timer = setTimeout(() =>{
41 | if (_this) func.apply(_this, args)
42 | else func(args)
43 | }, delay)
44 | }
45 | }
46 |
47 |
48 | //解析lyric格式的歌词
49 | export function lyricParse(lyric) {
50 | if (!lyric) return {}
51 | let lyrics_arr = lyric.split('\n')
52 | let lyric_map = {}
53 | for (let i = 0; i < lyrics_arr.length - 1; i++) {
54 | let str_time = /\d{1,2}[.,:]\d{1,2}[.,:]\d{2,3}/.exec(lyrics_arr[i])
55 | if (str_time) {
56 | str_time = str_time[0]
57 | // IE 中的一个大坑
58 | // IE 浏览器不支持正则中的后置断言和前置断言
59 | // let m = /(?<=\[)\d{1,2}/.exec(str_time)[0]
60 | // let s = /(?<=\[\d{1,2}[.,:])\d{1,2}/.exec(str_time)[0]
61 | let times = str_time.split(/[.,:]/)
62 | let m = times[0]
63 | let s = times[1]
64 | let time = (parseInt(m) * 60) + parseInt(s)
65 | let result = lyrics_arr[i].split(/\[\d{1,2}[.,:]\d{1,2}[.,:]\d{2,3}]/)[1]
66 | lyric_map[time] = result ? result : '...'
67 | }
68 | }
69 | return lyric_map
70 | }
71 |
72 |
73 |
--------------------------------------------------------------------------------
/src/views/pages/home/NewSongs.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
59 |
60 |
67 |
--------------------------------------------------------------------------------
/src/components/content/clause/BigVideoCaluse.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
{{ adapter.playTime(video) | logogram }}
6 |
7 |
8 |
{{ adapter.title(video) }}
9 |
{{ adapter.duration(video) | timeLongFormat(true) }}
10 |
by {{ adapter.creatorName(video) }}
11 |
12 |
13 |
14 |
15 |
34 |
35 |
86 |
--------------------------------------------------------------------------------
/src/views/PlayPreview.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
{{ song['name'] }}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
49 |
50 |
92 |
--------------------------------------------------------------------------------
/src/views/pages/home/TopList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
{{ item['name'] }}
12 |
{{ item['updateFrequency'] }}
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
46 |
47 |
86 |
--------------------------------------------------------------------------------
/src/views/pages/AlbumDetail.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
70 |
71 |
80 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import 'core-js/stable';
2 | import 'regenerator-runtime/runtime'
3 |
4 | import Vue from 'vue'
5 | import App from './App.vue'
6 | import router from './router'
7 | import store from './store'
8 | import cookie from "./utils/cookie";
9 | import Bus from "./utils/bus";
10 | import Filter from "@/utils/filter";
11 | import Audioer from "@/utils/audioer";
12 | import Directive from "@/utils/directive"
13 |
14 |
15 | import {
16 | Button,
17 | Select,
18 | Input,
19 | Option,
20 | Container,
21 | Header,
22 | Aside,
23 | Main,
24 | Footer,
25 | Card,
26 | Menu,
27 | MenuItem,
28 | Submenu,
29 | Tabs,
30 | TabPane,
31 | Carousel,
32 | CarouselItem,
33 | Row,
34 | Col,
35 | Pagination,
36 | Slider,
37 | RadioButton,
38 | RadioGroup,
39 | Popover,
40 |
41 | Loading,
42 | Notification,
43 | } from 'element-ui';
44 |
45 | import 'element-ui/lib/theme-chalk/index.css';
46 | import '@/assets/css/effect.css'
47 | import '@/assets/css/element_ui_style_cover.css'
48 |
49 | Vue.use(Button)
50 | Vue.use(Select)
51 | Vue.use(Container)
52 | Vue.use(Header)
53 | Vue.use(Aside)
54 | Vue.use(Main)
55 | Vue.use(Footer)
56 | Vue.use(Card)
57 | Vue.use(Input)
58 | Vue.use(Option)
59 | Vue.use(MenuItem)
60 | Vue.use(Menu)
61 | Vue.use(Submenu)
62 | Vue.use(Tabs)
63 | Vue.use(TabPane)
64 | Vue.use(Carousel)
65 | Vue.use(CarouselItem)
66 | Vue.use(Row)
67 | Vue.use(Col)
68 | Vue.use(Pagination)
69 | Vue.use(Slider)
70 | Vue.use(RadioButton)
71 | Vue.use(RadioGroup)
72 | Vue.use(Popover)
73 | Vue.use(Loading.directive)
74 |
75 | //安装全局filter
76 | Vue.use(Filter)
77 |
78 | //安装全局audio
79 | Vue.use(Audioer)
80 |
81 | //自定义v-指令
82 | Vue.use(Directive)
83 |
84 | const Check = function(obj) {
85 | if (!obj) return false
86 | if (typeof obj === 'object' && Object.keys(obj).length === 0) return false
87 | if (Array.isArray(obj) && obj.length === 0) return false
88 | return true
89 | }
90 |
91 | Vue.config.productionTip = false
92 |
93 | Vue.prototype.$cookie = cookie
94 | Vue.prototype.$notify = Notification
95 | Vue.prototype.$bus = Bus
96 | Vue.prototype.$Check = Check
97 |
98 |
99 | new Vue({
100 | router,
101 | store,
102 | render: h => h(App)
103 | }).$mount('#app')
104 |
--------------------------------------------------------------------------------
/plugins/UploadServerPlugin.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios')
2 | const path = require('path')
3 | const fs = require('fs')
4 |
5 | const PLUGIN_NAME = 'UploadServerPlugin'
6 |
7 | class UploadServerPlugin {
8 |
9 | constructor(config) { this.config = config }
10 |
11 | apply(compiler) {
12 |
13 | compiler.hooks.afterEmit.tap(PLUGIN_NAME, compilation => {
14 |
15 | if (process.env.NODE_ENV !== 'production')
16 | return
17 |
18 | let assets = compilation.assets
19 | this.upload(assets)
20 | .then(() =>
21 | console.log('\x1B[32m%s\x1B[39m', 'Upload to complete'))
22 | })
23 | }
24 |
25 | upload(assets) {
26 | return new Promise((resolve, reject) => {
27 | this.beforeUpdate()
28 | .then(() => this.updateAll(assets))
29 | .then(() => resolve())
30 | .catch(err => {
31 | let meg = err.response? {
32 | 401: '密码错误!',
33 | 403: '请求暂时被拒接!',
34 | 500: '服务器更新文件失败!'
35 | }[err.response.status]: ''
36 | console.log('\x1B[31m%s\x1B[39m', `上传服务器失败!! \n ${meg} \n ${err}`)
37 | })
38 | })
39 | }
40 |
41 | beforeUpdate() {
42 | let config = this.config
43 | return axios
44 | .post(`${config.address}:${config.port}/api/before-update`,{
45 | key: config.password
46 | })
47 | }
48 |
49 | updateAll(assets) {
50 | let promises = []
51 |
52 | Object.keys(assets)
53 | .forEach((filename) =>
54 | promises.push(this.update(filename, assets[filename].existsAt)))
55 |
56 | return Promise.all(promises)
57 | }
58 |
59 | update(filename, fullPath) {
60 | let config = this.config
61 |
62 | return new Promise((resolve, reject) => {
63 | fs.readFile(fullPath, (err, data) => {
64 | if (err) {
65 | reject(`fs 读取文件错误:${fullPath} \n ${err}`)
66 | return
67 | }
68 |
69 | axios
70 | .post(`${config.address}:${config.port}/api/hot-update`, {
71 | key: config.password,
72 | filename: filename,
73 | file: data,
74 | }).then(res => {
75 | console.log('\x1B[32m%s\x1B[39m', `上传文件成功: dist/${filename}`)
76 | resolve(res)
77 | }).catch(err => reject(err))
78 | })
79 | })
80 | }
81 | }
82 |
83 | module.exports = UploadServerPlugin
84 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueRouter from 'vue-router'
3 |
4 | Vue.use(VueRouter)
5 |
6 | const TODO = ()=> import('@/views/pages/TODO')
7 |
8 | const Discover = () => import('@/views/pages/home/Discover')
9 | const PersonalRec = () => import('@/views/pages/home/PersonalRec')
10 | const PlaylistCategory = () => import('@/views/pages/home/PlaylistCategory')
11 | const TopList = () => import('@/views/pages/home/TopList')
12 | const ArtistCategory = ()=> import('@/views/pages/home/ArtistsCategory')
13 | const NewSongs = () => import('@/views/pages/home/NewSongs')
14 | const Collects = () => import('@/views/pages/MyCollects')
15 | const Mv = () => import('@/views/pages/Mv')
16 |
17 | const SongsDetail = () => import('@/views/pages/SongsDetail')
18 | const SearchDetail = () => import('@/views/pages/SearchDetail')
19 | const VideoPlay = () => import('@/views/pages/VideoPlay')
20 | const AlbumDetail = ()=> import('@/views/pages/AlbumDetail')
21 | const ArtistDetail = ()=> import('@/views/pages/ArtistDetail')
22 | const Profile = ()=> import('@/views/pages/Profile')
23 |
24 |
25 | const routes = [
26 | { path: '/', redirect: '/discover' },
27 |
28 | {
29 | path: '/test',
30 | component: () => import('@/test')
31 | },
32 |
33 | {
34 | path: '/discover', component: Discover,
35 | children: [
36 | { path: '/', redirect: '/discover/recommend' },
37 | { path: '/discover/recommend', component: PersonalRec },
38 | { path: '/discover/playlists', component: PlaylistCategory },
39 | { path: '/discover/toplist', component: TopList },
40 | { path: '/discover/artists', component: ArtistCategory },
41 | { path: '/discover/newsongs', component: NewSongs }
42 | ]
43 | },
44 |
45 | { path: '/todo', component: TODO },
46 |
47 | { path: '/playlist/:id', component: SongsDetail },
48 |
49 | { path: '/search' , component: SearchDetail },
50 |
51 | { path: '/video' , component: VideoPlay },
52 |
53 | { path: '/album/:id' , component: AlbumDetail },
54 |
55 | { path: '/artist/:id' , component: ArtistDetail },
56 |
57 | { path: '/profile/:id' , component: Profile },
58 |
59 | { path: '/collects' , component: Collects },
60 |
61 | { path: '/mv' , component: Mv },
62 | ]
63 |
64 | const router = new VueRouter({
65 | routes,
66 | mode: 'hash'
67 | })
68 |
69 | export default router
70 |
--------------------------------------------------------------------------------
/src/components/content/covers/CommonVideoCover.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
{{ adapter.playCount(video) | logogram }}
6 |
{{ adapter.duration(video) | timeLongFormat(true) }}
7 |
8 |
9 |
{{ adapter.title(video) }}
10 |
11 |
15 | by {{ adapter.creatorName(video) }}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
45 |
46 |
81 |
--------------------------------------------------------------------------------
/src/views/pages/Mv.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 地区:
5 |
6 |
7 | 类型:
8 |
9 |
10 | 排序:
11 |
12 |
13 |
23 |
24 |
25 |
26 |
27 |
75 |
76 |
85 |
--------------------------------------------------------------------------------
/src/assets/css/element_ui_style_cover.css:
--------------------------------------------------------------------------------
1 | /* 用于覆盖Element UI组件的基本样式 */
2 |
3 |
4 | /*NavMenu Style*/
5 | .el-menu {
6 | border: none;
7 | }
8 |
9 | .el-submenu .el-submenu__title {
10 | height: 40px;
11 | color: #37474f;
12 | line-height: 40px;
13 | font-size: 12px;
14 | font-weight: bold;
15 |
16 | background-color: #fafafa;
17 | }
18 |
19 | .el-submenu.is-disabled {
20 | background-color: #fafafa;
21 | }
22 |
23 | .el-submenu .el-menu-item {
24 | height: 35px;
25 | line-height: 35px;
26 | font-size: 11px;
27 | }
28 |
29 | .el-submenu .el-menu-item[style] {
30 | padding: 0 10px !important;
31 | text-indent: 10px;
32 | }
33 |
34 | .el-submenu .el-menu-item.is-disabled,
35 | .el-submenu.is-disabled .el-submenu__title {
36 | cursor: default;
37 | }
38 |
39 |
40 | /*Tabs Style*/
41 |
42 | .el-tabs .el-tabs__item {
43 | font-size: 12px;
44 | }
45 |
46 | .el-tabs .el-tabs__nav-scroll,
47 | .el-tabs.align-left .el-tabs__nav-scroll{
48 | display: -webkit-box;
49 | display: -ms-flexbox;
50 | display: -webkit-flex;
51 | display: flex;
52 | }
53 |
54 | .el-tabs .el-tabs__nav-scroll {
55 | -webkit-box-pack: center;
56 | -ms-flex-pack: center;
57 | -webkit-justify-content: center;
58 | justify-content: center;
59 | }
60 |
61 | .el-tabs.align-left .el-tabs__nav-scroll {
62 | -webkit-box-pack: start;
63 | -ms-flex-pack: start;
64 | -webkit-justify-content: flex-start;
65 | justify-content: left;
66 | }
67 |
68 | .el-tabs.align-left .el-tabs__nav-wrap {
69 | padding-left: 40px ;
70 | }
71 |
72 |
73 | .el-tabs.small .el-tabs__item {
74 | padding: 0 10px;
75 | font-size: 10px;
76 | height: 35px;
77 | }
78 |
79 | .el-tabs.small .el-tabs__nav-wrap {
80 | padding-left: 20px ;
81 | }
82 |
83 | .el-tabs.small .el-tabs__nav-wrap::after {
84 | height: 1px;
85 | }
86 |
87 | /* Card Style */
88 |
89 | .el-card {
90 | border: none;
91 | }
92 |
93 |
94 | /* Slider */
95 |
96 | .el-slider .el-slider__bar, .el-slider .el-slider__runway {
97 | height: 4px;
98 | }
99 |
100 | .el-slider .el-slider__runway {
101 | background-clip: content-box;
102 | padding: 4px 0;
103 | }
104 |
105 | .el-slider .el-slider__button {
106 | height: 5px;
107 | width: 5px;
108 | }
109 |
110 | .el-slider .el-slider__button-wrapper {
111 | outline: none;
112 | transform: translate(-15px, 3px);
113 | }
114 |
115 | .el-slider .el-slider__runway {
116 | margin: 8px 0;
117 | }
118 |
--------------------------------------------------------------------------------
/src/components/content/complound/CommentArea.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
16 |
17 |
18 |
19 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
还没有任何评论,快来抢沙发吧~
35 |
36 |
37 |
38 |
39 |
49 |
50 |
51 |
52 |
53 |
90 |
91 |
102 |
--------------------------------------------------------------------------------
/src/utils/filter.js:
--------------------------------------------------------------------------------
1 |
2 | const Filter = {
3 |
4 | install: function(Vue) {
5 |
6 | //日期格式化(用法同C# "yyyy-MM-dd HH:mm:ss")
7 | Vue.filter("dateTimeFormat", function (date, fmt = 'yyyy-MM-dd HH:mm:ss') { //日期时间格式化
8 | if (!date) {
9 | return ''
10 | }
11 | if (typeof date === 'string') {
12 | date = date.replace('T', ' ').replace('Z', '');
13 | date = new Date(date.replace(/-/g, '/'))
14 | }
15 | if (typeof date === 'number') {
16 | date = new Date(date)
17 | }
18 | var o = {
19 | 'M+': date.getMonth() + 1,
20 | 'd+': date.getDate(),
21 | 'h+': date.getHours() % 12 === 0 ? 12 : date.getHours() % 12,
22 | 'H+': date.getHours(),
23 | 'm+': date.getMinutes(),
24 | 's+': date.getSeconds(),
25 | 'q+': Math.floor((date.getMonth() + 3) / 3),
26 | 'S': date.getMilliseconds()
27 | }
28 | var week = {
29 | '0': '\u65e5',
30 | '1': '\u4e00',
31 | '2': '\u4e8c',
32 | '3': '\u4e09',
33 | '4': '\u56db',
34 | '5': '\u4e94',
35 | '6': '\u516d'
36 | }
37 | if (/(y+)/.test(fmt)) {
38 | fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
39 | }
40 | if (/(E+)/.test(fmt)) {
41 | fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? '\u661f\u671f' : '\u5468') : '') + week[date.getDay() + ''])
42 | }
43 | for (var k in o) {
44 | if (new RegExp('(' + k + ')').test(fmt)) {
45 | fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
46 | }
47 | }
48 | return fmt
49 | });
50 |
51 | //秒、毫秒(时长)格式化为时分秒(例:65000ms => 00:01:05)
52 | Vue.filter('timeLongFormat', function (value, isMs=false,dft = '00:00') {
53 | let total = parseInt(value);
54 | if (!isNaN(total)) {
55 | if (isMs) {
56 | total = total/1000;
57 | }
58 | let hours = parseInt(total / 3600);
59 | let minutes = parseInt((total % 3600) / 60);
60 | let seconds = parseInt((total % 3600) % 60);
61 | let h = hours > 9 ? hours : '0' + hours;
62 | let m = minutes > 9 ? minutes : '0' + minutes;
63 | let s = seconds > 9 ? seconds : '0' + seconds;
64 | if (hours === 0) return m + ':' + s;
65 | return h + ':' + m + ':' + s;
66 | }
67 | else {
68 | return dft;
69 | }
70 | });
71 |
72 | Vue.filter('logogram', function (value) {
73 | if (value >= 10000) {
74 | return value = (value / 10000).toFixed(1) + '万'
75 | }
76 | return value
77 | })
78 | }
79 | }
80 |
81 | export default Filter
82 |
--------------------------------------------------------------------------------
/src/views/pages/ArtistDetail.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
88 |
89 |
94 |
--------------------------------------------------------------------------------
/src/components/content/clause/DetailedSongCaluse.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ adapter.index(song) }}
4 |
5 |
6 |
7 |
8 |
9 | {{ adapter.name(song) }}
10 | ({{ adapter.alia(song) }})
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | {{ adapter.duration(song) | timeLongFormat(true) }}
19 |
20 |
21 |
22 |
40 |
41 |
107 |
--------------------------------------------------------------------------------
/src/components/content/tracks/DetailSongTrack.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
14 |
15 |
16 |
76 |
77 |
86 |
--------------------------------------------------------------------------------
/src/components/content/complound/SongsListDetail.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
11 |
12 |
13 |
14 |
15 |
16 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
94 |
95 |
101 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 |
4 | import types from "./types";
5 | import { song_list_detail } from "@/network/request_show";
6 |
7 | Vue.use(Vuex)
8 |
9 | export default new Vuex.Store({
10 | state: {
11 | isLogin: false,
12 | profile: {
13 | name: null,
14 | UID: 0,
15 | avatarUrl: null,
16 | playlist: [],
17 | coll_playlist: [],
18 | liked_song: [],
19 | },
20 |
21 | player: {
22 | songsId: 0,
23 | current: 0,
24 | playing: false,
25 | playTracks: [],
26 | }
27 | },
28 |
29 | getters: {
30 | TrackLength: state => {
31 | return state.player.playTracks.length
32 | }
33 | },
34 |
35 | mutations: {
36 | [types.UPDATE_LOGIN_STATUS] ( state, { isLogin, profile } ) {
37 | state.isLogin = isLogin
38 | state.profile.name = profile['nickname']
39 | state.profile.UID = profile['userId']
40 | state.profile.avatarUrl = profile['avatarUrl']
41 | },
42 |
43 | [types.AUDIO_CHANGE] (state, { songsId, songsTracks, index } ) {
44 | state.player.playTracks = songsTracks
45 | state.player.current = index
46 | state.player.songsId = songsId
47 | },
48 |
49 | [types.AUDIO_INSERT] (state, { id }) {
50 | let current = state.player.current
51 | let index = state.player.playTracks.length !== 0? current + 1: 0
52 | state.player.playTracks.splice(index, 0, { id })
53 | state.player.current = index
54 | },
55 |
56 | [types.LIKE_LIST_ADD] (state, { id } ) {
57 | let likelist = state.profile.liked_song
58 | if (!likelist.includes(id))
59 | state.profile.liked_song.push(id)
60 | },
61 |
62 | [types.LIKE_LIST_DEL] (state, { id } ) {
63 | let likelist = state.profile.liked_song
64 | let index = likelist.indexOf(id)
65 | if (index > -1) {
66 | likelist.splice(index, 1)
67 | }
68 | },
69 |
70 | [types.AUDIO_PLAY] (state) { state.player.playing = true },
71 | [types.AUDIO_STOP] (state) { state.player.playing = false },
72 | [types.PLAYLIST] (state, { track }) { state.profile.playlist = track },
73 | [types.COLL_PLAYLIST] (state, { track }) { state.profile.coll_playlist = track },
74 | [types.LIKED_SONG] (state, { track }) { state.profile.liked_song = track }
75 | },
76 | actions: {
77 | [types.AUDIO_CHANGE] (content, { songsId, index }) {
78 | if (content.state.player.songsId !== songsId) {
79 | song_list_detail(songsId).then(result => {
80 | content.commit(
81 | types.AUDIO_CHANGE,
82 | { songsId, songsTracks: result['playlist']['trackIds'], index } )
83 | })
84 | } else {
85 | content.commit(
86 | types.AUDIO_CHANGE,
87 | { songsId, songsTracks: content.state.player.playTracks, index } )
88 | }
89 | }
90 | },
91 | modules: {
92 |
93 | }
94 | })
95 |
--------------------------------------------------------------------------------
/src/components/common/video/Slider.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
68 |
69 |
118 |
--------------------------------------------------------------------------------
/src/components/pages/topinfo/ProfileShow.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | {{ data['profile']['nickname'] }}
9 |
15 | Lv.{{ data['level'] }}
16 |
17 |
18 |
19 | {{ data['profile']['eventCount'] | logogram }}
20 | 动态
21 |
22 |
23 | {{ data['profile']['follows'] | logogram}}
24 | 关注
25 |
26 |
27 | {{ data['profile']['followeds'] | logogram}}
28 | 粉丝
29 |
30 |
31 |
32 |
33 |
个人介绍:{{ data['profile']['signature'] }}
34 |
35 |
36 |
37 |
38 |
39 |
49 |
50 |
129 |
--------------------------------------------------------------------------------
/src/views/pages/home/ArtistsCategory.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 语种:
4 | 分类:
5 | 筛选:
6 |
7 |
8 |
9 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
99 |
100 |
105 |
--------------------------------------------------------------------------------
/src/components/content/clause/CommentClause.vue:
--------------------------------------------------------------------------------
1 |
2 |
31 |
32 |
33 |
70 |
71 |
120 |
--------------------------------------------------------------------------------
/src/components/common/Pagination.vue:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
126 |
127 |
132 |
--------------------------------------------------------------------------------
/src/components/header/Search.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
80 |
81 |
149 |
--------------------------------------------------------------------------------