├── 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 | 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 | 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 | 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 | 6 | 27 | 28 | -------------------------------------------------------------------------------- /music-client/src/components/Swiper.vue: -------------------------------------------------------------------------------- 1 | 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 | 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 | 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 | 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 | 17 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /music-client/src/components/ContentList.vue: -------------------------------------------------------------------------------- 1 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 37 | 38 | 116 | 117 | 120 | -------------------------------------------------------------------------------- /music-client/src/components/TheAside.vue: -------------------------------------------------------------------------------- 1 | 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 | --------------------------------------------------------------------------------