The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── .github
    └── workflows
    │   └── build.yml
├── .gitignore
├── LICENSE
├── README.md
├── img
    ├── image-20240108131746139.png
    ├── image-20240108131824788.png
    └── image-20240108131927175.png
├── music-client
    ├── .browserslistrc
    ├── .eslintrc.js
    ├── .gitignore
    ├── README.md
    ├── babel.config.js
    ├── package-lock.json
    ├── package.json
    ├── public
    │   ├── favicon.ico
    │   └── index.html
    ├── src
    │   ├── App.vue
    │   ├── api
    │   │   ├── index.ts
    │   │   └── request.ts
    │   ├── assets
    │   │   ├── css
    │   │   │   ├── global.scss
    │   │   │   ├── index.scss
    │   │   │   ├── sign.scss
    │   │   │   ├── var.scss
    │   │   │   ├── yin-current-play.scss
    │   │   │   └── yin-play-bar.scss
    │   │   ├── icons
    │   │   │   ├── iconfont.js
    │   │   │   ├── iconfont1.js
    │   │   │   ├── iconfont2.js
    │   │   │   ├── iconfont3.js
    │   │   │   ├── iconfont4.js
    │   │   │   └── index.js
    │   │   └── images
    │   │   │   ├── tubiao.jpg
    │   │   │   └── user.jpg
    │   ├── components
    │   │   ├── Comment.vue
    │   │   ├── PlayList.vue
    │   │   ├── SongList.vue
    │   │   └── layouts
    │   │   │   ├── YinAudio.vue
    │   │   │   ├── YinCurrentPlay.vue
    │   │   │   ├── YinFooter.vue
    │   │   │   ├── YinHeader.vue
    │   │   │   ├── YinHeaderNav.vue
    │   │   │   ├── YinIcon.vue
    │   │   │   ├── YinLoginLogo.vue
    │   │   │   ├── YinNav.vue
    │   │   │   ├── YinPlayBar.vue
    │   │   │   └── YinScrollTop.vue
    │   ├── enums
    │   │   ├── area.ts
    │   │   ├── icon.ts
    │   │   ├── index.ts
    │   │   ├── music-name.ts
    │   │   ├── nav.ts
    │   │   ├── router-name.ts
    │   │   ├── singer.ts
    │   │   ├── songList.ts
    │   │   └── validate.ts
    │   ├── main.ts
    │   ├── mixins
    │   │   └── mixin.ts
    │   ├── router
    │   │   └── index.ts
    │   ├── shims-vue.d.ts
    │   ├── store
    │   │   ├── configure.ts
    │   │   ├── index.ts
    │   │   ├── song.ts
    │   │   └── user.ts
    │   ├── utils
    │   │   └── index.ts
    │   └── views
    │   │   ├── FPassword.vue
    │   │   ├── Home.vue
    │   │   ├── Lyric.vue
    │   │   ├── SignIn.vue
    │   │   ├── SignUp.vue
    │   │   ├── YinContainer.vue
    │   │   ├── error
    │   │       └── 404.vue
    │   │   ├── loginByemail.vue
    │   │   ├── personal
    │   │       └── Personal.vue
    │   │   ├── search
    │   │       ├── Search.vue
    │   │       ├── SearchSong.vue
    │   │       └── SearchSongList.vue
    │   │   ├── setting
    │   │       ├── Password.vue
    │   │       ├── PersonalData.vue
    │   │       ├── Setting.vue
    │   │       └── Upload.vue
    │   │   ├── singer
    │   │       ├── Singer.vue
    │   │       └── SingerDetail.vue
    │   │   └── song-sheet
    │   │       ├── SongSheet.vue
    │   │       └── SongSheetDetail.vue
    ├── tsconfig.json
    └── vue.config.js
├── music-manage
    ├── .browserslistrc
    ├── .eslintrc.js
    ├── .gitignore
    ├── README.md
    ├── babel.config.js
    ├── package-lock.json
    ├── package.json
    ├── public
    │   ├── favicon.ico
    │   └── index.html
    ├── src
    │   ├── App.vue
    │   ├── api
    │   │   ├── index.ts
    │   │   └── request.ts
    │   ├── assets
    │   │   ├── css
    │   │   │   └── main.css
    │   │   ├── icons
    │   │   │   └── iconfont.js
    │   │   └── images
    │   │   │   ├── background.jpg
    │   │   │   └── user.jpg
    │   ├── components
    │   │   ├── dialog
    │   │   │   └── YinDelDialog.vue
    │   │   └── layouts
    │   │   │   ├── YinAside.vue
    │   │   │   ├── YinAudio.vue
    │   │   │   └── YinHeader.vue
    │   ├── enums
    │   │   ├── area.ts
    │   │   ├── icon.ts
    │   │   ├── index.ts
    │   │   ├── music-name.ts
    │   │   └── router-name.ts
    │   ├── main.ts
    │   ├── mixins
    │   │   └── mixin.ts
    │   ├── router
    │   │   └── index.ts
    │   ├── shims-vue.d.ts
    │   ├── store
    │   │   └── index.ts
    │   ├── utils
    │   │   ├── emitter.ts
    │   │   └── index.ts
    │   └── views
    │   │   ├── CollectPage.vue
    │   │   ├── CommentPage.vue
    │   │   ├── ConsumerPage.vue
    │   │   ├── Home.vue
    │   │   ├── InfoPage.vue
    │   │   ├── ListSongPage.vue
    │   │   ├── Login.vue
    │   │   ├── SingerPage.vue
    │   │   ├── SongListPage.vue
    │   │   └── SongPage.vue
    ├── tsconfig.json
    └── vue.config.js
└── music-server
    ├── .gitignore
    ├── Dockerfile
    ├── docker-server
        ├── docker-compose.yml
        └── dockerfile
    ├── docker-vue-client
        └── dockerfile
    ├── docker-vue-manage
        └── dockerfile
    ├── mvnw
    ├── mvnw.cmd
    ├── pom.xml
    ├── sql
        └── tp_music.sql
    └── src
        ├── main
            ├── java
            │   └── com
            │   │   └── example
            │   │       └── yin
            │   │           ├── YinMusicApplication.java
            │   │           ├── common
            │   │               └── R.java
            │   │           ├── config
            │   │               ├── CorsInterceptor.java
            │   │               ├── MinioConfig.java
            │   │               ├── RedisConfig.java
            │   │               ├── WebCharacterEncodingFilter.java
            │   │               ├── WebMvcConfig.java
            │   │               └── WebPicConfig.java
            │   │           ├── constant
            │   │               └── Constants.java
            │   │           ├── controller
            │   │               ├── AdminController.java
            │   │               ├── BannerController.java
            │   │               ├── CollectController.java
            │   │               ├── CommentController.java
            │   │               ├── ConsumerController.java
            │   │               ├── FileDownloadController.java
            │   │               ├── ListSongController.java
            │   │               ├── MinioController.java
            │   │               ├── MinioUploadController.java
            │   │               ├── RankListController.java
            │   │               ├── SingerController.java
            │   │               ├── SongController.java
            │   │               ├── SongListController.java
            │   │               └── UserSupportController.java
            │   │           ├── handler
            │   │               └── MyMetaObjectHandler.java
            │   │           ├── mapper
            │   │               ├── AdminMapper.java
            │   │               ├── BannerMapper.java
            │   │               ├── CollectMapper.java
            │   │               ├── CommentMapper.java
            │   │               ├── ConsumerMapper.java
            │   │               ├── ListSongMapper.java
            │   │               ├── RankListMapper.java
            │   │               ├── SingerMapper.java
            │   │               ├── SongListMapper.java
            │   │               ├── SongMapper.java
            │   │               └── UserSupportMapper.java
            │   │           ├── model
            │   │               ├── domain
            │   │               │   ├── Admin.java
            │   │               │   ├── Banner.java
            │   │               │   ├── Collect.java
            │   │               │   ├── Comment.java
            │   │               │   ├── Consumer.java
            │   │               │   ├── ListSong.java
            │   │               │   ├── Order.java
            │   │               │   ├── RankList.java
            │   │               │   ├── ResetPasswordRequest.java
            │   │               │   ├── Singer.java
            │   │               │   ├── Song.java
            │   │               │   ├── SongList.java
            │   │               │   └── UserSupport.java
            │   │               └── request
            │   │               │   ├── AdminRequest.java
            │   │               │   ├── CollectRequest.java
            │   │               │   ├── CommentRequest.java
            │   │               │   ├── ConsumerRequest.java
            │   │               │   ├── ListSongRequest.java
            │   │               │   ├── RankListRequest.java
            │   │               │   ├── SingerRequest.java
            │   │               │   ├── SongListRequest.java
            │   │               │   ├── SongRequest.java
            │   │               │   └── UserSupportRequest.java
            │   │           ├── service
            │   │               ├── AdminService.java
            │   │               ├── BannerService.java
            │   │               ├── CollectService.java
            │   │               ├── CommentService.java
            │   │               ├── ConsumerService.java
            │   │               ├── ListSongService.java
            │   │               ├── OrderManager.java
            │   │               ├── RankListService.java
            │   │               ├── SingerService.java
            │   │               ├── SongListService.java
            │   │               ├── SongService.java
            │   │               ├── UserSupportService.java
            │   │               └── impl
            │   │               │   ├── AdminServiceImpl.java
            │   │               │   ├── BannerServiceImpl.java
            │   │               │   ├── CollectServiceImpl.java
            │   │               │   ├── CommentServiceImpl.java
            │   │               │   ├── ConsumerServiceImpl.java
            │   │               │   ├── ListSongServiceImpl.java
            │   │               │   ├── RankListServiceImpl.java
            │   │               │   ├── SimpleOrderManager.java
            │   │               │   ├── SingerServiceImpl.java
            │   │               │   ├── SongListServiceImpl.java
            │   │               │   ├── SongServiceImpl.java
            │   │               │   └── UserSupportServiceImpl.java
            │   │           └── utils
            │   │               ├── RandomUtils.java
            │   │               └── TestFileUtil.java
            └── resources
            │   ├── application-dev.properties
            │   ├── application-prod.properties
            │   ├── application.properties
            │   ├── application.yml
            │   ├── log4j.properties
            │   ├── mapper
            │       ├── AdminMapper.xml
            │       ├── BannerMapper.xml
            │       ├── CollectMapper.xml
            │       ├── CommentMapper.xml
            │       ├── ConsumerMapper.xml
            │       ├── ListSongMapper.xml
            │       ├── RankListMapper.xml
            │       ├── SingerMapper.xml
            │       ├── SongListMapper.xml
            │       ├── SongMapper.xml
            │       └── UserSupportMapper.xml
            │   └── mysql-connector-java-8.0.13.jar
        └── test
            └── java
                └── com
                    └── example
                        └── yin
                            └── YinMusicApplicationTests.java


/.github/workflows/build.yml:
--------------------------------------------------------------------------------
 1 | name: Build CI
 2 | 
 3 | on:
 4 |   workflow_dispatch:
 5 | 
 6 | jobs:
 7 |   build:
 8 |     runs-on: ubuntu-latest
 9 |     steps:
10 |       - name: Checkout
11 |         uses: actions/checkout@main
12 |         with:
13 |           fetch-depth: 0
14 |       
15 |       - name: Set up QEMU
16 |         uses: docker/setup-qemu-action@master
17 |   
18 |       - name: Set up Docker Buildx
19 |         uses: docker/setup-buildx-action@master
20 | 
21 |       - name: Login to DockerHub
22 |         uses: docker/login-action@master
23 |         with:
24 |           username: ${{secrets.DOCKER_USERNAME}}
25 |           password: ${{secrets.DOCKER_PASSWORD}}
26 | 
27 |       - name: Build and push
28 |         uses: docker/build-push-action@master
29 |         with:
30 |           platforms: linux/amd64,linux/arm64
31 |           push: true
32 |           context: music-server
33 |           tags: ${{secrets.DOCKER_USERNAME}}/music-server:latest
34 |           file: music-server/Dockerfile


--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .idea


--------------------------------------------------------------------------------
/img/image-20240108131746139.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yin-Hongwei/music-website/2cccb623c437abc0b90c91948d2c559a387fd335/img/image-20240108131746139.png


--------------------------------------------------------------------------------
/img/image-20240108131824788.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yin-Hongwei/music-website/2cccb623c437abc0b90c91948d2c559a387fd335/img/image-20240108131824788.png


--------------------------------------------------------------------------------
/img/image-20240108131927175.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yin-Hongwei/music-website/2cccb623c437abc0b90c91948d2c559a387fd335/img/image-20240108131927175.png


--------------------------------------------------------------------------------
/music-client/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 | not dead
4 | not ie 11
5 | 


--------------------------------------------------------------------------------
/music-client/.eslintrc.js:
--------------------------------------------------------------------------------
 1 | module.exports = {
 2 |   root: true,
 3 |   env: {
 4 |     node: true
 5 |   },
 6 |   'extends': [
 7 |     'plugin:vue/vue3-essential',
 8 |     'eslint:recommended',
 9 |     '@vue/typescript/recommended'
10 |   ],
11 |   parserOptions: {
12 |     ecmaVersion: 2020
13 |   },
14 |   rules: {
15 |     'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
16 |     'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
17 |     'vue/multi-word-component-names': 0,
18 |     "@typescript-eslint/no-unused-vars": ["off"],
19 |     "@typescript-eslint/no-explicit-any": ["off"],
20 |     'no-undef': 0
21 |   }
22 | }
23 | 


--------------------------------------------------------------------------------
/music-client/.gitignore:
--------------------------------------------------------------------------------
 1 | .DS_Store
 2 | node_modules
 3 | /dist
 4 | 
 5 | 
 6 | # local env files
 7 | .env.local
 8 | .env.*.local
 9 | 
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 | 
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 | 


--------------------------------------------------------------------------------
/music-client/README.md:
--------------------------------------------------------------------------------
 1 | # music
 2 | 
 3 | ## Project setup
 4 | ```
 5 | npm install
 6 | ```
 7 | 
 8 | ### Compiles and hot-reloads for development
 9 | ```
10 | npm run serve
11 | ```
12 | 
13 | ### Compiles and minifies for production
14 | ```
15 | npm run build
16 | ```
17 | 
18 | ### Lints and fixes files
19 | ```
20 | npm run lint
21 | ```
22 | 
23 | ### Customize configuration
24 | See [Configuration Reference](https://cli.vuejs.org/config/).
25 | 


--------------------------------------------------------------------------------
/music-client/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 |   presets: [
3 |     '@vue/cli-plugin-babel/preset'
4 |   ]
5 | }
6 | 


--------------------------------------------------------------------------------
/music-client/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "music-client",
 3 |   "version": "3.0.0",
 4 |   "private": true,
 5 |   "scripts": {
 6 |     "serve": "vue-cli-service serve",
 7 |     "build": "vue-cli-service build",
 8 |     "lint": "vue-cli-service lint"
 9 |   },
10 |   "dependencies": {
11 |     "axios": "^0.26.0",
12 |     "core-js": "^3.8.3",
13 |     "element-plus": "^2.0.4",
14 |     "vue": "^3.2.13",
15 |     "vue-router": "^4.0.3",
16 |     "vuex": "^4.0.0"
17 |   },
18 |   "devDependencies": {
19 |     "@element-plus/icons-vue": "^1.0.0",
20 |     "@typescript-eslint/eslint-plugin": "^5.4.0",
21 |     "@typescript-eslint/parser": "^5.4.0",
22 |     "@vue/cli-plugin-babel": "~5.0.0",
23 |     "@vue/cli-plugin-eslint": "~5.0.0",
24 |     "@vue/cli-plugin-router": "~5.0.0",
25 |     "@vue/cli-plugin-typescript": "~5.0.0",
26 |     "@vue/cli-plugin-vuex": "~5.0.0",
27 |     "@vue/cli-service": "~5.0.0",
28 |     "@vue/eslint-config-typescript": "^9.1.0",
29 |     "eslint": "^7.32.0",
30 |     "eslint-plugin-vue": "^8.0.3",
31 |     "sass": "^1.32.7",
32 |     "sass-loader": "^12.0.0",
33 |     "typescript": "~4.5.5"
34 |   }
35 | }
36 | 


--------------------------------------------------------------------------------
/music-client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yin-Hongwei/music-website/2cccb623c437abc0b90c91948d2c559a387fd335/music-client/public/favicon.ico


--------------------------------------------------------------------------------
/music-client/public/index.html:
--------------------------------------------------------------------------------
 1 | <!DOCTYPE html>
 2 | <html lang="">
 3 |   <head>
 4 |     <meta charset="utf-8">
 5 |     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6 |     <meta name="viewport" content="width=device-width,initial-scale=1.0">
 7 |     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
 8 |     <title><%= htmlWebpackPlugin.options.title %></title>
 9 |   </head>
10 |   <body>
11 |     <noscript>
12 |       <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
13 |     </noscript>
14 |     <div id="app"></div>
15 |     <!-- built files will be auto injected -->
16 |   </body>
17 | </html>
18 | 


--------------------------------------------------------------------------------
/music-client/src/App.vue:
--------------------------------------------------------------------------------
1 | <template>
2 |   <router-view />
3 | </template>
4 | 


--------------------------------------------------------------------------------
/music-client/src/api/request.ts:
--------------------------------------------------------------------------------
  1 | import axios from "axios";
  2 | import router from "@/router";
  3 | 
  4 | const BASE_URL = process.env.NODE_HOST;
  5 | 
  6 | axios.defaults.timeout = 5000; // 超时时间设置
  7 | axios.defaults.withCredentials = true; // true允许跨域
  8 | axios.defaults.baseURL = BASE_URL;
  9 | // Content-Type 响应头
 10 | axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=UTF-8";
 11 | 
 12 | // 响应拦截器
 13 | axios.interceptors.response.use(
 14 |   (response) => {
 15 |     // 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
 16 |     // 否则的话抛出错误
 17 |     if (response.status === 200) {
 18 |       return Promise.resolve(response);
 19 |     } else {
 20 |       return Promise.reject(response);
 21 |     }
 22 |   },
 23 |   // 服务器状态码不是2开头的的情况
 24 |   (error) => {
 25 |     if (error.response.status) {
 26 |       switch (error.response.status) {
 27 |         // 401: 未登录
 28 |         case 401:
 29 |           router.replace({
 30 |             path: "/",
 31 |             query: {
 32 |               // redirect: router.currentRoute.fullPath
 33 |             },
 34 |           });
 35 |           break;
 36 |         case 403:
 37 |           // console.log('管理员权限已修改请重新登录')
 38 |           // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
 39 |           setTimeout(() => {
 40 |             router.replace({
 41 |               path: "/",
 42 |               query: {
 43 |                 // redirect: router.currentRoute.fullPath
 44 |               },
 45 |             });
 46 |           }, 1000);
 47 |           break;
 48 | 
 49 |         // 404请求不存在
 50 |         case 404:
 51 |           // console.log('请求页面飞到火星去了')
 52 |           break;
 53 |       }
 54 |       return Promise.reject(error.response);
 55 |     }
 56 |   }
 57 | );
 58 | 
 59 | export function getBaseURL() {
 60 |   return BASE_URL;
 61 | }
 62 | 
 63 | /**
 64 |  * 封装get方法
 65 |  * @param url
 66 |  * @param data
 67 |  * @returns {Promise}
 68 |  */
 69 | export function get(url, params?: object) {
 70 |   return new Promise((resolve, reject) => {
 71 |     axios.get(url, params).then(
 72 |       (response) => resolve(response.data),
 73 |       (error) => reject(error)
 74 |     );
 75 |   });
 76 | }
 77 | 
 78 | /**
 79 |  * 封装post请求
 80 |  * @param url
 81 |  * @param data
 82 |  * @returns {Promise}
 83 |  */
 84 | export function post(url, data = {}) {
 85 |   return new Promise((resolve, reject) => {
 86 |     axios.post(url, data).then(
 87 |       (response) => resolve(response.data),
 88 |       (error) => reject(error)
 89 |     );
 90 |   });
 91 | }
 92 | 
 93 | /**
 94 |  * 封装delete请求
 95 |  * @param url
 96 |  * @param data
 97 |  * @returns {Promise}
 98 |  */
 99 | export function deletes(url, data = {}) {
100 |   return new Promise((resolve, reject) => {
101 |     axios.delete(url, data).then(
102 |       (response) => resolve(response.data),
103 |       (error) => reject(error)
104 |     );
105 |   });
106 | }
107 | 
108 | /**
109 |  * 封装put请求
110 |  * @param url
111 |  * @param data
112 |  * @returns {Promise}
113 |  */
114 | export function put(url, data = {}) {
115 |   return new Promise((resolve, reject) => {
116 |     axios.put(url, data).then(
117 |       (response) => resolve(response.data),
118 |       (error) => reject(error)
119 |     );
120 |   });
121 | }
122 | 


--------------------------------------------------------------------------------
/music-client/src/assets/css/global.scss:
--------------------------------------------------------------------------------
 1 | @import "var.scss";
 2 | 
 3 | // 上下左右居中
 4 | @mixin layout($justify-content: flex-start, $align-items: stretch, $flex-direction: row, $flex-wrap: nowrap) {
 5 |   display: flex;
 6 |   justify-content: $justify-content;
 7 |   align-items: $align-items;
 8 |   flex-direction: $flex-direction;
 9 |   flex-wrap: $flex-wrap;
10 | }
11 | 
12 | // 图标
13 | @mixin icon($size: 1.5em, $color: $color-black) {
14 |   width: $size;
15 |   height: $size;
16 |   font-size: $size;
17 |   color: $color;
18 |   fill: currentColor;
19 |   overflow: hidden;
20 |   position: relative;
21 | }
22 | 


--------------------------------------------------------------------------------
/music-client/src/assets/css/index.scss:
--------------------------------------------------------------------------------
 1 | @import "./var.scss";
 2 | @import "./global.scss";
 3 | 
 4 | html,
 5 | body,
 6 | div,
 7 | span,
 8 | h1,
 9 | h2,
10 | h3,
11 | h4,
12 | h5,
13 | h6,
14 | p,
15 | blockquote,
16 | pre,
17 | dl,
18 | dt,
19 | dd,
20 | ol,
21 | ul,
22 | li,
23 | hr,
24 | img,
25 | a,
26 | form,
27 | label,
28 | tr,
29 | th,
30 | td,
31 | article,
32 | aside,
33 | canvas,
34 | details,
35 | embed,
36 | figure,
37 | figcaption,
38 | footer,
39 | header {
40 |   padding: 0;
41 |   margin: 0;
42 | }
43 | 
44 | html, body, #app {
45 |   height: 100%;
46 | }
47 | 
48 | ul,
49 | li {
50 |   list-style: none;
51 |   display: inline-block;
52 | }
53 | 
54 | .pagination {
55 |   @include layout(center);
56 |   transform: translateY(15px);
57 | }
58 | 
59 | @media screen and (min-width: $sm) {
60 |   .play-list-container {
61 |     margin: 0 8% 30px 8%;
62 |   }
63 | }
64 | 
65 | /*el*/
66 | .el-select-dropdown__item {
67 |   display: block !important;
68 | }
69 | 


--------------------------------------------------------------------------------
/music-client/src/assets/css/sign.scss:
--------------------------------------------------------------------------------
 1 | @import "@/assets/css/var.scss";
 2 | @import "@/assets/css/global.scss";
 3 | 
 4 | @media screen and (min-width: $sm) {
 5 |   .sign {
 6 |     width: 300px;
 7 |     position: absolute;
 8 |     left: 60vw;
 9 |     top: $header-height + 60px;
10 |   }
11 | }
12 | 
13 | @media screen and (max-width: $sm) {
14 |   .sign {
15 |     width: 60vw;
16 |     position: relative;
17 |     margin: auto;
18 |     margin-top: -78vh;
19 |   }
20 | }
21 | 
22 | .sign {
23 |   padding: 30px 50px;
24 |   border-radius: 10px;
25 |   background-color: $color-white;
26 | 
27 |   .sign-head {
28 |     text-align: center;
29 |     margin-bottom: 10px;
30 |     font-size: 20px;
31 |     font-weight: 600;
32 |   }
33 | 
34 |   .sign-btn:deep(.el-form-item__content) {
35 |     @include layout(space-between);
36 |     button {
37 |       width: 50%;
38 |     }
39 |   }
40 | }
41 | 


--------------------------------------------------------------------------------
/music-client/src/assets/css/var.scss:
--------------------------------------------------------------------------------
 1 | //Colors
 2 | $color-white: #ffffff;
 3 | $color-light-white: #fefefe;
 4 | $color-grey: #67757f;
 5 | $color-light-grey: #EFEFEF;
 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 | $color-red: rgb(245, 108, 108);
13 | 
14 | // Theme Global Color
15 | $theme-color: $color-blue;
16 | $theme-background-color: #e6ecf0;
17 | $theme-header-color: $color-light-white;
18 | $theme-footer-color: $theme-background-color;
19 | $theme-play-bar-color: $color-light-white;
20 | 
21 | // Fonts
22 | $font-family: Lato, Helvetica Neue For Number, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, PingFang SC, Hiragino Sans GB, Microsoft YaHei,
23 |   Helvetica Neue, Helvetica, Arial, sans-serif;
24 | // $font-family: Avenir, Helvetica, Arial, sans-serif;
25 | $font-size-default: 1rem;
26 | $font-size-logo: 1.5rem;
27 | $font-size-header: 1rem;
28 | 
29 | // header
30 | $header-height: 60px;
31 | $header-padding: 0 4%;
32 | $header-margin: 0;
33 | $header-logo-width: 10%;
34 | $header-logo-margin: 0 10px;
35 | $header-nav-padding: 0 0.5rem;
36 | $header-nav-margin: 0 0.5rem;
37 | $header-search-radius: 10px;
38 | $header-search-height: $header-height - 20px;
39 | $header-search-max-width: 25vw;
40 | $header-search-min-width: 200px;
41 | $header-search-btn-height: ($header-height / 2);
42 | $header-search-btn-width: 60px;
43 | $header-user-width: ($header-height / 1.7);
44 | $header-user-margin: 1rem;
45 | $header-user-radius: 50%;
46 | $header-menu-width: 150px;
47 | $header-menu-padding: 7px 0px;
48 | $header-menu-radius: 4px;
49 | 
50 | // page
51 | $content-padding: 0 8% 20px 8%;
52 | $border-radius-songlist: 12px;
53 | 
54 | // footer
55 | $footer-height: 100px;
56 | 
57 | // current-play
58 | $current-play: 350px;
59 | 
60 | // play-bar
61 | $play-bar-height: 60px;
62 | 
63 | // style
64 | $box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
65 | 
66 | // Media queries
67 | $sm: 668px;
68 | $bg: 1024px;
69 | $md: 1300px;
70 | $lg: 1450px;
71 | 


--------------------------------------------------------------------------------
/music-client/src/assets/css/yin-current-play.scss:
--------------------------------------------------------------------------------
 1 | @import "var.scss";
 2 | @import "global.scss";
 3 | 
 4 | .aside-fade-enter-active {
 5 |   transition: all 0.3s ease;
 6 | }
 7 | 
 8 | .aside-fade-leave-active {
 9 |   transition: all 0.2s ease;
10 | }
11 | 
12 | .aside-fade-enter,
13 | .aside-fade-leave-to {
14 |   transform: translateX(10px);
15 |   opacity: 0;
16 | }
17 | 
18 | .yin-current-play {
19 |   font-size: 14px;
20 |   width: $current-play;
21 |   position: fixed;
22 |   right: 0;
23 |   top: $header-height;
24 |   bottom: 0;
25 |   padding-bottom: $footer-height;
26 |   z-index: 99;
27 |   background-color: $color-white;
28 |   box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.4);
29 |   overflow: hidden;
30 | }
31 | 
32 | .title,
33 | .control,
34 | .menus li {
35 |   padding-left: 20px;
36 |   box-sizing: border-box;
37 | }
38 | 
39 | .title {
40 |   margin: 10px 0;
41 | }
42 | 
43 | .control {
44 |   margin: 3px 0;
45 |   color: $color-grey;
46 | }
47 | 
48 | .menus {
49 |   width: 100%;
50 |   height: calc(100% - 19px);
51 |   cursor: pointer;
52 |   z-index: 100;
53 |   overflow: scroll;
54 |   white-space: nowrap;
55 |   li {
56 |     display: block;
57 |     width: 100%;
58 |     height: 40px;
59 |     line-height: 40px;
60 |     &:hover {
61 |       background-color: $color-light-grey;
62 |     }
63 |   }
64 | }
65 | 
66 | .is-play {
67 |   color: $color-black;
68 |   font-weight: bold;
69 | }
70 | 


--------------------------------------------------------------------------------
/music-client/src/assets/css/yin-play-bar.scss:
--------------------------------------------------------------------------------
  1 | @import "var.scss";
  2 | @import "global.scss";
  3 | 
  4 | .play-bar {
  5 |   position: fixed;
  6 |   z-index: 100;
  7 |   bottom: 0;
  8 |   width: 100%;
  9 |   transition: all 0.5s;
 10 | 
 11 |   .fold {
 12 |     position: absolute;
 13 |     bottom: $play-bar-height + 10px;
 14 |     left: 20px;
 15 |     cursor: pointer;
 16 |   }
 17 | 
 18 |   .progress {
 19 |     position: absolute;
 20 |     margin-top: -10px;
 21 |   }
 22 | 
 23 |   .control-box {
 24 |     display: flex;
 25 |     align-items: center;
 26 |     justify-content: space-between;
 27 |     height: $play-bar-height;
 28 |     width: 100%;
 29 |     background-color: $theme-play-bar-color;
 30 | 
 31 |     .song-ctr {
 32 |       position: relative;
 33 |       margin: auto;
 34 |       flex-wrap: nowrap;
 35 | 
 36 |       svg {
 37 |         width: 5rem;
 38 |         cursor: pointer;
 39 |       }
 40 |     }
 41 | 
 42 |     .info-box {
 43 |       .song-bar-img {
 44 |         width: calc($play-bar-height - 15px);
 45 |         height: calc($play-bar-height - 15px);
 46 |         border-radius: 4px;
 47 |         margin-right: 10px;
 48 |         cursor: pointer;
 49 |       }
 50 |       .song-info {
 51 |         font-size: 14px;
 52 |       }
 53 |       .time-info {
 54 |         font-size: 12px;
 55 |         color: $color-grey;
 56 |       }
 57 |     }
 58 | 
 59 |     .song-edit {
 60 |       width: 30%;
 61 |       justify-content: flex-end;
 62 |     }
 63 |   }
 64 | }
 65 | 
 66 | .turn {
 67 |   transform: rotate(180deg);
 68 | }
 69 | 
 70 | .show {
 71 |   bottom: -($play-bar-height) + 5px;
 72 | }
 73 | 
 74 | .icon {
 75 |   @include icon(1.1em, $color-black);
 76 | }
 77 | 
 78 | .active.icon {
 79 |   color: $color-red;
 80 | }
 81 | 
 82 | @media screen and (min-width: $sm) {
 83 |   .info-box {
 84 |     width: 30%;
 85 |     min-width: 200px;
 86 |     margin-left: 30px;
 87 |   }
 88 |   .song-ctr,
 89 |   .info-box,
 90 |   .song-edit {
 91 |     display: flex;
 92 |     align-items: center;
 93 |   }
 94 | }
 95 | 
 96 | @media screen and (max-width: $sm) {
 97 |   .info-box {
 98 |     display: flex;
 99 |     flex-direction: row;
100 |     width: 70%;
101 |     margin-left: 10px;
102 |   }
103 | 
104 |   .yin-play-show {
105 |     display: none;
106 |   }
107 | }
108 | 


--------------------------------------------------------------------------------
/music-client/src/assets/icons/iconfont1.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | !function(d){var t,n='<svg><symbol id="icon-liebiao" viewBox="0 0 1024 1024"><path d="M892.928 128q28.672 0 48.64 19.968t19.968 48.64l0 52.224q0 28.672-19.968 48.64t-48.64 19.968l-759.808 0q-28.672 0-48.64-19.968t-19.968-48.64l0-52.224q0-28.672 19.968-48.64t48.64-19.968l759.808 0zM892.928 448.512q28.672 0 48.64 19.968t19.968 48.64l0 52.224q0 28.672-19.968 48.64t-48.64 19.968l-759.808 0q-28.672 0-48.64-19.968t-19.968-48.64l0-52.224q0-28.672 19.968-48.64t48.64-19.968l759.808 0zM892.928 769.024q28.672 0 48.64 19.968t19.968 48.64l0 52.224q0 28.672-19.968 48.64t-48.64 19.968l-759.808 0q-28.672 0-48.64-19.968t-19.968-48.64l0-52.224q0-28.672 19.968-48.64t48.64-19.968l759.808 0z"  ></path></symbol><symbol id="icon-xiazai" viewBox="0 0 1024 1024"><path d="M819.203 405.649c0-169.66-137.541-307.19-307.201-307.19s-307.195 137.53-307.195 307.19c-113.105 0-204.8 91.69-204.8 204.801s91.695 204.801 204.8 204.801h102.4V733.33h-102.4c-67.755 0-122.88-55.12-122.88-122.88 0-67.761 55.125-122.881 122.88-122.881h81.92v-81.92c0-124.22 101.055-225.28 225.275-225.28 124.221 0 225.281 101.06 225.281 225.28v81.92h81.92c67.76 0 122.871 55.12 122.871 122.881 0 67.76-55.111 122.88-122.871 122.88h-102.4v81.921h102.4c113.09 0 204.791-91.69 204.791-204.801s-91.701-204.801-204.791-204.801z" fill="#040000" ></path><path d="M511.393 925.541l221.281-238.02-64.441-60-110.79 119.22V410.22h-92.16v336.47L354.488 627.521l-64.431 60z" fill="#040000" ></path></symbol></svg>',e=(t=document.getElementsByTagName("script"))[t.length-1].getAttribute("data-injectcss");if(e&&!d.__iconfont__svg__cssinject__){d.__iconfont__svg__cssinject__=!0;try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}catch(t){console&&console.log(t)}}!function(t){if(document.addEventListener)if(~["complete","loaded","interactive"].indexOf(document.readyState))setTimeout(t,0);else{var e=function(){document.removeEventListener("DOMContentLoaded",e,!1),t()};document.addEventListener("DOMContentLoaded",e,!1)}else document.attachEvent&&(n=t,i=d.document,o=!1,l=function(){o||(o=!0,n())},(c=function(){try{i.documentElement.doScroll("left")}catch(t){return void setTimeout(c,50)}l()})(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,l())});var n,i,o,l,c}(function(){var t,e;(t=document.createElement("div")).innerHTML=n,n=null,(e=t.getElementsByTagName("svg")[0])&&(e.setAttribute("aria-hidden","true"),e.style.position="absolute",e.style.width=0,e.style.height=0,e.style.overflow="hidden",function(t,e){e.firstChild?function(t,e){e.parentNode.insertBefore(t,e)}(t,e.firstChild):e.appendChild(t)}(e,document.body))})}(window);
3 | 


--------------------------------------------------------------------------------
/music-client/src/assets/icons/index.js:
--------------------------------------------------------------------------------
1 | import './iconfont.js'
2 | import './iconfont1.js'
3 | import './iconfont2.js'
4 | import './iconfont3.js'
5 | import './iconfont4.js'
6 | 


--------------------------------------------------------------------------------
/music-client/src/assets/images/tubiao.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yin-Hongwei/music-website/2cccb623c437abc0b90c91948d2c559a387fd335/music-client/src/assets/images/tubiao.jpg


--------------------------------------------------------------------------------
/music-client/src/assets/images/user.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yin-Hongwei/music-website/2cccb623c437abc0b90c91948d2c559a387fd335/music-client/src/assets/images/user.jpg


--------------------------------------------------------------------------------
/music-client/src/components/layouts/YinAudio.vue:
--------------------------------------------------------------------------------
  1 | <template>
  2 |   <audio :src="attachImageUrl(songUrl)" controls="controls" :ref="player" preload="true" @canplay="canplay" @timeupdate="timeupdate" @ended="ended">
  3 |     <!--(1)属性:controls,preload(2)事件:canplay,timeupdate,ended(3)方法:play(),pause() -->
  4 |     <!--controls:向用户显示音频控件(播放/暂停/进度条/音量)-->
  5 |     <!--preload:属性规定是否在页面加载后载入音频-->
  6 |     <!--canplay:当音频/视频处于加载过程中时,会发生的事件-->
  7 |     <!--timeupdate:当目前的播放位置已更改时-->
  8 |     <!--ended:当目前的播放列表已结束时-->
  9 |   </audio>
 10 | </template>
 11 | 
 12 | <script lang="ts">
 13 | import { defineComponent, ref, getCurrentInstance, computed, watch } from "vue";
 14 | import { useStore } from "vuex";
 15 | import { HttpManager } from "@/api";
 16 | import { onMounted } from 'vue';
 17 | 
 18 | export default defineComponent({
 19 |   setup() {
 20 | 
 21 |     const { proxy } = getCurrentInstance();
 22 |     const store = useStore();
 23 |     const divRef = ref<HTMLAudioElement>();
 24 |     const player = (el) => {
 25 |       divRef.value = el;
 26 |     };
 27 | 
 28 |      const muted = ref(true); // 添加一个 reactive 的 muted 属性
 29 | 
 30 |     const audioDom = document.querySelector('audio');
 31 |     if (audioDom) {
 32 |       // 设置为静音并尝试自动播放
 33 |       audioDom.muted = true;
 34 |       audioDom.play()
 35 |         .then(() => {
 36 |           // 自动播放成功
 37 |         })
 38 |         .catch(error => {
 39 |           // 自动播放失败,可能是因为没有用户交互
 40 |           console.error('自动播放失败,需要用户交互。', error);
 41 |         });
 42 |     }
 43 | 
 44 | 
 45 |     const songUrl = computed(() => store.getters.songUrl); // 音乐链接
 46 |     const isPlay = computed(() => store.getters.isPlay); // 播放状态
 47 |     const volume = computed(() => store.getters.volume); // 音量
 48 |     const changeTime = computed(() => store.getters.changeTime); // 指定播放时刻
 49 |     const autoNext = computed(() => store.getters.autoNext); // 用于触发自动播放下一首
 50 |     // 监听播放还是暂停
 51 |     watch(isPlay, () => togglePlay());
 52 |     // 跳到指定时刻播放
 53 |     watch(changeTime, () => (divRef.value.currentTime = changeTime.value));
 54 |     watch(volume, (value) => (divRef.value.volume = value));
 55 | 
 56 |     // 开始 / 暂停
 57 |     function togglePlay() {
 58 |       isPlay.value ? divRef.value.play() : divRef.value.pause();
 59 |     }
 60 |     // 获取歌曲链接后准备播放
 61 |     function canplay() {
 62 |       //  记录音乐时长
 63 |       proxy.$store.commit("setDuration", divRef.value.duration);
 64 |       //  开始播放
 65 |       if (muted.value) {
 66 |         divRef.value.muted = false;
 67 |         muted.value = false;
 68 |       }
 69 |       // divRef.value.play();
 70 |       proxy.$store.commit("setIsPlay", true);
 71 |     }
 72 |     // 音乐播放时记录音乐的播放位置
 73 |     function timeupdate() {
 74 |       proxy.$store.commit("setCurTime", divRef.value.currentTime);
 75 |     }
 76 |     // 音乐播放结束时触发
 77 |     function ended() {
 78 |       proxy.$store.commit("setIsPlay", false);
 79 |       proxy.$store.commit("setCurTime", 0);
 80 |       proxy.$store.commit("setAutoNext", !autoNext.value);
 81 |     }
 82 | 
 83 | 
 84 | 
 85 |     return {
 86 |       songUrl,
 87 |       player,
 88 |       canplay,
 89 |       timeupdate,
 90 |       ended,
 91 |       muted,
 92 |       attachImageUrl: HttpManager.attachImageUrl,
 93 |     };
 94 |   },
 95 | });
 96 | </script>
 97 | 
 98 | <style scoped>
 99 | audio {
100 |   display: none;
101 | }
102 | </style>
103 | 


--------------------------------------------------------------------------------
/music-client/src/components/layouts/YinCurrentPlay.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <transition name="aside-fade">
 3 |     <div class="yin-current-play" v-if="showAside">
 4 |       <h2 class="title">当前播放</h2>
 5 |       <div class="control">共 {{ (currentPlayList && currentPlayList.length) || 0 }} 首</div>
 6 |       <ul class="menus">
 7 |         <li
 8 |           v-for="(item, index) in currentPlayList"
 9 |           :class="{ 'is-play': songId === item.id }"
10 |           :key="index"
11 |           @click="playMusic({
12 |             id: item.id,
13 |             url: item.url,
14 |             pic: item.pic,
15 |             index: index,
16 |             name: item.name,
17 |             lyric: item.lyric,
18 |             currentSongList: currentPlayList,
19 |           })">
20 |           {{ getSongTitle(item.name) }}
21 |         </li>
22 |       </ul>
23 |     </div>
24 |   </transition>
25 | </template>
26 | 
27 | <script lang="ts">
28 | import { defineComponent, getCurrentInstance, computed, onMounted } from "vue";
29 | import { useStore } from "vuex";
30 | import mixin from "@/mixins/mixin";
31 | 
32 | export default defineComponent({
33 |   setup() {
34 |     const { proxy } = getCurrentInstance();
35 |     const store = useStore();
36 |     const { getSongTitle, playMusic } = mixin();
37 | 
38 |     const songId = computed(() => store.getters.songId); // 音乐 ID
39 |     const currentPlayList = computed(() => store.getters.currentPlayList); // 当前播放
40 |     const showAside = computed(() => store.getters.showAside); // 是否显示侧边栏
41 | 
42 |     onMounted(() => {
43 |       document.addEventListener('click', () => {
44 |         proxy.$store.commit('setShowAside', false)
45 |       }, true)
46 |     })
47 | 
48 |     return {
49 |       songId,
50 |       currentPlayList,
51 |       showAside,
52 |       getSongTitle,
53 |       playMusic,
54 |     };
55 |   },
56 | });
57 | </script>
58 | 
59 | <style lang="scss" scoped>
60 | @import "@/assets/css/yin-current-play.scss";
61 | </style>
62 | 


--------------------------------------------------------------------------------
/music-client/src/components/layouts/YinFooter.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <div class="yin-footer">
 3 |     <p v-for="(item, index) in footerList" :key="index">
 4 |       {{ item }}
 5 |     </p>
 6 |   </div>
 7 | </template>
 8 | 
 9 | <script lang="ts">
10 | import { defineComponent, readonly } from "vue";
11 | 
12 | export default defineComponent({
13 |   setup() {
14 |     const footerList = readonly([
15 |       "关于 | 帮助 | 条款 | 反馈",
16 |       "Copyright © 2019 Yin-Hongwei",
17 |     ]);
18 | 
19 |     return { footerList };
20 |   },
21 | });
22 | </script>
23 | 
24 | <style lang="scss" scoped>
25 | @import "@/assets/css/var.scss";
26 | @import "@/assets/css/global.scss";
27 | 
28 | .yin-footer {
29 |   width: 100%;
30 |   height: $footer-height;
31 |   padding: 20px 0;
32 |   box-sizing: border-box;
33 |   font-size: 14px;
34 |   @include layout(center, center, column);
35 | }
36 | 
37 | p {
38 |   height: 30px;
39 | }
40 | </style>
41 | 


--------------------------------------------------------------------------------
/music-client/src/components/layouts/YinHeaderNav.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <ul class="yin-header-nav">
 3 |     <li :class="{ active: item.name === activeName }" v-for="item in styleList" :key="item.path" @click="handleChangeView(item)">
 4 |       {{ item.name }}
 5 |     </li>
 6 |   </ul>
 7 | </template>
 8 | 
 9 | <script lang="ts">
10 | import { defineComponent, getCurrentInstance } from "vue";
11 | 
12 | export default defineComponent({
13 |   props: {
14 |     styleList: Array,
15 |     activeName: String,
16 |   },
17 |   emits: ["click"],
18 |   setup() {
19 |     const { proxy } = getCurrentInstance();
20 | 
21 |     function handleChangeView(item) {
22 |       proxy.$emit("click", item.path, item.name);
23 |     }
24 |     return {
25 |       handleChangeView,
26 |     };
27 |   },
28 | });
29 | </script>
30 | 
31 | <style lang="scss" scoped>
32 | @import "@/assets/css/var.scss";
33 | 
34 | li {
35 |   margin: $header-nav-margin;
36 |   padding: $header-nav-padding;
37 |   line-height: 3.3rem;
38 |   color: $color-grey;
39 |   border-bottom: none;
40 |   cursor: pointer;
41 | }
42 | 
43 | li.active {
44 |   color: $color-black;
45 |   font-weight: 600;
46 |   border-bottom: 5px solid $color-black;
47 | }
48 | </style>
49 | 


--------------------------------------------------------------------------------
/music-client/src/components/layouts/YinIcon.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <svg class="icon" aria-hidden="true">
 3 |     <use :xlink:href="icon"></use>
 4 |   </svg>
 5 | </template>
 6 | 
 7 | <script lang="ts">
 8 | import { defineComponent } from "vue";
 9 | 
10 | export default defineComponent({
11 |   props: {
12 |     icon: String,
13 |   },
14 | });
15 | </script>
16 | 


--------------------------------------------------------------------------------
/music-client/src/components/layouts/YinLoginLogo.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <div class="login-logo">
 3 |     <yin-icon :icon="icon"></yin-icon>
 4 |   </div>
 5 | </template>
 6 | 
 7 | <script lang="ts">
 8 | import { defineComponent } from "vue";
 9 | import YinIcon from "./YinIcon.vue";
10 | import { Icon } from "@/enums";
11 | 
12 | export default defineComponent({
13 |   components: {
14 |     YinIcon,
15 |   },
16 |   data() {
17 |     return {
18 |       icon: Icon.ERJI,
19 |     };
20 |   },
21 | });
22 | </script>
23 | 
24 | <style lang="scss" scoped>
25 | @import "@/assets/css/var.scss";
26 | @import "@/assets/css/global.scss";
27 | 
28 | .login-logo {
29 |   background-color: $color-blue-light;
30 |   height: calc(100vh - $header-height - $footer-height);
31 |   min-width: 50vw;
32 |   overflow: hidden;
33 |   @include layout(center, center);
34 |   .icon {
35 |     @include icon(36rem, $color-blue-dark);
36 |     transform: rotate(-30deg);
37 |   }
38 | }
39 | 
40 | @media screen and (min-width: $sm) {
41 |   .login-logo {
42 |     width: 50vw;
43 |   }
44 | }
45 | 
46 | @media screen and (max-width: $sm) {
47 |   .login-logo {
48 |     width: 100vw;
49 |   }
50 | }
51 | </style>
52 | 


--------------------------------------------------------------------------------
/music-client/src/components/layouts/YinNav.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <ul class="yin-nav">
 3 |     <li v-for="(item, index) in styleList" :key="index" :class="{ active: item.name == activeName }" @click="handleChangeView(item)">
 4 |       {{ item.name }}
 5 |     </li>
 6 |   </ul>
 7 | </template>
 8 | 
 9 | <script lang="ts">
10 | import { defineComponent, getCurrentInstance } from "vue";
11 | 
12 | export default defineComponent({
13 |   props: {
14 |     styleList: Array,
15 |     activeName: String,
16 |   },
17 |   emits: ["click"],
18 |   setup() {
19 |     const { proxy } = getCurrentInstance();
20 | 
21 |     function handleChangeView(val) {
22 |       proxy.$emit("click", val);
23 |     }
24 |     return {
25 |       handleChangeView,
26 |     };
27 |   },
28 | });
29 | </script>
30 | 
31 | <style lang="scss" scoped>
32 | @import "@/assets/css/var.scss";
33 | 
34 | .yin-nav {
35 |   width: 100%;
36 |   li {
37 |     line-height: 2rem;
38 |     font-size: 1rem;
39 |     color: $color-grey;
40 |     border-bottom: none;
41 |     cursor: pointer;
42 |   }
43 |   li.active {
44 |     color: $color-black;
45 |     font-weight: 600;
46 |   }
47 | }
48 | 
49 | @media screen and (min-width: $sm) {
50 |   .yin-nav {
51 |     li {
52 |       margin: 0.5rem 1rem;
53 |     }
54 |   }
55 | }
56 | 
57 | @media screen and (max-width: $sm) {
58 |   .yin-nav {
59 |     li {
60 |       margin: 0.3rem 0.4rem;
61 |     }
62 |   }
63 | }
64 | </style>
65 | 


--------------------------------------------------------------------------------
/music-client/src/components/layouts/YinScrollTop.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <div class="scroll-top" @click="returnTop">
 3 |     <div class="box-in"></div>
 4 |   </div>
 5 | </template>
 6 | 
 7 | <script lang="ts">
 8 | import { defineComponent } from "vue";
 9 | 
10 | export default defineComponent({
11 |   setup() {
12 |     function returnTop() {
13 |       let timer: number = null;
14 |       cancelAnimationFrame(timer);
15 |       const startTime = new Date();
16 |       const S = document.body.scrollTop || document.documentElement.scrollTop;
17 |       const T = 500;
18 |       timer = requestAnimationFrame(function func() {
19 |         const diff: number = new Date().valueOf() - startTime.valueOf();
20 |         const t = T - Math.max(0, T - diff);
21 |         document.documentElement.scrollTop = document.body.scrollTop = S - (t * S) / T;
22 |         timer = requestAnimationFrame(func);
23 |         if (t === T) cancelAnimationFrame(timer);
24 |       });
25 |     }
26 |     return { returnTop };
27 |   },
28 | });
29 | </script>
30 | 
31 | <style lang="scss" scoped>
32 | @import "@/assets/css/var.scss";
33 | @import "@/assets/css/global.scss";
34 | 
35 | .scroll-top {
36 |   position: fixed;
37 |   z-index: 100;
38 |   width: 40px;
39 |   height: 20px;
40 |   right: 10px;
41 |   bottom: 80px;
42 |   padding-top: 20px;
43 |   text-align: center;
44 |   background-color: $color-white;
45 |   border-radius: 20%;
46 |   overflow: hidden;
47 |   box-shadow: 0 0 4px 3px rgba(0, 0, 0, 0.2);
48 |   cursor: pointer;
49 |   &:hover:before {
50 |     top: 50%;
51 |   }
52 |   &:hover .box-in {
53 |     visibility: hidden;
54 |   }
55 |   &:before {
56 |     content: "回到顶部";
57 |     position: absolute;
58 |     font-weight: bold;
59 |     font-size: small;
60 |     width: 30px;
61 |     top: -50%;
62 |     left: 50%;
63 |     transform: translate(-50%, -50%);
64 |   }
65 | }
66 | 
67 | .box-in {
68 |   visibility: visible;
69 |   display: inline-block;
70 |   height: 10px;
71 |   width: 10px;
72 |   border: 1px solid $color-black;
73 |   border-color: $color-black transparent transparent $color-black;
74 |   // 按钮中间的小三角翻转
75 |   transform: rotate(45deg) translate(-5px, -5px);
76 | }
77 | </style>
78 | 


--------------------------------------------------------------------------------
/music-client/src/enums/area.ts:
--------------------------------------------------------------------------------
  1 | // 地区选择
  2 | export const AREA = [
  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 | 


--------------------------------------------------------------------------------
/music-client/src/enums/icon.ts:
--------------------------------------------------------------------------------
 1 | export const enum Icon {
 2 |   BOFANG = "#icon-bofang", // 播放
 3 |   ZANTING = "#icon-zanting", // 暂停
 4 |   YINLIANG = "#icon-yinliang", // 音量有背景
 5 |   YINLIANG1 = "#icon-yinliang1", // 音量无背景
 6 |   ERJI = "#icon-erji", // 耳机
 7 |   SOUSUO = "#icon-sousuo", // 搜索
 8 |   XIAZAI = "#icon-xiazai", // 下载
 9 |   ZHEDIE = "#icon-jiantou-xia-cuxiantiao", // 折叠
10 |   SHANGYISHOU = "#icon-ziyuanldpi", // 上一首
11 |   XIAYISHOU = "#icon-ziyuanldpi1", // 下一首
12 |   JINGYIN = "#icon-yinliangjingyinheix", // 静音
13 |   LIEBIAO = "#icon-liebiao", // 列表
14 |   Dislike = "#icon-xihuan1", // 未收藏
15 |   Like = "#icon-xihuan", // 收藏
16 |   Support = "#icon-zan", // 赞
17 |   XUNHUAN = "#icon-xunhuan", // 循环
18 |   LUANXU = "#icon-xunhuan1", // 乱序
19 | }
20 | 


--------------------------------------------------------------------------------
/music-client/src/enums/index.ts:
--------------------------------------------------------------------------------
 1 | import { AREA } from "./area";
 2 | import { Icon } from "./icon";
 3 | import { MUSICNAME } from "./music-name";
 4 | import { NavName, HEADERNAVLIST, SIGNLIST, MENULIST } from "./nav";
 5 | import { singerStyle } from "./singer";
 6 | import { SONGSTYLE } from "./songList";
 7 | import { RouterName } from "./router-name";
 8 | import { validatePassword, SignInRules, SignUpRules } from "./validate";
 9 | 
10 | export {
11 |   AREA,
12 |   Icon,
13 |   MUSICNAME,
14 |   NavName,
15 |   HEADERNAVLIST,
16 |   RouterName,
17 |   SIGNLIST,
18 |   MENULIST,
19 |   singerStyle,
20 |   SONGSTYLE,
21 |   validatePassword,
22 |   SignInRules,
23 |   SignUpRules,
24 | };
25 | 


--------------------------------------------------------------------------------
/music-client/src/enums/music-name.ts:
--------------------------------------------------------------------------------
1 | export const MUSICNAME = "Yin-music";
2 | 


--------------------------------------------------------------------------------
/music-client/src/enums/nav.ts:
--------------------------------------------------------------------------------
 1 | import { RouterName } from "./router-name";
 2 | 
 3 | export const enum NavName {
 4 |   Home = "首页",
 5 |   SongSheet = "歌单",
 6 |   Singer = "歌手",
 7 |   Personal = "个人主页",
 8 |   Setting = "设置",
 9 |   SignIn = "登录",
10 |   SignUp = "注册",
11 |   SignOut = "退出",
12 | }
13 | 
14 | // 左侧导航栏
15 | export const HEADERNAVLIST = [
16 |   {
17 |     name: NavName.Home,
18 |     path: RouterName.Home,
19 |   },
20 |   {
21 |     name: NavName.SongSheet,
22 |     path: RouterName.SongSheet,
23 |   },
24 |   {
25 |     name: NavName.Singer,
26 |     path: RouterName.Singer,
27 |   },
28 | ];
29 | 
30 | // 右侧导航栏
31 | export const SIGNLIST = [
32 |   {
33 |     name: NavName.SignIn,
34 |     path: RouterName.SignIn,
35 |   },
36 |   {
37 |     name: NavName.SignUp,
38 |     path: RouterName.SignUp,
39 |   },
40 | ];
41 | 
42 | // 用户下拉菜单项
43 | export const MENULIST = [
44 |   {
45 |     name: NavName.Personal,
46 |     path: RouterName.Personal,
47 |   },
48 |   {
49 |     name: NavName.Setting,
50 |     path: RouterName.Setting,
51 |   },
52 |   {
53 |     name: NavName.SignOut,
54 |     path: RouterName.SignOut,
55 |   },
56 | ];
57 | 


--------------------------------------------------------------------------------
/music-client/src/enums/router-name.ts:
--------------------------------------------------------------------------------
 1 | export const enum RouterName {
 2 |   Home = "/",
 3 |   SongSheet = "/song-sheet",
 4 |   SongSheetDetail = "/song-sheet-detail",
 5 |   Singer = "/singer",
 6 |   SingerDetail = "/singer-detail",
 7 |   Personal = "/personal",
 8 |   Setting = "/setting",
 9 |   PersonalData = "/personal-data",
10 |   SignIn = "/sign-in",
11 |   SignUp = "/sign-up",
12 |   Search = "/search",
13 |   Lyric = "/lyric",
14 |   Error = "/404",
15 |   SignOut = "0",
16 |   ForgotPassword="/FPassword",
17 |   loginByemail="/loginByemail",
18 | }
19 | 


--------------------------------------------------------------------------------
/music-client/src/enums/singer.ts:
--------------------------------------------------------------------------------
 1 | export const singerStyle = [
 2 |   {
 3 |     name: "全部歌手",
 4 |     type: "-1",
 5 |   },
 6 |   {
 7 |     name: "男歌手",
 8 |     type: "1",
 9 |   },
10 |   {
11 |     name: "女歌手",
12 |     type: "0",
13 |   },
14 |   {
15 |     name: "组合歌手",
16 |     type: "2",
17 |   },
18 | ];
19 | 


--------------------------------------------------------------------------------
/music-client/src/enums/songList.ts:
--------------------------------------------------------------------------------
 1 | export const SONGSTYLE = [
 2 |   {
 3 |     name: "全部歌单",
 4 |     type: "One",
 5 |   },
 6 |   {
 7 |     name: "华语",
 8 |     type: "Two",
 9 |   },
10 |   {
11 |     name: "粤语",
12 |     type: "Three",
13 |   },
14 |   {
15 |     name: "欧美",
16 |     type: "Four",
17 |   },
18 |   {
19 |     name: "日韩",
20 |     type: "Five",
21 |   },
22 |   {
23 |     name: "轻音乐",
24 |     type: "Six",
25 |   },
26 |   {
27 |     name: "BGM",
28 |     type: "Seven",
29 |   },
30 |   {
31 |     name: "乐器",
32 |     type: "Eight",
33 |   },
34 | ];
35 | 


--------------------------------------------------------------------------------
/music-client/src/enums/validate.ts:
--------------------------------------------------------------------------------
 1 | // 登录规则
 2 | const validateName = (rule, value, callback) => {
 3 |   if (!value) {
 4 |     return callback(new Error("用户名不能为空"));
 5 |   } else {
 6 |     callback();
 7 |   }
 8 | };
 9 | 
10 | export const validatePassword = (rule, value, callback) => {
11 |   if (value === "") {
12 |     callback(new Error("密码不能为空"));
13 |   } else {
14 |     callback();
15 |   }
16 | };
17 | 
18 | export const SignInRules = {
19 |   username: [{ validator: validateName, trigger: "blur", min: 3 }],
20 |   password: [{ validator: validatePassword, trigger: "blur", min: 3 }],
21 | };
22 | 
23 | // 注册规则
24 | export const SignUpRules = {
25 |   username: [{ required: true, trigger: "blur", min: 3 }],
26 |   password: [{ required: true, trigger: "blur", min: 3 }],
27 |   sex: [{ required: true, message: "请选择性别", trigger: "change" }],
28 |   phoneNum: [{ essage: "请选择日期", trigger: "blur" }],
29 |   email: [
30 |     { message: "请输入邮箱地址", trigger: "blur" },
31 |     {
32 |       type: "email",
33 |       message: "请输入正确的邮箱地址",
34 |       trigger: ["blur", "change"],
35 |     },
36 |   ],
37 |   birth: [{ required: true, type: "date", message: "请选择日期", trigger: "change" }],
38 |   introduction: [{ message: "请输入介绍", trigger: "blur" }],
39 |   location: [{ message: "请输入地区", trigger: "change" }],
40 | };
41 | 


--------------------------------------------------------------------------------
/music-client/src/main.ts:
--------------------------------------------------------------------------------
 1 | import { createApp } from "vue";
 2 | import ElementPlus from "element-plus";
 3 | import App from "./App.vue";
 4 | import router from "./router";
 5 | import store from "./store";
 6 | import "element-plus/dist/index.css";
 7 | import "./assets/css/index.scss";
 8 | import "./assets/icons/index.js";
 9 | 
10 | import { ComponentCustomProperties } from "vue";
11 | import { Store } from "vuex";
12 | declare module "@vue/runtime-core" {
13 |   interface State {
14 |     count: number;
15 |   }
16 | 
17 |   interface ComponentCustomProperties {
18 |     $store: Store<State>;
19 |   }
20 | }
21 | 
22 | createApp(App).use(store).use(router).use(ElementPlus).mount("#app");
23 | 


--------------------------------------------------------------------------------
/music-client/src/shims-vue.d.ts:
--------------------------------------------------------------------------------
 1 | /* eslint-disable */
 2 | declare module "*.vue" {
 3 |   import type { DefineComponent } from "vue";
 4 |   const component: DefineComponent<{}, {}, any>;
 5 |   export default component;
 6 | }
 7 | 
 8 | declare module "vue/types/vue" {
 9 |   import VueRouter, { Route } from "vue-router";
10 | 
11 |   interface Vue {
12 |     $router: VueRouter;
13 |     $route: Route;
14 |   }
15 | }
16 | 
17 | interface ResponseBody {
18 |   code: string;
19 |   success: boolean;
20 |   message: string;
21 |   type: string;
22 |   data?: any;
23 | }
24 | 


--------------------------------------------------------------------------------
/music-client/src/store/configure.ts:
--------------------------------------------------------------------------------
 1 | export default {
 2 |   state: {
 3 |     token: false, // 用户是否登录
 4 |     showAside: false, // 是否显示侧边栏
 5 |     searchWord: "", // 搜索关键词
 6 |     activeNavName: "", // 导航栏名称
 7 |   },
 8 |   getters: {
 9 |     token: (state) => state.token,
10 |     activeNavName: (state) => state.activeNavName,
11 |     showAside: (state) => state.showAside,
12 |     searchWord: (state) => state.searchWord,
13 |   },
14 |   mutations: {
15 |     setToken: (state, token) => {
16 |       state.token = token;
17 |     },
18 |     setActiveNavName: (state, activeNavName) => {
19 |       state.activeNavName = activeNavName;
20 |     },
21 |     setShowAside: (state, showAside) => {
22 |       state.showAside = showAside;
23 |     },
24 |     setSearchWord: (state, searchWord) => {
25 |       state.searchWord = searchWord;
26 |     },
27 |   },
28 | };
29 | 


--------------------------------------------------------------------------------
/music-client/src/store/index.ts:
--------------------------------------------------------------------------------
 1 | import { createStore } from "vuex";
 2 | import configure from "./configure";
 3 | import user from "./user";
 4 | import song from "./song";
 5 | 
 6 | export default createStore({
 7 |   modules: {
 8 |     configure,
 9 |     user,
10 |     song,
11 |   },
12 | });
13 | 


--------------------------------------------------------------------------------
/music-client/src/store/user.ts:
--------------------------------------------------------------------------------
 1 | export default {
 2 |   state: {
 3 |     userId: "", // ID
 4 |     username: "", // 名字
 5 |     userPic: "", // 图片
 6 |   },
 7 |   getters: {
 8 |     userId: (state) => state.userId,
 9 |     username: (state) => state.username,
10 |     userPic: (state) => state.userPic,
11 |   },
12 |   mutations: {
13 |     setUserId: (state, userId) => {
14 |       state.userId = userId;
15 |     },
16 |     setUsername: (state, username) => {
17 |       state.username = username;
18 |     },
19 |     setUserPic: (state, userPic) => {
20 |       state.userPic = userPic;
21 |     },
22 |   },
23 | };
24 | 


--------------------------------------------------------------------------------
/music-client/src/views/FPassword.vue:
--------------------------------------------------------------------------------
  1 | <template>
  2 |   <el-container id="appSend">
  3 |     <el-header>
  4 |       <h1>修改密码</h1>
  5 |     </el-header>
  6 |     <el-main>
  7 |       <el-form @submit.prevent="handleSubmit">
  8 |         <el-form-item label="邮箱:" prop="email">
  9 |           <el-input id="email" v-model="email" type="email" required />
 10 |           <el-button @click="sendVerificationCode">发送验证码</el-button>
 11 |         </el-form-item>
 12 |         <el-form-item label="验证码:" prop="code">
 13 |           <el-input id="code" v-model="code" type="text" required />
 14 |         </el-form-item>
 15 |         <el-form-item label="新密码:" prop="password">
 16 |           <el-input id="password" v-model="password" type="password" required />
 17 |         </el-form-item>
 18 |         <el-form-item label="确认密码:" prop="confirmPassword">
 19 |           <el-input id="confirmPassword" v-model="confirmPassword" type="password" required />
 20 |         </el-form-item>
 21 |         <el-form-item>
 22 |           
 23 |           <el-button @click="handleSubmit" type="submit">提交</el-button>
 24 |           
 25 |         </el-form-item>
 26 |       </el-form>
 27 |     </el-main>
 28 |   </el-container>
 29 | </template>
 30 | 
 31 | 
 32 | <style>
 33 | #appSend {
 34 |   max-width: 400px;
 35 |   margin: 0 auto;
 36 | }
 37 | </style>
 38 | 
 39 | <script>
 40 | import axios from 'axios';
 41 | export default {
 42 |   
 43 | 
 44 |   data() {
 45 |   
 46 |     return {
 47 |       email: "",
 48 |       code: "",
 49 |       password: "",
 50 |       confirmPassword: ""
 51 |     };
 52 |   },
 53 |   methods: {
 54 |     async sendVerificationCode() {
 55 |       try {
 56 |          const email =document.getElementById('email').value;
 57 |          const response = await axios.get('http://localhost:8888/user/sendVerificationCode',({params: {
 58 |          email: email
 59 |   }}));
 60 |          console.log(response.data);
 61 |         this.$message({
 62 |           message: response.data,
 63 |           type: 'success'
 64 |         });
 65 |       } catch (error) {
 66 |         console.error('Error submitting email:');
 67 |        this.$message({
 68 |         message: 'response.data',
 69 |         type: 'error'
 70 |       });
 71 |  } 
 72 |    },
 73 |     async handleSubmit() {
 74 |   try {
 75 |     const email =document.getElementById('email').value;
 76 |     const code=document.getElementById('code').value
 77 |     const password=document.getElementById('password').value
 78 |     const confirmPassword=document.getElementById('confirmPassword').value
 79 |     const data = {
 80 |       email: email,
 81 |       code: code,
 82 |       password: password,
 83 |       confirmPassword: confirmPassword
 84 |     };
 85 |     const response = await axios.post('http://localhost:8888/user/resetPassword', data);
 86 |     console.log(response.data);
 87 |     this.$message({
 88 |       message: response.data,
 89 |       type: 'success'
 90 |     });
 91 |   } catch (error) {
 92 |     this.$message({
 93 |       message: 'response.data',
 94 |       type: 'error'
 95 |     });
 96 |   }
 97 | }
 98 | 
 99 | },
100 | };
101 | </script>
102 | 


--------------------------------------------------------------------------------
/music-client/src/views/Home.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <!--轮播图-->
 3 |   <el-carousel v-if="swiperList.length" class="swiper-container" type="card" height="20vw" :interval="4000">
 4 |     <el-carousel-item v-for="(item, index) in swiperList" :key="index">
 5 |       <img :src="HttpManager.attachImageUrl(item.pic)" />
 6 |     </el-carousel-item>
 7 |   </el-carousel>
 8 |   <!--热门歌单-->
 9 |   <play-list class="play-list-container" title="歌单" path="song-sheet-detail" :playList="songList"></play-list>
10 |   <!--热门歌手-->
11 |   <play-list class="play-list-container" title="歌手" path="singer-detail" :playList="singerList"></play-list>
12 | </template>
13 | 
14 | <script lang="ts" setup>
15 | import { ref, onMounted } from "vue";
16 | 
17 | import PlayList from "@/components/PlayList.vue";
18 | import {  NavName } from "@/enums";
19 | import { HttpManager } from "@/api";
20 | import mixin from "@/mixins/mixin";
21 | 
22 | const songList = ref([]); // 歌单列表
23 | const singerList = ref([]); // 歌手列表
24 | const swiperList = ref([]);// 轮播图 每次都在进行查询
25 | const { changeIndex } = mixin();
26 | try {
27 | 
28 |   HttpManager.getBannerList().then((res) => {
29 |     swiperList.value = (res as ResponseBody).data.sort();
30 |   });
31 | 
32 |   HttpManager.getSongList().then((res) => {
33 |     songList.value = (res as ResponseBody).data.sort().slice(0, 10);
34 |   });
35 | 
36 |   HttpManager.getAllSinger().then((res) => {
37 |     singerList.value = (res as ResponseBody).data.sort().slice(0, 10);
38 |   });
39 | 
40 |   onMounted(() => {
41 |     changeIndex(NavName.Home);
42 |   });
43 | } catch (error) {
44 |   console.error(error);
45 | }
46 | </script>
47 | 
48 | <style lang="scss" scoped>
49 | @import "@/assets/css/var.scss";
50 | 
51 | /*轮播图*/
52 | .swiper-container {
53 |   width: 90%;
54 |   margin: auto;
55 |   padding-top: 20px;
56 |   img {
57 |     width: 100%;
58 |   }
59 | }
60 | 
61 | .swiper-container:deep(.el-carousel__indicators.el-carousel__indicators--outside) {
62 |   display: inline-block;
63 |   transform: translateX(30vw);
64 | }
65 | 
66 | .el-slider__runway {
67 |   background-color: $color-blue;
68 | }
69 | </style>
70 | 


--------------------------------------------------------------------------------
/music-client/src/views/YinContainer.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <el-container>
 3 |     <el-header>
 4 |       <yin-header></yin-header>
 5 |     </el-header>
 6 |     <el-main>
 7 |       <router-view />
 8 |       <yin-current-play></yin-current-play>
 9 |       <yin-play-bar></yin-play-bar>
10 |       <yin-scroll-top></yin-scroll-top>
11 |       <yin-audio></yin-audio>
12 |     </el-main>
13 |     <el-footer>
14 |       <yin-footer></yin-footer>
15 |     </el-footer>
16 |   </el-container>
17 | </template>
18 | 
19 | <script lang="ts" setup>
20 | import { getCurrentInstance } from "vue";
21 | import YinHeader from "@/components/layouts/YinHeader.vue";
22 | import YinCurrentPlay from "@/components/layouts/YinCurrentPlay.vue";
23 | import YinPlayBar from "@/components/layouts/YinPlayBar.vue";
24 | import YinScrollTop from "@/components/layouts/YinScrollTop.vue";
25 | import YinFooter from "@/components/layouts/YinFooter.vue";
26 | import YinAudio from "@/components/layouts/YinAudio.vue";
27 | 
28 | const { proxy } = getCurrentInstance();
29 | 
30 | if (sessionStorage.getItem("dataStore")) {
31 |   proxy.$store.replaceState(Object.assign({}, proxy.$store.state, JSON.parse(sessionStorage.getItem("dataStore"))));
32 | }
33 | 
34 | window.addEventListener("beforeunload", () => {
35 |   sessionStorage.setItem("dataStore", JSON.stringify(proxy.$store.state));
36 | });
37 | </script>
38 | 
39 | <style lang="scss" scoped>
40 | @import "@/assets/css/var.scss";
41 | @import "@/assets/css/global.scss";
42 | 
43 | .el-container {
44 |   min-height: calc(100% - 60px);
45 | }
46 | .el-header {
47 |   padding: 0;
48 | }
49 | .el-main {
50 |   padding-left: 0;
51 |   padding-right: 0;
52 | }
53 | </style>
54 | 


--------------------------------------------------------------------------------
/music-client/src/views/error/404.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <div class="error-page">
 3 |     <div class="error-code">404</div>
 4 |   </div>
 5 | </template>
 6 | 
 7 | <style scoped>
 8 | .error-page {
 9 |   display: flex;
10 |   justify-content: center;
11 |   align-items: stretch;
12 |   flex-direction: row;
13 |   flex-wrap: nowrap;
14 |   width: 100%;
15 |   height: 100%;
16 |   padding: 11rem 0;
17 |   box-sizing: border-box;
18 | }
19 | 
20 | .error-code {
21 |   font-size: 250px;
22 |   font-weight: bolder;
23 |   color: #000000;
24 | }
25 | </style>
26 | 


--------------------------------------------------------------------------------
/music-client/src/views/loginByemail.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <yin-login-logo></yin-login-logo>
 3 |   <div class="sign">
 4 |     <div class="sign-head">
 5 |       <span>邮箱登录</span>
 6 |     </div>
 7 |     <el-form ref="signInForm" status-icon :model="registerForm" :rules="SignInRules">
 8 |       <el-form-item prop="email">
 9 |         <el-input placeholder="邮箱" v-model="registerForm.email"></el-input>
10 |       </el-form-item>
11 |       <el-form-item prop="password">
12 |         <el-input type="password" placeholder="密码" v-model="registerForm.password" @keyup.enter="handleLoginIn"></el-input>
13 |       </el-form-item>
14 |       <el-form-item class="sign-btn">
15 |         <el-button type="primary" @click="handleLoginIn">登录</el-button>
16 |          <el-button type="primary" @click="handleLoginCancel">取消</el-button>
17 |       </el-form-item>
18 |     </el-form>
19 |   </div>
20 | </template>
21 | 
22 | <script lang="ts">
23 | import { defineComponent, reactive, getCurrentInstance } from "vue";
24 | import mixin from "@/mixins/mixin";
25 | import YinLoginLogo from "@/components/layouts/YinLoginLogo.vue";
26 | import { HttpManager } from "@/api";
27 | import { NavName, RouterName, SignInRules } from "@/enums";
28 | 
29 | export default defineComponent({
30 |   components: {
31 |     YinLoginLogo,
32 |   },
33 |   setup() {
34 |     const { proxy } = getCurrentInstance();
35 |     const { routerManager, changeIndex } = mixin();
36 | 
37 |     // 登录
38 |     const registerForm = reactive({
39 |       email: "",
40 |       password: "",
41 |     });
42 | 
43 |     async function handleLoginCancel() {
44 |        routerManager(RouterName.SignIn, { path: RouterName.SignIn });
45 |     }
46 | 
47 |     async function handleLoginIn() {
48 |       let canRun = true;
49 |       (proxy.$refs["signInForm"] as any).validate((valid) => {
50 |         if (!valid) return (canRun = false);
51 |       });
52 |       if (!canRun) return;
53 | 
54 | 
55 |       try {
56 |         const email = registerForm.email;
57 |         const password = registerForm.password;
58 |         const result = (await HttpManager.signInByemail({email,password})) as ResponseBody;
59 |         (proxy as any).$message({
60 |           message: result.message,
61 |           type: result.type,
62 |         });
63 | 
64 |         if (result.success) {
65 |           proxy.$store.commit("setUserId", result.data[0].id);
66 |           proxy.$store.commit("setUsername", result.data[0].username);
67 |           proxy.$store.commit("setUserPic", result.data[0].avator);
68 |           proxy.$store.commit("setToken", true);
69 |           changeIndex(NavName.Home);
70 |           routerManager(RouterName.Home, { path: RouterName.Home });
71 |         }
72 |       } catch (error) {
73 |         console.error(error);
74 |       }
75 |     }
76 | 
77 |     return {
78 |       registerForm,
79 |       SignInRules,
80 |       handleLoginIn,
81 |       handleLoginCancel,
82 |     };
83 |   },
84 | });
85 | </script>
86 | 
87 | <style lang="scss" scoped>
88 | @import "@/assets/css/sign.scss";
89 | </style>
90 | 


--------------------------------------------------------------------------------
/music-client/src/views/search/Search.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <div class="search">
 3 |     <yin-nav :styleList="searchNavList" :activeName="activeName" @click="handleChangeView"></yin-nav>
 4 |     <component class="search-list" :is="currentView"></component>
 5 |   </div>
 6 | </template>
 7 | 
 8 | <script lang="ts">
 9 | import { defineComponent } from "vue";
10 | import YinNav from "@/components/layouts/YinNav.vue";
11 | import SearchSong from "./SearchSong.vue";
12 | import SearchSongList from "./SearchSongList.vue";
13 | 
14 | export default defineComponent({
15 |   components: {
16 |     YinNav,
17 |     SearchSong,
18 |     SearchSongList,
19 |   },
20 |   data() {
21 |     return {
22 |       searchNavList: [
23 |         {
24 |           name: "歌曲",
25 |           value: "SearchSong",
26 |         },
27 |         {
28 |           name: "歌单",
29 |           value: "SearchSongList",
30 |         },
31 |       ],
32 |       activeName: "歌曲",
33 |       currentView: "SearchSong",
34 |     };
35 |   },
36 |   methods: {
37 |     handleChangeView(item) {
38 |       this.activeName = item.name;
39 |       this.currentView = item.value;
40 |     },
41 |   },
42 | });
43 | </script>
44 | 
45 | <style lang="scss" scoped>
46 | @import "@/assets/css/var.scss";
47 | @import "@/assets/css/global.scss";
48 | 
49 | .search {
50 |   margin: auto;
51 |   width: 900px;
52 |   
53 |   .search-list {
54 |     min-height: 480px;
55 |   }
56 | }
57 | </style>
58 | 


--------------------------------------------------------------------------------
/music-client/src/views/search/SearchSong.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <div class="search-song">
 3 |     <song-list :songList="currentSongList"></song-list>
 4 |   </div>
 5 | </template>
 6 | 
 7 | <script lang="ts">
 8 | import { defineComponent, ref, computed, watch, onMounted, getCurrentInstance } from "vue";
 9 | import { useStore } from "vuex";
10 | import SongList from "@/components/SongList.vue";
11 | import { HttpManager } from "@/api";
12 | 
13 | export default defineComponent({
14 |   components: {
15 |     SongList,
16 |   },
17 |   setup() {
18 |     const { proxy } = getCurrentInstance();
19 |     const store = useStore();
20 | 
21 |     const currentSongList = ref([]); // 存放的音乐
22 |     const searchWord = computed(() => store.getters.searchWord);
23 |     watch(searchWord, (value) => {
24 |       searchSong(value);
25 |     });
26 | 
27 |     // 搜索音乐
28 |     async function searchSong(value) {
29 |       if (!value) {
30 |         currentSongList.value = [];
31 |         return;
32 |       }
33 |       const result = (await HttpManager.getSongOfSingerName(value)) as ResponseBody;
34 |       if (!result.data.length) {
35 |         currentSongList.value = [];
36 |         (proxy as any).$message({
37 |           message: "暂时没有相关歌曲",
38 |           type: "warning",
39 |         });
40 |       } else {
41 |         currentSongList.value = result.data;
42 |       }
43 |     }
44 | 
45 |     onMounted(() => {
46 |       searchSong(proxy.$route.query.keywords);
47 |     });
48 | 
49 |     return {
50 |       currentSongList,
51 |     };
52 |   },
53 | });
54 | </script>
55 | 


--------------------------------------------------------------------------------
/music-client/src/views/search/SearchSongList.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <div class="search-song-list">
 3 |     <play-list :playList="playList" path="song-sheet-detail"></play-list>
 4 |   </div>
 5 | </template>
 6 | 
 7 | <script lang="ts">
 8 | import { defineComponent, ref, computed, watch, onMounted, getCurrentInstance } from "vue";
 9 | import { useStore } from "vuex";
10 | import PlayList from "@/components/PlayList.vue";
11 | import { HttpManager } from "@/api";
12 | 
13 | export default defineComponent({
14 |   components: {
15 |     PlayList,
16 |   },
17 |   setup() {
18 |     const { proxy } = getCurrentInstance();
19 |     const store = useStore();
20 | 
21 |     const playList = ref([]);
22 |     const searchWord = computed(() => store.getters.searchWord);
23 |     watch(searchWord, (value) => {
24 |       getSearchList(value);
25 |     });
26 | 
27 |     async function getSearchList(value) {
28 |       if (!value) return;
29 |       const result = (await HttpManager.getSongListOfLikeTitle(value)) as ResponseBody;
30 |       if (!result.data.length) {
31 |         (proxy as any).$message({
32 |           message: "暂无该歌曲内容",
33 |           type: "warning",
34 |         });
35 |       } else {
36 |         playList.value = result.data;
37 |       }
38 |     }
39 | 
40 |     onMounted(() => {
41 |       getSearchList(proxy.$route.query.keywords);
42 |     });
43 | 
44 |     return {
45 |       playList,
46 |     };
47 |   },
48 | });
49 | </script>
50 | 


--------------------------------------------------------------------------------
/music-client/src/views/setting/Password.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <el-form ref="passwordForm" label-width="70px" :model="form" :rules="rules">
 3 |     <el-form-item label="旧密码" prop="oldPassword">
 4 |       <el-input type="password" v-model="form.oldPassword" />
 5 |     </el-form-item>
 6 |     <el-form-item label="新密码" prop="newPassword">
 7 |       <el-input type="password" v-model="form.newPassword" />
 8 |     </el-form-item>
 9 |     <el-form-item label="密码确认" prop="confirmPassword">
10 |       <el-input type="password" v-model="form.confirmPassword" />
11 |     </el-form-item>
12 |     <el-form-item>
13 |       <el-button @click="clearData()">重置</el-button>
14 |       <el-button type="primary" @click="confirm()">确认修改</el-button>
15 |     </el-form-item>
16 |   </el-form>
17 | </template>
18 | 
19 | <script lang="ts">
20 | import { defineComponent, getCurrentInstance, computed, reactive } from "vue";
21 | import { useStore } from "vuex";
22 | import mixin from "@/mixins/mixin";
23 | import { HttpManager } from "@/api";
24 | import { validatePassword } from "@/enums";
25 | 
26 | export default defineComponent({
27 |   setup() {
28 |     const store = useStore();
29 |     const { proxy } = getCurrentInstance();
30 |     const { goBack } = mixin();
31 | 
32 |     const form = reactive({
33 |       oldPassword: "",
34 |       newPassword: "",
35 |       confirmPassword: "",
36 |     });
37 |     const userId = computed(() => store.getters.userId);
38 |     const userName = computed(() => store.getters.username);
39 | 
40 |     const validateCheck = (rule: any, value: any, callback: any) => {
41 |       if (value === "") {
42 |         callback(new Error("密码不能为空"));
43 |       } else if (value !== form.newPassword) {
44 |         callback(new Error("请输入正确密码"));
45 |       } else {
46 |         callback();
47 |       }
48 |     };
49 |     const rules = reactive({
50 |       oldPassword: [{ validator: validatePassword, trigger: "blur", min: 3 }],
51 |       newPassword: [{ validator: validatePassword, trigger: "blur", min: 3 }],
52 |       confirmPassword: [{ validator: validateCheck, trigger: "blur", min: 3 }],
53 |     });
54 | 
55 |     async function clearData() {
56 |       form.oldPassword = "";
57 |       form.newPassword = "";
58 |       form.confirmPassword = "";
59 |     }
60 | 
61 |     async function confirm() {
62 |       let canRun = true;
63 |       (proxy.$refs["passwordForm"] as any).validate((valid) => {
64 |         if (!valid) return (canRun = false);
65 |       });
66 |       if (!canRun) return;
67 | 
68 | 
69 |       const id = userId.value;
70 |       const username = userName.value;
71 |       const oldPassword = form.oldPassword;
72 |       const password = form.newPassword;
73 | 
74 |       const result = (await HttpManager.updateUserPassword({id,username,oldPassword,password})) as ResponseBody;
75 |       (proxy as any).$message({
76 |         message: result.message,
77 |         type: result.type,
78 |       });
79 |       if (result.success) goBack();
80 |     }
81 | 
82 |     return {
83 |       form,
84 |       clearData,
85 |       confirm,
86 |       rules,
87 |     };
88 |   },
89 | });
90 | </script>
91 | 
92 | <style></style>
93 | 


--------------------------------------------------------------------------------
/music-client/src/views/setting/Setting.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <div class="setting">
 3 |     <h1>设置</h1>
 4 |     <el-tabs tab-position="left">
 5 |       <el-tab-pane label="个人资料" class="content">
 6 |         <Personal-data></Personal-data>
 7 |       </el-tab-pane>
 8 |       <el-tab-pane label="更改密码" class="content">
 9 |         <Password></Password>
10 |       </el-tab-pane>
11 |       <el-tab-pane label="账号和安全" class="content">
12 |         <el-button type="danger" :icon="Delete" @click="cancelAccount">注销账号</el-button>
13 |       </el-tab-pane>
14 |     </el-tabs>
15 |   </div>
16 | </template>
17 | 
18 | <script lang="ts">
19 | import { defineComponent, getCurrentInstance, computed, reactive } from "vue";
20 | import { Delete } from "@element-plus/icons-vue";
21 | import PersonalData from "./PersonalData.vue";
22 | import Password from "./Password.vue";
23 | import { HttpManager } from "@/api";
24 | import { useStore } from "vuex";
25 | import mixin from "@/mixins/mixin";
26 | import { RouterName } from "@/enums";
27 | 
28 | export default defineComponent({
29 |   components: {
30 |     PersonalData,
31 |     Password,
32 |   },
33 |   setup() {
34 |     const { proxy } = getCurrentInstance();
35 |     const store = useStore();
36 |     const { routerManager } = mixin();
37 | 
38 |     const userId = computed(() => store.getters.userId);
39 | 
40 |     async function cancelAccount() {
41 |       const result = (await HttpManager.deleteUser(userId.value)) as ResponseBody;
42 |       (proxy as any).$message({
43 |         message: result.message,
44 |         type: result.type,
45 |       });
46 |       routerManager(RouterName.SignIn, { path: RouterName.SignIn });
47 |       proxy.$store.commit("setToken", false);
48 |     }
49 | 
50 |     return {
51 |       Delete,
52 |       cancelAccount,
53 |     };
54 |   },
55 | });
56 | </script>
57 | 
58 | <style lang="scss" scoped>
59 | @import "@/assets/css/var.scss";
60 | @import "@/assets/css/global.scss";
61 | 
62 | h1 {
63 |   border-bottom: 1px solid $color-grey;
64 | }
65 | 
66 | .content {
67 |   padding-top: 20px;
68 |   text-align: center;
69 | }
70 | 
71 | @media screen and (min-width: $sm) {
72 |   .setting {
73 |     margin: 30px 10%;
74 |     margin-top: 0;
75 |     padding: 20px;
76 |     min-height: 60vh;
77 |   }
78 | }
79 | 
80 | @media screen and (max-width: $sm) {
81 |   .setting {
82 |     padding: 20px;
83 |   }
84 | }
85 | </style>
86 | 


--------------------------------------------------------------------------------
/music-client/src/views/setting/Upload.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <div class="upload">
 3 |     <el-upload drag :action="uploadUrl()" :show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
 4 |       <el-icon class="el-icon--upload"><upload-filled /></el-icon>
 5 |       <div class="el-upload__text">将文件拖到此处或点击上传</div>
 6 |       <template #tip>
 7 |         <p class="el-upload__tip">只能上传 {{ uploadTypes.join("、") }} 文件, 且不超过10M</p>
 8 |       </template>
 9 |     </el-upload>
10 |   </div>
11 | </template>
12 | 
13 | <script lang="ts">
14 | import { defineComponent, ref, computed, getCurrentInstance } from "vue";
15 | import { useStore } from "vuex";
16 | import { UploadFilled } from "@element-plus/icons-vue";
17 | import { HttpManager } from "@/api";
18 | 
19 | export default defineComponent({
20 |   components: {
21 |     UploadFilled,
22 |   },
23 |   setup() {
24 |     const { proxy } = getCurrentInstance();
25 |     const store = useStore();
26 | 
27 |     const uploadTypes = ref(["jpg", "jpeg", "png", "gif"]);
28 |     const userId = computed(() => store.getters.userId);
29 | 
30 |     function uploadUrl() {
31 |       return HttpManager.uploadUrl(userId.value);
32 |     }
33 | 
34 |     function beforeAvatarUpload(file) {
35 |       const ltCode = 2;
36 |       const isLt10M = file.size / 1024 / 1024;
37 |       const isExistFileType = uploadTypes.value.includes(file.type.replace(/image\//, ""));
38 | 
39 |       if (isLt10M > ltCode || isLt10M <= 0) {
40 |         (proxy as any).$message.error(`图片大小范围是 0~${ltCode}MB!`);
41 |       }
42 |       if (!isExistFileType) {
43 |         (proxy as any).$message.error(`图片只支持 ${uploadTypes.value.join("、")} 格式!`);
44 |       }
45 | 
46 |       return isLt10M && isExistFileType;
47 |     }
48 | 
49 |     function handleAvatarSuccess(response, file) {
50 |       (proxy as any).$message({
51 |         message: response.message,
52 |         type: response.type,
53 |       });
54 | 
55 |       if (response.success) proxy.$store.commit("setUserPic", response.data);
56 |     }
57 | 
58 |     return {
59 |       uploadTypes,
60 |       uploadUrl,
61 |       beforeAvatarUpload,
62 |       handleAvatarSuccess,
63 |     };
64 |   },
65 | });
66 | </script>
67 | 
68 | <style scoped>
69 | .upload {
70 |   width: 100%;
71 |   height: 300px;
72 |   display: flex;
73 |   justify-content: center;
74 |   align-items: center;
75 | }
76 | </style>
77 | 


--------------------------------------------------------------------------------
/music-client/src/views/singer/Singer.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <div class="play-list-container">
 3 |     <yin-nav :styleList="singerStyle" :activeName="activeName" @click="handleChangeView"></yin-nav>
 4 |     <play-list :playList="data" path="singer-detail"></play-list>
 5 |     <el-pagination
 6 |       class="pagination"
 7 |       background
 8 |       layout="total, prev, pager, next"
 9 |       :current-page="currentPage"
10 |       :page-size="pageSize"
11 |       :total="allPlayList.length"
12 |       @current-change="handleCurrentChange"
13 |     >
14 |     </el-pagination>
15 |   </div>
16 | </template>
17 | 
18 | <script lang="ts" setup>
19 | import { ref, computed } from "vue";
20 | import YinNav from "@/components/layouts/YinNav.vue";
21 | import PlayList from "@/components/PlayList.vue";
22 | import { singerStyle } from "@/enums";
23 | import { HttpManager } from "@/api";
24 | 
25 | // data
26 | const activeName = ref("全部歌手");
27 | const pageSize = ref(15); // 页数
28 | const currentPage = ref(1); // 当前页
29 | const allPlayList = ref([]);
30 | // computed
31 | const data = computed(() => {
32 |   return allPlayList.value.slice((currentPage.value - 1) * pageSize.value, currentPage.value * pageSize.value);
33 | });
34 | 
35 | // 获取所有歌手
36 | async function getAllSinger() {
37 |   const result = (await HttpManager.getAllSinger()) as ResponseBody;
38 |   currentPage.value = 1;
39 |   allPlayList.value = result.data;
40 | }
41 | 
42 | getAllSinger();
43 | 
44 | // 获取当前页
45 | function handleCurrentChange(val) {
46 |   currentPage.value = val;
47 | }
48 | 
49 | function handleChangeView(item) {
50 |   activeName.value = item.name;
51 |   allPlayList.value = [];
52 |   if (item.name === "全部歌手") {
53 |     getAllSinger();
54 |   } else {
55 |     getSingerSex(item.type);
56 |   }
57 | }
58 | 
59 | // 通过性别对歌手分类
60 | async function getSingerSex(sex) {
61 |   const result = (await HttpManager.getSingerOfSex(sex)) as ResponseBody;
62 |   currentPage.value = 1;
63 |   allPlayList.value = result.data;
64 | }
65 | </script>
66 | 


--------------------------------------------------------------------------------
/music-client/src/views/singer/SingerDetail.vue:
--------------------------------------------------------------------------------
  1 | <template>
  2 |   <el-container>
  3 |     <el-aside class="album-slide">
  4 |       <el-image class="singer-img" fit="contain" :src="attachImageUrl(songDetails.pic)" />
  5 |       <div class="album-info">
  6 |         <h2>基本资料</h2>
  7 |         <ul>
  8 |           <li v-if="songDetails.sex !== 2">性别:{{ getUserSex(songDetails.sex) }}</li>
  9 |           <li>生日:{{ getBirth(songDetails.birth) }}</li>
 10 |           <li>故乡:{{ songDetails.location }}</li>
 11 |         </ul>
 12 |       </div>
 13 |     </el-aside>
 14 |     <el-main class="album-main">
 15 |       <h1>{{ songDetails.name }}</h1>
 16 |       <p>{{ songDetails.introduction }}</p>
 17 |       <song-list :songList="currentSongList"></song-list>
 18 |     </el-main>
 19 |   </el-container>
 20 | </template>
 21 | 
 22 | <script lang="ts">
 23 | import { defineComponent, ref, computed, onMounted } from "vue";
 24 | import { useStore } from "vuex";
 25 | import mixin from "@/mixins/mixin";
 26 | import SongList from "@/components/SongList.vue";
 27 | import { HttpManager } from "@/api";
 28 | import { getBirth } from "@/utils";
 29 | 
 30 | export default defineComponent({
 31 |   components: {
 32 |     SongList,
 33 |   },
 34 |   setup() {
 35 |     const store = useStore();
 36 |     const { getUserSex } = mixin();
 37 | 
 38 |     const currentSongList = ref([]);
 39 |     const songDetails = computed(() => store.getters.songDetails) as any;
 40 | 
 41 |     onMounted(async () => {
 42 |       try {
 43 |         const result = (await HttpManager.getSongOfSingerId(songDetails.value.id)) as ResponseBody;
 44 |         currentSongList.value = result.data;
 45 |       } catch (error) {
 46 |         console.error(error);
 47 |       }
 48 |     });
 49 | 
 50 |     return {
 51 |       songDetails,
 52 |       currentSongList,
 53 |       attachImageUrl: HttpManager.attachImageUrl,
 54 |       getBirth,
 55 |       getUserSex,
 56 |     };
 57 |   },
 58 | });
 59 | </script>
 60 | 
 61 | <style lang="scss" scoped>
 62 | @import "@/assets/css/var.scss";
 63 | 
 64 | .album-slide {
 65 |   display: flex;
 66 |   flex-direction: column;
 67 |   align-items: center;
 68 |   padding-top: 20px;
 69 | 
 70 |   .singer-img {
 71 |     height: 250px;
 72 |     width: 250px;
 73 |     border-radius: 10%;
 74 |   }
 75 | 
 76 |   .album-info {
 77 |     width: 60%;
 78 |     padding-top: 2rem;
 79 |     li {
 80 |       width: 100%;
 81 |       height: 30px;
 82 |       line-height: 30px;
 83 |     }
 84 |   }
 85 | }
 86 | 
 87 | .album-main {
 88 |   p {
 89 |     color: rgba(0, 0, 0, 0.5);
 90 |     margin: 10px 0 20px 0px;
 91 |   }
 92 | }
 93 | 
 94 | @media screen and (min-width: $sm) {
 95 |   .album-slide {
 96 |     position: fixed;
 97 |     width: 400px;
 98 |   }
 99 |   .album-main {
100 |     min-width: 600px;
101 |     padding-right: 10vw;
102 |     margin-left: 400px;
103 |   }
104 | }
105 | 
106 | @media screen and (max-width: $sm) {
107 |   .album-slide {
108 |     display: none;
109 |   }
110 | }
111 | </style>
112 | 


--------------------------------------------------------------------------------
/music-client/src/views/song-sheet/SongSheet.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <div class="play-list-container">
 3 |     <yin-nav :styleList="songStyle" :activeName="activeName" @click="handleChangeView"></yin-nav>
 4 |     <play-list :playList="data" path="song-sheet-detail"></play-list>
 5 |     <el-pagination
 6 |       class="pagination"
 7 |       background
 8 |       layout="total, prev, pager, next"
 9 |       :current-page="currentPage"
10 |       :page-size="pageSize"
11 |       :total="allPlayList.length"
12 |       @current-change="handleCurrentChange"
13 |     >
14 |     </el-pagination>
15 |   </div>
16 | </template>
17 | 
18 | <script lang="ts">
19 | import { defineComponent, ref, computed } from "vue";
20 | import YinNav from "@/components/layouts/YinNav.vue";
21 | import PlayList from "@/components/PlayList.vue";
22 | import { SONGSTYLE } from "@/enums";
23 | import { HttpManager } from "@/api";
24 | 
25 | export default defineComponent({
26 |   components: {
27 |     YinNav,
28 |     PlayList,
29 |   },
30 |   setup() {
31 |     const activeName = ref("全部歌单");
32 |     const pageSize = ref(15); // 页数
33 |     const currentPage = ref(1); // 当前页
34 |     const songStyle = ref(SONGSTYLE); // 歌单导航栏类别
35 |     const allPlayList = ref([]); // 歌单
36 |     const data = computed(() => allPlayList.value.slice((currentPage.value - 1) * pageSize.value, currentPage.value * pageSize.value));
37 | 
38 |     // 获取全部歌单
39 |     async function getSongList() {
40 |       allPlayList.value = ((await HttpManager.getSongList()) as ResponseBody).data;
41 |       currentPage.value = 1;
42 |     }
43 |     // 通过类别获取歌单
44 |     async function getSongListOfStyle(style) {
45 |       allPlayList.value = ((await HttpManager.getSongListOfStyle(style)) as ResponseBody).data;
46 |       currentPage.value = 1;
47 |     }
48 | 
49 |     try {
50 |       getSongList();
51 |     } catch (error) {
52 |       console.error(error);
53 |     }
54 | 
55 |     // 获取歌单
56 |     async function handleChangeView(item) {
57 |       activeName.value = item.name;
58 |       allPlayList.value = [];
59 |       try {
60 |         if (item.name === "全部歌单") {
61 |           await getSongList();
62 |         } else {
63 |           await getSongListOfStyle(item.name);
64 |         }
65 |       } catch (error) {
66 |         console.error(error);
67 |       }
68 |     }
69 |     // 获取当前页
70 |     function handleCurrentChange(val) {
71 |       currentPage.value = val;
72 |     }
73 |     return {
74 |       activeName,
75 |       songStyle,
76 |       pageSize,
77 |       currentPage,
78 |       allPlayList,
79 |       data,
80 |       handleChangeView,
81 |       handleCurrentChange,
82 |     };
83 |   },
84 | });
85 | </script>
86 | 


--------------------------------------------------------------------------------
/music-client/tsconfig.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "compilerOptions": {
 3 |     "target": "esnext",
 4 |     "module": "esnext",
 5 |     "strict": true,
 6 |     "jsx": "preserve",
 7 |     "moduleResolution": "node",
 8 |     "skipLibCheck": true,
 9 |     "esModuleInterop": true,
10 |     "allowSyntheticDefaultImports": true,
11 |     "forceConsistentCasingInFileNames": true,
12 |     "useDefineForClassFields": true,
13 |     "sourceMap": true,
14 |     "noImplicitAny": false,
15 |     "strictNullChecks": false,
16 |     "baseUrl": ".",
17 |     "types": [
18 |       "webpack-env"
19 |     ],
20 |     "paths": {
21 |       "@/*": [
22 |         "src/*"
23 |       ]
24 |     },
25 |     "lib": [
26 |       "esnext",
27 |       "dom",
28 |       "dom.iterable",
29 |       "scripthost"
30 |     ]
31 |   },
32 |   "include": [
33 |     "src/**/*.ts",
34 |     "src/**/*.tsx",
35 |     "src/**/*.vue",
36 |     "tests/**/*.ts",
37 |     "tests/**/*.tsx"
38 |   ],
39 |   "exclude": [
40 |     "node_modules"
41 |   ]
42 | }
43 | 


--------------------------------------------------------------------------------
/music-client/vue.config.js:
--------------------------------------------------------------------------------
 1 | const { defineConfig } = require('@vue/cli-service')
 2 | module.exports = defineConfig({
 3 |   transpileDependencies: true,
 4 |   chainWebpack: config => {
 5 |     config.plugin('define').tap(definitions => {
 6 |       Object.assign(definitions[0]['process.env'], {
 7 |         NODE_HOST: '"http://localhost:8888"',
 8 |       });
 9 |       return definitions;
10 |     });
11 |   }
12 | })
13 | 


--------------------------------------------------------------------------------
/music-manage/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 | not dead
4 | not ie 11
5 | 


--------------------------------------------------------------------------------
/music-manage/.eslintrc.js:
--------------------------------------------------------------------------------
 1 | module.exports = {
 2 |   root: true,
 3 |   env: {
 4 |     node: true
 5 |   },
 6 |   'extends': [
 7 |     'plugin:vue/vue3-essential',
 8 |     'eslint:recommended',
 9 |     '@vue/typescript/recommended'
10 |   ],
11 |   parserOptions: {
12 |     ecmaVersion: 2020
13 |   },
14 |   rules: {
15 |     'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
16 |     'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
17 |     'vue/multi-word-component-names': 0,
18 |     "@typescript-eslint/no-unused-vars": ["off"],
19 |     "@typescript-eslint/no-explicit-any": ["off"],
20 |     'no-undef': 0
21 |   }
22 | }
23 | 


--------------------------------------------------------------------------------
/music-manage/.gitignore:
--------------------------------------------------------------------------------
 1 | .DS_Store
 2 | node_modules
 3 | /dist
 4 | 
 5 | 
 6 | # local env files
 7 | .env.local
 8 | .env.*.local
 9 | 
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 | 
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 | 


--------------------------------------------------------------------------------
/music-manage/README.md:
--------------------------------------------------------------------------------
 1 | # music-manage
 2 | 
 3 | ## Project setup
 4 | ```
 5 | npm install
 6 | ```
 7 | 
 8 | ### Compiles and hot-reloads for development
 9 | ```
10 | npm run serve
11 | ```
12 | 
13 | ### Compiles and minifies for production
14 | ```
15 | npm run build
16 | ```
17 | 
18 | ### Lints and fixes files
19 | ```
20 | npm run lint
21 | ```
22 | 
23 | ### Customize configuration
24 | See [Configuration Reference](https://cli.vuejs.org/config/).
25 | 


--------------------------------------------------------------------------------
/music-manage/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 |   presets: [
3 |     '@vue/cli-plugin-babel/preset'
4 |   ]
5 | }
6 | 


--------------------------------------------------------------------------------
/music-manage/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "music-manage",
 3 |   "version": "3.0.0",
 4 |   "private": true,
 5 |   "scripts": {
 6 |     "serve": "vue-cli-service serve",
 7 |     "build": "vue-cli-service build",
 8 |     "lint": "vue-cli-service lint"
 9 |   },
10 |   "dependencies": {
11 |     "axios": "^0.26.1",
12 |     "core-js": "^3.8.3",
13 |     "echarts": "^5.3.2",
14 |     "element-plus": "^2.1.8",
15 |     "mitt": "^3.0.0",
16 |     "vue": "^3.2.13",
17 |     "vue-router": "^4.0.3",
18 |     "vuex": "^4.0.0"
19 |   },
20 |   "devDependencies": {
21 |     "@typescript-eslint/eslint-plugin": "^5.4.0",
22 |     "@typescript-eslint/parser": "^5.4.0",
23 |     "@vue/cli-plugin-babel": "~5.0.0",
24 |     "@vue/cli-plugin-eslint": "~5.0.0",
25 |     "@vue/cli-plugin-router": "~5.0.0",
26 |     "@vue/cli-plugin-typescript": "~5.0.0",
27 |     "@vue/cli-plugin-vuex": "~5.0.0",
28 |     "@vue/cli-service": "~5.0.0",
29 |     "@vue/eslint-config-typescript": "^9.1.0",
30 |     "eslint": "^7.32.0",
31 |     "eslint-plugin-vue": "^8.0.3",
32 |     "typescript": "~4.5.5"
33 |   }
34 | }
35 | 


--------------------------------------------------------------------------------
/music-manage/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yin-Hongwei/music-website/2cccb623c437abc0b90c91948d2c559a387fd335/music-manage/public/favicon.ico


--------------------------------------------------------------------------------
/music-manage/public/index.html:
--------------------------------------------------------------------------------
 1 | <!DOCTYPE html>
 2 | <html lang="">
 3 |   <head>
 4 |     <meta charset="utf-8">
 5 |     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6 |     <meta name="viewport" content="width=device-width,initial-scale=1.0">
 7 |     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
 8 |     <title><%= htmlWebpackPlugin.options.title %></title>
 9 |   </head>
10 |   <body>
11 |     <noscript>
12 |       <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
13 |     </noscript>
14 |     <div id="app"></div>
15 |     <!-- built files will be auto injected -->
16 |   </body>
17 | </html>
18 | 


--------------------------------------------------------------------------------
/music-manage/src/App.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <div id="app">
 3 |     <router-view></router-view>
 4 |   </div>
 5 | </template>
 6 | 
 7 | <script lang="ts" setup>
 8 | import { getCurrentInstance } from "vue";
 9 | 
10 | const { proxy } = getCurrentInstance();
11 | 
12 | if (sessionStorage.getItem("dataStore")) {
13 |   proxy.$store.replaceState(Object.assign({}, proxy.$store.state, JSON.parse(sessionStorage.getItem("dataStore"))));
14 | }
15 | 
16 | window.addEventListener("beforeunload", () => {
17 |   sessionStorage.setItem("dataStore", JSON.stringify(proxy.$store.state));
18 | });
19 | </script>
20 | 


--------------------------------------------------------------------------------
/music-manage/src/api/request.ts:
--------------------------------------------------------------------------------
  1 | import axios from 'axios'
  2 | import router from '../router'
  3 | 
  4 | const BASE_URL = process.env.NODE_HOST
  5 | 
  6 | axios.defaults.timeout = 5000 // 超时时间设置
  7 | axios.defaults.withCredentials = true // true允许跨域
  8 | axios.defaults.baseURL = BASE_URL
  9 | // Content-Type 响应头
 10 | axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
 11 | 
 12 | // 响应拦截器
 13 | axios.interceptors.response.use(
 14 |   response => {
 15 |     // 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
 16 |     // 否则的话抛出错误
 17 |     if (response.status === 200) {
 18 |       return Promise.resolve(response)
 19 |     } else {
 20 |       return Promise.reject(response)
 21 |     }
 22 |   },
 23 |   // 服务器状态码不是2开头的的情况
 24 |   error => {
 25 |     if (error.response.status) {
 26 |       switch (error.response.status) {
 27 |         // 401: 未登录
 28 |         case 401:
 29 |           router.replace({
 30 |             path: "/",
 31 |             query: {
 32 |               // redirect: router.currentRoute.fullPath
 33 |             },
 34 |           });
 35 |           break;
 36 |         case 403:
 37 |           // console.log('管理员权限已修改请重新登录')
 38 |           // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
 39 |           setTimeout(() => {
 40 |             router.replace({
 41 |               path: "/",
 42 |               query: {
 43 |                 // redirect: router.currentRoute.fullPath
 44 |               },
 45 |             });
 46 |           }, 1000);
 47 |           break;
 48 | 
 49 |         // 404请求不存在
 50 |         case 404:
 51 |           // console.log('请求页面飞到火星去了')
 52 |           break;
 53 |       }
 54 |       return Promise.reject(error.response);
 55 |     }
 56 |   }
 57 | )
 58 | 
 59 | export function getBaseURL() {
 60 |   return BASE_URL;
 61 | }
 62 | 
 63 | /**
 64 |  * 封装get方法
 65 |  * @param url
 66 |  * @param data
 67 |  * @returns {Promise}
 68 |  */
 69 | export function get(url, params?: object) {
 70 |   return new Promise((resolve, reject) => {
 71 |     axios.get(url, params).then(
 72 |       response => resolve(response.data),
 73 |       error => reject(error)
 74 |     )
 75 |   });
 76 | }
 77 | 
 78 | /**
 79 |  * 封装post请求
 80 |  * @param url
 81 |  * @param data
 82 |  * @returns {Promise}
 83 |  */
 84 | export function post(url, data = {}) {
 85 |   return new Promise((resolve, reject) => {
 86 |     axios.post(url, data).then(
 87 |       response => resolve(response.data),
 88 |       error => reject(error)
 89 |     );
 90 |   });
 91 | }
 92 | 
 93 | /**
 94 |  * 封装delete请求
 95 |  * @param url
 96 |  * @param data
 97 |  * @returns {Promise}
 98 |  */
 99 | export function deletes(url, data = {}) {
100 |   return new Promise((resolve, reject) => {
101 |     axios.delete(url, data).then(
102 |       response => resolve(response.data),
103 |       error => reject(error)
104 |     );
105 |   });
106 | }
107 | 
108 | /**
109 |  * 封装put请求
110 |  * @param url
111 |  * @param data
112 |  * @returns {Promise}
113 |  */
114 | export function put(url, data = {}) {
115 |   return new Promise((resolve, reject) => {
116 |     axios.put(url, data).then(
117 |       response => resolve(response.data),
118 |       error => reject(error)
119 |     );
120 |   });
121 | }
122 | 


--------------------------------------------------------------------------------
/music-manage/src/assets/css/main.css:
--------------------------------------------------------------------------------
 1 | html, body, div, span,
 2 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
 3 | dl, dt, dd, ol, ul, li,hr,img,a,
 4 | form, label, tr, th, td,
 5 | article, aside, canvas, details, embed,
 6 | figure, figcaption, footer, header {
 7 |   padding: 0;
 8 |   margin: 0;
 9 | }
10 | 
11 | html,
12 | body,
13 | #app,
14 | .wrapper {
15 |   width: 100%;
16 |   height: 100%;
17 |   overflow: hidden;
18 | }
19 | 
20 | ul,
21 | li {
22 |   list-style: none;
23 |   display: inline-block;
24 | }
25 | 
26 | a {
27 |   text-decoration: none;
28 | }
29 | 
30 | .crumbs {
31 |   margin-bottom: 20px;
32 | }
33 | 
34 | .pagination {
35 |   display: flex;
36 |   justify-content: center;
37 |   margin: 20px 0;
38 | }
39 | 
40 | .handle-box {
41 |   margin-bottom: 20px;
42 |   font-size: 12px;
43 |   display: flex;
44 |   width: 30%;
45 | }
46 | 
47 | .handle-box input {
48 |   margin: 0 10px;
49 | }
50 | 


--------------------------------------------------------------------------------
/music-manage/src/assets/icons/iconfont.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | !function(a){var e,n='<svg><symbol id="icon-bofanganniu" viewBox="0 0 1024 1024"><path d="M927.870095 571.688039 167.320423 1014.160886C121.562471 1041.981153 61.44 1007.279555 61.44 954.218179L61.44 68.595037C63.693916 16.802233 124.631347-17.041827 171.276012 8.961322L928.382003 451.43039C974.037627 479.202079 974.037627 543.611136 927.870095 571.688039Z"  ></path></symbol><symbol id="icon-zanting" viewBox="0 0 1024 1024"><path d="M268.97201558 114.31784297c73.21218086 0 132.56071902 59.34853814 132.56071901 132.560719v530.24287606c0 73.21218086-59.34853814 132.56071902-132.56071901 132.560719s-132.56071902-59.34853814-132.56071901-132.560719V246.87856197c0-73.21218086 59.34853814-132.56071902 132.56071901-132.560719z m486.05596884 0c73.21218086 0 132.56071902 59.34853814 132.56071901 132.560719v530.24287606c0 73.21218086-59.34853814 132.56071902-132.56071901 132.560719s-132.56071902-59.34853814-132.56071901-132.560719V246.87856197c0-73.21218086 59.34853814-132.56071902 132.56071901-132.560719z"  ></path></symbol></svg>',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("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}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-manage/src/assets/images/background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yin-Hongwei/music-website/2cccb623c437abc0b90c91948d2c559a387fd335/music-manage/src/assets/images/background.jpg


--------------------------------------------------------------------------------
/music-manage/src/assets/images/user.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yin-Hongwei/music-website/2cccb623c437abc0b90c91948d2c559a387fd335/music-manage/src/assets/images/user.jpg


--------------------------------------------------------------------------------
/music-manage/src/components/dialog/YinDelDialog.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <div>
 3 |     <!-- 删除提示框 -->
 4 |     <el-dialog title="提示" v-model="centerDialogVisible" width="300px" center>
 5 |       <div class="del-dialog-cnt" align="center">删除不可恢复,是否确定删除?</div>
 6 |       <template #footer>
 7 |         <span class="dialog-footer">
 8 |           <el-button @click="cancelRow">取 消</el-button>
 9 |           <el-button type="primary" @click="confirm">确 定</el-button>
10 |         </span>
11 |       </template>
12 |     </el-dialog>
13 |   </div>
14 | </template>
15 | 
16 | <script lang="ts">
17 | import { defineComponent, getCurrentInstance, toRefs, watch, ref } from "vue";
18 | 
19 | export default defineComponent({
20 |   props: {
21 |     delVisible: Boolean,
22 |   },
23 |   emits: ["cancelRow", "confirm"],
24 |   setup(props) {
25 |     const { proxy } = getCurrentInstance();
26 | 
27 |     const { delVisible } = toRefs(props);
28 |     const centerDialogVisible = ref(delVisible.value);
29 | 
30 |     watch(delVisible, (value) => {
31 |       centerDialogVisible.value = value;
32 |     });
33 | 
34 |     function cancelRow() {
35 |       proxy.$emit("cancelRow", false);
36 |     }
37 |     function confirm() {
38 |       proxy.$emit("confirm", null);
39 |     }
40 |     return {
41 |       centerDialogVisible,
42 |       cancelRow,
43 |       confirm,
44 |     };
45 |   },
46 | });
47 | </script>
48 | 


--------------------------------------------------------------------------------
/music-manage/src/components/layouts/YinAside.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <div class="sidebar">
 3 |     <el-menu
 4 |       class="sidebar-el-menu"
 5 |       background-color="#ffffff"
 6 |       active-text-color="#30a4fc"
 7 |       default-active="2"
 8 |       router
 9 |       :collapse="collapse"
10 |     >
11 |       <el-menu-item index="info">
12 |         <el-icon><pie-chart /></el-icon>
13 |         <span>系统首页</span>
14 |       </el-menu-item>
15 |       <el-menu-item index="consumer">
16 |         <el-icon><User /></el-icon>
17 |         <span>用户管理</span>
18 |       </el-menu-item>
19 |       <el-menu-item index="singer">
20 |         <el-icon><mic /></el-icon>
21 |         <span>歌手管理</span>
22 |       </el-menu-item>
23 |       <el-menu-item index="songList">
24 |         <el-icon><Document /></el-icon>
25 |         <span>歌单管理</span>
26 |       </el-menu-item>
27 |     </el-menu>
28 |   </div>
29 | </template>
30 | 
31 | <script lang="ts" setup>
32 | import { ref } from "vue";
33 | import { PieChart, Mic, Document, User } from "@element-plus/icons-vue";
34 | import emitter from "@/utils/emitter";
35 | 
36 | const collapse = ref(false);
37 | emitter.on("collapse", (msg) => {
38 |   collapse.value = msg as boolean;
39 | });
40 | </script>
41 | 
42 | <style scoped>
43 | .sidebar {
44 |   display: block;
45 |   position: absolute;
46 |   left: 0;
47 |   top: 60px;
48 |   bottom: 0;
49 |   overflow-y: scroll;
50 | }
51 | 
52 | .sidebar::-webkit-scrollbar {
53 |   width: 0;
54 | }
55 | 
56 | .sidebar > ul {
57 |   height: 100%;
58 | }
59 | 
60 | .sidebar-el-menu:not(.el-menu--collapse) {
61 |   width: 150px;
62 | }
63 | </style>
64 | 


--------------------------------------------------------------------------------
/music-manage/src/components/layouts/YinAudio.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <audio controls="controls" preload="true" v-if="url" :ref="player" :src="attachImageUrl(url)" @canplay="startPlay" @ended="ended"></audio>
 3 | </template>
 4 | 
 5 | <script lang="ts">
 6 | import { defineComponent, getCurrentInstance, computed, watch, ref } from "vue";
 7 | import { useStore } from "vuex";
 8 | import { HttpManager } from "@/api";
 9 | 
10 | export default defineComponent({
11 |   setup() {
12 |     const { proxy } = getCurrentInstance();
13 |     const store = useStore();
14 |     const divRef = ref<HTMLAudioElement>();
15 |     const player = (el) => {
16 |       divRef.value = el;
17 |     };
18 | 
19 |     const url = computed(() => store.getters.url); // 音乐链接
20 |     const isPlay = computed(() => store.getters.isPlay); // 播放状态
21 |     // 监听播放还是暂停
22 |     watch(isPlay, () => {
23 |       togglePlay();
24 |     });
25 | 
26 |     // 开始/暂停
27 |     function togglePlay() {
28 |       isPlay.value ? divRef.value.play() : divRef.value.pause();
29 |     }
30 | 
31 |     // 获取歌曲链接后准备播放
32 |     function startPlay() {
33 |       divRef.value.play();
34 |     }
35 |     // 音乐播放结束时触发
36 |     function ended() {
37 |       proxy.$store.commit("setIsPlay", false);
38 |     }
39 |     return {
40 |       url,
41 |       isPlay,
42 |       player,
43 |       startPlay,
44 |       ended,
45 |       attachImageUrl: HttpManager.attachImageUrl,
46 |     };
47 |   },
48 | });
49 | </script>
50 | 
51 | <style>
52 | audio {
53 |   display: none;
54 | }
55 | </style>
56 | 


--------------------------------------------------------------------------------
/music-manage/src/enums/area.ts:
--------------------------------------------------------------------------------
  1 | export const AREA = [
  2 |   {
  3 |     value: "北京",
  4 |     label: "北京",
  5 |   },
  6 |   {
  7 |     value: "天津",
  8 |     label: "天津",
  9 |   },
 10 |   {
 11 |     value: "河北",
 12 |     label: "河北",
 13 |   },
 14 |   {
 15 |     value: "山西",
 16 |     label: "山西",
 17 |   },
 18 |   {
 19 |     value: "内蒙古",
 20 |     label: "内蒙古",
 21 |   },
 22 |   {
 23 |     value: "辽宁",
 24 |     label: "辽宁",
 25 |   },
 26 |   {
 27 |     value: "吉林",
 28 |     label: "吉林",
 29 |   },
 30 |   {
 31 |     value: "黑龙江",
 32 |     label: "黑龙江",
 33 |   },
 34 |   {
 35 |     value: "上海",
 36 |     label: "上海",
 37 |   },
 38 |   {
 39 |     value: "江苏",
 40 |     label: "江苏",
 41 |   },
 42 |   {
 43 |     value: "浙江",
 44 |     label: "浙江",
 45 |   },
 46 |   {
 47 |     value: "安徽",
 48 |     label: "安徽",
 49 |   },
 50 |   {
 51 |     value: "福建",
 52 |     label: "福建",
 53 |   },
 54 |   {
 55 |     value: "江西",
 56 |     label: "江西",
 57 |   },
 58 |   {
 59 |     value: "山东",
 60 |     label: "山东",
 61 |   },
 62 |   {
 63 |     value: "河南",
 64 |     label: "河南",
 65 |   },
 66 |   {
 67 |     value: "湖北",
 68 |     label: "湖北",
 69 |   },
 70 |   {
 71 |     value: "湖南",
 72 |     label: "湖南",
 73 |   },
 74 |   {
 75 |     value: "广东",
 76 |     label: "广东",
 77 |   },
 78 |   {
 79 |     value: "广西",
 80 |     label: "广西",
 81 |   },
 82 |   {
 83 |     value: "海南",
 84 |     label: "海南",
 85 |   },
 86 |   {
 87 |     value: "重庆",
 88 |     label: "重庆",
 89 |   },
 90 |   {
 91 |     value: "四川",
 92 |     label: "四川",
 93 |   },
 94 |   {
 95 |     value: "贵州",
 96 |     label: "贵州",
 97 |   },
 98 |   {
 99 |     value: "云南",
100 |     label: "云南",
101 |   },
102 |   {
103 |     value: "西藏",
104 |     label: "西藏",
105 |   },
106 |   {
107 |     value: "陕西",
108 |     label: "陕西",
109 |   },
110 |   {
111 |     value: "甘肃",
112 |     label: "甘肃",
113 |   },
114 |   {
115 |     value: "青海",
116 |     label: "青海",
117 |   },
118 |   {
119 |     value: "宁夏",
120 |     label: "宁夏",
121 |   },
122 |   {
123 |     value: "新疆",
124 |     label: "新疆",
125 |   },
126 |   {
127 |     value: "香港",
128 |     label: "香港",
129 |   },
130 |   {
131 |     value: "澳门",
132 |     label: "澳门",
133 |   },
134 |   {
135 |     value: "台湾",
136 |     label: "台湾",
137 |   },
138 | ];
139 | 


--------------------------------------------------------------------------------
/music-manage/src/enums/icon.ts:
--------------------------------------------------------------------------------
1 | export const enum Icon {
2 |   BOFANG = "#icon-bofanganniu", // 播放
3 |   ZANTING = "#icon-zanting", // 暂停
4 | }
5 | 


--------------------------------------------------------------------------------
/music-manage/src/enums/index.ts:
--------------------------------------------------------------------------------
1 | import { AREA } from "./area";
2 | import { Icon } from "./icon";
3 | import { MUSICNAME } from "./music-name";
4 | import { RouterName } from "./router-name";
5 | 
6 | export { AREA, Icon, MUSICNAME, RouterName };
7 | 


--------------------------------------------------------------------------------
/music-manage/src/enums/music-name.ts:
--------------------------------------------------------------------------------
1 | export const MUSICNAME = 'Yin-music 后台管理'
2 | 


--------------------------------------------------------------------------------
/music-manage/src/enums/router-name.ts:
--------------------------------------------------------------------------------
 1 | export const enum RouterName {
 2 |   Home = "/home",
 3 |   Info = "/info",
 4 |   Song = "/song",
 5 |   Singer = "/singer",
 6 |   SongList = "/songList",
 7 |   ListSong = "/listSong",
 8 |   Comment = "/Comment",
 9 |   Consumer = "/consumer",
10 |   Collect = "/collect",
11 |   Error = "/404",
12 |   SignIn = "/",
13 |   SignOut = "0",
14 | }
15 | 


--------------------------------------------------------------------------------
/music-manage/src/main.ts:
--------------------------------------------------------------------------------
 1 | import { createApp } from "vue";
 2 | import ElementPlus from "element-plus";
 3 | import App from "./App.vue";
 4 | import router from "./router";
 5 | import store from "./store";
 6 | import "element-plus/dist/index.css";
 7 | import "./assets/css/main.css";
 8 | import "./assets/icons/iconfont.js";
 9 | 
10 | import { Store } from "vuex";
11 | declare module "@vue/runtime-core" {
12 |   interface State {
13 |     count: number;
14 |   }
15 | 
16 |   interface ComponentCustomProperties {
17 |     $store: Store<State>;
18 |   }
19 | }
20 | 
21 | createApp(App).use(store).use(router).use(ElementPlus).mount("#app");
22 | 


--------------------------------------------------------------------------------
/music-manage/src/mixins/mixin.ts:
--------------------------------------------------------------------------------
 1 | import { getCurrentInstance, ref } from "vue";
 2 | import { LocationQueryRaw } from "vue-router";
 3 | import { RouterName } from "@/enums";
 4 | 
 5 | interface routerOptions {
 6 |   path?: string;
 7 |   query?: LocationQueryRaw;
 8 | }
 9 | 
10 | export default function () {
11 |   const { proxy } = getCurrentInstance();
12 |   const uploadTypes = ref(["jpg", "jpeg", "png", "gif"]);
13 | 
14 |   function changeSex(value) {
15 |     if (value === 0) {
16 |       return "女";
17 |     } else if (value === 1) {
18 |       return "男";
19 |     } else if (value === 2) {
20 |       return "组合";
21 |     } else if (value === 3) {
22 |       return "不明";
23 |     } else if (value === "男" || value === "女") {
24 |       return value;
25 |     }
26 |   }
27 | 
28 |   function beforeImgUpload(file) {
29 |     const ltCode = 2;
30 |     const isLt2M = file.size / 1024 / 1024 < ltCode;
31 |     const isExistFileType = uploadTypes.value.includes(file.type.replace(/image\//, ""));
32 | 
33 |     if (!isExistFileType) {
34 |       (proxy as any).$message.error(`图片只支持 ${uploadTypes.value.join("、")} 格式!`);
35 |     }
36 |     if (!isLt2M) {
37 |       (proxy as any).$message.error(`上传头像图片大小不能超过 ${ltCode}MB!`);
38 |     }
39 |     
40 |     return isExistFileType && isLt2M;
41 |   }
42 | 
43 |   function beforeSongUpload(file) {
44 |     const ltCode = 10;
45 |     const isLt10M = file.size / 1024 / 1024 < ltCode;
46 |     const testmsg = file.name.substring(file.name.lastIndexOf(".") + 1);
47 |     const extension = testmsg === "mp3";
48 | 
49 |     if (!extension) {
50 |       (proxy as any).$message({
51 |         message: "上传文件只能是mp3格式!",
52 |         type: "error",
53 |       });
54 |     }
55 |     if (!isLt10M) {
56 |       (proxy as any).$message.error(`上传头像图片大小不能超过 ${ltCode}MB!`);
57 |     }
58 | 
59 |     return extension && isLt10M;
60 |   }
61 | 
62 |   // 路由管理
63 |   function routerManager(routerName: string | number, options: routerOptions) {
64 |     switch (routerName) {
65 |       case RouterName.Song:
66 |       case RouterName.ListSong:
67 |       case RouterName.Comment:
68 |       case RouterName.Consumer:
69 |       case RouterName.Collect:
70 |         proxy.$router.push({ path: options.path, query: options.query });
71 |         break;
72 |       case RouterName.Home:
73 |       case RouterName.SignIn:
74 |       case RouterName.SignOut:
75 |       case RouterName.Info:
76 |       case RouterName.Singer:
77 |       case RouterName.SongList:
78 |       case RouterName.Error:
79 |       default:
80 |         proxy.$router.push({ path: options.path });
81 |         break;
82 |     }
83 |   }
84 | 
85 |   function goBack(step = -1) {
86 |     proxy.$router.go(step);
87 |   }
88 | 
89 |   return { changeSex, routerManager, goBack, beforeImgUpload, beforeSongUpload };
90 | }
91 | 


--------------------------------------------------------------------------------
/music-manage/src/router/index.ts:
--------------------------------------------------------------------------------
 1 | import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
 2 | 
 3 | const routes: Array<RouteRecordRaw> = [
 4 |   {
 5 |     path: '/Home',
 6 |     component: () => import('@/views/Home.vue'),
 7 |     meta: { title: '自述文件' },
 8 |     children: [
 9 |       {
10 |         path: '/Info',
11 |         component: () => import('@/views/InfoPage.vue'),
12 |         meta: { title: 'Info' }
13 |       },
14 |       {
15 |         path: '/song',
16 |         component: () => import('@/views/SongPage.vue'),
17 |         meta: { title: 'Song' }
18 |       },
19 |       {
20 |         path: '/singer',
21 |         component: () => import('@/views/SingerPage.vue'),
22 |         meta: { title: 'Singer' }
23 |       },
24 |       {
25 |         path: '/SongList',
26 |         component: () => import('@/views/SongListPage.vue'),
27 |         meta: { title: 'SongList' }
28 |       },
29 |       {
30 |         path: '/ListSong',
31 |         component: () => import('@/views/ListSongPage.vue'),
32 |         meta: { title: 'ListSong' }
33 |       },
34 |       {
35 |         path: '/Comment',
36 |         component: () => import('@/views/CommentPage.vue'),
37 |         meta: { title: 'Comment' }
38 |       },
39 |       {
40 |         path: '/Consumer',
41 |         component: () => import('@/views/ConsumerPage.vue'),
42 |         meta: { title: 'Consumer' }
43 |       },
44 |       {
45 |         path: '/Collect',
46 |         component: () => import('@/views/CollectPage.vue'),
47 |         meta: { title: 'Collect' }
48 |       }
49 |     ]
50 |   },
51 |   {
52 |     path: '/',
53 |     component: () => import('@/views/Login.vue')
54 |   }
55 | ]
56 | 
57 | const router = createRouter({
58 |   history: createWebHistory(process.env.BASE_URL),
59 |   routes
60 | })
61 | 
62 | export default router
63 | 


--------------------------------------------------------------------------------
/music-manage/src/shims-vue.d.ts:
--------------------------------------------------------------------------------
 1 | /* eslint-disable */
 2 | declare module "*.vue" {
 3 |   import type { DefineComponent } from "vue";
 4 |   const component: DefineComponent<{}, {}, any>;
 5 |   export default component;
 6 | }
 7 | 
 8 | declare module "vue/types/vue" {
 9 |   import VueRouter, { Route } from "vue-router";
10 | 
11 |   interface Vue {
12 |     $router: VueRouter;
13 |     $route: Route;
14 |   }
15 | }
16 | 
17 | interface ResponseBody {
18 |   code: string;
19 |   success: boolean;
20 |   message: string;
21 |   type: string;
22 |   data?: any;
23 | }
24 | 


--------------------------------------------------------------------------------
/music-manage/src/store/index.ts:
--------------------------------------------------------------------------------
 1 | import { createStore } from 'vuex'
 2 | 
 3 | export default createStore({
 4 |   state: {
 5 |     userPic: "/img/avatorImages/user.jpg",
 6 |     isPlay: false,
 7 |     url: '',
 8 |     id: '',
 9 |     breadcrumbList: []
10 |   },
11 |   getters: {
12 |     userPic: state => state.userPic,
13 |     isPlay: state => state.isPlay,
14 |     url: state => state.url,
15 |     id: state => state.id,
16 |     breadcrumbList: state => state.breadcrumbList
17 |   },
18 |   mutations: {
19 |     setUserPic: (state, userPic) => { state.userPic = userPic },
20 |     setIsPlay: (state, isPlay) => { state.isPlay = isPlay },
21 |     setUrl: (state, url) => { state.url = url },
22 |     setId: (state, id) => { state.id = id },
23 |     setBreadcrumbList: (state, breadcrumbList) => { state.breadcrumbList = breadcrumbList }
24 |   }
25 | })


--------------------------------------------------------------------------------
/music-manage/src/utils/emitter.ts:
--------------------------------------------------------------------------------
1 | import mitt from "mitt";
2 | 
3 | const emitter = mitt();
4 | 
5 | export default emitter;
6 | 


--------------------------------------------------------------------------------
/music-manage/src/utils/index.ts:
--------------------------------------------------------------------------------
 1 | // 解析日期
 2 | export function getBirth(cellValue) {
 3 |   if (cellValue == null || cellValue == "") return "";
 4 |   const date = new Date(cellValue);
 5 |   const year = date.getFullYear();
 6 |   const month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
 7 |   const day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
 8 |   return year + "-" + month + "-" + day;
 9 | }
10 | 
11 | // 解析歌词
12 | export function parseLyric(text) {
13 |   const lines = text.split("\n");
14 |   const pattern = /\[\d{2}:\d{2}.(\d{3}|\d{2})\]/g;
15 |   const result = [];
16 | 
17 |   // 对于歌词格式不对的特殊处理
18 |   if (!/\[.+\]/.test(text)) {
19 |     return [text];
20 |   }
21 |   for (const item of lines) {
22 |     if (pattern.test(item)) {
23 |       const value = item.replace(pattern, ""); // 存歌词
24 |       result.push(value);
25 |     }
26 |   }
27 |   return result;
28 | }
29 | 


--------------------------------------------------------------------------------
/music-manage/src/views/Home.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <yin-header></yin-header>
 3 |   <yin-aside></yin-aside>
 4 |   <div class="content-box" :class="{ 'content-collapse': collapse }">
 5 |     <router-view></router-view>
 6 |   </div>
 7 |   <yin-audio></yin-audio>
 8 | </template>
 9 | 
10 | <script lang="ts" setup>
11 | import { ref } from "vue";
12 | import YinHeader from "@/components/layouts/YinHeader.vue";
13 | import YinAudio from "@/components/layouts/YinAudio.vue";
14 | import YinAside from "@/components/layouts/YinAside.vue";
15 | import emitter from "@/utils/emitter";
16 | 
17 | const collapse = ref(false);
18 | emitter.on("collapse", (msg) => {
19 |   collapse.value = msg as boolean;
20 | });
21 | </script>
22 | 
23 | <style scoped>
24 | .content-box {
25 |   position: absolute;
26 |   left: 150px;
27 |   right: 0;
28 |   top: 60px;
29 |   bottom: 0;
30 |   overflow-y: scroll;
31 |   transition: left 0.3s ease-in-out;
32 |   padding: 20px;
33 | }
34 | 
35 | .content-collapse {
36 |   left: 65px;
37 | }
38 | </style>
39 | 


--------------------------------------------------------------------------------
/music-manage/src/views/Login.vue:
--------------------------------------------------------------------------------
 1 | <template>
 2 |   <div class="login-container">
 3 |     <div class="title">{{ nusicName }}</div>
 4 |     <div class="login">
 5 |       <el-form :model="ruleForm" :rules="rules">
 6 |         <el-form-item prop="username">
 7 |           <el-input v-model="ruleForm.username" placeholder="username"></el-input>
 8 |         </el-form-item>
 9 |         <el-form-item prop="password">
10 |           <el-input type="password" placeholder="password" v-model="ruleForm.password" @keyup.enter="submitForm"></el-input>
11 |         </el-form-item>
12 |         <el-form-item>
13 |           <el-button class="login-btn" type="primary" @click="submitForm">登录</el-button>
14 |         </el-form-item>
15 |       </el-form>
16 |     </div>
17 |   </div>
18 | </template>
19 | 
20 | <script lang="ts">
21 | import { defineComponent, getCurrentInstance, ref, reactive } from "vue";
22 | import mixin from "@/mixins/mixin";
23 | import { HttpManager } from "@/api/index";
24 | import { RouterName, MUSICNAME } from "@/enums";
25 | 
26 | export default defineComponent({
27 |   setup() {
28 |     const { proxy } = getCurrentInstance();
29 |     const { routerManager } = mixin();
30 | 
31 |     const nusicName = ref(MUSICNAME);
32 |     const ruleForm = reactive({
33 |       username: "admin",
34 |       password: "123",
35 |     });
36 |     const rules = reactive({
37 |       username: [{ required: true, message: "请输入用户名", trigger: "blur" }],
38 |       password: [{ required: true, message: "请输入密码", trigger: "blur" }],
39 |     });
40 |     async function submitForm() {
41 |       let username = ruleForm.username;
42 |       let password = ruleForm.password;
43 |       const result = (await HttpManager.getLoginStatus({username,password})) as ResponseBody;
44 |       (proxy as any).$message({
45 |         message: result.message,
46 |         type: result.type,
47 |       });
48 | 
49 |       if (result.success) routerManager(RouterName.Info, { path: RouterName.Info });
50 |     }
51 |     return {
52 |       nusicName,
53 |       ruleForm,
54 |       rules,
55 |       submitForm,
56 |     };
57 |   },
58 | });
59 | </script>
60 | 
61 | <style scoped>
62 | .login-container {
63 |   position: relative;
64 |   background: url("../assets/images/background.jpg");
65 |   background-attachment: fixed;
66 |   background-position: center;
67 |   background-size: cover;
68 |   width: 100%;
69 |   height: 100%;
70 | }
71 | 
72 | .title {
73 |   position: absolute;
74 |   top: 50%;
75 |   width: 100%;
76 |   margin-top: -230px;
77 |   text-align: center;
78 |   font-size: 30px;
79 |   font-weight: 600;
80 |   color: #fff;
81 | }
82 | 
83 | .login {
84 |   position: absolute;
85 |   left: 50%;
86 |   top: 50%;
87 |   width: 300px;
88 |   margin: -150px 0 0 -190px;
89 |   padding: 40px;
90 |   border-radius: 5px;
91 |   background: #fff;
92 | }
93 | 
94 | .login-btn {
95 |   width: 100%;
96 | }
97 | </style>
98 | 


--------------------------------------------------------------------------------
/music-manage/tsconfig.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "compilerOptions": {
 3 |     "target": "esnext",
 4 |     "module": "esnext",
 5 |     "strict": true,
 6 |     "jsx": "preserve",
 7 |     "moduleResolution": "node",
 8 |     "skipLibCheck": true,
 9 |     "esModuleInterop": true,
10 |     "allowSyntheticDefaultImports": true,
11 |     "forceConsistentCasingInFileNames": true,
12 |     "useDefineForClassFields": true,
13 |     "sourceMap": true,
14 |     "noImplicitAny": false,
15 |     "strictNullChecks": false,
16 |     "baseUrl": ".",
17 |     "types": [
18 |       "webpack-env"
19 |     ],
20 |     "paths": {
21 |       "@/*": [
22 |         "src/*"
23 |       ]
24 |     },
25 |     "lib": [
26 |       "esnext",
27 |       "dom",
28 |       "dom.iterable",
29 |       "scripthost"
30 |     ]
31 |   },
32 |   "include": [
33 |     "src/**/*.ts",
34 |     "src/**/*.tsx",
35 |     "src/**/*.vue",
36 |     "tests/**/*.ts",
37 |     "tests/**/*.tsx"
38 |   ],
39 |   "exclude": [
40 |     "node_modules"
41 |   ]
42 | }
43 | 


--------------------------------------------------------------------------------
/music-manage/vue.config.js:
--------------------------------------------------------------------------------
 1 | const { defineConfig } = require('@vue/cli-service')
 2 | 
 3 | module.exports = defineConfig({
 4 |   transpileDependencies: true,
 5 |   chainWebpack: config => {
 6 |     config.plugin('define').tap(definitions => {
 7 |       Object.assign(definitions[0]['process.env'], {
 8 |         NODE_HOST: '"http://localhost:8888"',
 9 |       });
10 |       return definitions;
11 |     });
12 |   }
13 | })
14 | 


--------------------------------------------------------------------------------
/music-server/.gitignore:
--------------------------------------------------------------------------------
 1 | /target/
 2 | !.mvn/wrapper/maven-wrapper.jar
 3 | 
 4 | ### STS ###
 5 | .apt_generated
 6 | .classpath
 7 | .factorypath
 8 | .project
 9 | .settings
10 | .springBeans
11 | .sts4-cache
12 | target/
13 | .DS_Store
14 | ../img/
15 | ../song/
16 | img/
17 | song/
18 | logs/
19 | 
20 | ### IntelliJ IDEA ###
21 | .idea
22 | *.iws
23 | *.iml
24 | *.ipr
25 | 
26 | ### NetBeans ###
27 | /nbproject/private/
28 | /build/
29 | /nbbuild/
30 | /dist/
31 | /nbdist/
32 | /.nb-gradle/
33 | 


--------------------------------------------------------------------------------
/music-server/Dockerfile:
--------------------------------------------------------------------------------
 1 | FROM maven:3-openjdk-8-slim AS builder
 2 | WORKDIR /app
 3 | 
 4 | COPY pom.xml ./
 5 | RUN mvn dependency:resolve -DskipTests -B
 6 | 
 7 | COPY src ./src
 8 | RUN mvn clean package -DskipTests -B -T 1C
 9 | 
10 | FROM openjdk:8-jre-alpine
11 | WORKDIR /app
12 | COPY --from=builder /app/target/yin-0.0.1-SNAPSHOT.jar /app/yin-0.0.1-SNAPSHOT.jar
13 | ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app/yin-0.0.1-SNAPSHOT.jar","--spring.config.location=/config/application-prod.yml"]
14 | EXPOSE 8888


--------------------------------------------------------------------------------
/music-server/docker-server/docker-compose.yml:
--------------------------------------------------------------------------------
 1 | version: '3'
 2 | services:
 3 |   web:
 4 |     build: .
 5 |     ports:
 6 |       - "8888:8888"
 7 |     depends_on:
 8 |       - db
 9 |   db:
10 |     image: mysql:8.0
11 |     environment:
12 |       MYSQL_ROOT_PASSWORD: 123456
13 |       MYSQL_DATABASE: tp_music
14 |       MYSQL_USER: myuser
15 |       MYSQL_PASSWORD: 123456


--------------------------------------------------------------------------------
/music-server/docker-server/dockerfile:
--------------------------------------------------------------------------------
1 | # 使用官方的Java基础镜像
2 | FROM openjdk:8-jdk-alpine
3 | # 将本地的jar文件复制到容器中
4 | COPY yin-0.0.1-SNAPSHOT.jar yin-0.0.1-SNAPSHOT.jar
5 | # 暴露端口
6 | EXPOSE 8888
7 | # 运行命令
8 | ENTRYPOINT ["java", "-jar", "/yin-0.0.1-SNAPSHOT.jar"]
9 | 


--------------------------------------------------------------------------------
/music-server/docker-vue-client/dockerfile:
--------------------------------------------------------------------------------
 1 | # 使用官方的Node.js基础镜像作为基础镜像
 2 | FROM node:14
 3 | # 设置工作目录
 4 | WORKDIR /appClient
 5 | # 将package.json和package-lock.json复制到工作目录
 6 | COPY package*.json ./
 7 | # 安装依赖
 8 | RUN npm install
 9 | # 将前端项目(通常是dist文件夹)复制到工作目录,记住要提前将vue打包成dist文件夹
10 | COPY dist /appClient/dist
11 | # 暴露端口
12 | EXPOSE 8080
13 | # 运行命令
14 | CMD ["npm", "start"]
15 | 


--------------------------------------------------------------------------------
/music-server/docker-vue-manage/dockerfile:
--------------------------------------------------------------------------------
 1 | # 使用官方的Node.js基础镜像作为基础镜像
 2 | FROM node:14
 3 | # 设置工作目录
 4 | WORKDIR /appManage
 5 | # 将package.json和package-lock.json复制到工作目录
 6 | COPY package*.json ./
 7 | # 安装依赖
 8 | RUN npm install
 9 | # 将前端项目(通常是dist文件夹)复制到工作目录,记住要提前将vue打包成dist文件夹
10 | COPY dist /appManage/dist
11 | # 暴露端口
12 | EXPOSE 8081
13 | # 运行命令
14 | CMD ["npm", "start"]
15 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/YinMusicApplication.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin;
 2 | 
 3 | import org.mybatis.spring.annotation.MapperScan;
 4 | import org.springframework.boot.SpringApplication;
 5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
 6 | 
 7 | import static com.example.yin.constant.Constants.ASSETS_PATH;
 8 | 
 9 | @SpringBootApplication
10 | @MapperScan("com.example.yin.mapper")
11 | public class YinMusicApplication {
12 | 
13 |     public static void main(String[] args) {
14 |         SpringApplication.run(YinMusicApplication.class, args);
15 |     }
16 | 
17 | }
18 | 
19 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/common/R.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.common;
 2 | 
 3 | import lombok.Data;
 4 | 
 5 | /**
 6 |  * @Author 祝英台炸油条
 7 |  * @Time : 2022/6/4 19:04
 8 |  **/
 9 | @Data
10 | public class R {
11 | 
12 |     private int code;
13 | 
14 |     private String message;
15 | 
16 |     private String type;
17 | 
18 |     private Boolean success;
19 | 
20 |     private Object data;
21 | 
22 |     public static R success(String message) {
23 |         R r = new R();
24 |         r.setCode(200);
25 |         r.setMessage(message);
26 |         r.setSuccess(true);
27 |         r.setType("success");
28 |         r.setData(null);
29 |         return r;
30 |     }
31 | 
32 |     public static R success(String message, Object data) {
33 |         R r = success(message);
34 |         r.setData(data);
35 |         return r;
36 |     }
37 | 
38 |     public static R warning(String message) {
39 |         R r = error(message);
40 |         r.setType("warning");
41 |         return r;
42 |     }
43 | 
44 |     public static R error(String message) {
45 |         R r = success(message);
46 |         r.setSuccess(false);
47 |         r.setType("error");
48 |         return r;
49 |     }
50 | 
51 |     public static R fatal(String message) {
52 |         R r = error(message);
53 |         r.setCode(500);
54 |         return r;
55 |     }
56 | }
57 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/config/CorsInterceptor.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.config;
 2 | 
 3 | import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
 4 | 
 5 | import javax.servlet.http.HttpServletRequest;
 6 | import javax.servlet.http.HttpServletResponse;
 7 | 
 8 | 
 9 | public class CorsInterceptor extends HandlerInterceptorAdapter {
10 | 
11 |     @Override
12 |     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
13 |         response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
14 |         response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
15 |         response.setHeader("Access-Control-Max-Age", "3600");
16 |         response.setHeader("Access-Control-Allow-Headers", "x_requested_with,x-requested-with,Authorization,Content-Type,token");
17 |         response.setHeader("Access-Control-Allow-Credentials", "true");
18 |         return true;
19 |     }
20 | }
21 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/config/MinioConfig.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.config;
 2 | 
 3 | import io.minio.MinioClient;
 4 | import org.springframework.beans.factory.annotation.Value;
 5 | import org.springframework.context.annotation.Bean;
 6 | import org.springframework.context.annotation.Configuration;
 7 | 
 8 | @Configuration
 9 | public class MinioConfig {
10 | 
11 |     @Value("${minio.endpoint}")
12 |     private String minioEndpoint;
13 | 
14 |     @Value("${minio.access-key}")
15 |     private String minioAccessKey;
16 | 
17 |     @Value("${minio.secret-key}")
18 |     private String minioSecretKey;
19 | 
20 |     @Bean
21 |     public MinioClient minioClient() {
22 |         return MinioClient.builder()
23 |                 .endpoint(minioEndpoint)
24 |                 .credentials(minioAccessKey, minioSecretKey)
25 |                 .build();
26 |     }
27 | }
28 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/config/WebCharacterEncodingFilter.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.config;
 2 | 
 3 | import org.springframework.context.annotation.Configuration;
 4 | import org.springframework.http.converter.HttpMessageConverter;
 5 | import org.springframework.http.converter.StringHttpMessageConverter;
 6 | import org.springframework.web.servlet.config.annotation.CorsRegistry;
 7 | import org.springframework.web.servlet.config.annotation.EnableWebMvc;
 8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 9 | 
10 | import java.nio.charset.StandardCharsets;
11 | import java.util.List;
12 | 
13 | /**
14 |  * 说明:解决以下问题
15 |  * <p>
16 |  *     因使用WebMvcConfigurer加载静态时 url encode编码无法解析为正常中文问题
17 |  * </p>
18 |  *
19 |  */
20 | 
21 | @EnableWebMvc
22 | @Configuration
23 | public class WebCharacterEncodingFilter implements WebMvcConfigurer {
24 | 
25 |     /**
26 |      * 乱码处理
27 |      */
28 |     public HttpMessageConverter<String> responseBodyConverter() {
29 |         final StringHttpMessageConverter converter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
30 |         converter.setWriteAcceptCharset(false);
31 |         return converter;
32 |     }
33 | 
34 |     @Override
35 |     public void addCorsMappings(CorsRegistry registry) {
36 |         registry.addMapping("/**").allowedOrigins("*").allowedMethods("*").allowedHeaders("*");
37 |     }
38 | 
39 |     @Override
40 |     public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
41 |         if (!converters.isEmpty()) {
42 |             converters.add(converters.get(0));
43 |             converters.set(0, responseBodyConverter());
44 |         } else {
45 |             converters.add(responseBodyConverter());
46 |         }
47 |     }
48 | }
49 | 
50 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/config/WebMvcConfig.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.config;
 2 | 
 3 | import org.springframework.context.annotation.Bean;
 4 | import org.springframework.context.annotation.Configuration;
 5 | import org.springframework.web.servlet.config.annotation.CorsRegistry;
 6 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 8 | 
 9 | /**
10 |  * @Author 祝英台炸油条
11 |  * @Time : 2022/6/7 17:08
12 |  **/
13 | @Configuration
14 | public class WebMvcConfig implements WebMvcConfigurer {
15 | 
16 |     @Bean
17 |     public CorsInterceptor corsInterceptor() {
18 |         return new CorsInterceptor();
19 |     }
20 | 
21 |     @Override
22 |     public void addInterceptors(InterceptorRegistry registry) {
23 |         registry.addInterceptor(corsInterceptor())
24 |                 .addPathPatterns("/**");
25 |     }
26 | 
27 | }


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/config/WebPicConfig.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.config;
 2 | 
 3 | import com.example.yin.constant.Constants;
 4 | import org.springframework.context.annotation.Configuration;
 5 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
 6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 7 | 
 8 | /**
 9 |  * 集中一下图像的配置类吧
10 |  *
11 |  * @Author 祝英台炸油条
12 |  * @Time : 2022/6/5 22:23
13 |  **/
14 | @Configuration
15 | public class WebPicConfig implements WebMvcConfigurer {
16 | 
17 |     //TODO 这个配置类的目的是什么  就是注册了一个类似于拦截器吧  看到对应的资源 会将其修改成相应的地址
18 |     @Override
19 |     public void addResourceHandlers(ResourceHandlerRegistry registry) {
20 |         registry.addResourceHandler("/img/avatorImages/**")
21 |                 .addResourceLocations(Constants.AVATOR_IMAGES_PATH);
22 |         registry.addResourceHandler("/img/singerPic/**")
23 |                 .addResourceLocations(Constants.SINGER_PIC_PATH);
24 |         registry.addResourceHandler("/img/songPic/**")
25 |                 .addResourceLocations(Constants.SONG_PIC_PATH);
26 |         registry.addResourceHandler("/song/**")
27 |                 .addResourceLocations(Constants.SONG_PATH);
28 |         registry.addResourceHandler("/img/songListPic/**")
29 |                 .addResourceLocations(Constants.SONGLIST_PIC_PATH);
30 |         registry.addResourceHandler("/img/swiper/**")
31 |                 .addResourceLocations(Constants.BANNER_PIC_PATH);
32 |     }
33 | 
34 | }
35 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/constant/Constants.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.constant;
 2 | 
 3 | public class Constants {
 4 |     /* 歌曲图片,歌手图片,歌曲文件,歌单图片等文件的存放路径 */
 5 |     public static String ASSETS_PATH = System.getProperty("user.dir");
 6 |     
 7 |     public static String AVATOR_IMAGES_PATH = "file:" + ASSETS_PATH + "/img/avatorImages/";
 8 |     public static String SONGLIST_PIC_PATH = "file:" + ASSETS_PATH + "/img/songListPic/";
 9 |     public static String SONG_PIC_PATH = "file:" + ASSETS_PATH + "/img/songPic/";
10 |     public static String SONG_PATH = "file:" + ASSETS_PATH + "/song/";
11 |     public static String SINGER_PIC_PATH = "file:" + ASSETS_PATH + "/img/singerPic/";
12 |     public static String BANNER_PIC_PATH = "file:" + ASSETS_PATH + "/img/swiper/";
13 | 
14 |     /* 盐值加密 */
15 |     public static String SALT = "zyt";
16 | }
17 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/controller/AdminController.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.controller;
 2 | 
 3 | import com.example.yin.common.R;
 4 | import com.example.yin.model.request.AdminRequest;
 5 | import com.example.yin.service.AdminService;
 6 | import org.springframework.beans.factory.annotation.Autowired;
 7 | import org.springframework.web.bind.annotation.PostMapping;
 8 | import org.springframework.web.bind.annotation.RequestBody;
 9 | import org.springframework.web.bind.annotation.RestController;
10 | 
11 | import javax.servlet.http.HttpSession;
12 | 
13 | /**
14 |  * 后台管理的相关事宜
15 |  */
16 | @RestController
17 | public class AdminController {
18 |     @Autowired
19 |     private AdminService adminService;
20 | 
21 |     // 判断是否登录成功
22 |     @PostMapping("/admin/login/status")
23 |     public R loginStatus(@RequestBody AdminRequest adminRequest, HttpSession session) {
24 |         return adminService.verityPasswd(adminRequest, session);
25 |     }
26 | }
27 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/controller/BannerController.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.controller;
 2 | 
 3 | import com.example.yin.common.R;
 4 | import com.example.yin.service.BannerService;
 5 | import org.springframework.beans.factory.annotation.Autowired;
 6 | import org.springframework.web.bind.annotation.GetMapping;
 7 | import org.springframework.web.bind.annotation.RequestMapping;
 8 | import org.springframework.web.bind.annotation.RestController;
 9 | 
10 | /**
11 |  * @Author 祝英台炸油条
12 |  * @Time : 2022/6/13 13:16
13 |  **/
14 | @RestController
15 | @RequestMapping("/banner")
16 | public class BannerController {
17 | 
18 |     @Autowired
19 |     private BannerService bannerService;
20 | 
21 |     @GetMapping("/getAllBanner")
22 |     public R getAllBanner(){
23 |         return R.success("成功获取轮播图与",bannerService.getAllBanner());
24 |     }
25 | }
26 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/controller/CollectController.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.controller;
 2 | 
 3 | import com.example.yin.common.R;
 4 | import com.example.yin.model.request.CollectRequest;
 5 | import com.example.yin.service.CollectService;
 6 | import org.springframework.beans.factory.annotation.Autowired;
 7 | import org.springframework.web.bind.annotation.*;
 8 | 
 9 | @RestController
10 | public class CollectController {
11 | 
12 |     @Autowired
13 |     private CollectService collectService;
14 | 
15 | 
16 |     // 添加收藏的歌曲
17 |     //前台界面逻辑
18 |     @PostMapping("/collection/add")
19 |     public R addCollection(@RequestBody CollectRequest addCollectRequest) {
20 |         return collectService.addCollection(addCollectRequest);
21 |     }
22 | 
23 |     //TODO  这些其实有点偏简单的逻辑  所以就一点 所以放在外面  拿到里面
24 |     // 取消收藏的歌曲
25 |     @DeleteMapping("/collection/delete")
26 |     public R deleteCollection(@RequestParam Integer userId, @RequestParam Integer songId) {
27 |         return collectService.deleteCollect(userId, songId);
28 |     }
29 | 
30 |     // 是否收藏歌曲
31 |     @PostMapping("/collection/status")
32 |     public R isCollection(@RequestBody CollectRequest isCollectRequest) {
33 |         return collectService.existSongId(isCollectRequest);
34 | 
35 |     }
36 | 
37 |     // 返回的指定用户 ID 收藏的列表
38 |     @GetMapping("/collection/detail")
39 |     public R collectionOfUser(@RequestParam Integer userId) {
40 |         return collectService.collectionOfUser(userId);
41 |     }
42 | }
43 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/controller/CommentController.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.controller;
 2 | 
 3 | import com.example.yin.common.R;
 4 | import com.example.yin.model.request.CommentRequest;
 5 | import com.example.yin.service.CommentService;
 6 | import org.springframework.beans.factory.annotation.Autowired;
 7 | import org.springframework.web.bind.annotation.*;
 8 | 
 9 | @RestController
10 | public class CommentController {
11 |     @Autowired
12 |     private CommentService commentService;
13 | 
14 | 
15 |     // 提交评论
16 |     @PostMapping("/comment/add")
17 |     public R addComment(@RequestBody CommentRequest addCommentRequest) {
18 |         return commentService.addComment(addCommentRequest);
19 |     }
20 | 
21 |     // 删除评论
22 |     @GetMapping("/comment/delete")
23 |     public R deleteComment(@RequestParam Integer id) {
24 |         return commentService.deleteComment(id);
25 |     }
26 | 
27 |     // 获得指定歌曲 ID 的评论列表
28 |     @GetMapping("/comment/song/detail")
29 |     public R commentOfSongId(@RequestParam Integer songId) {
30 |         return commentService.commentOfSongId(songId);
31 |     }
32 | 
33 |     // 获得指定歌单 ID 的评论列表
34 |     @GetMapping("/comment/songList/detail")
35 |     public R commentOfSongListId(@RequestParam Integer songListId) {
36 |         return commentService.commentOfSongListId(songListId);
37 |     }
38 | 
39 |     // 点赞
40 |     @PostMapping("/comment/like")
41 |     public R commentOfLike(@RequestBody CommentRequest upCommentRequest) {
42 |         return commentService.updateCommentMsg(upCommentRequest);
43 |     }
44 | }
45 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/controller/FileDownloadController.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.controller;
 2 | 
 3 | import com.alibaba.excel.EasyExcel;
 4 | import com.alibaba.excel.util.ListUtils;
 5 | import com.example.yin.model.domain.SongList;
 6 | import com.example.yin.service.SongListService;
 7 | import com.example.yin.utils.TestFileUtil;
 8 | import io.minio.GetObjectArgs;
 9 | import io.minio.MinioClient;
10 | import io.minio.errors.*;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.beans.factory.annotation.Value;
13 | import org.springframework.core.io.ByteArrayResource;
14 | import org.springframework.core.io.Resource;
15 | import org.springframework.http.HttpHeaders;
16 | import org.springframework.http.MediaType;
17 | import org.springframework.http.ResponseEntity;
18 | import org.springframework.stereotype.Controller;
19 | import org.springframework.web.bind.annotation.GetMapping;
20 | import org.springframework.web.bind.annotation.PathVariable;
21 | import org.springframework.web.bind.annotation.RequestMapping;
22 | 
23 | import javax.servlet.http.HttpServletRequest;
24 | import java.io.ByteArrayOutputStream;
25 | import java.io.File;
26 | import java.io.IOException;
27 | import java.io.InputStream;
28 | import java.nio.file.Files;
29 | import java.security.InvalidKeyException;
30 | import java.security.NoSuchAlgorithmException;
31 | import java.util.List;
32 | 
33 | @Controller
34 | @RequestMapping("/download")
35 | public class FileDownloadController {
36 | 
37 |     @Autowired
38 |     private MinioClient minioClient;
39 |     @Value("${minio.bucket-name}")
40 |     private String bucketName;
41 | 
42 |     @GetMapping("/{fileName}")
43 |     public ResponseEntity<Resource> downloadFile(@PathVariable String fileName, HttpServletRequest request) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
44 | 
45 |         GetObjectArgs args = GetObjectArgs.builder()
46 |                 .bucket(bucketName)
47 |                 .object(fileName)
48 |                 .build();
49 |         InputStream inputStream = minioClient.getObject(args);
50 | 
51 |         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
52 |         byte[] buffer = new byte[1024];
53 |         int bytesRead;
54 |         while ((bytesRead = inputStream.read(buffer)) != -1) {
55 |             outputStream.write(buffer, 0, bytesRead);
56 |         }
57 |         byte[] musicBytes = outputStream.toByteArray();
58 |         // 创建一个ByteArrayResource对象,用于包装字节数组
59 |         ByteArrayResource resource = new ByteArrayResource(musicBytes);
60 |         // 构建响应头
61 |         HttpHeaders headers = new HttpHeaders();
62 |         headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);
63 |         // 返回一个 ResponseEntity 对象
64 |         return ResponseEntity.ok()
65 |                 .headers(headers)
66 |                 .contentLength(musicBytes.length)
67 |                 .contentType(MediaType.APPLICATION_OCTET_STREAM)
68 |                 .body(resource);
69 |     }
70 |  }
71 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/controller/ListSongController.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.controller;
 2 | 
 3 | import com.alibaba.excel.EasyExcel;
 4 | import com.example.yin.common.R;
 5 | import com.example.yin.model.domain.SongList;
 6 | import com.example.yin.model.request.ListSongRequest;
 7 | import com.example.yin.service.ListSongService;
 8 | import com.example.yin.service.SongListService;
 9 | import com.example.yin.utils.TestFileUtil;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.core.io.InputStreamResource;
12 | import org.springframework.core.io.Resource;
13 | import org.springframework.http.HttpHeaders;
14 | import org.springframework.http.MediaType;
15 | import org.springframework.http.ResponseEntity;
16 | import org.springframework.web.bind.annotation.*;
17 | 
18 | import javax.servlet.http.HttpServletRequest;
19 | import java.io.File;
20 | import java.io.FileInputStream;
21 | import java.io.IOException;
22 | import java.nio.file.Files;
23 | import java.util.List;
24 | 
25 | @RestController
26 | public class ListSongController {
27 | 
28 |     @Autowired
29 |     private ListSongService listSongService;
30 |     @Autowired
31 |     private SongListService service;
32 |     // 给歌单添加歌曲
33 |     @PostMapping("/listSong/add")
34 |     public R addListSong(@RequestBody ListSongRequest addListSongRequest) {
35 |         return listSongService.addListSong(addListSongRequest);
36 |     }
37 | 
38 |     // 删除歌单里的歌曲
39 |     @GetMapping("/listSong/delete")
40 |     public R deleteListSong(@RequestParam int songId) {
41 |         return listSongService.deleteListSong(songId);
42 |     }
43 | 
44 |     // 返回歌单里指定歌单 ID 的歌曲
45 |     @GetMapping("/listSong/detail")
46 |     public R listSongOfSongId(@RequestParam int songListId) {
47 |         return listSongService.listSongOfSongId(songListId);
48 |     }
49 | 
50 |     // 更新歌单里面的歌曲信息
51 |     @PostMapping("/listSong/update")
52 |     public R updateListSongMsg(@RequestBody ListSongRequest updateListSongRequest) {
53 |         return listSongService.updateListSongMsg(updateListSongRequest);
54 |     }
55 |     //导出歌单
56 |     @GetMapping("/excle")
57 |     public ResponseEntity<Resource> getExcle(HttpServletRequest request) throws IOException {
58 |         String fileName = "SongList" + System.currentTimeMillis() + ".xlsx";
59 |         EasyExcel.write(fileName, SongList.class).sheet("模板").doWrite(data());
60 |         File file = new File(fileName);
61 |         HttpHeaders headers = new HttpHeaders();
62 |         headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);
63 | 
64 |         byte[] content = Files.readAllBytes(file.toPath());
65 |         InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
66 | 
67 |         return ResponseEntity.ok()
68 |                 .headers(headers)
69 |                 .contentLength(content.length)
70 |                 .contentType(MediaType.APPLICATION_OCTET_STREAM)
71 |                 .body(resource);
72 |     }
73 |     private List<SongList> data() {
74 |         List<SongList> allSong = service.findAllSong();
75 |         return allSong;
76 |     }
77 | 
78 | }
79 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/controller/RankListController.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.controller;
 2 | 
 3 | import com.example.yin.common.R;
 4 | import com.example.yin.model.request.RankListRequest;
 5 | import com.example.yin.service.RankListService;
 6 | import org.springframework.beans.factory.annotation.Autowired;
 7 | import org.springframework.web.bind.annotation.*;
 8 | 
 9 | @RestController
10 | public class RankListController {
11 | 
12 |     @Autowired
13 |     private RankListService rankListService;
14 | 
15 | 
16 |     // 提交评分
17 |     @PostMapping("/rankList/add")
18 |     public R addRank(@RequestBody RankListRequest rankListAddRequest) {
19 |         return rankListService.addRank(rankListAddRequest);
20 |     }
21 | 
22 |     // 获取指定歌单的评分
23 |     @GetMapping("/rankList")
24 |     public R rankOfSongListId(@RequestParam Long songListId) {
25 |         return rankListService.rankOfSongListId(songListId);
26 |     }
27 | 
28 |     // 获取指定用户的歌单评分
29 |     @GetMapping("/rankList/user")
30 |     public R getUserRank(@RequestParam(required = false) Long consumerId, @RequestParam Long songListId) {
31 |         R userRank = rankListService.getUserRank(consumerId, songListId);
32 |         return R.success("成功",userRank);
33 |     }
34 | 
35 | 
36 | }
37 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/controller/SingerController.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.controller;
 2 | 
 3 | import com.example.yin.common.R;
 4 | import com.example.yin.model.request.SingerRequest;
 5 | import com.example.yin.service.SingerService;
 6 | import org.springframework.beans.factory.annotation.Autowired;
 7 | import org.springframework.web.bind.annotation.*;
 8 | import org.springframework.web.multipart.MultipartFile;
 9 | 
10 | @RestController
11 | public class SingerController {
12 | 
13 |     @Autowired
14 |     private SingerService singerService;
15 | 
16 | 
17 |     // 添加歌手
18 |     @PostMapping("/singer/add")
19 |     public R addSinger(@RequestBody SingerRequest addSingerRequest) {
20 |         return singerService.addSinger(addSingerRequest);
21 |     }
22 | 
23 |     // 删除歌手
24 |     @DeleteMapping("/singer/delete")
25 |     public R deleteSinger(@RequestParam int id) {
26 |         return singerService.deleteSinger(id);
27 |     }
28 | 
29 |     // 返回所有歌手
30 |     @GetMapping("/singer")
31 |     public R allSinger() {
32 |         return singerService.allSinger();
33 |     }
34 | 
35 |     // 根据歌手名查找歌手
36 |     @GetMapping("/singer/name/detail")
37 |     public R singerOfName(@RequestParam String name) {
38 |         return singerService.singerOfName(name);
39 |     }
40 | 
41 |     // 根据歌手性别查找歌手
42 |     @GetMapping("/singer/sex/detail")
43 |     public R singerOfSex(@RequestParam int sex) {
44 |         return singerService.singerOfSex(sex);
45 |     }
46 | 
47 |     // 更新歌手信息
48 |     @PostMapping("/singer/update")
49 |     public R updateSingerMsg(@RequestBody SingerRequest updateSingerRequest) {
50 |         return singerService.updateSingerMsg(updateSingerRequest);
51 |     }
52 | 
53 |     // 更新歌手头像
54 |     @PostMapping("/singer/avatar/update")
55 |     public R updateSingerPic(@RequestParam("file") MultipartFile avatorFile, @RequestParam("id") int id) {
56 |         return singerService.updateSingerPic(avatorFile, id);
57 |     }
58 | }
59 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/controller/SongListController.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.controller;
 2 | 
 3 | import com.example.yin.common.R;
 4 | import com.example.yin.model.request.SongListRequest;
 5 | import com.example.yin.service.SongListService;
 6 | import org.springframework.beans.factory.annotation.Autowired;
 7 | import org.springframework.web.bind.annotation.*;
 8 | import org.springframework.web.multipart.MultipartFile;
 9 | 
10 | @RestController
11 | public class SongListController {
12 | 
13 |     @Autowired
14 |     private SongListService songListService;
15 | 
16 | 
17 |     // 添加歌单
18 |     @PostMapping("/songList/add")
19 |     public R addSongList(@RequestBody SongListRequest addSongListRequest) {
20 |         return songListService.addSongList(addSongListRequest);
21 |     }
22 | 
23 |     // 删除歌单
24 |     @GetMapping("/songList/delete")
25 |     public R deleteSongList(@RequestParam int id) {
26 |         return songListService.deleteSongList(id);
27 |     }
28 | 
29 |     //TODO 这块就是前端显现相应的歌单list
30 |     // 返回所有歌单
31 |     @GetMapping("/songList")
32 |     public R allSongList() {
33 |         return songListService.allSongList();
34 |     }
35 | 
36 |     // 返回标题包含文字的歌单
37 |     @GetMapping("/songList/likeTitle/detail")
38 |     public R songListOfLikeTitle(@RequestParam String title) {
39 |         return songListService.likeTitle('%' + title + '%');
40 |     }
41 | 
42 |     // 返回指定类型的歌单
43 |     @GetMapping("/songList/style/detail")
44 |     public R songListOfStyle(@RequestParam String style) {
45 |         return songListService.likeStyle('%' + style + '%');
46 |     }
47 | 
48 |     // 更新歌单信息
49 |     @PostMapping("/songList/update")
50 |     public R updateSongListMsg(@RequestBody SongListRequest updateSongListRequest) {
51 |         return songListService.updateSongListMsg(updateSongListRequest);
52 | 
53 |     }
54 | 
55 |     // 更新歌单图片
56 |     @PostMapping("/songList/img/update")
57 |     public R updateSongListPic(@RequestParam("file") MultipartFile avatorFile, @RequestParam("id") int id) {
58 | 
59 |         return songListService.updateSongListImg(avatorFile,id);
60 |     }
61 | }
62 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/controller/UserSupportController.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.controller;
 2 | 
 3 | import com.example.yin.common.R;
 4 | import com.example.yin.model.request.UserSupportRequest;
 5 | import com.example.yin.service.UserSupportService;
 6 | import org.springframework.beans.factory.annotation.Autowired;
 7 | import org.springframework.web.bind.annotation.PostMapping;
 8 | import org.springframework.web.bind.annotation.RequestBody;
 9 | import org.springframework.web.bind.annotation.RequestMapping;
10 | import org.springframework.web.bind.annotation.RestController;
11 | 
12 | /**
13 |  * @Author 祝英台炸油条
14 |  * @Time : 2022/6/11 16:07
15 |  **/
16 | @RestController
17 | @RequestMapping("/userSupport")
18 | public class UserSupportController {
19 | 
20 |     @Autowired
21 |     UserSupportService userSupportService;
22 | 
23 |     @PostMapping("/test")
24 |     public R isUserSupportComment(@RequestBody UserSupportRequest userSupportRequest) {
25 |         return userSupportService.isUserSupportComment(userSupportRequest);
26 |     }
27 | 
28 |     @PostMapping("/insert")
29 |     public R insertCommentSupport(@RequestBody UserSupportRequest userSupportRequest) {
30 |         return userSupportService.insertCommentSupport(userSupportRequest);
31 |     }
32 | 
33 |     @PostMapping("/delete")
34 |     public R deleteCommentSupport(@RequestBody UserSupportRequest userSupportRequest) {
35 |         return userSupportService.deleteCommentSupport(userSupportRequest);
36 |     }
37 | }
38 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/handler/MyMetaObjectHandler.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.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.util.Date;
 8 | 
 9 | @Component
10 | public class MyMetaObjectHandler implements MetaObjectHandler {
11 |     @Override
12 |     public void insertFill(MetaObject metaObject) {
13 |         this.setFieldValByName("createTime", new Date(), metaObject);
14 |         this.setFieldValByName("updateTime", new Date(), metaObject);
15 |     }
16 | 
17 |     @Override
18 |     public void updateFill(MetaObject metaObject) {
19 |         this.setFieldValByName("updateTime", new Date(), metaObject);
20 |     }
21 | }
22 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/mapper/AdminMapper.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.mapper;
 2 | 
 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 4 | import com.example.yin.model.domain.Admin;
 5 | import org.springframework.stereotype.Repository;
 6 | 
 7 | @Repository
 8 | public interface AdminMapper extends BaseMapper<Admin> {
 9 | 
10 | }
11 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/mapper/BannerMapper.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.mapper;
 2 | 
 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 4 | import com.example.yin.model.domain.Banner;
 5 | 
 6 | /**
 7 | * @author asus
 8 | * @description 针对表【banner】的数据库操作Mapper
 9 | * @createDate 2022-06-13 13:13:42
10 | * @Entity generator.domain.Banner
11 | */
12 | public interface BannerMapper extends BaseMapper<Banner> {
13 | 
14 | 
15 | }
16 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/mapper/CollectMapper.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.mapper;
 2 | 
 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 4 | import com.example.yin.model.domain.Collect;
 5 | import org.springframework.stereotype.Repository;
 6 | 
 7 | @Repository
 8 | public interface CollectMapper extends BaseMapper<Collect> {
 9 | 
10 | }
11 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/mapper/CommentMapper.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.mapper;
 2 | 
 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 4 | import com.example.yin.model.domain.Comment;
 5 | import org.springframework.stereotype.Repository;
 6 | 
 7 | @Repository
 8 | public interface CommentMapper extends BaseMapper<Comment> {
 9 | 
10 | }
11 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/mapper/ConsumerMapper.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.mapper;
 2 | 
 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 4 | import com.example.yin.model.domain.Consumer;
 5 | import org.springframework.stereotype.Repository;
 6 | 
 7 | @Repository
 8 | public interface ConsumerMapper extends BaseMapper<Consumer> {
 9 | 
10 | }
11 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/mapper/ListSongMapper.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.mapper;
 2 | 
 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 4 | import com.example.yin.model.domain.ListSong;
 5 | import org.springframework.stereotype.Repository;
 6 | 
 7 | @Repository
 8 | public interface ListSongMapper extends BaseMapper<ListSong> {
 9 | 
10 | }
11 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/mapper/RankListMapper.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.mapper;
 2 | 
 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 4 | import com.example.yin.model.domain.RankList;
 5 | import org.apache.ibatis.annotations.Param;
 6 | import org.springframework.stereotype.Repository;
 7 | 
 8 | @Repository
 9 | public interface RankListMapper extends BaseMapper<RankList> {
10 | 
11 |     /**
12 |      * 查总分
13 |      * @param songListId
14 |      * @return
15 |      */
16 |     int selectScoreSum(Long songListId);
17 | 
18 |     /**
19 |      * 查制定用户评分
20 |      * @param consumerId
21 |      * @param songListId
22 |      * @return
23 |      */
24 |     Integer selectUserRank(@Param("consumer_id") Long consumerId, @Param("song_list_id")  Long songListId);
25 | }
26 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/mapper/SingerMapper.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.mapper;
 2 | 
 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 4 | import com.example.yin.model.domain.Singer;
 5 | import org.springframework.stereotype.Repository;
 6 | 
 7 | @Repository
 8 | public interface SingerMapper extends BaseMapper<Singer> {
 9 | 
10 | }
11 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/mapper/SongListMapper.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.mapper;
 2 | 
 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 4 | import com.example.yin.model.domain.SongList;
 5 | import org.springframework.stereotype.Repository;
 6 | 
 7 | @Repository
 8 | 
 9 | public interface SongListMapper extends BaseMapper<SongList> {
10 | 
11 | 
12 | }
13 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/mapper/SongMapper.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.mapper;
 2 | 
 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 4 | import com.example.yin.model.domain.Song;
 5 | import org.springframework.stereotype.Repository;
 6 | 
 7 | @Repository
 8 | public interface SongMapper extends BaseMapper<Song> {
 9 | 
10 | }
11 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/mapper/UserSupportMapper.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.mapper;
 2 | 
 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 4 | import com.example.yin.model.domain.UserSupport;
 5 | 
 6 | /**
 7 |  * @author asus
 8 |  * @description 针对表【user_support】的数据库操作Mapper
 9 |  * @createDate 2022-06-11 16:06:28
10 |  * @Entity generator.domain.UserSupport
11 |  */
12 | public interface UserSupportMapper extends BaseMapper<UserSupport> {
13 | 
14 | }
15 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/domain/Admin.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.domain;
 2 | 
 3 | import com.baomidou.mybatisplus.annotation.IdType;
 4 | import com.baomidou.mybatisplus.annotation.TableId;
 5 | import com.baomidou.mybatisplus.annotation.TableName;
 6 | import lombok.Data;
 7 | import org.apache.commons.lang3.builder.ToStringBuilder;
 8 | 
 9 | @TableName(value = "admin")
10 | @Data
11 | public class Admin {
12 |     @TableId(type = IdType.AUTO)
13 |     private Integer id;
14 | 
15 |     private String name;
16 | 
17 |     private String password;
18 | 
19 |     @Override
20 |     public String toString() {
21 |         return ToStringBuilder.reflectionToString(this);
22 |     }
23 | }
24 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/domain/Banner.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.domain;
 2 | 
 3 | import lombok.Data;
 4 | 
 5 | import java.io.Serializable;
 6 | 
 7 | /**
 8 |  * 
 9 |  * @TableName banner
10 |  */
11 | @Data
12 | public class Banner implements Serializable {
13 |     /**
14 |      * 
15 |      */
16 |     private Integer id;
17 | 
18 |     /**
19 |      * 
20 |      */
21 |     private String pic;
22 | 
23 |     private static final long serialVersionUID = 1L;
24 | 
25 |     @Override
26 |     public boolean equals(Object that) {
27 |         if (this == that) {
28 |             return true;
29 |         }
30 |         if (that == null) {
31 |             return false;
32 |         }
33 |         if (getClass() != that.getClass()) {
34 |             return false;
35 |         }
36 |         Banner other = (Banner) that;
37 |         return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
38 |             && (this.getPic() == null ? other.getPic() == null : this.getPic().equals(other.getPic()));
39 |     }
40 | 
41 |     @Override
42 |     public int hashCode() {
43 |         final int prime = 31;
44 |         int result = 1;
45 |         result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
46 |         result = prime * result + ((getPic() == null) ? 0 : getPic().hashCode());
47 |         return result;
48 |     }
49 | 
50 |     @Override
51 |     public String toString() {
52 |         StringBuilder sb = new StringBuilder();
53 |         sb.append(getClass().getSimpleName());
54 |         sb.append(" [");
55 |         sb.append("Hash = ").append(hashCode());
56 |         sb.append(", id=").append(id);
57 |         sb.append(", pic=").append(pic);
58 |         sb.append(", serialVersionUID=").append(serialVersionUID);
59 |         sb.append("]");
60 |         return sb.toString();
61 |     }
62 | }


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/domain/Collect.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.domain;
 2 | 
 3 | import com.baomidou.mybatisplus.annotation.*;
 4 | import lombok.Data;
 5 | import org.apache.commons.lang3.builder.ToStringBuilder;
 6 | 
 7 | import java.util.Date;
 8 | 
 9 | @TableName(value = "collect")
10 | @Data
11 | public class Collect {
12 |     @TableId(type = IdType.AUTO)
13 |     private Integer id;
14 | 
15 |     private Integer userId;
16 | 
17 |     private Byte type;
18 | 
19 |     private Integer songId;
20 | 
21 |     private Integer songListId;
22 | 
23 |     @TableField(fill = FieldFill.INSERT)
24 |     private Date createTime;
25 | 
26 | 
27 |     @Override
28 |     public String toString() {
29 |         return ToStringBuilder.reflectionToString(this);
30 |     }
31 | 
32 | }
33 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/domain/Comment.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.domain;
 2 | 
 3 | import com.baomidou.mybatisplus.annotation.*;
 4 | import lombok.Data;
 5 | import org.apache.commons.lang3.builder.ToStringBuilder;
 6 | 
 7 | import java.util.Date;
 8 | 
 9 | @TableName(value = "comment")
10 | @Data
11 | public class Comment {
12 |     @TableId(type = IdType.AUTO)
13 |     private Integer id;
14 | 
15 |     private Integer userId;
16 | 
17 |     private Integer songId;
18 | 
19 |     private Integer songListId;
20 | 
21 |     private String content;
22 | 
23 |     @TableField(fill = FieldFill.INSERT)
24 |     private Date createTime;
25 | 
26 |     private Byte type;
27 | 
28 |     private Integer up;
29 | 
30 | 
31 |     @Override
32 |     public String toString() {
33 |         return ToStringBuilder.reflectionToString(this);
34 |     }
35 | }
36 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/domain/Consumer.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.domain;
 2 | 
 3 | import com.baomidou.mybatisplus.annotation.*;
 4 | import lombok.Data;
 5 | import org.apache.commons.lang3.builder.ToStringBuilder;
 6 | 
 7 | import java.util.Date;
 8 | 
 9 | @TableName(value = "consumer")
10 | @Data
11 | public class Consumer {
12 |     @TableId(type = IdType.AUTO)
13 |     private Integer id;
14 | 
15 |     private String username;
16 | 
17 |     private String password;
18 | 
19 |     private Byte sex;
20 | 
21 |     private String phoneNum;
22 |     @TableField(value = "email")
23 |     private String email;
24 | 
25 |     private Date birth;
26 | 
27 |     private String introduction;
28 | 
29 |     private String location;
30 | 
31 |     private String avator;
32 | 
33 |     @TableField(fill = FieldFill.INSERT)
34 |     private Date createTime;
35 | 
36 |     @TableField(fill = FieldFill.INSERT_UPDATE)
37 |     private Date updateTime;
38 | 
39 |     @Override
40 |     public String toString() {
41 |         return ToStringBuilder.reflectionToString(this);
42 |     }
43 | }
44 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/domain/ListSong.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.domain;
 2 | 
 3 | import com.baomidou.mybatisplus.annotation.IdType;
 4 | import com.baomidou.mybatisplus.annotation.TableId;
 5 | import com.baomidou.mybatisplus.annotation.TableName;
 6 | import lombok.Data;
 7 | import org.apache.commons.lang3.builder.ToStringBuilder;
 8 | 
 9 | import java.io.Serializable;
10 | 
11 | @TableName(value = "list_song")
12 | @Data
13 | public class ListSong implements Serializable {
14 | 
15 |     @TableId(type = IdType.AUTO)
16 |     private Integer id;
17 | 
18 |     private Integer songId;
19 | 
20 |     private Integer songListId;
21 | 
22 |     @Override
23 |     public String toString() {
24 |         return ToStringBuilder.reflectionToString(this);
25 |     }
26 | }
27 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/domain/Order.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.domain;
 2 |  
 3 | import lombok.AllArgsConstructor;
 4 | import lombok.Data;
 5 | import lombok.NoArgsConstructor;
 6 |  
 7 | @Data
 8 | @AllArgsConstructor
 9 | @NoArgsConstructor
10 | public class Order {
11 |     private int id;
12 |     private String name;
13 |     private String password;
14 | }


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/domain/RankList.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.domain;
 2 | 
 3 | import com.baomidou.mybatisplus.annotation.IdType;
 4 | import com.baomidou.mybatisplus.annotation.TableId;
 5 | import com.baomidou.mybatisplus.annotation.TableName;
 6 | import lombok.Data;
 7 | 
 8 | import java.io.Serializable;
 9 | 
10 | @TableName(value = "rank_list")
11 | @Data
12 | public class RankList implements Serializable {
13 | 
14 |     @TableId(type = IdType.AUTO)
15 |     private Long id;
16 | 
17 |     private Long songListId;
18 | 
19 |     private Long consumerId;
20 | 
21 |     private Integer score;
22 | 
23 | }
24 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/domain/ResetPasswordRequest.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.domain;
 2 | 
 3 | import lombok.AllArgsConstructor;
 4 | import lombok.Data;
 5 | import lombok.NoArgsConstructor;
 6 | import lombok.ToString;
 7 | 
 8 | @Data
 9 | @AllArgsConstructor
10 | @NoArgsConstructor
11 | @ToString
12 | public class ResetPasswordRequest {
13 |     private String email;
14 |     private String code;
15 |     private String password;
16 |     private String confirmPassword;
17 | }
18 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/domain/Singer.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.domain;
 2 | 
 3 | import com.baomidou.mybatisplus.annotation.IdType;
 4 | import com.baomidou.mybatisplus.annotation.TableId;
 5 | import com.baomidou.mybatisplus.annotation.TableName;
 6 | import lombok.Data;
 7 | import org.apache.commons.lang3.builder.ToStringBuilder;
 8 | 
 9 | import java.util.Date;
10 | 
11 | @TableName(value = "singer")
12 | @Data
13 | public class Singer {
14 | 
15 |     @TableId(type = IdType.AUTO)
16 |     private Integer id;
17 | 
18 |     private String name;
19 | 
20 |     private Byte sex;
21 | 
22 |     private String pic;
23 | 
24 |     private Date birth;
25 | 
26 |     private String location;
27 | 
28 |     private String introduction;
29 | 
30 |     @Override
31 |     public String toString() {
32 |         return ToStringBuilder.reflectionToString(this);
33 |     }
34 | }
35 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/domain/Song.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.domain;
 2 | 
 3 | import com.baomidou.mybatisplus.annotation.*;
 4 | import lombok.Data;
 5 | import org.apache.commons.lang3.builder.ToStringBuilder;
 6 | 
 7 | import java.util.Date;
 8 | 
 9 | @TableName(value = "song")
10 | @Data
11 | public class Song {
12 | 
13 |     @TableId(type = IdType.AUTO)
14 |     private Integer id;
15 | 
16 |     private Integer singerId;
17 | 
18 |     private String name;
19 | 
20 |     private String introduction;
21 | 
22 |     @TableField(fill = FieldFill.INSERT)
23 |     private Date createTime;
24 | 
25 |     @TableField(fill = FieldFill.INSERT_UPDATE)
26 |     private Date updateTime;
27 | 
28 |     private String pic;
29 | 
30 |     private String lyric;
31 | 
32 |     private String url;
33 | 
34 |     @Override
35 |     public String toString() {
36 |         return ToStringBuilder.reflectionToString(this);
37 |     }
38 | }
39 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/domain/SongList.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.domain;
 2 | 
 3 | import com.baomidou.mybatisplus.annotation.IdType;
 4 | import com.baomidou.mybatisplus.annotation.TableId;
 5 | import com.baomidou.mybatisplus.annotation.TableName;
 6 | import lombok.Data;
 7 | import org.apache.commons.lang3.builder.ToStringBuilder;
 8 | 
 9 | @TableName(value = "song_list")
10 | @Data
11 | public class SongList {
12 | 
13 |     @TableId(type = IdType.AUTO)
14 |     private Integer id;
15 | 
16 |     private String title;
17 | 
18 |     private String pic;
19 | 
20 |     private String style;
21 | 
22 |     private String introduction;
23 | 
24 |     @Override
25 |     public String toString() {
26 |         return ToStringBuilder.reflectionToString(this);
27 |     }
28 | }
29 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/domain/UserSupport.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.domain;
 2 | 
 3 | import com.baomidou.mybatisplus.annotation.IdType;
 4 | import com.baomidou.mybatisplus.annotation.TableId;
 5 | import lombok.Data;
 6 | 
 7 | import java.io.Serializable;
 8 | 
 9 | /**
10 |  * 
11 |  * @TableName user_support
12 |  */
13 | @Data
14 | public class UserSupport implements Serializable {
15 |     /**
16 |      * 
17 |      */
18 |     @TableId(type = IdType.AUTO)
19 |     private Integer id;
20 | 
21 |     /**
22 |      * 
23 |      */
24 |     private Integer commentId;
25 | 
26 |     /**
27 |      * 
28 |      */
29 |     private Integer userId;
30 | 
31 |     private static final long serialVersionUID = 1L;
32 | 
33 |     @Override
34 |     public boolean equals(Object that) {
35 |         if (this == that) {
36 |             return true;
37 |         }
38 |         if (that == null) {
39 |             return false;
40 |         }
41 |         if (getClass() != that.getClass()) {
42 |             return false;
43 |         }
44 |         UserSupport other = (UserSupport) that;
45 |         return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
46 |             && (this.getCommentId() == null ? other.getCommentId() == null : this.getCommentId().equals(other.getCommentId()))
47 |             && (this.getUserId() == null ? other.getUserId() == null : this.getUserId().equals(other.getUserId()));
48 |     }
49 | 
50 |     @Override
51 |     public int hashCode() {
52 |         final int prime = 31;
53 |         int result = 1;
54 |         result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
55 |         result = prime * result + ((getCommentId() == null) ? 0 : getCommentId().hashCode());
56 |         result = prime * result + ((getUserId() == null) ? 0 : getUserId().hashCode());
57 |         return result;
58 |     }
59 | 
60 |     @Override
61 |     public String toString() {
62 |         StringBuilder sb = new StringBuilder();
63 |         sb.append(getClass().getSimpleName());
64 |         sb.append(" [");
65 |         sb.append("Hash = ").append(hashCode());
66 |         sb.append(", id=").append(id);
67 |         sb.append(", commentId=").append(commentId);
68 |         sb.append(", userId=").append(userId);
69 |         sb.append(", serialVersionUID=").append(serialVersionUID);
70 |         sb.append("]");
71 |         return sb.toString();
72 |     }
73 | }


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/request/AdminRequest.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.request;
 2 | 
 3 | import lombok.Data;
 4 | 
 5 | /**
 6 |  * @Author 祝英台炸油条
 7 |  * @Time : 2022/6/6 18:44
 8 |  **/
 9 | @Data
10 | public class AdminRequest {
11 |     private Integer id;
12 | 
13 |     private String username;
14 | 
15 |     private String password;
16 | }
17 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/request/CollectRequest.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.request;
 2 | 
 3 | import lombok.Data;
 4 | 
 5 | import java.util.Date;
 6 | 
 7 | /**
 8 |  * @Author 祝英台炸油条
 9 |  * @Time : 2022/6/6 13:11
10 |  **/
11 | @Data
12 | public class CollectRequest {
13 |     private Integer id;
14 | 
15 |     private Integer userId;
16 | 
17 |     private Byte type;
18 | 
19 |     private Integer songId;
20 | 
21 |     private Integer songListId;
22 | 
23 |     private Date createTime;
24 | }
25 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/request/CommentRequest.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.request;
 2 | 
 3 | import lombok.Data;
 4 | 
 5 | import java.util.Date;
 6 | 
 7 | /**
 8 |  * @Author 祝英台炸油条
 9 |  * @Time : 2022/6/6 14:29
10 |  **/
11 | @Data
12 | public class CommentRequest {
13 |     private Integer id;
14 | 
15 |     private Integer userId;
16 | 
17 |     private Integer songId;
18 | 
19 |     private Integer songListId;
20 | 
21 |     private String content;
22 | 
23 |     private Date createTime;
24 | 
25 |     private Byte nowType;
26 | 
27 |     private Integer up;//点赞
28 | }
29 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/request/ConsumerRequest.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.request;
 2 | 
 3 | import lombok.Data;
 4 | 
 5 | import java.util.Date;
 6 | 
 7 | /**
 8 |  * @Author 祝英台炸油条
 9 |  * @Time : 2022/6/5 19:35
10 |  * 这块 现在尝试把所有有关用户的属性都放入
11 |  **/
12 | @Data
13 | public class ConsumerRequest {
14 |     private Integer id;
15 | 
16 |     private String username;
17 | 
18 |     private String oldPassword; //因为会用到用户旧密码 这无所谓的对应即可
19 | 
20 |     private String password;
21 | 
22 |     private Byte sex;
23 | 
24 |     private String phoneNum;
25 | 
26 |     private String email;
27 | 
28 |     private Date birth;
29 | 
30 |     private String introduction;
31 | 
32 |     private String location;
33 | 
34 |     private String avator;
35 | 
36 |     private Date createTime;
37 | }
38 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/request/ListSongRequest.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.request;
 2 | 
 3 | import lombok.Data;
 4 | 
 5 | /**
 6 |  * @Author 祝英台炸油条
 7 |  * @Time : 2022/6/6 20:38
 8 |  **/
 9 | @Data
10 | public class ListSongRequest {
11 |     private Integer id;
12 | 
13 |     private Integer songId;
14 | 
15 |     private Integer songListId;
16 | }
17 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/request/RankListRequest.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.request;
 2 | 
 3 | import lombok.Data;
 4 | 
 5 | /**
 6 |  * @Author 祝英台炸油条
 7 |  * @Time : 2022/6/6 16:57
 8 |  **/
 9 | @Data
10 | public class RankListRequest {
11 |     private Long id;
12 | 
13 |     private Long songListId;
14 | 
15 |     private Long consumerId;
16 | 
17 |     private Integer score;
18 | }
19 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/request/SingerRequest.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.request;
 2 | 
 3 | import lombok.Data;
 4 | 
 5 | import java.util.Date;
 6 | 
 7 | /**
 8 |  * @Author 祝英台炸油条
 9 |  * @Time : 2022/6/6 20:14
10 |  **/
11 | @Data
12 | public class SingerRequest {
13 |     private Integer id;
14 | 
15 |     private String name;
16 | 
17 |     private Byte sex;
18 | 
19 |     private String pic;
20 | 
21 |     private Date birth;
22 | 
23 |     private String location;
24 | 
25 |     private String introduction;
26 | }
27 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/request/SongListRequest.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.request;
 2 | 
 3 | import lombok.Data;
 4 | 
 5 | /**
 6 |  * @Author 祝英台炸油条
 7 |  * @Time : 2022/6/6 20:38
 8 |  **/
 9 | @Data
10 | public class SongListRequest {
11 |     private Integer id;
12 | 
13 |     private String title;
14 | 
15 |     private String pic;
16 | 
17 |     private String style;
18 | 
19 |     private String introduction;
20 | }
21 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/request/SongRequest.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.request;
 2 | 
 3 | import lombok.Data;
 4 | 
 5 | import java.util.Date;
 6 | 
 7 | /**
 8 |  * @Author 祝英台炸油条
 9 |  * @Time : 2022/6/6 19:11
10 |  **/
11 | @Data
12 | public class SongRequest {
13 | 
14 |     private Integer id;
15 | 
16 |     private Integer singerId;
17 | 
18 |     private String name;
19 | 
20 |     private String introduction;
21 | 
22 |     private Date createTime;
23 | 
24 |     private Date updateTime;
25 | 
26 |     private String pic;
27 | 
28 |     private String lyric;
29 | 
30 |     private String url;
31 | }
32 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/model/request/UserSupportRequest.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.model.request;
 2 | 
 3 | import lombok.Data;
 4 | 
 5 | /**
 6 |  * @Author 祝英台炸油条
 7 |  * @Time : 2022/6/11 16:08
 8 |  **/
 9 | @Data
10 | public class UserSupportRequest {
11 |     Integer id;
12 |     Integer commentId;
13 |     Integer userId;
14 | }
15 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/AdminService.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service;
 2 | 
 3 | import com.baomidou.mybatisplus.extension.service.IService;
 4 | import com.example.yin.common.R;
 5 | import com.example.yin.model.domain.Admin;
 6 | import com.example.yin.model.request.AdminRequest;
 7 | 
 8 | import javax.servlet.http.HttpSession;
 9 | 
10 | public interface AdminService extends IService<Admin> {
11 | 
12 |     R verityPasswd(AdminRequest adminRequest, HttpSession session);
13 | }
14 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/BannerService.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service;
 2 | 
 3 | import com.baomidou.mybatisplus.extension.service.IService;
 4 | import com.example.yin.model.domain.Banner;
 5 | 
 6 | import java.util.List;
 7 | 
 8 | /**
 9 | * @author asus
10 | * @description 针对表【banner】的数据库操作Service
11 | * @createDate 2022-06-13 13:13:42
12 | */
13 | public interface BannerService extends IService<Banner> {
14 | 
15 |     List<Banner> getAllBanner();
16 | 
17 | }
18 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/CollectService.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service;
 2 | 
 3 | import com.baomidou.mybatisplus.extension.service.IService;
 4 | import com.example.yin.common.R;
 5 | import com.example.yin.model.domain.Collect;
 6 | import com.example.yin.model.request.CollectRequest;
 7 | 
 8 | public interface CollectService extends IService<Collect> {
 9 | 
10 |     R addCollection(CollectRequest addCollectRequest);
11 | 
12 |     R existSongId(CollectRequest isCollectRequest);
13 | 
14 |     R deleteCollect(Integer userId,Integer songId);
15 | 
16 |     R collectionOfUser(Integer userId);
17 | }
18 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/CommentService.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service;
 2 | 
 3 | import com.baomidou.mybatisplus.extension.service.IService;
 4 | import com.example.yin.common.R;
 5 | import com.example.yin.model.domain.Comment;
 6 | import com.example.yin.model.request.CommentRequest;
 7 | 
 8 | public interface CommentService extends IService<Comment> {
 9 | 
10 |     R addComment(CommentRequest addCommentRequest);
11 | 
12 |     R updateCommentMsg(CommentRequest upCommentRequest);
13 | 
14 |     R deleteComment(Integer id);
15 | 
16 |     R commentOfSongId(Integer songId);
17 | 
18 |     R commentOfSongListId(Integer songListId);
19 | 
20 | }
21 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/ConsumerService.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service;
 2 | 
 3 | import com.baomidou.mybatisplus.extension.service.IService;
 4 | import com.example.yin.common.R;
 5 | import com.example.yin.model.domain.Consumer;
 6 | import com.example.yin.model.request.ConsumerRequest;
 7 | import org.springframework.web.multipart.MultipartFile;
 8 | 
 9 | import javax.servlet.http.HttpSession;
10 | 
11 | public interface ConsumerService extends IService<Consumer> {
12 | 
13 |     R addUser(ConsumerRequest registryRequest);
14 | 
15 |     R updateUserMsg(ConsumerRequest updateRequest);
16 | 
17 |     R updateUserAvator(MultipartFile avatorFile, int id);
18 | 
19 |     R updatePassword(ConsumerRequest updatePasswordRequest);
20 | 
21 |     boolean existUser(String username);
22 | 
23 |     boolean verityPasswd(String username, String password);
24 | 
25 |     R deleteUser(Integer id);
26 | 
27 |     R allUser();
28 | 
29 |     R userOfId(Integer id);
30 | 
31 |     R loginStatus(ConsumerRequest loginRequest, HttpSession session);
32 |     R loginEmailStatus(ConsumerRequest loginRequest, HttpSession session);
33 |     Consumer findByEmail (String email);
34 |     R updatePassword01(ConsumerRequest updatePasswordRequest);
35 | }
36 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/ListSongService.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service;
 2 | 
 3 | import com.baomidou.mybatisplus.extension.service.IService;
 4 | import com.example.yin.common.R;
 5 | import com.example.yin.model.domain.ListSong;
 6 | import com.example.yin.model.request.ListSongRequest;
 7 | 
 8 | import java.util.List;
 9 | 
10 | public interface ListSongService extends IService<ListSong> {
11 | 
12 |     R addListSong(ListSongRequest addListSongRequest);
13 | 
14 |     R updateListSongMsg(ListSongRequest updateListSongRequest);
15 | 
16 |     R deleteListSong(Integer songId);
17 | 
18 |     //看看这啥
19 |     List<ListSong> allListSong();
20 | 
21 |     R listSongOfSongId(Integer songListId);
22 | }
23 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/OrderManager.java:
--------------------------------------------------------------------------------
1 | package com.example.yin.service;
2 | 
3 | import com.example.yin.model.domain.Order;
4 | public interface OrderManager {
5 |     void sendPassword(Order order,String reciveAddress);
6 |     void sendCode(String code,String reciveAddress);
7 | }


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/RankListService.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service;
 2 | 
 3 | import com.baomidou.mybatisplus.extension.service.IService;
 4 | import com.example.yin.common.R;
 5 | import com.example.yin.model.domain.RankList;
 6 | import com.example.yin.model.request.RankListRequest;
 7 | 
 8 | public interface RankListService extends IService<RankList> {
 9 | 
10 |     R addRank(RankListRequest rankListAddRequest);
11 | 
12 |     R rankOfSongListId(Long songListId);
13 | 
14 |     R getUserRank(Long consumerId, Long songListId);
15 | 
16 | }
17 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/SingerService.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service;
 2 | 
 3 | import com.baomidou.mybatisplus.extension.service.IService;
 4 | import com.example.yin.common.R;
 5 | import com.example.yin.model.domain.Singer;
 6 | import com.example.yin.model.request.SingerRequest;
 7 | import org.springframework.web.multipart.MultipartFile;
 8 | 
 9 | public interface SingerService extends IService<Singer> {
10 | 
11 |     R addSinger (SingerRequest addSingerRequest);
12 | 
13 |     R updateSingerMsg(SingerRequest updateSingerRequest);
14 | 
15 |     R updateSingerPic(MultipartFile avatorFile, int id);
16 | 
17 |     R deleteSinger(Integer id);
18 | 
19 |     R allSinger();
20 | 
21 |     R singerOfName(String name);
22 | 
23 |     R singerOfSex(Integer sex);
24 | }
25 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/SongListService.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service;
 2 | 
 3 | import com.baomidou.mybatisplus.extension.service.IService;
 4 | import com.example.yin.common.R;
 5 | import com.example.yin.model.domain.SongList;
 6 | import com.example.yin.model.request.SongListRequest;
 7 | import org.springframework.web.multipart.MultipartFile;
 8 | 
 9 | import java.util.List;
10 | 
11 | public interface SongListService extends IService<SongList> {
12 | 
13 |     R addSongList(SongListRequest addSongListRequest);
14 | 
15 |     R updateSongListMsg(SongListRequest updateSongListRequest);
16 | 
17 |     R updateSongListImg(MultipartFile avatorFile, int id);
18 | 
19 |     R deleteSongList(Integer id);
20 | 
21 |     R allSongList();
22 | 
23 |     List<SongList> findAllSong();
24 | 
25 |     R likeTitle(String title);
26 | 
27 |     R likeStyle(String style);
28 | }
29 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/SongService.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service;
 2 | 
 3 | import com.baomidou.mybatisplus.extension.service.IService;
 4 | import com.example.yin.common.R;
 5 | import com.example.yin.model.domain.Song;
 6 | import com.example.yin.model.request.SongRequest;
 7 | import org.springframework.web.multipart.MultipartFile;
 8 | 
 9 | public interface SongService extends IService<Song> {
10 | 
11 |     R addSong (SongRequest addSongRequest,MultipartFile lrcfile,  MultipartFile mpfile);
12 | 
13 |     R updateSongMsg(SongRequest updateSongRequest);
14 | 
15 |     R updateSongUrl(MultipartFile urlFile, int id);
16 | 
17 |     R updateSongPic(MultipartFile urlFile, int id);
18 | 
19 |     R deleteSong(Integer id);
20 | 
21 |     R allSong();
22 | 
23 |     R songOfSingerId(Integer singerId);
24 | 
25 |     R songOfId(Integer id);
26 | 
27 |     R songOfSingerName(String name);
28 | 
29 |     R updateSongLrc(MultipartFile lrcFile, int id);
30 | }
31 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/UserSupportService.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service;
 2 | 
 3 | import com.baomidou.mybatisplus.extension.service.IService;
 4 | import com.example.yin.common.R;
 5 | import com.example.yin.model.domain.UserSupport;
 6 | import com.example.yin.model.request.UserSupportRequest;
 7 | 
 8 | /**
 9 |  * @author asus
10 |  * @description 针对表【user_support】的数据库操作Service
11 |  * @createDate 2022-06-11 16:06:28
12 |  */
13 | public interface UserSupportService extends IService<UserSupport> {
14 | 
15 |     R isUserSupportComment(UserSupportRequest userSupportRequest);
16 | 
17 |     R insertCommentSupport(UserSupportRequest userSupportRequest);
18 | 
19 |     R deleteCommentSupport(UserSupportRequest userSupportRequest);
20 | }
21 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/impl/AdminServiceImpl.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service.impl;
 2 | 
 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 4 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 5 | import com.example.yin.common.R;
 6 | import com.example.yin.mapper.AdminMapper;
 7 | import com.example.yin.model.domain.Admin;
 8 | import com.example.yin.model.request.AdminRequest;
 9 | import com.example.yin.service.AdminService;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.stereotype.Service;
12 | 
13 | import javax.servlet.http.HttpSession;
14 | 
15 | @Service
16 | public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {
17 | 
18 |     @Autowired
19 |     private AdminMapper adminMapper;
20 | 
21 |     @Override
22 |     public R verityPasswd(AdminRequest adminRequest, HttpSession session) {
23 |         QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
24 |         queryWrapper.eq("name",adminRequest.getUsername());
25 |         queryWrapper.eq("password",adminRequest.getPassword());
26 |         if (adminMapper.selectCount(queryWrapper) > 0) {
27 |             session.setAttribute("name", adminRequest.getUsername());
28 |             return R.success("登录成功");
29 |         } else {
30 |             return R.error("用户名或密码错误");
31 |         }
32 |     }
33 | }
34 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/impl/BannerServiceImpl.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service.impl;
 2 | 
 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 4 | import com.example.yin.mapper.BannerMapper;
 5 | import com.example.yin.model.domain.Banner;
 6 | import com.example.yin.service.BannerService;
 7 | import org.springframework.beans.factory.annotation.Autowired;
 8 | import org.springframework.cache.annotation.Cacheable;
 9 | import org.springframework.stereotype.Service;
10 | 
11 | import java.util.List;
12 | 
13 | /**
14 |  * @author asus
15 |  * @description 针对表【banner】的数据库操作Service实现
16 |  * @createDate 2022-06-13 13:13:42
17 |  */
18 | @Service
19 | public class BannerServiceImpl extends ServiceImpl<BannerMapper, Banner>
20 |         implements BannerService {
21 | 
22 |     @Autowired
23 |     private BannerMapper bannerMapper;
24 | 
25 |     @Cacheable(value = "banner", key = "'list'")  //放在缓存中 redis 是以key-value进行存储的
26 |     @Override
27 |     public List<Banner> getAllBanner() {
28 |         System.out.println("没有走缓存");
29 |         return bannerMapper.selectList(null);
30 |     }
31 | }
32 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/impl/CollectServiceImpl.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service.impl;
 2 | 
 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 4 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 5 | import com.example.yin.common.R;
 6 | import com.example.yin.mapper.CollectMapper;
 7 | import com.example.yin.model.domain.Collect;
 8 | import com.example.yin.model.request.CollectRequest;
 9 | import com.example.yin.service.CollectService;
10 | import org.springframework.beans.BeanUtils;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.stereotype.Service;
13 | 
14 | @Service
15 | public class CollectServiceImpl extends ServiceImpl<CollectMapper, Collect> implements CollectService {
16 |     @Autowired
17 |     private CollectMapper collectMapper;
18 | 
19 |     @Override
20 |     public R addCollection(CollectRequest addCollectRequest) {
21 |         //作者用type来判断收藏的是歌还是歌单
22 |         Collect collect = new Collect();
23 |         BeanUtils.copyProperties(addCollectRequest, collect);
24 |         if (collectMapper.insert(collect) > 0) {
25 |             return R.success("收藏成功", true);
26 |         } else {
27 |             return R.error("收藏失败");
28 |         }
29 |     }
30 | 
31 |     @Override
32 |     public R existSongId(CollectRequest isCollectRequest) {
33 |         QueryWrapper<Collect> queryWrapper = new QueryWrapper();
34 |         queryWrapper.eq("user_id",isCollectRequest.getUserId());
35 |         queryWrapper.eq("song_id",isCollectRequest.getSongId());
36 |         if (collectMapper.selectCount(queryWrapper) > 0) {
37 |             return R.success("已收藏", true);
38 |         } else {
39 |             return R.success("未收藏", false);
40 |         }
41 |     }
42 | 
43 |     @Override
44 |     public R deleteCollect(Integer userId, Integer songId) {
45 |         QueryWrapper<Collect> queryWrapper = new QueryWrapper();
46 |         queryWrapper.eq("user_id",userId);
47 |         queryWrapper.eq("song_id",songId);
48 |         if (collectMapper.delete(queryWrapper) > 0) {
49 |             return R.success("取消收藏", false);
50 |         } else {
51 |             return R.error("取消收藏失败");
52 |         }
53 |     }
54 | 
55 |     @Override
56 |     public R collectionOfUser(Integer userId) {
57 |         QueryWrapper<Collect> queryWrapper = new QueryWrapper();
58 |         queryWrapper.eq("user_id",userId);
59 |         return R.success("用户收藏", collectMapper.selectList(queryWrapper));
60 |     }
61 | }
62 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/impl/CommentServiceImpl.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service.impl;
 2 | 
 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 4 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 5 | import com.example.yin.common.R;
 6 | import com.example.yin.mapper.CommentMapper;
 7 | import com.example.yin.model.domain.Comment;
 8 | import com.example.yin.model.request.CommentRequest;
 9 | import com.example.yin.service.CommentService;
10 | import org.springframework.beans.BeanUtils;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.stereotype.Service;
13 | 
14 | @Service
15 | public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {
16 |     @Autowired
17 |     private CommentMapper commentMapper;
18 | 
19 |     @Override
20 |     public R addComment(CommentRequest addCommentRequest) {
21 |         Comment comment = new Comment();
22 |         BeanUtils.copyProperties(addCommentRequest, comment);
23 |         comment.setType(addCommentRequest.getNowType());
24 |         if (commentMapper.insert(comment) > 0) {
25 |             return R.success("评论成功");
26 |         } else {
27 |             return R.error("评论失败");
28 |         }
29 |     }
30 | 
31 |     @Override
32 |     public R updateCommentMsg(CommentRequest addCommentRequest) {
33 |         Comment comment = new Comment();
34 |         BeanUtils.copyProperties(addCommentRequest, comment);
35 |         if (commentMapper.updateById(comment) > 0) {
36 |             return R.success("点赞成功");
37 |         } else {
38 |             return R.error("点赞失败");
39 |         }
40 |     }
41 | 
42 |     //    删除评论
43 |     @Override
44 |     public R deleteComment(Integer id) {
45 |         if (commentMapper.deleteById(id) > 0) {
46 |             return R.success("删除成功");
47 |         } else {
48 |             return R.error("删除失败");
49 |         }
50 |     }
51 | 
52 |     @Override
53 |     public R commentOfSongId(Integer songId) {
54 |         QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
55 |         queryWrapper.eq("song_id",songId);
56 |         return R.success(null, commentMapper.selectList(queryWrapper));
57 |     }
58 | 
59 |     @Override
60 |     public R commentOfSongListId(Integer songListId) {
61 |         QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
62 |         queryWrapper.eq("song_list_id",songListId);
63 |         return R.success(null, commentMapper.selectList(queryWrapper));
64 |     }
65 | }
66 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/impl/ListSongServiceImpl.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service.impl;
 2 | 
 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 4 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 5 | import com.example.yin.common.R;
 6 | import com.example.yin.mapper.ListSongMapper;
 7 | import com.example.yin.model.domain.ListSong;
 8 | import com.example.yin.model.request.ListSongRequest;
 9 | import com.example.yin.service.ListSongService;
10 | import org.springframework.beans.BeanUtils;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.stereotype.Service;
13 | 
14 | import java.util.List;
15 | 
16 | @Service
17 | public class ListSongServiceImpl extends ServiceImpl<ListSongMapper, ListSong> implements ListSongService {
18 | 
19 |     @Autowired
20 |     private ListSongMapper listSongMapper;
21 | 
22 |     @Override
23 |     public List<ListSong> allListSong() {
24 |         return listSongMapper.selectList(null);
25 |     }
26 | 
27 |     @Override
28 |     public R updateListSongMsg(ListSongRequest updateListSongRequest) {
29 |         ListSong listSong = new ListSong();
30 |         BeanUtils.copyProperties(updateListSongRequest, listSong);
31 |         if (listSongMapper.updateById(listSong) > 0) {
32 |             return R.success("修改成功");
33 |         } else {
34 |             return R.error("修改失败");
35 |         }
36 |     }
37 | 
38 |     @Override
39 |     public R deleteListSong(Integer songId) {
40 |         QueryWrapper<ListSong> queryWrapper = new QueryWrapper<>();
41 |         queryWrapper.eq("song_id",songId);
42 |         if (listSongMapper.delete(queryWrapper) > 0) {
43 |             return R.success("删除成功");
44 |         } else {
45 |             return R.error("删除失败");
46 |         }
47 |     }
48 | 
49 |     @Override
50 |     public R addListSong(ListSongRequest addListSongRequest) {
51 |         ListSong listSong = new ListSong();
52 |         BeanUtils.copyProperties(addListSongRequest, listSong);
53 |         if (listSongMapper.insert(listSong) > 0) {
54 |             return R.success("添加成功");
55 |         } else {
56 |             return R.error("添加失败");
57 |         }
58 |     }
59 | 
60 |     @Override
61 |     public R listSongOfSongId(Integer songListId) {
62 |         QueryWrapper<ListSong> queryWrapper = new QueryWrapper<>();
63 |         queryWrapper.eq("song_list_id",songListId);
64 |         return R.success("查询成功", listSongMapper.selectList(queryWrapper));
65 |     }
66 | 
67 | }
68 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/impl/RankListServiceImpl.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service.impl;
 2 | 
 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 4 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 5 | import com.example.yin.common.R;
 6 | import com.example.yin.mapper.RankListMapper;
 7 | import com.example.yin.model.domain.RankList;
 8 | import com.example.yin.model.request.RankListRequest;
 9 | import com.example.yin.service.RankListService;
10 | import org.springframework.beans.BeanUtils;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.stereotype.Service;
13 | 
14 | /**
15 |  * @author Administrator
16 |  */
17 | @Service
18 | public class RankListServiceImpl extends ServiceImpl<RankListMapper, RankList> implements RankListService {
19 | 
20 | 
21 |     @Autowired
22 |     private RankListMapper rankMapper;
23 | 
24 |     @Override
25 |     public R addRank(RankListRequest rankListAddRequest) {
26 |         RankList rankList = new RankList();
27 |         BeanUtils.copyProperties(rankListAddRequest, rankList);
28 |         if (rankMapper.insert(rankList) > 0) {
29 |             return R.success("评价成功");
30 |         } else {
31 |             return R.error("评价失败");
32 |         }
33 |     }
34 | 
35 |     @Override
36 |     public R rankOfSongListId(Long songListId) {
37 |         // 评分总人数如果为 0,则返回0;否则返回计算出的结果
38 |         QueryWrapper<RankList> queryWrapper = new QueryWrapper<>();
39 |         queryWrapper.eq("song_list_id",songListId);
40 |         Long rankNum = rankMapper.selectCount(queryWrapper);
41 |         return R.success(null, (rankNum <= 0) ? 0 : rankMapper.selectScoreSum(songListId) / rankNum);
42 |     }
43 | 
44 |     @Override
45 |     public R getUserRank(Long consumerId, Long songListId) {
46 |         Integer i = rankMapper.selectUserRank(consumerId, songListId);
47 |         return R.success(null, i);
48 |     }
49 | }
50 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/impl/SimpleOrderManager.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service.impl;
 2 |  
 3 | import javax.mail.Message;
 4 | import javax.mail.internet.InternetAddress;
 5 | import javax.mail.internet.MimeMessage;
 6 | import com.example.yin.model.domain.Order;
 7 | import com.example.yin.service.OrderManager;
 8 | import org.jetbrains.annotations.NotNull;
 9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.beans.factory.annotation.Value;
11 | import org.springframework.mail.MailException;
12 | import org.springframework.mail.javamail.JavaMailSender;
13 | import org.springframework.mail.javamail.MimeMessagePreparator;
14 | import org.springframework.stereotype.Service;
15 | /**
16 |  * 邮箱信息的发送
17 |  */
18 | 
19 | @Service
20 | public class SimpleOrderManager implements OrderManager {
21 | 
22 |     @Value("${mail.address}")
23 |     private String sendAddress;
24 | 
25 |     @Autowired
26 |     private JavaMailSender mailSender;
27 | 
28 |     public void setMailSender(JavaMailSender mailSender) {
29 |         this.mailSender = mailSender;
30 |     }
31 | 
32 |     public void sendPassword(Order order, String reciveAddress) {
33 |         MimeMessagePreparator preparator = new MimeMessagePreparator() {
34 |             public void prepare(@NotNull MimeMessage mimeMessage) throws Exception {
35 |                 mimeMessage.setRecipient(Message.RecipientType.TO,
36 |                         new InternetAddress(reciveAddress));
37 |                 mimeMessage.setFrom(new InternetAddress(sendAddress));
38 |                 mimeMessage.setText("Dear " + order.getName() + "\n" +
39 |                         "Your  password is :" + order.getPassword() + ".");
40 |             }
41 |         };
42 | 
43 |         try {
44 |             this.mailSender.send(preparator);
45 |         } catch (MailException ex) {
46 | 
47 |             System.err.println(ex.getMessage());
48 |         }
49 |     }
50 | 
51 |     public void sendCode(String code, String reciveAddress) {
52 |         MimeMessagePreparator preparator = new MimeMessagePreparator() {
53 |             public void prepare(@NotNull MimeMessage mimeMessage) throws Exception {
54 |                 mimeMessage.setRecipient(Message.RecipientType.TO,
55 |                         new InternetAddress(reciveAddress));
56 |                 mimeMessage.setFrom(new InternetAddress(sendAddress));
57 |                 mimeMessage.setText("Dear you code is " + code);
58 |             }
59 |         };
60 |         this.mailSender.send(preparator);
61 |     }
62 | }


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/impl/SingerServiceImpl.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service.impl;
 2 | 
 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 4 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 5 | import com.example.yin.common.R;
 6 | import com.example.yin.controller.MinioUploadController;
 7 | import com.example.yin.mapper.SingerMapper;
 8 | import com.example.yin.model.domain.Singer;
 9 | import com.example.yin.model.request.SingerRequest;
10 | import com.example.yin.service.SingerService;
11 | import org.springframework.beans.BeanUtils;
12 | import org.springframework.beans.factory.annotation.Autowired;
13 | import org.springframework.stereotype.Service;
14 | import org.springframework.web.multipart.MultipartFile;
15 | 
16 | import java.io.File;
17 | import java.io.IOException;
18 | 
19 | @Service
20 | public class SingerServiceImpl extends ServiceImpl<SingerMapper, Singer> implements SingerService {
21 | 
22 |     @Autowired
23 |     private SingerMapper singerMapper;
24 | 
25 |     @Override
26 |     public R updateSingerMsg(SingerRequest updateSingerRequest) {
27 |         Singer singer = new Singer();
28 |         BeanUtils.copyProperties(updateSingerRequest, singer);
29 |         if (singerMapper.updateById(singer) > 0) {
30 |             return R.success("修改成功");
31 |         } else {
32 |             return R.error("修改失败");
33 |         }
34 |     }
35 | 
36 |     @Override
37 |     public R updateSingerPic(MultipartFile avatorFile, int id) {
38 |         String fileName =  avatorFile.getOriginalFilename();
39 |         MinioUploadController.uploadImgFile(avatorFile);
40 |         String imgPath = "/user01/singer/img/" + fileName;
41 |         Singer singer = new Singer();
42 |         singer.setId(id);
43 |         singer.setPic(imgPath);
44 |         if (singerMapper.updateById(singer) > 0) {
45 |             return R.success("上传成功", imgPath);
46 |         } else {
47 |             return R.error("上传失败");
48 |         }
49 |     }
50 | 
51 |     @Override
52 |     public R deleteSinger(Integer id) {
53 |         if (singerMapper.deleteById(id) > 0) {
54 |             return R.success("删除成功");
55 |         } else {
56 |             return R.error("删除失败");
57 |         }
58 |     }
59 | 
60 |     @Override
61 |     public R allSinger() {
62 |         return R.success(null, singerMapper.selectList(null));
63 |     }
64 | 
65 |     @Override
66 |     public R addSinger(SingerRequest addSingerRequest) {
67 |         Singer singer = new Singer();
68 |         BeanUtils.copyProperties(addSingerRequest, singer);
69 |         String pic = "/img/avatorImages/user.jpg";
70 |         singer.setPic(pic);
71 |         if (singerMapper.insert(singer) > 0) {
72 |             return R.success("添加成功");
73 |         } else {
74 |             return R.error("添加失败");
75 |         }
76 |     }
77 | 
78 |     @Override
79 |     public R singerOfName(String name) {
80 |         QueryWrapper<Singer> queryWrapper = new QueryWrapper<>();
81 |         queryWrapper.like("name", name);
82 |         return R.success(null, singerMapper.selectList(queryWrapper));
83 |     }
84 | 
85 |     @Override
86 |     public R singerOfSex(Integer sex) {
87 |         QueryWrapper<Singer> queryWrapper = new QueryWrapper<>();
88 |         queryWrapper.like("sex", sex);
89 |         return R.success(null, singerMapper.selectList(queryWrapper));
90 |     }
91 | }
92 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/service/impl/UserSupportServiceImpl.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.service.impl;
 2 | 
 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 4 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 5 | import com.example.yin.common.R;
 6 | import com.example.yin.mapper.UserSupportMapper;
 7 | import com.example.yin.model.domain.UserSupport;
 8 | import com.example.yin.model.request.UserSupportRequest;
 9 | import com.example.yin.service.UserSupportService;
10 | import org.springframework.beans.BeanUtils;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.stereotype.Service;
13 | 
14 | /**
15 |  * @author asus
16 |  * @description 针对表【user_support】的数据库操作Service实现
17 |  * @createDate 2022-06-11 16:06:28
18 |  */
19 | @Service
20 | public class UserSupportServiceImpl extends ServiceImpl<UserSupportMapper, UserSupport>
21 |         implements UserSupportService {
22 | 
23 |     @Autowired
24 |     private UserSupportMapper userSupportMapper;
25 | 
26 |     @Override
27 |     public R isUserSupportComment(UserSupportRequest userSupportRequest) {
28 |         QueryWrapper<UserSupport> queryWrapper = new QueryWrapper<>();
29 |         queryWrapper.eq("comment_id", userSupportRequest.getCommentId());
30 |         queryWrapper.eq("user_id", userSupportRequest.getUserId());
31 |         if (userSupportMapper.selectCount(queryWrapper) > 0) {
32 |             return R.success("您已取消点赞", true);
33 |         } else {
34 |             return R.success("您已点赞", false);
35 |         }
36 |     }
37 | 
38 |     @Override
39 |     public R insertCommentSupport(UserSupportRequest userSupportRequest) {
40 |         UserSupport userSupport = new UserSupport();
41 |         BeanUtils.copyProperties(userSupportRequest, userSupport);
42 |         if (userSupportMapper.insert(userSupport) > 0) {
43 |             return R.success("添加记录成功");
44 |         }
45 |         return R.error("添加时,发生异常");
46 |     }
47 | 
48 |     @Override
49 |     public R deleteCommentSupport(UserSupportRequest userSupportRequest) {
50 |         QueryWrapper<UserSupport> queryWrapper = new QueryWrapper<>();
51 |         queryWrapper.eq("comment_id", userSupportRequest.getCommentId());
52 |         queryWrapper.eq("user_id", userSupportRequest.getUserId());
53 |         if (userSupportMapper.delete(queryWrapper) > 0) {
54 |             return R.success("删除记录成功");
55 |         }
56 |         return R.error("删除记录发生异常");
57 |     }
58 | }
59 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/utils/RandomUtils.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.utils;
 2 | 
 3 | import java.util.Random;
 4 | 
 5 | public class RandomUtils {
 6 |     public static String code(){
 7 |         String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; // 可以包含的字符集合
 8 |         int length = 5; // 生成的字符串长度为5个字符
 9 |         StringBuilder randomString = new StringBuilder();
10 |         Random random = new Random();
11 |         for (int i = 0; i < length; i++) {
12 |             int randomIndex = random.nextInt(characters.length());
13 |             char randomChar = characters.charAt(randomIndex);
14 |             randomString.append(randomChar);
15 |         }
16 |         return randomString.toString();
17 |     }
18 | }
19 | 


--------------------------------------------------------------------------------
/music-server/src/main/java/com/example/yin/utils/TestFileUtil.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin.utils;
 2 | 
 3 | import java.io.File;
 4 | import java.io.InputStream;
 5 | import java.util.ArrayList;
 6 | import java.util.List;
 7 | 
 8 | import org.apache.commons.collections4.CollectionUtils;
 9 | 
10 | public class TestFileUtil {
11 | 
12 |     public static InputStream getResourcesFileInputStream(String fileName) {
13 |         return Thread.currentThread().getContextClassLoader().getResourceAsStream("" + fileName);
14 |     }
15 | 
16 |     public static String getPath() {
17 |         return TestFileUtil.class.getResource("/").getPath();
18 |     }
19 | 
20 |     public static TestPathBuild pathBuild() {
21 |         return new TestPathBuild();
22 |     }
23 | 
24 |     public static File createNewFile(String pathName) {
25 |         File file = new File(getPath() + pathName);
26 |         if (file.exists()) {
27 |             file.delete();
28 |         } else {
29 |             if (!file.getParentFile().exists()) {
30 |                 file.getParentFile().mkdirs();
31 |             }
32 |         }
33 |         return file;
34 |     }
35 | 
36 |     public static File readFile(String pathName) {
37 |         return new File(getPath() + pathName);
38 |     }
39 | 
40 |     public static File readUserHomeFile(String pathName) {
41 |         return new File(System.getProperty("user.home") + File.separator + pathName);
42 |     }
43 | 
44 |     /**
45 |      * build to test file path
46 |      **/
47 |     public static class TestPathBuild {
48 |         private TestPathBuild() {
49 |             subPath = new ArrayList<>();
50 |         }
51 | 
52 |         private final List<String> subPath;
53 | 
54 |         public TestPathBuild sub(String dirOrFile) {
55 |             subPath.add(dirOrFile);
56 |             return this;
57 |         }
58 | 
59 |         public String getPath() {
60 |             if (CollectionUtils.isEmpty(subPath)) {
61 |                 return TestFileUtil.class.getResource("/").getPath();
62 |             }
63 |             if (subPath.size() == 1) {
64 |                 return TestFileUtil.class.getResource("/").getPath() + subPath.get(0);
65 |             }
66 |             StringBuilder path = new StringBuilder(TestFileUtil.class.getResource("/").getPath());
67 |             path.append(subPath.get(0));
68 |             for (int i = 1; i < subPath.size(); i++) {
69 |                 path.append(File.separator).append(subPath.get(i));
70 |             }
71 |             return path.toString();
72 |         }
73 | 
74 |     }
75 | 
76 | }


--------------------------------------------------------------------------------
/music-server/src/main/resources/application-dev.properties:
--------------------------------------------------------------------------------
 1 | spring.datasource.url=jdbc:mysql://localhost:3306/tp_music?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
 2 | spring.datasource.username=root
 3 | spring.datasource.password=123456
 4 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
 5 | 
 6 | minio.endpoint=http://localhost:9000
 7 | minio.access-key=root
 8 | minio.secret-key=123456789
 9 | minio.bucket-name=user01
10 | # 文件上传的大小
11 | spring.servlet.multipart.max-file-size= 50MB
12 | # 文件上传的最大请求大小
13 | spring.servlet.multipart.max-request-size= 50MB
14 | 
15 | 


--------------------------------------------------------------------------------
/music-server/src/main/resources/application-prod.properties:
--------------------------------------------------------------------------------
1 | spring.datasource.url=jdbc:mysql://121.43.39.136:3306/tp_music?serverTimezone=GMT%2B8&useSSL=false
2 | spring.datasource.username=root
3 | spring.datasource.password=123456
4 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
5 | 


--------------------------------------------------------------------------------
/music-server/src/main/resources/application.properties:
--------------------------------------------------------------------------------
 1 | mybatis.typeAliasesPackage=com.example.yin.model.domain
 2 | mybatis.mapperLocations=classpath:mapper/*.xml
 3 | spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
 4 | spring.jackson.time-zone=GMT+8
 5 | server.port=8888
 6 | 
 7 | spring.devtools.restart.enabled=false
 8 | 
 9 | spring.devtools.restart.additional-paths=src/main/java
10 | 
11 | spring.devtools.restart.exclude=WEB-INF/**
12 | 
13 | logging.level.org.springframework.boot.autoconfigure=ERROR
14 | 
15 | spring.redis.host=127.0.0.1
16 | spring.redis.port=6379
17 | spring.redis.database=0
18 | spring.redis.timeout=1800000
19 | spring.redis.lettuce.pool.max-active=20
20 | spring.redis.lettuce.pool.max-wait=-1
21 | 
22 | spring.redis.lettuce.pool.max-idle=5
23 | spring.redis.lettuce.pool.min-idle=0
24 | spring.profiles.active=dev
25 | 


--------------------------------------------------------------------------------
/music-server/src/main/resources/application.yml:
--------------------------------------------------------------------------------
 1 | spring:
 2 |   mail:
 3 |     host: smtp.163.com # 网站发送邮件邮箱服务 host
 4 |     port: 465
 5 |     username:   # 开启那个服务的邮箱
 6 |     password:  # 开启服务的那个认证码
 7 |     properties:
 8 |       mail:
 9 |         smtp:
10 |           auth: true
11 |           socketFactory:
12 |             class: javax.net.ssl.SSLSocketFactory
13 |           starttls:
14 |             enable: true
15 | mail:
16 |   address:   # 开启那个服务的邮箱
17 | 
18 | mybatis-plus:
19 |   configuration:
20 |     log-impl: org.apache.ibatis.logging.stdout.StdOutImpl


--------------------------------------------------------------------------------
/music-server/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
 1 | # LOG4J
 2 | log4j.rootCategory=INFO, stdout,file
 3 | 
 4 | # print to console
 5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender
 6 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
 7 | log4j.appender.stdout.layout.ConversionPattern=%d{yy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n
 8 | 
 9 | # print to file
10 | log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
11 | log4j.appender.file.DatePattern='-'yyyy-MM-dd'.log'
12 | log4j.appender.file.File=./logs/musicWebsite
13 | log4j.appender.file.layout=org.apache.log4j.PatternLayout
14 | log4j.appender.file.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} %p [%c]: %m%n
15 | 


--------------------------------------------------------------------------------
/music-server/src/main/resources/mapper/AdminMapper.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 3 | <mapper namespace="com.example.yin.mapper.AdminMapper">
 4 |   <resultMap id="BaseResultMap" type="com.example.yin.model.domain.Admin">
 5 |     <id column="id" jdbcType="INTEGER" property="id" />
 6 |     <result column="name" jdbcType="VARCHAR" property="name" />
 7 |     <result column="password" jdbcType="VARCHAR" property="password" />
 8 |   </resultMap>
 9 |   <sql id="Base_Column_List">
10 |     id, name, password
11 |   </sql>
12 | 
13 | </mapper>
14 | 


--------------------------------------------------------------------------------
/music-server/src/main/resources/mapper/BannerMapper.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <!DOCTYPE mapper
 3 |         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4 |         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 | <mapper namespace="com.example.yin.mapper.BannerMapper">
 6 | 
 7 |     <resultMap id="BaseResultMap" type="com.example.yin.model.domain.Banner">
 8 |             <id property="id" column="id" jdbcType="INTEGER"/>
 9 |             <result property="pic" column="pic" jdbcType="VARCHAR"/>
10 |     </resultMap>
11 | 
12 |     <sql id="Base_Column_List">
13 |         id,pic
14 |     </sql>
15 | </mapper>
16 | 


--------------------------------------------------------------------------------
/music-server/src/main/resources/mapper/CollectMapper.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8" ?>
 2 | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 3 | <mapper namespace="com.example.yin.mapper.CollectMapper">
 4 |   <resultMap id="BaseResultMap" type="com.example.yin.model.domain.Collect">
 5 |     <id column="id" property="id" jdbcType="INTEGER" />
 6 |     <result column="user_id" property="userId" jdbcType="INTEGER" />
 7 |     <result column="type" property="type" jdbcType="TINYINT" />
 8 |     <result column="song_id" property="songId" jdbcType="INTEGER" />
 9 |     <result column="song_list_id" property="songListId" jdbcType="INTEGER" />
10 |     <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
11 |   </resultMap>
12 |   <sql id="Base_Column_List">
13 |     id, user_id, type, song_id, song_list_id, create_time
14 |   </sql>
15 | 
16 | </mapper>
17 | 


--------------------------------------------------------------------------------
/music-server/src/main/resources/mapper/CommentMapper.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8" ?>
 2 | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 3 | <mapper namespace="com.example.yin.mapper.CommentMapper">
 4 |   <resultMap id="BaseResultMap" type="com.example.yin.model.domain.Comment">
 5 |     <id column="id" property="id" jdbcType="INTEGER" />
 6 |     <result column="user_id" property="userId" jdbcType="INTEGER" />
 7 |     <result column="song_id" property="songId" jdbcType="INTEGER" />
 8 |     <result column="song_list_id" property="songListId" jdbcType="INTEGER" />
 9 |     <result column="content" property="content" jdbcType="VARCHAR" />
10 |     <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
11 |     <result column="type" property="type" jdbcType="TINYINT" />
12 |     <result column="up" property="up" jdbcType="INTEGER" />
13 |   </resultMap>
14 |   <sql id="Base_Column_List">
15 |     id, user_id, song_id, song_list_id, content, create_time, type, up
16 |   </sql>
17 | 
18 | </mapper>
19 | 


--------------------------------------------------------------------------------
/music-server/src/main/resources/mapper/ConsumerMapper.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8" ?>
 2 | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 3 | <mapper namespace="com.example.yin.mapper.ConsumerMapper">
 4 |   <resultMap id="BaseResultMap" type="com.example.yin.model.domain.Consumer">
 5 |     <result column="id" property="id" jdbcType="INTEGER" />
 6 |     <result column="username" property="username" jdbcType="VARCHAR" />
 7 |     <result column="password" property="password" jdbcType="VARCHAR" />
 8 |     <result column="sex" property="sex" jdbcType="TINYINT" />
 9 |     <result column="phone_num" property="phoneNum" jdbcType="CHAR" />
10 |     <result column="email" property="email" jdbcType="CHAR" />
11 |     <result column="birth" property="birth" jdbcType="TIMESTAMP" />
12 |     <result column="introduction" property="introduction" jdbcType="VARCHAR" />
13 |     <result column="location" property="location" jdbcType="VARCHAR" />
14 |     <result column="avator" property="avator" jdbcType="VARCHAR" />
15 |     <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
16 |     <result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />
17 |   </resultMap>
18 |   <sql id="Base_Column_List">
19 |     id, username, password, sex, phone_num, email, birth, introduction, location, avator, create_time, update_time
20 |   </sql>
21 | 
22 | </mapper>
23 | 


--------------------------------------------------------------------------------
/music-server/src/main/resources/mapper/ListSongMapper.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8" ?>
 2 | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 3 | <mapper namespace="com.example.yin.mapper.ListSongMapper">
 4 |   <resultMap id="BaseResultMap" type="com.example.yin.model.domain.ListSong">
 5 |     <id column="id" property="id" jdbcType="INTEGER" />
 6 |     <result column="song_id" property="songId" jdbcType="INTEGER" />
 7 |     <result column="song_list_id" property="songListId" jdbcType="INTEGER" />
 8 |   </resultMap>
 9 |   <sql id="Base_Column_List">
10 |     id, song_id, song_list_id
11 |   </sql>
12 | 
13 | </mapper>
14 | 


--------------------------------------------------------------------------------
/music-server/src/main/resources/mapper/RankListMapper.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8" ?>
 2 | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 3 | <mapper namespace="com.example.yin.mapper.RankListMapper">
 4 |   <resultMap id="BaseResultMap" type="com.example.yin.model.domain.RankList">
 5 |     <result column="id" property="id" jdbcType="BIGINT" />
 6 |     <result column="songListId" property="songListId" jdbcType="BIGINT" />
 7 |     <result column="consumerId" property="consumerId" jdbcType="BIGINT" />
 8 |     <result column="score" property="score" jdbcType="INTEGER" />
 9 |   </resultMap>
10 | 
11 |   <select id="selectScoreSum" resultType="java.lang.Integer">
12 |   SELECT COALESCE(sum(score), 0) as score from rank_list where song_list_id = #{0} ;
13 |   </select>
14 | 
15 |   <select id="selectUserRank" resultType="java.lang.Integer" parameterType="com.example.yin.model.domain.RankList">
16 |     select score
17 |     from rank_list
18 |     where consumer_id = #{consumer_id, jdbcType=BIGINT} and song_list_id = #{song_list_id, jdbcType=BIGINT}
19 |   </select>
20 | 
21 | </mapper>


--------------------------------------------------------------------------------
/music-server/src/main/resources/mapper/SingerMapper.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8" ?>
 2 | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 3 | <mapper namespace="com.example.yin.mapper.SingerMapper">
 4 |   <resultMap id="BaseResultMap" type="com.example.yin.model.domain.Singer">
 5 |     <id column="id" property="id" jdbcType="INTEGER" />
 6 |     <result column="name" property="name" jdbcType="VARCHAR" />
 7 |     <result column="sex" property="sex" jdbcType="TINYINT" />
 8 |     <result column="pic" property="pic" jdbcType="VARCHAR" />
 9 |     <result column="birth" property="birth" jdbcType="TIMESTAMP" />
10 |     <result column="location" property="location" jdbcType="VARCHAR" />
11 |     <result column="introduction" property="introduction" jdbcType="VARCHAR" />
12 |   </resultMap>
13 |   <sql id="Base_Column_List">
14 |     id, name, sex, pic, birth, location, introduction
15 |   </sql>
16 | 
17 | </mapper>
18 | 


--------------------------------------------------------------------------------
/music-server/src/main/resources/mapper/SongListMapper.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8" ?>
 2 | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 3 | <mapper namespace="com.example.yin.mapper.SongListMapper">
 4 |   <resultMap id="BaseResultMap" type="com.example.yin.model.domain.SongList">
 5 |     <id column="id" property="id" jdbcType="INTEGER" />
 6 |     <result column="title" property="title" jdbcType="VARCHAR" />
 7 |     <result column="pic" property="pic" jdbcType="VARCHAR" />
 8 |     <result column="style" property="style" jdbcType="VARCHAR" />
 9 |   </resultMap>
10 |   <resultMap id="ResultMapWithBLOBs" type="com.example.yin.model.domain.SongList" extends="BaseResultMap">
11 |     <result column="introduction" property="introduction" jdbcType="LONGVARCHAR" />
12 |   </resultMap>
13 |   <sql id="Base_Column_List">
14 |     id, title, pic, style
15 |   </sql>
16 |   <sql id="Blob_Column_List">
17 |     introduction
18 |   </sql>
19 | 
20 | </mapper>
21 | 


--------------------------------------------------------------------------------
/music-server/src/main/resources/mapper/SongMapper.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8" ?>
 2 | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 3 | <mapper namespace="com.example.yin.mapper.SongMapper">
 4 |   <resultMap id="BaseResultMap" type="com.example.yin.model.domain.Song">
 5 |     <id column="id" property="id" jdbcType="INTEGER" />
 6 |     <result column="singer_id" property="singerId" jdbcType="INTEGER" />
 7 |     <result column="name" property="name" jdbcType="VARCHAR" />
 8 |     <result column="introduction" property="introduction" jdbcType="VARCHAR" />
 9 |     <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
10 |     <result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />
11 |     <result column="pic" property="pic" jdbcType="VARCHAR" />
12 |     <result column="url" property="url" jdbcType="VARCHAR" />
13 |   </resultMap>
14 |   <resultMap id="ResultMapWithBLOBs" type="com.example.yin.model.domain.Song" extends="BaseResultMap">
15 |     <result column="lyric" property="lyric" jdbcType="LONGVARCHAR" />
16 |   </resultMap>
17 |   <sql id="Base_Column_List">
18 |     id, singer_id, name, introduction, create_time, update_time, pic
19 |   </sql>
20 |   <sql id="Blob_Column_List">
21 |     lyric
22 |   </sql>
23 | 
24 | </mapper>
25 | 


--------------------------------------------------------------------------------
/music-server/src/main/resources/mapper/UserSupportMapper.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <!DOCTYPE mapper
 3 |         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4 |         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 | <mapper namespace="com.example.yin.mapper.UserSupportMapper">
 6 | 
 7 |     <resultMap id="BaseResultMap" type="com.example.yin.model.domain.UserSupport">
 8 |             <id property="id" column="id" jdbcType="INTEGER"/>
 9 |             <result property="commentId" column="comment_id" jdbcType="INTEGER"/>
10 |             <result property="userId" column="user_id" jdbcType="INTEGER"/>
11 |     </resultMap>
12 | 
13 |     <sql id="Base_Column_List">
14 |         id,comment_id,user_id
15 |     </sql>
16 | </mapper>
17 | 


--------------------------------------------------------------------------------
/music-server/src/main/resources/mysql-connector-java-8.0.13.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Yin-Hongwei/music-website/2cccb623c437abc0b90c91948d2c559a387fd335/music-server/src/main/resources/mysql-connector-java-8.0.13.jar


--------------------------------------------------------------------------------
/music-server/src/test/java/com/example/yin/YinMusicApplicationTests.java:
--------------------------------------------------------------------------------
 1 | package com.example.yin;
 2 | 
 3 | import com.example.yin.service.impl.ConsumerServiceImpl;
 4 | import org.junit.jupiter.api.Test;
 5 | import org.junit.runner.RunWith;
 6 | import org.springframework.beans.factory.annotation.Autowired;
 7 | import org.springframework.boot.test.context.SpringBootTest;
 8 | import org.springframework.test.context.junit4.SpringRunner;
 9 | 
10 | @RunWith(SpringRunner.class)
11 | @SpringBootTest
12 | public class YinMusicApplicationTests {
13 | 
14 |     @Autowired
15 |     // private SongServiceImpl songService;
16 |     // private SingerServiceImpl singerService;
17 |     // private SongListServiceImpl songListService;
18 |     private ConsumerServiceImpl consumerService;
19 |     // private RankListServiceImpl rankListService;
20 | 
21 |     // @Test
22 |     // public void contextLoads() {
23 |     //
24 |     // }
25 | 
26 |     // @Test
27 |     // public void testRank(){
28 |     // Rank rank_list = new Rank();
29 |     // rank_list.setConsumerId(2L);
30 |     // rank_list.setScore(3);
31 |     // rank_list.setSongListId(2L);
32 |     // rankListService.insert(rank_list);
33 |     // System.out.println("歌单均分为"+rankListService.selectAverScore(2L));
34 |     // }
35 | 
36 |     // 歌曲
37 |     // @Test
38 |     // public void songTest(){
39 |     // Song song = new Song();
40 |     // song.setName("Sanna Nielsen-Undo");
41 |     // song.setPic("/img/songPic/1775711278864263.jpg");
42 |     // song.setSingerId(42);
43 |     // song.setCreateTime(new Date());
44 |     // song.setUpdateTime(new Date());
45 |     // song.setIntroduction("Undo");
46 |     // song.setLyric("[00:00:00]暂无歌词");
47 |     // song.setUrl("/song/Sanna Nielsen-Undo.mp3");
48 |     // songService.addSong(song);
49 |     // }
50 | 
51 |     // //歌手
52 |     // @Test
53 |     // public void singerTest(){
54 |     // Singer singer = new Singer();
55 |     // singer.setName("Álvaro Soler");
56 |     // singer.setSex(new Byte("1"));
57 |     // singer.setPic("/img/singerPic/soler.jpg");
58 |     // singer.setBirth(new Date());
59 |     // singer.setLocation("西班牙");
60 |     // singer.setIntroduction("全名是Álvaro Tauchert
61 |     // Soler,是一位新晋西班牙歌手,流行音乐作曲家。出生于1991年,西班牙巴塞罗纳。");
62 |     // singerService.addSinger(singer);
63 |     // }
64 |     // @Test
65 |     // public void singerTest2()
66 |     // {
67 |     // System.out.println(singerService.allSinger());
68 |     // }
69 | 
70 |     // 歌单
71 |     // @Test
72 |     // public void songListTest(){
73 |     //
74 |     // SongList songList = new SongList();
75 |     // songList.setTitle("国风传统器乐赏~~♪");
76 |     // songList.setPic("/img/songListPic/19169985230816413.jpg");
77 |     // songList.setIntroduction(" 都是自己很喜欢的吉他指弹");
78 |     // songList.setStyle("乐器");
79 |     // songListService.addSongList(songList);
80 |     // }
81 |     // @Test
82 |     // public void songListTest2()
83 |     // {
84 |     // System.out.println(songListService.allSongList());
85 |     // }
86 | 
87 |     // 用户
88 | 
89 |     @Test
90 |     public void consumerTest2()
91 |     {
92 |     System.out.println(consumerService.allUser());
93 |     }
94 | }
95 | 


--------------------------------------------------------------------------------