├── music-server ├── README.md ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties └── src │ └── main │ ├── java │ └── com │ │ └── xs │ │ ├── service │ │ ├── TestService.java │ │ ├── RedisService.java │ │ ├── LogoutService.java │ │ ├── RankService.java │ │ ├── AdminService.java │ │ ├── RecentSongService.java │ │ ├── impl │ │ │ ├── RedisServiceImpl.java │ │ │ ├── LogoutServiceImpl.java │ │ │ ├── AdminServiceImpl.java │ │ │ ├── TestServiceImpl.java │ │ │ └── RankServiceImpl.java │ │ ├── ListSongService.java │ │ ├── ConsumerService.java │ │ ├── CollectService.java │ │ ├── CommentService.java │ │ ├── SongService.java │ │ ├── SongListService.java │ │ └── SingerService.java │ │ ├── MusicApplication.java │ │ ├── exception │ │ ├── NotFoundException.java │ │ ├── BadRequestException.java │ │ ├── PersistenceException.java │ │ └── BizException.java │ │ ├── strategy │ │ ├── UploadStrategy.java │ │ ├── context │ │ │ └── UploadStrategyContext.java │ │ └── impl │ │ │ └── AbstractUploadStrategyImpl.java │ │ ├── vo │ │ ├── LoginVo.java │ │ ├── SingerVo.java │ │ ├── SongListVo.java │ │ ├── SearchVo.java │ │ ├── SongVo.java │ │ ├── CollectVo.java │ │ ├── ListSongVo.java │ │ ├── CommentVo.java │ │ └── RecentSongVo.java │ │ ├── dto │ │ ├── SingerDto.java │ │ ├── ConsumerDto.java │ │ ├── LoginInfoDto.java │ │ ├── ListSongDto.java │ │ ├── SearchDto.java │ │ ├── ListSongByNameDto.java │ │ ├── CommentDto.java │ │ ├── CollectDto.java │ │ └── SongDto.java │ │ ├── mapper │ │ ├── AdminMapper.java │ │ ├── ConsumerMapper.java │ │ ├── RanksMapper.java │ │ ├── RecentSongMapper.java │ │ ├── ListSongMapper.java │ │ ├── SongListMapper.java │ │ ├── SingerMapper.java │ │ ├── SongMapper.java │ │ ├── CollectMapper.java │ │ └── CommentMapper.java │ │ ├── controller │ │ ├── CheckLoginStateController.java │ │ ├── admin │ │ │ ├── LogoutAdminController.java │ │ │ ├── ListSongAdminController.java │ │ │ └── ConsumerAdminController.java │ │ ├── RankController.java │ │ ├── UploadController.java │ │ ├── RecentSongController.java │ │ ├── CollectController.java │ │ └── CommentController.java │ │ ├── config │ │ ├── MybatisPlusConfig.java │ │ ├── MyAuthenticationEntryPoint.java │ │ ├── CrossConfig.java │ │ └── RedisConfig.java │ │ ├── domain │ │ ├── ListSong.java │ │ ├── SongList.java │ │ ├── Ranks.java │ │ ├── Singer.java │ │ ├── Collect.java │ │ ├── RecentSong.java │ │ ├── Comment.java │ │ ├── Song.java │ │ ├── Consumer.java │ │ └── Admin.java │ │ ├── enums │ │ ├── UploadModeEnum.java │ │ ├── FilePathEnum.java │ │ ├── StatusCodeEnum.java │ │ └── FileExtEnum.java │ │ ├── handler │ │ └── MyMetaObjectHandler.java │ │ ├── common │ │ └── Result.java │ │ └── util │ │ ├── JacksonUtils.java │ │ └── FastJsonRedisSerializer.java │ └── resources │ ├── mapper │ ├── AdminMapper.xml │ ├── RanksMapper.xml │ ├── ListSongMapper.xml │ ├── SongListMapper.xml │ ├── SingerMapper.xml │ └── ConsumerMapper.xml │ └── application.yml ├── music-view ├── src │ ├── assets │ │ ├── css │ │ │ ├── song-audio.scss │ │ │ ├── search-songs.scss │ │ │ ├── search-song-Lists.scss │ │ │ ├── swiper.scss │ │ │ ├── app.scss │ │ │ ├── the-footer.scss │ │ │ ├── 404.scss │ │ │ ├── logo.scss │ │ │ ├── login-logo.scss │ │ │ ├── upload.scss │ │ │ ├── home.scss │ │ │ ├── search.scss │ │ │ ├── sign-up.scss │ │ │ ├── global.scss │ │ │ ├── index.scss │ │ │ ├── login-in.scss │ │ │ ├── song-list.scss │ │ │ ├── info.scss │ │ │ ├── singer.scss │ │ │ ├── scroll-top.scss │ │ │ ├── album-content.scss │ │ │ ├── setting.scss │ │ │ ├── singer-album.scss │ │ │ ├── leader-board.scss │ │ │ ├── comment.scss │ │ │ ├── song-comment.scss │ │ │ ├── content-list.scss │ │ │ ├── the-aside.scss │ │ │ ├── var.scss │ │ │ ├── song-list-album.scss │ │ │ ├── my-music.scss │ │ │ └── lyric.scss │ │ └── data │ │ │ ├── consumerList.js │ │ │ ├── user.js │ │ │ ├── singer.js │ │ │ ├── header.js │ │ │ ├── swiper.js │ │ │ └── form.js │ ├── api │ │ ├── login.js │ │ ├── Rank.js │ │ ├── RecentSong.js │ │ ├── Comment.js │ │ ├── ListSong.js │ │ ├── Collect.js │ │ ├── Consumer.js │ │ ├── Singer.js │ │ ├── SongList.js │ │ └── Song.js │ ├── utils │ │ └── get-page-title.js │ ├── plugins │ │ ├── validate.js │ │ └── axios.js │ ├── store │ │ ├── index.js │ │ └── user.js │ ├── components │ │ ├── LoginLogo.vue │ │ ├── Logo.vue │ │ ├── ScrollTop.vue │ │ ├── search │ │ │ ├── SearchSongs.vue │ │ │ └── SearchSongLists.vue │ │ ├── TheFooter.vue │ │ ├── TheAside.vue │ │ ├── ContentList.vue │ │ ├── Swiper.vue │ │ └── AlbumContent.vue │ ├── main.js │ ├── settings.js │ ├── pages │ │ ├── Setting.vue │ │ ├── LeaderBoard.vue │ │ ├── Search.vue │ │ └── SingerAlbum.vue │ └── App.vue ├── public │ ├── favicon.ico │ └── index.html ├── babel.config.js ├── README.md └── package.json └── music-admin ├── babel.config.js ├── public ├── favicon.ico └── index.html ├── src ├── assets │ ├── js │ │ ├── bus.js │ │ ├── iconfont.js │ │ └── city.js │ └── css │ │ └── main.css ├── utils │ └── get-page-title.js ├── plugins │ ├── validate.js │ └── axios.js ├── App.vue ├── api │ ├── login.js │ ├── Collect.js │ ├── Comment.js │ ├── ListSong.js │ ├── Consumer.js │ ├── Song.js │ ├── Singer.js │ └── SongList.js ├── main.js ├── settings.js ├── components │ ├── Home.vue │ ├── SongAudio.vue │ └── TheAside.vue └── store │ └── store.js ├── README.md └── package.json /music-server/README.md: -------------------------------------------------------------------------------- 1 | # music 2 | SpringBoot+Vue开发的在线音乐网站 3 | -------------------------------------------------------------------------------- /music-view/src/assets/css/song-audio.scss: -------------------------------------------------------------------------------- 1 | audio { 2 | display: none; 3 | } 4 | -------------------------------------------------------------------------------- /music-view/src/assets/css/search-songs.scss: -------------------------------------------------------------------------------- 1 | .search-songs { 2 | min-height: 300px; 3 | } 4 | -------------------------------------------------------------------------------- /music-view/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs669/personal-music-website/HEAD/music-view/public/favicon.ico -------------------------------------------------------------------------------- /music-admin/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | compact: false, 3 | presets: ["@vue/cli-plugin-babel/preset"], 4 | }; 5 | -------------------------------------------------------------------------------- /music-admin/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs669/personal-music-website/HEAD/music-admin/public/favicon.ico -------------------------------------------------------------------------------- /music-view/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | compact: false, 3 | presets: ["@vue/cli-plugin-babel/preset"], 4 | }; 5 | -------------------------------------------------------------------------------- /music-view/src/assets/css/search-song-Lists.scss: -------------------------------------------------------------------------------- 1 | 2 | .search-song-Lists{ 3 | min-height: 300px; 4 | margin-top: 50px; 5 | } 6 | -------------------------------------------------------------------------------- /music-admin/src/assets/js/bus.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | 3 | // 使用 Event Bus 4 | const bus = new Vue(); 5 | 6 | export default bus; 7 | -------------------------------------------------------------------------------- /music-view/src/assets/css/swiper.scss: -------------------------------------------------------------------------------- 1 | .swiper { 2 | width: 90%; 3 | margin: 40px auto auto; 4 | img { 5 | width: 100%; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /music-server/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs669/personal-music-website/HEAD/music-server/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/service/TestService.java: -------------------------------------------------------------------------------- 1 | package com.xs.service; 2 | 3 | public interface TestService { 4 | 5 | void changeUrl(); 6 | } 7 | -------------------------------------------------------------------------------- /music-view/src/assets/data/consumerList.js: -------------------------------------------------------------------------------- 1 | const menuList = [ 2 | { name: "设置", path: "/setting" }, 3 | { name: "退出", path: 0 }, 4 | ]; 5 | 6 | export default menuList; 7 | -------------------------------------------------------------------------------- /music-view/src/assets/data/user.js: -------------------------------------------------------------------------------- 1 | const loginMsg = [ 2 | { name: "登录", path: "/login" }, 3 | { name: "注册", path: "/register" }, 4 | ]; 5 | 6 | export default loginMsg; 7 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/service/RedisService.java: -------------------------------------------------------------------------------- 1 | package com.xs.service; 2 | 3 | import com.xs.common.Result; 4 | 5 | public interface RedisService { 6 | 7 | Result checkLoginState(String username); 8 | } 9 | -------------------------------------------------------------------------------- /music-view/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 default singerStyle; 9 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/service/LogoutService.java: -------------------------------------------------------------------------------- 1 | package com.xs.service; 2 | 3 | import com.xs.common.Result; 4 | 5 | public interface LogoutService { 6 | 7 | /** 8 | * 退出登录 9 | */ 10 | Result logout(); 11 | } 12 | -------------------------------------------------------------------------------- /music-view/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-view/src/api/login.js: -------------------------------------------------------------------------------- 1 | import axios from "../plugins/axios"; 2 | 3 | export function login(loginInfoDto) { 4 | return axios({ 5 | url: "admin/login/status", 6 | method: "POST", 7 | data: { 8 | ...loginInfoDto, 9 | }, 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /music-server/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar 3 | -------------------------------------------------------------------------------- /music-admin/src/utils/get-page-title.js: -------------------------------------------------------------------------------- 1 | import defaultSettings from '@/settings' 2 | 3 | const title = defaultSettings.title 4 | 5 | export default function getPageTitle(pageTitle) { 6 | if (pageTitle) { 7 | return `${pageTitle} - ${title}` 8 | } 9 | return `${title}` 10 | } 11 | -------------------------------------------------------------------------------- /music-view/src/assets/data/header.js: -------------------------------------------------------------------------------- 1 | const navMsg = [ 2 | { name: "首页", path: "/" }, 3 | { name: "歌单", path: "/songList" }, 4 | { name: "歌手", path: "/singer" }, 5 | { name: "排行榜", path: "/leaderBoard" }, 6 | { name: "我的音乐", path: "/myMusic" }, 7 | ]; 8 | 9 | export default navMsg; 10 | -------------------------------------------------------------------------------- /music-view/src/utils/get-page-title.js: -------------------------------------------------------------------------------- 1 | import defaultSettings from "@/settings"; 2 | 3 | const title = defaultSettings.title; 4 | 5 | export default function getPageTitle(pageTitle) { 6 | if (pageTitle) { 7 | return `${pageTitle} - ${title}`; 8 | } 9 | return `${title}`; 10 | } 11 | -------------------------------------------------------------------------------- /music-view/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 | p { 10 | height: 30px; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /music-view/src/plugins/validate.js: -------------------------------------------------------------------------------- 1 | export function isEmail(s) { 2 | return /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/.test( 3 | s 4 | ); 5 | } 6 | 7 | export function isPhoneNum(s) { 8 | return /^(13[0-9]{9})|(15[0-9]{9})|(17[0-9]{9})|(18[0-9]{9})|(19[0-9]{9})$/.test( 9 | s 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /music-admin/src/plugins/validate.js: -------------------------------------------------------------------------------- 1 | export function isEmail(s) { 2 | return /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/.test( 3 | s 4 | ); 5 | } 6 | 7 | export function isPhoneNum(s) { 8 | return /^(13[0-9]{9})|(15[0-9]{9})|(17[0-9]{9})|(18[0-9]{9})|(19[0-9]{9})$/.test( 9 | s 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /music-view/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-view/src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import Vuex from "vuex"; 3 | import configure from "./configure"; 4 | import song from "./song"; 5 | import user from "./user"; 6 | Vue.use(Vuex); 7 | 8 | const store = new Vuex.Store({ 9 | modules: { 10 | configure, 11 | song, 12 | user, 13 | }, 14 | }); 15 | 16 | export default store; 17 | -------------------------------------------------------------------------------- /music-admin/src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /music-admin/src/api/login.js: -------------------------------------------------------------------------------- 1 | import axios from "../plugins/axios"; 2 | 3 | export function login(Admin) { 4 | return axios({ 5 | url: "login", 6 | method: "POST", 7 | data: { 8 | ...Admin, 9 | }, 10 | }); 11 | } 12 | 13 | export function logout() { 14 | return axios({ 15 | url: "logout", 16 | method: "POST", 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /music-admin/README.md: -------------------------------------------------------------------------------- 1 | # music-admin 2 | 3 | ## Project setup 4 | ``` 5 | yarn install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | yarn serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | yarn build 16 | ``` 17 | 18 | 19 | ### Customize configuration 20 | See [Configuration Reference](https://cli.vuejs.org/config/). 21 | -------------------------------------------------------------------------------- /music-view/README.md: -------------------------------------------------------------------------------- 1 | # music-view 2 | 3 | ## Project setup 4 | ``` 5 | yarn install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | yarn serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | yarn build 16 | ``` 17 | 18 | 19 | ### Customize configuration 20 | See [Configuration Reference](https://cli.vuejs.org/config/). 21 | -------------------------------------------------------------------------------- /music-view/src/components/LoginLogo.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | 15 | 18 | -------------------------------------------------------------------------------- /music-view/src/assets/css/logo.scss: -------------------------------------------------------------------------------- 1 | @import "var.scss"; 2 | @import "global.scss"; 3 | 4 | .login-logo { 5 | background-color: $color-blue-light; 6 | height: 75vh; 7 | width: 50vw; 8 | min-width: 650px; 9 | overflow: hidden; 10 | @include layout(center, center); 11 | .icon { 12 | @include icon(6.5em, $color-blue-dark); 13 | transform: rotate(-30deg); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /music-view/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: 170vh; 7 | width: 50vw; 8 | min-width: 650px; 9 | overflow: hidden; 10 | @include layout(center, center); 11 | .icon { 12 | @include icon(6.5em, $color-blue-dark); 13 | transform: rotate(-30deg); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /music-view/src/api/Rank.js: -------------------------------------------------------------------------------- 1 | import axios from "../plugins/axios"; 2 | 3 | export function addRank(Rank) { 4 | return axios({ 5 | url: "rank/add", 6 | method: "POST", 7 | data: { 8 | ...Rank, 9 | }, 10 | }); 11 | } 12 | 13 | export function getRankAvgScore(songListId) { 14 | return axios({ 15 | url: `rank/getAvgScore/${songListId}`, 16 | method: "GET", 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/MusicApplication.java: -------------------------------------------------------------------------------- 1 | package com.xs; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class MusicApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(MusicApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /music-view/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%= htmlWebpackPlugin.options.title %> 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /music-admin/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%= htmlWebpackPlugin.options.title %> 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /music-view/src/components/Logo.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 15 | 16 | 19 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/exception/NotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.xs.exception; 2 | 3 | /** 4 | * 404异常 5 | */ 6 | 7 | public class NotFoundException extends RuntimeException { 8 | public NotFoundException() { 9 | } 10 | 11 | public NotFoundException(String message) { 12 | super(message); 13 | } 14 | 15 | public NotFoundException(String message, Throwable cause) { 16 | super(message, cause); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/exception/BadRequestException.java: -------------------------------------------------------------------------------- 1 | package com.xs.exception; 2 | 3 | /** 4 | * 非法请求异常 5 | */ 6 | 7 | public class BadRequestException extends RuntimeException { 8 | public BadRequestException() { 9 | } 10 | 11 | public BadRequestException(String message) { 12 | super(message); 13 | } 14 | 15 | public BadRequestException(String message, Throwable cause) { 16 | super(message, cause); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /music-view/src/assets/css/upload.scss: -------------------------------------------------------------------------------- 1 | @import "var.scss"; 2 | @import "global.scss"; 3 | 4 | .upload { 5 | width: 100%; 6 | .title { 7 | height: 50px; 8 | line-height: 50px; 9 | padding-left: 20px; 10 | font-size: 20px; 11 | font-weight: 600; 12 | color: $color-black; 13 | } 14 | hr { 15 | width: 98%; 16 | } 17 | .section { 18 | height: 400px; 19 | @include layout(center, center); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/exception/PersistenceException.java: -------------------------------------------------------------------------------- 1 | package com.xs.exception; 2 | 3 | /** 4 | * 持久化异常 5 | */ 6 | 7 | public class PersistenceException extends RuntimeException { 8 | public PersistenceException() { 9 | } 10 | 11 | public PersistenceException(String message) { 12 | super(message); 13 | } 14 | 15 | public PersistenceException(String message, Throwable cause) { 16 | super(message, cause); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/strategy/UploadStrategy.java: -------------------------------------------------------------------------------- 1 | package com.xs.strategy; 2 | 3 | import org.springframework.web.multipart.MultipartFile; 4 | 5 | /** 6 | * 上传策略 7 | */ 8 | public interface UploadStrategy { 9 | 10 | /** 11 | * 上传文件 12 | * 13 | * @param file 文件 14 | * @param path 上传路径 15 | * @return {@link String} 文件地址 16 | */ 17 | String uploadFile(MultipartFile file, String path); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/vo/LoginVo.java: -------------------------------------------------------------------------------- 1 | package com.xs.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serial; 6 | import java.io.Serializable; 7 | 8 | @Data 9 | public class LoginVo implements Serializable { 10 | 11 | /** 12 | * 用户名 13 | */ 14 | private String username; 15 | 16 | /** 17 | * 密码 18 | */ 19 | private String password; 20 | 21 | @Serial 22 | private static final long serialVersionUID = 1L; 23 | } 24 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/dto/SingerDto.java: -------------------------------------------------------------------------------- 1 | package com.xs.dto; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serial; 6 | import java.io.Serializable; 7 | 8 | @Data 9 | public class SingerDto implements Serializable { 10 | 11 | /** 12 | * 歌手性别 13 | */ 14 | private Integer sex; 15 | 16 | /** 17 | * 按歌手性别统计的数量 18 | */ 19 | private Integer number; 20 | 21 | @Serial 22 | private static final long serialVersionUID = 1L; 23 | } 24 | -------------------------------------------------------------------------------- /music-view/src/components/ScrollTop.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 21 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/dto/ConsumerDto.java: -------------------------------------------------------------------------------- 1 | package com.xs.dto; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serial; 6 | import java.io.Serializable; 7 | 8 | @Data 9 | public class ConsumerDto implements Serializable { 10 | 11 | /** 12 | * 用户性别 13 | */ 14 | private Integer sex; 15 | 16 | /** 17 | * 按用户性别统计的数量 18 | */ 19 | private Integer number; 20 | 21 | @Serial 22 | private static final long serialVersionUID = 1L; 23 | } 24 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/vo/SingerVo.java: -------------------------------------------------------------------------------- 1 | package com.xs.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serial; 6 | import java.io.Serializable; 7 | 8 | @Data 9 | public class SingerVo implements Serializable { 10 | 11 | /** 12 | * 歌手所在地区 13 | */ 14 | private String location; 15 | 16 | /** 17 | * 按地区分组查询歌手数量 18 | */ 19 | private Integer number; 20 | 21 | @Serial 22 | private static final long serialVersionUID = 1L; 23 | } 24 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/vo/SongListVo.java: -------------------------------------------------------------------------------- 1 | package com.xs.vo; 2 | 3 | import lombok.Builder; 4 | import lombok.Data; 5 | 6 | import java.io.Serial; 7 | import java.io.Serializable; 8 | 9 | @Data 10 | @Builder 11 | public class SongListVo implements Serializable { 12 | 13 | /** 14 | * 歌单类型 15 | */ 16 | private String style; 17 | 18 | /** 19 | * 按歌单类型分组查询的歌单数量 20 | */ 21 | private Integer number; 22 | 23 | @Serial 24 | private static final long serialVersionUID = 1L; 25 | } 26 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/dto/LoginInfoDto.java: -------------------------------------------------------------------------------- 1 | package com.xs.dto; 2 | 3 | import lombok.Data; 4 | import lombok.NoArgsConstructor; 5 | 6 | import java.io.Serial; 7 | import java.io.Serializable; 8 | 9 | /** 10 | * 登录账号密码 11 | */ 12 | @NoArgsConstructor 13 | @Data 14 | public class LoginInfoDto implements Serializable { 15 | 16 | /** 17 | * 用户名 18 | */ 19 | private String username; 20 | 21 | /** 22 | * 密码 23 | */ 24 | private String password; 25 | 26 | @Serial 27 | private static final long serialVersionUID = 1L; 28 | } 29 | -------------------------------------------------------------------------------- /music-view/src/components/search/SearchSongs.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 18 | 19 | 22 | -------------------------------------------------------------------------------- /music-view/src/assets/css/home.scss: -------------------------------------------------------------------------------- 1 | @import "var.scss"; 2 | 3 | .home { 4 | margin-top: $header-height - 10px; 5 | .section { 6 | width: 100%; 7 | margin-top: 20px; 8 | padding: $content-padding; 9 | background-color: $color-white; 10 | box-sizing: border-box; 11 | .section-title { 12 | height: 60px; 13 | line-height: 60px; 14 | padding-top: 10px; 15 | font-size: 28px; 16 | font-weight: 500; 17 | text-align: center; 18 | color: $color-black; 19 | box-sizing: border-box; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/service/RankService.java: -------------------------------------------------------------------------------- 1 | package com.xs.service; 2 | 3 | import com.xs.common.Result; 4 | import com.xs.domain.Ranks; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | 7 | /** 8 | * @author xs 9 | * description 针对表【rank(评价)】的数据库操作Service 10 | * createDate 2022-10-11 16:16:20 11 | */ 12 | public interface RankService extends IService { 13 | 14 | /** 15 | * 添加歌单评价 16 | */ 17 | Result addRanks(Ranks ranks); 18 | 19 | /** 20 | * 获取指定歌单的平均分 21 | */ 22 | Result getRanksAvgScore(Long id); 23 | } 24 | -------------------------------------------------------------------------------- /music-view/src/components/search/SearchSongLists.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | 20 | 23 | -------------------------------------------------------------------------------- /music-view/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 | span { 19 | line-height: 50px; 20 | cursor: pointer; 21 | } 22 | } 23 | 24 | .isActive { 25 | font-weight: 600; 26 | border-bottom:5px solid $color-black; 27 | } 28 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/mapper/AdminMapper.java: -------------------------------------------------------------------------------- 1 | package com.xs.mapper; 2 | 3 | import com.xs.domain.Admin; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | import org.springframework.stereotype.Repository; 7 | 8 | /** 9 | * @author xs 10 | * description 针对表【admin(管理员)】的数据库操作Mapper 11 | * createDate 2022-10-03 16:22:14 12 | * Entity com.xs.domain.Admin 13 | */ 14 | @Repository 15 | @Mapper 16 | public interface AdminMapper extends BaseMapper { 17 | 18 | Admin findByUsername(String username); 19 | } 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /music-view/src/assets/data/swiper.js: -------------------------------------------------------------------------------- 1 | const swiperList = [ 2 | { picImg: "https://www.freemusic.ltd/img/swiper/a.jpg" }, 3 | { picImg: "https://www.freemusic.ltd/img/swiper/b.jpg" }, 4 | { picImg: "https://www.freemusic.ltd/img/swiper/c.jpg" }, 5 | { picImg: "https://www.freemusic.ltd/img/swiper/d.jpg" }, 6 | { picImg: "https://www.freemusic.ltd/img/swiper/e.jpg" }, 7 | { picImg: "https://www.freemusic.ltd/img/swiper/f.jpg" }, 8 | { picImg: "https://www.freemusic.ltd/img/swiper/g.jpg" }, 9 | { picImg: "https://www.freemusic.ltd/img/swiper/h.jpg" }, 10 | ]; 11 | 12 | export default swiperList; 13 | -------------------------------------------------------------------------------- /music-admin/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import App from "./App"; 3 | import router from "./router/index"; 4 | import ElementUI from "element-ui"; 5 | import "element-ui/lib/theme-chalk/index.css"; 6 | import "./assets/css/main.css"; 7 | import { VePie, VeHistogram, VeRing} from "v-charts/lib/index.esm"; 8 | import store from "./store/store"; 9 | 10 | Vue.use(ElementUI); 11 | Vue.component(VePie.name, VePie); 12 | Vue.component(VeHistogram.name, VeHistogram); 13 | Vue.component(VeRing.name, VeRing); 14 | 15 | // eslint-disable-next-line no-new 16 | new Vue({ 17 | el: "#app", 18 | router, 19 | store, 20 | render: (h) => h(App), 21 | }); 22 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/vo/SearchVo.java: -------------------------------------------------------------------------------- 1 | package com.xs.vo; 2 | 3 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 4 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 5 | import lombok.Data; 6 | 7 | import java.io.Serializable; 8 | 9 | @Data 10 | public class SearchVo implements Serializable { 11 | 12 | /** 13 | * 指定字段id 14 | */ 15 | @JsonSerialize(using = ToStringSerializer.class) 16 | private Long id; 17 | 18 | /** 19 | * 搜索关键字 20 | */ 21 | private String keyWord; 22 | 23 | /** 24 | * id类型 (0:用户, 1:歌曲, 2:歌单) 25 | */ 26 | private Integer type; 27 | } 28 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/dto/ListSongDto.java: -------------------------------------------------------------------------------- 1 | package com.xs.dto; 2 | 3 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 4 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 5 | import lombok.Data; 6 | 7 | import java.io.Serial; 8 | import java.io.Serializable; 9 | 10 | @Data 11 | public class ListSongDto implements Serializable { 12 | 13 | /** 14 | * 歌曲id 15 | */ 16 | @JsonSerialize(using = ToStringSerializer.class) 17 | private Long songId; 18 | 19 | /** 20 | * 歌曲名称 21 | */ 22 | private String songName; 23 | 24 | @Serial 25 | private static final long serialVersionUID = 1L; 26 | } 27 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/dto/SearchDto.java: -------------------------------------------------------------------------------- 1 | package com.xs.dto; 2 | 3 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 4 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 5 | import lombok.Data; 6 | 7 | import java.io.Serial; 8 | import java.io.Serializable; 9 | 10 | @Data 11 | public class SearchDto implements Serializable { 12 | 13 | /** 14 | * 指定用户id 15 | */ 16 | @JsonSerialize(using = ToStringSerializer.class) 17 | private Long id; 18 | 19 | /** 20 | * 搜索关键字 21 | */ 22 | private String keyWord; 23 | 24 | @Serial 25 | private static final long serialVersionUID = 1L; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/dto/ListSongByNameDto.java: -------------------------------------------------------------------------------- 1 | package com.xs.dto; 2 | 3 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 4 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 5 | import lombok.Data; 6 | 7 | import java.io.Serial; 8 | import java.io.Serializable; 9 | 10 | @Data 11 | public class ListSongByNameDto implements Serializable { 12 | 13 | /** 14 | * 歌单id 15 | */ 16 | @JsonSerialize(using = ToStringSerializer.class) 17 | private Long songListId; 18 | 19 | /** 20 | * 歌单歌曲搜索关键词 21 | */ 22 | private String name; 23 | 24 | @Serial 25 | private static final long serialVersionUID = 1L; 26 | } 27 | -------------------------------------------------------------------------------- /music-view/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import App from "./App"; 3 | import router from "./router"; 4 | import "./assets/css/index.scss"; 5 | import ElementUI from "element-ui"; 6 | import "element-ui/lib/theme-chalk/index.css"; 7 | import "@/assets/js/iconfont.js"; 8 | import "@/assets/js/iconfont1.js"; 9 | import "@/assets/js/iconfont2.js"; 10 | import "@/assets/js/iconfont3.js"; 11 | import "@/assets/js/iconfont4.js"; 12 | import store from "./store"; 13 | 14 | Vue.use(ElementUI); 15 | 16 | Vue.config.productionTip = false; 17 | 18 | /* eslint-disable no-new */ 19 | new Vue({ 20 | el: "#app", 21 | router, 22 | store, 23 | components: { App }, 24 | render: (h) => h(App), 25 | }); 26 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/dto/CommentDto.java: -------------------------------------------------------------------------------- 1 | package com.xs.dto; 2 | 3 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 4 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | 8 | import java.io.Serial; 9 | import java.io.Serializable; 10 | 11 | @Data 12 | @Builder 13 | public class CommentDto implements Serializable { 14 | 15 | /** 16 | * 主键 17 | */ 18 | @JsonSerialize(using = ToStringSerializer.class) 19 | private Long id; 20 | 21 | /** 22 | * 点赞数 23 | */ 24 | private Integer up; 25 | 26 | @Serial 27 | private static final long serialVersionUID = 1L; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /music-admin/src/settings.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | /** 3 | * @type {string} 4 | * @description page title 5 | */ 6 | title: '音乐网站后台', 7 | 8 | /** 9 | * @type {string} 10 | * @description logo URL 11 | */ 12 | logo: 'https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png', 13 | 14 | /** 15 | * @type {boolean} true | false 16 | * @description Whether fix the header 17 | */ 18 | fixedHeader: true, 19 | 20 | /** 21 | * @type {boolean} true | false 22 | * @description Whether show the logo in sidebar 23 | */ 24 | sidebarLogo: true, 25 | 26 | /** 27 | * @type {Array} 28 | * @description 默认展开的父级菜单 29 | */ 30 | defaultOpeneds: ['/example'] 31 | } 32 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/service/AdminService.java: -------------------------------------------------------------------------------- 1 | package com.xs.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.xs.domain.Admin; 5 | import org.springframework.security.core.userdetails.UserDetails; 6 | import org.springframework.security.core.userdetails.UserDetailsService; 7 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 8 | 9 | /** 10 | * @author xs 11 | * description 针对表【admin(管理员)】的数据库操作Service 12 | * createDate 2022-10-03 16:22:14 13 | */ 14 | public interface AdminService extends IService, UserDetailsService { 15 | 16 | UserDetails loadUserByUsername(String username) throws UsernameNotFoundException; 17 | } 18 | -------------------------------------------------------------------------------- /music-view/src/settings.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | /** 3 | * @type {string} 4 | * @description page title 5 | */ 6 | title: "音乐网站前台", 7 | 8 | /** 9 | * @type {string} 10 | * @description logo URL 11 | */ 12 | logo: "https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png", 13 | 14 | /** 15 | * @type {boolean} true | false 16 | * @description Whether fix the header 17 | */ 18 | fixedHeader: true, 19 | 20 | /** 21 | * @type {boolean} true | false 22 | * @description Whether show the logo in sidebar 23 | */ 24 | sidebarLogo: true, 25 | 26 | /** 27 | * @type {Array} 28 | * @description 默认展开的父级菜单 29 | */ 30 | defaultOpeneds: ["/example"], 31 | }; 32 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/vo/SongVo.java: -------------------------------------------------------------------------------- 1 | package com.xs.vo; 2 | 3 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 4 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 5 | import lombok.Data; 6 | 7 | import java.io.Serial; 8 | import java.io.Serializable; 9 | 10 | @Data 11 | public class SongVo implements Serializable { 12 | 13 | /** 14 | * 歌手id 15 | */ 16 | @JsonSerialize(using = ToStringSerializer.class) 17 | private Long id; 18 | 19 | /** 20 | * 歌曲搜索关键字 21 | */ 22 | private String name; 23 | 24 | /** 25 | * 播放量 26 | */ 27 | private Integer playCount; 28 | 29 | @Serial 30 | private static final long serialVersionUID = 1L; 31 | } 32 | -------------------------------------------------------------------------------- /music-admin/src/api/Collect.js: -------------------------------------------------------------------------------- 1 | import axios from "../plugins/axios"; 2 | 3 | export function getAllCollectByUserId(userId) { 4 | return axios({ 5 | url: `collect/collectOfUserId/${userId}`, 6 | method: "GET", 7 | }); 8 | } 9 | 10 | export function delCollect(id) { 11 | return axios({ 12 | url: `collect/del/${id}`, 13 | method: "DELETE", 14 | }); 15 | } 16 | 17 | export function delAllCollect(ids) { 18 | return axios({ 19 | url: `collect/delAll/${ids}`, 20 | method: "DELETE", 21 | }); 22 | } 23 | 24 | export function searchCollectByUserId(searchDto) { 25 | return axios({ 26 | url: "collect/searchOfUserId", 27 | method: "POST", 28 | data: { 29 | ...searchDto, 30 | }, 31 | }); 32 | } 33 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/controller/CheckLoginStateController.java: -------------------------------------------------------------------------------- 1 | package com.xs.controller; 2 | 3 | import com.xs.common.Result; 4 | import com.xs.service.RedisService; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.PathVariable; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import javax.annotation.Resource; 10 | 11 | @RestController 12 | public class CheckLoginStateController { 13 | 14 | @Resource 15 | private RedisService redisService; 16 | 17 | @GetMapping("/checkLoginState/{username}") 18 | public Result checkLoginState(@PathVariable String username) { 19 | return redisService.checkLoginState(username); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /music-view/src/assets/css/sign-up.scss: -------------------------------------------------------------------------------- 1 | @import "var.scss"; 2 | @import "global.scss"; 3 | 4 | .box { 5 | display: flex; 6 | 7 | .img { 8 | margin-top: 24px; 9 | width: 880px; 10 | height: 580px; 11 | } 12 | 13 | .signUp { 14 | margin: 70px auto 0; 15 | background-color: $color-white; 16 | border-radius: 10px; 17 | width: 350px; 18 | height: 474px; 19 | padding: 30px 30px; 20 | 21 | .signUp-head { 22 | text-align: center; 23 | margin-bottom: 10px; 24 | font-size: 20px; 25 | font-weight: 600; 26 | } 27 | 28 | .login-btn { 29 | @include layout(space-between); 30 | button { 31 | display: block; 32 | width: 50%; 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/config/MybatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.xs.config; 2 | 3 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 4 | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | @Configuration 9 | public class MybatisPlusConfig { 10 | 11 | @Bean 12 | public MybatisPlusInterceptor mybatisPlusInterceptor() { 13 | MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); 14 | mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor()); 15 | return mybatisPlusInterceptor; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /music-view/src/api/RecentSong.js: -------------------------------------------------------------------------------- 1 | import axios from "../plugins/axios"; 2 | 3 | export function addRecentSong(RecentSong) { 4 | return axios({ 5 | url: "recentSong/add", 6 | method: "POST", 7 | data: { 8 | ...RecentSong, 9 | }, 10 | }); 11 | } 12 | 13 | export function getRecentSongByUserId(id) { 14 | return axios({ 15 | url: `recentSong/recentSongOfUserId/${id}`, 16 | method: "GET", 17 | }); 18 | } 19 | 20 | export function recommendSongList(id) { 21 | return axios({ 22 | url: `recentSong/recommendSongList/${id}`, 23 | method: "GET", 24 | }); 25 | } 26 | 27 | export function recommendSinger(id) { 28 | return axios({ 29 | url: `recentSong/recommendSinger/${id}`, 30 | method: "GET", 31 | }); 32 | } 33 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/controller/admin/LogoutAdminController.java: -------------------------------------------------------------------------------- 1 | package com.xs.controller.admin; 2 | 3 | import com.xs.common.Result; 4 | import com.xs.service.LogoutService; 5 | import org.springframework.web.bind.annotation.PostMapping; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import javax.annotation.Resource; 10 | 11 | @RestController 12 | @RequestMapping("/admin") 13 | public class LogoutAdminController { 14 | 15 | @Resource 16 | private LogoutService logoutService; 17 | 18 | /** 19 | * 退出登录 20 | */ 21 | @PostMapping("/logout") 22 | public Result logout() { 23 | return logoutService.logout(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /music-view/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-view/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-view/src/assets/css/login-in.scss: -------------------------------------------------------------------------------- 1 | @import "var.scss"; 2 | @import "global.scss"; 3 | 4 | .box { 5 | display: flex; 6 | margin-bottom: 50px; 7 | 8 | .img { 9 | margin-top: 24px; 10 | width: 880px; 11 | height: 580px; 12 | } 13 | 14 | .login { 15 | margin: 70px auto 0; 16 | width: 300px; 17 | height: 474px; 18 | padding: 30px 50px; 19 | border-radius: 10px; 20 | background-color: #fff; 21 | 22 | .login-head { 23 | text-align: center; 24 | margin-top: 70px; 25 | margin-bottom: 10px; 26 | font-size: 20px; 27 | font-weight: 600; 28 | } 29 | 30 | .login-btn { 31 | @include layout(space-between); 32 | button { 33 | display: block; 34 | width: 50%; 35 | } 36 | } 37 | } 38 | } 39 | 40 | 41 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/service/RecentSongService.java: -------------------------------------------------------------------------------- 1 | package com.xs.service; 2 | 3 | import com.xs.common.Result; 4 | import com.xs.domain.RecentSong; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | 7 | /** 8 | * @author xs 9 | * description 针对表【recent_song】的数据库操作Service 10 | * createDate 2022-10-30 10:18:56 11 | */ 12 | public interface RecentSongService extends IService { 13 | 14 | /** 15 | * 添加歌曲最近播放记录 16 | */ 17 | Result addRecentSong(RecentSong recentSong); 18 | 19 | /** 20 | * 获取当前用户最近播放列表 21 | */ 22 | Result getRecentSongByUserId(Long id); 23 | 24 | /** 25 | * 推荐歌单 26 | */ 27 | Result recommendSongList(Long id); 28 | 29 | /** 30 | * 推荐歌手 31 | */ 32 | Result recommendSinger(Long id); 33 | } 34 | -------------------------------------------------------------------------------- /music-view/src/plugins/axios.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import { Message } from "element-ui"; 3 | 4 | const request = axios.create({ 5 | baseURL: "/api", 6 | timeout: 30000, 7 | }); 8 | 9 | // 响应拦截 10 | request.interceptors.response.use( 11 | (response) => { 12 | const res = response; 13 | if (res.data.code !== 200) { 14 | if (res.data.code === 500 && res.data.data === null) { 15 | console.log("暂无数据"); 16 | } else { 17 | let msg = res.data.msg || "Error"; 18 | Message.error(msg); 19 | return Promise.reject(new Error(msg)); 20 | } 21 | } 22 | return res; 23 | }, 24 | (error) => { 25 | console.info(error); 26 | Message.error(error.message); 27 | return Promise.reject(error); 28 | } 29 | ); 30 | 31 | export default request; 32 | -------------------------------------------------------------------------------- /music-admin/src/components/Home.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/service/impl/RedisServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.xs.service.impl; 2 | 3 | import com.xs.common.Result; 4 | import com.xs.domain.Admin; 5 | import com.xs.service.RedisService; 6 | import com.xs.util.RedisCache; 7 | import org.springframework.stereotype.Service; 8 | 9 | import javax.annotation.Resource; 10 | import java.util.Objects; 11 | 12 | @Service 13 | public class RedisServiceImpl implements RedisService { 14 | 15 | @Resource 16 | private RedisCache redisCache; 17 | 18 | @Override 19 | public Result checkLoginState(String username) { 20 | Admin admin = redisCache.getCacheObject(username); 21 | if (Objects.nonNull(admin)) { 22 | return Result.ok("token生效中", true); 23 | } else { 24 | return Result.ok("凭证已失效", false); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/exception/BizException.java: -------------------------------------------------------------------------------- 1 | package com.xs.exception; 2 | 3 | import com.xs.enums.StatusCodeEnum; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Getter; 6 | 7 | import static com.xs.enums.StatusCodeEnum.FAIL; 8 | 9 | /** 10 | * 业务异常 11 | */ 12 | @Getter 13 | @AllArgsConstructor 14 | public class BizException extends RuntimeException { 15 | 16 | /** 17 | * 错误码 18 | */ 19 | private Integer code = FAIL.getCode(); 20 | 21 | /** 22 | * 错误信息 23 | */ 24 | private final String message; 25 | 26 | public BizException(String message) { 27 | this.message = message; 28 | } 29 | 30 | public BizException(StatusCodeEnum statusCodeEnum) { 31 | this.code = statusCodeEnum.getCode(); 32 | this.message = statusCodeEnum.getDesc(); 33 | } 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/controller/RankController.java: -------------------------------------------------------------------------------- 1 | package com.xs.controller; 2 | 3 | import com.xs.common.Result; 4 | import com.xs.domain.Ranks; 5 | import com.xs.service.RankService; 6 | import org.springframework.web.bind.annotation.*; 7 | 8 | import javax.annotation.Resource; 9 | 10 | @RestController 11 | @RequestMapping("/rank") 12 | public class RankController { 13 | 14 | @Resource 15 | private RankService rankService; 16 | 17 | /** 18 | * 添加歌单评价 19 | */ 20 | @PostMapping("/add") 21 | public Result addRank(@RequestBody Ranks ranks) { 22 | return rankService.addRanks(ranks); 23 | } 24 | 25 | /** 26 | * 获取指定歌单的平均分 27 | */ 28 | @GetMapping("/getAvgScore/{id}") 29 | public Result getRanksAvgScore(@PathVariable Long id) { 30 | return rankService.getRanksAvgScore(id); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /music-view/src/assets/css/song-list.scss: -------------------------------------------------------------------------------- 1 | @import "var.scss"; 2 | @import "global.scss"; 3 | 4 | .song-list { 5 | position: relative; 6 | margin: 30px 150px; 7 | margin-top: $header-height + 20px; 8 | padding-bottom: 50px; 9 | min-width: 800px; 10 | background-color: $color-white; 11 | } 12 | 13 | .song-list-header { 14 | width: 100%; 15 | padding: 0 40px; 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 | li.active { 27 | color: $color-black; 28 | font-weight: 600; 29 | border-bottom: 4px solid $color-black; 30 | } 31 | } 32 | 33 | .pagination { 34 | position: absolute; 35 | bottom: 10px; 36 | left: 35%; 37 | @include layout; 38 | } 39 | -------------------------------------------------------------------------------- /music-view/src/assets/css/info.scss: -------------------------------------------------------------------------------- 1 | @import "var.scss"; 2 | @import "global.scss"; 3 | 4 | .info { 5 | padding-bottom: 30px; 6 | .title { 7 | height: 50px; 8 | line-height: 50px; 9 | padding-left: 20px; 10 | font-size: 20px; 11 | font-weight: 600; 12 | color: $color-black; 13 | } 14 | 15 | hr { 16 | width: 98%; 17 | } 18 | 19 | .personal { 20 | padding-right: 50px; 21 | padding-top: 40px; 22 | } 23 | 24 | .btn { 25 | width: 100%; 26 | height: 40px; 27 | margin-left: 40px; 28 | @include layout(center, center); 29 | cursor: pointer; 30 | div { 31 | display: inline-block; 32 | width: 100px; 33 | height: 30px; 34 | line-height: 30px; 35 | text-align: center; 36 | background-color: $color-blue-active; 37 | margin: 0 20px; 38 | color: $color-white; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/domain/ListSong.java: -------------------------------------------------------------------------------- 1 | package com.xs.domain; 2 | 3 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 4 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 5 | import lombok.Data; 6 | 7 | import java.io.Serial; 8 | import java.io.Serializable; 9 | 10 | /** 11 | * 歌单包含歌曲列表 12 | * TableName list_song 13 | */ 14 | @Data 15 | public class ListSong implements Serializable { 16 | 17 | /** 18 | * 主键 19 | */ 20 | @JsonSerialize(using = ToStringSerializer.class) 21 | private Long id; 22 | 23 | /** 24 | * 歌曲id 25 | */ 26 | @JsonSerialize(using = ToStringSerializer.class) 27 | private Long songId; 28 | 29 | /** 30 | * 歌单id 31 | */ 32 | @JsonSerialize(using = ToStringSerializer.class) 33 | private Long songListId; 34 | 35 | @Serial 36 | private static final long serialVersionUID = 1L; 37 | } -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/enums/UploadModeEnum.java: -------------------------------------------------------------------------------- 1 | package com.xs.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * 上传模式枚举 8 | */ 9 | @Getter 10 | @AllArgsConstructor 11 | public enum UploadModeEnum { 12 | /** 13 | * 本地 14 | */ 15 | LOCAL("local", "localUploadStrategyImpl"); 16 | 17 | /** 18 | * 模式 19 | */ 20 | private final String mode; 21 | 22 | /** 23 | * 策略 24 | */ 25 | private final String strategy; 26 | 27 | /** 28 | * 获取策略 29 | * 30 | * @param mode 模式 31 | * @return {@link String} 搜索策略 32 | */ 33 | public static String getStrategy(String mode) { 34 | for (UploadModeEnum value : UploadModeEnum.values()) { 35 | if (value.getMode().equals(mode)) { 36 | return value.getStrategy(); 37 | } 38 | } 39 | return null; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/vo/CollectVo.java: -------------------------------------------------------------------------------- 1 | package com.xs.vo; 2 | 3 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 4 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 5 | import lombok.Data; 6 | 7 | import java.io.Serial; 8 | import java.io.Serializable; 9 | 10 | @Data 11 | public class CollectVo implements Serializable { 12 | 13 | /** 14 | * 用户id 15 | */ 16 | @JsonSerialize(using = ToStringSerializer.class) 17 | private Long userId; 18 | 19 | /** 20 | * 收藏类型 21 | */ 22 | private Integer type; 23 | 24 | /** 25 | * 歌曲id 26 | */ 27 | @JsonSerialize(using = ToStringSerializer.class) 28 | private Long songId; 29 | 30 | /** 31 | * 歌曲id 32 | */ 33 | @JsonSerialize(using = ToStringSerializer.class) 34 | private Long songListId; 35 | 36 | @Serial 37 | private static final long serialVersionUID = 1L; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /music-view/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 | position: relative; 12 | margin: 30px 10%; 13 | margin-top: $header-height + 20px; 14 | padding-bottom: 50px; 15 | background-color: $color-white; 16 | .singer-header { 17 | width: 100%; 18 | padding: 0 40px; 19 | li { 20 | display: inline-block; 21 | line-height: 40px; 22 | margin: 40px 20px 15px 20px; 23 | font-size: 20px; 24 | font-weight: 400; 25 | color: $color-grey; 26 | border-bottom: none; 27 | cursor: pointer; 28 | } 29 | li.active { 30 | color: $color-black; 31 | font-weight: 600; 32 | border-bottom: 4px solid $color-black; 33 | } 34 | } 35 | } 36 | 37 | .pagination { 38 | position: absolute; 39 | left: 35%; 40 | bottom: 10px; 41 | @include layout; 42 | } 43 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/domain/SongList.java: -------------------------------------------------------------------------------- 1 | package com.xs.domain; 2 | 3 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 4 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 5 | import lombok.Data; 6 | 7 | import java.io.Serial; 8 | import java.io.Serializable; 9 | 10 | /** 11 | * 歌单 12 | * TableName song_list 13 | */ 14 | @Data 15 | public class SongList implements Serializable { 16 | 17 | /** 18 | * 主键 19 | */ 20 | @JsonSerialize(using = ToStringSerializer.class) 21 | private Long id; 22 | 23 | /** 24 | * 标题 25 | */ 26 | private String title; 27 | 28 | /** 29 | * 歌单图片 30 | */ 31 | private String pic; 32 | 33 | /** 34 | * 歌单简介 35 | */ 36 | private String introduction; 37 | 38 | /** 39 | * 风格 40 | */ 41 | private String style; 42 | 43 | @Serial 44 | private static final long serialVersionUID = 1L; 45 | } -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/service/impl/LogoutServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.xs.service.impl; 2 | 3 | import com.xs.common.Result; 4 | import com.xs.service.LogoutService; 5 | import com.xs.util.RedisCache; 6 | import org.springframework.security.core.Authentication; 7 | import org.springframework.security.core.context.SecurityContextHolder; 8 | import org.springframework.stereotype.Service; 9 | 10 | import javax.annotation.Resource; 11 | 12 | @Service 13 | public class LogoutServiceImpl implements LogoutService { 14 | 15 | @Resource 16 | private RedisCache redisCache; 17 | 18 | /** 19 | * 退出登录 20 | */ 21 | @Override 22 | public Result logout() { 23 | Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 24 | String username = (String) authentication.getPrincipal(); 25 | redisCache.deleteObject(username); 26 | return Result.ok("退出登录成功"); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/vo/ListSongVo.java: -------------------------------------------------------------------------------- 1 | package com.xs.vo; 2 | 3 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 4 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 5 | import lombok.Data; 6 | 7 | import java.io.Serial; 8 | import java.io.Serializable; 9 | 10 | @Data 11 | public class ListSongVo implements Serializable { 12 | 13 | /** 14 | * 主键 15 | */ 16 | @JsonSerialize(using = ToStringSerializer.class) 17 | private Long id; 18 | 19 | /** 20 | * 歌曲id 21 | */ 22 | @JsonSerialize(using = ToStringSerializer.class) 23 | private Long songId; 24 | 25 | /** 26 | * 歌单id 27 | */ 28 | @JsonSerialize(using = ToStringSerializer.class) 29 | private Long songListId; 30 | 31 | /** 32 | * 歌手名-歌曲名 33 | */ 34 | private String singerNameAndsongName; 35 | 36 | @Serial 37 | private static final long serialVersionUID = 1L; 38 | } 39 | -------------------------------------------------------------------------------- /music-server/src/main/resources/mapper/AdminMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/domain/Ranks.java: -------------------------------------------------------------------------------- 1 | package com.xs.domain; 2 | 3 | import java.io.Serial; 4 | import java.io.Serializable; 5 | 6 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 7 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 8 | import lombok.Data; 9 | 10 | /** 11 | * 评价 12 | * TableName ranks 13 | */ 14 | @Data 15 | public class Ranks implements Serializable { 16 | 17 | /** 18 | * 主键 19 | */ 20 | @JsonSerialize(using = ToStringSerializer.class) 21 | private Long id; 22 | 23 | /** 24 | * 歌单id 25 | */ 26 | @JsonSerialize(using = ToStringSerializer.class) 27 | private Long songListId; 28 | 29 | /** 30 | * 用户id 31 | */ 32 | @JsonSerialize(using = ToStringSerializer.class) 33 | private Long consumerId; 34 | 35 | /** 36 | * 评分 37 | */ 38 | private Integer score; 39 | 40 | @Serial 41 | private static final long serialVersionUID = 1L; 42 | } -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/enums/FilePathEnum.java: -------------------------------------------------------------------------------- 1 | package com.xs.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * 文件路径枚举 8 | */ 9 | @Getter 10 | @AllArgsConstructor 11 | public enum FilePathEnum { 12 | /** 13 | * 头像路径 14 | */ 15 | AVATAR("avatar/", "头像路径"), 16 | /** 17 | * 文章图片路径 18 | */ 19 | ARTICLE("articles/", "文章图片路径"), 20 | /** 21 | * 音频路径 22 | */ 23 | VOICE("voice/", "音频路径"), 24 | /** 25 | * 照片路径 26 | */ 27 | PHOTO("photos/", "相册路径"), 28 | /** 29 | * 配置图片路径 30 | */ 31 | CONFIG("config/", "配置图片路径"), 32 | /** 33 | * 说说图片路径 34 | */ 35 | TALK("talks/", "说说图片路径"), 36 | /** 37 | * md文件路径 38 | */ 39 | MD("markdown/", "md文件路径"); 40 | 41 | /** 42 | * 路径 43 | */ 44 | private final String path; 45 | 46 | /** 47 | * 描述 48 | */ 49 | private final String desc; 50 | 51 | } 52 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/handler/MyMetaObjectHandler.java: -------------------------------------------------------------------------------- 1 | package com.xs.handler; 2 | 3 | import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; 4 | import org.apache.ibatis.reflection.MetaObject; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | @Component 10 | public class MyMetaObjectHandler implements MetaObjectHandler { 11 | 12 | @Override 13 | public void insertFill(MetaObject metaObject) { 14 | this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); 15 | this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); 16 | } 17 | 18 | @Override 19 | public void updateFill(MetaObject metaObject) { 20 | this.strictUpdateFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); 21 | this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /music-view/src/pages/Setting.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 35 | 36 | 39 | -------------------------------------------------------------------------------- /music-view/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 | &:hover:before { 17 | top: 50%; 18 | } 19 | &:hover .box-in { 20 | visibility: hidden; 21 | } 22 | &:before { 23 | content: "回到顶部"; 24 | position: absolute; 25 | font-weight: bold; 26 | width: 30px; 27 | top: -50%; 28 | left: 50%; 29 | transform: translate(-50%, -50%); 30 | } 31 | } 32 | 33 | .box-in { 34 | visibility: visible; 35 | display: inline-block; 36 | height: 15px; 37 | width: 15px; 38 | border: 1px solid $color-black; 39 | border-color: $color-black transparent transparent $color-black; 40 | transform: rotate(45deg); 41 | } 42 | -------------------------------------------------------------------------------- /music-admin/src/plugins/axios.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import { Message } from "element-ui"; 3 | 4 | const request = axios.create({ 5 | baseURL: "/apk", 6 | timeout: 5000, 7 | }); 8 | 9 | request.interceptors.request.use((config) => { 10 | const token = window.localStorage.getItem("token"); 11 | if (token) { 12 | config.headers.Authorization = token; 13 | } 14 | return config; 15 | }); 16 | 17 | // 响应拦截 18 | request.interceptors.response.use( 19 | (response) => { 20 | const res = response.data; 21 | if (res.code !== 200) { 22 | if (res.code === 500 && res.data === null) { 23 | console.log("暂无数据"); 24 | } else { 25 | let msg = res.msg || "Error"; 26 | Message.error(msg); 27 | return Promise.reject(new Error(msg)); 28 | } 29 | } 30 | return res; 31 | }, 32 | (error) => { 33 | console.info(error); 34 | Message.error(error.message); 35 | return Promise.reject(error); 36 | } 37 | ); 38 | 39 | export default request; 40 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/mapper/ConsumerMapper.java: -------------------------------------------------------------------------------- 1 | package com.xs.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.xs.domain.Consumer; 5 | import com.xs.dto.ConsumerDto; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.springframework.stereotype.Repository; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @author xs 13 | * description 针对表【consumer(前端用户)】的数据库操作Mapper 14 | * createDate 2022-10-11 12:58:48 15 | * Entity com.xs.domain.Consumer 16 | */ 17 | @Repository 18 | @Mapper 19 | public interface ConsumerMapper extends BaseMapper { 20 | 21 | /** 22 | * 查询所有用户 23 | */ 24 | List getAllConsumer(); 25 | 26 | /** 27 | * 获取用户总数 28 | */ 29 | int getConsumerCount(); 30 | 31 | /** 32 | * 按性别统计用户数量 33 | */ 34 | List getConsumerCountBySex(); 35 | 36 | /** 37 | * 用户登录 38 | */ 39 | Consumer login(String username, String password); 40 | } 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /music-view/src/api/Comment.js: -------------------------------------------------------------------------------- 1 | import axios from "../plugins/axios"; 2 | 3 | export function addComment(Comment) { 4 | return axios({ 5 | url: "comment/add", 6 | method: "POST", 7 | data: { 8 | ...Comment, 9 | }, 10 | }); 11 | } 12 | 13 | export function updateCommentUp(CommentDto) { 14 | return axios({ 15 | url: "comment/updateCommentUp", 16 | method: "PUT", 17 | data: { 18 | ...CommentDto, 19 | }, 20 | }); 21 | } 22 | 23 | export function cancelCommentUp(CommentDto) { 24 | return axios({ 25 | url: "comment/cancelCommentUp", 26 | method: "PUT", 27 | data: { 28 | ...CommentDto, 29 | }, 30 | }); 31 | } 32 | 33 | export function getAllCommentBySongId(songId) { 34 | return axios({ 35 | url: `comment/commentOfSongId/${songId}`, 36 | method: "GET", 37 | }); 38 | } 39 | 40 | export function getAllCommentBySongListId(songListId) { 41 | return axios({ 42 | url: `comment/commentOfSongListId/${songListId}`, 43 | method: "GET", 44 | }); 45 | } 46 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/mapper/RanksMapper.java: -------------------------------------------------------------------------------- 1 | package com.xs.mapper; 2 | 3 | import com.xs.domain.Ranks; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | import org.springframework.stereotype.Repository; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * @author xs 12 | * description 针对表【Rank(评价)】的数据库操作Mapper 13 | * createDate 2022-10-11 16:16:20 14 | * Entity com.xs.domain.Rank 15 | */ 16 | @Repository 17 | @Mapper 18 | public interface RanksMapper extends BaseMapper { 19 | 20 | /** 21 | * 按歌单id删除评价信息 22 | */ 23 | int deleteBySongListId(Long id); 24 | 25 | /** 26 | * 按用户id删除评价信息 27 | */ 28 | int deleteByConsumerId(Long id); 29 | 30 | /** 31 | * 获取所有歌单评价 32 | */ 33 | List getAllRanks(); 34 | 35 | /** 36 | * 获取指定歌单评价总分 37 | */ 38 | double[] getAllScore(Long id); 39 | 40 | /** 41 | * 获取指定歌单评价数量 42 | */ 43 | int getCountBySongListId(Long id); 44 | } 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /music-view/src/components/TheFooter.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 31 | 32 | 35 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/strategy/context/UploadStrategyContext.java: -------------------------------------------------------------------------------- 1 | package com.xs.strategy.context; 2 | 3 | import com.xs.strategy.UploadStrategy; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.stereotype.Service; 6 | import org.springframework.web.multipart.MultipartFile; 7 | 8 | import javax.annotation.Resource; 9 | import java.util.Map; 10 | 11 | import static com.xs.enums.UploadModeEnum.getStrategy; 12 | 13 | /** 14 | * 上传策略上下文 15 | */ 16 | @Service 17 | public class UploadStrategyContext { 18 | /** 19 | * 上传模式 20 | */ 21 | @Value("${upload.mode}") 22 | private String uploadMode; 23 | 24 | @Resource 25 | private Map uploadStrategyMap; 26 | 27 | /** 28 | * 执行上传策略 29 | * 30 | * @param file 文件 31 | * @param path 路径 32 | * @return {@link String} 文件地址 33 | */ 34 | public String executeUploadStrategy(MultipartFile file, String path) { 35 | return uploadStrategyMap.get(getStrategy(uploadMode)).uploadFile(file, path); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/config/MyAuthenticationEntryPoint.java: -------------------------------------------------------------------------------- 1 | package com.xs.config; 2 | 3 | import com.xs.common.Result; 4 | import com.xs.util.JacksonUtils; 5 | import org.springframework.security.core.AuthenticationException; 6 | import org.springframework.security.web.AuthenticationEntryPoint; 7 | import org.springframework.stereotype.Component; 8 | 9 | import javax.servlet.http.HttpServletRequest; 10 | import javax.servlet.http.HttpServletResponse; 11 | import java.io.IOException; 12 | import java.io.PrintWriter; 13 | 14 | /** 15 | * 未登录 拒绝访问 16 | */ 17 | @Component 18 | public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint { 19 | 20 | @Override 21 | public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException { 22 | response.setContentType("application/json;charset=utf-8"); 23 | PrintWriter out = response.getWriter(); 24 | Result result = Result.create(403, "请登录"); 25 | out.write(JacksonUtils.writeValueAsString(result)); 26 | out.flush(); 27 | out.close(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/mapper/RecentSongMapper.java: -------------------------------------------------------------------------------- 1 | package com.xs.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.xs.domain.RecentSong; 5 | import com.xs.domain.Singer; 6 | import com.xs.domain.SongList; 7 | import com.xs.vo.RecentSongVo; 8 | import org.apache.ibatis.annotations.Mapper; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * @author xs 14 | * description 针对表【recent_song】的数据库操作Mapper 15 | * createDate 2022-10-30 10:18:56 16 | * Entity com.xs.domain.RecentSong 17 | */ 18 | @Mapper 19 | public interface RecentSongMapper extends BaseMapper { 20 | 21 | /** 22 | * 查询所有播放记录 23 | */ 24 | List getAllRecentSong(); 25 | 26 | /** 27 | * 获取当前用户最近播放列表 28 | */ 29 | List getRecentSongByUserId(Long id); 30 | 31 | /** 32 | * 由最近播放歌曲查询其歌单信息 33 | */ 34 | List getSongListByRecentSong(Long userId); 35 | 36 | /** 37 | * 由最近播放歌曲查询其歌手信息 38 | */ 39 | List getSingerByRecentSong(Long userId); 40 | 41 | } 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /music-admin/src/api/Comment.js: -------------------------------------------------------------------------------- 1 | import axios from "../plugins/axios"; 2 | 3 | export function getAllCommentBySongId(songId) { 4 | return axios({ 5 | url: `comment/commentOfSongId/${songId}`, 6 | method: "GET", 7 | }); 8 | } 9 | 10 | export function getAllCommentBySongListId(songListId) { 11 | return axios({ 12 | url: `comment/commentOfSongListId/${songListId}`, 13 | method: "GET", 14 | }); 15 | } 16 | 17 | export function deleteComment(id) { 18 | return axios({ 19 | url: `comment/delete/${id}`, 20 | method: "DELETE", 21 | }); 22 | } 23 | 24 | export function deleteAllComment(ids) { 25 | return axios({ 26 | url: `comment/deleteAll/${ids}`, 27 | method: "DELETE", 28 | }); 29 | } 30 | 31 | export function getAllCommentByUserId(userId) { 32 | return axios({ 33 | url: `comment/commentOfUserId/${userId}`, 34 | method: "GET", 35 | }); 36 | } 37 | 38 | export function searchComment(searchVo) { 39 | return axios({ 40 | url: "/comment/searchComment", 41 | method: "POST", 42 | data: { 43 | ...searchVo, 44 | }, 45 | }); 46 | } 47 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/service/ListSongService.java: -------------------------------------------------------------------------------- 1 | package com.xs.service; 2 | 3 | import com.xs.common.Result; 4 | import com.xs.domain.ListSong; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | import com.xs.dto.ListSongByNameDto; 7 | import com.xs.vo.ListSongVo; 8 | 9 | /** 10 | * @author xs 11 | * description 针对表【list_song(歌单包含歌曲列表)】的数据库操作Service 12 | * createDate 2022-10-09 22:19:02 13 | */ 14 | public interface ListSongService extends IService { 15 | 16 | /** 17 | * 查找歌手对应的歌曲名称 18 | */ 19 | Result getSongNameBySingerId(Long singId); 20 | 21 | /** 22 | * 查询所有歌单歌曲 23 | */ 24 | Result getAll(Long id); 25 | 26 | /** 27 | * 添加歌单歌曲 28 | */ 29 | Result addListSong(ListSongVo listSongVo); 30 | 31 | /** 32 | * 删除歌单歌曲 33 | */ 34 | Result deleteListSong(Long id); 35 | 36 | /** 37 | * 批量删除歌曲 38 | */ 39 | Result deleteAllListSong(Long[] ids); 40 | 41 | /** 42 | * 按名称查询歌单歌曲 43 | */ 44 | Result getListSongByName(ListSongByNameDto listSongByNameDto); 45 | } 46 | -------------------------------------------------------------------------------- /music-view/src/App.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 39 | 40 | 43 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/config/CrossConfig.java: -------------------------------------------------------------------------------- 1 | package com.xs.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.cors.CorsConfiguration; 6 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 7 | import org.springframework.web.filter.CorsFilter; 8 | 9 | @Configuration 10 | public class CrossConfig { 11 | 12 | @Bean 13 | public CorsFilter corsFilter(){ 14 | //1. 创建CorsConfiguration对象 15 | CorsConfiguration corsConfiguration = new CorsConfiguration(); 16 | corsConfiguration.addAllowedOrigin("*");//设置允许那些域来访问,*是通配符,允许所有域 17 | corsConfiguration.addAllowedHeader("*");//请求头字段 18 | corsConfiguration.addAllowedMethod("*");//请求方式(GET,POST,DELETE,PUT) 19 | //设置source 20 | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 21 | source.registerCorsConfiguration("/**",corsConfiguration);//1.映射路径 2.传入CorsConfiguration对象 22 | return new CorsFilter(source); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /music-view/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "music-view", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build" 8 | }, 9 | "dependencies": { 10 | "axios": "^0.24.0", 11 | "core-js": "^3.6.5", 12 | "element-ui": "^2.15.6", 13 | "normalize.css": "7.0.0", 14 | "nprogress": "^0.2.0", 15 | "webpack": "^4.36.0", 16 | "html-webpack-plugin": "^4.0.0", 17 | "script-ext-html-webpack-plugin": "^2.1.5", 18 | "vue": "^2.6.11", 19 | "vue-router": "^3.5.1", 20 | "vuex": "^3.2.0" 21 | }, 22 | "devDependencies": { 23 | "@vue/cli-plugin-babel": "~4.5.0", 24 | "@vue/cli-plugin-router": "~4.5.0", 25 | "@vue/cli-plugin-vuex": "~4.5.0", 26 | "@vue/cli-service": "~4.5.0", 27 | "node-sass": "^6.0.1", 28 | "sass-loader": "^10.0.1", 29 | "vue-template-compiler": "^2.6.11" 30 | }, 31 | "eslintConfig": { 32 | "root": true, 33 | "env": { 34 | "node": true 35 | } 36 | }, 37 | "browserslist": [ 38 | "> 1%", 39 | "last 2 versions" 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /music-admin/src/api/ListSong.js: -------------------------------------------------------------------------------- 1 | import axios from "../plugins/axios"; 2 | 3 | export function getSongNameBySingerId(singerId) { 4 | return axios({ 5 | url: `listSong/songOfName/${singerId}`, 6 | method: "GET", 7 | }); 8 | } 9 | 10 | export function getAllListSongBySongListId(id) { 11 | return axios({ 12 | url: `listSong/all/${id}`, 13 | method: "GET", 14 | }); 15 | } 16 | 17 | export function addListSong(ListSongVo) { 18 | return axios({ 19 | url: "listSong/add", 20 | method: "POST", 21 | data: { 22 | ...ListSongVo, 23 | }, 24 | }); 25 | } 26 | 27 | export function deleteAllListSong(ids) { 28 | return axios({ 29 | url: `listSong/deleteAll/${ids}`, 30 | method: "DELETE", 31 | }); 32 | } 33 | 34 | export function deleteListSong(id) { 35 | return axios({ 36 | url: `listSong/delete/${id}`, 37 | method: "DELETE", 38 | }); 39 | } 40 | 41 | export function getListSongByName(ListSongByNameDto) { 42 | return axios({ 43 | url: "listSong/listSongOfName", 44 | method: "POST", 45 | data: { 46 | ...ListSongByNameDto, 47 | }, 48 | }); 49 | } 50 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/domain/Singer.java: -------------------------------------------------------------------------------- 1 | package com.xs.domain; 2 | 3 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 4 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 5 | import lombok.Data; 6 | 7 | import java.io.Serial; 8 | import java.io.Serializable; 9 | import java.util.Date; 10 | 11 | /** 12 | * 歌手 13 | * TableName singer 14 | */ 15 | @Data 16 | public class Singer implements Serializable { 17 | 18 | /** 19 | * 主键 20 | */ 21 | @JsonSerialize(using = ToStringSerializer.class) 22 | private Long id; 23 | 24 | /** 25 | * 姓名 26 | */ 27 | private String name; 28 | 29 | /** 30 | * 性别(1男0女) 31 | */ 32 | private Integer sex; 33 | 34 | /** 35 | * 头像 36 | */ 37 | private String pic; 38 | 39 | /** 40 | * 生日 41 | */ 42 | private Date birth; 43 | 44 | /** 45 | * 所属地区 46 | */ 47 | private String location; 48 | 49 | /** 50 | * 简介 51 | */ 52 | private String introduction; 53 | 54 | @Serial 55 | private static final long serialVersionUID = 1L; 56 | } -------------------------------------------------------------------------------- /music-view/src/api/ListSong.js: -------------------------------------------------------------------------------- 1 | import axios from "../plugins/axios"; 2 | 3 | export function getSongNameBySingerId(singerId) { 4 | return axios({ 5 | url: `listSong/songOfName/${singerId}`, 6 | method: "GET", 7 | }); 8 | } 9 | 10 | export function getAllListSongBySongListId(id) { 11 | return axios({ 12 | url: `listSong/all/${id}`, 13 | method: "GET", 14 | }); 15 | } 16 | 17 | export function addListSong(ListSongVo) { 18 | return axios({ 19 | url: "listSong/add", 20 | method: "POST", 21 | data: { 22 | ...ListSongVo, 23 | }, 24 | }); 25 | } 26 | 27 | export function deleteAllListSong(ids) { 28 | return axios({ 29 | url: `listSong/deleteAll/${ids}`, 30 | method: "DELETE", 31 | }); 32 | } 33 | 34 | export function deleteListSong(id) { 35 | return axios({ 36 | url: `listSong/delete/${id}`, 37 | method: "DELETE", 38 | }); 39 | } 40 | 41 | export function getListSongByName(ListSongByNameDto) { 42 | return axios({ 43 | url: "listSong/listSongOfName", 44 | method: "POST", 45 | data: { 46 | ...ListSongByNameDto, 47 | }, 48 | }); 49 | } 50 | -------------------------------------------------------------------------------- /music-view/src/pages/LeaderBoard.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 39 | 40 | 43 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/dto/CollectDto.java: -------------------------------------------------------------------------------- 1 | package com.xs.dto; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 6 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | 10 | import java.io.Serial; 11 | import java.io.Serializable; 12 | import java.time.LocalDateTime; 13 | 14 | @Data 15 | @Builder 16 | public class CollectDto implements Serializable { 17 | 18 | /** 19 | * 主键 20 | */ 21 | @JsonSerialize(using = ToStringSerializer.class) 22 | private Long id; 23 | 24 | /** 25 | * 用户头像 26 | */ 27 | private String avatar; 28 | 29 | /** 30 | * 用户名 31 | */ 32 | private String username; 33 | 34 | /** 35 | * 收藏内容 36 | */ 37 | private String content; 38 | 39 | /** 40 | * 收藏时间 41 | */ 42 | @TableField(fill = FieldFill.INSERT_UPDATE) 43 | private LocalDateTime createTime; 44 | 45 | @Serial 46 | private static final long serialVersionUID = 1L; 47 | } 48 | -------------------------------------------------------------------------------- /music-view/src/components/TheAside.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 42 | 43 | 46 | -------------------------------------------------------------------------------- /music-admin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "music-admin", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build" 8 | }, 9 | "dependencies": { 10 | "axios": "^0.24.0", 11 | "core-js": "^3.6.5", 12 | "echarts": "^4.8.0", 13 | "element-ui": "^2.15.6", 14 | "normalize.css": "7.0.0", 15 | "nprogress": "^0.2.0", 16 | "script-ext-html-webpack-plugin": "^2.1.5", 17 | "webpack": "^4.0.0", 18 | "html-webpack-plugin": "^4.0.0", 19 | "zrender": "^4.3.1", 20 | "v-charts": "^1.19.0", 21 | "vue-echarts": "^5.0.0-beta.0", 22 | "vue": "^2.6.11", 23 | "vue-router": "^3.5.1", 24 | "vuex": "^3.2.0" 25 | }, 26 | "devDependencies": { 27 | "@vue/cli-plugin-babel": "~4.5.0", 28 | "@vue/cli-plugin-router": "~4.5.0", 29 | "@vue/cli-plugin-vuex": "~4.5.0", 30 | "@vue/cli-service": "~4.5.0", 31 | "vue-template-compiler": "^2.6.11" 32 | }, 33 | "eslintConfig": { 34 | "root": true, 35 | "env": { 36 | "node": true 37 | } 38 | }, 39 | "browserslist": [ 40 | "> 1%", 41 | "last 2 versions" 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /music-view/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: 600px; 9 | 10 | .title { 11 | text-align: center; 12 | } 13 | > ul { 14 | width: 100%; 15 | padding-bottom: 50px; 16 | > li { 17 | border-bottom: 1px solid rgba(0, 0, 0, 0.1); 18 | display: block; 19 | height: 50px; 20 | line-height: 50px; 21 | text-indent: 20px; 22 | cursor: pointer; 23 | } 24 | } 25 | } 26 | 27 | .song-item { 28 | @include layout; 29 | white-space: nowrap; 30 | overflow: hidden; 31 | text-overflow: ellipsis; 32 | .item-index { 33 | width: 5%; 34 | } 35 | .item-title { 36 | width: 25%; 37 | } 38 | .item-name { 39 | width: 25%; 40 | } 41 | .item-intro { 42 | width: 30%; 43 | } 44 | .item-count { 45 | width: 10%; 46 | } 47 | } 48 | 49 | .is-play { 50 | color: $color-blue-active; 51 | font-weight: bold; 52 | } 53 | 54 | .icon { 55 | @include icon(1.3em, $color-blue-active); 56 | vertical-align: -0.3em; 57 | right: 5px; 58 | } 59 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/controller/UploadController.java: -------------------------------------------------------------------------------- 1 | package com.xs.controller; 2 | 3 | import com.xs.enums.FilePathEnum; 4 | import com.xs.strategy.context.UploadStrategyContext; 5 | import com.xs.vo.R; 6 | import org.springframework.web.bind.annotation.PostMapping; 7 | import org.springframework.web.bind.annotation.RequestParam; 8 | import org.springframework.web.bind.annotation.RestController; 9 | import org.springframework.web.multipart.MultipartFile; 10 | 11 | import javax.annotation.Resource; 12 | 13 | @RestController 14 | public class UploadController { 15 | 16 | @Resource 17 | private UploadStrategyContext uploadStrategyContext; 18 | 19 | /** 20 | * 上传头像 21 | */ 22 | @PostMapping("/upload") 23 | public R upload(@RequestParam("pic") MultipartFile file) { 24 | return R.ok(uploadStrategyContext.executeUploadStrategy(file, FilePathEnum.AVATAR.getPath())); 25 | } 26 | 27 | /** 28 | * 上传mp3 29 | */ 30 | @PostMapping("/uploadAudio") 31 | public R uploadAudio(@RequestParam("mp3") MultipartFile file) { 32 | return R.ok(uploadStrategyContext.executeUploadStrategy(file, FilePathEnum.VOICE.getPath())); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/mapper/ListSongMapper.java: -------------------------------------------------------------------------------- 1 | package com.xs.mapper; 2 | 3 | import com.xs.domain.ListSong; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import com.xs.dto.ListSongDto; 6 | import com.xs.vo.ListSongVo; 7 | import org.apache.ibatis.annotations.Mapper; 8 | import org.springframework.stereotype.Repository; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * @author xs 14 | * description 针对表【list_song(歌单包含歌曲列表)】的数据库操作Mapper 15 | * createDate 2022-10-09 22:19:02 16 | * Entity com.xs.domain.ListSong 17 | */ 18 | @Repository 19 | @Mapper 20 | public interface ListSongMapper extends BaseMapper { 21 | 22 | /** 23 | * 查找歌手对应的歌曲名称 24 | */ 25 | List getSongNameBySingerId(Long singerId); 26 | 27 | /** 28 | * 查询所有歌单歌曲 29 | */ 30 | List getAll(Long id); 31 | 32 | /** 33 | * 添加歌单歌曲 34 | */ 35 | int addListSong(Long songId, Long songListId); 36 | 37 | /** 38 | * 按歌单id删除歌单歌曲信息 39 | */ 40 | int deleteBySongListId(Long id); 41 | 42 | /** 43 | * 查询某个歌单中的歌曲信息 44 | */ 45 | List getAllListSongBySongListId(Long songListId); 46 | 47 | } 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/mapper/SongListMapper.java: -------------------------------------------------------------------------------- 1 | package com.xs.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.xs.domain.SongList; 5 | import com.xs.vo.SongListVo; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.springframework.stereotype.Repository; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @author xs 13 | * description 针对表【song_list(歌单)】的数据库操作Mapper 14 | * createDate 2022-10-09 16:10:47 15 | * Entity com.xs.domain.SongList 16 | */ 17 | @Repository 18 | @Mapper 19 | public interface SongListMapper extends BaseMapper { 20 | 21 | /** 22 | * 查询所有歌单 23 | */ 24 | List getAllSongList(); 25 | 26 | /** 27 | * 获取歌手总数 28 | */ 29 | int getSongListCount(); 30 | 31 | /** 32 | * 按歌单类型分组查询的歌单数量 33 | */ 34 | List getSongListCountByStyle(); 35 | 36 | /** 37 | * 按歌单风格名称查询所有歌单 38 | */ 39 | List getSongListByStyle(String style); 40 | 41 | /** 42 | * 获取所有歌单风格 43 | */ 44 | String[] getAllStyle(); 45 | 46 | /** 47 | * 按风格查询歌单数量 48 | */ 49 | Integer getAllSongListCountByStyle(String style); 50 | } 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /music-view/src/pages/Search.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 40 | 41 | 44 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/vo/CommentVo.java: -------------------------------------------------------------------------------- 1 | package com.xs.vo; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 6 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | 10 | import java.io.Serial; 11 | import java.io.Serializable; 12 | import java.time.LocalDateTime; 13 | 14 | @Data 15 | @Builder 16 | public class CommentVo implements Serializable { 17 | 18 | /** 19 | * 主键 20 | */ 21 | @JsonSerialize(using = ToStringSerializer.class) 22 | private Long id; 23 | 24 | /** 25 | * 用户头像 26 | */ 27 | private String avatar; 28 | 29 | /** 30 | * 用户名 31 | */ 32 | private String username; 33 | 34 | /** 35 | * 评论内容 36 | */ 37 | private String content; 38 | 39 | /** 40 | * 评论时间 41 | */ 42 | @TableField(fill = FieldFill.INSERT_UPDATE) 43 | private LocalDateTime createTime; 44 | 45 | /** 46 | * 评论点赞数 47 | */ 48 | private Integer up; 49 | 50 | @Serial 51 | private static final long serialVersionUID = 1L; 52 | 53 | } 54 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/enums/StatusCodeEnum.java: -------------------------------------------------------------------------------- 1 | package com.xs.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * 接口状态码枚举 8 | **/ 9 | @Getter 10 | @AllArgsConstructor 11 | public enum StatusCodeEnum { 12 | /** 13 | * 成功 14 | */ 15 | SUCCESS(20000, "操作成功"), 16 | /** 17 | * 未登录 18 | */ 19 | NO_LOGIN(40001, "用户未登录"), 20 | /** 21 | * 没有操作权限 22 | */ 23 | AUTHORIZED(40300, "没有操作权限"), 24 | /** 25 | * 系统异常 26 | */ 27 | SYSTEM_ERROR(50000, "系统异常"), 28 | /** 29 | * 失败 30 | */ 31 | FAIL(51000, "操作失败"), 32 | /** 33 | * 参数校验失败 34 | */ 35 | VALID_ERROR(52000, "参数格式不正确"), 36 | /** 37 | * 用户名已存在 38 | */ 39 | USERNAME_EXIST(52001, "用户名已存在"), 40 | /** 41 | * 用户名不存在 42 | */ 43 | USERNAME_NOT_EXIST(52002, "用户名不存在"), 44 | /** 45 | * qq登录错误 46 | */ 47 | QQ_LOGIN_ERROR(53001, "qq登录错误"), 48 | /** 49 | * 微博登录错误 50 | */ 51 | WEIBO_LOGIN_ERROR(53002, "微博登录错误"); 52 | 53 | /** 54 | * 状态码 55 | */ 56 | private final Integer code; 57 | 58 | /** 59 | * 描述 60 | */ 61 | private final String desc; 62 | 63 | } 64 | -------------------------------------------------------------------------------- /music-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8889 3 | 4 | spring: 5 | 6 | main: 7 | allow-circular-references: true 8 | 9 | jackson: 10 | time-zone: GMT+8 11 | 12 | servlet: 13 | multipart: 14 | max-file-size: 50MB 15 | max-request-size: 100MB 16 | 17 | #在windows本地部署不用配置,可以删掉这段配置 18 | redis: 19 | host: #在服务器上则写上服务器的ip地址 20 | port: 6379 21 | password: #密码(默认没有密码) 22 | 23 | datasource: 24 | druid: 25 | driver-class-name: com.mysql.cj.jdbc.Driver 26 | url: jdbc:mysql://ip地址:端口号(默认为3306)/music?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai 27 | username: #用户名 28 | password: #密码 29 | 30 | token: 31 | expireTime: 259200000 32 | secretKey: abcdefghijklmnopqrstuvwxyz 33 | 34 | upload: 35 | mode: local 36 | 37 | local: 38 | # nginx映射本地文件路径 39 | url: http://localhost/ 40 | #windows本地:http://localhost/ 41 | #服务器:http://ip地址/ 或 https://域名/ 42 | # 本地文件存储路径 43 | path: /upload/ 44 | #windows本地:nginx默认挂载在C盘 若nginx挂载点在C:/upload路径 则配置为:/upload/ 45 | #服务器:若nginx挂载点在/usr/local/upload路径 则配置为:/usr/local/upload/ 46 | 47 | mybatis-plus: 48 | global-config: 49 | db-config: 50 | id-type: assign_id 51 | -------------------------------------------------------------------------------- /music-view/src/api/Collect.js: -------------------------------------------------------------------------------- 1 | import axios from "../plugins/axios"; 2 | 3 | export function addCollect(Collect) { 4 | return axios({ 5 | url: "collect/add", 6 | method: "POST", 7 | data: { 8 | ...Collect, 9 | }, 10 | }); 11 | } 12 | 13 | export function cancelCollect(CollectVo) { 14 | return axios({ 15 | url: "collect/cancel", 16 | method: "DELETE", 17 | data: { 18 | ...CollectVo, 19 | }, 20 | }); 21 | } 22 | 23 | export function getCollectBySongId(CollectVo) { 24 | return axios({ 25 | url: "collect/getCollectBySongId", 26 | method: "POST", 27 | data: { 28 | ...CollectVo, 29 | }, 30 | }); 31 | } 32 | 33 | export function getAllCollectByConsumerId(userId) { 34 | return axios({ 35 | url: `collect/collectOfConsumerId/${userId}`, 36 | method: "GET", 37 | }); 38 | } 39 | 40 | export function getCollectBySongListId(CollectVo) { 41 | return axios({ 42 | url: "collect/getCollectBySongListId", 43 | method: "POST", 44 | data: { 45 | ...CollectVo, 46 | }, 47 | }); 48 | } 49 | 50 | export function getAllCollectSongListByUserId(userId) { 51 | return axios({ 52 | url: `collect/collectSongListOfUserId/${userId}`, 53 | method: "GET", 54 | }); 55 | } 56 | -------------------------------------------------------------------------------- /music-view/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 | li { 31 | display: block; 32 | height: 40px; 33 | line-height: 40px; 34 | font-size: 18px; 35 | padding: 0 10px; 36 | box-sizing: border-box; 37 | border-radius: 5px; 38 | margin-right: 2px; 39 | cursor: pointer; 40 | 41 | &:hover { 42 | background-color: $color-blue-active; 43 | color: $color-white; 44 | } 45 | &:active { 46 | background-color: $color-blue-shallow; 47 | } 48 | } 49 | } 50 | 51 | .activeColor { 52 | background-color: $color-blue-shallow !important; 53 | color: $color-white; 54 | } 55 | 56 | /* 右边内容 */ 57 | .contentCol { 58 | flex: 1; 59 | padding-top: 20px; 60 | } 61 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/vo/RecentSongVo.java: -------------------------------------------------------------------------------- 1 | package com.xs.vo; 2 | 3 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 4 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | 8 | import java.io.Serial; 9 | import java.io.Serializable; 10 | 11 | @Builder 12 | @Data 13 | public class RecentSongVo implements Serializable { 14 | 15 | /** 16 | * 主键 17 | */ 18 | @JsonSerialize(using = ToStringSerializer.class) 19 | private Long id; 20 | 21 | /** 22 | * 歌手id 23 | */ 24 | @JsonSerialize(using = ToStringSerializer.class) 25 | private Long singerId; 26 | 27 | /** 28 | * 歌名 29 | */ 30 | private String name; 31 | 32 | /** 33 | * 歌手名 34 | */ 35 | private String singerName; 36 | 37 | /** 38 | * 简介 39 | */ 40 | private String introduction; 41 | 42 | /** 43 | * 歌曲图片 44 | */ 45 | private String pic; 46 | 47 | /** 48 | * 歌词 49 | */ 50 | private String lyric; 51 | 52 | /** 53 | * 歌曲地址 54 | */ 55 | private String url; 56 | 57 | /** 58 | * 播放量 59 | */ 60 | private Integer playCount; 61 | 62 | @Serial 63 | private static final long serialVersionUID = 1L; 64 | } 65 | -------------------------------------------------------------------------------- /music-view/src/components/ContentList.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 40 | 41 | 44 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/mapper/SingerMapper.java: -------------------------------------------------------------------------------- 1 | package com.xs.mapper; 2 | 3 | import com.xs.domain.Singer; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import com.xs.dto.SingerDto; 6 | import com.xs.vo.SingerVo; 7 | import org.apache.ibatis.annotations.Mapper; 8 | import org.springframework.stereotype.Repository; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * @author xs 14 | * description 针对表【singer(歌手)】的数据库操作Mapper 15 | * createDate 2022-10-05 15:08:13 16 | * Entity com.xs.domain.Singer 17 | */ 18 | @Repository 19 | @Mapper 20 | public interface SingerMapper extends BaseMapper { 21 | 22 | /** 23 | * 查询所有歌手 24 | */ 25 | List selectAllSinger(); 26 | 27 | /** 28 | * 按歌手名称查询 29 | */ 30 | List getSingerByName(String name); 31 | 32 | /** 33 | * 获取歌手总数 34 | */ 35 | int getSingerCount(); 36 | 37 | /** 38 | * 按歌手id查询歌手名 39 | */ 40 | String getSingerNameById(Long id); 41 | 42 | /** 43 | * 按性别分组查询歌手数量 44 | */ 45 | List getSingerCountBySex(); 46 | 47 | /** 48 | * 按地区分组查询歌手数量 49 | */ 50 | List getSingerCountByLocation(); 51 | 52 | /** 53 | * 按性别查询歌手数量 54 | */ 55 | Integer getAllSingerCountBySex(Integer sex); 56 | } 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /music-admin/src/api/Consumer.js: -------------------------------------------------------------------------------- 1 | import axios from "../plugins/axios"; 2 | 3 | export function getAllConsumer() { 4 | return axios({ 5 | url: "consumer/all", 6 | method: "GET", 7 | }); 8 | } 9 | 10 | export function updateConsumer(Consumer) { 11 | return axios({ 12 | url: "consumer/update", 13 | method: "PUT", 14 | data: { 15 | ...Consumer, 16 | }, 17 | }); 18 | } 19 | 20 | export function getConsumerByName(name) { 21 | return axios({ 22 | url: `consumer/consumerOfName/${name}`, 23 | method: "GET", 24 | }); 25 | } 26 | 27 | export function addConsumer(Consumer) { 28 | return axios({ 29 | url: "consumer/add", 30 | method: "POST", 31 | data: { 32 | ...Consumer, 33 | }, 34 | }); 35 | } 36 | 37 | export function deleteConsumer(id) { 38 | return axios({ 39 | url: `consumer/delete/${id}`, 40 | method: "DELETE", 41 | }); 42 | } 43 | 44 | export function deleteAllConsumer(ids) { 45 | return axios({ 46 | url: `consumer/deleteAll/${ids}`, 47 | method: "DELETE", 48 | }); 49 | } 50 | 51 | export function getConsumerCount() { 52 | return axios({ 53 | url: "consumer/getCount", 54 | method: "GET", 55 | }); 56 | } 57 | 58 | export function getConsumerCountBySex() { 59 | return axios({ 60 | url: "consumer/getCountBySex", 61 | method: "GET", 62 | }); 63 | } 64 | -------------------------------------------------------------------------------- /music-admin/src/api/Song.js: -------------------------------------------------------------------------------- 1 | import axios from "../plugins/axios"; 2 | 3 | export function addSong(Song) { 4 | return axios({ 5 | url: "song/add", 6 | method: "POST", 7 | data: { 8 | ...Song, 9 | }, 10 | }); 11 | } 12 | 13 | export function getAllSongBySingerId(id) { 14 | return axios({ 15 | url: `song/allSong/${id}`, 16 | method: "GET", 17 | }); 18 | } 19 | 20 | export function getAllSongByName(name) { 21 | return axios({ 22 | url: `song/songOfName/${name}`, 23 | method: "GET", 24 | }); 25 | } 26 | 27 | export function updateSong(Song) { 28 | return axios({ 29 | url: "song/update", 30 | method: "PUT", 31 | data: { 32 | ...Song, 33 | }, 34 | }); 35 | } 36 | 37 | export function deleteSong(id) { 38 | return axios({ 39 | url: `song/delete/${id}`, 40 | method: "DELETE", 41 | }); 42 | } 43 | 44 | export function deleteAllSong(ids) { 45 | return axios({ 46 | url: `song/deleteAll/${ids}`, 47 | method: "DELETE", 48 | }); 49 | } 50 | 51 | export function getSongCount() { 52 | return axios({ 53 | url: "song/getCount", 54 | method: "GET", 55 | }); 56 | } 57 | 58 | export function getAllSongByNameAndSingerId(SongVo) { 59 | return axios({ 60 | url: "song/songOfName", 61 | method: "POST", 62 | data: { 63 | ...SongVo, 64 | }, 65 | }); 66 | } 67 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/enums/FileExtEnum.java: -------------------------------------------------------------------------------- 1 | package com.xs.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * 文件扩展名枚举 8 | */ 9 | @Getter 10 | @AllArgsConstructor 11 | public enum FileExtEnum { 12 | /** 13 | * jpg文件 14 | */ 15 | JPG(".jpg", "jpg文件"), 16 | /** 17 | * png文件 18 | */ 19 | PNG(".png", "png文件"), 20 | /** 21 | * Jpeg文件 22 | */ 23 | JPEG(".jpeg", "jpeg文件"), 24 | /** 25 | * wav文件 26 | */ 27 | WAV(".wav", "wav文件"), 28 | /** 29 | * md文件 30 | */ 31 | MD(".md","markdown文件"), 32 | /** 33 | * txt文件 34 | */ 35 | TXT(".txt","txt文件"), 36 | 37 | /** 38 | * 音频文件 39 | */ 40 | MP3(".mp3", "mp3文件"); 41 | 42 | /** 43 | * 获取文件格式 44 | * 45 | * @param extName 扩展名 46 | * @return {@link FileExtEnum} 文件格式 47 | */ 48 | public static FileExtEnum getFileExt(String extName) { 49 | for (FileExtEnum value : FileExtEnum.values()) { 50 | if (value.getExtName().equalsIgnoreCase(extName)) { 51 | return value; 52 | } 53 | } 54 | return null; 55 | } 56 | 57 | /** 58 | * 扩展名 59 | */ 60 | private final String extName; 61 | 62 | /** 63 | * 描述 64 | */ 65 | private final String desc; 66 | 67 | } 68 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/common/Result.java: -------------------------------------------------------------------------------- 1 | package com.xs.common; 2 | 3 | import lombok.Data; 4 | import lombok.NoArgsConstructor; 5 | 6 | import java.io.Serial; 7 | import java.io.Serializable; 8 | 9 | /** 10 | * 封装响应结果 11 | */ 12 | @NoArgsConstructor 13 | @Data 14 | public class Result implements Serializable { 15 | private Integer code; 16 | private String msg; 17 | private Object data; 18 | 19 | private Result(Integer code, String msg) { 20 | this.code = code; 21 | this.msg = msg; 22 | this.data = null; 23 | } 24 | 25 | private Result(Integer code, String msg, Object data) { 26 | this.code = code; 27 | this.msg = msg; 28 | this.data = data; 29 | } 30 | 31 | public static Result ok(String msg, Object data) { 32 | return new Result(200, msg, data); 33 | } 34 | 35 | public static Result ok(String msg) { 36 | return new Result(200, msg); 37 | } 38 | 39 | public static Result error(String msg) { 40 | return new Result(500, msg); 41 | } 42 | 43 | public static Result error() { 44 | return new Result(500, "异常错误"); 45 | } 46 | 47 | public static Result create(Integer code, String msg, Object data) { 48 | return new Result(code, msg, data); 49 | } 50 | 51 | public static Result create(Integer code, String msg) { 52 | return new Result(code, msg); 53 | } 54 | 55 | @Serial 56 | private static final long serialVersionUID = 1L; 57 | } 58 | -------------------------------------------------------------------------------- /music-view/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 | img { 36 | width: 100%; 37 | } 38 | } 39 | 40 | .info { 41 | color: $color-black; 42 | font-size: 20px; 43 | font-weight: 500; 44 | margin-top: -80px; 45 | padding: 30px 40px 30px 60px; 46 | li { 47 | width: 100%; 48 | height: 40px; 49 | } 50 | } 51 | } 52 | 53 | /*右*/ 54 | .album-content { 55 | margin-left: 300px; 56 | padding: 30px 100px; 57 | .intro { 58 | font-size: 20px; 59 | span { 60 | color: rgba(0, 0, 0, 0.5); 61 | } 62 | } 63 | 64 | .content { 65 | margin-top: 50px; 66 | } 67 | } 68 | 69 | -------------------------------------------------------------------------------- /music-view/src/assets/css/leader-board.scss: -------------------------------------------------------------------------------- 1 | @import "var.scss"; 2 | 3 | .leader-board-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 | .leader-board-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 | img { 36 | width: 100%; 37 | } 38 | } 39 | 40 | .info { 41 | color: $color-black; 42 | font-size: 20px; 43 | font-weight: 500; 44 | margin-top: -80px; 45 | padding: 30px 40px 30px 60px; 46 | li { 47 | width: 100%; 48 | height: 40px; 49 | } 50 | } 51 | } 52 | 53 | /*右*/ 54 | .album-content { 55 | margin-left: 300px; 56 | padding: 30px 100px; 57 | .intro { 58 | font-size: 20px; 59 | span { 60 | color: rgba(0, 0, 0, 0.5); 61 | } 62 | } 63 | 64 | .content { 65 | margin-top: 50px; 66 | } 67 | } 68 | 69 | -------------------------------------------------------------------------------- /music-view/src/components/Swiper.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 46 | 47 | 50 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/config/RedisConfig.java: -------------------------------------------------------------------------------- 1 | package com.xs.config; 2 | 3 | import com.xs.util.FastJsonRedisSerializer; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.data.redis.connection.RedisConnectionFactory; 7 | import org.springframework.data.redis.core.RedisTemplate; 8 | import org.springframework.data.redis.serializer.StringRedisSerializer; 9 | 10 | @Configuration 11 | public class RedisConfig { 12 | 13 | @Bean 14 | @SuppressWarnings(value = { "unchecked", "rawtypes" }) 15 | public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) 16 | { 17 | RedisTemplate template = new RedisTemplate<>(); 18 | template.setConnectionFactory(connectionFactory); 19 | 20 | FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class); 21 | 22 | // 使用StringRedisSerializer来序列化和反序列化redis的key值 23 | template.setKeySerializer(new StringRedisSerializer()); 24 | template.setValueSerializer(serializer); 25 | 26 | // Hash的key也采用StringRedisSerializer的序列化方式 27 | template.setHashKeySerializer(new StringRedisSerializer()); 28 | template.setHashValueSerializer(serializer); 29 | 30 | template.afterPropertiesSet(); 31 | return template; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/domain/Collect.java: -------------------------------------------------------------------------------- 1 | package com.xs.domain; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 6 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 7 | import lombok.Data; 8 | 9 | import java.io.Serial; 10 | import java.io.Serializable; 11 | import java.time.LocalDateTime; 12 | 13 | /** 14 | * 收藏 15 | * TableName collect 16 | */ 17 | @Data 18 | public class Collect implements Serializable { 19 | /** 20 | * 主键 21 | */ 22 | @JsonSerialize(using = ToStringSerializer.class) 23 | private Long id; 24 | 25 | /** 26 | * 用户id 27 | */ 28 | @JsonSerialize(using = ToStringSerializer.class) 29 | private Long userId; 30 | 31 | /** 32 | * 收藏类型(1歌单0歌曲) 33 | */ 34 | private Integer type; 35 | 36 | /** 37 | * 歌曲id 38 | */ 39 | @JsonSerialize(using = ToStringSerializer.class) 40 | private Long songId; 41 | 42 | /** 43 | * 歌单id 44 | */ 45 | @JsonSerialize(using = ToStringSerializer.class) 46 | private Long songListId; 47 | 48 | /** 49 | * 收藏时间 50 | */ 51 | @TableField(fill = FieldFill.INSERT_UPDATE) 52 | private LocalDateTime createTime; 53 | 54 | @Serial 55 | private static final long serialVersionUID = 1L; 56 | } -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/domain/RecentSong.java: -------------------------------------------------------------------------------- 1 | package com.xs.domain; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 6 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 7 | import lombok.Data; 8 | 9 | import java.io.Serial; 10 | import java.io.Serializable; 11 | import java.time.LocalDateTime; 12 | 13 | /** 14 | * TableName recent_song 15 | */ 16 | @Data 17 | public class RecentSong implements Serializable { 18 | 19 | /** 20 | * 主键 21 | */ 22 | @JsonSerialize(using = ToStringSerializer.class) 23 | private Long id; 24 | 25 | /** 26 | * 用户id 27 | */ 28 | @JsonSerialize(using = ToStringSerializer.class) 29 | private Long userId; 30 | 31 | /** 32 | * 歌曲id 33 | */ 34 | @JsonSerialize(using = ToStringSerializer.class) 35 | private Long songId; 36 | 37 | /** 38 | * 播放量 39 | */ 40 | private Integer count; 41 | 42 | /** 43 | * 创建时间 44 | */ 45 | @TableField(fill = FieldFill.INSERT_UPDATE) 46 | private LocalDateTime createTime; 47 | 48 | /** 49 | * 更新时间 50 | */ 51 | @TableField(fill = FieldFill.INSERT_UPDATE) 52 | private LocalDateTime updateTime; 53 | 54 | @Serial 55 | private static final long serialVersionUID = 1L; 56 | } -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/service/ConsumerService.java: -------------------------------------------------------------------------------- 1 | package com.xs.service; 2 | 3 | import com.xs.common.Result; 4 | import com.xs.domain.Consumer; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | import com.xs.vo.LoginVo; 7 | 8 | import javax.servlet.http.HttpSession; 9 | 10 | /** 11 | * @author xs 12 | * description 针对表【consumer(前端用户)】的数据库操作Service 13 | * createDate 2022-10-11 12:58:48 14 | */ 15 | public interface ConsumerService extends IService { 16 | 17 | /** 18 | * 查询所有用户 19 | */ 20 | Result getAll(); 21 | 22 | /** 23 | * 修改用户信息 24 | */ 25 | Result updateConsumer(Consumer consumer); 26 | 27 | /** 28 | * 按用户名称查询用户信息 29 | */ 30 | Result getConsumerByName(String name); 31 | 32 | /** 33 | * 添加用户 34 | */ 35 | Result addConsumer(Consumer consumer); 36 | 37 | /** 38 | * 删除用户 39 | */ 40 | Result deleteConsumer(Long id); 41 | 42 | /** 43 | * 批量删除用户 44 | */ 45 | Result deleteAllConsumer(Long[] ids); 46 | 47 | /** 48 | * 获取用户总数 49 | */ 50 | Result getConsumerCount(); 51 | 52 | /** 53 | * 按性别分组查询用户数量 54 | */ 55 | Result getConsumerCountBySex(); 56 | 57 | /** 58 | * 用户登录 59 | */ 60 | Result login(LoginVo loginVo); 61 | 62 | /** 63 | * 按id查询用户信息 64 | */ 65 | Result getConsumerById(Long id); 66 | } 67 | -------------------------------------------------------------------------------- /music-admin/src/store/store.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import Vuex from "vuex"; 3 | 4 | Vue.use(Vuex); 5 | const store = new Vuex.Store({ 6 | state: { 7 | HOST: "127.0.0.1:8888", 8 | isPlay: false, // 判断歌曲是否在播放 9 | url: "", // 歌曲地址 10 | id: "", // 歌曲id 11 | isLoginIn: false, 12 | }, 13 | getters: { 14 | isLoginIn: (state) => { 15 | let isLoginIn = state.isLoginIn; 16 | if (!isLoginIn) { 17 | isLoginIn = JSON.parse(window.sessionStorage.getItem("isLoginIn")); 18 | } 19 | return isLoginIn; 20 | }, 21 | isPlay: (state) => state.isPlay, 22 | url: (state) => state.url, 23 | id: (state) => state.id, 24 | }, 25 | mutations: { 26 | setSearchSongListData: (state, searchSongListData) => { 27 | state.searchSongListData = searchSongListData; 28 | window.sessionStorage.setItem( 29 | "searchSongListData", 30 | JSON.stringify(searchSongListData) 31 | ); 32 | }, 33 | setLsLoginIn: (state, isLoginIn) => { 34 | state.isLoginIn = isLoginIn; 35 | window.sessionStorage.setItem("isLoginIn", JSON.stringify(isLoginIn)); 36 | }, 37 | setIsPlay: (state, isPlay) => { 38 | state.isPlay = isPlay; 39 | }, 40 | setUrl: (state, url) => { 41 | state.url = url; 42 | }, 43 | setId: (state, id) => { 44 | state.id = id; 45 | }, 46 | }, 47 | }); 48 | 49 | export default store; 50 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/mapper/SongMapper.java: -------------------------------------------------------------------------------- 1 | package com.xs.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.xs.domain.Song; 5 | import com.xs.dto.SongDto; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.springframework.stereotype.Repository; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @author xs 13 | * description 针对表【song(歌曲)】的数据库操作Mapper 14 | * createDate 2022-10-05 15:00:05 15 | * Entity com.xs.domain.Song 16 | */ 17 | @Repository 18 | @Mapper 19 | public interface SongMapper extends BaseMapper { 20 | 21 | /** 22 | * 按歌手id查询歌曲信息 23 | */ 24 | List getAllSongBySingerId(Long id); 25 | 26 | /** 27 | * 按歌手id删除歌曲信息 28 | */ 29 | int deleteBySingerId(Long id); 30 | 31 | /** 32 | * 获取歌曲总数 33 | */ 34 | int getSongCount(); 35 | 36 | /** 37 | * 查询所有歌曲 38 | */ 39 | List getAllSong(); 40 | 41 | /** 42 | * 模糊查询所有歌曲 43 | */ 44 | List getAllBySongName(String name); 45 | 46 | /** 47 | * 模糊查询某个歌手所属全部歌曲 48 | */ 49 | List getAllSongByNameAndSingerId(Long id, String name); 50 | 51 | /** 52 | * 按播放量排行 53 | */ 54 | List getSongByPlayCount(); 55 | 56 | /** 57 | * 按歌单id查询歌曲信息 58 | */ 59 | List getAllSongBySongListId(Long songListId); 60 | } 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/service/impl/AdminServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.xs.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 4 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 5 | import com.xs.domain.Admin; 6 | import com.xs.mapper.AdminMapper; 7 | import com.xs.service.AdminService; 8 | import org.springframework.security.core.userdetails.UserDetails; 9 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 10 | import org.springframework.stereotype.Service; 11 | 12 | import javax.annotation.Resource; 13 | import java.util.Objects; 14 | 15 | /** 16 | * @author xs 17 | * description 针对表【admin(管理员)】的数据库操作Service实现 18 | * createDate 2022-10-03 16:22:14 19 | */ 20 | @Service 21 | public class AdminServiceImpl extends ServiceImpl implements AdminService { 22 | 23 | @Resource 24 | private AdminMapper adminMapper; 25 | 26 | @Override 27 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 28 | LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); 29 | lqw.eq(Admin::getUsername, username); 30 | Admin admin = adminMapper.selectOne(lqw); 31 | if (Objects.isNull(admin)) { 32 | throw new UsernameNotFoundException("用户不存在"); 33 | } 34 | return admin; 35 | } 36 | } 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/controller/RecentSongController.java: -------------------------------------------------------------------------------- 1 | package com.xs.controller; 2 | 3 | import com.xs.common.Result; 4 | import com.xs.domain.RecentSong; 5 | import com.xs.service.RecentSongService; 6 | import org.springframework.web.bind.annotation.*; 7 | 8 | import javax.annotation.Resource; 9 | 10 | @RequestMapping("/recentSong") 11 | @RestController 12 | public class RecentSongController { 13 | 14 | @Resource 15 | private RecentSongService recentSongService; 16 | 17 | /** 18 | * 添加歌曲最近播放记录 19 | */ 20 | @PostMapping("/add") 21 | public Result addRecentSong(@RequestBody RecentSong recentSong) { 22 | return recentSongService.addRecentSong(recentSong); 23 | } 24 | 25 | /** 26 | * 获取当前用户最近播放列表 27 | */ 28 | @GetMapping("/recentSongOfUserId/{id}") 29 | public Result getRecentSongByUserId(@PathVariable Long id) { 30 | return recentSongService.getRecentSongByUserId(id); 31 | } 32 | 33 | /** 34 | * 推荐歌单 35 | */ 36 | @GetMapping("/recommendSongList/{id}") 37 | public Result recommendSongList(@PathVariable Long id) { 38 | return recentSongService.recommendSongList(id); 39 | } 40 | 41 | /** 42 | * 推荐歌手 43 | */ 44 | @GetMapping("/recommendSinger/{id}") 45 | public Result recommendSinger(@PathVariable Long id) { 46 | return recentSongService.recommendSinger(id); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /music-server/src/main/resources/mapper/RanksMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | delete ranks from ranks where song_list_id = #{id} 15 | 16 | 17 | 18 | delete ranks from ranks where consumer_id = #{id} 19 | 20 | 21 | 24 | 25 | 28 | 29 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /music-view/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 | .comment-img { 17 | width: 70px; 18 | img { 19 | width: 100%; 20 | } 21 | } 22 | .comment-input { 23 | margin-left: 10px; 24 | flex: 1; 25 | } 26 | } 27 | .sub-btn { 28 | margin-top: 10px; 29 | margin-left: 90%; 30 | } 31 | } 32 | 33 | /*热门评论*/ 34 | .popular { 35 | width: 100%; 36 | > li { 37 | border-bottom: solid 1px rgba(0, 0, 0, 0.1); 38 | padding: 15px 0; 39 | display: flex; 40 | .popular-img { 41 | width: 50px; 42 | img { 43 | width: 100%; 44 | } 45 | } 46 | 47 | .popular-msg { 48 | padding: 0 20px; 49 | flex: 1; 50 | li { 51 | width: 100%; 52 | } 53 | .name { 54 | font-size: 1rem; 55 | } 56 | .time { 57 | font-size: 0.6rem; 58 | color: rgba(0, 0, 0, 0.5); 59 | } 60 | .content { 61 | font-size: 1rem; 62 | } 63 | } 64 | 65 | .up { 66 | width: 50px; 67 | line-height: 60px; 68 | } 69 | } 70 | } 71 | 72 | .icon { 73 | @include icon(1em); 74 | } 75 | -------------------------------------------------------------------------------- /music-view/src/assets/css/song-comment.scss: -------------------------------------------------------------------------------- 1 | @import "var.scss"; 2 | @import "global.scss"; 3 | 4 | /*评论*/ 5 | .comment { 6 | 7 | color: #fff; 8 | 9 | h2 { 10 | margin-bottom: 20px; 11 | text-align: center; 12 | height: 50px; 13 | line-height: 50px; 14 | border-bottom: 1px solid #fff; 15 | } 16 | 17 | .comment-msg { 18 | display: flex; 19 | .comment-img { 20 | width: 70px; 21 | img { 22 | width: 100%; 23 | } 24 | } 25 | .comment-input { 26 | margin-left: 10px; 27 | flex: 1; 28 | } 29 | } 30 | .sub-btn { 31 | margin-top: 10px; 32 | margin-left: 90%; 33 | } 34 | } 35 | 36 | /*热门评论*/ 37 | .popular { 38 | width: 100%; 39 | > li { 40 | border-bottom: solid 1px #fff; 41 | padding: 15px 0; 42 | display: flex; 43 | .popular-img { 44 | width: 50px; 45 | img { 46 | width: 100%; 47 | } 48 | } 49 | 50 | .popular-msg { 51 | color: #fff; 52 | padding: 0 20px; 53 | flex: 1; 54 | li { 55 | width: 100%; 56 | } 57 | .name { 58 | font-size: 1rem; 59 | } 60 | .time { 61 | font-size: 0.6rem; 62 | } 63 | .content { 64 | font-size: 1rem; 65 | } 66 | } 67 | 68 | .up { 69 | color: #fff; 70 | width: 50px; 71 | line-height: 60px; 72 | } 73 | } 74 | } 75 | 76 | .icon { 77 | @include icon(1em); 78 | } 79 | -------------------------------------------------------------------------------- /music-view/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 | .section-content { 8 | @include layout(flex-start, stretch, row, wrap); 9 | } 10 | } 11 | 12 | .content-item { 13 | width: 18%; 14 | margin: 20px 1%; 15 | overflow: hidden; 16 | border-radius: 4px; 17 | @include box-shadow(0 0 5px 1px rgba(0, 0, 0, 0.1)); 18 | position: relative; 19 | &:hover { 20 | @include box-shadow(0 0 5px 2px rgba(0, 0, 0, 0.3)); 21 | } 22 | &:hover .item-img { 23 | transform: scale(1.1); 24 | } 25 | .item-name { 26 | overflow: hidden; 27 | text-overflow: ellipsis; 28 | display: -webkit-box; 29 | -webkit-box-orient: vertical; 30 | -webkit-line-clamp: 2; 31 | margin: 10px 8px; 32 | } 33 | } 34 | 35 | .item-img { 36 | width: 100%; 37 | transition: all 0.4s ease; 38 | } 39 | 40 | .kuo, 41 | .mask { 42 | width: 100%; 43 | padding-bottom: 100%; 44 | height: 0; 45 | overflow: hidden; 46 | } 47 | 48 | .mask { 49 | position: absolute; 50 | top: 0; 51 | background-color: rgba(52, 47, 41, 0.4); 52 | transition: all 0.3s ease-in-out; 53 | opacity: 0; 54 | @include layout(center); 55 | > .icon { 56 | position: absolute; 57 | top: 40%; 58 | } 59 | &:hover { 60 | opacity: 1; 61 | cursor: pointer; 62 | } 63 | } 64 | 65 | .icon { 66 | @include icon(2em, rgba(240, 240, 240, 1)); 67 | } 68 | -------------------------------------------------------------------------------- /music-view/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 | li { 48 | display: block; 49 | width: 100%; 50 | height: 40px; 51 | line-height: 40px; 52 | padding-left: 20px; 53 | box-sizing: border-box; 54 | border-bottom: solid 1px rgba(0, 0, 0, 0.2); 55 | &:hover{ 56 | background-color: $color-blue; 57 | color: $color-white; 58 | } 59 | } 60 | } 61 | 62 | .is-play{ 63 | color: $color-blue-active; 64 | font-weight: bold; 65 | } 66 | -------------------------------------------------------------------------------- /music-admin/src/components/SongAudio.vue: -------------------------------------------------------------------------------- 1 | 13 | 62 | 63 | 68 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/service/CollectService.java: -------------------------------------------------------------------------------- 1 | package com.xs.service; 2 | 3 | import com.xs.common.Result; 4 | import com.xs.domain.Collect; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | import com.xs.dto.SearchDto; 7 | import com.xs.vo.CollectVo; 8 | 9 | /** 10 | * @author xs 11 | * description 针对表【collect(收藏)】的数据库操作Service 12 | * createDate 2022-10-11 16:14:36 13 | */ 14 | public interface CollectService extends IService { 15 | 16 | /** 17 | * 收藏歌曲 18 | */ 19 | Result addCollect(Collect collect); 20 | 21 | /** 22 | * 取消收藏 23 | */ 24 | Result cancelCollect(CollectVo collectVo); 25 | 26 | /** 27 | * 查询歌曲收藏状态 28 | */ 29 | Result getCollectBySongId(CollectVo collectVo); 30 | 31 | /** 32 | * 获取指定用户所有收藏歌曲 33 | */ 34 | Result getAllCollectByConsumerId(Long id); 35 | 36 | /** 37 | * 查询歌单收藏状态 38 | */ 39 | Result getCollectBySongListId(CollectVo collectVo); 40 | 41 | /** 42 | * 获取指定用户所有收藏歌单 43 | */ 44 | Result getAllCollectSongListByUserId(Long id); 45 | 46 | /** 47 | * 获取指定用户收藏信息 48 | */ 49 | Result getAllCollectByUserId(Long id); 50 | 51 | /** 52 | * 删除指定用户收藏数据 53 | */ 54 | Result delCollect(Long id); 55 | 56 | /** 57 | * 批量删除指定用户收藏数据 58 | */ 59 | Result delAllCollect(Long[] ids); 60 | 61 | /** 62 | * 模糊搜索指定用户收藏信息 63 | */ 64 | Result searchCollectByUserId(SearchDto searchDto); 65 | } 66 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/service/CommentService.java: -------------------------------------------------------------------------------- 1 | package com.xs.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.xs.common.Result; 5 | import com.xs.domain.Comment; 6 | import com.xs.dto.CommentDto; 7 | import com.xs.vo.SearchVo; 8 | 9 | /** 10 | * @author xs 11 | * description 针对表【comment(评论)】的数据库操作Service 12 | * createDate 2022-10-11 16:10:41 13 | */ 14 | public interface CommentService extends IService { 15 | 16 | /** 17 | * 添加评论 18 | */ 19 | Result addComment(Comment comment); 20 | 21 | /** 22 | * 修改评论 23 | */ 24 | Result updateComment(Comment comment); 25 | 26 | /** 27 | * 删除评论 28 | */ 29 | Result deleteComment(Long id); 30 | 31 | /** 32 | * 查询所有评论 33 | */ 34 | Result getAllComment(); 35 | 36 | /** 37 | * 查询指定歌单所有评论 38 | */ 39 | Result getAllCommentBySongListId(Long id); 40 | 41 | /** 42 | * 查询指定歌曲所有评论 43 | */ 44 | Result getAllCommentBySongId(Long id); 45 | 46 | /** 47 | * 给指定评论点赞 48 | */ 49 | Result updateCommentUp(CommentDto commentDto); 50 | 51 | /** 52 | * 取消点赞 53 | */ 54 | Result cancelCommentUp(CommentDto commentDto); 55 | 56 | /** 57 | * 批量删除评论 58 | */ 59 | Result deleteAllComment(Long[] ids); 60 | 61 | /** 62 | * 获取指定用户所有评论 63 | */ 64 | Result getAllCommentByUserId(Long id); 65 | 66 | /** 67 | * 按评论内容或用户名模糊搜索 68 | */ 69 | Result searchComment(SearchVo searchVo); 70 | } 71 | -------------------------------------------------------------------------------- /music-view/src/api/Consumer.js: -------------------------------------------------------------------------------- 1 | import axios from "../plugins/axios"; 2 | 3 | export function getAllConsumer() { 4 | return axios({ 5 | url: "consumer/all", 6 | method: "GET", 7 | }); 8 | } 9 | 10 | export function updateConsumer(Consumer) { 11 | return axios({ 12 | url: "consumer/update", 13 | method: "PUT", 14 | data: { 15 | ...Consumer, 16 | }, 17 | }); 18 | } 19 | 20 | export function getConsumerByName(name) { 21 | return axios({ 22 | url: `consumer/consumerOfName/${name}`, 23 | method: "GET", 24 | }); 25 | } 26 | 27 | export function addConsumer(Consumer) { 28 | return axios({ 29 | url: "consumer/add", 30 | method: "POST", 31 | data: { 32 | ...Consumer, 33 | }, 34 | }); 35 | } 36 | 37 | export function deleteConsumer(id) { 38 | return axios({ 39 | url: `consumer/delete/${id}`, 40 | method: "DELETE", 41 | }); 42 | } 43 | 44 | export function deleteAllConsumer(ids) { 45 | return axios({ 46 | url: `consumer/deleteAll/${ids}`, 47 | method: "DELETE", 48 | }); 49 | } 50 | 51 | export function getConsumerCount() { 52 | return axios({ 53 | url: "consumer/getCount", 54 | method: "GET", 55 | }); 56 | } 57 | 58 | export function login(LoginVo) { 59 | return axios({ 60 | url: "consumer/login", 61 | method: "POST", 62 | data: { 63 | ...LoginVo, 64 | }, 65 | }); 66 | } 67 | 68 | export function getConsumerById(userId) { 69 | return axios({ 70 | url: `consumer/consumerOfId/${userId}`, 71 | method: "GET", 72 | }); 73 | } 74 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/domain/Comment.java: -------------------------------------------------------------------------------- 1 | package com.xs.domain; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 6 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 7 | import lombok.Data; 8 | 9 | import java.io.Serial; 10 | import java.io.Serializable; 11 | import java.time.LocalDateTime; 12 | 13 | /** 14 | * 评论 15 | * TableName comment 16 | */ 17 | @Data 18 | public class Comment implements Serializable { 19 | /** 20 | * 主键 21 | */ 22 | @JsonSerialize(using = ToStringSerializer.class) 23 | private Long id; 24 | 25 | /** 26 | * 用户id 27 | */ 28 | @JsonSerialize(using = ToStringSerializer.class) 29 | private Long userId; 30 | 31 | /** 32 | * 评论类型(1歌单0歌曲) 33 | */ 34 | private Integer type; 35 | 36 | /** 37 | * 歌曲id 38 | */ 39 | @JsonSerialize(using = ToStringSerializer.class) 40 | private Long songId; 41 | 42 | /** 43 | * 歌单id 44 | */ 45 | @JsonSerialize(using = ToStringSerializer.class) 46 | private Long songListId; 47 | 48 | /** 49 | * 评论内容 50 | */ 51 | private String content; 52 | 53 | /** 54 | * 评论时间 55 | */ 56 | @TableField(fill = FieldFill.INSERT_UPDATE) 57 | private LocalDateTime createTime; 58 | 59 | /** 60 | * 评论点赞数 61 | */ 62 | private Integer up; 63 | 64 | @Serial 65 | private static final long serialVersionUID = 1L; 66 | } -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/mapper/CollectMapper.java: -------------------------------------------------------------------------------- 1 | package com.xs.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.xs.domain.Collect; 5 | import com.xs.domain.Singer; 6 | import com.xs.domain.SongList; 7 | import com.xs.dto.CollectDto; 8 | import com.xs.dto.SongDto; 9 | import org.apache.ibatis.annotations.Mapper; 10 | import org.springframework.stereotype.Repository; 11 | 12 | import java.util.List; 13 | 14 | /** 15 | * @author xs 16 | * description 针对表【collect(收藏)】的数据库操作Mapper 17 | * createDate 2022-10-11 16:14:36 18 | * Entity com.xs.domain.Collect 19 | */ 20 | @Repository 21 | @Mapper 22 | public interface CollectMapper extends BaseMapper { 23 | 24 | /** 25 | * 按歌单id删除收藏信息 26 | */ 27 | int deleteBySongListId(Long id); 28 | 29 | /** 30 | * 按歌曲id删除收藏信息 31 | */ 32 | int deleteBySongId(Long id); 33 | 34 | /** 35 | * 按用户id删除收藏信息 36 | */ 37 | int deleteByUserId(Long id); 38 | 39 | /** 40 | * 获取指定用户所有收藏歌曲 41 | */ 42 | List getAllCollectSongByConsumerId(Long id); 43 | 44 | /** 45 | * 获取指定用户所有收藏歌单 46 | */ 47 | List getAllCollectSongListByConsumerId(Long id); 48 | 49 | /** 50 | * 获取指定用户所有收藏歌曲信息 51 | */ 52 | List getAllCollectSongByUserId(Long userId); 53 | 54 | /** 55 | * 获取指定用户所有收藏歌单信息 56 | */ 57 | List getAllCollectSongListByUserId(Long userId); 58 | 59 | /** 60 | * 根据收藏歌曲查询歌手信息 61 | */ 62 | List getSingerByCollectSong(Long userId); 63 | } 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/domain/Song.java: -------------------------------------------------------------------------------- 1 | package com.xs.domain; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 6 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 7 | import lombok.Data; 8 | 9 | import java.io.Serial; 10 | import java.io.Serializable; 11 | import java.time.LocalDateTime; 12 | 13 | /** 14 | * 歌曲 15 | */ 16 | @Data 17 | public class Song implements Serializable { 18 | 19 | /** 20 | * 主键 21 | */ 22 | @JsonSerialize(using = ToStringSerializer.class) 23 | private Long id; 24 | 25 | /** 26 | * 歌手id 27 | */ 28 | @JsonSerialize(using = ToStringSerializer.class) 29 | private Long singerId; 30 | 31 | /** 32 | * 歌名 33 | */ 34 | private String name; 35 | 36 | /** 37 | * 简介 38 | */ 39 | private String introduction; 40 | 41 | /** 42 | * 创建时间 43 | */ 44 | @TableField(fill = FieldFill.INSERT_UPDATE) 45 | private LocalDateTime createTime; 46 | 47 | /** 48 | * 更新时间 49 | */ 50 | @TableField(fill = FieldFill.INSERT_UPDATE) 51 | private LocalDateTime updateTime; 52 | 53 | /** 54 | * 歌曲图片 55 | */ 56 | private String pic; 57 | 58 | /** 59 | * 歌词 60 | */ 61 | private String lyric; 62 | 63 | /** 64 | * 歌曲地址 65 | */ 66 | private String url; 67 | 68 | /** 69 | * 播放量 70 | */ 71 | private Integer playCount; 72 | 73 | @Serial 74 | private static final long serialVersionUID = 1L; 75 | } -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/service/SongService.java: -------------------------------------------------------------------------------- 1 | package com.xs.service; 2 | 3 | import com.xs.common.Result; 4 | import com.xs.domain.Song; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | import com.xs.vo.SongVo; 7 | 8 | /** 9 | * @author xs 10 | * description 针对表【song(歌曲)】的数据库操作Service 11 | * createDate 2022-10-05 15:00:05 12 | */ 13 | public interface SongService extends IService { 14 | 15 | /** 16 | * 添加歌曲 17 | */ 18 | Result addSong(Song song); 19 | 20 | /** 21 | * 更新歌曲 22 | */ 23 | Result updateSong(Song song); 24 | 25 | /** 26 | * 按歌名查询歌曲 27 | */ 28 | Result getAllSongByName(String name); 29 | 30 | /** 31 | * 按id删除歌曲 32 | */ 33 | Result deleteSong(Long id); 34 | 35 | /** 36 | * 批量删除歌曲 37 | */ 38 | Result deleteAllSong(Long[] ids); 39 | 40 | /** 41 | * 按歌手id查询所有歌曲 42 | */ 43 | Result getAllSongBySingId(Long id); 44 | 45 | /** 46 | * 获取歌曲总数 47 | */ 48 | Result getSongCount(); 49 | 50 | /** 51 | * 查询所有歌曲 52 | */ 53 | Result getAllSong(); 54 | 55 | /** 56 | * 模糊查询某个歌手所属全部歌曲 57 | */ 58 | Result getAllSongByNameAndSingerId(SongVo songVo); 59 | 60 | /** 61 | * 按歌单id查询所有歌曲 62 | */ 63 | Result getAllSongBySongListId(Long id); 64 | 65 | /** 66 | * 按歌手id查询所有歌曲和歌手名 67 | */ 68 | Result gerAllSongAndSingerNameBySingerId(Long id); 69 | 70 | /** 71 | * 增加播放量 72 | */ 73 | Result addPlayCount(SongVo songVo); 74 | 75 | /** 76 | * 按播放量排行 77 | */ 78 | Result getSongByPlayCount(); 79 | } 80 | -------------------------------------------------------------------------------- /music-admin/src/api/Singer.js: -------------------------------------------------------------------------------- 1 | import axios from "../plugins/axios"; 2 | 3 | export function addSinger(Singer) { 4 | return axios({ 5 | url: "singer/add", 6 | method: "POST", 7 | data: { 8 | ...Singer, 9 | }, 10 | }); 11 | } 12 | 13 | export function getAllSingerByPage(currentPage) { 14 | return axios({ 15 | url: `singer/allSinger/${currentPage}`, 16 | method: "GET", 17 | }); 18 | } 19 | 20 | export function getAllSinger() { 21 | return axios({ 22 | url: "singer/allSinger", 23 | method: "GET", 24 | }); 25 | } 26 | 27 | export function getSingerByName(name) { 28 | return axios({ 29 | url: `singer/singerOfName/${name}`, 30 | method: "GET", 31 | }); 32 | } 33 | 34 | export function updateSinger(Singer) { 35 | return axios({ 36 | url: "singer/update", 37 | method: "PUT", 38 | data: { 39 | ...Singer, 40 | }, 41 | }); 42 | } 43 | 44 | export function deleteSinger(id) { 45 | return axios({ 46 | url: `singer/delete/${id}`, 47 | method: "DELETE", 48 | }); 49 | } 50 | 51 | export function deleteAllSinger(ids) { 52 | return axios({ 53 | url: `singer/deleteAll/${ids}`, 54 | method: "DELETE", 55 | }); 56 | } 57 | 58 | export function getSingerCount() { 59 | return axios({ 60 | url: "singer/getCount", 61 | method: "GET", 62 | }); 63 | } 64 | 65 | export function getSingerCountByLocation() { 66 | return axios({ 67 | url: "singer/getCountByLocation", 68 | method: "GET", 69 | }); 70 | } 71 | 72 | export function getSingerCountBySex() { 73 | return axios({ 74 | url: "singer/getCountBySex", 75 | method: "GET", 76 | }); 77 | } 78 | -------------------------------------------------------------------------------- /music-admin/src/assets/css/main.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | html, 7 | body, 8 | #app, 9 | .wrapper { 10 | width: 100%; 11 | height: 100%; 12 | overflow: hidden; 13 | } 14 | 15 | body { 16 | font-family: 'PingFang SC', "Helvetica Neue", Helvetica, "microsoft yahei", arial, STHeiTi, sans-serif; 17 | } 18 | 19 | a { 20 | text-decoration: none 21 | } 22 | 23 | .content-box { 24 | position: absolute; 25 | left: 150px; 26 | right: 0; 27 | top: 70px; 28 | bottom: 0; 29 | overflow-y: scroll; 30 | -webkit-transition: left .3s ease-in-out; 31 | transition: left .3s ease-in-out; 32 | background: #f0f0f0; 33 | } 34 | 35 | .content { 36 | width: auto; 37 | padding: 20px; 38 | } 39 | 40 | .content-collapse { 41 | left: 65px; 42 | } 43 | 44 | .container { 45 | padding: 20px; 46 | background: #fff; 47 | border: 1px solid #ddd; 48 | border-radius: 5px; 49 | } 50 | 51 | .crumbs { 52 | margin-bottom: 20px; 53 | } 54 | 55 | .pagination { 56 | margin: 20px 0; 57 | text-align: right; 58 | } 59 | 60 | .plugins-tips { 61 | padding: 20px 10px; 62 | margin-bottom: 20px; 63 | } 64 | 65 | .el-button+.el-tooltip { 66 | margin-left: 10px; 67 | } 68 | 69 | .el-table tr:hover { 70 | background: #f6faff; 71 | } 72 | 73 | .mgb20 { 74 | margin-bottom: 20px; 75 | } 76 | 77 | .move-enter-active, 78 | .move-leave-active { 79 | transition: opacity .5s; 80 | } 81 | 82 | .move-enter, 83 | .move-leave { 84 | opacity: 0; 85 | } 86 | 87 | /*表单*/ 88 | .el-select { 89 | width: 100%; 90 | } 91 | .table{ 92 | min-width: 800px; 93 | } 94 | .el-dialog__body { 95 | padding: 10px 20px 0 10px; 96 | } 97 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/dto/SongDto.java: -------------------------------------------------------------------------------- 1 | package com.xs.dto; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 6 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 7 | import lombok.Data; 8 | 9 | import java.io.Serial; 10 | import java.io.Serializable; 11 | import java.time.LocalDateTime; 12 | 13 | @Data 14 | public class SongDto implements Serializable { 15 | 16 | /** 17 | * 主键 18 | */ 19 | @JsonSerialize(using = ToStringSerializer.class) 20 | private Long id; 21 | 22 | /** 23 | * 歌手id 24 | */ 25 | @JsonSerialize(using = ToStringSerializer.class) 26 | private Long singerId; 27 | 28 | /** 29 | * 歌名 30 | */ 31 | private String name; 32 | 33 | /** 34 | * 歌手名 35 | */ 36 | private String singerName; 37 | 38 | /** 39 | * 简介 40 | */ 41 | private String introduction; 42 | 43 | /** 44 | * 创建时间 45 | */ 46 | @TableField(fill = FieldFill.INSERT_UPDATE) 47 | private LocalDateTime createTime; 48 | 49 | /** 50 | * 更新时间 51 | */ 52 | @TableField(fill = FieldFill.INSERT_UPDATE) 53 | private LocalDateTime updateTime; 54 | 55 | /** 56 | * 歌曲图片 57 | */ 58 | private String pic; 59 | 60 | /** 61 | * 歌词 62 | */ 63 | private String lyric; 64 | 65 | /** 66 | * 歌曲地址 67 | */ 68 | private String url; 69 | 70 | /** 71 | * 播放量 72 | */ 73 | private Integer playCount; 74 | 75 | @Serial 76 | private static final long serialVersionUID = 1L; 77 | } 78 | -------------------------------------------------------------------------------- /music-admin/src/api/SongList.js: -------------------------------------------------------------------------------- 1 | import axios from "../plugins/axios"; 2 | 3 | export function addSongList(SongList) { 4 | return axios({ 5 | url: "songList/add", 6 | method: "POST", 7 | data: { 8 | ...SongList, 9 | }, 10 | }); 11 | } 12 | 13 | export function getAllSongListByPage(currentPage) { 14 | return axios({ 15 | url: `songList/all/${currentPage}`, 16 | method: "GET", 17 | }); 18 | } 19 | 20 | export function getSongListByName(name) { 21 | return axios({ 22 | url: `songList/songListOfName/${name}`, 23 | method: "GET", 24 | }); 25 | } 26 | 27 | export function updateSongList(SongList) { 28 | return axios({ 29 | url: "songList/update", 30 | method: "PUT", 31 | data: { 32 | ...SongList, 33 | }, 34 | }); 35 | } 36 | 37 | export function deleteSongList(id) { 38 | return axios({ 39 | url: `songList/delete/${id}`, 40 | method: "DELETE", 41 | }); 42 | } 43 | 44 | export function deleteAllSongList(ids) { 45 | return axios({ 46 | url: `songList/deleteAll/${ids}`, 47 | method: "DELETE", 48 | }); 49 | } 50 | 51 | export function getSongListCount() { 52 | return axios({ 53 | url: "songList/getCount", 54 | method: "GET", 55 | }); 56 | } 57 | 58 | export function getSongListCountByStyle() { 59 | return axios({ 60 | url: "songList/getSongListCountByStyle", 61 | method: "GET", 62 | }); 63 | } 64 | 65 | export function getSongListByStyle(style) { 66 | return axios({ 67 | url: `songList/getSongListByStyle/${style}`, 68 | method: "GET", 69 | }); 70 | } 71 | 72 | export function getAllStyle() { 73 | return axios({ 74 | url: "songList/allStyle", 75 | method: "GET", 76 | }); 77 | } 78 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/mapper/CommentMapper.java: -------------------------------------------------------------------------------- 1 | package com.xs.mapper; 2 | 3 | import com.xs.domain.Comment; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import com.xs.vo.CommentVo; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.springframework.stereotype.Repository; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @author xs 13 | * description 针对表【comment(评论)】的数据库操作Mapper 14 | * createDate 2022-10-11 16:10:41 15 | * Entity com.xs.domain.Comment 16 | */ 17 | @Repository 18 | @Mapper 19 | public interface CommentMapper extends BaseMapper { 20 | 21 | /** 22 | * 按用户id删除评论信息 23 | */ 24 | int deleteByUserId(Long id); 25 | 26 | /** 27 | * 按歌单id删除评论信息 28 | */ 29 | int deleteBySongListId(Long id); 30 | 31 | /** 32 | * 按歌曲id删除评论信息 33 | */ 34 | int deleteBySongId(Long id); 35 | 36 | /** 37 | * 查询所有评论 38 | */ 39 | List getAllComment(); 40 | 41 | /** 42 | * 查询指定歌单所有评论 43 | */ 44 | List getAllCommentBySongListId(Long id); 45 | 46 | /** 47 | * 查询指定歌曲所有评论 48 | */ 49 | List getAllCommentBySongId(Long id); 50 | 51 | /** 52 | * 查询指定用户所有评论 53 | */ 54 | List getAllCommentByUserId(Long id); 55 | 56 | /** 57 | * 模糊查询指定用户评论 58 | */ 59 | List searchCommentByUserId(Long id, String keyWord); 60 | 61 | /** 62 | * 模糊查询指定歌曲评论 63 | */ 64 | List searchCommentBySongId(Long id, String keyWord); 65 | 66 | /** 67 | * 模糊查询指定歌单评论 68 | */ 69 | List searchCommentBySongListId(Long id, String keyWord); 70 | } 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /music-view/src/store/user.js: -------------------------------------------------------------------------------- 1 | const user = { 2 | state: { 3 | collectList: [], 4 | control: "#icon-xunhuanbofang", 5 | flag: 0, 6 | recentSongList: [], 7 | }, 8 | getters: { 9 | recentSongList: (state) => { 10 | state.recentSongList = JSON.parse( 11 | window.sessionStorage.getItem("recentSongList") 12 | ); 13 | return state.recentSongList; 14 | }, 15 | collectList: (state) => { 16 | state.collectList = JSON.parse( 17 | window.sessionStorage.getItem("collectList") 18 | ); 19 | return state.collectList; 20 | }, 21 | control: (state) => { 22 | state.control = JSON.parse(window.sessionStorage.getItem("control")); 23 | return state.control; 24 | }, 25 | flag: (state) => { 26 | state.flag = JSON.parse(window.sessionStorage.getItem("flag")); 27 | return state.flag; 28 | }, 29 | }, 30 | mutations: { 31 | setRecentSongList: (state, recentSongList) => { 32 | state.recentSongList = recentSongList; 33 | window.sessionStorage.setItem( 34 | "recentSongList", 35 | JSON.stringify(recentSongList) 36 | ); 37 | }, 38 | setCollectList: (state, collectList) => { 39 | state.collectList = collectList; 40 | window.sessionStorage.setItem("collectList", JSON.stringify(collectList)); 41 | }, 42 | setControl: (state, control) => { 43 | state.control = control; 44 | window.sessionStorage.setItem("control", JSON.stringify(control)); 45 | }, 46 | setFlag: (state, flag) => { 47 | state.flag = flag; 48 | window.sessionStorage.setItem("flag", JSON.stringify(flag)); 49 | }, 50 | }, 51 | }; 52 | 53 | export default user; 54 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/domain/Consumer.java: -------------------------------------------------------------------------------- 1 | package com.xs.domain; 2 | 3 | import java.io.Serial; 4 | import java.io.Serializable; 5 | import java.time.LocalDateTime; 6 | import java.util.Date; 7 | 8 | import com.baomidou.mybatisplus.annotation.FieldFill; 9 | import com.baomidou.mybatisplus.annotation.TableField; 10 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 11 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 12 | import lombok.Data; 13 | 14 | /** 15 | * 前端用户 16 | * TableName consumer 17 | */ 18 | @Data 19 | public class Consumer implements Serializable { 20 | /** 21 | * 主键 22 | */ 23 | @JsonSerialize(using = ToStringSerializer.class) 24 | private Long id; 25 | 26 | /** 27 | * 账号 28 | */ 29 | private String username; 30 | 31 | /** 32 | * 密码 33 | */ 34 | private String password; 35 | 36 | /** 37 | * 性别(1男0女) 38 | */ 39 | private Integer sex; 40 | 41 | /** 42 | * 电话 43 | */ 44 | private String phoneNum; 45 | 46 | /** 47 | * 电子邮箱 48 | */ 49 | private String email; 50 | 51 | /** 52 | * 生日 53 | */ 54 | private Date birth; 55 | 56 | /** 57 | * 签名 58 | */ 59 | private String introduction; 60 | 61 | /** 62 | * 地区 63 | */ 64 | private String location; 65 | 66 | /** 67 | * 头像 68 | */ 69 | private String avatar; 70 | 71 | /** 72 | * 创建时间 73 | */ 74 | @TableField(fill = FieldFill.INSERT) 75 | private LocalDateTime createTime; 76 | 77 | /** 78 | * 更新时间 79 | */ 80 | @TableField(fill = FieldFill.INSERT_UPDATE) 81 | private LocalDateTime updateTime; 82 | 83 | @Serial 84 | private static final long serialVersionUID = 1L; 85 | } -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/service/SongListService.java: -------------------------------------------------------------------------------- 1 | package com.xs.service; 2 | 3 | import com.xs.common.Result; 4 | import com.xs.domain.SongList; 5 | import com.baomidou.mybatisplus.extension.service.IService; 6 | 7 | /** 8 | * @author xs 9 | * description 针对表【song_list(歌单)】的数据库操作Service 10 | * createDate 2022-10-09 16:10:47 11 | */ 12 | public interface SongListService extends IService { 13 | 14 | /** 15 | * 分页查询所有歌单 16 | */ 17 | Result getAllSongListByPage(Integer currentPage); 18 | 19 | /** 20 | * 按标题查询歌单 21 | */ 22 | Result getSongListByName(String name); 23 | 24 | /** 25 | * 添加歌单 26 | */ 27 | Result addSongList(SongList songList); 28 | 29 | /** 30 | * 修改歌单 31 | */ 32 | Result updateSongList(SongList songList); 33 | 34 | /** 35 | * 删除歌单 36 | */ 37 | Result deleteSongList(Long id); 38 | 39 | /** 40 | * 批量删除歌单 41 | */ 42 | Result deleteAllSongList(Long[] ids); 43 | 44 | /** 45 | * 获取歌手总数 46 | */ 47 | Result getSongListCount(); 48 | 49 | /** 50 | * 按歌单类型分组查询的歌单数量 51 | */ 52 | Result getSongListCountByStyle(); 53 | 54 | /** 55 | * 按歌单风格名称查询所有歌单 56 | */ 57 | Result getSongListByStyle(String style); 58 | 59 | /** 60 | * 查询所有歌单的风格并统计 61 | */ 62 | Result getAllStyle(); 63 | 64 | /** 65 | * 分页查询所有歌单 66 | */ 67 | Result getSongListByPage(Integer currentPage); 68 | 69 | /** 70 | * 查询所有歌单 71 | */ 72 | Result getAllSongList(); 73 | 74 | /** 75 | * 按歌单风格名称分组查询所有歌单 76 | */ 77 | Result getSongListByStyleAndPage(String style, Integer currentPage); 78 | 79 | /** 80 | * 按风格查询歌单数量 81 | */ 82 | Result getAllSongListCountByStyle(String style); 83 | } 84 | -------------------------------------------------------------------------------- /music-view/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-view/src/components/AlbumContent.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 59 | 60 | 63 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/controller/admin/ListSongAdminController.java: -------------------------------------------------------------------------------- 1 | package com.xs.controller.admin; 2 | 3 | import com.xs.common.Result; 4 | import com.xs.dto.ListSongByNameDto; 5 | import com.xs.service.ListSongService; 6 | import com.xs.vo.ListSongVo; 7 | import org.springframework.web.bind.annotation.*; 8 | 9 | import javax.annotation.Resource; 10 | 11 | @RequestMapping("/admin/listSong") 12 | @RestController 13 | public class ListSongAdminController { 14 | 15 | @Resource 16 | private ListSongService listSongService; 17 | 18 | /** 19 | * 查找歌手对应的歌曲名称 20 | */ 21 | @GetMapping("/songOfName/{singId}") 22 | public Result getSongNameBySingerId(@PathVariable Long singId) { 23 | return listSongService.getSongNameBySingerId(singId); 24 | } 25 | 26 | /** 27 | * 查询所有歌单歌曲 28 | */ 29 | @GetMapping("/all/{id}") 30 | public Result getAll(@PathVariable Long id) { 31 | return listSongService.getAll(id); 32 | } 33 | 34 | /** 35 | * 添加歌单歌曲 36 | */ 37 | @PostMapping("/add") 38 | public Result addListSong(@RequestBody ListSongVo listSongVo) { 39 | return listSongService.addListSong(listSongVo); 40 | } 41 | 42 | /** 43 | * 删除歌单歌曲 44 | */ 45 | @DeleteMapping("/delete/{id}") 46 | public Result deleteListSong(@PathVariable Long id) { 47 | return listSongService.deleteListSong(id); 48 | } 49 | 50 | /** 51 | * 批量删除歌曲 52 | */ 53 | @DeleteMapping("/deleteAll/{ids}") 54 | public Result deleteAllListSong(@PathVariable Long[] ids) { 55 | return listSongService.deleteAllListSong(ids); 56 | } 57 | 58 | /** 59 | * 按名称查询歌单歌曲 60 | */ 61 | @PostMapping("/listSongOfName") 62 | public Result getListSongByName(@RequestBody ListSongByNameDto listSongByNameDto) { 63 | return listSongService.getListSongByName(listSongByNameDto); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /music-view/src/assets/css/song-list-album.scss: -------------------------------------------------------------------------------- 1 | @import "var.scss"; 2 | @import "global.scss"; 3 | 4 | /*歌单背景*/ 5 | .song-list-album { 6 | margin-top: $header-height; 7 | padding-top: 150px; 8 | background-color: $theme-background-color; 9 | 10 | &::before { 11 | /*背景*/ 12 | content: ""; 13 | background-color: $theme-color; 14 | position: absolute; 15 | top: 0; 16 | width: 100%; 17 | height: $header-height + 150px; 18 | } 19 | } 20 | 21 | /*歌单左侧*/ 22 | .album-slide { 23 | float: left; 24 | width: 400px; 25 | 26 | /*歌单图像*/ 27 | .album-img { 28 | position: relative; 29 | display: inline-block; 30 | height: 300px; 31 | width: 300px; 32 | top: -100px; 33 | left: 50px; 34 | border-radius: 10%; 35 | overflow: hidden; 36 | border: 5px solid $color-white; 37 | background-color: $color-white; 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 | span { 51 | color: rgba(0, 0, 0, 0.5); 52 | } 53 | } 54 | } 55 | 56 | /*歌单内容*/ 57 | .album-content { 58 | margin-left: 300px; 59 | padding: 40px 100px; 60 | /*歌单题目*/ 61 | .album-title { 62 | font-size: 30px; 63 | font-weight: 600; 64 | } 65 | 66 | /*歌单打分*/ 67 | .album-score { 68 | display: flex; 69 | align-items: center; 70 | margin: 50px; 71 | > div { 72 | margin-left: 100px; 73 | } 74 | > span { 75 | font-size: 60px; 76 | } 77 | h3 { 78 | margin: 10px 0; 79 | } 80 | } 81 | 82 | /*歌曲列表*/ 83 | .songs-body { 84 | background-color: $color-white; 85 | border-radius: 12px; 86 | padding: 0 40px 50px 40px; 87 | min-width: 700px; 88 | } 89 | } 90 | 91 | .icon { 92 | @include icon(1.2em, #696969); 93 | } 94 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/service/SingerService.java: -------------------------------------------------------------------------------- 1 | package com.xs.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.xs.common.Result; 5 | import com.xs.domain.Singer; 6 | 7 | /** 8 | * @author xs 9 | * description 针对表【singer(歌手)】的数据库操作Service 10 | * createDate 2022-10-05 15:08:13 11 | */ 12 | public interface SingerService extends IService { 13 | 14 | /** 15 | * 添加歌手 16 | */ 17 | Result addSinger(Singer singer); 18 | 19 | /** 20 | * 修改歌手 21 | */ 22 | Result updateSinger(Singer singer); 23 | 24 | /** 25 | * 删除歌手 26 | */ 27 | Result deleteSinger(Long id); 28 | 29 | /** 30 | * 分页查询所有歌手 31 | */ 32 | Result getAllSingerByPage(Integer currentPage); 33 | 34 | /** 35 | * 按名字模糊查询歌手 36 | */ 37 | Result singerOfName(String name); 38 | 39 | /** 40 | * 批量删除歌手 41 | */ 42 | Result deleteAllSinger(Long[] ids); 43 | 44 | /** 45 | * 获取歌手总数 46 | */ 47 | Result getSingerCount(); 48 | 49 | /** 50 | * 按歌手id查询歌手名 51 | */ 52 | Result getSingerNameById(Long id); 53 | 54 | /** 55 | * 按地区分组查询歌手数量 56 | */ 57 | Result getSingerCountByLocation(); 58 | 59 | /** 60 | * 按性别分组查询歌手数量 61 | */ 62 | Result getSingerCountBySex(); 63 | 64 | /** 65 | * 按性别查询所有歌手 66 | */ 67 | Result getAllSingerBySex(Integer sex); 68 | 69 | /** 70 | * 按id查询歌手 71 | */ 72 | Result getSingerById(Long id); 73 | 74 | /** 75 | * 查询所有歌手 76 | */ 77 | Result getAllSinger(); 78 | 79 | /** 80 | * 分页查询所有歌手 81 | */ 82 | Result getSingerByPage(Integer currentPage); 83 | 84 | /** 85 | * 按性别分页查询所有歌手 86 | */ 87 | Result getAllSingerBySexAndPage(Integer sex, Integer currentPage); 88 | 89 | /** 90 | * 按性别查询歌手数量 91 | */ 92 | Result getAllSingerCountBySex(Integer sex); 93 | } 94 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/controller/CollectController.java: -------------------------------------------------------------------------------- 1 | package com.xs.controller; 2 | 3 | import com.xs.common.Result; 4 | import com.xs.domain.Collect; 5 | import com.xs.service.CollectService; 6 | import com.xs.vo.CollectVo; 7 | import org.springframework.web.bind.annotation.*; 8 | 9 | import javax.annotation.Resource; 10 | 11 | @RestController 12 | @RequestMapping("/collect") 13 | public class CollectController { 14 | 15 | @Resource 16 | private CollectService collectService; 17 | 18 | /** 19 | * 收藏歌曲 20 | */ 21 | @PostMapping("/add") 22 | public Result addCollect(@RequestBody Collect collect) { 23 | return collectService.addCollect(collect); 24 | } 25 | 26 | /** 27 | * 取消收藏 28 | */ 29 | @DeleteMapping("/cancel") 30 | public Result cancelCollect(@RequestBody CollectVo collectVo) { 31 | return collectService.cancelCollect(collectVo); 32 | } 33 | 34 | /** 35 | * 查询歌曲收藏状态 36 | */ 37 | @PostMapping("/getCollectBySongId") 38 | public Result getCollectBySongId(@RequestBody CollectVo collectVo) { 39 | return collectService.getCollectBySongId(collectVo); 40 | } 41 | 42 | /** 43 | * 查询歌单收藏状态 44 | */ 45 | @PostMapping("/getCollectBySongListId") 46 | public Result getCollectBySongListId(@RequestBody CollectVo collectVo) { 47 | return collectService.getCollectBySongListId(collectVo); 48 | } 49 | 50 | /** 51 | * 获取指定用户所有收藏歌曲 52 | */ 53 | @GetMapping("/collectOfConsumerId/{id}") 54 | public Result getAllCollectByConsumerId(@PathVariable Long id) { 55 | return collectService.getAllCollectByConsumerId(id); 56 | } 57 | 58 | /** 59 | * 获取指定用户所有收藏歌单 60 | */ 61 | @GetMapping("/collectSongListOfUserId/{id}") 62 | public Result getAllCollectSongListByUserId(@PathVariable Long id) { 63 | return collectService.getAllCollectSongListByUserId(id); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/util/JacksonUtils.java: -------------------------------------------------------------------------------- 1 | package com.xs.util; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.fasterxml.jackson.core.type.TypeReference; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; 7 | 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | 11 | /** 12 | * Jackson Object Mapper 13 | */ 14 | public class JacksonUtils { 15 | private static final ObjectMapper objectMapper = new ObjectMapper(); 16 | public static String writeValueAsString(Object value) { 17 | try { 18 | objectMapper.registerModule(new JavaTimeModule()); 19 | return objectMapper.writeValueAsString(value); 20 | } catch (JsonProcessingException e) { 21 | e.printStackTrace(); 22 | return ""; 23 | } 24 | } 25 | 26 | public static T readValue(String content, Class valueType) { 27 | try { 28 | objectMapper.registerModule(new JavaTimeModule()); 29 | return objectMapper.readValue(content, valueType); 30 | } catch (IOException e) { 31 | e.printStackTrace(); 32 | return null; 33 | } 34 | } 35 | 36 | public static T readValue(String content, TypeReference valueTypeRef) { 37 | try { 38 | objectMapper.registerModule(new JavaTimeModule()); 39 | return objectMapper.readValue(content, valueTypeRef); 40 | } catch (IOException e) { 41 | e.printStackTrace(); 42 | return null; 43 | } 44 | } 45 | 46 | public static T readValue(InputStream src, Class valueType) { 47 | try { 48 | objectMapper.registerModule(new JavaTimeModule()); 49 | return objectMapper.readValue(src, valueType); 50 | } catch (IOException e) { 51 | e.printStackTrace(); 52 | return null; 53 | } 54 | } 55 | 56 | public static T convertValue(Object fromValue, Class toValueType) { 57 | objectMapper.registerModule(new JavaTimeModule()); 58 | return objectMapper.convertValue(fromValue, toValueType); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /music-server/src/main/resources/mapper/ListSongMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | insert into list_song(song_id, song_list_id) VALUES (#{songId}, #{songListId}) 14 | 15 | 16 | 17 | delete 18 | list_song 19 | from 20 | list_song 21 | where 22 | song_list_id = #{id} 23 | 24 | 25 | 33 | 34 | 42 | 43 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /music-view/src/api/Singer.js: -------------------------------------------------------------------------------- 1 | import axios from "../plugins/axios"; 2 | 3 | export function addSinger(Singer) { 4 | return axios({ 5 | url: "singer/add", 6 | method: "POST", 7 | data: { 8 | ...Singer, 9 | }, 10 | }); 11 | } 12 | 13 | export function getAllSinger() { 14 | return axios({ 15 | url: "singer/allSinger", 16 | method: "GET", 17 | }); 18 | } 19 | 20 | export function getSingerByName(name) { 21 | return axios({ 22 | url: `singer/singerOfName/${name}`, 23 | method: "GET", 24 | }); 25 | } 26 | 27 | export function updateSinger(Singer) { 28 | return axios({ 29 | url: "singer/update", 30 | method: "PUT", 31 | data: { 32 | ...Singer, 33 | }, 34 | }); 35 | } 36 | 37 | export function deleteSinger(id) { 38 | return axios({ 39 | url: `singer/delete/${id}`, 40 | method: "DELETE", 41 | }); 42 | } 43 | 44 | export function deleteAllSinger(ids) { 45 | return axios({ 46 | url: `singer/deleteAll/${ids}`, 47 | method: "DELETE", 48 | }); 49 | } 50 | 51 | export function getSingerCount() { 52 | return axios({ 53 | url: "singer/getCount", 54 | method: "GET", 55 | }); 56 | } 57 | 58 | export function getSingerNameById(id) { 59 | return axios({ 60 | url: `singer/getSingerNameById/${id}`, 61 | method: "GET", 62 | }); 63 | } 64 | 65 | export function getAllSingerBySex(sex) { 66 | return axios({ 67 | url: `singer/getAllSingerBySex/${sex}`, 68 | method: "GET", 69 | }); 70 | } 71 | 72 | export function getSingerByPage(currentPage) { 73 | return axios({ 74 | url: `singer/allSinger/${currentPage}`, 75 | method: "GET", 76 | }); 77 | } 78 | 79 | export function getAllSingerCountBySex(sex) { 80 | return axios({ 81 | url: `singer/singerCountBySex/${sex}`, 82 | method: "GET", 83 | }); 84 | } 85 | 86 | export function getAllSingerBySexAndPage(sex, currentPage) { 87 | return axios({ 88 | url: `singer/getAllSingerBySex/${sex}/${currentPage}`, 89 | method: "GET", 90 | }); 91 | } 92 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/strategy/impl/AbstractUploadStrategyImpl.java: -------------------------------------------------------------------------------- 1 | package com.xs.strategy.impl; 2 | 3 | import com.xs.exception.BizException; 4 | import com.xs.strategy.UploadStrategy; 5 | import com.xs.util.FileUtils; 6 | import org.springframework.stereotype.Service; 7 | import org.springframework.web.multipart.MultipartFile; 8 | 9 | import java.io.IOException; 10 | import java.io.InputStream; 11 | 12 | /** 13 | * 抽象上传模板 14 | */ 15 | @Service 16 | public abstract class AbstractUploadStrategyImpl implements UploadStrategy { 17 | 18 | @Override 19 | public String uploadFile(MultipartFile file, String path) { 20 | try { 21 | // 获取文件md5值 22 | String md5 = FileUtils.getMd5(file.getInputStream()); 23 | // 获取文件扩展名 24 | String extName = FileUtils.getExtName(file.getOriginalFilename()); 25 | // 重新生成文件名 26 | String fileName = md5 + extName; 27 | // 判断文件是否已存在 28 | if (!exists(fileName)) { 29 | // 不存在则继续上传 30 | upload(path, fileName, file.getInputStream()); 31 | } 32 | // 返回文件访问路径 33 | return getFileAccessUrl(path + fileName); 34 | } catch (Exception e) { 35 | e.printStackTrace(); 36 | throw new BizException("文件上传失败"); 37 | } 38 | } 39 | 40 | /** 41 | * 判断文件是否存在 42 | * 43 | * @param filePath 文件路径 44 | * @return {@link Boolean} 45 | */ 46 | public abstract Boolean exists(String filePath); 47 | 48 | /** 49 | * 上传 50 | * 51 | * @param path 路径 52 | * @param fileName 文件名 53 | * @param inputStream 输入流 54 | * @throws IOException io异常 55 | */ 56 | public abstract void upload(String path, String fileName, InputStream inputStream) throws IOException; 57 | 58 | /** 59 | * 获取文件访问url 60 | * 61 | * @param filePath 文件路径 62 | * @return {@link String} 63 | */ 64 | public abstract String getFileAccessUrl(String filePath); 65 | 66 | } 67 | -------------------------------------------------------------------------------- /music-admin/src/components/TheAside.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 67 | 68 | 88 | -------------------------------------------------------------------------------- /music-view/src/api/SongList.js: -------------------------------------------------------------------------------- 1 | import axios from "../plugins/axios"; 2 | 3 | export function addSongList(SongList) { 4 | return axios({ 5 | url: "songList/add", 6 | method: "POST", 7 | data: { 8 | ...SongList, 9 | }, 10 | }); 11 | } 12 | 13 | export function getAllSongList() { 14 | return axios({ 15 | url: "songList/all", 16 | method: "GET", 17 | }); 18 | } 19 | 20 | export function getAllSongListByPage(currentPage) { 21 | return axios({ 22 | url: `songList/all/${currentPage}`, 23 | method: "GET", 24 | }); 25 | } 26 | 27 | export function getSongListByName(name) { 28 | return axios({ 29 | url: `songList/songListOfName/${name}`, 30 | method: "GET", 31 | }); 32 | } 33 | 34 | export function updateSongList(SongList) { 35 | return axios({ 36 | url: "songList/update", 37 | method: "PUT", 38 | data: { 39 | ...SongList, 40 | }, 41 | }); 42 | } 43 | 44 | export function deleteSongList(id) { 45 | return axios({ 46 | url: `songList/delete/${id}`, 47 | method: "DELETE", 48 | }); 49 | } 50 | 51 | export function deleteAllSongList(ids) { 52 | return axios({ 53 | url: `songList/deleteAll/${ids}`, 54 | method: "DELETE", 55 | }); 56 | } 57 | 58 | export function getSongListCount() { 59 | return axios({ 60 | url: "songList/getCount", 61 | method: "GET", 62 | }); 63 | } 64 | 65 | export function getSongListByStyle(style) { 66 | return axios({ 67 | url: `songList/getSongListByStyle/${style}`, 68 | method: "GET", 69 | }); 70 | } 71 | 72 | export function getSongListByStyleAndPage(style, currentPage) { 73 | return axios({ 74 | url: `songList/getSongListByStyle/${style}/${currentPage}`, 75 | method: "GET", 76 | }); 77 | } 78 | 79 | export function getAllStyle() { 80 | return axios({ 81 | url: "songList/allStyle", 82 | method: "GET", 83 | }); 84 | } 85 | 86 | export function getAllSongListCountByStyle(style) { 87 | return axios({ 88 | url: `songList/songListCountByStyle/${style}`, 89 | method: "GET", 90 | }); 91 | } 92 | -------------------------------------------------------------------------------- /music-server/src/main/resources/mapper/SongListMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 21 | 24 | 25 | 32 | 33 | 41 | 42 | 48 | 49 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/domain/Admin.java: -------------------------------------------------------------------------------- 1 | package com.xs.domain; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 5 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 6 | import lombok.Data; 7 | import org.springframework.security.core.GrantedAuthority; 8 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 9 | import org.springframework.security.core.userdetails.UserDetails; 10 | 11 | import java.io.Serial; 12 | import java.io.Serializable; 13 | import java.util.ArrayList; 14 | import java.util.Collection; 15 | import java.util.Date; 16 | import java.util.List; 17 | 18 | /** 19 | * 管理员 20 | */ 21 | @Data 22 | public class Admin implements Serializable, UserDetails { 23 | /** 24 | * 主键 25 | */ 26 | @JsonSerialize(using = ToStringSerializer.class) 27 | private Long id; 28 | 29 | /** 30 | * 账号 31 | */ 32 | private String username; 33 | 34 | /** 35 | * 密码 36 | */ 37 | private String password; 38 | 39 | /** 40 | * 用户角色 41 | */ 42 | private String role; 43 | 44 | /** 45 | * token有效期 46 | */ 47 | private Date expiration; 48 | 49 | @Serial 50 | private static final long serialVersionUID = 1L; 51 | 52 | @JsonIgnore 53 | @Override 54 | public Collection getAuthorities() { 55 | List authorityList = new ArrayList<>(); 56 | authorityList.add(new SimpleGrantedAuthority(role)); 57 | return authorityList; 58 | } 59 | 60 | @JsonIgnore 61 | @Override 62 | public boolean isAccountNonExpired() { 63 | return true; 64 | } 65 | 66 | @JsonIgnore 67 | @Override 68 | public boolean isAccountNonLocked() { 69 | return true; 70 | } 71 | 72 | @JsonIgnore 73 | @Override 74 | public boolean isCredentialsNonExpired() { 75 | return true; 76 | } 77 | 78 | @JsonIgnore 79 | @Override 80 | public boolean isEnabled() { 81 | return true; 82 | } 83 | } -------------------------------------------------------------------------------- /music-view/src/api/Song.js: -------------------------------------------------------------------------------- 1 | import axios from "../plugins/axios"; 2 | 3 | export function getAllSong() { 4 | return axios({ 5 | url: "song/all", 6 | method: "GET", 7 | }); 8 | } 9 | 10 | export function addSong(Song) { 11 | return axios({ 12 | url: "song/add", 13 | method: "POST", 14 | data: { 15 | ...Song, 16 | }, 17 | }); 18 | } 19 | 20 | export function getAllSongBySingerId(id) { 21 | return axios({ 22 | url: `song/allSong/${id}`, 23 | method: "GET", 24 | }); 25 | } 26 | 27 | export function getAllSongByName(name) { 28 | return axios({ 29 | url: `song/songOfName/${name}`, 30 | method: "GET", 31 | }); 32 | } 33 | 34 | export function updateSong(Song) { 35 | return axios({ 36 | url: "song/update", 37 | method: "PUT", 38 | data: { 39 | ...Song, 40 | }, 41 | }); 42 | } 43 | 44 | export function deleteSong(id) { 45 | return axios({ 46 | url: `song/delete/${id}`, 47 | method: "DELETE", 48 | }); 49 | } 50 | 51 | export function deleteAllSong(ids) { 52 | return axios({ 53 | url: `song/deleteAll/${ids}`, 54 | method: "DELETE", 55 | }); 56 | } 57 | 58 | export function getSongCount() { 59 | return axios({ 60 | url: "song/getCount", 61 | method: "GET", 62 | }); 63 | } 64 | 65 | export function download(url) { 66 | return axios({ 67 | url: url, 68 | method: "GET", 69 | responseType: "blob", 70 | }); 71 | } 72 | 73 | export function getAllSongBySongListId(id) { 74 | return axios({ 75 | url: `song/all/${id}`, 76 | method: "GET", 77 | }); 78 | } 79 | 80 | export function gerAllSongAndSingerNameBySingerId(singerId) { 81 | return axios({ 82 | url: `song/songAndSingerName/${singerId}`, 83 | method: "GET", 84 | }); 85 | } 86 | 87 | export function getSongByPlayCount() { 88 | return axios({ 89 | url: "song/songOfPlayCount", 90 | method: "GET", 91 | }); 92 | } 93 | 94 | export function addPlayCount(SongVo) { 95 | return axios({ 96 | url: "song/addPlayCount", 97 | method: "POST", 98 | data: { 99 | ...SongVo, 100 | }, 101 | }); 102 | } 103 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/util/FastJsonRedisSerializer.java: -------------------------------------------------------------------------------- 1 | package com.xs.util; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.parser.ParserConfig; 5 | import com.alibaba.fastjson.serializer.SerializerFeature; 6 | import com.alibaba.fastjson.util.TypeUtils; 7 | import com.fasterxml.jackson.databind.JavaType; 8 | import com.fasterxml.jackson.databind.type.TypeFactory; 9 | import org.springframework.data.redis.serializer.RedisSerializer; 10 | import org.springframework.data.redis.serializer.SerializationException; 11 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 12 | 13 | import java.nio.charset.Charset; 14 | import java.nio.charset.StandardCharsets; 15 | 16 | public class FastJsonRedisSerializer implements RedisSerializer 17 | { 18 | 19 | public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; 20 | 21 | private final Class clazz; 22 | 23 | static 24 | { 25 | ParserConfig.getGlobalInstance().addAccept("com.xs.domain"); 26 | ParserConfig.getGlobalInstance().addAccept("org.springframework.security.core.authority."); 27 | TypeUtils.addMapping("org.springframework.security.core.authority.SimpleGrantedAuthority", SimpleGrantedAuthority.class); 28 | } 29 | 30 | public FastJsonRedisSerializer(Class clazz) 31 | { 32 | super(); 33 | this.clazz = clazz; 34 | } 35 | 36 | @Override 37 | public byte[] serialize(T t) throws SerializationException 38 | { 39 | if (t == null) 40 | { 41 | return new byte[0]; 42 | } 43 | return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET); 44 | } 45 | 46 | @Override 47 | public T deserialize(byte[] bytes) throws SerializationException 48 | { 49 | if (bytes == null || bytes.length <= 0) 50 | { 51 | return null; 52 | } 53 | String str = new String(bytes, DEFAULT_CHARSET); 54 | 55 | return JSON.parseObject(str, clazz); 56 | } 57 | 58 | 59 | protected JavaType getJavaType(Class clazz) 60 | { 61 | return TypeFactory.defaultInstance().constructType(clazz); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/service/impl/TestServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.xs.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 4 | import com.xs.domain.Singer; 5 | import com.xs.domain.Song; 6 | import com.xs.domain.SongList; 7 | import com.xs.mapper.SingerMapper; 8 | import com.xs.mapper.SongListMapper; 9 | import com.xs.mapper.SongMapper; 10 | import com.xs.service.TestService; 11 | import org.springframework.stereotype.Service; 12 | 13 | import javax.annotation.Resource; 14 | import java.util.List; 15 | 16 | @Service 17 | public class TestServiceImpl implements TestService { 18 | 19 | @Resource 20 | private SingerMapper singerMapper; 21 | 22 | @Resource 23 | private SongMapper songMapper; 24 | 25 | @Resource 26 | private SongListMapper songListMapper; 27 | 28 | @Override 29 | public void changeUrl() { 30 | List allSongList = songListMapper.getAllSongList(); 31 | for (SongList songList : allSongList) { 32 | String pic = songList.getPic(); 33 | String replace = pic.replace("http://localhost/", "https://www.freemusic.ltd/"); 34 | songList.setPic(replace); 35 | songListMapper.updateById(songList); 36 | } 37 | List singerList = singerMapper.selectAllSinger(); 38 | for (Singer singer : singerList) { 39 | String pic = singer.getPic(); 40 | String replace = pic.replace("http://localhost/", "https://www.freemusic.ltd/"); 41 | singer.setPic(replace); 42 | singerMapper.updateById(singer); 43 | } 44 | LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); 45 | List songList = songMapper.selectList(lqw); 46 | for (Song song : songList) { 47 | String pic = song.getPic(); 48 | String replace = pic.replace("http://localhost/", "https://www.freemusic.ltd/"); 49 | song.setPic(replace); 50 | String url = song.getUrl(); 51 | String replace1 = url.replace("http://localhost/", "https://www.freemusic.ltd/"); 52 | song.setUrl(replace1); 53 | songMapper.updateById(song); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /music-view/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 | img { 36 | width: 100%; 37 | } 38 | } 39 | 40 | /*信息*/ 41 | .album-info { 42 | color: $color-black; 43 | width: 500px; 44 | font-size: 20px; 45 | font-weight: 500; 46 | margin-top: -100px; 47 | margin-left: 100px; 48 | padding: 30px 30px; 49 | li { 50 | width: 100%; 51 | line-height: 40px; 52 | } 53 | } 54 | } 55 | 56 | /*歌单内容*/ 57 | .album-content { 58 | margin-left: 300px; 59 | padding: 40px 100px; 60 | 61 | .songList { 62 | background-color: $color-white; 63 | border-radius: 20px; 64 | min-width: 600px; 65 | } 66 | 67 | /*歌单题目*/ 68 | .album-title { 69 | font-size: 30px; 70 | font-weight: 600; 71 | } 72 | 73 | .songs-body { 74 | margin-top: 50px; 75 | } 76 | } 77 | 78 | .activeColor { 79 | background-color: $color-blue-shallow !important; 80 | color: $color-white; 81 | } 82 | 83 | .content { 84 | display: flex; 85 | li { 86 | display: block; 87 | height: 40px; 88 | line-height: 40px; 89 | font-size: 18px; 90 | padding: 0 10px; 91 | box-sizing: border-box; 92 | border-radius: 5px; 93 | margin-right: 2px; 94 | cursor: pointer; 95 | 96 | &:hover { 97 | background-color: $color-blue-active; 98 | color: $color-white; 99 | } 100 | &:active { 101 | background-color: $color-blue-shallow; 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/controller/CommentController.java: -------------------------------------------------------------------------------- 1 | package com.xs.controller; 2 | 3 | import com.xs.common.Result; 4 | import com.xs.domain.Comment; 5 | import com.xs.dto.CommentDto; 6 | import com.xs.service.CommentService; 7 | import org.springframework.web.bind.annotation.*; 8 | 9 | import javax.annotation.Resource; 10 | 11 | @RestController 12 | @RequestMapping("/comment") 13 | public class CommentController { 14 | 15 | @Resource 16 | private CommentService commentService; 17 | 18 | /** 19 | * 添加评论 20 | */ 21 | @PostMapping("/add") 22 | public Result addComment(@RequestBody Comment comment) { 23 | return commentService.addComment(comment); 24 | } 25 | 26 | /** 27 | * 修改评论 28 | */ 29 | @PutMapping("/update") 30 | public Result updateComment(@RequestBody Comment comment) { 31 | return commentService.updateComment(comment); 32 | } 33 | 34 | /** 35 | * 删除评论 36 | */ 37 | @DeleteMapping("/delete/{id}") 38 | public Result deleteComment(@PathVariable Long id) { 39 | return commentService.deleteComment(id); 40 | } 41 | 42 | /** 43 | * 查询所有评论 44 | */ 45 | @GetMapping("/all") 46 | public Result getAllComment() { 47 | return commentService.getAllComment(); 48 | } 49 | 50 | /** 51 | * 查询指定歌单所有评论 52 | */ 53 | @GetMapping("/commentOfSongListId/{id}") 54 | public Result getAllCommentBySongListId(@PathVariable Long id) { 55 | return commentService.getAllCommentBySongListId(id); 56 | } 57 | 58 | /** 59 | * 查询指定歌曲所有评论 60 | */ 61 | @GetMapping("/commentOfSongId/{id}") 62 | public Result getAllCommentBySongId(@PathVariable Long id) { 63 | return commentService.getAllCommentBySongId(id); 64 | } 65 | 66 | /** 67 | * 给指定评论点赞 68 | */ 69 | @PutMapping("/updateCommentUp") 70 | public Result updateCommentUp(@RequestBody CommentDto commentDto) { 71 | return commentService.updateCommentUp(commentDto); 72 | } 73 | 74 | /** 75 | * 取消点赞 76 | */ 77 | @PutMapping("/cancelCommentUp") 78 | public Result cancelCommentUp(@RequestBody CommentDto commentDto) { 79 | return commentService.cancelCommentUp(commentDto); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /music-server/src/main/resources/mapper/SingerMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 23 | 24 | 32 | 33 | 36 | 37 | 40 | 41 | 44 | 45 | 53 | 54 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /music-admin/src/assets/js/iconfont.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | !function(a){var e,n='',t=(e=document.getElementsByTagName("script"))[e.length-1].getAttribute("data-injectcss");if(t&&!a.__iconfont__svg__cssinject__){a.__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&&(o=e,i=a.document,c=!1,(d=function(){try{i.documentElement.doScroll("left")}catch(e){return void setTimeout(d,50)}n()})(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,n())});function n(){c||(c=!0,o())}var o,i,c,d}(function(){var e,t;(e=document.createElement("div")).innerHTML=n,n=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",function(e,t){t.firstChild?function(e,t){t.parentNode.insertBefore(e,t)}(e,t.firstChild):t.appendChild(e)}(t,document.body))})}(window); 3 | -------------------------------------------------------------------------------- /music-view/src/assets/css/lyric.scss: -------------------------------------------------------------------------------- 1 | .box { 2 | 3 | display: flex; 4 | background-color: darkslategrey; 5 | 6 | .the-aside { 7 | width: 400px; 8 | 9 | .img { 10 | margin-top: 90px; 11 | width: 300px; 12 | height: 300px; 13 | border: 5px solid #fff; 14 | border-radius: 10%; 15 | overflow: hidden; 16 | background-color: #fff; 17 | margin-bottom: 20px; 18 | margin-left: 20px; 19 | } 20 | 21 | .show { 22 | font-size: 16px; 23 | } 24 | 25 | .show h3 { 26 | font-weight: normal; 27 | margin-left: 80px; 28 | color: #fff; 29 | } 30 | 31 | .show h3 span{ 32 | color: #2aa3ef; 33 | } 34 | 35 | } 36 | .content { 37 | .lyric-title { 38 | margin-top: 90px; 39 | text-align: center; 40 | color: #fff; 41 | font-weight: bold; 42 | } 43 | 44 | .song-lyric { 45 | margin: 10px auto; 46 | width: 500px; 47 | height: 400px; 48 | overflow-x: hidden; 49 | overflow-y: scroll; 50 | border-radius: 12px; 51 | padding: 0 20px 50px 20px; 52 | font-family: sans-serif; 53 | 54 | .has-lyric { 55 | font-size: 16px; 56 | padding: 30px 0; 57 | width: 100%; 58 | min-height: 170px; 59 | text-align: center; 60 | 61 | li { 62 | width: 100%; 63 | height: 40px; 64 | line-height: 40px; 65 | color: #fff; 66 | } 67 | } 68 | 69 | .no-lyric { 70 | margin: 200px 0; 71 | width: 100%; 72 | text-align: center; 73 | 74 | span { 75 | font-size: 16px; 76 | text-align: center; 77 | } 78 | } 79 | } 80 | 81 | .lyric-fade-enter, 82 | .lyric-fade-leave-to { 83 | transform: translateX(30px); 84 | opacity: 0; 85 | } 86 | 87 | .lyric-fade-enter-active, 88 | .lyric-fade-leave-active { 89 | transition: all 0.3s ease; 90 | } 91 | 92 | .song-lyric::-webkit-scrollbar { 93 | display: none; 94 | } 95 | 96 | .comment { 97 | width: 500px; 98 | margin: 10px auto 100px; 99 | } 100 | 101 | } 102 | } 103 | 104 | 105 | -------------------------------------------------------------------------------- /music-admin/src/assets/js/city.js: -------------------------------------------------------------------------------- 1 | // 地区选择 2 | const cities = [ 3 | { 4 | value: "北京", 5 | label: "北京", 6 | }, 7 | { 8 | value: "天津", 9 | label: "天津", 10 | }, 11 | { 12 | value: "河北", 13 | label: "河北", 14 | }, 15 | { 16 | value: "山西", 17 | label: "山西", 18 | }, 19 | { 20 | value: "内蒙古", 21 | label: "内蒙古", 22 | }, 23 | { 24 | value: "辽宁", 25 | label: "辽宁", 26 | }, 27 | { 28 | value: "吉林", 29 | label: "吉林", 30 | }, 31 | { 32 | value: "黑龙江", 33 | label: "黑龙江", 34 | }, 35 | { 36 | value: "上海", 37 | label: "上海", 38 | }, 39 | { 40 | value: "江苏", 41 | label: "江苏", 42 | }, 43 | { 44 | value: "浙江", 45 | label: "浙江", 46 | }, 47 | { 48 | value: "安徽", 49 | label: "安徽", 50 | }, 51 | { 52 | value: "福建", 53 | label: "福建", 54 | }, 55 | { 56 | value: "江西", 57 | label: "江西", 58 | }, 59 | { 60 | value: "山东", 61 | label: "山东", 62 | }, 63 | { 64 | value: "河南", 65 | label: "河南", 66 | }, 67 | { 68 | value: "湖北", 69 | label: "湖北", 70 | }, 71 | { 72 | value: "湖南", 73 | label: "湖南", 74 | }, 75 | { 76 | value: "广东", 77 | label: "广东", 78 | }, 79 | { 80 | value: "广西", 81 | label: "广西", 82 | }, 83 | { 84 | value: "海南", 85 | label: "海南", 86 | }, 87 | { 88 | value: "重庆", 89 | label: "重庆", 90 | }, 91 | { 92 | value: "四川", 93 | label: "四川", 94 | }, 95 | { 96 | value: "贵州", 97 | label: "贵州", 98 | }, 99 | { 100 | value: "云南", 101 | label: "云南", 102 | }, 103 | { 104 | value: "西藏", 105 | label: "西藏", 106 | }, 107 | { 108 | value: "陕西", 109 | label: "陕西", 110 | }, 111 | { 112 | value: "甘肃", 113 | label: "甘肃", 114 | }, 115 | { 116 | value: "青海", 117 | label: "青海", 118 | }, 119 | { 120 | value: "宁夏", 121 | label: "宁夏", 122 | }, 123 | { 124 | value: "新疆", 125 | label: "新疆", 126 | }, 127 | { 128 | value: "香港", 129 | label: "香港", 130 | }, 131 | { 132 | value: "澳门", 133 | label: "澳门", 134 | }, 135 | { 136 | value: "台湾", 137 | label: "台湾", 138 | }, 139 | ]; 140 | 141 | export default cities; 142 | -------------------------------------------------------------------------------- /music-view/src/assets/data/form.js: -------------------------------------------------------------------------------- 1 | // 地区选择 2 | const cities = [ 3 | { 4 | value: "北京", 5 | label: "北京", 6 | }, 7 | { 8 | value: "天津", 9 | label: "天津", 10 | }, 11 | { 12 | value: "河北", 13 | label: "河北", 14 | }, 15 | { 16 | value: "山西", 17 | label: "山西", 18 | }, 19 | { 20 | value: "内蒙古", 21 | label: "内蒙古", 22 | }, 23 | { 24 | value: "辽宁", 25 | label: "辽宁", 26 | }, 27 | { 28 | value: "吉林", 29 | label: "吉林", 30 | }, 31 | { 32 | value: "黑龙江", 33 | label: "黑龙江", 34 | }, 35 | { 36 | value: "上海", 37 | label: "上海", 38 | }, 39 | { 40 | value: "江苏", 41 | label: "江苏", 42 | }, 43 | { 44 | value: "浙江", 45 | label: "浙江", 46 | }, 47 | { 48 | value: "安徽", 49 | label: "安徽", 50 | }, 51 | { 52 | value: "福建", 53 | label: "福建", 54 | }, 55 | { 56 | value: "江西", 57 | label: "江西", 58 | }, 59 | { 60 | value: "山东", 61 | label: "山东", 62 | }, 63 | { 64 | value: "河南", 65 | label: "河南", 66 | }, 67 | { 68 | value: "湖北", 69 | label: "湖北", 70 | }, 71 | { 72 | value: "湖南", 73 | label: "湖南", 74 | }, 75 | { 76 | value: "广东", 77 | label: "广东", 78 | }, 79 | { 80 | value: "广西", 81 | label: "广西", 82 | }, 83 | { 84 | value: "海南", 85 | label: "海南", 86 | }, 87 | { 88 | value: "重庆", 89 | label: "重庆", 90 | }, 91 | { 92 | value: "四川", 93 | label: "四川", 94 | }, 95 | { 96 | value: "贵州", 97 | label: "贵州", 98 | }, 99 | { 100 | value: "云南", 101 | label: "云南", 102 | }, 103 | { 104 | value: "西藏", 105 | label: "西藏", 106 | }, 107 | { 108 | value: "陕西", 109 | label: "陕西", 110 | }, 111 | { 112 | value: "甘肃", 113 | label: "甘肃", 114 | }, 115 | { 116 | value: "青海", 117 | label: "青海", 118 | }, 119 | { 120 | value: "宁夏", 121 | label: "宁夏", 122 | }, 123 | { 124 | value: "新疆", 125 | label: "新疆", 126 | }, 127 | { 128 | value: "香港", 129 | label: "香港", 130 | }, 131 | { 132 | value: "澳门", 133 | label: "澳门", 134 | }, 135 | { 136 | value: "台湾", 137 | label: "台湾", 138 | }, 139 | ]; 140 | 141 | export default cities; 142 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/service/impl/RankServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.xs.service.impl; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | import com.xs.common.Result; 5 | import com.xs.domain.Ranks; 6 | import com.xs.mapper.RanksMapper; 7 | import com.xs.service.RankService; 8 | import org.springframework.stereotype.Service; 9 | 10 | import javax.annotation.Resource; 11 | import java.text.DecimalFormat; 12 | import java.util.List; 13 | import java.util.Objects; 14 | 15 | /** 16 | * @author xs 17 | * description 针对表【Ranks(评价)】的数据库操作Service实现 18 | * createDate 2022-10-11 16:16:20 19 | */ 20 | @Service 21 | public class RankServiceImpl extends ServiceImpl implements RankService { 22 | 23 | @Resource 24 | private RanksMapper ranksMapper; 25 | 26 | /** 27 | * 添加歌单评价 28 | */ 29 | @Override 30 | public Result addRanks(Ranks ranks) { 31 | List ranksList = ranksMapper.getAllRanks(); 32 | if (!ranksList.isEmpty()) { 33 | for (Ranks r : ranksList) { 34 | if (r.getSongListId().equals(ranks.getSongListId()) && r.getConsumerId().equals(ranks.getConsumerId())) { 35 | return Result.error("用户不能重复评价"); 36 | } 37 | } 38 | } 39 | int i = ranksMapper.insert(ranks); 40 | if (i > 0) { 41 | return Result.ok("评价成功"); 42 | } else { 43 | return Result.error("评价失败"); 44 | } 45 | } 46 | 47 | /** 48 | * 获取指定歌单的平均分 49 | */ 50 | @Override 51 | public Result getRanksAvgScore(Long id) { 52 | double[] allScore = ranksMapper.getAllScore(id); 53 | double count = 0; 54 | if (Objects.nonNull(allScore) && allScore.length != 0) { 55 | for (double i : allScore) { 56 | count += i; 57 | } 58 | int number = ranksMapper.getCountBySongListId(id); 59 | if (number == 0) { 60 | return Result.error("数据为空"); 61 | } else { 62 | double avgScore = count / number / 2; 63 | return Result.ok("查询成功", new DecimalFormat("0.0").format(avgScore)); 64 | } 65 | } else { 66 | return Result.error("数据为空"); 67 | } 68 | } 69 | } 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /music-view/src/pages/SingerAlbum.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 80 | 81 | 84 | -------------------------------------------------------------------------------- /music-server/src/main/resources/mapper/ConsumerMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 27 | 28 | 34 | 35 | 38 | 39 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /music-server/src/main/java/com/xs/controller/admin/ConsumerAdminController.java: -------------------------------------------------------------------------------- 1 | package com.xs.controller.admin; 2 | 3 | import com.xs.common.Result; 4 | import com.xs.domain.Consumer; 5 | import com.xs.service.ConsumerService; 6 | import org.springframework.web.bind.annotation.*; 7 | 8 | import javax.annotation.Resource; 9 | 10 | @RequestMapping("/admin/consumer") 11 | @RestController 12 | public class ConsumerAdminController { 13 | 14 | @Resource 15 | private ConsumerService consumerService; 16 | 17 | /** 18 | * 查询所有用户 19 | */ 20 | @GetMapping("/all") 21 | public Result getAll() { 22 | return consumerService.getAll(); 23 | } 24 | 25 | /** 26 | * 修改用户信息 27 | */ 28 | @PutMapping("/update") 29 | public Result updateConsumer(@RequestBody Consumer consumer) { 30 | return consumerService.updateConsumer(consumer); 31 | } 32 | 33 | /** 34 | * 按用户名称查询用户信息 35 | */ 36 | @GetMapping("/consumerOfName/{name}") 37 | public Result getConsumerByName(@PathVariable String name) { 38 | return consumerService.getConsumerByName(name); 39 | } 40 | 41 | /** 42 | * 添加用户 43 | */ 44 | @PostMapping("/add") 45 | public Result addConsumer(@RequestBody Consumer consumer) { 46 | return consumerService.addConsumer(consumer); 47 | } 48 | 49 | /** 50 | * 删除用户 51 | */ 52 | @DeleteMapping("/delete/{id}") 53 | public Result deleteConsumer(@PathVariable Long id) { 54 | return consumerService.deleteConsumer(id); 55 | } 56 | 57 | /** 58 | * 批量删除用户 59 | */ 60 | @DeleteMapping("/deleteAll/{ids}") 61 | public Result deleteAllConsumer(@PathVariable Long[] ids) { 62 | return consumerService.deleteAllConsumer(ids); 63 | } 64 | 65 | /** 66 | * 获取用户总数 67 | */ 68 | @GetMapping("/getCount") 69 | public Result getConsumerCount() { 70 | return consumerService.getConsumerCount(); 71 | } 72 | 73 | /** 74 | * 按性别分组查询用户数量 75 | */ 76 | @GetMapping("/getCountBySex") 77 | public Result getConsumerCountBySex() { 78 | return consumerService.getConsumerCountBySex(); 79 | } 80 | 81 | /** 82 | * 按id查询用户信息 83 | */ 84 | @GetMapping("/consumerOfId/{id}") 85 | public Result getConsumerById(@PathVariable Long id) { 86 | return consumerService.getConsumerById(id); 87 | } 88 | } 89 | --------------------------------------------------------------------------------