├── music-client
├── src
│ ├── assets
│ │ ├── css
│ │ │ ├── song-audio.scss
│ │ │ ├── search-songs.scss
│ │ │ ├── search-song-Lists.scss
│ │ │ ├── swiper.scss
│ │ │ ├── app.scss
│ │ │ ├── the-footer.scss
│ │ │ ├── 404.scss
│ │ │ ├── login-logo.scss
│ │ │ ├── upload.scss
│ │ │ ├── home.scss
│ │ │ ├── search.scss
│ │ │ ├── sign-up.scss
│ │ │ ├── login-in.scss
│ │ │ ├── index.scss
│ │ │ ├── global.scss
│ │ │ ├── song-list.scss
│ │ │ ├── singer.scss
│ │ │ ├── info.scss
│ │ │ ├── scroll-top.scss
│ │ │ ├── lyric.scss
│ │ │ ├── album-content.scss
│ │ │ ├── setting.scss
│ │ │ ├── singer-album.scss
│ │ │ ├── my-music.scss
│ │ │ ├── comment.scss
│ │ │ ├── content-list.scss
│ │ │ ├── the-aside.scss
│ │ │ ├── var.scss
│ │ │ ├── song-list-album.scss
│ │ │ ├── play-bar.scss
│ │ │ └── the-header.scss
│ │ ├── img
│ │ │ ├── user.jpg
│ │ │ ├── tubiao.jpg
│ │ │ └── swiper
│ │ │ │ ├── 1.jpg
│ │ │ │ ├── 2.jpg
│ │ │ │ ├── 3.jpg
│ │ │ │ ├── 4.jpg
│ │ │ │ ├── 5.jpg
│ │ │ │ ├── 6.jpg
│ │ │ │ ├── 7.jpg
│ │ │ │ └── 8.jpg
│ │ ├── data
│ │ │ ├── singer.js
│ │ │ ├── songList.js
│ │ │ ├── header.js
│ │ │ ├── swiper.js
│ │ │ └── form.js
│ │ └── js
│ │ │ ├── iconfont1.js
│ │ │ ├── iconfont2.js
│ │ │ └── iconfont3.js
│ ├── components
│ │ ├── TheFooter.vue
│ │ ├── LoginLogo.vue
│ │ ├── ScrollTop.vue
│ │ ├── search
│ │ │ ├── SearchSongs.vue
│ │ │ └── SearchSongLists.vue
│ │ ├── Swiper.vue
│ │ ├── ContentList.vue
│ │ ├── AlbumContent.vue
│ │ ├── Upload.vue
│ │ ├── SongAudio.vue
│ │ ├── TheHeader.vue
│ │ └── TheAside.vue
│ ├── store
│ │ ├── index.js
│ │ ├── user.js
│ │ └── configure.js
│ ├── main.js
│ ├── App.vue
│ ├── pages
│ │ ├── Search.vue
│ │ ├── Setting.vue
│ │ ├── Lyric.vue
│ │ ├── SingerAlbum.vue
│ │ ├── Singer.vue
│ │ ├── SongList.vue
│ │ └── MyMusic.vue
│ ├── api
│ │ ├── http.js
│ │ └── index.js
│ ├── router
│ │ └── index.js
│ └── mixins
│ │ └── index.js
├── test
│ ├── unit
│ │ ├── setup.js
│ │ ├── .eslintrc
│ │ ├── specs
│ │ │ └── HelloWorld.spec.js
│ │ └── jest.conf.js
│ └── e2e
│ │ ├── specs
│ │ └── test.js
│ │ ├── custom-assertions
│ │ └── elementCount.js
│ │ ├── nightwatch.conf.js
│ │ └── runner.js
├── dist
│ ├── static
│ │ ├── img
│ │ │ ├── 1.3976b58.jpg
│ │ │ ├── 2.1fac6a5.jpg
│ │ │ ├── 3.c629094.jpg
│ │ │ ├── 4.6085806.jpg
│ │ │ ├── 5.6a642ac.jpg
│ │ │ ├── 6.327b9c6.jpg
│ │ │ ├── 7.a81db1c.jpg
│ │ │ └── 8.76af304.jpg
│ │ ├── fonts
│ │ │ ├── element-icons.732389d.ttf
│ │ │ └── element-icons.535877f.woff
│ │ └── js
│ │ │ ├── manifest.2ae2e69a05c33dfc65f8.js
│ │ │ └── manifest.2ae2e69a05c33dfc65f8.js.map
│ └── index.html
├── .postcssrc.js
├── build
│ ├── vue-loader.conf.js
│ ├── build.js
│ ├── check-versions.js
│ ├── webpack.base.conf.js
│ ├── utils.js
│ └── webpack.dev.conf.js
└── .eslintrc.js
├── music-server
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── xusheng
│ │ │ │ └── music
│ │ │ │ ├── service
│ │ │ │ ├── AdminService.java
│ │ │ │ ├── RankService.java
│ │ │ │ ├── impl
│ │ │ │ │ ├── AdminServiceImpl.java
│ │ │ │ │ ├── RankServiceImpl.java
│ │ │ │ │ ├── CollectServiceImpl.java
│ │ │ │ │ ├── SingerServiceImpl.java
│ │ │ │ │ ├── CommentServiceImpl.java
│ │ │ │ │ ├── ConsumerServiceImpl.java
│ │ │ │ │ ├── ListSongServiceImpl.java
│ │ │ │ │ ├── SongServiceImpl.java
│ │ │ │ │ └── SongListServiceImpl.java
│ │ │ │ ├── SingerService.java
│ │ │ │ ├── CommentService.java
│ │ │ │ ├── ConsumerService.java
│ │ │ │ ├── CollectService.java
│ │ │ │ ├── ListSongService.java
│ │ │ │ ├── SongService.java
│ │ │ │ └── SongListService.java
│ │ │ │ ├── dao
│ │ │ │ ├── AdminMapper.java
│ │ │ │ ├── RankMapper.java
│ │ │ │ ├── SingerMapper.java
│ │ │ │ ├── ConsumerMapper.java
│ │ │ │ ├── CommentMapper.java
│ │ │ │ ├── ListSongMapper.java
│ │ │ │ ├── CollectMapper.java
│ │ │ │ ├── SongMapper.java
│ │ │ │ └── SongListMapper.java
│ │ │ │ ├── utils
│ │ │ │ └── Consts.java
│ │ │ │ ├── config
│ │ │ │ ├── WebMvcConfig.java
│ │ │ │ └── FileConfig.java
│ │ │ │ ├── domain
│ │ │ │ ├── Admin.java
│ │ │ │ ├── ListSong.java
│ │ │ │ ├── Rank.java
│ │ │ │ ├── SongList.java
│ │ │ │ ├── Collect.java
│ │ │ │ ├── Singer.java
│ │ │ │ ├── Comment.java
│ │ │ │ ├── Song.java
│ │ │ │ └── Consumer.java
│ │ │ │ └── controller
│ │ │ │ ├── RankController.java
│ │ │ │ └── ListSongController.java
│ │ └── resources
│ │ │ └── mapper
│ │ │ ├── AdminMapper.xml
│ │ │ ├── RankMapper.xml
│ │ │ ├── ListSongMapper.xml
│ │ │ ├── CollectMapper.xml
│ │ │ ├── SongListMapper.xml
│ │ │ ├── SingerMapper.xml
│ │ │ └── CommentMapper.xml
│ └── test
│ │ └── java
│ │ └── com
│ │ └── xusheng
│ │ └── music
│ │ └── MusicApplicationTests.java
└── pom.xml
└── README.md
/music-client/src/assets/css/song-audio.scss:
--------------------------------------------------------------------------------
1 | audio {
2 | display: none;
3 | }
4 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/search-songs.scss:
--------------------------------------------------------------------------------
1 | .search-songs {
2 | min-height: 300px;
3 | }
4 |
--------------------------------------------------------------------------------
/music-client/test/unit/setup.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | Vue.config.productionTip = false
4 |
--------------------------------------------------------------------------------
/music-client/test/unit/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "jest": true
4 | },
5 | "globals": {
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/music-client/src/assets/img/user.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/src/assets/img/user.jpg
--------------------------------------------------------------------------------
/music-client/src/assets/css/search-song-Lists.scss:
--------------------------------------------------------------------------------
1 |
2 | .search-song-Lists {
3 | min-height: 300px;
4 | margin-top: 50px;
5 | }
6 |
--------------------------------------------------------------------------------
/music-client/src/assets/img/tubiao.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/src/assets/img/tubiao.jpg
--------------------------------------------------------------------------------
/music-client/src/assets/img/swiper/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/src/assets/img/swiper/1.jpg
--------------------------------------------------------------------------------
/music-client/src/assets/img/swiper/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/src/assets/img/swiper/2.jpg
--------------------------------------------------------------------------------
/music-client/src/assets/img/swiper/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/src/assets/img/swiper/3.jpg
--------------------------------------------------------------------------------
/music-client/src/assets/img/swiper/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/src/assets/img/swiper/4.jpg
--------------------------------------------------------------------------------
/music-client/src/assets/img/swiper/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/src/assets/img/swiper/5.jpg
--------------------------------------------------------------------------------
/music-client/src/assets/img/swiper/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/src/assets/img/swiper/6.jpg
--------------------------------------------------------------------------------
/music-client/src/assets/img/swiper/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/src/assets/img/swiper/7.jpg
--------------------------------------------------------------------------------
/music-client/src/assets/img/swiper/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/src/assets/img/swiper/8.jpg
--------------------------------------------------------------------------------
/music-client/dist/static/img/1.3976b58.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/dist/static/img/1.3976b58.jpg
--------------------------------------------------------------------------------
/music-client/dist/static/img/2.1fac6a5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/dist/static/img/2.1fac6a5.jpg
--------------------------------------------------------------------------------
/music-client/dist/static/img/3.c629094.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/dist/static/img/3.c629094.jpg
--------------------------------------------------------------------------------
/music-client/dist/static/img/4.6085806.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/dist/static/img/4.6085806.jpg
--------------------------------------------------------------------------------
/music-client/dist/static/img/5.6a642ac.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/dist/static/img/5.6a642ac.jpg
--------------------------------------------------------------------------------
/music-client/dist/static/img/6.327b9c6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/dist/static/img/6.327b9c6.jpg
--------------------------------------------------------------------------------
/music-client/dist/static/img/7.a81db1c.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/dist/static/img/7.a81db1c.jpg
--------------------------------------------------------------------------------
/music-client/dist/static/img/8.76af304.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/dist/static/img/8.76af304.jpg
--------------------------------------------------------------------------------
/music-client/dist/static/fonts/element-icons.732389d.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/dist/static/fonts/element-icons.732389d.ttf
--------------------------------------------------------------------------------
/music-client/dist/static/fonts/element-icons.535877f.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KakarottoCui/VueMusicSys/HEAD/music-client/dist/static/fonts/element-icons.535877f.woff
--------------------------------------------------------------------------------
/music-client/src/assets/css/swiper.scss:
--------------------------------------------------------------------------------
1 | .swiper {
2 | width: 90%;
3 | margin: auto;
4 | margin-top: 40px;
5 |
6 | img {
7 | width: 100%;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/music-client/src/assets/data/singer.js:
--------------------------------------------------------------------------------
1 | const singerStyle = [
2 | {name: '全部歌手', type: '-1'},
3 | {name: '男歌手', type: '1'},
4 | {name: '女歌手', type: '0'},
5 | {name: '组合歌手', type: '2'}
6 | ]
7 |
8 | export {singerStyle}
9 |
--------------------------------------------------------------------------------
/music-client/src/assets/data/songList.js:
--------------------------------------------------------------------------------
1 | const songStyle = [
2 | {name: '全部歌单'},
3 | {name: '华语'},
4 | {name: '粤语'},
5 | {name: '欧美'},
6 | {name: '日韩'},
7 | {name: '轻音乐'},
8 | {name: 'BGM'},
9 | {name: '乐器'}
10 | ]
11 | export {songStyle}
12 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/app.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 | @import "global.scss";
3 |
4 | #app {
5 | background-color: $theme-background-color;
6 | @include layout(flex-start, stretch, column);
7 | }
8 |
9 | .music-content {
10 | flex: 1;
11 | }
12 |
--------------------------------------------------------------------------------
/music-client/.postcssrc.js:
--------------------------------------------------------------------------------
1 | // https://github.com/michael-ciniawsky/postcss-load-config
2 |
3 | module.exports = {
4 | "plugins": {
5 | "postcss-import": {},
6 | "postcss-url": {},
7 | // to edit target browsers: use "browserslist" field in package.json
8 | "autoprefixer": {}
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/the-footer.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 | @import "global.scss";
3 |
4 | .the-footer {
5 | width: 100%;
6 | height: $footer-height;
7 | background-color: $theme-footer-color;
8 | @include layout(center, center, column);
9 |
10 | p {
11 | height: 30px;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/service/AdminService.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.service;
2 |
3 | /**
4 | * 管理员service接口
5 | */
6 | public interface AdminService {
7 |
8 | /**
9 | * 验证密码是否正确
10 | */
11 | public boolean verifyPassword(String username, String password);
12 | }
13 |
--------------------------------------------------------------------------------
/music-server/src/test/java/com/xusheng/music/MusicApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class MusicApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/404.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 | @import "global.scss";
3 |
4 | .error-page {
5 | @include layout(center);
6 | width: 100%;
7 | height: 100%;
8 | padding: 11rem 0;
9 | box-sizing: border-box;
10 |
11 | .error-code {
12 | font-size: 250px;
13 | font-weight: bolder;
14 | color: $theme-color;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/music-client/src/components/TheFooter.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
15 |
--------------------------------------------------------------------------------
/music-client/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import configure from './configure'
4 | import user from './user'
5 | import song from './song'
6 |
7 | Vue.use(Vuex)
8 |
9 | const store = new Vuex.Store({
10 | modules: {
11 | configure,
12 | user,
13 | song
14 | }
15 | })
16 |
17 | export default store
18 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/dao/AdminMapper.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.dao;
2 |
3 | import org.springframework.stereotype.Repository;
4 |
5 | /**
6 | * 管理员Dao
7 | */
8 | @Repository
9 | public interface AdminMapper {
10 | /**
11 | * 验证密码是否正确
12 | */
13 | public int verifyPassword(String username, String password);
14 | }
15 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/utils/Consts.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.utils;
2 |
3 | /**
4 | * 常量
5 | */
6 | public class Consts {
7 | /*登录名*/
8 | public static final String NAME = "name";
9 | /*返回码*/
10 | public static final String CODE = "code";
11 | /*返回信息*/
12 | public static final String MSG = "msg";
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/music-client/src/components/LoginLogo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/login-logo.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 | @import "global.scss";
3 |
4 | .login-logo {
5 | background-color: $color-blue-light;
6 | height: 100vh;
7 | width: 50vw;
8 | min-width: 650px;
9 | overflow: hidden;
10 | @include layout(center, center);
11 |
12 | .icon {
13 | @include icon(6.5em, $color-blue-dark);
14 | transform: rotate(-30deg);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/music-client/test/unit/specs/HelloWorld.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import HelloWorld from '@/components/HelloWorld'
3 |
4 | describe('HelloWorld.vue', () => {
5 | it('should render correct contents', () => {
6 | const Constructor = Vue.extend(HelloWorld)
7 | const vm = new Constructor().$mount()
8 | expect(vm.$el.querySelector('.hello h1').textContent)
9 | .toEqual('Welcome to Your Vue.js App')
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/upload.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 | @import "global.scss";
3 |
4 | .upload {
5 | width: 100%;
6 |
7 | .title {
8 | height: 50px;
9 | line-height: 50px;
10 | padding-left: 20px;
11 | font-size: 20px;
12 | font-weight: 600;
13 | color: $color-black;
14 | }
15 |
16 | hr {
17 | width: 98%;
18 | }
19 |
20 | .section {
21 | height: 400px;
22 | @include layout(center, center);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # VueMusicSys
2 | 基于Springboot和Vue的在线音乐平台
3 |
4 | 演示视频连接:https://www.bilibili.com/video/BV1pY4y1b7x3/
5 |
6 | 实现的功能
7 |
8 | 音乐播放、用户登录注册、用户信息编辑、头像修改 歌曲、歌单搜索、歌单打分、歌单、歌曲评论、歌单列表、歌手列表分页显示、歌词同步显示、音乐收藏、下载、拖动控制、音量控制 后台对用户、歌曲、歌手、歌单信息的管理等
9 |
10 | 用到的技术
11 |
12 | 服务端使用 JAVA语言 Spring Boot + MyBatis 来实现,数据库使用了 MySQL。
13 |
14 | 前端 Vue + Vue-Router + Vuex + Axios + ElementUI git
15 |
16 | 详询 微信1:egvh56ufy7hh ,微信2:dabocode 。承接商业项目、课设、毕设和论文,包括但不限于Web、APP、小程序等,课设、毕设提供远程部署和不限次数代码解答!
17 |
--------------------------------------------------------------------------------
/music-client/src/components/ScrollTop.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
16 |
17 |
--------------------------------------------------------------------------------
/music-client/dist/index.html:
--------------------------------------------------------------------------------
1 |
音乐
--------------------------------------------------------------------------------
/music-client/src/assets/data/header.js:
--------------------------------------------------------------------------------
1 | //左侧导航栏
2 | const navMsg = [
3 | {name: '首页', path: '/'},
4 | {name: '歌单', path: '/song-list'},
5 | {name: '歌手', path: '/singer'},
6 | {name: '我的音乐', path: '/my-music'}
7 | ]
8 |
9 | //右侧导航栏
10 | const loginMsg = [
11 | {name: '登录', path: '/login-in'},
12 | {name: '注册', path: '/sign-up'}
13 | ]
14 |
15 | //用户下拉菜单
16 | const menuList = [
17 | {name: '设置', path: '/setting'},
18 | {name: '退出', path: 0}
19 | ]
20 |
21 |
22 | export {
23 | navMsg,
24 | loginMsg,
25 | menuList
26 | }
27 |
--------------------------------------------------------------------------------
/music-client/src/assets/data/swiper.js:
--------------------------------------------------------------------------------
1 | //轮播图的数据
2 | const swiperList = [
3 | {picImg: require('@/assets/img/swiper/1.jpg')},
4 | {picImg: require('@/assets/img/swiper/2.jpg')},
5 | {picImg: require('@/assets/img/swiper/3.jpg')},
6 | {picImg: require('@/assets/img/swiper/4.jpg')},
7 | {picImg: require('@/assets/img/swiper/5.jpg')},
8 | {picImg: require('@/assets/img/swiper/6.jpg')},
9 | {picImg: require('@/assets/img/swiper/7.jpg')},
10 | {picImg: require('@/assets/img/swiper/8.jpg')}
11 | ]
12 |
13 | export {
14 | swiperList
15 | }
16 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/home.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 |
3 | .home {
4 | margin-top: $header-height - 10px;
5 |
6 | .section {
7 | width: 100%;
8 | margin-top: 20px;
9 | padding: $content-padding;
10 | background-color: $color-white;
11 | box-sizing: border-box;
12 |
13 | .section-title {
14 | height: 60px;
15 | line-height: 60px;
16 | padding-top: 10px;
17 | font-size: 28px;
18 | font-weight: 500;
19 | text-align: center;
20 | color: $color-black;
21 | box-sizing: border-box;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/search.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 | @import "global.scss";
3 |
4 | .search {
5 | margin: auto;
6 | margin-top: $header-height + 20px;
7 | background-color: $color-white;
8 | border-radius: 12px;
9 | width: 900px;
10 | position: relative;
11 | }
12 |
13 | .searchList-nav {
14 | @include layout(space-around);
15 | margin-top: 20px;
16 | font-size: 1.5rem;
17 | color: $color-black;
18 |
19 | span {
20 | line-height: 50px;
21 | cursor: pointer;
22 | }
23 | }
24 |
25 | .isActive {
26 | font-weight: 600;
27 | border-bottom: 5px solid $color-black;
28 | }
29 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/sign-up.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 | @import "global.scss";
3 |
4 | .signUp {
5 | position: absolute;
6 | top: $header-height + 20px;
7 | background-color: $color-white;
8 | border-radius: 10px;
9 | width: 350px;
10 | margin-left: 900px;
11 | padding: 30px 30px;
12 |
13 | .signUp-head {
14 | text-align: center;
15 | margin-bottom: 10px;
16 | font-size: 20px;
17 | font-weight: 600;
18 | }
19 |
20 | .login-btn {
21 | @include layout(space-between);
22 |
23 | button {
24 | display: block;
25 | width: 50%;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/service/RankService.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.service;
2 |
3 | import com.xusheng.music.domain.Rank;
4 |
5 | /**
6 | * 评价service接口
7 | */
8 | public interface RankService {
9 | /**
10 | * 增加
11 | */
12 | public boolean insert(Rank rank);
13 |
14 | /**
15 | * 查总分
16 | */
17 | public int selectScoreSum(Integer songListId);
18 |
19 | /**
20 | * 查总评分人数
21 | */
22 | public int selectRankNum(Integer songListId);
23 |
24 | /**
25 | * 计算平均分
26 | */
27 | public int rankOfSongListId(Integer songListId);
28 | }
29 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/login-in.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 | @import "global.scss";
3 |
4 | .login {
5 | position: absolute;
6 | margin-left: 850px;
7 | width: 300px;
8 | height: 210px;
9 | top: $header-height + 60px;
10 | padding: 30px 50px;
11 | border-radius: 10px;
12 | background-color: $color-white;
13 |
14 | .login-head {
15 | text-align: center;
16 | margin-bottom: 10px;
17 | font-size: 20px;
18 | font-weight: 600;
19 | }
20 |
21 | .login-btn {
22 | @include layout(space-between);
23 |
24 | button {
25 | display: block;
26 | width: 50%;
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/music-client/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App'
3 | import router from './router'
4 | import store from './store/index'
5 | import './assets/css/index.scss'
6 | import ElementUI from 'element-ui'
7 | import 'element-ui/lib/theme-chalk/index.css'
8 | import '@/assets/js/iconfont.js'
9 | import '@/assets/js/iconfont1.js'
10 | import '@/assets/js/iconfont2.js'
11 | import '@/assets/js/iconfont3.js'
12 |
13 | Vue.use(ElementUI)
14 |
15 | Vue.config.productionTip = false
16 |
17 | /* eslint-disable no-new */
18 | new Vue({
19 | el: '#app',
20 | router,
21 | store,
22 | components: {App},
23 | template: ''
24 | })
25 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/dao/RankMapper.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.dao;
2 |
3 | import com.xusheng.music.domain.Rank;
4 | import org.springframework.stereotype.Repository;
5 |
6 | /**
7 | * 评价Dao
8 | */
9 | @Repository
10 | public interface RankMapper {
11 | /**
12 | * 增加
13 | */
14 | public int insert(Rank rank);
15 |
16 | /**
17 | * 查总分
18 | */
19 | public int selectScoreSum(Integer songListId);
20 |
21 | /**
22 | * 查总评分人数
23 | */
24 | public int selectRankNum(Integer songListId);
25 | }
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/music-client/test/e2e/specs/test.js:
--------------------------------------------------------------------------------
1 | // For authoring Nightwatch tests, see
2 | // http://nightwatchjs.org/guide#usage
3 |
4 | module.exports = {
5 | 'default e2e tests': function (browser) {
6 | // automatically uses dev Server port from /config.index.js
7 | // default: http://localhost:8080
8 | // see nightwatch.conf.js
9 | const devServer = browser.globals.devServerURL
10 |
11 | browser
12 | .url(devServer)
13 | .waitForElementVisible('#app', 5000)
14 | .assert.elementPresent('.hello')
15 | .assert.containsText('h1', 'Welcome to Your Vue.js App')
16 | .assert.elementCount('img', 1)
17 | .end()
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/music-client/build/vue-loader.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const config = require('../config')
4 | const isProduction = process.env.NODE_ENV === 'production'
5 | const sourceMapEnabled = isProduction
6 | ? config.build.productionSourceMap
7 | : config.dev.cssSourceMap
8 |
9 | module.exports = {
10 | loaders: utils.cssLoaders({
11 | sourceMap: sourceMapEnabled,
12 | extract: isProduction
13 | }),
14 | cssSourceMap: sourceMapEnabled,
15 | cacheBusting: config.dev.cacheBusting,
16 | transformToRequire: {
17 | video: ['src', 'poster'],
18 | source: 'src',
19 | img: 'src',
20 | image: 'xlink:href'
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/config/WebMvcConfig.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.config;
2 |
3 | import org.springframework.context.annotation.Configuration;
4 | import org.springframework.web.servlet.config.annotation.CorsRegistry;
5 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
6 |
7 | /**
8 | * 解决跨域问题
9 | */
10 | @Configuration
11 | public class WebMvcConfig extends WebMvcConfigurerAdapter {
12 |
13 | @Override
14 | public void addCorsMappings(CorsRegistry registry) {
15 | registry.addMapping("/**")
16 | .allowedOrigins("*")
17 | .allowedMethods("*")
18 | .allowCredentials(true);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/music-client/src/components/search/SearchSongs.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
27 |
28 |
--------------------------------------------------------------------------------
/music-client/src/components/Swiper.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
25 |
26 |
--------------------------------------------------------------------------------
/music-server/src/main/resources/mapper/AdminMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/index.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 |
3 | * {
4 | padding: 0;
5 | margin: 0;
6 | }
7 |
8 | ul,
9 | li {
10 | list-style: none;
11 | display: inline-block;
12 | }
13 |
14 | html {
15 | min-width: 1200px;
16 | font-size: 14px;
17 | }
18 |
19 | div {
20 | box-sizing: content-box;
21 | }
22 |
23 | /*表单*/
24 | .el-select-dropdown__item {
25 | display: block !important;
26 | }
27 |
28 | /*轮播图*/
29 | .el-scrollbar__view,
30 | .el-select-dropdown__list {
31 | width: 100% !important;
32 | text-align: center;
33 | }
34 |
35 | .el-carousel__indicators,
36 | .el-carousel__indicators--outside {
37 | display: inline-block;
38 | margin-left: 500px !important;
39 | }
40 |
41 | .el-slider__runway {
42 | background-color: $color-blue !important;
43 | }
44 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/global.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 |
3 | // 上下左右居中
4 | @mixin layout(
5 | $justify-content: flex-start,
6 | $align-items: stretch,
7 | $flex-direction: row,
8 | $flex-wrap: nowrap
9 | ) {
10 | display: flex;
11 | justify-content: $justify-content;
12 | align-items: $align-items;
13 | flex-direction: $flex-direction;
14 | flex-wrap: $flex-wrap;
15 | }
16 |
17 | // 图标
18 | @mixin icon($size: 1.5em, $color: $color-black) {
19 | width: $size;
20 | height: $size;
21 | font-size: $size;
22 | color: $color;
23 | fill: currentColor;
24 | overflow: hidden;
25 | position: relative;
26 | }
27 |
28 | @mixin box-shadow($box-shadow) {
29 | -webkit-box-shadow: $box-shadow;
30 | -moz-box-shadow: $box-shadow;
31 | box-shadow: $box-shadow;
32 | }
33 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/song-list.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 | @import "global.scss";
3 |
4 | .song-list {
5 | margin: 30px 150px;
6 | margin-top: $header-height + 20px;
7 | padding-bottom: 50px;
8 | min-width: 800px;
9 | background-color: $color-white;
10 | }
11 |
12 | .song-list-header {
13 | width: 100%;
14 | padding: 0 40px;
15 |
16 | li {
17 | display: inline-block;
18 | line-height: 40px;
19 | margin: 40px 20px 15px 20px;
20 | font-size: 20px;
21 | font-weight: 400;
22 | color: $color-grey;
23 | border-bottom: none;
24 | cursor: pointer;
25 | }
26 |
27 | li.active {
28 | color: $color-black;
29 | font-weight: 600;
30 | border-bottom: 4px solid $color-black;
31 | }
32 | }
33 |
34 | .pagination {
35 | @include layout;
36 | }
37 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/service/impl/AdminServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.service.impl;
2 |
3 | import com.xusheng.music.dao.AdminMapper;
4 | import com.xusheng.music.service.AdminService;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Service;
7 |
8 | /**
9 | * 管理员service实现类
10 | */
11 | @Service
12 | public class AdminServiceImpl implements AdminService {
13 |
14 | @Autowired
15 | private AdminMapper adminMapper;
16 |
17 | /**
18 | * 验证密码是否正确
19 | *
20 | * @param username
21 | * @param password
22 | */
23 | @Override
24 | public boolean verifyPassword(String username, String password) {
25 | return adminMapper.verifyPassword(username, password) > 0;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/domain/Admin.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.domain;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * 管理员
7 | */
8 | public class Admin implements Serializable {
9 | /*主键*/
10 | private Integer id;
11 | /*账号*/
12 | private String name;
13 | /*密码*/
14 | private String password;
15 |
16 | public Integer getId() {
17 | return id;
18 | }
19 |
20 | public void setId(Integer id) {
21 | this.id = id;
22 | }
23 |
24 | public String getName() {
25 | return name;
26 | }
27 |
28 | public void setName(String name) {
29 | this.name = name;
30 | }
31 |
32 | public String getPassword() {
33 | return password;
34 | }
35 |
36 | public void setPassword(String password) {
37 | this.password = password;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/singer.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 | @import "global.scss";
3 |
4 | div,
5 | ul,
6 | li {
7 | box-sizing: border-box;
8 | }
9 |
10 | .singer {
11 | margin: 30px 10%;
12 | margin-top: $header-height + 20px;
13 | padding-bottom: 50px;
14 | background-color: $color-white;
15 |
16 | .singer-header {
17 | width: 100%;
18 | padding: 0 40px;
19 |
20 | li {
21 | display: inline-block;
22 | line-height: 40px;
23 | margin: 40px 20px 15px 20px;
24 | font-size: 20px;
25 | font-weight: 400;
26 | color: $color-grey;
27 | border-bottom: none;
28 | cursor: pointer;
29 | }
30 |
31 | li.active {
32 | color: $color-black;
33 | font-weight: 600;
34 | border-bottom: 4px solid $color-black;
35 | }
36 | }
37 | }
38 |
39 | .pagination {
40 | @include layout;
41 | }
42 |
--------------------------------------------------------------------------------
/music-client/test/unit/jest.conf.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 |
3 | module.exports = {
4 | rootDir: path.resolve(__dirname, '../../'),
5 | moduleFileExtensions: [
6 | 'js',
7 | 'json',
8 | 'vue'
9 | ],
10 | moduleNameMapper: {
11 | '^@/(.*)$': '/src/$1'
12 | },
13 | transform: {
14 | '^.+\\.js$': '/node_modules/babel-jest',
15 | '.*\\.(vue)$': '/node_modules/vue-jest'
16 | },
17 | testPathIgnorePatterns: [
18 | '/test/e2e'
19 | ],
20 | snapshotSerializers: ['/node_modules/jest-serializer-vue'],
21 | setupFiles: ['/test/unit/setup'],
22 | mapCoverage: true,
23 | coverageDirectory: '/test/unit/coverage',
24 | collectCoverageFrom: [
25 | 'src/**/*.{js,vue}',
26 | '!src/main.js',
27 | '!src/router/index.js',
28 | '!**/node_modules/**'
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/music-client/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
33 |
34 |
37 |
--------------------------------------------------------------------------------
/music-client/dist/static/js/manifest.2ae2e69a05c33dfc65f8.js:
--------------------------------------------------------------------------------
1 | !function(r){var n=window.webpackJsonp;window.webpackJsonp=function(e,u,c){for(var f,i,p,a=0,l=[];a has count: ' + count
12 | this.expected = count
13 | this.pass = function (val) {
14 | return val === this.expected
15 | }
16 | this.value = function (res) {
17 | return res.value
18 | }
19 | this.command = function (cb) {
20 | var self = this
21 | return this.api.execute(function (selector) {
22 | return document.querySelectorAll(selector).length
23 | }, [selector], function (res) {
24 | cb.call(self, res)
25 | })
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/music-client/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // https://eslint.org/docs/user-guide/configuring
2 |
3 | module.exports = {
4 | root: true,
5 | parserOptions: {
6 | parser: 'babel-eslint'
7 | },
8 | env: {
9 | browser: true,
10 | },
11 | extends: [
12 | // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
13 | // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
14 | 'plugin:vue/essential',
15 | // https://github.com/standard/standard/blob/master/docs/RULES-en.md
16 | 'standard'
17 | ],
18 | // required to lint *.vue files
19 | plugins: [
20 | 'vue'
21 | ],
22 | // add your custom rules here
23 | rules: {
24 | // allow async-await
25 | 'generator-star-spacing': 'off',
26 | // allow debugger during development
27 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/service/SingerService.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.service;
2 |
3 | import com.xusheng.music.domain.Singer;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * 歌手service接口
9 | */
10 | public interface SingerService {
11 | /**
12 | * 增加
13 | */
14 | public boolean insert(Singer singer);
15 |
16 | /**
17 | * 修改
18 | */
19 | public boolean update(Singer singer);
20 |
21 | /**
22 | * 删除
23 | */
24 | public boolean delete(Integer id);
25 |
26 | /**
27 | * 根据主键查询整个对象
28 | */
29 | public Singer selectByPrimaryKey(Integer id);
30 |
31 | /**
32 | * 查询所有歌手
33 | */
34 | public List allSinger();
35 |
36 | /**
37 | * 根据歌手名字模糊查询列表
38 | */
39 | public List singerOfName(String name);
40 |
41 | /**
42 | * 根据性别查询
43 | */
44 | public List singerOfSex(Integer sex);
45 | }
46 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/service/CommentService.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.service;
2 |
3 | import com.xusheng.music.domain.Comment;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * 评论service接口
9 | */
10 | public interface CommentService {
11 | /**
12 | * 增加
13 | */
14 | public boolean insert(Comment comment);
15 |
16 | /**
17 | * 修改
18 | */
19 | public boolean update(Comment comment);
20 |
21 | /**
22 | * 删除
23 | */
24 | public boolean delete(Integer id);
25 |
26 | /**
27 | * 根据主键查询整个对象
28 | */
29 | public Comment selectByPrimaryKey(Integer id);
30 |
31 | /**
32 | * 查询所有评论
33 | */
34 | public List allComment();
35 |
36 | /**
37 | * 查询某个歌曲下的所有评论
38 | */
39 | public List commentOfSongId(Integer songId);
40 |
41 | /**
42 | * 查询某个歌单下的所有评论
43 | */
44 | public List commentOfSongListId(Integer songListId);
45 | }
46 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/service/ConsumerService.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.service;
2 |
3 | import com.xusheng.music.domain.Consumer;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * 前端用户service接口
9 | */
10 | public interface ConsumerService {
11 | /**
12 | * 增加
13 | */
14 | public boolean insert(Consumer consumer);
15 |
16 | /**
17 | * 修改
18 | */
19 | public boolean update(Consumer consumer);
20 |
21 | /**
22 | * 删除
23 | */
24 | public boolean delete(Integer id);
25 |
26 | /**
27 | * 根据主键查询整个对象
28 | */
29 | public Consumer selectByPrimaryKey(Integer id);
30 |
31 | /**
32 | * 查询所有用户
33 | */
34 | public List allConsumer();
35 |
36 | /**
37 | * 查看密码是否正确
38 | */
39 | public boolean verifyPassword(String username, String password);
40 |
41 | /**
42 | * 根据账号查询
43 | */
44 | public Consumer getByUsername(String username);
45 | }
46 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/service/CollectService.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.service;
2 |
3 | import com.xusheng.music.domain.Collect;
4 | import org.apache.ibatis.annotations.Param;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * 收藏service接口
10 | */
11 | public interface CollectService {
12 | /**
13 | * 增加
14 | */
15 | public boolean insert(Collect collect);
16 |
17 | /**
18 | * 删除
19 | */
20 | public boolean delete(Integer id);
21 |
22 | /**
23 | * 根据用户id和歌曲id删除
24 | */
25 | public boolean deleteByUserIdSongId(Integer userId, Integer songId);
26 |
27 | /**
28 | * 查询所有收藏
29 | */
30 | public List allCollect();
31 |
32 | /**
33 | * 查询某个用户的收藏列表
34 | */
35 | public List collectOfUserId(Integer userId);
36 |
37 | /**
38 | * 查询某个用户是否已经收藏了某个歌曲
39 | */
40 | public boolean existSongId(@Param("userId") Integer userId, @Param("songId") Integer songId);
41 | }
42 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/scroll-top.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 | @import "global.scss";
3 |
4 | .scroll-top {
5 | position: fixed;
6 | width: 50px;
7 | height: 30px;
8 | right: 10px;
9 | bottom: 80px;
10 | padding-top: 20px;
11 | text-align: center;
12 | background-color: $color-white;
13 | border-radius: 20%;
14 | overflow: hidden;
15 | @include box-shadow(0 0 4px 3px rgba(0, 0, 0, 0.2));
16 |
17 | &:hover:before {
18 | top: 50%;
19 | }
20 |
21 | &:hover .box-in {
22 | visibility: hidden;
23 | }
24 |
25 | &:before {
26 | content: "回到顶部";
27 | position: absolute;
28 | font-weight: bold;
29 | width: 30px;
30 | top: -50%;
31 | left: 50%;
32 | transform: translate(-50%, -50%);
33 | }
34 | }
35 |
36 | .box-in {
37 | visibility: visible;
38 | display: inline-block;
39 | height: 15px;
40 | width: 15px;
41 | border: 1px solid $color-black;
42 | border-color: $color-black transparent transparent $color-black;
43 | transform: rotate(45deg);
44 | }
45 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/service/ListSongService.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.service;
2 |
3 | import com.xusheng.music.domain.ListSong;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * 歌单里面的歌曲service接口
9 | */
10 | public interface ListSongService {
11 | /**
12 | * 增加
13 | */
14 | public boolean insert(ListSong listSong);
15 |
16 | /**
17 | * 修改
18 | */
19 | public boolean update(ListSong listSong);
20 |
21 | /**
22 | * 删除
23 | */
24 | public boolean delete(Integer id);
25 |
26 | /**
27 | * 根据歌曲id和歌单id删除
28 | */
29 | public boolean deleteBySongIdAndSongListId(Integer songId, Integer songListId);
30 |
31 | /**
32 | * 根据主键查询整个对象
33 | */
34 | public ListSong selectByPrimaryKey(Integer id);
35 |
36 | /**
37 | * 查询所有歌单里面的歌曲
38 | */
39 | public List allListSong();
40 |
41 | /**
42 | * 根据歌单id查询所有的歌曲
43 | */
44 | public List listSongOfSongListId(Integer songListId);
45 | }
46 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/service/SongService.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.service;
2 |
3 | import com.xusheng.music.domain.Song;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * 歌曲service接口
9 | */
10 | public interface SongService {
11 | /**
12 | * 增加
13 | */
14 | public boolean insert(Song song);
15 |
16 | /**
17 | * 修改
18 | */
19 | public boolean update(Song song);
20 |
21 | /**
22 | * 删除
23 | */
24 | public boolean delete(Integer id);
25 |
26 | /**
27 | * 根据主键查询整个对象
28 | */
29 | public Song selectByPrimaryKey(Integer id);
30 |
31 | /**
32 | * 查询所有歌曲
33 | */
34 | public List allSong();
35 |
36 | /**
37 | * 根据歌名精确查询列表
38 | */
39 | public List songOfName(String name);
40 |
41 | /**
42 | * 根据歌名模糊查询列表
43 | */
44 | public List likeSongOfName(String name);
45 |
46 | /**
47 | * 根据歌手id查询
48 | */
49 | public List songOfSingerId(Integer singerId);
50 | }
51 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/dao/SingerMapper.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.dao;
2 |
3 | import com.xusheng.music.domain.Singer;
4 | import org.springframework.stereotype.Repository;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * 歌手Dao
10 | */
11 | @Repository
12 | public interface SingerMapper {
13 | /**
14 | * 增加
15 | */
16 | public int insert(Singer singer);
17 |
18 | /**
19 | * 修改
20 | */
21 | public int update(Singer singer);
22 |
23 | /**
24 | * 删除
25 | */
26 | public int delete(Integer id);
27 |
28 | /**
29 | * 根据主键查询整个对象
30 | */
31 | public Singer selectByPrimaryKey(Integer id);
32 |
33 | /**
34 | * 查询所有歌手
35 | */
36 | public List allSinger();
37 |
38 | /**
39 | * 根据歌手名字模糊查询列表
40 | */
41 | public List singerOfName(String name);
42 |
43 | /**
44 | * 根据性别查询
45 | */
46 | public List singerOfSex(Integer sex);
47 | }
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/service/SongListService.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.service;
2 |
3 | import com.xusheng.music.domain.SongList;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * 歌单service接口
9 | */
10 | public interface SongListService {
11 | /**
12 | * 增加
13 | */
14 | public boolean insert(SongList songList);
15 |
16 | /**
17 | * 修改
18 | */
19 | public boolean update(SongList songList);
20 |
21 | /**
22 | * 删除
23 | */
24 | public boolean delete(Integer id);
25 |
26 | /**
27 | * 根据主键查询整个对象
28 | */
29 | public SongList selectByPrimaryKey(Integer id);
30 |
31 | /**
32 | * 查询所有歌单
33 | */
34 | public List allSongList();
35 |
36 | /**
37 | * 根据标题精确查询歌单列表
38 | */
39 | public List songListOfTitle(String title);
40 |
41 | /**
42 | * 根据标题模糊查询歌单列表
43 | */
44 | public List likeTitle(String title);
45 |
46 | /**
47 | * 根据风格模糊查询歌单列表
48 | */
49 | public List likeStyle(String style);
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/dao/ConsumerMapper.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.dao;
2 |
3 | import com.xusheng.music.domain.Consumer;
4 | import org.springframework.stereotype.Repository;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * 前端用户Dao
10 | */
11 | @Repository
12 | public interface ConsumerMapper {
13 | /**
14 | * 增加
15 | */
16 | public int insert(Consumer consumer);
17 |
18 | /**
19 | * 修改
20 | */
21 | public int update(Consumer consumer);
22 |
23 | /**
24 | * 删除
25 | */
26 | public int delete(Integer id);
27 |
28 | /**
29 | * 根据主键查询整个对象
30 | */
31 | public Consumer selectByPrimaryKey(Integer id);
32 |
33 | /**
34 | * 查询所有用户
35 | */
36 | public List allConsumer();
37 |
38 | /**
39 | * 验证密码
40 | */
41 | public int verifyPassword(String username, String password);
42 |
43 | /**
44 | * 根据账号查询
45 | */
46 | public Consumer getByUsername(String username);
47 | }
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/dao/CommentMapper.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.dao;
2 |
3 | import com.xusheng.music.domain.Comment;
4 | import org.springframework.stereotype.Repository;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * 评论Dao
10 | */
11 | @Repository
12 | public interface CommentMapper {
13 | /**
14 | * 增加
15 | */
16 | public int insert(Comment comment);
17 |
18 | /**
19 | * 修改
20 | */
21 | public int update(Comment comment);
22 |
23 | /**
24 | * 删除
25 | */
26 | public int delete(Integer id);
27 |
28 | /**
29 | * 根据主键查询整个对象
30 | */
31 | public Comment selectByPrimaryKey(Integer id);
32 |
33 | /**
34 | * 查询所有评论
35 | */
36 | public List allComment();
37 |
38 | /**
39 | * 查询某个歌曲下的所有评论
40 | */
41 | public List commentOfSongId(Integer songId);
42 |
43 | /**
44 | * 查询某个歌单下的所有评论
45 | */
46 | public List commentOfSongListId(Integer songListId);
47 | }
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/lyric.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 |
3 | .song-lyric {
4 | margin: auto;
5 | margin-top: $header-height + 20px;
6 | width: 700px;
7 | background-color: $color-white;
8 | border-radius: 12px;
9 | padding: 0 20px 50px 20px;
10 | font-family: $font-family;
11 |
12 | .lyric-title {
13 | text-align: center;
14 | height: 60px;
15 | line-height: 60px;
16 | border-bottom: 2px solid $color-black;
17 | }
18 |
19 | .has-lyric {
20 | font-size: 18px;
21 | padding: 30px 0;
22 | width: 100%;
23 | min-height: 170px;
24 | text-align: center;
25 |
26 | li {
27 | width: 100%;
28 | height: 40px;
29 | line-height: 40px;
30 | }
31 | }
32 |
33 | .no-lyric {
34 | margin: 200px 0;
35 | width: 100%;
36 | text-align: center;
37 |
38 | span {
39 | font-size: 18px;
40 | text-align: center;
41 | }
42 | }
43 | }
44 |
45 | .lyric-fade-enter,
46 | .lyric-fade-leave-to {
47 | transform: translateX(30px);
48 | opacity: 0;
49 | }
50 |
51 | .lyric-fade-enter-active,
52 | .lyric-fade-leave-active {
53 | transition: all 0.3s ease;
54 | }
55 |
--------------------------------------------------------------------------------
/music-client/src/pages/Search.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
35 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/domain/Rank.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.domain;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * 评价
7 | */
8 | public class Rank implements Serializable {
9 | /*主键*/
10 | private Integer id;
11 | /*歌单id*/
12 | private Integer songListId;
13 | /*用户id*/
14 | private Integer consumerId;
15 | /*评分*/
16 | private Integer score;
17 |
18 | public Integer getId() {
19 | return id;
20 | }
21 |
22 | public void setId(Integer id) {
23 | this.id = id;
24 | }
25 |
26 | public Integer getSongListId() {
27 | return songListId;
28 | }
29 |
30 | public void setSongListId(Integer songListId) {
31 | this.songListId = songListId;
32 | }
33 |
34 | public Integer getConsumerId() {
35 | return consumerId;
36 | }
37 |
38 | public void setConsumerId(Integer consumerId) {
39 | this.consumerId = consumerId;
40 | }
41 |
42 | public Integer getScore() {
43 | return score;
44 | }
45 |
46 | public void setScore(Integer score) {
47 | this.score = score;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/dao/ListSongMapper.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.dao;
2 |
3 | import com.xusheng.music.domain.ListSong;
4 | import org.springframework.stereotype.Repository;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * 歌单里面的歌曲Dao
10 | */
11 | @Repository
12 | public interface ListSongMapper {
13 | /**
14 | * 增加
15 | */
16 | public int insert(ListSong listSong);
17 |
18 | /**
19 | * 修改
20 | */
21 | public int update(ListSong listSong);
22 |
23 | /**
24 | * 删除
25 | */
26 | public int delete(Integer id);
27 |
28 | /**
29 | * 根据歌曲id和歌单id删除
30 | */
31 | public int deleteBySongIdAndSongListId(Integer songId, Integer songListId);
32 |
33 | /**
34 | * 根据主键查询整个对象
35 | */
36 | public ListSong selectByPrimaryKey(Integer id);
37 |
38 | /**
39 | * 查询所有歌单里面的歌曲
40 | */
41 | public List allListSong();
42 |
43 | /**
44 | * 根据歌单id查询所有的歌曲
45 | */
46 | public List listSongOfSongListId(Integer songListId);
47 | }
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/dao/CollectMapper.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.dao;
2 |
3 | import com.xusheng.music.domain.Collect;
4 | import org.apache.ibatis.annotations.Param;
5 | import org.springframework.stereotype.Repository;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * 收藏Dao
11 | */
12 | @Repository
13 | public interface CollectMapper {
14 | /**
15 | * 增加
16 | */
17 | public int insert(Collect collect);
18 |
19 | /**
20 | * 删除
21 | */
22 | public int delete(Integer id);
23 |
24 | /**
25 | * 根据用户id和歌曲id删除
26 | */
27 | public int deleteByUserIdSongId(@Param("userId") Integer userId, @Param("songId") Integer songId);
28 |
29 | /**
30 | * 查询所有收藏
31 | */
32 | public List allCollect();
33 |
34 | /**
35 | * 查询某个用户的收藏列表
36 | */
37 | public List collectOfUserId(Integer userId);
38 |
39 | /**
40 | * 查询某个用户是否已经收藏了某个歌曲
41 | */
42 | public int existSongId(@Param("userId") Integer userId, @Param("songId") Integer songId);
43 |
44 | }
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/album-content.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 | @import "global.scss";
3 |
4 | .content {
5 | background-color: $color-white;
6 | border-radius: $border-radius-songlist;
7 | padding: 20px 40px;
8 | min-width: 700px;
9 |
10 | .title {
11 | text-align: center;
12 | }
13 |
14 | > ul {
15 | width: 100%;
16 | padding-bottom: 50px;
17 |
18 | > li {
19 | border-bottom: 1px solid rgba(0, 0, 0, 0.1);
20 | display: block;
21 | height: 50px;
22 | line-height: 50px;
23 | text-indent: 20px;
24 | cursor: pointer;
25 | }
26 | }
27 | }
28 |
29 | .song-item {
30 | @include layout;
31 | white-space: nowrap;
32 | overflow: hidden;
33 | text-overflow: ellipsis;
34 |
35 | .item-index {
36 | width: 5%;
37 | }
38 |
39 | .item-title {
40 | width: 30%;
41 | }
42 |
43 | .item-name {
44 | width: 25%;
45 | }
46 |
47 | .item-intro {
48 | width: 40%;
49 | }
50 | }
51 |
52 | .is-play {
53 | color: $color-blue-active;
54 | font-weight: bold;
55 | }
56 |
57 | .icon {
58 | @include icon(1.3em, $color-blue-active);
59 | vertical-align: -0.3em;
60 | right: 5px;
61 | }
62 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/dao/SongMapper.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.dao;
2 |
3 | import com.xusheng.music.domain.Song;
4 | import org.springframework.stereotype.Repository;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * 歌手Dao
10 | */
11 | @Repository
12 | public interface SongMapper {
13 | /**
14 | * 增加
15 | */
16 | public int insert(Song song);
17 |
18 | /**
19 | * 修改
20 | */
21 | public int update(Song song);
22 |
23 | /**
24 | * 删除
25 | */
26 | public int delete(Integer id);
27 |
28 | /**
29 | * 根据主键查询整个对象
30 | */
31 | public Song selectByPrimaryKey(Integer id);
32 |
33 | /**
34 | * 查询所有歌曲
35 | */
36 | public List allSong();
37 |
38 | /**
39 | * 根据歌名精确查询列表
40 | */
41 | public List songOfName(String name);
42 |
43 | /**
44 | * 根据歌名模糊查询列表
45 | */
46 | public List likeSongOfName(String name);
47 |
48 | /**
49 | * 根据歌手id查询
50 | */
51 | public List songOfSingerId(Integer singerId);
52 | }
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/dao/SongListMapper.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.dao;
2 |
3 | import com.xusheng.music.domain.SongList;
4 | import org.springframework.stereotype.Repository;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * 歌单Dao
10 | */
11 | @Repository
12 | public interface SongListMapper {
13 | /**
14 | * 增加
15 | */
16 | public int insert(SongList songList);
17 |
18 | /**
19 | * 修改
20 | */
21 | public int update(SongList songList);
22 |
23 | /**
24 | * 删除
25 | */
26 | public int delete(Integer id);
27 |
28 | /**
29 | * 根据主键查询整个对象
30 | */
31 | public SongList selectByPrimaryKey(Integer id);
32 |
33 | /**
34 | * 查询所有歌单
35 | */
36 | public List allSongList();
37 |
38 | /**
39 | * 根据标题精确查询歌单列表
40 | */
41 | public List songListOfTitle(String title);
42 |
43 | /**
44 | * 根据标题模糊查询歌单列表
45 | */
46 | public List likeTitle(String title);
47 |
48 | /**
49 | * 根据风格模糊查询歌单列表
50 | */
51 | public List likeStyle(String style);
52 |
53 |
54 | }
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/music-client/test/e2e/nightwatch.conf.js:
--------------------------------------------------------------------------------
1 | require('babel-register')
2 | var config = require('../../config')
3 |
4 | // http://nightwatchjs.org/gettingstarted#settings-file
5 | module.exports = {
6 | src_folders: ['test/e2e/specs'],
7 | output_folder: 'test/e2e/reports',
8 | custom_assertions_path: ['test/e2e/custom-assertions'],
9 |
10 | selenium: {
11 | start_process: true,
12 | server_path: require('selenium-server').path,
13 | host: '127.0.0.1',
14 | port: 4444,
15 | cli_args: {
16 | 'webdriver.chrome.driver': require('chromedriver').path
17 | }
18 | },
19 |
20 | test_settings: {
21 | default: {
22 | selenium_port: 4444,
23 | selenium_host: 'localhost',
24 | silent: true,
25 | globals: {
26 | devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port)
27 | }
28 | },
29 |
30 | chrome: {
31 | desiredCapabilities: {
32 | browserName: 'chrome',
33 | javascriptEnabled: true,
34 | acceptSslCerts: true
35 | }
36 | },
37 |
38 | firefox: {
39 | desiredCapabilities: {
40 | browserName: 'firefox',
41 | javascriptEnabled: true,
42 | acceptSslCerts: true
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/setting.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 | @import "global.scss";
3 |
4 | .setting {
5 | margin: 30px 10%;
6 | margin-top: $header-height + 20px;
7 | min-height: 65vh;
8 | @include layout;
9 | background-color: $color-white;
10 | border-radius: 12px;
11 | }
12 |
13 | /* 左侧导航栏 */
14 | .leftCol {
15 | margin-top: 10px;
16 | padding: 0 20px;
17 | box-sizing: border-box;
18 | width: 200px;
19 |
20 | .settingsMainHeader {
21 | height: 60px;
22 | line-height: 60px;
23 | font-size: 22px;
24 | font-weight: 500;
25 | }
26 | }
27 |
28 | .setting-aside {
29 | width: 100%;
30 |
31 | li {
32 | display: block;
33 | height: 40px;
34 | line-height: 40px;
35 | font-size: 18px;
36 | padding: 0 10px;
37 | box-sizing: border-box;
38 | border-radius: 5px;
39 | margin-right: 2px;
40 | cursor: pointer;
41 |
42 | &:hover {
43 | background-color: $color-blue-active;
44 | color: $color-white;
45 | }
46 |
47 | &:active {
48 | background-color: $color-blue-shallow;
49 | }
50 | }
51 | }
52 |
53 | .activeColor {
54 | background-color: $color-blue-shallow !important;
55 | color: $color-white;
56 | }
57 |
58 | /* 右边内容 */
59 | .contentCol {
60 | flex: 1;
61 | padding-top: 20px;
62 | }
63 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/domain/SongList.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.domain;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * 歌单
7 | */
8 | public class SongList implements Serializable {
9 | /*主键*/
10 | private Integer id;
11 | /*歌单标题*/
12 | private String title;
13 | /*歌单图片*/
14 | private String pic;
15 | /*简介*/
16 | private String introduction;
17 | /*风格*/
18 | private String style;
19 |
20 | public Integer getId() {
21 | return id;
22 | }
23 |
24 | public void setId(Integer id) {
25 | this.id = id;
26 | }
27 |
28 | public String getTitle() {
29 | return title;
30 | }
31 |
32 | public void setTitle(String title) {
33 | this.title = title;
34 | }
35 |
36 | public String getPic() {
37 | return pic;
38 | }
39 |
40 | public void setPic(String pic) {
41 | this.pic = pic;
42 | }
43 |
44 | public String getIntroduction() {
45 | return introduction;
46 | }
47 |
48 | public void setIntroduction(String introduction) {
49 | this.introduction = introduction;
50 | }
51 |
52 | public String getStyle() {
53 | return style;
54 | }
55 |
56 | public void setStyle(String style) {
57 | this.style = style;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/music-client/src/components/search/SearchSongLists.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
43 |
44 |
--------------------------------------------------------------------------------
/music-client/build/build.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | require('./check-versions')()
3 |
4 | process.env.NODE_ENV = 'production'
5 |
6 | const ora = require('ora')
7 | const rm = require('rimraf')
8 | const path = require('path')
9 | const chalk = require('chalk')
10 | const webpack = require('webpack')
11 | const config = require('../config')
12 | const webpackConfig = require('./webpack.prod.conf')
13 |
14 | const spinner = ora('building for production...')
15 | spinner.start()
16 |
17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
18 | if (err) throw err
19 | webpack(webpackConfig, (err, stats) => {
20 | spinner.stop()
21 | if (err) throw err
22 | process.stdout.write(stats.toString({
23 | colors: true,
24 | modules: false,
25 | children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
26 | chunks: false,
27 | chunkModules: false
28 | }) + '\n\n')
29 |
30 | if (stats.hasErrors()) {
31 | console.log(chalk.red(' Build failed with errors.\n'))
32 | process.exit(1)
33 | }
34 |
35 | console.log(chalk.cyan(' Build complete.\n'))
36 | console.log(chalk.yellow(
37 | ' Tip: built files are meant to be served over an HTTP server.\n' +
38 | ' Opening index.html over file:// won\'t work.\n'
39 | ))
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/singer-album.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 |
3 | .singer-album {
4 | margin-top: $header-height;
5 | padding-top: 150px;
6 | background-color: $theme-background-color;
7 |
8 | &::before {
9 | /*背景*/
10 | content: "";
11 | background-color: $theme-color;
12 | position: absolute;
13 | top: 0;
14 | width: 100%;
15 | height: $header-height + 150px;
16 | }
17 | }
18 |
19 | /*左*/
20 | .album-slide {
21 | float: left;
22 | width: 400px;
23 |
24 | .singer-img {
25 | position: relative;
26 | display: inline-block;
27 | height: 300px;
28 | width: 300px;
29 | top: -100px;
30 | left: 50px;
31 | border-radius: 10%;
32 | overflow: hidden;
33 | border: 5px solid $color-white;
34 | background-color: $color-white;
35 |
36 | img {
37 | width: 100%;
38 | }
39 | }
40 |
41 | .info {
42 | color: $color-black;
43 | font-size: 20px;
44 | font-weight: 500;
45 | margin-top: -80px;
46 | padding: 30px 40px 30px 60px;
47 |
48 | li {
49 | width: 100%;
50 | height: 40px;
51 | }
52 | }
53 | }
54 |
55 | /*右*/
56 | .album-content {
57 | margin-left: 300px;
58 | padding: 30px 100px;
59 |
60 | .intro {
61 | font-size: 20px;
62 |
63 | span {
64 | color: rgba(0, 0, 0, 0.5);
65 | }
66 | }
67 |
68 | .content {
69 | margin-top: 50px;
70 | }
71 | }
72 |
73 |
--------------------------------------------------------------------------------
/music-client/src/store/user.js:
--------------------------------------------------------------------------------
1 | const user = {
2 | state: {
3 | userId: '', //用户id
4 | username: '', //用户账号
5 | avator: '', //用户头像
6 | },
7 | getters: {
8 | userId: state => {
9 | let userId = state.userId
10 | if (!userId) {
11 | userId = JSON.parse(window.sessionStorage.getItem('userId'))
12 | }
13 | return userId
14 | },
15 | username: state => {
16 | let username = state.username
17 | if (!username) {
18 | username = JSON.parse(window.sessionStorage.getItem('username'))
19 | }
20 | return username
21 | },
22 | avator: state => {
23 | let avator = state.avator
24 | if (!avator) {
25 | avator = JSON.parse(window.sessionStorage.getItem('avator'))
26 | }
27 | return avator
28 | }
29 |
30 | },
31 | mutations: {
32 | setUserId: (state, userId) => {
33 | state.userId = userId
34 | window.sessionStorage.setItem('userId', JSON.stringify(userId))
35 | },
36 | setUsername: (state, username) => {
37 | state.username = username
38 | window.sessionStorage.setItem('username', JSON.stringify(username))
39 | },
40 | setAvator: (state, avator) => {
41 | state.avator = avator
42 | window.sessionStorage.setItem('avator', JSON.stringify(avator))
43 | }
44 | }
45 | }
46 |
47 | export default user
48 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/my-music.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 |
3 | .my-music {
4 | margin-top: $header-height;
5 | padding-top: 150px;
6 | background-color: $theme-background-color;
7 |
8 | &::before {
9 | /*背景*/
10 | content: "";
11 | background-color: $theme-color;
12 | position: absolute;
13 | top: 0;
14 | width: 100%;
15 | height: $header-height + 150px;
16 | }
17 | }
18 |
19 | /*左侧*/
20 | .album-slide {
21 | float: left;
22 | width: 400px;
23 |
24 | // 图片
25 | .album-img {
26 | height: 200px;
27 | width: 200px;
28 | display: inline-block;
29 | position: relative;
30 | top: -100px;
31 | left: 50px;
32 | border-radius: 50%;
33 | overflow: hidden;
34 | border: 5px solid $color-white;
35 |
36 | img {
37 | width: 100%;
38 | }
39 | }
40 |
41 | /*信息*/
42 | .album-info {
43 | color: $color-black;
44 | width: 500px;
45 | font-size: 20px;
46 | font-weight: 500;
47 | margin-top: -100px;
48 | margin-left: 100px;
49 | padding: 30px 30px;
50 |
51 | li {
52 | width: 100%;
53 | line-height: 40px;
54 | }
55 | }
56 | }
57 |
58 | /*歌单内容*/
59 | .album-content {
60 | margin-left: 300px;
61 | padding: 40px 100px;
62 | /*歌单题目*/
63 | .album-title {
64 | font-size: 30px;
65 | font-weight: 600;
66 | }
67 |
68 | .songs-body {
69 | margin-top: 50px;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/music-client/src/pages/Setting.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
设置
5 |
6 | -
8 | {{item.name}}
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/music-client/src/components/ContentList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
![]()
7 |
8 |
11 |
12 |
13 | {{item.name||item.title}}
14 |
15 |
16 |
17 |
18 |
36 |
39 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/comment.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 | @import "global.scss";
3 |
4 | /*评论*/
5 | .comment {
6 | h2 {
7 | margin-bottom: 20px;
8 | text-align: center;
9 | height: 50px;
10 | line-height: 50px;
11 | border-bottom: 1px solid $color-black;
12 | }
13 |
14 | .comment-msg {
15 | display: flex;
16 |
17 | .comment-img {
18 | width: 70px;
19 |
20 | img {
21 | width: 100%;
22 | }
23 | }
24 |
25 | .comment-input {
26 | margin-left: 10px;
27 | flex: 1;
28 | }
29 | }
30 |
31 | .sub-btn {
32 | margin-top: 10px;
33 | margin-left: 90%;
34 | }
35 | }
36 |
37 | /*热门评论*/
38 | .popular {
39 | width: 100%;
40 |
41 | > li {
42 | border-bottom: solid 1px rgba(0, 0, 0, 0.1);
43 | padding: 15px 0;
44 | display: flex;
45 |
46 | .popular-img {
47 | width: 50px;
48 |
49 | img {
50 | width: 100%;
51 | }
52 | }
53 |
54 | .popular-msg {
55 | padding: 0 20px;
56 | flex: 1;
57 |
58 | li {
59 | width: 100%;
60 | }
61 |
62 | .name {
63 | font-size: 1rem;
64 | }
65 |
66 | .time {
67 | font-size: 0.6rem;
68 | color: rgba(0, 0, 0, 0.5);
69 | }
70 |
71 | .content {
72 | font-size: 1rem;
73 | }
74 | }
75 |
76 | .up {
77 | width: 50px;
78 | line-height: 60px;
79 | }
80 | }
81 | }
82 |
83 | .icon {
84 | @include icon(1em);
85 | }
86 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/content-list.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 | @import "global.scss";
3 |
4 | .content-list {
5 | min-height: 500px;
6 | padding: 0 20px;
7 |
8 | .section-content {
9 | @include layout(flex-start, stretch, row, wrap);
10 | }
11 | }
12 |
13 | .content-item {
14 | width: 18%;
15 | margin: 20px 1%;
16 | overflow: hidden;
17 | border-radius: 4px;
18 | @include box-shadow(0 0 5px 1px rgba(0, 0, 0, 0.1));
19 | position: relative;
20 |
21 | &:hover {
22 | @include box-shadow(0 0 5px 2px rgba(0, 0, 0, 0.3));
23 | }
24 |
25 | &:hover .item-img {
26 | transform: scale(1.1);
27 | }
28 |
29 | .item-name {
30 | overflow: hidden;
31 | text-overflow: ellipsis;
32 | display: -webkit-box;
33 | -webkit-box-orient: vertical;
34 | -webkit-line-clamp: 2;
35 | margin: 10px 8px;
36 | }
37 | }
38 |
39 | .item-img {
40 | width: 100%;
41 | transition: all 0.4s ease;
42 | }
43 |
44 | .kuo,
45 | .mask {
46 | width: 100%;
47 | padding-bottom: 100%;
48 | height: 0;
49 | overflow: hidden;
50 | }
51 |
52 | .mask {
53 | position: absolute;
54 | top: 0;
55 | background-color: rgba(52, 47, 41, 0.4);
56 | transition: all 0.3s ease-in-out;
57 | opacity: 0;
58 | @include layout(center);
59 |
60 | > .icon {
61 | position: absolute;
62 | top: 40%;
63 | }
64 |
65 | &:hover {
66 | opacity: 1;
67 | cursor: pointer;
68 | }
69 | }
70 |
71 | .icon {
72 | @include icon(2em, rgba(240, 240, 240, 1));
73 | }
74 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/the-aside.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 | @import "global.scss";
3 |
4 | .slide-fade-enter-active {
5 | transition: all .3s ease;
6 | }
7 |
8 | .slide-fade-leave-active {
9 | transition: all .2s ease;
10 | }
11 |
12 | .slide-fade-enter, .slide-fade-leave-to {
13 | transform: translateX(10px);
14 | opacity: 0;
15 | }
16 |
17 | .the-aside {
18 | font-size: 14px;
19 | width: 250px;
20 | height: 370px;
21 | position: fixed;
22 | right: 0;
23 | top: 150px;
24 | z-index: 99;
25 | background-color: $color-white;
26 | @include box-shadow(1px 1px 10px rgba(0, 0, 0, 0.4));
27 | border: 1px solid rgba(0, 0, 0, 0.5);
28 | border-top-left-radius: 5px;
29 | border-bottom-left-radius: 5px;
30 | overflow: hidden;
31 | }
32 |
33 | .title {
34 | padding-left: 20px;
35 | margin: 10px 0;
36 | box-sizing: border-box;
37 | }
38 |
39 | .menus {
40 | background-color: $color-white;
41 | width: 100%;
42 | height: calc(100% - 19px);
43 | cursor: pointer;
44 | z-index: 100;
45 | overflow: scroll;
46 | white-space: nowrap;
47 |
48 | li {
49 | display: block;
50 | width: 100%;
51 | height: 40px;
52 | line-height: 40px;
53 | padding-left: 20px;
54 | box-sizing: border-box;
55 | border-bottom: solid 1px rgba(0, 0, 0, 0.2);
56 |
57 | &:hover {
58 | background-color: $color-blue;
59 | color: $color-white;
60 | }
61 | }
62 | }
63 |
64 | .is-play {
65 | color: $color-blue-active;
66 | font-weight: bold;
67 | }
68 |
--------------------------------------------------------------------------------
/music-client/src/components/AlbumContent.vue:
--------------------------------------------------------------------------------
1 |
2 |
28 |
29 |
40 |
41 |
--------------------------------------------------------------------------------
/music-client/build/check-versions.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const chalk = require('chalk')
3 | const semver = require('semver')
4 | const packageConfig = require('../package.json')
5 | const shell = require('shelljs')
6 |
7 | function exec(cmd) {
8 | return require('child_process').execSync(cmd).toString().trim()
9 | }
10 |
11 | const versionRequirements = [
12 | {
13 | name: 'node',
14 | currentVersion: semver.clean(process.version),
15 | versionRequirement: packageConfig.engines.node
16 | }
17 | ]
18 |
19 | if (shell.which('npm')) {
20 | versionRequirements.push({
21 | name: 'npm',
22 | currentVersion: exec('npm --version'),
23 | versionRequirement: packageConfig.engines.npm
24 | })
25 | }
26 |
27 | module.exports = function () {
28 | const warnings = []
29 |
30 | for (let i = 0; i < versionRequirements.length; i++) {
31 | const mod = versionRequirements[i]
32 |
33 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
34 | warnings.push(mod.name + ': ' +
35 | chalk.red(mod.currentVersion) + ' should be ' +
36 | chalk.green(mod.versionRequirement)
37 | )
38 | }
39 | }
40 |
41 | if (warnings.length) {
42 | console.log('')
43 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
44 | console.log()
45 |
46 | for (let i = 0; i < warnings.length; i++) {
47 | const warning = warnings[i]
48 | console.log(' ' + warning)
49 | }
50 |
51 | console.log()
52 | process.exit(1)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/domain/Collect.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.domain;
2 |
3 | import java.io.Serializable;
4 | import java.util.Date;
5 |
6 | /**
7 | * 收藏
8 | */
9 | public class Collect implements Serializable {
10 | private Integer id; //主键
11 | private Integer userId; //用户id
12 | private Byte type; //收藏类型(0歌曲1歌单)
13 | private Integer songId; //歌曲id
14 | private Integer songListId; //歌单id
15 | private Date createTime; //收藏时间
16 |
17 | public Integer getId() {
18 | return id;
19 | }
20 |
21 | public void setId(Integer id) {
22 | this.id = id;
23 | }
24 |
25 | public Integer getUserId() {
26 | return userId;
27 | }
28 |
29 | public void setUserId(Integer userId) {
30 | this.userId = userId;
31 | }
32 |
33 | public Byte getType() {
34 | return type;
35 | }
36 |
37 | public void setType(Byte type) {
38 | this.type = type;
39 | }
40 |
41 | public Integer getSongId() {
42 | return songId;
43 | }
44 |
45 | public void setSongId(Integer songId) {
46 | this.songId = songId;
47 | }
48 |
49 | public Integer getSongListId() {
50 | return songListId;
51 | }
52 |
53 | public void setSongListId(Integer songListId) {
54 | this.songListId = songListId;
55 | }
56 |
57 | public Date getCreateTime() {
58 | return createTime;
59 | }
60 |
61 | public void setCreateTime(Date createTime) {
62 | this.createTime = createTime;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/service/impl/RankServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.service.impl;
2 |
3 | import com.xusheng.music.dao.RankMapper;
4 | import com.xusheng.music.domain.Rank;
5 | import com.xusheng.music.service.RankService;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.stereotype.Service;
8 |
9 | /**
10 | * 评价service实现
11 | */
12 | @Service
13 | public class RankServiceImpl implements RankService {
14 |
15 | @Autowired
16 | private RankMapper rankMapper;
17 |
18 | /**
19 | * 增加
20 | *
21 | * @param rank
22 | */
23 | @Override
24 | public boolean insert(Rank rank) {
25 | return rankMapper.insert(rank) > 0;
26 | }
27 |
28 | /**
29 | * 查总分
30 | *
31 | * @param songListId
32 | */
33 | @Override
34 | public int selectScoreSum(Integer songListId) {
35 | return rankMapper.selectScoreSum(songListId);
36 | }
37 |
38 | /**
39 | * 查总评分人数
40 | *
41 | * @param songListId
42 | */
43 | @Override
44 | public int selectRankNum(Integer songListId) {
45 | return rankMapper.selectRankNum(songListId);
46 | }
47 |
48 | /**
49 | * 计算平均分
50 | *
51 | * @param songListId
52 | */
53 | @Override
54 | public int rankOfSongListId(Integer songListId) {
55 | int rankNum = rankMapper.selectRankNum(songListId);
56 | if (rankNum == 0) {
57 | return 5;
58 | }
59 | return rankMapper.selectScoreSum(songListId) / rankNum;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/domain/Singer.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.domain;
2 |
3 | import java.io.Serializable;
4 | import java.util.Date;
5 |
6 | /**
7 | * 歌手
8 | */
9 | public class Singer implements Serializable {
10 | /*主键*/
11 | private Integer id;
12 | /*账号*/
13 | private String name;
14 | /*性别*/
15 | private Byte sex;
16 | /*头像*/
17 | private String pic;
18 | /*生日*/
19 | private Date birth;
20 | /*地区*/
21 | private String location;
22 | /*简介*/
23 | private String introduction;
24 |
25 | public Integer getId() {
26 | return id;
27 | }
28 |
29 | public void setId(Integer id) {
30 | this.id = id;
31 | }
32 |
33 | public String getName() {
34 | return name;
35 | }
36 |
37 | public void setName(String name) {
38 | this.name = name;
39 | }
40 |
41 | public Byte getSex() {
42 | return sex;
43 | }
44 |
45 | public void setSex(Byte sex) {
46 | this.sex = sex;
47 | }
48 |
49 | public String getPic() {
50 | return pic;
51 | }
52 |
53 | public void setPic(String pic) {
54 | this.pic = pic;
55 | }
56 |
57 | public Date getBirth() {
58 | return birth;
59 | }
60 |
61 | public void setBirth(Date birth) {
62 | this.birth = birth;
63 | }
64 |
65 | public String getLocation() {
66 | return location;
67 | }
68 |
69 | public void setLocation(String location) {
70 | this.location = location;
71 | }
72 |
73 | public String getIntroduction() {
74 | return introduction;
75 | }
76 |
77 | public void setIntroduction(String introduction) {
78 | this.introduction = introduction;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/music-client/src/api/http.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 | import router from '../router';
3 |
4 | axios.defaults.timeout = 5000; //超市时间是5秒
5 | axios.defaults.withCredentials = true; //允许跨域
6 | //Content-Type 响应头
7 | axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
8 | //基础url
9 | axios.defaults.baseURL = "http://localhost:8888";
10 |
11 | //响应拦截器
12 | axios.interceptors.response.use(
13 | response => {
14 | //如果reponse里面的status是200,说明访问到接口了,否则错误
15 | if (response.status == 200) {
16 | return Promise.resolve(response);
17 | } else {
18 | return Promise.reject(response);
19 | }
20 | },
21 | error => {
22 | if (error.response.status) {
23 | switch (error.response.status) {
24 | case 401: //未登录
25 | router.replace({
26 | path: '/',
27 | query: {
28 | redirect: router.currentRoute.fullPath
29 | }
30 | });
31 | break;
32 | case 404: //没找到
33 | break;
34 | }
35 | return Promise.reject(error.response);
36 | }
37 | }
38 | );
39 |
40 | /**
41 | * 封装get方法
42 | */
43 | export function get(url, params = {}) {
44 | return new Promise((resolve, reject) => {
45 | axios.get(url, {params: params})
46 | .then(response => {
47 | resolve(response.data);
48 | })
49 | .catch(err => {
50 | reject(err);
51 | })
52 | });
53 | }
54 |
55 | /**
56 | * 封装post方法
57 | */
58 | export function post(url, data = {}) {
59 | return new Promise((resolve, reject) => {
60 | axios.post(url, data)
61 | .then(response => {
62 | resolve(response.data);
63 | })
64 | .catch(err => {
65 | reject(err);
66 | })
67 | });
68 | }
69 |
--------------------------------------------------------------------------------
/music-client/test/e2e/runner.js:
--------------------------------------------------------------------------------
1 | // 1. start the dev server using production config
2 | process.env.NODE_ENV = 'testing'
3 |
4 | const webpack = require('webpack')
5 | const DevServer = require('webpack-dev-server')
6 |
7 | const webpackConfig = require('../../build/webpack.prod.conf')
8 | const devConfigPromise = require('../../build/webpack.dev.conf')
9 |
10 | let server
11 |
12 | devConfigPromise.then(devConfig => {
13 | const devServerOptions = devConfig.devServer
14 | const compiler = webpack(webpackConfig)
15 | server = new DevServer(compiler, devServerOptions)
16 | const port = devServerOptions.port
17 | const host = devServerOptions.host
18 | return server.listen(port, host)
19 | })
20 | .then(() => {
21 | // 2. run the nightwatch test suite against it
22 | // to run in additional browsers:
23 | // 1. add an entry in test/e2e/nightwatch.conf.js under "test_settings"
24 | // 2. add it to the --env flag below
25 | // or override the environment flag, for example: `npm run e2e -- --env chrome,firefox`
26 | // For more information on Nightwatch's config file, see
27 | // http://nightwatchjs.org/guide#settings-file
28 | let opts = process.argv.slice(2)
29 | if (opts.indexOf('--config') === -1) {
30 | opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js'])
31 | }
32 | if (opts.indexOf('--env') === -1) {
33 | opts = opts.concat(['--env', 'chrome'])
34 | }
35 |
36 | const spawn = require('cross-spawn')
37 | const runner = spawn('./node_modules/.bin/nightwatch', opts, {stdio: 'inherit'})
38 |
39 | runner.on('exit', function (code) {
40 | server.close()
41 | process.exit(code)
42 | })
43 |
44 | runner.on('error', function (err) {
45 | server.close()
46 | throw err
47 | })
48 | })
49 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/var.scss:
--------------------------------------------------------------------------------
1 | //Colors
2 | $color-white: #ffffff;
3 | $color-light-white: #fefefe;
4 | $color-grey: #67757f;
5 | $color-light-grey: #ebeef0;
6 | $color-black: #000000;
7 | $color-blue-shallow: #a9dbf9;
8 | $color-blue: #95d2f6;
9 | $color-blue-active: #30a4fc;
10 | $color-blue-light: #2aa3ef;
11 | $color-blue-dark: #2796dd;
12 |
13 | // Theme Global Color
14 | $theme-color: $color-blue;
15 | $theme-background-color: #e6ecf0;
16 | $theme-header-color: $color-light-white;
17 | $theme-footer-color: $theme-background-color;
18 | $theme-play-bar-color: $color-light-white;
19 |
20 | // Fonts
21 | $font-family: Lato, Helvetica Neue For Number, -apple-system, BlinkMacSystemFont,
22 | Segoe UI, Roboto, PingFang SC, Hiragino Sans GB, Microsoft YaHei,
23 | Helvetica Neue, Helvetica, Arial, sans-serif;
24 | $font-size-default: 14px;
25 | $font-size-logo: 26px;
26 | $font-size-header: 18px;
27 |
28 | // header
29 | $header-height: 70px;
30 | $header-padding: 0 80px;
31 | $header-margin: 0;
32 | $header-logo-width: 150px;
33 | $header-logo-margin: 0 10px;
34 | $header-nav-padding: 0 10px;
35 | $header-nav-margin: 0 10px;
36 | $header-search-radius: 5px;
37 | $header-search-height: ($header-height / 2);
38 | $header-search-width: 270px;
39 | $header-search-btn-height: ($header-height / 2);
40 | $header-search-btn-width: 60px;
41 | $header-user-height: ($header-height / 3) * 2;
42 | $header-user-width: ($header-height / 3) * 2;
43 | $header-user-margin: 0 25px;
44 | $header-user-radius: 50%;
45 | $header-menu-width: 150px;
46 | $header-menu-padding: 7px 0px;
47 | $header-menu-radius: 4px;
48 |
49 | // page
50 | $content-padding: 0 120px 50px 120px;
51 | $border-radius-songlist: 12px;
52 |
53 | // footer
54 | $footer-height: 180px;
55 |
56 | // play-bar
57 | $play-bar-height: 60px;
58 |
59 | // style
60 | $box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
61 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/song-list-album.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 |
3 | /*歌单背景*/
4 | .song-list-album {
5 | margin-top: $header-height;
6 | padding-top: 150px;
7 | background-color: $theme-background-color;
8 |
9 | &::before {
10 | /*背景*/
11 | content: "";
12 | background-color: $theme-color;
13 | position: absolute;
14 | top: 0;
15 | width: 100%;
16 | height: $header-height + 150px;
17 | }
18 | }
19 |
20 | /*歌单左侧*/
21 | .album-slide {
22 | float: left;
23 | width: 400px;
24 |
25 | /*歌单图像*/
26 | .album-img {
27 | position: relative;
28 | display: inline-block;
29 | height: 300px;
30 | width: 300px;
31 | top: -100px;
32 | left: 50px;
33 | border-radius: 10%;
34 | overflow: hidden;
35 | border: 5px solid $color-white;
36 | background-color: $color-white;
37 |
38 | img {
39 | width: 100%;
40 | }
41 | }
42 |
43 | /*歌单信息*/
44 | .album-info {
45 | color: $color-black;
46 | font-size: 20px;
47 | font-weight: 500;
48 | margin-top: -80px;
49 | padding: 30px 40px 30px 60px;
50 |
51 | span {
52 | color: rgba(0, 0, 0, 0.5);
53 | }
54 | }
55 | }
56 |
57 | /*歌单内容*/
58 | .album-content {
59 | margin-left: 300px;
60 | padding: 40px 100px;
61 | /*歌单题目*/
62 | .album-title {
63 | font-size: 30px;
64 | font-weight: 600;
65 | }
66 |
67 | /*歌单打分*/
68 | .album-score {
69 | display: flex;
70 | align-items: center;
71 | margin: 50px;
72 |
73 | > div {
74 | margin-left: 100px;
75 | }
76 |
77 | > span {
78 | font-size: 60px;
79 | }
80 |
81 | h3 {
82 | margin: 10px 0;
83 | }
84 | }
85 |
86 | /*歌曲列表*/
87 | .songs-body {
88 | background-color: $color-white;
89 | border-radius: 12px;
90 | padding: 0 40px 50px 40px;
91 | min-width: 700px;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/music-client/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import Home from '@/pages/Home'
4 | import MyMusic from '@/pages/MyMusic'
5 | import Singer from '@/pages/Singer'
6 | import SongList from '@/pages/SongList'
7 | import Search from '@/pages/Search'
8 | import Lyric from '@/pages/lyric'
9 | import SignUp from '@/pages/SignUp'
10 | import LoginIn from '@/pages/LoginIn'
11 | import Setting from '@/pages/Setting'
12 | import SingerAlbum from '@/pages/SingerAlbum'
13 | import SongListAlbum from '@/pages/SongListAlbum'
14 |
15 |
16 | Vue.use(Router)
17 |
18 | export default new Router({
19 | routes: [
20 | {
21 | path: '/',
22 | name: 'home',
23 | component: Home
24 | },
25 | {
26 | path: '/my-music',
27 | name: 'my-music',
28 | component: MyMusic
29 | },
30 | {
31 | path: '/singer',
32 | name: 'singer',
33 | component: Singer
34 | },
35 | {
36 | path: '/song-list',
37 | name: 'song-list',
38 | component: SongList
39 | },
40 | {
41 | path: '/search',
42 | name: 'search',
43 | component: Search
44 | },
45 | {
46 | path: '/lyric',
47 | name: 'lyric',
48 | component: Lyric
49 | },
50 | {
51 | path: '/sign-up',
52 | name: 'sign-up',
53 | component: SignUp
54 | },
55 | {
56 | path: '/login-in',
57 | name: 'login-in',
58 | component: LoginIn
59 | },
60 | {
61 | path: '/setting',
62 | name: 'setting',
63 | component: Setting
64 | },
65 | {
66 | path: '/singer-album/:id',
67 | name: 'singer-album',
68 | component: SingerAlbum
69 | },
70 | {
71 | path: '/song-list-album/:id',
72 | name: 'song-list-album',
73 | component: SongListAlbum
74 | }
75 |
76 | ],
77 | scrollBehavior(to, from, savedPosition) {
78 | return {x: 0, y: 0}
79 | }
80 | })
81 |
--------------------------------------------------------------------------------
/music-client/src/store/configure.js:
--------------------------------------------------------------------------------
1 | const configure = {
2 | state: {
3 | HOST: 'http://127.0.0.1:8888', //后台访问地址根目录
4 | activeName: '', //当前选中的菜单名
5 | showAside: false, //是否显示播放中的歌曲列表
6 | loginIn: false, //用户是否已登录
7 | isActive: false, //当前歌曲是否已收藏
8 | },
9 | getters: {
10 | activeName: state => {
11 | let activeName = state.activeName
12 | if (!activeName) {
13 | activeName = JSON.parse(window.sessionStorage.getItem('activeName'))
14 | }
15 | return activeName
16 | },
17 | showAside: state => {
18 | let showAside = state.showAside
19 | if (!showAside) {
20 | showAside = JSON.parse(window.sessionStorage.getItem('showAside'))
21 | }
22 | return showAside
23 | },
24 | loginIn: state => {
25 | let loginIn = state.loginIn
26 | if (!loginIn) {
27 | loginIn = JSON.parse(window.sessionStorage.getItem('loginIn'))
28 | }
29 | return loginIn
30 | },
31 | isActive: state => {
32 | let isActive = state.isActive
33 | if (!isActive) {
34 | isActive = JSON.parse(window.sessionStorage.getItem('isActive'))
35 | }
36 | return isActive
37 | }
38 | },
39 | mutations: {
40 | setActiveName: (state, activeName) => {
41 | state.activeName = activeName
42 | window.sessionStorage.setItem('activeName', JSON.stringify(activeName))
43 | },
44 | setShowAside: (state, showAside) => {
45 | state.showAside = showAside
46 | window.sessionStorage.setItem('showAside', JSON.stringify(showAside))
47 | },
48 | setLoginIn: (state, loginIn) => {
49 | state.loginIn = loginIn
50 | window.sessionStorage.setItem('loginIn', JSON.stringify(loginIn))
51 | },
52 | setIsActive: (state, isActive) => {
53 | state.isActive = isActive
54 | window.sessionStorage.setItem('isActive', JSON.stringify(isActive))
55 | }
56 | }
57 | }
58 |
59 | export default configure
60 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/service/impl/CollectServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.service.impl;
2 |
3 | import com.xusheng.music.dao.CollectMapper;
4 | import com.xusheng.music.domain.Collect;
5 | import com.xusheng.music.service.CollectService;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.stereotype.Service;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * 收藏service实现类
13 | */
14 | @Service
15 | public class CollectServiceImpl implements CollectService {
16 |
17 | @Autowired
18 | private CollectMapper collectMapper;
19 |
20 |
21 | /**
22 | * 增加
23 | *
24 | * @param collect
25 | */
26 | @Override
27 | public boolean insert(Collect collect) {
28 | return collectMapper.insert(collect) > 0;
29 | }
30 |
31 | /**
32 | * 删除
33 | *
34 | * @param id
35 | */
36 | @Override
37 | public boolean delete(Integer id) {
38 | return collectMapper.delete(id) > 0;
39 | }
40 |
41 | /**
42 | * 根据用户id和歌曲id删除
43 | *
44 | * @param userId
45 | * @param songId
46 | */
47 | @Override
48 | public boolean deleteByUserIdSongId(Integer userId, Integer songId) {
49 | return collectMapper.deleteByUserIdSongId(userId, songId) > 0;
50 | }
51 |
52 | /**
53 | * 查询所有收藏
54 | */
55 | @Override
56 | public List allCollect() {
57 | return collectMapper.allCollect();
58 | }
59 |
60 | /**
61 | * 查询某个用户的收藏列表
62 | *
63 | * @param userId
64 | */
65 | @Override
66 | public List collectOfUserId(Integer userId) {
67 | return collectMapper.collectOfUserId(userId);
68 | }
69 |
70 | /**
71 | * 查询某个用户是否已经收藏了某个歌曲
72 | *
73 | * @param userId
74 | * @param songId
75 | */
76 | @Override
77 | public boolean existSongId(Integer userId, Integer songId) {
78 | return collectMapper.existSongId(userId, songId) > 0;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/music-client/src/components/Upload.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
修改头像
4 |
5 |
6 |
8 |
9 |
10 | 将文件拖到此处,或修改头像
11 |
12 | 只能上传jpg/png文件,且不能超过10MB
13 |
14 |
15 |
16 |
17 |
60 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/domain/Comment.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.domain;
2 |
3 | import java.io.Serializable;
4 | import java.util.Date;
5 |
6 | /**
7 | * 评论
8 | */
9 | public class Comment implements Serializable {
10 | /*主键*/
11 | private Integer id;
12 | /*用户id*/
13 | private Integer userId;
14 | /*评论类型(0歌曲1歌单)*/
15 | private Byte type;
16 | /*歌曲id*/
17 | private Integer songId;
18 | /*歌单id*/
19 | private Integer songListId;
20 | /*评论内容*/
21 | private String content;
22 | /*评论时间*/
23 | private Date createTime;
24 | /*评论点赞数*/
25 | private Integer up;
26 |
27 | public Integer getId() {
28 | return id;
29 | }
30 |
31 | public void setId(Integer id) {
32 | this.id = id;
33 | }
34 |
35 | public Integer getUserId() {
36 | return userId;
37 | }
38 |
39 | public void setUserId(Integer userId) {
40 | this.userId = userId;
41 | }
42 |
43 | public Byte getType() {
44 | return type;
45 | }
46 |
47 | public void setType(Byte type) {
48 | this.type = type;
49 | }
50 |
51 | public Integer getSongId() {
52 | return songId;
53 | }
54 |
55 | public void setSongId(Integer songId) {
56 | this.songId = songId;
57 | }
58 |
59 | public Integer getSongListId() {
60 | return songListId;
61 | }
62 |
63 | public void setSongListId(Integer songListId) {
64 | this.songListId = songListId;
65 | }
66 |
67 | public String getContent() {
68 | return content;
69 | }
70 |
71 | public void setContent(String content) {
72 | this.content = content;
73 | }
74 |
75 | public Date getCreateTime() {
76 | return createTime;
77 | }
78 |
79 | public void setCreateTime(Date createTime) {
80 | this.createTime = createTime;
81 | }
82 |
83 | public Integer getUp() {
84 | return up;
85 | }
86 |
87 | public void setUp(Integer up) {
88 | this.up = up;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/service/impl/SingerServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.service.impl;
2 |
3 | import com.xusheng.music.dao.SingerMapper;
4 | import com.xusheng.music.domain.Singer;
5 | import com.xusheng.music.service.SingerService;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.stereotype.Service;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * 歌手service实现类
13 | */
14 | @Service
15 | public class SingerServiceImpl implements SingerService {
16 |
17 | @Autowired
18 | private SingerMapper singerMapper;
19 |
20 | /**
21 | * 增加
22 | *
23 | * @param singer
24 | */
25 | @Override
26 | public boolean insert(Singer singer) {
27 | return singerMapper.insert(singer) > 0;
28 | }
29 |
30 | /**
31 | * 修改
32 | *
33 | * @param singer
34 | */
35 | @Override
36 | public boolean update(Singer singer) {
37 | return singerMapper.update(singer) > 0;
38 | }
39 |
40 | /**
41 | * 删除
42 | *
43 | * @param id
44 | */
45 | @Override
46 | public boolean delete(Integer id) {
47 | return singerMapper.delete(id) > 0;
48 | }
49 |
50 | /**
51 | * 根据主键查询整个对象
52 | *
53 | * @param id
54 | */
55 | @Override
56 | public Singer selectByPrimaryKey(Integer id) {
57 | return singerMapper.selectByPrimaryKey(id);
58 | }
59 |
60 | /**
61 | * 查询所有歌手
62 | */
63 | @Override
64 | public List allSinger() {
65 | return singerMapper.allSinger();
66 | }
67 |
68 | /**
69 | * 根据歌手名字模糊查询列表
70 | *
71 | * @param name
72 | */
73 | @Override
74 | public List singerOfName(String name) {
75 | return singerMapper.singerOfName(name);
76 | }
77 |
78 | /**
79 | * 根据性别查询
80 | *
81 | * @param sex
82 | */
83 | @Override
84 | public List singerOfSex(Integer sex) {
85 | return singerMapper.singerOfSex(sex);
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/service/impl/CommentServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.service.impl;
2 |
3 | import com.xusheng.music.dao.CommentMapper;
4 | import com.xusheng.music.domain.Comment;
5 | import com.xusheng.music.service.CommentService;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.stereotype.Service;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * 评论service实现类
13 | */
14 | @Service
15 | public class CommentServiceImpl implements CommentService {
16 |
17 | @Autowired
18 | private CommentMapper commentMapper;
19 |
20 | /**
21 | * 增加
22 | *
23 | * @param comment
24 | */
25 | @Override
26 | public boolean insert(Comment comment) {
27 | return commentMapper.insert(comment) > 0;
28 | }
29 |
30 | /**
31 | * 修改
32 | *
33 | * @param comment
34 | */
35 | @Override
36 | public boolean update(Comment comment) {
37 | return commentMapper.update(comment) > 0;
38 | }
39 |
40 | /**
41 | * 删除
42 | *
43 | * @param id
44 | */
45 | @Override
46 | public boolean delete(Integer id) {
47 | return commentMapper.delete(id) > 0;
48 | }
49 |
50 | /**
51 | * 根据主键查询整个对象
52 | *
53 | * @param id
54 | */
55 | @Override
56 | public Comment selectByPrimaryKey(Integer id) {
57 | return commentMapper.selectByPrimaryKey(id);
58 | }
59 |
60 | /**
61 | * 查询所有评论
62 | */
63 | @Override
64 | public List allComment() {
65 | return commentMapper.allComment();
66 | }
67 |
68 | /**
69 | * 查询某个歌曲下的所有评论
70 | *
71 | * @param songId
72 | */
73 | @Override
74 | public List commentOfSongId(Integer songId) {
75 | return commentMapper.commentOfSongId(songId);
76 | }
77 |
78 | /**
79 | * 查询某个歌单下的所有评论
80 | *
81 | * @param songListId
82 | */
83 | @Override
84 | public List commentOfSongListId(Integer songListId) {
85 | return commentMapper.commentOfSongListId(songListId);
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/service/impl/ConsumerServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.service.impl;
2 |
3 | import com.xusheng.music.dao.ConsumerMapper;
4 | import com.xusheng.music.domain.Consumer;
5 | import com.xusheng.music.service.ConsumerService;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.stereotype.Service;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * 前端用户service实现类
13 | */
14 | @Service
15 | public class ConsumerServiceImpl implements ConsumerService {
16 |
17 | @Autowired
18 | private ConsumerMapper consumerMapper;
19 |
20 | /**
21 | * 增加
22 | *
23 | * @param consumer
24 | */
25 | @Override
26 | public boolean insert(Consumer consumer) {
27 | return consumerMapper.insert(consumer) > 0;
28 | }
29 |
30 | /**
31 | * 修改
32 | *
33 | * @param consumer
34 | */
35 | @Override
36 | public boolean update(Consumer consumer) {
37 | return consumerMapper.update(consumer) > 0;
38 | }
39 |
40 | /**
41 | * 删除
42 | *
43 | * @param id
44 | */
45 | @Override
46 | public boolean delete(Integer id) {
47 | return consumerMapper.delete(id) > 0;
48 | }
49 |
50 | /**
51 | * 根据主键查询整个对象
52 | *
53 | * @param id
54 | */
55 | @Override
56 | public Consumer selectByPrimaryKey(Integer id) {
57 | return consumerMapper.selectByPrimaryKey(id);
58 | }
59 |
60 | /**
61 | * 查询所有用户
62 | */
63 | @Override
64 | public List allConsumer() {
65 | return consumerMapper.allConsumer();
66 | }
67 |
68 | /**
69 | * 查看密码是否正确
70 | *
71 | * @param username
72 | * @param password
73 | */
74 | @Override
75 | public boolean verifyPassword(String username, String password) {
76 | return consumerMapper.verifyPassword(username, password) > 0;
77 | }
78 |
79 | /**
80 | * 根据账号查询
81 | *
82 | * @param username
83 | */
84 | @Override
85 | public Consumer getByUsername(String username) {
86 | return consumerMapper.getByUsername(username);
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/service/impl/ListSongServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.service.impl;
2 |
3 | import com.xusheng.music.dao.ListSongMapper;
4 | import com.xusheng.music.domain.ListSong;
5 | import com.xusheng.music.service.ListSongService;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.stereotype.Service;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * 歌单里面的歌曲service实现类
13 | */
14 | @Service
15 | public class ListSongServiceImpl implements ListSongService {
16 | @Autowired
17 | private ListSongMapper listSongMapper;
18 |
19 | /**
20 | * 增加
21 | *
22 | * @param listSong
23 | */
24 | @Override
25 | public boolean insert(ListSong listSong) {
26 | return listSongMapper.insert(listSong) > 0;
27 | }
28 |
29 | /**
30 | * 修改
31 | *
32 | * @param listSong
33 | */
34 | @Override
35 | public boolean update(ListSong listSong) {
36 | return listSongMapper.update(listSong) > 0;
37 | }
38 |
39 | /**
40 | * 删除
41 | *
42 | * @param id
43 | */
44 | @Override
45 | public boolean delete(Integer id) {
46 | return listSongMapper.delete(id) > 0;
47 | }
48 |
49 | /**
50 | * 根据歌曲id和歌单id删除
51 | */
52 | @Override
53 | public boolean deleteBySongIdAndSongListId(Integer songId, Integer songListId) {
54 | return listSongMapper.deleteBySongIdAndSongListId(songId, songListId) > 0;
55 | }
56 |
57 | /**
58 | * 根据主键查询整个对象
59 | *
60 | * @param id
61 | */
62 | @Override
63 | public ListSong selectByPrimaryKey(Integer id) {
64 | return listSongMapper.selectByPrimaryKey(id);
65 | }
66 |
67 | /**
68 | * 查询所有歌单里面的歌曲
69 | */
70 | @Override
71 | public List allListSong() {
72 | return listSongMapper.allListSong();
73 | }
74 |
75 | /**
76 | * 根据歌单id查询所有的歌曲
77 | *
78 | * @param songListId
79 | */
80 | @Override
81 | public List listSongOfSongListId(Integer songListId) {
82 | return listSongMapper.listSongOfSongListId(songListId);
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/controller/RankController.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.controller;
2 |
3 | import com.alibaba.fastjson.JSONObject;
4 | import com.xusheng.music.domain.Rank;
5 | import com.xusheng.music.service.RankService;
6 | import com.xusheng.music.utils.Consts;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.web.bind.annotation.RequestMapping;
9 | import org.springframework.web.bind.annotation.RequestMethod;
10 | import org.springframework.web.bind.annotation.RestController;
11 |
12 | import javax.servlet.http.HttpServletRequest;
13 |
14 | @RestController
15 | public class RankController {
16 |
17 | @Autowired
18 | private RankService rankService;
19 |
20 | /**
21 | * 新增评价
22 | */
23 | @RequestMapping(value = "/rank/add", method = RequestMethod.POST)
24 | public Object add(HttpServletRequest request) {
25 | JSONObject jsonObject = new JSONObject();
26 | String songListId = request.getParameter("songListId");
27 | String consumerId = request.getParameter("consumerId");
28 | String score = request.getParameter("score");
29 |
30 | Rank rank = new Rank();
31 | rank.setSongListId(Integer.parseInt(songListId));
32 | rank.setConsumerId(Integer.parseInt(consumerId));
33 | rank.setScore(Integer.parseInt(score));
34 | boolean flag = rankService.insert(rank);
35 | if (flag) {
36 | jsonObject.put(Consts.CODE, 1);
37 | jsonObject.put(Consts.MSG, "评价成功");
38 | return jsonObject;
39 | }
40 | jsonObject.put(Consts.CODE, 0);
41 | jsonObject.put(Consts.MSG, "评价失败");
42 | return jsonObject;
43 | }
44 |
45 | /**
46 | * 计算平均分
47 | */
48 | @RequestMapping(value = "/rank", method = RequestMethod.GET)
49 | public Object rankOfSongListId(HttpServletRequest request) {
50 | String songListId = request.getParameter("songListId");
51 | return rankService.rankOfSongListId(Integer.parseInt(songListId));
52 | }
53 | }
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/music-client/src/pages/Lyric.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
歌词
4 |
5 |
6 | -
7 | {{item[1]}}
8 |
9 |
10 |
11 |
12 | 暂无歌词
13 |
14 |
15 |
16 |
63 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/service/impl/SongServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.service.impl;
2 |
3 | import com.xusheng.music.dao.SongMapper;
4 | import com.xusheng.music.domain.Song;
5 | import com.xusheng.music.service.SongService;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.stereotype.Service;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * 歌曲service实现类
13 | */
14 | @Service
15 | public class SongServiceImpl implements SongService {
16 | @Autowired
17 | private SongMapper songMapper;
18 |
19 | /**
20 | * 增加
21 | *
22 | * @param song
23 | */
24 | @Override
25 | public boolean insert(Song song) {
26 | return songMapper.insert(song) > 0;
27 | }
28 |
29 | /**
30 | * 修改
31 | *
32 | * @param song
33 | */
34 | @Override
35 | public boolean update(Song song) {
36 | return songMapper.update(song) > 0;
37 | }
38 |
39 | /**
40 | * 删除
41 | *
42 | * @param id
43 | */
44 | @Override
45 | public boolean delete(Integer id) {
46 | return songMapper.delete(id) > 0;
47 | }
48 |
49 | /**
50 | * 根据主键查询整个对象
51 | *
52 | * @param id
53 | */
54 | @Override
55 | public Song selectByPrimaryKey(Integer id) {
56 | return songMapper.selectByPrimaryKey(id);
57 | }
58 |
59 | /**
60 | * 查询所有歌曲
61 | */
62 | @Override
63 | public List allSong() {
64 | return songMapper.allSong();
65 | }
66 |
67 | /**
68 | * 根据歌名精确查询列表
69 | *
70 | * @param name
71 | */
72 | @Override
73 | public List songOfName(String name) {
74 | return songMapper.songOfName(name);
75 | }
76 |
77 | /**
78 | * 根据歌名模糊查询列表
79 | *
80 | * @param name
81 | */
82 | @Override
83 | public List likeSongOfName(String name) {
84 | return songMapper.likeSongOfName("%" + name + "%");
85 | }
86 |
87 |
88 | /**
89 | * 根据歌手id查询
90 | *
91 | * @param singerId
92 | */
93 | @Override
94 | public List songOfSingerId(Integer singerId) {
95 | return songMapper.songOfSingerId(singerId);
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/music-client/src/components/SongAudio.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
74 |
75 |
--------------------------------------------------------------------------------
/music-server/src/main/resources/mapper/RankMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | insert into rank
15 |
16 |
17 | id,
18 |
19 |
20 | song_list_id,
21 |
22 |
23 | consumer_id,
24 |
25 |
26 | score,
27 |
28 |
29 |
30 |
31 | #{id},
32 |
33 |
34 | #{songListId},
35 |
36 |
37 | #{consumerId},
38 |
39 |
40 | #{score},
41 |
42 |
43 |
44 |
45 |
50 |
51 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/service/impl/SongListServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.service.impl;
2 |
3 | import com.xusheng.music.dao.SongListMapper;
4 | import com.xusheng.music.domain.SongList;
5 | import com.xusheng.music.service.SongListService;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.stereotype.Service;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * 歌单service实现类
13 | */
14 | @Service
15 | public class SongListServiceImpl implements SongListService {
16 |
17 | @Autowired
18 | private SongListMapper songListMapper;
19 |
20 |
21 | /**
22 | * 增加
23 | *
24 | * @param songList
25 | */
26 | @Override
27 | public boolean insert(SongList songList) {
28 | return songListMapper.insert(songList) > 0;
29 | }
30 |
31 | /**
32 | * 修改
33 | *
34 | * @param songList
35 | */
36 | @Override
37 | public boolean update(SongList songList) {
38 | return songListMapper.update(songList) > 0;
39 | }
40 |
41 | /**
42 | * 删除
43 | *
44 | * @param id
45 | */
46 | @Override
47 | public boolean delete(Integer id) {
48 | return songListMapper.delete(id) > 0;
49 | }
50 |
51 | /**
52 | * 根据主键查询整个对象
53 | *
54 | * @param id
55 | */
56 | @Override
57 | public SongList selectByPrimaryKey(Integer id) {
58 | return songListMapper.selectByPrimaryKey(id);
59 | }
60 |
61 | /**
62 | * 查询所有歌单
63 | */
64 | @Override
65 | public List allSongList() {
66 | return songListMapper.allSongList();
67 | }
68 |
69 | /**
70 | * 根据标题精确查询歌单列表
71 | *
72 | * @param title
73 | */
74 | @Override
75 | public List songListOfTitle(String title) {
76 | return songListMapper.songListOfTitle(title);
77 | }
78 |
79 | /**
80 | * 根据标题模糊查询歌单列表
81 | *
82 | * @param title
83 | */
84 | @Override
85 | public List likeTitle(String title) {
86 | return songListMapper.likeTitle(title);
87 | }
88 |
89 | /**
90 | * 根据风格模糊查询歌单列表
91 | *
92 | * @param style
93 | */
94 | @Override
95 | public List likeStyle(String style) {
96 | return songListMapper.likeStyle(style);
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/domain/Song.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.domain;
2 |
3 | import java.io.Serializable;
4 | import java.util.Date;
5 |
6 | /**
7 | * 歌曲
8 | */
9 | public class Song implements Serializable {
10 | /*主键*/
11 | private Integer id;
12 | //歌手id
13 | private Integer singerId;
14 | /*歌名*/
15 | private String name;
16 | /*简介*/
17 | private String introduction;
18 | /*创建时间*/
19 | private Date createTime;
20 | /*更新时间*/
21 | private Date updateTime;
22 | /*歌曲图片*/
23 | private String pic;
24 | /*歌词*/
25 | private String lyric;
26 | /*歌曲地址*/
27 | private String url;
28 |
29 | public Integer getId() {
30 | return id;
31 | }
32 |
33 | public void setId(Integer id) {
34 | this.id = id;
35 | }
36 |
37 | public Integer getSingerId() {
38 | return singerId;
39 | }
40 |
41 | public void setSingerId(Integer singerId) {
42 | this.singerId = singerId;
43 | }
44 |
45 | public String getName() {
46 | return name;
47 | }
48 |
49 | public void setName(String name) {
50 | this.name = name;
51 | }
52 |
53 | public String getIntroduction() {
54 | return introduction;
55 | }
56 |
57 | public void setIntroduction(String introduction) {
58 | this.introduction = introduction;
59 | }
60 |
61 | public Date getCreateTime() {
62 | return createTime;
63 | }
64 |
65 | public void setCreateTime(Date createTime) {
66 | this.createTime = createTime;
67 | }
68 |
69 | public Date getUpdateTime() {
70 | return updateTime;
71 | }
72 |
73 | public void setUpdateTime(Date updateTime) {
74 | this.updateTime = updateTime;
75 | }
76 |
77 | public String getPic() {
78 | return pic;
79 | }
80 |
81 | public void setPic(String pic) {
82 | this.pic = pic;
83 | }
84 |
85 | public String getLyric() {
86 | return lyric;
87 | }
88 |
89 | public void setLyric(String lyric) {
90 | this.lyric = lyric;
91 | }
92 |
93 | public String getUrl() {
94 | return url;
95 | }
96 |
97 | public void setUrl(String url) {
98 | this.url = url;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/config/FileConfig.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.config;
2 |
3 | import org.springframework.context.annotation.Configuration;
4 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
5 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
6 |
7 | /**
8 | * 定位各种文件或头像地址
9 | */
10 | @Configuration
11 | public class FileConfig implements WebMvcConfigurer {
12 |
13 | @Override
14 | public void addResourceHandlers(ResourceHandlerRegistry registry) {
15 | //歌手头像地址
16 | registry.addResourceHandler("/img/singerPic/**").addResourceLocations(
17 | "file:" + System.getProperty("user.dir") + System.getProperty("file.separator") + "img"
18 | + System.getProperty("file.separator") + "singerPic" + System.getProperty("file.separator")
19 | );
20 | //歌单图片地址
21 | registry.addResourceHandler("/img/songListPic/**").addResourceLocations(
22 | "file:" + System.getProperty("user.dir") + System.getProperty("file.separator") + "img"
23 | + System.getProperty("file.separator") + "songListPic" + System.getProperty("file.separator")
24 | );
25 | //歌曲图片地址
26 | registry.addResourceHandler("/img/songPic/**").addResourceLocations(
27 | "file:" + System.getProperty("user.dir") + System.getProperty("file.separator") + "img"
28 | + System.getProperty("file.separator") + "songPic" + System.getProperty("file.separator")
29 | );
30 | //歌曲地址
31 | registry.addResourceHandler("/song/**").addResourceLocations(
32 | "file:" + System.getProperty("user.dir") + System.getProperty("file.separator") + "song" + System.getProperty("file.separator")
33 | );
34 | //前端用户头像地址
35 | registry.addResourceHandler("/avatorImages/**").addResourceLocations(
36 | "file:" + System.getProperty("user.dir") + System.getProperty("file.separator") + "avatorImages" + System.getProperty("file.separator")
37 | );
38 | //用户头像默认地址
39 | registry.addResourceHandler("/img/**").addResourceLocations(
40 | "file:" + System.getProperty("user.dir") + System.getProperty("file.separator") + "img" + System.getProperty("file.separator")
41 | );
42 | }
43 | }
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/music-client/src/assets/data/form.js:
--------------------------------------------------------------------------------
1 | // 匹配规则
2 | const rules = {
3 | username: [
4 | {required: true, trigger: 'blur'}
5 | ],
6 | password: [
7 | {required: true, trigger: 'blur'}
8 | ],
9 | sex: [
10 | {required: true, message: '请选择性别', trigger: 'change'}
11 | ],
12 | phoneNum: [
13 | {essage: '请选择日期', trigger: 'blur'}
14 | ],
15 | email: [
16 | {message: '请输入邮箱地址', trigger: 'blur'},
17 | {type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change']}
18 | ],
19 | birth: [
20 | {required: true, type: 'date', message: '请选择日期', trigger: 'change'}
21 | ],
22 | introduction: [
23 | {message: '请输入介绍', trigger: 'blur'}
24 | ],
25 | location: [
26 | {message: '请输入地区', trigger: 'change'}
27 | ]
28 | }
29 |
30 | // 地区选择
31 | const cities = [{
32 | value: '北京',
33 | label: '北京'
34 | }, {
35 | value: '天津',
36 | label: '天津'
37 | }, {
38 | value: '河北',
39 | label: '河北'
40 | }, {
41 | value: '山西',
42 | label: '山西'
43 | }, {
44 | value: '内蒙古',
45 | label: '内蒙古'
46 | }, {
47 | value: '辽宁',
48 | label: '辽宁'
49 | }, {
50 | value: '吉林',
51 | label: '吉林'
52 | }, {
53 | value: '黑龙江',
54 | label: '黑龙江'
55 | }, {
56 | value: '上海',
57 | label: '上海'
58 | }, {
59 | value: '江苏',
60 | label: '江苏'
61 | }, {
62 | value: '浙江',
63 | label: '浙江'
64 | }, {
65 | value: '安徽',
66 | label: '安徽'
67 | }, {
68 | value: '福建',
69 | label: '福建'
70 | }, {
71 | value: '江西',
72 | label: '江西'
73 | }, {
74 | value: '山东',
75 | label: '山东'
76 | }, {
77 | value: '河南',
78 | label: '河南'
79 | }, {
80 | value: '湖北',
81 | label: '湖北'
82 | }, {
83 | value: '湖南',
84 | label: '湖南'
85 | }, {
86 | value: '广东',
87 | label: '广东'
88 | }, {
89 | value: '广西',
90 | label: '广西'
91 | }, {
92 | value: '海南',
93 | label: '海南'
94 | }, {
95 | value: '重庆',
96 | label: '重庆'
97 | }, {
98 | value: '四川',
99 | label: '四川'
100 | }, {
101 | value: '贵州',
102 | label: '贵州'
103 | }, {
104 | value: '云南',
105 | label: '云南'
106 | }, {
107 | value: '西藏',
108 | label: '西藏'
109 | }, {
110 | value: '陕西',
111 | label: '陕西'
112 | }, {
113 | value: '甘肃',
114 | label: '甘肃'
115 | }, {
116 | value: '青海',
117 | label: '青海'
118 | }, {
119 | value: '宁夏',
120 | label: '宁夏'
121 | }, {
122 | value: '新疆',
123 | label: '新疆'
124 | }, {
125 | value: '香港',
126 | label: '香港'
127 | }, {
128 | value: '澳门',
129 | label: '澳门'
130 | }, {
131 | value: '台湾',
132 | label: '台湾'
133 | }]
134 |
135 | export {
136 | rules,
137 | cities
138 | }
139 |
--------------------------------------------------------------------------------
/music-client/src/pages/SingerAlbum.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
![]()
6 |
7 |
8 | - {{attachSex(singer.sex)}}
9 | - 生日:{{attachBirth(singer.birth)}}
10 | - 故乡:{{singer.location}}
11 |
12 |
13 |
14 |
15 |
{{singer.name}}
16 | {{singer.introduction}}
17 |
18 |
23 |
24 |
25 |
26 |
79 |
80 |
83 |
--------------------------------------------------------------------------------
/music-client/src/assets/js/iconfont1.js:
--------------------------------------------------------------------------------
1 | !function(d){var t,n='',e=(t=document.getElementsByTagName("script"))[t.length-1].getAttribute("data-injectcss");if(e&&!d.__iconfont__svg__cssinject__){d.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(t){console&&console.log(t)}}!function(t){if(document.addEventListener)if(~["complete","loaded","interactive"].indexOf(document.readyState))setTimeout(t,0);else{var e=function(){document.removeEventListener("DOMContentLoaded",e,!1),t()};document.addEventListener("DOMContentLoaded",e,!1)}else document.attachEvent&&(n=t,i=d.document,o=!1,l=function(){o||(o=!0,n())},(c=function(){try{i.documentElement.doScroll("left")}catch(t){return void setTimeout(c,50)}l()})(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,l())});var n,i,o,l,c}(function(){var t,e;(t=document.createElement("div")).innerHTML=n,n=null,(e=t.getElementsByTagName("svg")[0])&&(e.setAttribute("aria-hidden","true"),e.style.position="absolute",e.style.width=0,e.style.height=0,e.style.overflow="hidden",function(t,e){e.firstChild?function(t,e){e.parentNode.insertBefore(t,e)}(t,e.firstChild):e.appendChild(t)}(e,document.body))})}(window);
--------------------------------------------------------------------------------
/music-client/src/api/index.js:
--------------------------------------------------------------------------------
1 | import Axios from "axios";
2 | import {get, post} from "./http";
3 |
4 | //============歌手相关================
5 | //查询歌手
6 | export const getAllSinger = () => get(`singer/allSinger`);
7 | //根据性别查询歌手
8 | export const getSingerOfSex = (sex) => get(`singer/singerOfSex?sex=${sex}`);
9 |
10 | //============歌曲相关================
11 | //根据歌手id查询歌曲
12 | export const songOfSingerId = (id) => get(`song/singer/detail?singerId=${id}`);
13 | //根据歌曲id查询歌曲对象
14 | export const songOfSongId = (id) => get(`song/detail?songId=${id}`);
15 | //根据歌手名字模糊查询歌曲
16 | export const likeSongOfName = (keywords) => get(`song/likeSongOfName?songName=${keywords}`);
17 |
18 | //============歌单相关================
19 | //查询歌单
20 | export const getAllSongList = () => get(`songList/allSongList`);
21 | //返回标题包含文字的歌单列表
22 | export const getSongListOfLikeTitle = (keywords) => get(`songList/likeTitle?title=${keywords}`);
23 | //根据风格模糊查询歌单列表
24 | export const getSongListOfLikeStyle = (style) => get(`songList/likeStyle?style=${style}`);
25 |
26 |
27 | //============歌单的歌曲相关============
28 | //根据歌单id查询歌曲列表
29 | export const listSongDetail = (songListId) => get(`listSong/detail?songListId=${songListId}`);
30 |
31 | //============用户相关================
32 | //查询用户
33 | export const getAllConsumer = () => get(`consumer/allConsumer`);
34 | //注册
35 | export const SignUp = (params) => post(`/consumer/add`, params);
36 | //登录
37 | export const loginIn = (params) => post(`/consumer/login`, params);
38 | //根据用户id查询该用户的详细信息
39 | export const getUserOfId = (id) => get(`/consumer/selectByPrimaryKey?id=${id}`);
40 | //更新用户信息
41 | export const updateUserMsg = (params) => post(`/consumer/update`, params);
42 |
43 | //下载音乐
44 | export const download = (url) => Axios({
45 | method: 'get',
46 | url: url,
47 | responseType: 'blob'
48 | });
49 |
50 | //===========评价======================
51 | //提交评分
52 | export const setRank = (params) => post(`/rank/add`, params);
53 | //获取指定歌单的平均分
54 | export const getRankOfSongListId = (songListId) => get(`/rank?songListId=${songListId}`);
55 |
56 | //===========评论======================
57 | //提交评论
58 | export const setComment = (params) => post(`/comment/add`, params);
59 | //点赞
60 | export const setLike = (params) => post(`/comment/like`, params);
61 | //返回当前歌单或歌曲的评论列表
62 | export const getAllComment = (type, id) => {
63 | if (type == 0) { //歌曲
64 | return get(`/comment/commentOfSongId?songId=${id}`);
65 | } else { //歌单
66 | return get(`/comment/commentOfSongListId?songListId=${id}`);
67 | }
68 | }
69 |
70 | //===============收藏===================
71 | //新增收藏
72 | export const setCollect = (params) => post(`/collect/add`, params);
73 | //指定用户的收藏列表
74 | export const getCollectOfUserId = (userId) => get(`/collect/collectOfUserId?userId=${userId}`);
75 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/controller/ListSongController.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.controller;
2 |
3 | import com.alibaba.fastjson.JSONObject;
4 | import com.xusheng.music.domain.ListSong;
5 | import com.xusheng.music.service.ListSongService;
6 | import com.xusheng.music.utils.Consts;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.web.bind.annotation.RequestMapping;
9 | import org.springframework.web.bind.annotation.RequestMethod;
10 | import org.springframework.web.bind.annotation.RestController;
11 |
12 | import javax.servlet.http.HttpServletRequest;
13 |
14 | /**
15 | * 歌单的歌曲管理controller
16 | */
17 | @RestController
18 | @RequestMapping("/listSong")
19 | public class ListSongController {
20 |
21 | @Autowired
22 | private ListSongService listSongService;
23 |
24 | /**
25 | * 给歌单添加歌曲
26 | */
27 | @RequestMapping(value = "/add", method = RequestMethod.POST)
28 | public Object addListSong(HttpServletRequest request) {
29 | JSONObject jsonObject = new JSONObject();
30 | //获取前端传来的参数
31 | String songId = request.getParameter("songId").trim(); //歌曲id
32 | String songListId = request.getParameter("songListId").trim(); //歌单id
33 | ListSong listSong = new ListSong();
34 | listSong.setSongId(Integer.parseInt(songId));
35 | listSong.setSongListId(Integer.parseInt(songListId));
36 | boolean flag = listSongService.insert(listSong);
37 | if (flag) {
38 | jsonObject.put(Consts.CODE, 1);
39 | jsonObject.put(Consts.MSG, "保存成功");
40 | return jsonObject;
41 | }
42 | jsonObject.put(Consts.CODE, 0);
43 | jsonObject.put(Consts.MSG, "保存失败");
44 | return jsonObject;
45 |
46 | }
47 |
48 | /**
49 | * 根据歌单id查询歌曲
50 | */
51 | @RequestMapping(value = "/detail", method = RequestMethod.GET)
52 | public Object detail(HttpServletRequest request) {
53 | String songListId = request.getParameter("songListId");
54 | return listSongService.listSongOfSongListId(Integer.parseInt(songListId));
55 | }
56 |
57 | /**
58 | * 删除歌单里的歌曲
59 | */
60 | @RequestMapping(value = "/delete", method = RequestMethod.GET)
61 | public Object delete(HttpServletRequest request) {
62 | String songId = request.getParameter("songId").trim(); //歌曲id
63 | String songListId = request.getParameter("songListId").trim(); //歌单id
64 | boolean flag = listSongService.deleteBySongIdAndSongListId(Integer.parseInt(songId), Integer.parseInt(songListId));
65 | return flag;
66 | }
67 |
68 | }
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/music-client/build/webpack.base.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const utils = require('./utils')
4 | const config = require('../config')
5 | const vueLoaderConfig = require('./vue-loader.conf')
6 |
7 | function resolve(dir) {
8 | return path.join(__dirname, '..', dir)
9 | }
10 |
11 | const createLintingRule = () => ({
12 | test: /\.(js|vue)$/,
13 | loader: 'eslint-loader',
14 | enforce: 'pre',
15 | include: [resolve('src'), resolve('test')],
16 | options: {
17 | formatter: require('eslint-friendly-formatter'),
18 | emitWarning: !config.dev.showEslintErrorsInOverlay
19 | }
20 | })
21 |
22 | module.exports = {
23 | context: path.resolve(__dirname, '../'),
24 | entry: {
25 | app: './src/main.js'
26 | },
27 | output: {
28 | path: config.build.assetsRoot,
29 | filename: '[name].js',
30 | publicPath: process.env.NODE_ENV === 'production'
31 | ? config.build.assetsPublicPath
32 | : config.dev.assetsPublicPath
33 | },
34 | resolve: {
35 | extensions: ['.js', '.vue', '.json'],
36 | alias: {
37 | 'vue$': 'vue/dist/vue.esm.js',
38 | '@': resolve('src'),
39 | }
40 | },
41 | module: {
42 | rules: [
43 | // ...(config.dev.useEslint ? [createLintingRule()] : []),
44 | {
45 | test: /\.vue$/,
46 | loader: 'vue-loader',
47 | options: vueLoaderConfig
48 | },
49 | {
50 | test: /\.js$/,
51 | loader: 'babel-loader',
52 | include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
53 | },
54 | {
55 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
56 | loader: 'url-loader',
57 | options: {
58 | limit: 10000,
59 | name: utils.assetsPath('img/[name].[hash:7].[ext]')
60 | }
61 | },
62 | {
63 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
64 | loader: 'url-loader',
65 | options: {
66 | limit: 10000,
67 | name: utils.assetsPath('media/[name].[hash:7].[ext]')
68 | }
69 | },
70 | {
71 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
72 | loader: 'url-loader',
73 | options: {
74 | limit: 10000,
75 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
76 | }
77 | }
78 | ]
79 | },
80 | node: {
81 | // prevent webpack from injecting useless setImmediate polyfill because Vue
82 | // source contains it (although only uses it if it's native).
83 | setImmediate: false,
84 | // prevent webpack from injecting mocks to Node native modules
85 | // that does not make sense for the client
86 | dgram: 'empty',
87 | fs: 'empty',
88 | net: 'empty',
89 | tls: 'empty',
90 | child_process: 'empty'
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/music-client/src/pages/Singer.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
16 |
17 |
18 |
19 |
85 |
86 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/play-bar.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 | @import "global.scss";
3 |
4 | .play-bar {
5 | position: fixed;
6 | bottom: 0;
7 | width: 100%;
8 | transition: all 0.5s;
9 | @include box-shadow($box-shadow);
10 |
11 | .item-up {
12 | position: absolute;
13 | bottom: $play-bar-height + 10px;
14 | left: 20px;
15 | cursor: pointer;
16 | }
17 |
18 | .kongjian {
19 | @include layout(center, center);
20 | bottom: 0;
21 | height: $play-bar-height;
22 | width: 100%;
23 | min-width: 1000px;
24 | background-color: $theme-play-bar-color;
25 |
26 | .item {
27 | position: relative;
28 | width: 80px;
29 | height: 50px;
30 | line-height: 60px;
31 | text-align: center;
32 | cursor: pointer;
33 |
34 | .icon.active {
35 | color: red !important;
36 | }
37 |
38 | .volume {
39 | position: absolute;
40 | display: none;
41 | height: 100px;
42 | top: -($play-bar-height + 50px);
43 | right: 22px;
44 | }
45 |
46 | .show-volume {
47 | display: block;
48 | }
49 | }
50 |
51 | .item-img {
52 | width: $play-bar-height;
53 | height: $play-bar-height;
54 |
55 | img {
56 | width: 100%;
57 | }
58 | }
59 |
60 | .playing-speed {
61 | // 进度条
62 | height: 50px;
63 | width: 900px;
64 | @include layout(center, center);
65 |
66 | .current-time,
67 | .left-time {
68 | width: 70px;
69 | text-align: center;
70 | font-size: 13px;
71 | color: $color-black;
72 | font-weight: 500;
73 | top: -10px;
74 | }
75 |
76 | .progress-box {
77 | flex: 1;
78 |
79 | .item-song-title {
80 | @include layout(space-between);
81 | height: 20px;
82 | line-height: 10px;
83 | }
84 |
85 | .progress {
86 | width: 100%;
87 | background: $color-blue-shallow;
88 | height: 6px;
89 |
90 | .bg {
91 | height: 100%;
92 |
93 | .cur-progress {
94 | height: 100%;
95 | background: $color-blue-active;
96 | }
97 | }
98 |
99 | .idot {
100 | width: 16px;
101 | height: 16px;
102 | position: relative;
103 | border-radius: 50%;
104 | background-color: $color-black;
105 | top: -11px;
106 | vertical-align: middle;
107 | }
108 | }
109 | }
110 | }
111 | }
112 | }
113 |
114 | .turn {
115 | transform: rotate(180deg);
116 | }
117 |
118 | .show {
119 | bottom: -($play-bar-height);
120 | }
121 |
122 | .icon {
123 | @include icon(1.2em, $color-black);
124 | }
125 |
--------------------------------------------------------------------------------
/music-client/src/pages/SongList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
16 |
17 |
18 |
19 |
85 |
86 |
--------------------------------------------------------------------------------
/music-server/src/main/java/com/xusheng/music/domain/Consumer.java:
--------------------------------------------------------------------------------
1 | package com.xusheng.music.domain;
2 |
3 | import java.util.Date;
4 |
5 | /**
6 | * 前端用户
7 | */
8 | public class Consumer {
9 | /*主键*/
10 | private Integer id;
11 | /*账号*/
12 | private String username;
13 | /*密码*/
14 | private String password;
15 | /*性别*/
16 | private Byte sex;
17 | /*手机号*/
18 | private String phoneNum;
19 | /*电子邮箱*/
20 | private String email;
21 | /*生日*/
22 | private Date birth;
23 | /*签名*/
24 | private String introduction;
25 | /*地区*/
26 | private String location;
27 | /*头像*/
28 | private String avator;
29 | /*创建时间*/
30 | private Date createTime;
31 | /*更新时间*/
32 | private Date updateTime;
33 |
34 | public Integer getId() {
35 | return id;
36 | }
37 |
38 | public void setId(Integer id) {
39 | this.id = id;
40 | }
41 |
42 | public String getUsername() {
43 | return username;
44 | }
45 |
46 | public void setUsername(String username) {
47 | this.username = username;
48 | }
49 |
50 | public String getPassword() {
51 | return password;
52 | }
53 |
54 | public void setPassword(String password) {
55 | this.password = password;
56 | }
57 |
58 | public Byte getSex() {
59 | return sex;
60 | }
61 |
62 | public void setSex(Byte sex) {
63 | this.sex = sex;
64 | }
65 |
66 | public String getPhoneNum() {
67 | return phoneNum;
68 | }
69 |
70 | public void setPhoneNum(String phoneNum) {
71 | this.phoneNum = phoneNum;
72 | }
73 |
74 | public String getEmail() {
75 | return email;
76 | }
77 |
78 | public void setEmail(String email) {
79 | this.email = email;
80 | }
81 |
82 | public Date getBirth() {
83 | return birth;
84 | }
85 |
86 | public void setBirth(Date birth) {
87 | this.birth = birth;
88 | }
89 |
90 | public String getIntroduction() {
91 | return introduction;
92 | }
93 |
94 | public void setIntroduction(String introduction) {
95 | this.introduction = introduction;
96 | }
97 |
98 | public String getLocation() {
99 | return location;
100 | }
101 |
102 | public void setLocation(String location) {
103 | this.location = location;
104 | }
105 |
106 | public String getAvator() {
107 | return avator;
108 | }
109 |
110 | public void setAvator(String avator) {
111 | this.avator = avator;
112 | }
113 |
114 | public Date getCreateTime() {
115 | return createTime;
116 | }
117 |
118 | public void setCreateTime(Date createTime) {
119 | this.createTime = createTime;
120 | }
121 |
122 | public Date getUpdateTime() {
123 | return updateTime;
124 | }
125 |
126 | public void setUpdateTime(Date updateTime) {
127 | this.updateTime = updateTime;
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/music-client/build/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const config = require('../config')
4 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
5 | const packageConfig = require('../package.json')
6 |
7 | exports.assetsPath = function (_path) {
8 | const assetsSubDirectory = process.env.NODE_ENV === 'production'
9 | ? config.build.assetsSubDirectory
10 | : config.dev.assetsSubDirectory
11 |
12 | return path.posix.join(assetsSubDirectory, _path)
13 | }
14 |
15 | exports.cssLoaders = function (options) {
16 | options = options || {}
17 |
18 | const cssLoader = {
19 | loader: 'css-loader',
20 | options: {
21 | sourceMap: options.sourceMap
22 | }
23 | }
24 |
25 | const postcssLoader = {
26 | loader: 'postcss-loader',
27 | options: {
28 | sourceMap: options.sourceMap
29 | }
30 | }
31 |
32 | // generate loader string to be used with extract text plugin
33 | function generateLoaders(loader, loaderOptions) {
34 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
35 |
36 | if (loader) {
37 | loaders.push({
38 | loader: loader + '-loader',
39 | options: Object.assign({}, loaderOptions, {
40 | sourceMap: options.sourceMap
41 | })
42 | })
43 | }
44 |
45 | // Extract CSS when that option is specified
46 | // (which is the case during production build)
47 | if (options.extract) {
48 | return ExtractTextPlugin.extract({
49 | use: loaders,
50 | fallback: 'vue-style-loader'
51 | })
52 | } else {
53 | return ['vue-style-loader'].concat(loaders)
54 | }
55 | }
56 |
57 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html
58 | return {
59 | css: generateLoaders(),
60 | postcss: generateLoaders(),
61 | less: generateLoaders('less'),
62 | sass: generateLoaders('sass', {indentedSyntax: true}),
63 | scss: generateLoaders('sass'),
64 | stylus: generateLoaders('stylus'),
65 | styl: generateLoaders('stylus')
66 | }
67 | }
68 |
69 | // Generate loaders for standalone style files (outside of .vue)
70 | exports.styleLoaders = function (options) {
71 | const output = []
72 | const loaders = exports.cssLoaders(options)
73 |
74 | for (const extension in loaders) {
75 | const loader = loaders[extension]
76 | output.push({
77 | test: new RegExp('\\.' + extension + '$'),
78 | use: loader
79 | })
80 | }
81 |
82 | return output
83 | }
84 |
85 | exports.createNotifierCallback = () => {
86 | const notifier = require('node-notifier')
87 |
88 | return (severity, errors) => {
89 | if (severity !== 'error') return
90 |
91 | const error = errors[0]
92 | const filename = error.file && error.file.split('!').pop()
93 |
94 | notifier.notify({
95 | title: packageConfig.name,
96 | message: severity + ': ' + error.name,
97 | subtitle: filename || '',
98 | icon: path.join(__dirname, 'logo.png')
99 | })
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/music-server/src/main/resources/mapper/ListSongMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | id,song_id,song_list_id
14 |
15 |
16 |
17 | insert into list_song
18 |
19 |
20 | id,
21 |
22 |
23 | song_id,
24 |
25 |
26 | song_list_id,
27 |
28 |
29 |
30 |
31 | #{id},
32 |
33 |
34 | #{songId},
35 |
36 |
37 | #{songListId},
38 |
39 |
40 |
41 |
42 |
43 | update list_song
44 |
45 |
46 | song_id = #{songId},
47 |
48 |
49 | song_list_id = #{songListId},
50 |
51 |
52 | where id = #{id}
53 |
54 |
55 |
56 | delete from list_song
57 | where id=#{id}
58 |
59 |
60 |
61 | delete from list_song
62 | where song_id=#{songId} and song_list_id=#{songListId}
63 |
64 |
65 |
71 |
72 |
77 |
78 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/music-server/src/main/resources/mapper/CollectMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | id,user_id,type,song_id,song_list_id,create_time
17 |
18 |
19 |
20 | insert into collect
21 |
22 |
23 | id,
24 |
25 |
26 | user_id,
27 |
28 |
29 | type,
30 |
31 |
32 | song_id,
33 |
34 |
35 | song_list_id,
36 |
37 | create_time,
38 |
39 |
40 |
41 | #{id},
42 |
43 |
44 | #{userId},
45 |
46 |
47 | #{type},
48 |
49 |
50 | #{songId},
51 |
52 |
53 | #{songListId},
54 |
55 | now(),
56 |
57 |
58 |
59 |
60 | delete from collect
61 | where id=#{id}
62 |
63 |
64 |
65 | delete from collect
66 | where user_id = #{userId} and song_id = #{songId}
67 |
68 |
69 |
74 |
75 |
81 |
82 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/music-client/build/webpack.dev.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const webpack = require('webpack')
4 | const config = require('../config')
5 | const merge = require('webpack-merge')
6 | const path = require('path')
7 | const baseWebpackConfig = require('./webpack.base.conf')
8 | const CopyWebpackPlugin = require('copy-webpack-plugin')
9 | const HtmlWebpackPlugin = require('html-webpack-plugin')
10 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
11 | const portfinder = require('portfinder')
12 |
13 | const HOST = process.env.HOST
14 | const PORT = process.env.PORT && Number(process.env.PORT)
15 |
16 | const devWebpackConfig = merge(baseWebpackConfig, {
17 | module: {
18 | rules: utils.styleLoaders({sourceMap: config.dev.cssSourceMap, usePostCSS: true})
19 | },
20 | // cheap-module-eval-source-map is faster for development
21 | devtool: config.dev.devtool,
22 |
23 | // these devServer options should be customized in /config/index.js
24 | devServer: {
25 | clientLogLevel: 'warning',
26 | historyApiFallback: {
27 | rewrites: [
28 | {from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html')},
29 | ],
30 | },
31 | hot: true,
32 | contentBase: false, // since we use CopyWebpackPlugin.
33 | compress: true,
34 | host: HOST || config.dev.host,
35 | port: PORT || config.dev.port,
36 | open: config.dev.autoOpenBrowser,
37 | overlay: config.dev.errorOverlay
38 | ? {warnings: false, errors: true}
39 | : false,
40 | publicPath: config.dev.assetsPublicPath,
41 | proxy: config.dev.proxyTable,
42 | quiet: true, // necessary for FriendlyErrorsPlugin
43 | disableHostCheck: true,
44 | watchOptions: {
45 | poll: config.dev.poll,
46 | }
47 | },
48 | plugins: [
49 | new webpack.DefinePlugin({
50 | 'process.env': require('../config/dev.env')
51 | }),
52 | new webpack.HotModuleReplacementPlugin(),
53 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
54 | new webpack.NoEmitOnErrorsPlugin(),
55 | // https://github.com/ampedandwired/html-webpack-plugin
56 | new HtmlWebpackPlugin({
57 | filename: 'index.html',
58 | template: 'index.html',
59 | inject: true
60 | }),
61 | // copy custom static assets
62 | new CopyWebpackPlugin([
63 | {
64 | from: path.resolve(__dirname, '../static'),
65 | to: config.dev.assetsSubDirectory,
66 | ignore: ['.*']
67 | }
68 | ])
69 | ]
70 | })
71 |
72 | module.exports = new Promise((resolve, reject) => {
73 | portfinder.basePort = process.env.PORT || config.dev.port
74 | portfinder.getPort((err, port) => {
75 | if (err) {
76 | reject(err)
77 | } else {
78 | // publish the new Port, necessary for e2e tests
79 | process.env.PORT = port
80 | // add port to devServer config
81 | devWebpackConfig.devServer.port = port
82 |
83 | // Add FriendlyErrorsPlugin
84 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
85 | compilationSuccessInfo: {
86 | messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
87 | },
88 | onErrors: config.dev.notifyOnErrors
89 | ? utils.createNotifierCallback()
90 | : undefined
91 | }))
92 |
93 | resolve(devWebpackConfig)
94 | }
95 | })
96 | })
97 |
--------------------------------------------------------------------------------
/music-server/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.3.3.RELEASE
9 |
10 |
11 | com.xusheng
12 | music
13 | 0.0.1-SNAPSHOT
14 | music
15 | 音乐网站
16 |
17 |
18 | 1.8
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-web
25 |
26 |
27 |
28 | org.mybatis.spring.boot
29 | mybatis-spring-boot-starter
30 | 2.1.3
31 |
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-devtools
36 | runtime
37 | true
38 |
39 |
40 | mysql
41 | mysql-connector-java
42 | runtime
43 |
44 |
45 |
46 | com.alibaba
47 | druid
48 | 1.1.10
49 |
50 |
51 |
52 | org.springframework.boot
53 | spring-boot-starter-jdbc
54 |
55 |
56 |
57 | org.apache.commons
58 | commons-lang3
59 |
60 |
61 |
62 | com.alibaba
63 | fastjson
64 | 1.2.47
65 |
66 |
67 |
68 | org.springframework.boot
69 | spring-boot-starter-test
70 | test
71 |
72 |
73 | org.junit.vintage
74 | junit-vintage-engine
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | org.springframework.boot
84 | spring-boot-maven-plugin
85 | 2.3.3.RELEASE
86 |
87 | true
88 | true
89 |
90 |
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/music-client/src/assets/css/the-header.scss:
--------------------------------------------------------------------------------
1 | @import "var.scss";
2 | @import "global.scss";
3 |
4 | .the-header {
5 | position: fixed;
6 | @include layout;
7 | width: 100%;
8 | height: $header-height;
9 | line-height: $header-height;
10 | padding: $header-padding;
11 | margin: $header-margin;
12 | background-color: $theme-header-color;
13 | @include box-shadow($box-shadow);
14 | box-sizing: border-box;
15 | z-index: 100;
16 | }
17 |
18 | .header-logo {
19 | margin: $header-logo-margin;
20 | font-size: $font-size-logo;
21 | font-weight: bold;
22 | white-space: nowrap;
23 | cursor: pointer;
24 |
25 | .icon {
26 | @include icon(($header-height / 3) * 2, $color-black);
27 | vertical-align: middle;
28 | }
29 | }
30 |
31 | /*nav*/
32 | .navbar {
33 | height: $header-height;
34 | white-space: nowrap;
35 |
36 | li {
37 | margin: $header-nav-margin;
38 | padding: $header-nav-padding;
39 | font-size: $font-size-header;
40 | color: $color-grey;
41 | text-align: center;
42 | border-bottom: none;
43 | box-sizing: border-box;
44 | cursor: pointer;
45 | }
46 | }
47 |
48 | /*搜索*/
49 | .header-search {
50 | @include layout;
51 | border-radius: $header-search-radius;
52 | overflow: hidden;
53 |
54 | input {
55 | height: $header-search-height;
56 | width: $header-search-width;
57 | font-size: $font-size-default;
58 | border: 0;
59 | text-indent: 10px;
60 | background-color: $color-light-grey;
61 |
62 | &:focus {
63 | outline: none;
64 | }
65 | }
66 |
67 | .search-btn {
68 | @include layout(center, center);
69 | background-color: $color-blue-active;
70 | width: $header-search-btn-width;
71 | height: $header-search-btn-height;
72 | cursor: pointer;
73 |
74 | .icon {
75 | @include icon(1.2em, $color-white);
76 | }
77 | }
78 | }
79 |
80 | /*用户*/
81 | .header-right {
82 | position: relative;
83 | @include layout(center, center);
84 |
85 | #user {
86 | overflow: hidden;
87 | width: $header-user-width;
88 | height: $header-user-height;
89 | border-radius: $header-user-radius;
90 | margin: $header-user-margin;
91 | cursor: pointer;
92 |
93 | img {
94 | width: 100%;
95 | }
96 | }
97 | }
98 |
99 | .menu {
100 | display: none;
101 | line-height: 0px;
102 | position: absolute;
103 | background-color: $color-white;
104 | @include box-shadow(1px 1px 10px rgba(0, 0, 0, 0.4));
105 | width: $header-menu-width;
106 | padding: $header-menu-padding;
107 | border-radius: $header-menu-radius;
108 | top: $header-height + 10px;
109 | right: -20px;
110 | z-index: 5;
111 | text-align: center;
112 | cursor: pointer;
113 |
114 | li {
115 | display: inline-block;
116 | width: 100%;
117 | height: 40px;
118 | line-height: 40px;
119 |
120 | &:hover {
121 | background-color: $theme-color;
122 | color: $color-white;
123 | }
124 | }
125 |
126 | :nth-child(1):before {
127 | content: " ";
128 | display: block; /*独占一行*/
129 | position: absolute;
130 | right: 45px;
131 | top: -5px; /*果断的露出上半部分*/
132 | width: 10px;
133 | height: 10px;
134 | background-color: $color-white;
135 | /*一个正方形倾斜四十五度就是三角了但是要把下半部分藏起来*/
136 | transform: rotate(45deg);
137 | }
138 |
139 | // :nth-child(1):hover:before {
140 | // background-color: $theme-color;
141 | // }
142 | }
143 |
144 | .show {
145 | display: block;
146 | }
147 |
148 | .active {
149 | color: $theme-color !important;
150 | border-bottom: 5px solid $theme-color !important;
151 | }
152 |
--------------------------------------------------------------------------------
/music-client/src/mixins/index.js:
--------------------------------------------------------------------------------
1 | import {mapGetters} from 'vuex';
2 | import {likeSongOfName, getCollectOfUserId} from '../api/index';
3 |
4 | export const mixin = {
5 | computed: {
6 | ...mapGetters([
7 | 'loginIn', //用户是否已登录
8 | 'userId', //当前登录用户的id
9 | ])
10 | },
11 | methods: {
12 | //提示信息
13 | notify(title, type) {
14 | this.$notify({
15 | title: title,
16 | type: type
17 | })
18 | },
19 |
20 | //获取图片地址
21 | attachImageUrl(srcUrl) {
22 | return srcUrl ? this.$store.state.configure.HOST + srcUrl : this.$store.state.configure.HOST + '/img/user.jpg';
23 | },
24 | //根据歌手名字模糊查询歌曲
25 | getSong() {
26 | if (!this.$route.query.keywords) {
27 | this.$store.commit('setListOfSongs', []);
28 | this.notify('您输入的内容为空', 'warning');
29 | } else {
30 | likeSongOfName(this.$route.query.keywords).then(res => {
31 | if (!res.length) {
32 | this.$store.commit('setListOfSongs', []);
33 | this.notify('系统暂无符合条件的歌曲', 'warning');
34 | } else {
35 | this.$store.commit('setListOfSongs', res);
36 | }
37 | }).catch(err => {
38 | console.log(err)
39 | })
40 | }
41 | },
42 | //获取名字前半部分--歌手名
43 | replaceLName(str) {
44 | let arr = str.split('-');
45 | return arr[0];
46 | },
47 | //获取名字后半部分--歌名
48 | replaceFName(str) {
49 | let arr = str.split('-');
50 | return arr[1];
51 | },
52 | //播放
53 | toplay: function (id, url, pic, index, name, lyric) {
54 | this.$store.commit('setId', id);
55 | this.$store.commit('setUrl', this.$store.state.configure.HOST + url);
56 | this.$store.commit('setPicUrl', this.$store.state.configure.HOST + pic);
57 | this.$store.commit('setListIndex', index);
58 | this.$store.commit('setTitle', this.replaceFName(name));
59 | this.$store.commit('setArtist', this.replaceLName(name));
60 | this.$store.commit('setLyric', this.parseLyric(lyric));
61 | this.$store.commit('setIsActive', false);
62 | if (this.loginIn) {
63 | getCollectOfUserId(this.userId)
64 | .then(res => {
65 | for (let item of res) {
66 | if (item.songId == id) {
67 | this.$store.commit('setIsActive', true);
68 | break;
69 | }
70 | }
71 | })
72 | }
73 | },
74 | //解析歌词
75 | parseLyric(text) {
76 | let lines = text.split("\n"); //将歌词按行分解成数组
77 | let pattern = /\[\d{2}:\d{2}.(\d{3}|\d{2})\]/g; //时间格式的正则表达式
78 | let result = []; //返回值
79 | //对于歌词格式不对的直接返回
80 | if (!(/\[.+\]/.test(text))) {
81 | return [[0, text]]
82 | }
83 | //去掉前面格式不正确的行
84 | while (!pattern.test(lines[0])) {
85 | lines = lines.slice(1);
86 | }
87 | //遍历每一行,形成一个每行带着俩元素的数组,第一个元素是以秒为计算单位的时间,第二个元素是歌词
88 | for (let item of lines) {
89 | let time = item.match(pattern); //存前面的时间段
90 | let value = item.replace(pattern, '');//存后面的歌词
91 | for (let item1 of time) {
92 | let t = item1.slice(1, -1).split(":"); //取出时间,换算成数组
93 | if (value != '') {
94 | result.push([parseInt(t[0], 10) * 60 + parseFloat(t[1]), value]);
95 | }
96 | }
97 | }
98 | //按照第一个元素--时间--排序
99 | result.sort(function (a, b) {
100 | return a[0] - b[0];
101 | });
102 | return result;
103 | },
104 | //获取生日
105 | attachBirth(val) {
106 | return val.substr(0, 10);
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/music-client/src/pages/MyMusic.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
![]()
6 |
7 |
8 | - 昵称:{{username}}
9 | - 性别:{{userSex}}
10 | - 生日:{{birth}}
11 | - 故乡:{{location}}
12 |
13 |
14 |
15 |
16 | 个性签名:{{introduction}}
17 |
18 |
23 |
24 |
25 |
26 |
27 |
107 |
108 |
--------------------------------------------------------------------------------
/music-client/src/assets/js/iconfont2.js:
--------------------------------------------------------------------------------
1 | !function(d){var e,a='',t=(e=document.getElementsByTagName("script"))[e.length-1].getAttribute("data-injectcss");if(t&&!d.__iconfont__svg__cssinject__){d.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(e){console&&console.log(e)}}!function(e){if(document.addEventListener)if(~["complete","loaded","interactive"].indexOf(document.readyState))setTimeout(e,0);else{var t=function(){document.removeEventListener("DOMContentLoaded",t,!1),e()};document.addEventListener("DOMContentLoaded",t,!1)}else document.attachEvent&&(c=e,o=d.document,i=!1,(a=function(){try{o.documentElement.doScroll("left")}catch(e){return void setTimeout(a,50)}n()})(),o.onreadystatechange=function(){"complete"==o.readyState&&(o.onreadystatechange=null,n())});function n(){i||(i=!0,c())}var c,o,i,a}(function(){var e,t,n,c,o,i;(e=document.createElement("div")).innerHTML=a,a=null,(t=e.getElementsByTagName("svg")[0])&&(t.setAttribute("aria-hidden","true"),t.style.position="absolute",t.style.width=0,t.style.height=0,t.style.overflow="hidden",n=t,(c=document.body).firstChild?(o=n,(i=c.firstChild).parentNode.insertBefore(o,i)):c.appendChild(n))})}(window);
--------------------------------------------------------------------------------
/music-client/src/components/TheHeader.vue:
--------------------------------------------------------------------------------
1 |
2 |
36 |
37 |
38 |
116 |
117 |
120 |
--------------------------------------------------------------------------------
/music-client/src/components/TheAside.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
播放列表
5 |
11 |
12 |
13 |
14 |
102 |
105 |
--------------------------------------------------------------------------------
/music-server/src/main/resources/mapper/SongListMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | id,title,pic,style
19 |
20 |
21 |
22 | id,title,pic,style,introduction
23 |
24 |
25 |
26 | insert into song_list
27 |
28 |
29 | id,
30 |
31 |
32 | title,
33 |
34 |
35 | pic,
36 |
37 |
38 | introduction,
39 |
40 |
41 | style,
42 |
43 |
44 |
45 |
46 | #{id},
47 |
48 |
49 | #{title},
50 |
51 |
52 | #{pic},
53 |
54 |
55 | #{introduction},
56 |
57 |
58 | #{style},
59 |
60 |
61 |
62 |
63 |
64 | update song_list
65 |
66 |
67 | title = #{title},
68 |
69 |
70 | pic = #{pic},
71 |
72 |
73 | introduction = #{introduction},
74 |
75 |
76 | style = #{style},
77 |
78 |
79 | where id = #{id}
80 |
81 |
82 |
83 | delete from song_list
84 | where id=#{id}
85 |
86 |
87 |
93 |
94 |
99 |
100 |
106 |
107 |
113 |
114 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/music-server/src/main/resources/mapper/SingerMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | id,name,sex,pic,birth,location,introduction
18 |
19 |
20 |
21 | insert into singer
22 |
23 |
24 | id,
25 |
26 |
27 | name,
28 |
29 |
30 | sex,
31 |
32 |
33 | pic,
34 |
35 |
36 | birth,
37 |
38 |
39 | location,
40 |
41 |
42 | introduction,
43 |
44 |
45 |
46 |
47 | #{id},
48 |
49 |
50 | #{name},
51 |
52 |
53 | #{sex},
54 |
55 |
56 | #{pic},
57 |
58 |
59 | #{birth},
60 |
61 |
62 | #{location},
63 |
64 |
65 | #{introduction},
66 |
67 |
68 |
69 |
70 |
71 | update singer
72 |
73 |
74 | name = #{name},
75 |
76 |
77 | sex = #{sex},
78 |
79 |
80 | pic = #{pic},
81 |
82 |
83 | birth = #{birth},
84 |
85 |
86 | location = #{location},
87 |
88 |
89 | introduction = #{introduction},
90 |
91 |
92 | where id = #{id}
93 |
94 |
95 |
96 | delete from singer
97 | where id=#{id}
98 |
99 |
100 |
106 |
107 |
112 |
113 |
119 |
120 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
--------------------------------------------------------------------------------
/music-client/src/assets/js/iconfont3.js:
--------------------------------------------------------------------------------
1 | !function(l){var e,a='',t=(e=document.getElementsByTagName("script"))[e.length-1].getAttribute("data-injectcss");if(t&&!l.__iconfont__svg__cssinject__){l.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(e){console&&console.log(e)}}!function(e){if(document.addEventListener)if(~["complete","loaded","interactive"].indexOf(document.readyState))setTimeout(e,0);else{var t=function(){document.removeEventListener("DOMContentLoaded",t,!1),e()};document.addEventListener("DOMContentLoaded",t,!1)}else document.attachEvent&&(i=e,o=l.document,c=!1,(a=function(){try{o.documentElement.doScroll("left")}catch(e){return void setTimeout(a,50)}n()})(),o.onreadystatechange=function(){"complete"==o.readyState&&(o.onreadystatechange=null,n())});function n(){c||(c=!0,i())}var i,o,c,a}(function(){var e,t,n,i,o,c;(e=document.createElement("div")).innerHTML=a,a=null,(t=e.getElementsByTagName("svg")[0])&&(t.setAttribute("aria-hidden","true"),t.style.position="absolute",t.style.width=0,t.style.height=0,t.style.overflow="hidden",n=t,(i=document.body).firstChild?(o=n,(c=i.firstChild).parentNode.insertBefore(o,c)):i.appendChild(n))})}(window);
--------------------------------------------------------------------------------
/music-client/dist/static/js/manifest.2ae2e69a05c33dfc65f8.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///webpack/bootstrap 330a7258bfbd9ba5a948"],"names":["parentJsonpFunction","window","chunkIds","moreModules","executeModules","moduleId","chunkId","result","i","resolves","length","installedChunks","push","Object","prototype","hasOwnProperty","call","modules","shift","__webpack_require__","s","installedModules","2","exports","module","l","m","c","d","name","getter","o","defineProperty","configurable","enumerable","get","n","__esModule","object","property","p","oe","err","console","error"],"mappings":"aACA,IAAAA,EAAAC,OAAA,aACAA,OAAA,sBAAAC,EAAAC,EAAAC,GAIA,IADA,IAAAC,EAAAC,EAAAC,EAAAC,EAAA,EAAAC,KACQD,EAAAN,EAAAQ,OAAoBF,IAC5BF,EAAAJ,EAAAM,GACAG,EAAAL,IACAG,EAAAG,KAAAD,EAAAL,GAAA,IAEAK,EAAAL,GAAA,EAEA,IAAAD,KAAAF,EACAU,OAAAC,UAAAC,eAAAC,KAAAb,EAAAE,KACAY,EAAAZ,GAAAF,EAAAE,IAIA,IADAL,KAAAE,EAAAC,EAAAC,GACAK,EAAAC,QACAD,EAAAS,OAAAT,GAEA,GAAAL,EACA,IAAAI,EAAA,EAAYA,EAAAJ,EAAAM,OAA2BF,IACvCD,EAAAY,IAAAC,EAAAhB,EAAAI,IAGA,OAAAD,GAIA,IAAAc,KAGAV,GACAW,EAAA,GAIA,SAAAH,EAAAd,GAGA,GAAAgB,EAAAhB,GACA,OAAAgB,EAAAhB,GAAAkB,QAGA,IAAAC,EAAAH,EAAAhB,IACAG,EAAAH,EACAoB,GAAA,EACAF,YAUA,OANAN,EAAAZ,GAAAW,KAAAQ,EAAAD,QAAAC,IAAAD,QAAAJ,GAGAK,EAAAC,GAAA,EAGAD,EAAAD,QAKAJ,EAAAO,EAAAT,EAGAE,EAAAQ,EAAAN,EAGAF,EAAAS,EAAA,SAAAL,EAAAM,EAAAC,GACAX,EAAAY,EAAAR,EAAAM,IACAhB,OAAAmB,eAAAT,EAAAM,GACAI,cAAA,EACAC,YAAA,EACAC,IAAAL,KAMAX,EAAAiB,EAAA,SAAAZ,GACA,IAAAM,EAAAN,KAAAa,WACA,WAA2B,OAAAb,EAAA,SAC3B,WAAiC,OAAAA,GAEjC,OADAL,EAAAS,EAAAE,EAAA,IAAAA,GACAA,GAIAX,EAAAY,EAAA,SAAAO,EAAAC,GAAsD,OAAA1B,OAAAC,UAAAC,eAAAC,KAAAsB,EAAAC,IAGtDpB,EAAAqB,EAAA,IAGArB,EAAAsB,GAAA,SAAAC,GAA8D,MAApBC,QAAAC,MAAAF,GAAoBA","file":"static/js/manifest.2ae2e69a05c33dfc65f8.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n \t\tif(executeModules) {\n \t\t\tfor(i=0; i < executeModules.length; i++) {\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// objects to store loaded and loading chunks\n \tvar installedChunks = {\n \t\t2: 0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 330a7258bfbd9ba5a948"],"sourceRoot":""}
--------------------------------------------------------------------------------
/music-server/src/main/resources/mapper/CommentMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | id,user_id,type,song_id,song_list_id,content,create_time,up
19 |
20 |
21 |
22 | insert into comment
23 |
24 |
25 | id,
26 |
27 |
28 | user_id,
29 |
30 |
31 | type,
32 |
33 |
34 | song_id,
35 |
36 |
37 | song_list_id,
38 |
39 |
40 | content,
41 |
42 | create_time,
43 |
44 | up,
45 |
46 |
47 |
48 |
49 | #{id},
50 |
51 |
52 | #{userId},
53 |
54 |
55 | #{type},
56 |
57 |
58 | #{songId},
59 |
60 |
61 | #{songListId},
62 |
63 |
64 | #{content},
65 |
66 | now(),
67 |
68 | #{up},
69 |
70 |
71 |
72 |
73 |
74 | update comment
75 |
76 |
77 | user_id = #{userId},
78 |
79 |
80 | type = #{type},
81 |
82 |
83 | song_id = #{songId},
84 |
85 |
86 | song_list_id = #{songListId},
87 |
88 |
89 | content = #{content},
90 |
91 |
92 | up = #{up},
93 |
94 |
95 | where id = #{id}
96 |
97 |
98 |
99 | delete from comment
100 | where id=#{id}
101 |
102 |
103 |
109 |
110 |
115 |
116 |
122 |
123 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------