[
  {
    "path": ".vscode/settings.json",
    "content": "{\n  \"cSpell.words\": [\n    \"RCVD\",\n    \"autofocus\",\n    \"blogaaa\",\n    \"flexbox\",\n    \"vmax\",\n    \"zhidao\"\n  ]\n}"
  },
  {
    "path": "README.md",
    "content": "<h1 align=\"center\">Welcome to Music-player 👋</h1>\n\n<p align=\"center\">\n<img src=\"https://img.shields.io/badge/webpack-^3.6.0-informational\" alt=\"webpack\">\n<img src=\"https://img.shields.io/badge/vue-2.5.2-success\" alt=\"vue\">\n<img src=\"https://img.shields.io/badge/node-10.15.3-fa983a\" alt=\"node\">\n<img src=\"https://img.shields.io/badge/dependencies-up to date-8c7ae6\" alt=\"dependencies\">\n<img src=\"https://img.shields.io/badge/dev dependencies-up to date-44bd32\" alt=\"dev dependencies\">\n<p>\n\n## :speech_balloon:前言\n\n随着不断的学习 Vue，需要做一个小项目通过在实现项目过程中了解到更多的知识。随着如今人们对于音乐的需求，移动端的使用量愈发增加，项目通过 Vue 编写实现，全面借用**网易云音乐移动端**的 UI 设计、功能实现，努力做到以假乱真的效果。前几天便着手开始弄了,到今天为止也算是勉强能用了。\n\n> 本项目自行构思得出，由个人独立编写程序研究。\n\n**注：此项目纯属个人瞎搞，正常使用请选择[网易云音乐官方](https://music.163.com)客户端。**\n\n## :muscle: 项目目标\n\n全面实现移动端网易云音乐的功能\n\n> **项目还在编写完善中**\n\n## 🚀 如何运行\n\n> node 版本 `[10.15.3]`\n\n### ✨ 开发过程\n\n```\n# 克隆\ngit clone https://github.com/powerdong/Music-player.git\n```\n\n```\n# 打开项目目录\ncd Music-player\n\ncd musicPlayer\n```\n\n```\n# 安装依赖\nnpm install\n```\n\n```\n# 开启本地服务运行项目\nnpm run dev\n```\n\n**欢迎 star，欢迎 issue**\n\n### :eyes: 项目进度\n\n**上一次更新(2020-03-15)：** ~~登录功能bug修复~~\n\n**最近一次更新(2020-05-04)：** 歌单详情bug修复\n\n> 感谢大家的关注，最近在实习期间未能及时更新，最近发现网易的api返回有变化，回来改了一个问题\n\n### :memo: 版本更新\n\n- **版本信息：** 2.4.8-> 2.8.10\n- **时间：** 2019 年 12 月 7 日\n- **更新内容：**\n  - 增加发现页面下拉刷新+轻提示\n  - 增加电台排行页面主播榜\n  - 增加电台排行页面节目榜中 24 小时榜\n  - 增加电台排行页面电台榜中付费精品榜\n  - 修复登录页面不能返回 Bug\n  - 修复其他已知问题\n  - 优化结构\n\n使用中有任何问题或建议，欢迎 Issue！\n\n本项目在不断完善中，请大家拭目以待~\n\n## 技术栈\n\n### :point_right: 主要依赖\n\n- Vue 全家桶(使用 Vue-cli 作为构建工具)\n- WebPack4.0\n- ES6\n- Less\n- ESLint\n- Vant UI\n- [网易云音乐 API](https://binaryify.github.io/NeteaseCloudMusicApi/#/)\n\n### :clap: 项目演示\n\n[demo 地址](http://140.143.128.100:3000)（请用 chrome/firefox 手机模式预览） -- 暂时停止\n\n## :mega: 目标功能\n\n- [x] 手机登录、注册\n- [x] 修改密码\n- [x] 我的页面歌单信息\n- [x] 添加，删除歌单\n- [x] 最近播放\n- [x] 心动模式\n- [x] 我的电台\n- [x] 我的收藏\n- [x] 发现页面推荐歌单\n- [x] 发现页面新碟\n- [x] 发现页面新歌\n- [x] 发现页面每日推荐\n- [x] 发现页面歌单\n- [x] 视频页面\n- [ ] 朋友页面\n- [x] 歌单广场\n- [x] 新歌推荐\n- [x] 更多新碟\n- [x] 发现页面排行榜\n- [x] 发现页面电台\n- [x] 退出账号\n- [x] 发现页面私人 FM\n- [x] 搜索功能\n- [x] 搜索结果展示\n- [x] 热搜榜\n- [x] 历史记录\n- [x] 搜索推荐\n- [x] 歌手分类\n- [x] 播放功能(**小播放器进度条**)\n- [x] 播放列表\n- [x] 添加删除播放列表\n- [x] 签到\n- [x] 歌曲喜欢与否\n- [x] 专辑收藏与否\n- [x] 歌单评论\n- [x] 专辑评论\n- [x] 点赞、发送、删除评论\n- [x] 电台节目评论\n- [x] 视频评论\n- [x] 用户相关\n- [ ] 页面滚动加载\n- [ ] 左右滑动切换\n- [ ] 页面切换动画\n- [ ] 登陆情况判断\n- [ ] 全面优化&修复\n\n## :computer: 部分截图\n\n侧边账户中心\n\n![uDnX80.png](https://user-gold-cdn.xitu.io/2019/10/4/16d95706581a456f?w=472&h=837&f=png&s=45997)\n\n发现页面&每日推荐\n\n![uDuYM8.gif](https://user-gold-cdn.xitu.io/2019/10/4/16d9572548c6aaf3?w=491&h=838&f=gif&s=3519632)\n\n歌单&歌单详情\n\n![uDuGxf.gif](https://user-gold-cdn.xitu.io/2019/10/4/16d9572540c179b1?w=491&h=838&f=gif&s=2610859)\n\n排行榜&排行榜信息\n\n![uDu3Gt.gif](https://user-gold-cdn.xitu.io/2019/10/4/16d95725335944d7?w=491&h=838&f=gif&s=934318)\n\n我的页面&最近播放\n\n![uDu1PI.gif](https://user-gold-cdn.xitu.io/2019/10/4/16d95725267c98e0?w=491&h=838&f=gif&s=290121)\n\n我的歌单&播放歌曲\n\n![uDutsS.gif](https://user-gold-cdn.xitu.io/2019/10/4/16d9572557bd8143?w=491&h=838&f=gif&s=7018012)\n\n搜索展示\n\n![uDu8RP.gif](https://user-gold-cdn.xitu.io/2019/10/4/16d9572538e2c261?w=491&h=838&f=gif&s=1094604)\n\n## :page_with_curl: 项目布局\n\n```js\n.src\n+-- api\n|   +-- config.js // 存取相关的api地址\n|   +-- index.js // 请求相关的api方法\n+-- assets\n|   +-- styles\n    |   +-- border.css // 移动端的1px边框\n    |   +-- global.less // 全局应用样式\n    |   +-- reset.css // 重置样式\n    |   +-- resetEleUI.less // 修改elementUI组件样式\n|   +-- utils // 全局要使用的方法\n    |   +-- getPhone // 获取手机号码\n    |   +-- modalScroll // 处理移动端滚动条\n|   +-- Bus.js // Bus 总线\n|   +-- Mixins.js // 混入(mixin)\n+-- base // 存取页面公共的小组件\n    +-- albumPage // 歌单展示页面组件\n    +-- songListPage // 展示歌曲列表\n    +-- alert // 提示消息\n    +-- audioAllTitle // 播放全部标题行\n    +-- button // 登陆页面按钮\n    +-- djSublistCard // 类似于我的电台页面的长卡片组件\n    +-- generalNav // 通用页面顶部的标题行\n    +-- icon // 图标展示\n    +-- idxCard // 官方排行榜\n    +-- imgCard // 歌单的图片卡\n    +-- interchangeable // 用来展示搜索展示页面除单曲以外的项目\n    +-- loading // 转圈loading\n    +-- pageErrorInfo // 出错提醒\n    +-- pageErrorLoading // 页面加载loading\n    +-- searchInput // 搜索框\n    +-- slider // 播放列表滑块\n    +-- sliderNav // 滑动标题\n    +-- song // 歌曲项\n    +-- titleFooter // 搜索展示页综合页面各项通用头和尾\n+-- getInfos // 获取一些静态信息\n    +-- getData // 获取静态信息方法\n    +-- icon // 存取图标信息\n+-- pages // 项目路由页面\n+-- router // 路由配置\n    +-- index\n+-- store // vuex 配置使用\n    +-- action // 根级别的 action\n    +-- getter // 根级别的 getter\n    +-- index // 组装模块并导出 store 的地方\n    +-- mutation-types // 根级别的 mutation-types\n    +-- mutation // 根级别的 mutation\n    +-- state // 根级别的 state\n```\n\n## 打包日志\n\n![M0Apjg.png](https://s2.ax1x.com/2019/11/16/M0Apjg.png)\n\n![M0ASgS.png](https://s2.ax1x.com/2019/11/16/M0ASgS.png)\n\n> 本项目会长期更新，欢迎大家指出问题，共同学习\n\n## 作者\n\n👤 **Lambda**\n"
  },
  {
    "path": "musicPlayer/.babelrc",
    "content": "{\n  \"presets\": [\n    [\"env\", {\n      \"modules\": false,\n      \"targets\": {\n        \"browsers\": [\"> 1%\", \"last 2 versions\", \"not ie <= 8\"]\n      }\n    }],\n    \"stage-2\"\n  ],\n  \"plugins\": [\n    [\"import\", {\n      \"libraryName\": \"vant\",\n      \"libraryDirectory\": \"es\",\n      \"style\": true\n    }],\n    \"transform-vue-jsx\", \"transform-runtime\", [\n      \"component\",\n      {\n        \"libraryName\": \"element-ui\",\n        \"styleLibraryName\": \"theme-chalk\"\n      }\n    ]\n  ]\n}\n"
  },
  {
    "path": "musicPlayer/.editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\nindent_style = space\nindent_size = 2\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n"
  },
  {
    "path": "musicPlayer/.eslintignore",
    "content": "/build/\n/config/\n/dist/\n/*.js\n"
  },
  {
    "path": "musicPlayer/.eslintrc.js",
    "content": "// https://eslint.org/docs/user-guide/configuring\n\nmodule.exports = {\n  root: true,\n  parserOptions: {\n    parser: 'babel-eslint'\n  },\n  env: {\n    browser: true,\n  },\n  extends: [\n    // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention\n    // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.\n    'plugin:vue/essential', \n    // https://github.com/standard/standard/blob/master/docs/RULES-en.md\n    'standard'\n  ],\n  // required to lint *.vue files\n  plugins: [\n    'vue'\n  ],\n  // add your custom rules here\n  rules: {\n    // allow async-await\n    'generator-star-spacing': 'off',\n    // allow debugger during development\n    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',\n    // \"quotes\": [1, \"double\"]\n  }\n}\n"
  },
  {
    "path": "musicPlayer/.gitignore",
    "content": ".DS_Store\nnode_modules/\n/dist/\nsave/\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Editor directories and files\n.idea\n.vscode\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n"
  },
  {
    "path": "musicPlayer/.postcssrc.js",
    "content": "// https://github.com/michael-ciniawsky/postcss-load-config\n\nmodule.exports = {\n  \"plugins\": {\n    \"postcss-import\": {},\n    \"postcss-url\": {},\n    // to edit target browsers: use \"browserslist\" field in package.json\n    \"autoprefixer\": {}\n  }\n}\n"
  },
  {
    "path": "musicPlayer/README.md",
    "content": "# music-player\n\n> 高仿网易云音乐\n\n## Build Setup\n\n``` bash\n# install dependencies\nnpm install\n\n# serve with hot reload at localhost:8080\nnpm run dev\n\n# build for production with minification\nnpm run build\n\n# build for production and view the bundle analyzer report\nnpm run build --report\n```\n\nFor a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).\n"
  },
  {
    "path": "musicPlayer/build/build.js",
    "content": "'use strict'\nrequire('./check-versions')()\n\nprocess.env.NODE_ENV = 'production'\n\nconst ora = require('ora')\nconst rm = require('rimraf')\nconst path = require('path')\nconst chalk = require('chalk')\nconst webpack = require('webpack')\nconst config = require('../config')\nconst webpackConfig = require('./webpack.prod.conf')\n\nconst spinner = ora('building for production...')\nspinner.start()\n\nrm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {\n  if (err) throw err\n  webpack(webpackConfig, (err, stats) => {\n    spinner.stop()\n    if (err) throw err\n    process.stdout.write(stats.toString({\n      colors: true,\n      modules: false,\n      children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.\n      chunks: false,\n      chunkModules: false\n    }) + '\\n\\n')\n\n    if (stats.hasErrors()) {\n      console.log(chalk.red('  Build failed with errors.\\n'))\n      process.exit(1)\n    }\n\n    console.log(chalk.cyan('  Build complete.\\n'))\n    console.log(chalk.yellow(\n      '  Tip: built files are meant to be served over an HTTP server.\\n' +\n      '  Opening index.html over file:// won\\'t work.\\n'\n    ))\n  })\n})\n"
  },
  {
    "path": "musicPlayer/build/check-versions.js",
    "content": "'use strict'\nconst chalk = require('chalk')\nconst semver = require('semver')\nconst packageConfig = require('../package.json')\nconst shell = require('shelljs')\n\nfunction exec (cmd) {\n  return require('child_process').execSync(cmd).toString().trim()\n}\n\nconst versionRequirements = [\n  {\n    name: 'node',\n    currentVersion: semver.clean(process.version),\n    versionRequirement: packageConfig.engines.node\n  }\n]\n\nif (shell.which('npm')) {\n  versionRequirements.push({\n    name: 'npm',\n    currentVersion: exec('npm --version'),\n    versionRequirement: packageConfig.engines.npm\n  })\n}\n\nmodule.exports = function () {\n  const warnings = []\n\n  for (let i = 0; i < versionRequirements.length; i++) {\n    const mod = versionRequirements[i]\n\n    if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {\n      warnings.push(mod.name + ': ' +\n        chalk.red(mod.currentVersion) + ' should be ' +\n        chalk.green(mod.versionRequirement)\n      )\n    }\n  }\n\n  if (warnings.length) {\n    console.log('')\n    console.log(chalk.yellow('To use this template, you must update following to modules:'))\n    console.log()\n\n    for (let i = 0; i < warnings.length; i++) {\n      const warning = warnings[i]\n      console.log('  ' + warning)\n    }\n\n    console.log()\n    process.exit(1)\n  }\n}\n"
  },
  {
    "path": "musicPlayer/build/utils.js",
    "content": "'use strict'\nconst path = require('path')\nconst config = require('../config')\nconst ExtractTextPlugin = require('extract-text-webpack-plugin')\nconst packageConfig = require('../package.json')\n\nexports.assetsPath = function (_path) {\n  const assetsSubDirectory = process.env.NODE_ENV === 'production'\n    ? config.build.assetsSubDirectory\n    : config.dev.assetsSubDirectory\n\n  return path.posix.join(assetsSubDirectory, _path)\n}\n\nexports.cssLoaders = function (options) {\n  options = options || {}\n\n  const cssLoader = {\n    loader: 'css-loader',\n    options: {\n      sourceMap: options.sourceMap\n    }\n  }\n\n  const postcssLoader = {\n    loader: 'postcss-loader',\n    options: {\n      sourceMap: options.sourceMap\n    }\n  }\n\n  // generate loader string to be used with extract text plugin\n  function generateLoaders (loader, loaderOptions) {\n    const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]\n\n    if (loader) {\n      loaders.push({\n        loader: loader + '-loader',\n        options: Object.assign({}, loaderOptions, {\n          sourceMap: options.sourceMap\n        })\n      })\n    }\n\n    // Extract CSS when that option is specified\n    // (which is the case during production build)\n    if (options.extract) {\n      return ExtractTextPlugin.extract({\n        use: loaders,\n        fallback: 'vue-style-loader'\n      })\n    } else {\n      return ['vue-style-loader'].concat(loaders)\n    }\n  }\n\n  // https://vue-loader.vuejs.org/en/configurations/extract-css.html\n  return {\n    css: generateLoaders(),\n    postcss: generateLoaders(),\n    less: generateLoaders('less'),\n    sass: generateLoaders('sass', { indentedSyntax: true }),\n    scss: generateLoaders('sass'),\n    stylus: generateLoaders('stylus'),\n    styl: generateLoaders('stylus')\n  }\n}\n\n// Generate loaders for standalone style files (outside of .vue)\nexports.styleLoaders = function (options) {\n  const output = []\n  const loaders = exports.cssLoaders(options)\n\n  for (const extension in loaders) {\n    const loader = loaders[extension]\n    output.push({\n      test: new RegExp('\\\\.' + extension + '$'),\n      use: loader\n    })\n  }\n\n  return output\n}\n\nexports.createNotifierCallback = () => {\n  const notifier = require('node-notifier')\n\n  return (severity, errors) => {\n    if (severity !== 'error') return\n\n    const error = errors[0]\n    const filename = error.file && error.file.split('!').pop()\n\n    notifier.notify({\n      title: packageConfig.name,\n      message: severity + ': ' + error.name,\n      subtitle: filename || '',\n      icon: path.join(__dirname, 'logo.png')\n    })\n  }\n}\n"
  },
  {
    "path": "musicPlayer/build/vue-loader.conf.js",
    "content": "'use strict'\nconst utils = require('./utils')\nconst config = require('../config')\nconst isProduction = process.env.NODE_ENV === 'production'\nconst sourceMapEnabled = isProduction\n  ? config.build.productionSourceMap\n  : config.dev.cssSourceMap\n\nmodule.exports = {\n  loaders: utils.cssLoaders({\n    sourceMap: sourceMapEnabled,\n    extract: isProduction\n  }),\n  cssSourceMap: sourceMapEnabled,\n  cacheBusting: config.dev.cacheBusting,\n  transformToRequire: {\n    video: ['src', 'poster'],\n    source: 'src',\n    img: 'src',\n    image: 'xlink:href'\n  }\n}\n"
  },
  {
    "path": "musicPlayer/build/webpack.base.conf.js",
    "content": "/*\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-11-18 19:13:26\n * @Update log: 更新日志\n */\n'use strict'\nconst path = require('path')\nconst utils = require('./utils')\nconst config = require('../config')\nconst vueLoaderConfig = require('./vue-loader.conf')\n\nfunction resolve (dir) {\n  return path.join(__dirname, '..', dir)\n}\n\nconst createLintingRule = () => ({\n  test: /\\.(js|vue)$/,\n  loader: 'eslint-loader',\n  enforce: 'pre',\n  include: [resolve('src'), resolve('test')],\n  options: {\n    formatter: require('eslint-friendly-formatter'),\n    emitWarning: !config.dev.showEslintErrorsInOverlay\n  }\n})\n\nmodule.exports = {\n  context: path.resolve(__dirname, '../'),\n  entry: {\n    app: './src/main.js'\n  },\n  output: {\n    path: config.build.assetsRoot,\n    filename: '[name].js',\n    publicPath: process.env.NODE_ENV === 'production'\n      ? config.build.assetsPublicPath : config.dev.assetsPublicPath\n  },\n  resolve: {\n    extensions: ['.js', '.vue', '.json'],\n    alias: {\n      'vue$': 'vue/dist/vue.esm.js',\n      '@': resolve('src'),\n      'styles': resolve('src/assets/styles'),\n      'mixins': resolve('src/assets'),\n      'getInfos': resolve('src/getInfos'),\n      'base': resolve('src/base'),\n      'api': resolve('src/api'),\n      'utils': resolve('src/assets/utils')\n    }\n  },\n  module: {\n    rules: [\n      ...(config.dev.useEslint ? [createLintingRule()] : []),\n      {\n        test: /\\.vue$/,\n        loader: 'vue-loader',\n        options: vueLoaderConfig\n      },\n      {\n        test: /\\.js$/,\n        loader: 'babel-loader',\n        include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]\n      },\n      {\n        test: /\\.(png|jpe?g|gif|svg)(\\?.*)?$/,\n        loader: 'url-loader',\n        options: {\n          limit: 10000,\n          name: utils.assetsPath('img/[name].[hash:7].[ext]')\n        }\n      },\n      {\n        test: /\\.(mp4|webm|ogg|mp3|wav|flac|aac)(\\?.*)?$/,\n        loader: 'url-loader',\n        options: {\n          limit: 10000,\n          name: utils.assetsPath('media/[name].[hash:7].[ext]')\n        }\n      },\n      {\n        test: /\\.(woff2?|eot|ttf|otf)(\\?.*)?$/,\n        loader: 'url-loader',\n        options: {\n          limit: 10000,\n          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')\n        }\n      }\n    ]\n  },\n  node: {\n    // prevent webpack from injecting useless setImmediate polyfill because Vue\n    // source contains it (although only uses it if it's native).\n    setImmediate: false,\n    // prevent webpack from injecting mocks to Node native modules\n    // that does not make sense for the client\n    dgram: 'empty',\n    fs: 'empty',\n    net: 'empty',\n    tls: 'empty',\n    child_process: 'empty'\n  }\n}\n"
  },
  {
    "path": "musicPlayer/build/webpack.dev.conf.js",
    "content": "'use strict'\nconst utils = require('./utils')\nconst webpack = require('webpack')\nconst config = require('../config')\nconst merge = require('webpack-merge')\nconst path = require('path')\nconst baseWebpackConfig = require('./webpack.base.conf')\nconst CopyWebpackPlugin = require('copy-webpack-plugin')\nconst HtmlWebpackPlugin = require('html-webpack-plugin')\nconst FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')\nconst portfinder = require('portfinder')\n\nconst HOST = process.env.HOST\nconst PORT = process.env.PORT && Number(process.env.PORT)\n\nconst devWebpackConfig = merge(baseWebpackConfig, {\n  module: {\n    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })\n  },\n  // cheap-module-eval-source-map is faster for development\n  devtool: config.dev.devtool,\n\n  // these devServer options should be customized in /config/index.js\n  devServer: {\n    clientLogLevel: 'warning',\n    historyApiFallback: {\n      rewrites: [\n        { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },\n      ],\n    },\n    hot: true,\n    contentBase: false, // since we use CopyWebpackPlugin.\n    compress: true,\n    host: HOST || config.dev.host,\n    port: PORT || config.dev.port,\n    open: config.dev.autoOpenBrowser,\n    overlay: config.dev.errorOverlay\n      ? { warnings: false, errors: true }\n      : false,\n    publicPath: config.dev.assetsPublicPath,\n    proxy: config.dev.proxyTable,\n    quiet: true, // necessary for FriendlyErrorsPlugin\n    watchOptions: {\n      poll: config.dev.poll,\n    }\n  },\n  plugins: [\n    new webpack.DefinePlugin({\n      'process.env': require('../config/dev.env')\n    }),\n    new webpack.HotModuleReplacementPlugin(),\n    new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.\n    new webpack.NoEmitOnErrorsPlugin(),\n    // https://github.com/ampedandwired/html-webpack-plugin\n    new HtmlWebpackPlugin({\n      filename: 'index.html',\n      template: 'index.html',\n      inject: true\n    }),\n    // copy custom static assets\n    new CopyWebpackPlugin([\n      {\n        from: path.resolve(__dirname, '../static'),\n        to: config.dev.assetsSubDirectory,\n        ignore: ['.*']\n      }\n    ])\n  ]\n})\n\nmodule.exports = new Promise((resolve, reject) => {\n  portfinder.basePort = process.env.PORT || config.dev.port\n  portfinder.getPort((err, port) => {\n    if (err) {\n      reject(err)\n    } else {\n      // publish the new Port, necessary for e2e tests\n      process.env.PORT = port\n      // add port to devServer config\n      devWebpackConfig.devServer.port = port\n\n      // Add FriendlyErrorsPlugin\n      devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({\n        compilationSuccessInfo: {\n          messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],\n        },\n        onErrors: config.dev.notifyOnErrors\n        ? utils.createNotifierCallback()\n        : undefined\n      }))\n\n      resolve(devWebpackConfig)\n    }\n  })\n})\n"
  },
  {
    "path": "musicPlayer/build/webpack.prod.conf.js",
    "content": "'use strict'\nconst path = require('path')\nconst utils = require('./utils')\nconst webpack = require('webpack')\nconst config = require('../config')\nconst merge = require('webpack-merge')\nconst baseWebpackConfig = require('./webpack.base.conf')\nconst CopyWebpackPlugin = require('copy-webpack-plugin')\nconst HtmlWebpackPlugin = require('html-webpack-plugin')\nconst ExtractTextPlugin = require('extract-text-webpack-plugin')\nconst OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')\nconst UglifyJsPlugin = require('uglifyjs-webpack-plugin')\n\nconst env = require('../config/prod.env')\n\nconst webpackConfig = merge(baseWebpackConfig, {\n  module: {\n    rules: utils.styleLoaders({\n      sourceMap: config.build.productionSourceMap,\n      extract: true,\n      usePostCSS: true\n    })\n  },\n  devtool: config.build.productionSourceMap ? config.build.devtool : false,\n  output: {\n    path: config.build.assetsRoot,\n    filename: utils.assetsPath('js/[name].[chunkhash].js'),\n    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')\n  },\n  plugins: [\n    // http://vuejs.github.io/vue-loader/en/workflow/production.html\n    new webpack.DefinePlugin({\n      'process.env': env\n    }),\n    new UglifyJsPlugin({\n      uglifyOptions: {\n        compress: {\n          warnings: false\n        }\n      },\n      sourceMap: config.build.productionSourceMap,\n      parallel: true\n    }),\n    // extract css into its own file\n    new ExtractTextPlugin({\n      filename: utils.assetsPath('css/[name].[contenthash].css'),\n      // Setting the following option to `false` will not extract CSS from codesplit chunks.\n      // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.\n      // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, \n      // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110\n      allChunks: true,\n    }),\n    // Compress extracted CSS. We are using this plugin so that possible\n    // duplicated CSS from different components can be deduped.\n    new OptimizeCSSPlugin({\n      cssProcessorOptions: config.build.productionSourceMap\n        ? { safe: true, map: { inline: false } }\n        : { safe: true }\n    }),\n    // generate dist index.html with correct asset hash for caching.\n    // you can customize output by editing /index.html\n    // see https://github.com/ampedandwired/html-webpack-plugin\n    new HtmlWebpackPlugin({\n      filename: config.build.index,\n      template: 'index.html',\n      inject: true,\n      minify: {\n        removeComments: true,\n        collapseWhitespace: true,\n        removeAttributeQuotes: true\n        // more options:\n        // https://github.com/kangax/html-minifier#options-quick-reference\n      },\n      // necessary to consistently work with multiple chunks via CommonsChunkPlugin\n      chunksSortMode: 'dependency'\n    }),\n    // keep module.id stable when vendor modules does not change\n    new webpack.HashedModuleIdsPlugin(),\n    // enable scope hoisting\n    new webpack.optimize.ModuleConcatenationPlugin(),\n    // split vendor js into its own file\n    new webpack.optimize.CommonsChunkPlugin({\n      name: 'vendor',\n      minChunks (module) {\n        // any required modules inside node_modules are extracted to vendor\n        return (\n          module.resource &&\n          /\\.js$/.test(module.resource) &&\n          module.resource.indexOf(\n            path.join(__dirname, '../node_modules')\n          ) === 0\n        )\n      }\n    }),\n    // extract webpack runtime and module manifest to its own file in order to\n    // prevent vendor hash from being updated whenever app bundle is updated\n    new webpack.optimize.CommonsChunkPlugin({\n      name: 'manifest',\n      minChunks: Infinity\n    }),\n    // This instance extracts shared chunks from code splitted chunks and bundles them\n    // in a separate chunk, similar to the vendor chunk\n    // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk\n    new webpack.optimize.CommonsChunkPlugin({\n      name: 'app',\n      async: 'vendor-async',\n      children: true,\n      minChunks: 3\n    }),\n\n    // copy custom static assets\n    new CopyWebpackPlugin([\n      {\n        from: path.resolve(__dirname, '../static'),\n        to: config.build.assetsSubDirectory,\n        ignore: ['.*']\n      }\n    ])\n  ]\n})\n\nif (config.build.productionGzip) {\n  const CompressionWebpackPlugin = require('compression-webpack-plugin')\n\n  webpackConfig.plugins.push(\n    new CompressionWebpackPlugin({\n      asset: '[path].gz[query]',\n      algorithm: 'gzip',\n      test: new RegExp(\n        '\\\\.(' +\n        config.build.productionGzipExtensions.join('|') +\n        ')$'\n      ),\n      threshold: 10240,\n      minRatio: 0.8\n    })\n  )\n}\n\nif (config.build.bundleAnalyzerReport) {\n  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin\n  webpackConfig.plugins.push(new BundleAnalyzerPlugin())\n}\n\nmodule.exports = webpackConfig\n"
  },
  {
    "path": "musicPlayer/config/dev.env.js",
    "content": "'use strict'\nconst merge = require('webpack-merge')\nconst prodEnv = require('./prod.env')\n\nmodule.exports = merge(prodEnv, {\n  NODE_ENV: '\"development\"'\n})\n"
  },
  {
    "path": "musicPlayer/config/index.js",
    "content": "/*\n * @Author: 李浩栋\n * @Begin: 2019-07-16 19:49:41\n * @Update: 2019-08-18 19:16:52\n * @Update log: 更新日志\n */\n'use strict'\n// Template version: 1.3.1\n// see http://vuejs-templates.github.io/webpack for documentation.\n\nconst path = require('path')\n\nmodule.exports = {\n  dev: {\n    // Paths\n    assetsSubDirectory: 'static',\n    assetsPublicPath: '/',\n    proxyTable: {// 输入/api 让其去访问http://localhost:3000/api\n      '/api': {\n        target: 'http://140.143.128.100:3000', // 设置调用的接口域名和端口号 ( 设置代理目标)\n        changeOrigin: true,\n        pathRewrite: {\n\n          '^/api': '' // 这是一个通配符，设置完了之后每个接口都要在前面加上/api（特别注意这一点）\n        }\n      }\n    },\n    // Various Dev Server settings\n    host: 'localhost', // can be overwritten by process.env.HOST\n    port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined\n    autoOpenBrowser: false,\n    errorOverlay: true,\n    notifyOnErrors: true,\n    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-\n\n    // Use Eslint Loader?\n    // If true, your code will be linted during bundling and\n    // linting errors and warnings will be shown in the console.\n    useEslint: true,\n    // If true, eslint errors and warnings will also be shown in the error overlay\n    // in the browser.\n    showEslintErrorsInOverlay: false,\n\n    /**\n     * Source Maps\n     */\n\n    // https://webpack.js.org/configuration/devtool/#development\n    devtool: 'cheap-module-eval-source-map',\n\n    // If you have problems debugging vue-files in devtools,\n    // set this to false - it *may* help\n    // https://vue-loader.vuejs.org/en/options.html#cachebusting\n    cacheBusting: true,\n\n    cssSourceMap: true\n  },\n\n  build: {\n    // Template for index.html\n    index: path.resolve(__dirname, '../dist/index.html'),\n\n    // Paths\n    assetsRoot: path.resolve(__dirname, '../dist'),\n    assetsSubDirectory: 'static',\n    assetsPublicPath: '/',\n\n    /**\n     * Source Maps\n     */\n\n    productionSourceMap: true,\n    // https://webpack.js.org/configuration/devtool/#production\n    devtool: '#source-map',\n\n    // Gzip off by default as many popular static hosts such as\n    // Surge or Netlify already gzip all static assets for you.\n    // Before setting to `true`, make sure to:\n    // npm install --save-dev compression-webpack-plugin\n    productionGzip: false,\n    productionGzipExtensions: ['js', 'css'],\n\n    // Run the build command with an extra argument to\n    // View the bundle analyzer report after build finishes:\n    // `npm run build --report`\n    // Set to `true` or `false` to always turn it on or off\n    bundleAnalyzerReport: process.env.npm_config_report\n  }\n}\n"
  },
  {
    "path": "musicPlayer/config/prod.env.js",
    "content": "'use strict'\nmodule.exports = {\n  NODE_ENV: '\"production\"'\n}\n"
  },
  {
    "path": "musicPlayer/index.html",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-11-04 13:34:22\n * @Update log: 更新日志\n -->\n<!DOCTYPE html>\n<html>\n\n<head>\n  <meta charset=\"utf-8\">\n  <meta name=\"viewport\"\n    content=\"width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no\">\n  <meta name=\"referrer\" content=\"never\">\n  <meta name=\"referrer\" content=\"no-referrer\">\n  <link href=\"http://p3.music.126.net/tBTNafgjNnTL1KlZMt7lVA==/18885211718935735.jpg\" rel=\"shortcut icon\">\n  <style>\n    html,\n    body {\n      overflow-x: hidden;\n      overflow-y: auto;\n    }\n\n    body {\n      position: relative;\n      font-family: Arial, \"Microsoft Yahei\", \"Helvetica Neue\", Helvetica, sans-serif;\n    }\n\n    #load {\n      width: 100vw;\n      height: 100vh;\n      display: none;\n      overflow: hidden;\n      background-color: #dd001b;\n      position: absolute;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      font-size: 10px;\n      z-index: 999;\n    }\n\n    .index-title {\n      position: absolute;\n      top: 2.3em;\n      width: 100%;\n      color: #fff;\n      font-size: 4.6em;\n      line-height: 1.5;\n      text-align: center;\n      opacity: 0;\n      animation: titleIn 1s both;\n    }\n\n    .index-icon {\n      position: absolute;\n      bottom: 3em;\n      font-size: 2em;\n      line-height: 1.5;\n      width: 100%;\n      color: #fff;\n      text-align: center;\n      float: right;\n      opacity: 0;\n      animation: iconIn 3s 2s both;\n    }\n\n    @keyframes titleIn {\n      100% {\n        opacity: 1;\n      }\n    }\n\n    @keyframes iconIn {\n      100% {\n        opacity: 1;\n      }\n    }\n\n  </style>\n  <title>music-player</title>\n</head>\n\n<body>\n  <div id=\"load\">\n    <p class=\"index-title\">音樂的力量</p>\n    <p class=\"index-icon\"><svg t=\"1567819718363\" class=\"icon\" style=\"transform: translateY(40%)\" viewBox=\"0 0 1024 1024\"\n        version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"1950\" width=\"50\" height=\"50\">\n        <path\n          d=\"M268.2 89.2h498.9c92 0 166.3 74.3 166.3 166.3v498.9c0 92-74.3 166.3-166.3 166.3H268.2c-92 0-166.3-74.3-166.3-166.3V255.5c0-92 74.3-166.3 166.3-166.3z m0 0\"\n          fill=\"#D92916\" p-id=\"1951\"></path>\n        <path\n          d=\"M640 196.4c19.7 4.8 38.2 13.8 54.2 26.2 6.1 4.3 10.8 10.1 13.8 16.9 4.3 10.6 3.2 22.6-3.1 32.1-10.2 15.9-31.3 20.7-47.3 10.7-3.8-2.4-6.6-5.9-10.4-7.9-10.1-7.1-22.1-11.1-34.5-11.4-8.5 0.9-16.4 5-22.1 11.4-5.7 5.8-8.2 14.1-6.6 22.1l12.8 48c30.7 1.2 60.6 9.9 87 25.5 25.6 15.7 48.2 35.9 66.6 59.7 15.7 20.6 27.4 44.1 34.5 69 7.5 25.9 10.5 52.9 8.6 79.7-1.6 22.6-6.3 44.9-13.8 66.3-19.9 52.4-56.2 97-103.6 127-34.7 21.6-73.7 35.3-114.3 40-27.8 4.1-56.1 4.1-83.9 0-57.6-10-110.6-38.1-151.2-80.1-71-72-100.6-175.1-78.4-273.8 20.6-93.6 85.9-171 174.7-207.1 12.6-5 26.7-4.2 38.7 2.1 10.3 7.4 15.8 19.9 14.2 32.5-1.5 12.8-10 23.7-22.1 28.3-76.2 29-130.3 97.4-141.2 178.1-5 37.1-0.7 74.8 12.4 109.8 18.8 51.1 55.6 93.6 103.6 119.4 29.1 15.1 61.4 23 94.2 22.8 27-0.2 53.7-4.9 79.1-14.2 43.7-15.6 80.2-46.8 102.2-87.7 5.5-9.8 9.9-20.3 13.1-31.1 9.1-31.3 9.1-64.6 0-96-8-26.1-23.2-49.4-43.8-67.3-9-7.9-18.7-15-29-21.1-9.1-5-18.9-8.7-29-11 6.9 27.6 14.5 55.2 21.7 83.2l3.5 20c1.9 57.7-38.3 108.3-94.9 119.4-28.6 5.7-58.3 0.1-82.9-15.5-22.9-15.2-40.1-37.5-49-63.5-5.1-14.6-7.8-29.8-8.3-45.2-1.8-33.8 7.4-67.2 26.2-95.3 23.3-32.6 57.3-56 96-66.3l-8.3-32.1c-7-22.9-5.1-47.5 5.2-69 6.1-12 14.5-22.7 24.9-31.4 10.5-10.2 23.1-17.9 36.9-22.8 17.5-4.7 36-4.9 53.6-0.4z m0 0\"\n          fill=\"#FFFFFF\" p-id=\"1952\"></path>\n        <path\n          d=\"M497.4 448.4c-10.2 10.8-17.3 24.1-20.4 38.7-2.6 13.2-2.6 26.8 0 40 2.6 14.9 10.8 28.2 22.8 37.3 10.1 6.9 22.6 9.3 34.5 6.6 21.8-4.2 37.8-22.7 39-44.9-0.7-5.4-1.7-10.7-3.1-15.9l-23.8-90.1c-18.5 5-35.4 14.7-49 28.3z m0 0\"\n          fill=\"#D92916\" p-id=\"1953\"></path>\n      </svg>网易云音乐</p>\n  </div>\n  <div id=\"app\"\"></div>\n    <!-- built files will be auto injected -->\n    <script>\n      const load = document.getElementById('load')\n      const body = document.getElementsByTagName('body')[0]\n      let data = sessionStorage.getItem('load');\n        console.log(!data);\n      if (!data) {\n        setLoad(body, load)\n      }\n\n      function setLoad(body, load) {\n        console.log('执行了')\n        body.style.overflow = 'hidden';\n        load.style.display = 'block';\n        sessionStorage.setItem('load', 1);\n        setTimeout(() => {\n          load.style.display = 'none'\n          body.style.overflow = '';\n        }, 5000);\n      }\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "musicPlayer/package.json",
    "content": "{\n  \"name\": \"music-player\",\n  \"version\": \"1.0.0\",\n  \"description\": \"高仿网易云音乐\",\n  \"author\": \"powerdong <m19893170798@163.com>\",\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"webpack-dev-server --inline --progress --host 0.0.0.0 --config build/webpack.dev.conf.js\",\n    \"start\": \"npm run dev\",\n    \"lint\": \"eslint --ext .js,.vue src\",\n    \"build\": \"node build/build.js\"\n  },\n  \"dependencies\": {\n    \"axios\": \"^0.19.0\",\n    \"core-js\": \"3\",\n    \"fastclick\": \"^1.0.6\",\n    \"less\": \"^3.9.0\",\n    \"less-loader\": \"^5.0.0\",\n    \"qs\": \"^6.8.0\",\n    \"vant\": \"^2.2.10\",\n    \"vue\": \"^2.5.2\",\n    \"vue-lazyload\": \"^1.3.2\",\n    \"vue-router\": \"^3.0.1\",\n    \"vuex\": \"^3.1.1\"\n  },\n  \"devDependencies\": {\n    \"autoprefixer\": \"^7.1.2\",\n    \"babel-core\": \"^6.22.1\",\n    \"babel-eslint\": \"^8.2.1\",\n    \"babel-helper-vue-jsx-merge-props\": \"^2.0.3\",\n    \"babel-loader\": \"^7.1.1\",\n    \"babel-plugin-component\": \"^1.1.1\",\n    \"babel-plugin-import\": \"^1.12.2\",\n    \"babel-plugin-syntax-jsx\": \"^6.18.0\",\n    \"babel-plugin-transform-runtime\": \"^6.22.0\",\n    \"babel-plugin-transform-vue-jsx\": \"^3.5.0\",\n    \"babel-preset-env\": \"^1.3.2\",\n    \"babel-preset-stage-2\": \"^6.22.0\",\n    \"chalk\": \"^2.0.1\",\n    \"copy-webpack-plugin\": \"^4.0.1\",\n    \"css-loader\": \"^0.28.0\",\n    \"eslint\": \"^4.15.0\",\n    \"eslint-config-standard\": \"^10.2.1\",\n    \"eslint-friendly-formatter\": \"^3.0.0\",\n    \"eslint-loader\": \"^1.7.1\",\n    \"eslint-plugin-import\": \"^2.7.0\",\n    \"eslint-plugin-node\": \"^5.2.0\",\n    \"eslint-plugin-promise\": \"^3.4.0\",\n    \"eslint-plugin-standard\": \"^3.0.1\",\n    \"eslint-plugin-vue\": \"^4.0.0\",\n    \"extract-text-webpack-plugin\": \"^3.0.0\",\n    \"file-loader\": \"^1.1.4\",\n    \"friendly-errors-webpack-plugin\": \"^1.6.1\",\n    \"html-webpack-plugin\": \"^2.30.1\",\n    \"node-notifier\": \"^5.1.2\",\n    \"optimize-css-assets-webpack-plugin\": \"^3.2.0\",\n    \"ora\": \"^1.2.0\",\n    \"portfinder\": \"^1.0.13\",\n    \"postcss-import\": \"^11.0.0\",\n    \"postcss-loader\": \"^2.0.8\",\n    \"postcss-url\": \"^7.2.1\",\n    \"rimraf\": \"^2.6.0\",\n    \"semver\": \"^5.3.0\",\n    \"shelljs\": \"^0.7.6\",\n    \"url-loader\": \"^0.5.8\",\n    \"vue-loader\": \"^13.3.0\",\n    \"vue-style-loader\": \"^3.0.1\",\n    \"vue-template-compiler\": \"^2.5.2\",\n    \"webpack\": \"^3.6.0\",\n    \"webpack-bundle-analyzer\": \"^2.9.0\",\n    \"webpack-dev-server\": \"^2.9.1\",\n    \"webpack-merge\": \"^4.1.0\"\n  },\n  \"engines\": {\n    \"node\": \">= 6.0.0\",\n    \"npm\": \">= 3.0.0\"\n  }\n}\n"
  },
  {
    "path": "musicPlayer/src/App.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-08-30 19:47:55\n * @Update: 2020-03-13 22:38:04\n * @Update log: 更新日志\n -->\n<template>\n  <div id=\"app\">\n    <transition name=\"router-fade\" mode=\"out-in\">\n      <keep-alive exclude=\"phoneVerify, phonePwd\">\n        <router-view></router-view>\n        <!-- <router-view v-if=\"$route.meta.keepAlive\"></router-view> -->\n      </keep-alive>\n      <!-- </transition>\n      <transition name=\"router-fade\" mode=\"out-in\">\n      <router-view v-if=\"!$route.meta.keepAlive\"></router-view>-->\n    </transition>\n    <!-- 通过查看播放列表的length来看看播放页面是否可以显示 -->\n    <play-song v-show=\"AUDIO_LIST.length\"></play-song>\n  </div>\n</template>\n\n<script>\nimport playSong from '@/pages/audioIndex'\nimport { mapGetters } from 'vuex'\nexport default {\n  name: 'App',\n  components: {\n    playSong\n  },\n  computed: {\n    ...mapGetters([\n      'FULL_SCREEN',\n      'AUDIO_LIST'\n    ])\n  },\n  data () {\n    return {\n      show: false\n    }\n  }\n}\n</script>\n\n<style lang=\"less\">\n#app {\n  height: 100vh;\n  width: 100vw;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/api/config.js",
    "content": "/*\n * @Author: 李浩栋\n * @Begin: 2019-08-19 13:42:17\n * @Update: 2019-12-03 13:37:22\n * @Update log: 更新日志\n */\nconst api = process.env.NODE_ENV === 'development' ? '/api' : ''\n\n// ===================发现页面\nexport const bannerSwiper = api + '/banner?type=1' // 请求发现页面轮播图\nexport const recSongList = api + '/top/playlist' // 推荐歌单，歌单广场\nexport const highquality = api + '/top/playlist/highquality' // 精品歌单\nexport const catlist = api + '/playlist/catlist' // 获取歌单分类 !!!\nexport const hot = api + '/playlist/hot' // 获取热门歌单分类 !!!\nexport const topList = api + '/toplist/detail' // 获取所有榜单内容摘要\nexport const idxList = api + '/top/list' // 获取排行榜\nexport const albumDetail = api + '/playlist/detail' // 获取歌单详情\nexport const recSongs = api + '/recommend/songs' // 每日推荐歌曲\nexport const dateRecSongList = api + '/recommend/resource' // 每日推荐歌单，发现页展示的那六个\nexport const newDish = api + '/top/album' // 发现页新碟\nexport const getDishInfo = api + '/album' // 获取专辑内容\nexport const newSongs = api + '/top/song' // 发现页新歌\nexport const personalFm = api + '/personal_fm' // 发现页私人FM\n// ======================播放歌曲\nexport const songUrl = api + '/song/url' // 获取歌曲url\nexport const checkSong = api + '/check/music' // 查看歌曲是否可用\nexport const songLyric = api + '/lyric' // 获取歌词\nexport const heartMode = api + '/playmode/intelligence/list' // 心动模式播放\nexport const likeMusicList = api + '/likelist' // 喜欢歌曲列表\nexport const likeMusic = api + '/like' // 喜欢歌曲\n// ===================登陆\nexport const phoneLogin = api + '/login/cellphone' // 手机号登陆\nexport const phoneRegistered = api + '/cellphone/existence/check' // 手机号是否被注册\nexport const sendVerify = api + '/captcha/sent' // 发送验证码\nexport const verify = api + '/captcha/verify' // 验证验证码\nexport const loginStatus = api + '/login/status' // 登录状态\nexport const logout = api + '/logout' // 退出登录\nexport const signIn = api + '/daily_signin' // 签到\nexport const register = api + '/register/cellphone' // 注册修改密码\n// ===================我的页面相关\nexport const userRecord = api + '/user/record' // 用户播放记录\nexport const userInfo = api + '/user/subcount' // 用户信息\nexport const userDetail = api + '/user/detail' // 用户详情\nexport const userEvent = api + '/user/event' // 用户动态\nexport const playlist = api + '/user/playlist' // 用户歌单\nexport const userDj = api + '/user/dj' // 用户电台 申请做主播那一行\nexport const favoriteAlbums = api + '/album/sublist' // 获取收藏的专辑\nexport const favoriteArtists = api + '/artist/sublist' // 获取收藏的歌手\nexport const favoriteVideos = api + '/mv/sublist' // 获取收藏的视频\nexport const djSublist = api + '/dj/sublist' // 获取订阅的电台\n// =================视频页面下相关\nexport const getVideoTag = api + '/video/group/list' // 获取视频标签导航\nexport const getVideoGroup = api + '/video/group' // 获取对应标签的视频详情\nexport const getVideoUrl = api + '/video/url' // 获取视频播放地址\nexport const getVideoDetail = api + '/video/detail' // 获取视频详情\nexport const getVideoRelated = api + '/related/allvideo' // 获取相关视频\nexport const getVideoComments = api + '/comment/video' // 获取视频评论\n// ==================搜索页面相关\nexport const search = api + '/search' // 搜索关键词\nexport const defaultSearch = api + '/search/default' // 默认搜索关键词\nexport const suggestSearch = api + '/search/suggest' // 搜索建议\nexport const hotSearchList = api + '/search/hot/detail' // 热搜列表\nexport const singerClass = api + '/artist/list' // 歌手分类\n// =================朋友页面\nexport const friend = api + '/event' // 获取朋友页面的动态\n// =================歌单事件\nexport const addOrDeletePlaylist = api + '/playlist/subscribe' // 收藏/取消收藏歌单\nexport const addPlaylist = api + '/playlist/create' // 添加歌单\nexport const deletePlaylist = api + '/playlist/delete' // 删除歌单\n// ================发现页面的电台页面\nexport const djBanner = api + '/dj/banner' // 电台页面的轮播图\nexport const radioRecommendations = api + '/dj/today/perfered' // 电台推荐数据\nexport const boutiqueRecommendations = api + '/dj/paygift' // 电台精品推荐\nexport const djClassification = api + '/dj/catelist' // 电台分类\nexport const djClassificationInfo = api + '/dj/recommend/type' // 电台分类推荐\nexport const djProgram = api + '/dj/program' // 电台节目\nexport const djDetail = api + '/dj/detail' // 电台详情\nexport const djPayGift = api + '/dj/paygift' // 电台付费精选\nexport const djSub = api + '/dj/sub' // 订阅/取消订阅电台\nexport const djToplist = api + '/dj/program/toplist' // 获取最热节目\nexport const djHotToplist = api + '/dj/toplist' // 获取电台榜\nexport const djProgramTopHours = api + '/dj/program/toplist/hours' // 获取节目榜24小时榜\nexport const djToplistHours = api + '/dj/toplist/hours' // 获取主播榜24小时榜\nexport const djToplistNewComers = api + '/dj/toplist/newcomer' // 获取主播榜新人榜\nexport const djToplistPopulars = api + '/dj/toplist/popular' // 获取主播榜最热主播\nexport const djToplistPays = api + '/dj/toplist/pay' // 获取电台磅付费精品榜\n// ================评论页面相关\nexport const commentPlaylist = api + '/comment/playlist' // 获取歌单的评论\nexport const commentAlbum = api + '/comment/album' // 获取专辑的评论\nexport const commentDj = api + '/comment/dj' // 获取电台节目评论\nexport const commentLike = api + '/comment/like' // 给评论点赞\nexport const pushOrDeleteCom = api + '/comment' // 发送删除评论\nexport const resourceLike = api + '/resource/like' // 资源点赞\n"
  },
  {
    "path": "musicPlayer/src/api/index.js",
    "content": "/*\n * @Author: 李浩栋\n * @Begin: 2019-08-19 13:47:19\n * @Update: 2019-12-08 12:02:19\n * @Update log: 更新日志\n */\nimport axios from 'axios'\nimport {\n  bannerSwiper,\n  recSongList,\n  highquality,\n  recSongs,\n  topList,\n  dateRecSongList,\n  newDish,\n  phoneLogin,\n  albumDetail,\n  sendVerify,\n  verify,\n  phoneRegistered,\n  loginStatus,\n  userRecord,\n  userInfo,\n  playlist,\n  userDj,\n  hotSearchList,\n  search,\n  defaultSearch,\n  suggestSearch,\n  songUrl,\n  checkSong,\n  songLyric,\n  idxList,\n  addOrDeletePlaylist,\n  addPlaylist,\n  deletePlaylist,\n  heartMode,\n  favoriteAlbums,\n  favoriteArtists,\n  favoriteVideos,\n  djSublist,\n  newSongs,\n  getDishInfo,\n  personalFm,\n  singerClass,\n  logout,\n  radioRecommendations,\n  boutiqueRecommendations,\n  djClassification,\n  djClassificationInfo,\n  djProgram,\n  djDetail,\n  djPayGift,\n  djSub,\n  djBanner,\n  djToplist,\n  djHotToplist,\n  likeMusicList,\n  likeMusic,\n  userDetail,\n  signIn,\n  friend,\n  getVideoTag,\n  getVideoGroup,\n  commentPlaylist,\n  commentLike,\n  commentAlbum,\n  userEvent,\n  pushOrDeleteCom,\n  getVideoUrl,\n  register,\n  commentDj,\n  getVideoDetail,\n  getVideoRelated,\n  getVideoComments,\n  resourceLike,\n  djProgramTopHours,\n  djToplistHours,\n  djToplistNewComers,\n  djToplistPopulars,\n  djToplistPays\n} from './config'\n// 请求超时时间\naxios.defaults.timeout = 30000\n\n// post请求头\naxios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'\n\n/**\n * 以后可以利用 ES6 的解构赋值进行重构\n * function personInfo({ name, age, address, gender }) {\n      console.log(name, age, address, gender)\n    }\n    personInfo({ gender: 'man', address: 'changsha', name: 'william', age: 18 })\n\n    function saveInfo({\n      name = 'william',\n      age = 18,\n      address = 'changsha',\n      gender = 'man'\n    } = {}) {\n      console.log(name, age, address, gender)\n    }\n    saveInfo()\n */\n\nexport default {\n  /**\n   * 请求发现页面首页轮播图\n   */\n  bannerSwiperFn () {\n    return axios.get(bannerSwiper)\n  },\n  /**\n   * 调用此接口 , 可获得每日推荐歌曲 ( 需要登录 )\n   */\n  recSongsFn () {\n    return axios.get(recSongs)\n  },\n  /**\n   * 调用此接口 , 传入歌单 id, 可 以获取对应歌单内的所有的音乐\n   * @param {*} id 歌单 id\n   * @param {*} s 歌单最近的 s 个收藏者,默认5个\n   */\n  albumDetailFn (id, s = 5) {\n    return axios.get(albumDetail, {\n      params: {\n        id,\n        s\n      }\n    })\n  },\n  /**\n   * 调用此接口,可获取所有榜单内容摘要\n   */\n  topListFn () {\n    return axios.get(topList)\n  },\n  /**\n   * 请求 可获取推荐歌单\n   * ?limit=10&order=hot\n   * @param {*} limit 取出数量，默认是30\n   * @param {*} order 分别对应最新和最热,可选值为 'new' 和 'hot'\n   * @param {*} cat tag, 比如 \" 华语 \"、\" 古风 \" 、\" 欧美 \"、\" 流行 \", 默认为 \"全部\",\n   *  :( 页数 -1)*30, 其中 30 为 limit 的值 , 默认 为 0\n   */\n  recSongListFn (limit = 30, order = 'hot', cat) {\n    return axios.get(recSongList, {\n      params: {\n        limit,\n        order,\n        cat\n      }\n    })\n  },\n  /**\n   * 获取精品歌单\n   * @param {*} limit 取出歌单数量 , 默认为 30\n   * @param {*} before 分页参数,取上一页最后一个歌单的 updateTime 获取下一页数据\n   * @param {*} cat cat: tag\n   */\n  highqualityFn (limit = 30, before, cat) {\n    return axios.get(highquality, {\n      params: {\n        limit,\n        before,\n        cat\n      }\n    })\n  },\n  /**\n   * 调用此接口 , 传入数字 idx, 可获取不同排行榜\n   * @param {*} idx 排行榜 idx\n   */\n  idxListFn (idx) {\n    return axios.get(idxList, {\n      params: {\n        idx\n      }\n    })\n  },\n  /**\n   * 可获得每日推荐歌单 ( 需要登录 )\n   */\n  dateRecSongListFn () {\n    return axios.get(dateRecSongList)\n  },\n  /**\n   * 调用此接口 , 可获取新碟上架列表\n   * @param {*} limit 取出数量 , 默认为 50\n   * @param {*} offset 偏移数量 , 用于分页\n   *  如 :( 页数 -1)*50, 其中 50 为 limit 的值 , 默认 为 0\n   */\n  newDishFn (limit = 10, offset) {\n    return axios.get(newDish, {\n      params: {\n        limit,\n        offset\n      }\n    })\n  },\n  /**\n   * 调用此接口 , 传入专辑 id, 可获得专辑内容\n   * @param {*} id 专辑id\n   */\n  getDishInfoFn (id) {\n    return axios.get(getDishInfo, {\n      params: {\n        id\n      }\n    })\n  },\n  /**\n   * 检测手机号码是否已注册\n   * @param {*} phone 手机号\n   */\n  phoneRegisteredFn (phone) {\n    return axios.get(phoneRegistered, {\n      params: {\n        phone\n      }\n    })\n  },\n  /**\n   * 调用此接口 ,传入手机号码, 可发送验证码\n   * @param {number} phone 手机号\n   */\n  sendVerifyFn (phone) {\n    return axios.get(sendVerify, {\n      params: {\n        phone\n      }\n    })\n  },\n  /**\n   * 验证验证码\n   * 调用此接口 ,传入手机号码和验证码, 可校验验证码是否正确\n   * @param {*} phone 手机号\n   * @param {*} captcha 验证码\n   */\n  verifyFn (phone, captcha) {\n    return axios.get(verify, {\n      params: {\n        phone,\n        captcha\n      }\n    })\n  },\n  /**\n   * 用户通过手机登录\n   * @param {number} phone 手机号\n   * @param {String} password 密码\n   */\n  phoneLoginFn (phone, password) {\n    return axios.get(phoneLogin, {\n      params: {\n        phone: phone || '',\n        password: password || ''\n      }\n    })\n  },\n  /**\n   * 获取当前登录状态\n   */\n  loginStatusFn () {\n    return axios.get(loginStatus)\n  },\n  /**\n   * 获取用户播放记录\n   * 登陆后调用此接口 , 传入用户 id, 可获取用户播放记录\n   * @param {*} uid 用户id\n   * @param {*} type type=1 时只返回 weekData, type=0 时返回 allData\n   */\n  userRecordFn (uid, type = 1) {\n    return axios.get(userRecord, {\n      params: {\n        uid,\n        type\n      }\n    })\n  },\n  /**\n   * 获取用户信息 , 歌单，收藏，mv, dj 数量\n   * 登陆后调用此接口 , 可以获取用户信息\n   * artistCount: 2 我的收藏中的歌手\n   * code: 200\n   * createDjRadioCount: 0\n   * createdPlaylistCount: 2 创建的歌单数\n   * djRadioCount: 1 我的电台\n   * mvCount: 0\n   * newProgramCount: 0\n   * programCount: 0\n   * subPlaylistCount: 3 收藏的歌单数\n   * @param {*} timestamp 时间戳，使得每次请求的URL不同，除掉了默认的2分钟缓存\n   */\n  userInfoFn (timestamp) {\n    return axios.get(userInfo, {\n      params: {\n        timestamp\n      }\n    })\n  },\n  /**\n   * 登陆后调用此接口 , 传入用户 id, 可以获取用户详情\n   * @param {*} uid 用户id\n   */\n  userDetailFn (uid) {\n    return axios.get(userDetail, {\n      params: {\n        uid\n      }\n    })\n  },\n  /**\n   * 登陆后调用此接口 , 传入用户 id, 可以获取用户动态\n   * @param {*} uid 用户 id\n   * @param {*} limit  返回数量 , 默认为 30\n   * @param {*} lasttime 返回数据的 lasttime ,默认-1,传入上一次返回结果的 lasttime,将会返回下一页的数据\n   */\n  userEventFn (uid, limit = 20, lasttime) {\n    return axios.get(userEvent, {\n      params: {\n        uid,\n        limit,\n        lasttime\n      }\n    })\n  },\n  /**\n   * 调用此接口 , 传入签到类型\n   * @param {*} type 签到类型 , 默认 0, 其中 0 为安卓端签到 ,1 为 web/PC 签到\n   * 其中安卓端签到可获得 3 点经验 , web/PC 端签到可获得 2 点经验\n   */\n  signInFn (type) {\n    return axios.get(signIn, {\n      params: {\n        type\n      }\n    })\n  },\n  /**\n   * 调用此接口 ,传入手机号码和验证码,密码,昵称, 可注册网易云音乐账号(同时可修改密码)\n   * @param {*} captcha 验证码\n   * @param {*} phone 手机号码\n   * @param {*} password 密码\n   * @param {*} nickname 昵称\n   */\n  registerFn (captcha, phone, password, nickname) {\n    return axios.get(register, {\n      params: {\n        captcha,\n        phone,\n        password,\n        nickname\n      }\n    })\n  },\n  /**\n   * 登陆后调用此接口 , 传入用户 id, 可以获取用户歌单\n   * @param {*} uid 用户id\n   * @param {*} timestamp 时间戳，使得每次请求的URL不同，除掉了默认的2分钟缓存\n   */\n  playlistFn (uid, timestamp) {\n    return axios.get(playlist, {\n      params: {\n        uid,\n        timestamp\n      }\n    })\n  },\n  /**\n   * 登陆后调用此接口 , 传入用户 id, 可以获取用户电台\n   * @param {*} uid 用户 id\n   */\n  userDjFn (uid) {\n    return axios.get(userDj, {\n      params: {\n        uid\n      }\n    })\n  },\n  /**\n   * 调用此接口,可获取热门搜索列表\n   */\n  hotSearchListFn () {\n    return axios.get(hotSearchList)\n  },\n  /**\n   * 调用此接口 , 传入搜索关键词可以搜索\n   * 该音乐 / 专辑 / 歌手 / 歌单 / 用户 , 关键词可以多个 , 以空格隔开\n   * @param {*} keywords 关键词\n   * @param {*} limit 返回数量 , 默认为 30\n   * @param {*} offset 偏移数量，用于分页 默认为 0\n   * @param {*} type 搜索类型 默认为 1 即单曲 这里设置默认返回综合\n   * 1: 单曲, 10: 专辑, 100: 歌手, 1000: 歌单\n   * 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频, 1018:综合\n   */\n  searchFn (keywords, limit = 30, offset = 0, type = 1018) {\n    return axios.get(search, {\n      params: {\n        keywords,\n        limit,\n        offset,\n        type\n      }\n    })\n  },\n  /**\n   * 调用此接口 , 可获取默认搜索关键词\n   */\n  defaultSearchFn () {\n    return axios.get(defaultSearch)\n  },\n  /**\n   * 调用此接口\n   * 传入搜索关键词可获得搜索建议 ,\n   * 搜索结果同时包含单曲 , 歌手 , 歌单 ,mv 信息\n   * @param {*} keywords 关键词\n   * @param {*} type 默认返回移动端数据\n   */\n  suggestSearchFn (keywords, type = 'mobile') {\n    return axios.get(suggestSearch, {\n      params: {\n        keywords,\n        type\n      }\n    })\n  },\n  /**\n   *  使用歌单详情接口后 , 能得到的音乐的 id, 但不能得到的音乐 url\n   * 调用此接口 , 传入的音乐 id( 可多个 , 用逗号隔开 )\n   * 可以获取对应的音乐的 url( 不需要登录 )\n   * @param {*} id 音乐 id\n   * @param {*} br 码率,默认设置了 999000 即最大码率,如果要 320k 则可设置为 320000,其他类推\n   */\n  songUrlFn (id, br) {\n    return axios.get(songUrl, {\n      params: {\n        id,\n        br\n      }\n    })\n  },\n  /**\n   * 传入歌曲 id, 可获取音乐是否可用\n   * @param {*} id 歌曲 id\n   * @param {*} br 码率,默认设置了 999000 即最大码率,如果要 320k 则可设置为 320000,其他类推\n   */\n  checkSongFn (id, br) {\n    return axios.get(checkSong, {\n      params: {\n        id,\n        br\n      }\n    })\n  },\n  /**\n   * 传入音乐 id 可获得对应音乐的歌词 ( 不需要登录 )\n   * @param {*} id 歌曲id\n   */\n  songLyricFn (id) {\n    return axios.get(songLyric, {\n      params: {\n        id\n      }\n    })\n  },\n  /**\n   * 传入类型和歌单 id 可收藏歌单或者取消收藏歌单\n   * @param {*} t 1：收藏 2：取消收藏\n   * @param {*} id  歌单id\n   */\n  addOrDeletePlaylistFn (t, id) {\n    return axios.get(addOrDeletePlaylist, {\n      params: {\n        t,\n        id\n      }\n    })\n  },\n  /**\n   * 调用此接口 , 传入歌单名字可新建歌单\n   * @param {*} name 歌单名\n   * @param {*} privacy 是否为隐私歌单 传'10'设置为隐私歌单\n   */\n  addPlaylistFn (name, privacy) {\n    return axios.get(addPlaylist, {\n      params: {\n        name,\n        privacy\n      }\n    })\n  },\n  /**\n   * 调用此接口 , 传入歌单名字可新建歌单\n   * @param {*} id 歌单id\n   */\n  deletePlaylistFn (id) {\n    return axios.get(deletePlaylist, {\n      params: {\n        id\n      }\n    })\n  },\n  /**\n   * 登录后调用此接口 , 可获取心动模式/智能播放列表\n   * @param {*} id  歌曲 id\n   * @param {*} pid 歌单id\n   * @param {*} sid 要开始播放的歌曲id\n   */\n  heartModeFn (id, pid, sid) {\n    return axios.get(heartMode, {\n      params: {\n        id,\n        pid,\n        sid\n      }\n    })\n  },\n  /**\n   * 调用此接口 , 传入音乐 id, 可喜欢该音乐\n   * @param {*} id 音乐id\n   * @param {*} like 布尔值 , 默认为 true 即喜欢 , 若传 false, 则取消喜欢\n   */\n  likeMusicFn (id, like) {\n    return axios.get(likeMusic, {\n      params: {\n        id,\n        like\n      }\n    })\n  },\n  /**\n   * 调用此接口 , 传入用户 id, 可获取已喜欢音乐id列表(id数组)\n   * @param {*} uid 用户id\n   */\n  likeMusicListFn (uid) {\n    const timestamp = +new Date()\n    return axios.get(likeMusicList, {\n      params: {\n        uid,\n        timestamp\n      }\n    })\n  },\n  /**\n   * 调用此接口 , 可获得已收藏专辑列表\n   * @param {*} limit 取出数量 , 默认为 25\n   * @param {*} offset 偏移数量 , 用于分页 , 如 :( 页数 -1)*25, 其中 25 为 limit 的值 , 默认 为 0\n   */\n  favoriteAlbumsFn (limit, offset) {\n    return axios.get(favoriteAlbums, {\n      params: {\n        limit,\n        offset\n      }\n    })\n  },\n  /**\n   * 调用此接口,可获取收藏的歌手列表\n   */\n  favoriteArtistsFn () {\n    return axios.get(favoriteArtists)\n  },\n  /**\n   * 调用此接口,可收藏视频\n   */\n  favoriteVideosFn () {\n    return axios.get(favoriteVideos)\n  },\n  /**\n   * 获取视频详情\n   * @param {*} id 视频id\n   */\n  getVideoDetailFn (id) {\n    return axios.get(getVideoDetail, {\n      params: {\n        id\n      }\n    })\n  },\n  /**\n   * 获取相关视频\n   * @param {*} id 视频id\n   */\n  getVideoRelatedFn (id) {\n    return axios.get(getVideoRelated, {\n      params: {\n        id\n      }\n    })\n  },\n  /**\n   * 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该 视频 的所有评论 ( 不需要登录 )\n   * @param {*} id 视频的 id\n   * @param {*} limit 取出评论数量 , 默认为 20\n   * @param {*} offset 偏移数量 , 用于分页 , 如 :( 评论页数 -1)*20, 其中 20 为 limit 的值\n   * @param {*} before 分页参数,取上一页最后一项的 time 获取下一页数据(获取超过5000条评论的时候需要用到)\n   */\n  getVideoCommentsFn (id, limit = 20, offset, before) {\n    const timestamp = +new Date()\n    return axios.get(getVideoComments, {\n      params: {\n        id,\n        limit,\n        offset,\n        before,\n        timestamp\n      }\n    })\n  },\n  /**\n   * 登陆后调用此接口 , 可获取订阅的电台列表\n   */\n  djSublistFn (timestamp) {\n    return axios.get(djSublist, {\n      params: {\n        timestamp\n      }\n    })\n  },\n  /**\n   * 调用此接口 , 可获取新歌速递\n   * @param {*} type 地区类型 id,对应以下:\n   * 全部:0 华语:7 欧美:96 日本:8 韩国:16\n   */\n  newSongsFn (type = 0) {\n    return axios.get(newSongs, {\n      params: {\n        type\n      }\n    })\n  },\n  /**\n   * 获取私人 FM\n   * 需要登录\n   */\n  personalFmFn () {\n    return axios.get(personalFm)\n  },\n  /**\n   * 调用此接口,可获取歌手分类列表\n   * @param {*} cat 歌手类型, 必选\n   * 入驻歌手 5001\n   * 华语男歌手 1001 华语女歌手 1002 华语组合/乐队 1003\n   * 欧美男歌手 2001 欧美女歌手 2002 欧美组合/乐队 2003\n   * 日本男歌手 6001 日本女歌手 6002 日本组合/乐队 6003\n   * 韩国男歌手 7001 韩国女歌手 7002 韩国组合/乐队 7003\n   * 其他男歌手 4001 其他女歌手 4002 其他组合/乐队 4003\n   * @param {*} limit  返回数量 , 默认为 30\n   * @param {*} offset 偏移数量，用于分页，默认为 0\n   * @param {*} initial 按首字母索引查找参数\n   * /artist/list?cat=1001&initial=b\n   * 返回内容将以 name 字段开头为 b 或者拼音开头为 b 为顺序排列\n   */\n  singerClassFn (cat = 1001, limit = 30, offset = 0, initial) {\n    return axios.get(singerClass, {\n      params: {\n        cat,\n        limit,\n        offset,\n        initial\n      }\n    })\n  },\n  /**\n   * 退出账号\n   */\n  logoutFn () {\n    return axios.get(logout)\n  },\n  /**\n   * 调用此接口,可获取电台banner\n   */\n  djBannerFn () {\n    return axios.get(djBanner)\n  },\n  /**\n   * 获取电台页面的电台推荐数据\n   */\n  radioRecomFn () {\n    return axios.get(radioRecommendations)\n  },\n  /**\n   * 可以获取付费精选的电台列表\n   * @param {*} limit 返回数量 , 默认为 30\n   * @param {*} offset  偏移数量, 默认为 0\n   */\n  boutiqueRecomFn (limit = 3, offset = 0) {\n    return axios.get(boutiqueRecommendations, {\n      params: {\n        limit,\n        offset\n      }\n    })\n  },\n  /**\n   * 登陆后调用此接口 , 可获得电台类型\n   */\n  djClassificationFn () {\n    return axios.get(djClassification)\n  },\n  /**\n   * 登陆后调用此接口 , 可获得推荐电台\n   * @param {*} type 电台类型\n   * 可通过/dj/catelist获取 , 对应关系为 id 对应 此接口的 type, name 对应类型意义\n   */\n  djClassificationInfoFn (type) {\n    return axios.get(djClassificationInfo, {\n      params: {\n        type\n      }\n    })\n  },\n  /**\n   * 登陆后调用此接口 , 传入rid, 可查看对应电台的电台节目以及对应的 id\n   * 需要 注意的是这个接口返回的 mp3Url 已经无效 , 都为 null\n   * 但是通过调用 /song/url 这 个接口 , 传入节目 id 仍然能获取到节目音频 ,\n   * 如 /song/url?id=478446370 获取代 码时间的一个节目的音频\n   * @param {*} rid 电台 的 id\n   * @param {*} limit 返回数量 , 默认为 30\n   * @param {*} offset 偏移数量，用于分页\n   * @param {*} asc 排序方式,默认为 false (新 => 老 ) 设置 true 可改为 老 => 新\n   */\n  djProgramFn (rid, limit = 30, offset = 0, asc) {\n    return axios.get(djProgram, {\n      params: {\n        rid,\n        limit,\n        offset,\n        asc\n      }\n    })\n  },\n  /**\n   * 登陆后调用此接口 , 传入rid, 可获得对应电台的详情介绍\n   * @param {*} rid 电台 的 id\n   */\n  djDetailFn (rid) {\n    return axios.get(djDetail, {\n      params: {\n        rid\n      }\n    })\n  },\n  /**\n   * 可以获取付费精选的电台列表 , 传入 limit 和 offset 可以进行分页\n   * @param {*} limit 返回数量 , 默认为 30\n   * @param {*} offset 偏移数量，用于分页\n   */\n  djPayGiftFn (limit = 30, offset = 0) {\n    return axios.get(djPayGift, {\n      params: {\n        limit,\n        offset\n      }\n    })\n  },\n  /**\n   * 登陆后调用此接口 , 传入rid, 可订阅 dj\n   * @param {*} rid 电台 的 id\n   * @param {*} t t=1 对应关注 t=0 对应取消关注\n   */\n  djSubFn (rid, t) {\n    return axios.get(djSub, {\n      params: {\n        rid,\n        t\n      }\n    })\n  },\n  /**\n   * 登陆后调用此接口 , 可获得电台节目榜\n   * @param {*} limit  返回数量 , 默认为 100\n   * @param {*} offset 偏移数量，用于分页\n   */\n  djToplistFn (limit = 100, offset = 0) {\n    return axios.get(djToplist, {\n      params: {\n        limit,\n        offset\n      }\n    })\n  },\n  /**\n   * 登陆后调用此接口 , 可获得新晋电台榜/热门电台榜\n   * @param {*} limit 返回数量 , 默认为 100\n   * @param {*} offset 偏移数量，用于分页\n   * @param {*} type 榜单类型, new 为新晋电台榜, hot为热门电台榜\n   */\n  djHotToplistFn (limit = 100, offset = 0, type = 'hot') {\n    return axios.get(djHotToplist, {\n      params: {\n        limit,\n        offset,\n        type\n      }\n    })\n  },\n  /**\n   * 调用此接口,可获取24小时节目榜\n   * @param {*} limit 返回数量 , 默认为 100 (不支持 offset)\n   */\n  djProgramTopHoursFn (limit) {\n    return axios.get(djProgramTopHours, {\n      params: {\n        limit\n      }\n    })\n  },\n  /**\n   * 调用此接口,可获取24小时主播榜\n   * @param {*} limit 返回数量 , 默认为 100 (不支持 offset)\n   */\n  djToplistHoursFn (limit) {\n    return axios.get(djToplistHours, {\n      params: {\n        limit\n      }\n    })\n  },\n  /**\n   * 说明 : 调用此接口,可获取主播新人榜\n   * @param {*} limit 返回数量 , 默认为 100 (不支持 offset)\n   */\n  djToplistNewComersFn (limit) {\n    return axios.get(djToplistNewComers, {\n      params: {\n        limit\n      }\n    })\n  },\n  /**\n   * 调用此接口,可获取最热主播榜\n   * @param {*} limit 返回数量 , 默认为 100 (不支持 offset)\n   */\n  djToplistPopularsFn (limit) {\n    return axios.get(djToplistPopulars, {\n      params: {\n        limit\n      }\n    })\n  },\n  /**\n   * 调用此接口,可获取付费精品电台\n   * @param {*} limit 返回数量 , 默认为 100 (不支持 offset)\n   */\n  djToplistPaysFn (limit) {\n    return axios.get(djToplistPays, {\n      params: {\n        limit\n      }\n    })\n  },\n  /**\n   * 调用此接口 , 可获取各种动态\n   * 对应网页版网易云，朋友界面里的各种动态消息\n   * 如分享的视频，音乐，照片等！\n   * @param {*} pagesize  每页数据,默认20\n   * @param {*} lasttime  返回数据的 lasttime ,默认-1\n   * 传入上一次返回结果的 lasttime,将会返回下一页的数据\n   */\n  friendFn (pagesize = 20, lasttime = -1) {\n    return axios.get(friend, {\n      params: {\n        pagesize,\n        lasttime\n      }\n    })\n  },\n  /**\n   * 调用此接口 , 可获取视频标签列表\n   */\n  getVideoTagFn () {\n    return axios.get(getVideoTag)\n  },\n  /**\n   * 调用此接口 , 传入id,可获取到相关的视频\n   * @param {*} id videoGroup 的 id\n   */\n  getVideoGroupFn (id) {\n    return axios.get(getVideoGroup, {\n      params: {\n        id\n      }\n    })\n  },\n  /**\n   * 调用此接口 , 传入视频 id,可获取视频播放地址\n   * @param {*} id 视频 id\n   */\n  getVideoUrlFn (id) {\n    return axios.get(getVideoUrl, {\n      params: {\n        id\n      }\n    })\n  },\n  /**\n   * 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该歌单的所有评论 ( 不需要 登录 )\n   * @param {*} id 歌单id\n   * @param {*} limit 取出评论数量 , 默认为 20\n   * @param {*} offset 偏移数量 , 用于分页\n   * @param {*} before 分页参数,取上一页最后一项的 time\n   * 获取下一页数据(获取超过5000条评论的时候需要用到)\n   */\n  commentPlaylistFn (id, limit = 20, offset, before) {\n    const timestamp = +new Date()\n    return axios.get(commentPlaylist, {\n      params: {\n        id,\n        limit,\n        offset,\n        before,\n        timestamp\n      }\n    })\n  },\n  /**\n   * 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该专辑的所有评论 ( 不需要 登录 )\n   * @param {*} id 专辑id\n   * @param {*} limit 取出评论数量 , 默认为 20\n   * @param {*} offset 偏移数量 , 用于分页\n   * @param {*} before 分页参数,取上一页最后一项的 time\n   * 获取下一页数据(获取超过5000条评论的时候需要用到)\n   */\n  commentAlbumFn (id, limit = 20, offset, before) {\n    const timestamp = +new Date()\n    return axios.get(commentAlbum, {\n      params: {\n        id,\n        limit,\n        offset,\n        before,\n        timestamp\n      }\n    })\n  },\n  commentDjFn (id, limit = 20, offset, before) {\n    const timestamp = +new Date()\n    return axios.get(commentDj, {\n      params: {\n        id,\n        limit,\n        offset,\n        before,\n        timestamp\n      }\n    })\n  },\n  /**\n   * 调用此接口 , 传入 type,\n   * 资源 id, 和评论 id cid\n   * 是否点赞参数 t 即可给对 应评论点赞 ( 需要登录 )\n   * @param {*} id 资源 id, 如歌曲 id,mv id\n   * @param {*} cid 评论 id\n   * @param {*} t 是否点赞 ,1 为点赞 ,0 为取消点赞\n   * @param {*} type  数字 , 资源类型 , 对应歌曲 , mv, 专辑 , 歌单 , 电台, 视频对应以下类型\n   * 0: 歌曲 1: mv 2: 歌单 3: 专辑 4: 电台 5: 视频  6: 动态\n   */\n  commentLikeFn (id, cid, t, type) {\n    return axios.get(commentLike, {\n      params: {\n        id,\n        cid,\n        t,\n        type\n      }\n    })\n  },\n  /**\n   * 调用此接口,可发送评论\n   * @param {*} t 1: 发送评论\n   * @param {*} type 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型\n   * 0: 歌曲 1: mv 2: 歌单 3: 专辑 4: 电台 5: 视频  6: 动态\n   * @param {*} id 对应资源 id\n   * @param {*} content 要发送的内容\n   * @param {*} commentId 回复的评论id (回复评论时必填)\n   * @param {*} threadId 如给动态发送评论，则不需要传 id，需要传动态的 threadId\n   */\n  pushComFn (type, id, content, commentId, threadId) {\n    const t = 1\n    const timestamp = +new Date()\n    return axios.post(pushOrDeleteCom, {\n      t,\n      type,\n      id,\n      content,\n      commentId,\n      threadId,\n      timestamp\n    })\n  },\n  /**\n   * 调用此接口,可删除评论\n   * @param {*} t 0: 删除评论\n   * @param {*} type 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型\n   * 0: 歌曲 1: mv 2: 歌单 3: 专辑 4: 电台 5: 视频  6: 动态\n   * @param {*} id 对应资源 id\n   * @param {*} threadId 如给动态删除评论，则不需要传 id，需要传动态的 `threadId`\n   * @param {*} commentId 回复的评论id (回复评论时必填),删除评论时传入评论的id\n   */\n  delComFn (type, id, commentId, threadId) {\n    const t = 0\n    return axios.post(pushOrDeleteCom, {\n      t,\n      type,\n      id,\n      threadId,\n      commentId\n    })\n  },\n  /**\n   * 调用此接口 , 可对 MV,电台,视频点赞\n   * @param {*} type 资源类型,对应以下类型 1: mv 4: 电台 5: 视频 6: 动态\n   * @param {*} id 资源 id\n   */\n  resourceLikeInFn (type, id) {\n    const t = 1\n    return axios.get(resourceLike, {\n      params: {\n        t,\n        type,\n        id\n      }\n    })\n  },\n  /**\n   * 调用此接口 , 可对 MV,电台,视频取消点赞\n   * @param {*} type 资源类型,对应以下类型 1: mv 4: 电台 5: 视频 6: 动态\n   * @param {*} id 资源 id\n   */\n  resourceLikeOutFn (type, id) {\n    const t = 0\n    return axios.get(resourceLike, {\n      params: {\n        t,\n        type,\n        id\n      }\n    })\n  }\n}\n"
  },
  {
    "path": "musicPlayer/src/assets/Bus.js",
    "content": "/*\n * @Author: 李浩栋\n * @Begin: 2019-08-29 10:48:10\n * @Update: 2019-08-29 10:50:16\n * @Update log: 更新日志\n */\nimport Vue from 'vue'\nexport default new Vue()\n"
  },
  {
    "path": "musicPlayer/src/assets/Mixins.js",
    "content": "/*\n * @Author: 李浩栋\n * @Begin: 2019-09-21 15:14:40\n * @Update: 2019-11-24 12:59:18\n * @Update log: 更新日志\n */\n\nimport {\n  mapGetters\n} from 'vuex'\nimport api from 'api'\nimport isInSport from 'utils/scrollStopVideo'\n\n/**\n * 这里包含对于不同模式下的icon展示\n * 对于更改mode\n * 对播放列表的展示隐藏\n */\nexport const audio = {\n  props: {\n    mode: {\n      type: Number\n    }\n  },\n  computed: {\n    modeClass: function () {\n      switch (this.mode) {\n        case 0: // 列表循环\n          return 'audioxunhuan'\n        case 1: // 单曲循环\n          return 'audiosingle-loop'\n        case 2: // 随机播放\n          return 'audiosuiji'\n      }\n    }\n  },\n  methods: {\n    changeMode () {\n      this.$emit('changeMode')\n    },\n    showAudioList () {\n      this.$emit('showAudioList')\n    }\n  }\n}\n\nlet timer = null\n\nexport const videoPage = {\n  data () {\n    return {\n      data: [],\n      load: true,\n      isLogin: +localStorage.getItem('loginState') || 0\n    }\n  },\n  created () {\n    this._getVideoDetail(this.$route.params.id)\n  },\n  methods: {\n    _getVideoDetail (id) {\n      api.getVideoGroupFn(id)\n        .then(res => {\n          const {\n            data\n          } = res\n          if (data.code === 200) {\n            this.data = data.datas\n            this.load = false\n          }\n        })\n        .catch(err => {\n          if (err) {\n            this.load = false\n          }\n        })\n    },\n    hideVideo () {\n      const self = this\n      if (timer) {\n        clearTimeout(timer)\n        timer = null\n      }\n      timer = setTimeout(() => {\n        this.stopVideo(self)\n      }, 300)\n    },\n    stopVideo (self) {\n      // 父容器\n      const wra = self.$el\n      // video集合\n      const videos = [...wra.querySelectorAll('.video-item')]\n      // 获取到当前正在播放的video\n      const ele = videos[this.index]\n      // 查看当前播放的video是否已经出去！！！\n      if (!isInSport(ele, wra)) {\n        // 出去的话调用方法，停止视频播放\n        self.$refs.public.stopVideoTag()\n      }\n    },\n    getIndex (index) {\n      this.index = index\n    }\n  }\n}\n\n/**\n * 当页面显示了播放组件，页面整体需要设置paddingBottom\n * 大小为迷你播放器的高度\n */\n\nexport const paddingBottom = {\n  computed: {\n    ...mapGetters({\n      miniAudio: 'FULL_SCREEN'\n    })\n  },\n  mounted () {\n    console.log(this.miniAudio)\n    if (!this.miniAudio) {\n      this.setPagePb()\n    }\n  },\n  watch: {\n    /**\n     * 监听当前是否播放\n     */\n    miniAudio: function (val) {\n      if (!val) {\n        this.setPagePb()\n      }\n    }\n  },\n  methods: {\n    setPagePb () {\n      this.$refs.wrapper.style.paddingBottom = '1.3rem'\n    }\n  }\n}\n"
  },
  {
    "path": "musicPlayer/src/assets/styles/border.css",
    "content": "@charset \"utf-8\";\n.border,\n.border-top,\n.border-right,\n.border-bottom,\n.border-left,\n.border-topbottom,\n.border-rightleft,\n.border-topleft,\n.border-rightbottom,\n.border-topright,\n.border-bottomleft {\n    position: relative;\n}\n.border::before,\n.border-top::before,\n.border-right::before,\n.border-bottom::before,\n.border-left::before,\n.border-topbottom::before,\n.border-topbottom::after,\n.border-rightleft::before,\n.border-rightleft::after,\n.border-topleft::before,\n.border-topleft::after,\n.border-rightbottom::before,\n.border-rightbottom::after,\n.border-topright::before,\n.border-topright::after,\n.border-bottomleft::before,\n.border-bottomleft::after {\n    content: \"\\0020\";\n    overflow: hidden;\n    position: absolute;\n}\n/* border\n * 因，边框是由伪元素区域遮盖在父级\n * 故，子级若有交互，需要对子级设置\n * 定位 及 z轴\n */\n.border::before {\n    box-sizing: border-box;\n    top: 0;\n    left: 0;\n    height: 100%;\n    width: 100%;\n    border: 1px solid #eaeaea;\n    transform-origin: 0 0;\n}\n.border-top::before,\n.border-bottom::before,\n.border-topbottom::before,\n.border-topbottom::after,\n.border-topleft::before,\n.border-rightbottom::after,\n.border-topright::before,\n.border-bottomleft::before {\n    left: 0;\n    width: 100%;\n    height: 1px;\n}\n.border-right::before,\n.border-left::before,\n.border-rightleft::before,\n.border-rightleft::after,\n.border-topleft::after,\n.border-rightbottom::before,\n.border-topright::after,\n.border-bottomleft::after {\n    top: 0;\n    width: 1px;\n    height: 100%;\n}\n.border-top::before,\n.border-topbottom::before,\n.border-topleft::before,\n.border-topright::before {\n    border-top: 1px solid #eaeaea;\n    transform-origin: 0 0;\n}\n.border-right::before,\n.border-rightbottom::before,\n.border-rightleft::before,\n.border-topright::after {\n    border-right: 1px solid #eaeaea;\n    transform-origin: 100% 0;\n}\n.border-bottom::before,\n.border-topbottom::after,\n.border-rightbottom::after,\n.border-bottomleft::before {\n    border-bottom: 1px solid #eaeaea;\n    transform-origin: 0 100%;\n}\n.border-left::before,\n.border-topleft::after,\n.border-rightleft::after,\n.border-bottomleft::after {\n    border-left: 1px solid #eaeaea;\n    transform-origin: 0 0;\n}\n.border-top::before,\n.border-topbottom::before,\n.border-topleft::before,\n.border-topright::before {\n    top: 0;\n}\n.border-right::before,\n.border-rightleft::after,\n.border-rightbottom::before,\n.border-topright::after {\n    right: 0;\n}\n.border-bottom::before,\n.border-topbottom::after,\n.border-rightbottom::after,\n.border-bottomleft::after {\n    bottom: 0;\n}\n.border-left::before,\n.border-rightleft::before,\n.border-topleft::after,\n.border-bottomleft::before {\n    left: 0;\n}\n@media (max--moz-device-pixel-ratio: 1.49), (-webkit-max-device-pixel-ratio: 1.49), (max-device-pixel-ratio: 1.49), (max-resolution: 143dpi), (max-resolution: 1.49dppx) {\n    /* 默认值，无需重置 */\n}\n@media (min--moz-device-pixel-ratio: 1.5) and (max--moz-device-pixel-ratio: 2.49), (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 2.49), (min-device-pixel-ratio: 1.5) and (max-device-pixel-ratio: 2.49), (min-resolution: 144dpi) and (max-resolution: 239dpi), (min-resolution: 1.5dppx) and (max-resolution: 2.49dppx) {\n    .border::before {\n        width: 200%;\n        height: 200%;\n        transform: scale(.5);\n    }\n    .border-top::before,\n    .border-bottom::before,\n    .border-topbottom::before,\n    .border-topbottom::after,\n    .border-topleft::before,\n    .border-rightbottom::after,\n    .border-topright::before,\n    .border-bottomleft::before {\n        transform: scaleY(.5);\n    }\n    .border-right::before,\n    .border-left::before,\n    .border-rightleft::before,\n    .border-rightleft::after,\n    .border-topleft::after,\n    .border-rightbottom::before,\n    .border-topright::after,\n    .border-bottomleft::after {\n        transform: scaleX(.5);\n    }\n}\n@media (min--moz-device-pixel-ratio: 2.5), (-webkit-min-device-pixel-ratio: 2.5), (min-device-pixel-ratio: 2.5), (min-resolution: 240dpi), (min-resolution: 2.5dppx) {\n    .border::before {\n        width: 300%;\n        height: 300%;\n        transform: scale(.33333);\n    }\n    .border-top::before,\n    .border-bottom::before,\n    .border-topbottom::before,\n    .border-topbottom::after,\n    .border-topleft::before,\n    .border-rightbottom::after,\n    .border-topright::before,\n    .border-bottomleft::before {\n        transform: scaleY(.33333);\n    }\n    .border-right::before,\n    .border-left::before,\n    .border-rightleft::before,\n    .border-rightleft::after,\n    .border-topleft::after,\n    .border-rightbottom::before,\n    .border-topright::after,\n    .border-bottomleft::after {\n        transform: scaleX(.33333);\n    }\n}\n"
  },
  {
    "path": "musicPlayer/src/assets/styles/global.less",
    "content": "// 主题色\n@bgcolor: #dd001b;\n// 图片圆角\n@imgBorderRadius: 0.11rem;\n// 图标宽度\n@iconWidth: 1rem;\n// 图标下方文本大小\n@iconText: 0.24rem;\n\n// 定义盒子模型 两边对齐布局\n.flex-between {\n  display: flex;\n  justify-content: space-between;\n}\n\n.titleFixed {\n  position: sticky;\n  width: 100vw;\n  top: 0;\n  background-color: #fff;\n  z-index: 99;\n}\n\n// 定义盒子模型  分散布局\n.flex-around {\n  display: flex;\n  justify-content: space-around;\n}\n\n.flex-center {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n}\n\n// 两行文本溢出打点 ...\n.twoLinesEllipsis {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  display: -webkit-box;\n  -webkit-line-clamp: 2;\n  overflow: hidden;\n  /*! autoprefixer: off */\n  -webkit-box-orient: vertical;\n}\n\n// 单行文字打点\n.ellipsis {\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n// 小标签\n.smallTag {\n  box-sizing: border-box;\n  padding: 0.1rem 0.1rem 0.1rem 0.13rem;\n  display: flex;\n  align-items: center;\n  // justify-content: center;\n  font-size: 0.2rem;\n  border-radius: 1rem;\n  letter-spacing: 0.05rem;\n  text-align: center;\n  border: 1px solid #ccc;\n}\n\n.tag-group {\n  box-sizing: border-box;\n  padding: 0.1rem 0.2rem 0.1rem 0.2rem;\n  font-size: 0.2rem;\n  border-radius: 0.2rem;\n  background-color: #eee;\n  margin-right: 0.1rem;\n}\n\n// 遮罩层\n.mask {\n  position: fixed;\n  z-index: 10;\n  left: 0;\n  top: 0;\n  width: 100vw;\n  height: 100vh;\n  background: rgba(0, 0, 0, 0.7);\n}\n\n// 灰色的数字样式\n.num {\n  font-size: 0.24rem;\n  color: #999;\n}\n\n// 导航栏的访问样式\n.ac {\n  color: #000;\n  font-size: 0.28rem;\n}\n\n// a标签覆盖整个区域\n.cover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  right: 0;\n  width: 90%;\n  height: 100%;\n}\n\n// 页面灰色分割线样式\n.split {\n  width: 100%;\n  height: 0.13rem;\n  background-color: #eee;\n  margin: 0.3rem 0;\n}\n\n// 页面有的左右padding\n.pd13 {\n  box-sizing: border-box;\n  padding: 0 0.13rem;\n}\n\n// 页面有的左右padding\n.pd23 {\n  box-sizing: border-box;\n  padding: 0 0.23rem;\n}\n\n.pb1 {\n  box-sizing: border-box;\n  padding-bottom: 1rem;\n}\n\n// 点击有波纹效果\n.ripple {\n  position: relative;\n  overflow: hidden;\n  user-select: none;\n\n  &:after {\n    position: absolute;\n    content: '';\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n    pointer-events: none;\n    //设置径向渐变\n    background-image: radial-gradient(circle, #666 10%, transparent 10.01%);\n    background-repeat: no-repeat;\n    background-position: 50%;\n    transform: scale(10, 10);\n    opacity: 0;\n    transition: transform .5s, opacity .6s;\n  }\n\n  &:active:after {\n    transform: scale(0, 0);\n    opacity: .3;\n    //设置初始状态\n    transition: 0s;\n  }\n}\n"
  },
  {
    "path": "musicPlayer/src/assets/styles/reset.css",
    "content": "@charset \"utf-8\";\n\nhtml {\n  background-color: #fff;\n  color: #000\n}\n\nbody,\nul,\nol,\ndl,\ndd,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nfigure,\nform,\nfieldset,\nlegend,\ninput,\ntextarea,\nbutton,\np,\nblockquote,\nth,\ntd,\npre,\nxmp {\n  margin: 0;\n  padding: 0\n}\n\nbody,\ninput,\ntextarea,\nbutton,\nselect,\npre,\nxmp,\ntt,\ncode,\nkbd,\nsamp {\n  line-height: 1.5;\n  font-family: tahoma, arial, \"Hiragino Sans GB\", simsun, sans-serif\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nsmall,\nbig,\ninput,\ntextarea,\nbutton,\nselect {\n  font-size: 100%\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n  font-family: tahoma, arial, \"Hiragino Sans GB\", \"微软雅黑\", simsun, sans-serif\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nb,\nstrong {\n  font-weight: normal\n}\n\naddress,\ncite,\ndfn,\nem,\ni,\noptgroup,\nvar {\n  font-style: normal\n}\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n  text-align: left\n}\n\ncaption,\nth {\n  text-align: inherit\n}\n\nul,\nol,\nmenu {\n  list-style: none\n}\n\nfieldset,\nimg {\n  border: 0\n}\n\nimg,\nobject,\ninput,\ntextarea,\nbutton,\nselect {\n  vertical-align: middle\n}\n\narticle,\naside,\nfooter,\nheader,\nsection,\nnav,\nfigure,\nfigcaption,\nhgroup,\ndetails,\nmenu {\n  display: block\n}\n\naudio,\ncanvas,\nvideo {\n  display: inline-block;\n  *display: inline;\n  *zoom: 1\n}\n\nblockquote:before,\nblockquote:after,\nq:before,\nq:after {\n  content: \"\\0020\"\n}\n\ntextarea {\n  overflow: auto;\n  resize: vertical\n}\n\ninput,\ntextarea,\nbutton,\nselect,\na {\n  outline: 0 none;\n  border: none;\n}\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  padding: 0;\n  border: 0\n}\n\nmark {\n  background-color: transparent\n}\n\na,\nins,\ns,\nu,\ndel {\n  text-decoration: none\n}\n\nsup,\nsub {\n  vertical-align: baseline\n}\n\nhtml {\n  height: 100%;\n  font-size: 14vw;\n  -webkit-tap-highlight-color: transparent;\n}\n\nbody {\n  font-family: Arial, \"Microsoft Yahei\", \"Helvetica Neue\", Helvetica, sans-serif;\n  color: #333;\n  font-size: .28em;\n  line-height: 1;\n  -webkit-text-size-adjust: none;\n}\n\nhr {\n  height: .02rem;\n  margin: .1rem 0;\n  border: medium none;\n  border-top: .02rem solid #cacaca;\n}\n\na {\n  color: #25a4bb;\n  text-decoration: none;\n}\n\n#audio_pb1 {\n  box-sizing: border-box ;\n  padding-bottom: 1rem;\n}"
  },
  {
    "path": "musicPlayer/src/assets/utils/cookie.js",
    "content": "/*\n * @Author: Lambda\n * @Begin: 2019-10-24 11:00:35\n * @Update: 2019-10-24 11:03:02\n * @Update log: 更新日志\n */\nexport const getCookie = _name => {\n  let name = _name + '='\n  let Cookies = document.cookie.split(';')\n  for (let i = 0; i < Cookies.length; i++) {\n    let Cookie = Cookies[i]\n    while (Cookie.charAt(0) === '') {\n      Cookie = Cookie.substring(1)\n    }\n    if (Cookie.indexOf(name) !== -1) {\n      return Cookie.substring(name.length, Cookie.length)\n    }\n  }\n  return ''\n}\n\nexport const setCookie = (name, value, expires, path, domain, secure) => {\n  let cookieText = encodeURIComponent(name) + '=' + encodeURIComponent(value)\n  if (expires instanceof Date) {\n    cookieText += '; expires=' + expires.toGMTString()\n  }\n  if (path) {\n    cookieText += '; path=' + path\n  }\n  if (domain) {\n    cookieText += '; domain=' + domain\n  }\n  if (secure) {\n    cookieText += '; secure'\n  }\n  document.cookie = cookieText\n}\n"
  },
  {
    "path": "musicPlayer/src/assets/utils/filters.js",
    "content": "/*\n * @Author: 李浩栋\n * @Begin: 2019-10-14 14:08:38\n * @Update: 2019-12-10 13:40:19\n * @Update log: 更新日志\n */\nexport const filterSetPlayCount = value => {\n  if (!value) return ''\n  if (value > 10000) {\n    value = parseInt(value / 10000) + '万'\n  } else if (value > 100000000) {\n    value = (value / 100000000).toFixed(1) + '亿'\n  }\n  return value\n}\n\n/**\n * 将毫秒转换为 分钟：秒数 的形式\n */\nexport const filterSetTime = value => {\n  if (!value) return ''\n  let min = parseInt(value / (1000 * 60))\n  if (min < 10) {\n    min = '0' + min\n  }\n  let sec = parseInt(value % (1000 * 60) / 1000)\n  if (sec < 10) {\n    sec = '0' + sec\n  }\n  value = `${min}:${sec}`\n  return value\n}\n\n/**\n * 将毫秒转换为 年.月.日\n */\nexport const filterSetYear = (value, splitY = '.', splitM = '.', splitD = '') => {\n  const oDate = new Date(value)\n  const oYear = oDate.getFullYear()\n  const oMonth = oDate.getMonth() + 1\n  const oDay = oDate.getDate()\n  value = `${oYear}${splitY}${oMonth}${splitM}${oDay}${splitD}`\n  return value\n}\n\n/**\n * 将毫秒设置为 月-日 格式\n */\nexport const filterSetMonth = (value, splitM = '-', splitD = '') => {\n  const oDate = new Date(value)\n  let oMonth = oDate.getMonth() + 1\n  let oDay = oDate.getDate()\n  if (oMonth < 10) {\n    oMonth = '0' + oMonth\n  }\n  if (oDay < 10) {\n    oDay = '0' + oDay\n  }\n  value = `${oMonth}${splitM}${oDay}${splitD}`\n  return value\n}\n\nexport const filterAge = time => {\n  if (!time) {\n    // 这里是因为默认值为0的话会返回1970\n    // 当传入默认值退出\n    return\n  }\n  let year = new Date(time).getFullYear()\n  const nowYear = new Date().getFullYear()\n  let age = ''\n  // 存下从1950年到现在时间每5年一个间隔的数值\n  let ages = []\n  for (let i = 1950; i < nowYear; i += 5) {\n    ages.push(i)\n  }\n  // 这里不能使用 forEach 因为forEach无法跳出循环！！！\n  for (let i = 0; i < ages.length; i++) {\n    const ele = ages[i]\n    if (year <= ele + 5) {\n      // 找到第一个满足条件的年份，拆分成数组，截取最后两位，组合返回\n      age = ele.toString().split('').splice(-2).join('')\n      break\n    }\n  }\n  return age\n}\n\nexport const filterJson = json => {\n  return JSON.parse(json.toString())\n}\n"
  },
  {
    "path": "musicPlayer/src/assets/utils/getAstro.js",
    "content": "/*\n * @Author: Lambda\n * @Begin: 2019-10-28 12:05:42\n * @Update: 2019-10-28 12:06:27\n * @Update log: 更新日志\n */\nexport const getAstro = (m, d) => {\n  return '魔羯水瓶双鱼牡羊金牛双子巨蟹狮子处女天秤天蝎射手魔羯'.substr(m * 2 - (d < '102223444433'.charAt(m - 1) - -19) * 2, 2)\n}\n"
  },
  {
    "path": "musicPlayer/src/assets/utils/getPhone.js",
    "content": "/*\n * @Author: 李浩栋\n * @Begin: 2019-08-26 13:35:48\n * @Update: 2019-08-26 13:47:13\n * @Update log: 更新日志\n */\nexport function getPhone () {\n  // 创建一个正则表达式\n  let reg = new RegExp(/\\d*$/)\n  // window.location.hash 返回从 “#” 开始的 url\n  // 返回一个数组（未匹配到则返回 null）\n  let phone = reg.exec(window.location.hash)[0]\n  return phone\n}\n"
  },
  {
    "path": "musicPlayer/src/assets/utils/getRandomArrayElements.js",
    "content": "/*\n * @Author: 李浩栋\n * @Begin: 2019-10-11 13:17:17\n * @Update: 2019-10-11 13:18:07\n * @Update log: 更新日志\n */\n/**\n * 随机取出数组中的几项\n */\nexport const getRandomArrayElements = (arr, count) => {\n  // eslint-disable-next-line one-var\n  let shuffled = arr.slice(0),\n    // 克隆一个数组，为了不影响外边的数据\n    i = arr.length,\n    min = i - count,\n    temp,\n    index\n  // 存下来数组信息  数组的长度\n  // 通过改变数组项的位置 输出后边的几位\n  while (--i > min) {\n    // 随机生成出一个索引\n    index = Math.floor((i + 1) * Math.random())\n    // 将随机索引项暂存\n    // 将数组后边的项与随机项调换\n    temp = shuffled[index]\n    shuffled[index] = shuffled[i]\n    shuffled[i] = temp\n  }\n  return shuffled.slice(min)\n}\n"
  },
  {
    "path": "musicPlayer/src/assets/utils/modalScroll.js",
    "content": "/*\n * @Author: 李浩栋\n * @Begin: 2019-07-27 17:08:42\n * @Update: 2019-08-10 16:42:32\n * @Update log: 更新日志\n */\n// 解决遮罩层滚动穿透问题，分别在遮罩层弹出后和关闭前调用\nlet _scrollTop\nclass ModalHelper {\n  // popup 显示时调用\n  static afterOpen () {\n    _scrollTop = document.scrollingElement.scrollTop\n    document.body.style.position = 'fixed'\n    document.body.style.top = -_scrollTop + 'px'\n    document.body.style.left = 0\n    document.body.style.bottom = 0\n    document.body.style.right = 0\n  }\n\n  // popup 关闭时调用\n  static beforeClose () {\n    document.body.style.position = ''\n    document.body.style.top = ''\n    document.body.style.left = ''\n    document.body.style.right = ''\n    document.body.style.bottom = ''\n    document.scrollingElement.scrollTop = _scrollTop\n  }\n}\n\nexport default ModalHelper\n"
  },
  {
    "path": "musicPlayer/src/assets/utils/scrollStopVideo.js",
    "content": "/*\n * @Author: Lambda\n * @Begin: 2019-11-19 12:37:10\n * @Update: 2019-11-19 13:48:22\n * @Update log: 更新日志\n */\n// 判断一个元素是否在视窗内\nfunction isInSport (ele, wra) {\n  // 判断该图片是否能够加载，判断图片是否在可视区域内\n  const wraHeight = wra.clientHeight\n  const rect = ele.getBoundingClientRect()\n  // 如果超出视窗返回false\n  if (rect.bottom <= (wraHeight + 100) && rect.bottom >= (wraHeight / 2)) {\n    return true\n  }\n  if (rect.top <= (wraHeight + 100) && rect.top >= 0) {\n    return true\n  }\n  return false\n}\n\nexport default isInSport\n"
  },
  {
    "path": "musicPlayer/src/assets/utils/setKeyWords.js",
    "content": "/*\n * @Author: Lambda\n * @Begin: 2019-11-01 13:07:59\n * @Update: 2019-11-04 13:40:35\n * @Update log: 更新日志\n */\n/**\n * 传入关键字和内容，将内容中含有关键字的部分添加对应的高亮样式\n * @param {*} keyword\n * @param {*} val\n */\nexport const filterSetKeyWords = (keyword, val, property) => {\n  let results = []\n  const _val = val\n  _val.map((item, index) => {\n    if (keyword && keyword.length > 0) {\n      // 匹配关键字正则\n      let replaceReg = new RegExp(keyword, 'g')\n      // 高亮替换v-html值\n      let replaceString =\n        `<i style=\"color: #3399EA\">${keyword}</i>`\n      _val[index][property] = item[property].replace(\n        replaceReg,\n        replaceString\n      )\n    }\n  })\n  results = _val\n  return results\n}\n"
  },
  {
    "path": "musicPlayer/src/base/albumPage/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-06 11:47:11\n * @Update: 2019-11-02 14:11:21\n * @Update log: 这个是歌单展示的通用组件\n -->\n<template>\n  <!-- 通过传递参数给子组件，标题，加载样式，图片链接，歌单名称，作者头像，作者昵称，歌单介绍，评论数，分享数，歌单歌曲数，收藏数，是否收藏 -->\n  <song-list-page\n    :title=\"title\"\n    :load=\"load\"\n    :imgUrl=\"albumInfo.coverImgUrl ? albumInfo.coverImgUrl : albumInfo.album ? albumInfo.album.picUrl : ''\"\n    :albumTitle=\"albumInfo.name ? albumInfo.name : albumInfo.album ? albumInfo.album.name : ''\"\n    :albumId=\"albumId\"\n    :idxId=\"idxId\"\n    :idxComId=\"idxComId\"\n    :dishId=\"dishId\"\n    :creatorImgUrl=\"albumInfo.creator ? albumInfo.creator.avatarUrl : albumInfo.album ? albumInfo.album.artist.picUrl:''\"\n    :author=\"albumInfo.creator ? albumInfo.creator.nickname : albumInfo.album ? albumInfo.album.artist.name : ''\"\n    :description=\"albumInfo.description ? albumInfo.description : albumInfo.album ? albumInfo.album.description : ''\"\n    :commentCount=\"albumInfo.commentCount ? albumInfo.commentCount : albumInfo.album ? albumInfo.album.info.commentCount : 0\"\n    :shareCount=\"albumInfo.shareCount ? albumInfo.shareCount : albumInfo.album ? albumInfo.album.info.shareCount : 0\"\n    :trackCount=\"albumInfo.trackCount ? albumInfo.trackCount : albumInfo.album ? albumInfo.album.size : 0\"\n    :subscribedCount=\"albumInfo.subscribedCount\"\n    :subscribed=\"albumInfo.subscribed\"\n    :isSubIn=\"albumInfo.subscribed\"\n    :playCount=\"albumInfo.playCount\"\n    @startPlayAll=\"startPlay\"\n  >\n    <!-- 这是一个通用的用来展示歌曲列表的组件，通过for循环组件进行渲染  这里使用 index+1 展示了页面的索引值 -->\n    <song-list\n      v-for=\"(item, index) in albumInfo.tracks || albumInfo.songs\"\n      :key=\"index\"\n      :songName=\"item.name\"\n      :artists=\"item.ar\"\n      :albumName=\"item.al.name\"\n      :num=\"index + 1\"\n      @beginSong=\"setAudioList(item, index)\"\n      :nowSong=\"item.id === audioSong.id\"\n    ></song-list>\n  </song-list-page>\n</template>\n\n<script>\nimport { mapActions, mapGetters } from 'vuex'\nimport songList from 'base/song'\nimport songListPage from 'base/songListPage'\nimport api from 'api'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      // 存储信息的数组\n      albumInfo: [],\n      // 用来定义是否显示load加载组件\n      load: true,\n      albumId: 0,\n      dishId: 0,\n      idxId: 0,\n      idxComId: 0,\n      title: ''\n    }\n  },\n  components: {\n    songListPage,\n    songList\n  },\n  /**\n   * 生命钩子函数在实例创建完成后被立即调用\n   */\n  created () {\n    // if (this.albumInfo) {\n    //   this.$router.go(-1)\n    // }\n  },\n  activated () {\n    this.load = true\n    this.albumInfo = []\n    let albumId = this.$route.params.albumId\n    let idxId = this.$route.params.idxId\n    let dishId = this.$route.params.dishId\n    if (albumId) {\n      this.title = '歌单'\n      this.albumId = +albumId\n      this._getInfo(albumId)\n      return\n    }\n    if (idxId || idxId === 0) {\n      this.title = ''\n      this.idxId = +idxId\n      this._getIdxInfo(idxId)\n      return\n    }\n    if (dishId) {\n      this.title = '专辑'\n      this.dishId = +dishId\n      this._getDishInfo(dishId)\n      return\n    }\n    // !Number(0) === true\n    /**\n     * 判断当在歌单页面刷新时无法获取到歌单内容\n     * 获取到的id值为undefined\n     */\n    if (!idxId || !albumId || !dishId) {\n      this.$router.go(-1)\n    }\n  },\n  computed: {\n    ...mapGetters({ audioSong: 'AUDIO_ING_SONG' })\n  },\n  methods: {\n    /**\n     * 根据传入的id获取歌单信息\n     *\n     * 这里需要增加 catch 方法！！！\n     */\n    _getInfo (id) {\n      // 这里使用的是定义的接口信息，详情查看 api 文件夹\n      api.albumDetailFn(id)\n        // 请求成功后返回数据\n        .then(res => {\n          // 接受数据\n          const data = res.data\n          // 查看返回数据的 code 状态，如果是 200 的话进行使用\n          if (data.code === 200) {\n            // 将请求回来的数据使用，将load 样式关闭\n            this.albumInfo = data.playlist\n            this.load = false\n          }\n        })\n        .catch(error => {\n          console.log(error)\n        })\n    },\n    /**\n     * 获取排行榜信息\n     */\n    _getIdxInfo (id) {\n      api.idxListFn(id)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.albumInfo = data.playlist\n            this.idxComId = data.playlist.id\n            this.load = false\n          }\n        })\n    },\n    /**\n     * 获取专辑内容\n     */\n    _getDishInfo (id) {\n      api.getDishInfoFn(id)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.albumInfo = data\n            this.load = false\n          }\n        })\n    },\n    setAudioList (item, index) {\n      this.selectPlay({\n        list: this.albumInfo.tracks,\n        index\n      })\n    },\n    startPlay () {\n      this.startPlayAll({\n        list: this.albumInfo.tracks\n      })\n    },\n    ...mapActions(['selectPlay', 'startPlayAll'])\n  },\n  destroyed () {\n    // 存储信息的数组\n    this.albumInfo = []\n    // 用来定义是否显示load加载组件\n    this.load = true\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/albumPage/index2.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-13 12:03:28\n * @Update: 2019-11-30 13:55:02\n * @Update log: 更新日志\n -->\n<template>\n  <detail-page :name=\"name\" :coverImgUrl=\"coverImgUrl\" :title=\"title\">\n    <div slot=\"data\">\n      <div class=\"info-top\">\n        <div class=\"img-info\">\n          <img v-lazy=\"imgUrl + '?param=200y200'\" :key=\"imgUrl\" alt />\n          <span class=\"play-count\">\n            <i class=\"date-song bofang\"></i>\n            {{playCount | setPlay}}\n          </span>\n        </div>\n        <div class=\"info-con\">\n          <p class=\"album-title\">{{iAlbumTitle}}</p>\n          <div class=\"creator\">\n            <div class=\"img-info\">\n              <img v-lazy=\"creatorImgUrl + '?param=200y200'\" :key=\"imgUrl\" alt />\n            </div>\n            <span>\n              {{author}}\n              <i class=\"date-song iconfontjiantou5\"></i>\n            </span>\n          </div>\n          <div class=\"desc-wrapper\">\n            <span class=\"desc\">{{description}}</span>\n            <i class=\"date-song iconfontjiantou5\"></i>\n          </div>\n        </div>\n      </div>\n      <div class=\"icons\">\n        <div class=\"comments\" @click=\"goComments\">\n          <i class=\"date-song pinglun\"></i>\n          <span>{{commentCount | setCom}}</span>\n        </div>\n        <div class=\"comments\">\n          <i class=\"date-song fenxiang\"></i>\n          <span>{{shareCount | setShare}}</span>\n        </div>\n        <div class=\"comments\">\n          <i class=\"date-song xiazai\"></i>\n          <span>下载</span>\n        </div>\n        <div class=\"comments\">\n          <i class=\"date-song duoxuankuang\"></i>\n          <span>多选</span>\n        </div>\n      </div>\n    </div>\n    <div slot=\"nav-list\" class=\"title pd23\">\n      <span>\n        <span @click=\"beginAudio\">\n          <i class=\"date-song cbofang\"></i>\n          播放全部\n        </span>\n        <!-- 当歌单组件时，需要显示当前歌单总共有多少首歌曲的信息 -->\n        <span class=\"count\" v-if=\"isAlbum\">(共{{trackCount}}首)</span>\n      </span>\n      <div class=\"collection\" :class=\"{ 'bg': !isSubInItem }\" ref=\"collection\" v-if=\"isAlbum\">\n        <span v-show=\"!isSubInItem\" @click=\"addPlaylist\">+ 收藏({{subscribedCountItem | setCol}})</span>\n        <span v-show=\"isSubInItem\" @click=\"deletePlaylist\">\n          <i class=\"date-song wenjianjia\"></i>\n          {{subscribedCountItem | setCol}}\n        </span>\n      </div>\n    </div>\n    <div slot=\"bottom\">\n      <song-list\n        v-for=\"(item, index) in albumInfo.tracks || albumInfo.songs\"\n        :key=\"index\"\n        :songName=\"item.name\"\n        :artists=\"item.ar\"\n        :albumName=\"item.al.name\"\n        :num=\"index + 1\"\n        @beginSong=\"setAudioList(item, index)\"\n        :nowSong=\"item.id === audioSong.id\"\n      ></song-list>\n    </div>\n    <slider\n      slot=\"slider\"\n      ref=\"slider\"\n      :title=\"title\"\n      :author=\"name\"\n      :imgUrl=\"coverImgUrl\"\n      :id=\"itemId\"\n      :djDetailList=\"djDetail\"\n    ></slider>\n  </detail-page>\n</template>\n\n<script>\nimport { mapActions, mapGetters } from 'vuex'\nimport { filterSetPlayCount } from 'utils/filters'\nimport detailPage from '@/components/detailPage'\nimport songList from 'base/song'\nimport pageLoading from 'base/pageLoading'\nimport slider from 'base/slider'\n\nimport api from 'api'\nexport default {\n  name: '',\n  data () {\n    return {\n      // 存储信息的数组\n      albumInfo: [],\n      // 用来定义是否显示load加载组件\n      load: true,\n      albumId: 0,\n      dishId: 0,\n      idxId: 0,\n      idxComId: 0,\n      iTitle: '歌单',\n      name: '',\n      isSubInItem: false,\n      loading: true,\n      title: '歌单',\n      subed: false,\n      ridId: 0,\n      itemId: 0,\n      imgUrl: '',\n      albumTitle: '',\n      creatorImgUrl: '',\n      author: '',\n      description: '',\n      commentCount: 0,\n      shareCount: 0,\n      trackCount: 0,\n      subscribedCount: 0,\n      subscribe: '',\n      isSubIn: false,\n      playCount: 0\n    }\n  },\n  filters: {\n    setCom: (val) => {\n      if (!val) {\n        return '评论'\n      }\n      return filterSetPlayCount(val)\n    },\n    setShare: (val) => {\n      if (!val) {\n        return '分享'\n      }\n      return filterSetPlayCount(val)\n    },\n    setCol: (val) => {\n      if (!val) {\n        return ''\n      }\n      return filterSetPlayCount(val)\n    },\n    setPlay: (val) => {\n      if (!val) {\n        return ''\n      }\n      return filterSetPlayCount(val)\n    }\n  },\n  computed: {\n    /**\n     * 返回日\n     */\n    day: function () {\n      const day = new Date().getDate() < 10\n        ? '0' + new Date().getDate()\n        : new Date().getDate()\n      return day\n    },\n    /**\n     * 返回月份\n     */\n    month: function () {\n      const month = new Date().getMonth() + 1 < 10\n        ? '0' + (new Date().getMonth() + 1)\n        : new Date().getMonth() + 1\n      return month\n    },\n    ...mapGetters({ audioSong: 'AUDIO_ING_SONG' })\n  },\n  activated () {\n    this.loading = true\n    this.albumInfo = []\n    let albumId = this.$route.params.albumId\n    let idxId = this.$route.params.idxId\n    let dishId = this.$route.params.dishId\n    if (albumId) {\n      this.title = '歌单'\n      this.albumId = +albumId\n      this._getInfo(albumId)\n      return\n    }\n    if (idxId || idxId === 0) {\n      this.title = ''\n      this.idxId = +idxId\n      this._getIdxInfo(idxId)\n      return\n    }\n    if (dishId) {\n      this.title = '专辑'\n      this.dishId = +dishId\n      this._getDishInfo(dishId)\n      return\n    }\n    /**\n     * 判断当在歌单页面刷新时无法获取到歌单内容\n     * 获取到的id值为undefined\n     */\n    if (!idxId || !albumId || !dishId) {\n      this.$router.go(-1)\n    }\n  },\n  methods: {\n    /**\n     * 收藏歌单\n     */\n    addPlaylist () {\n      const id = this.albumId || this.dishId || this.idxId\n      api.addOrDeletePlaylistFn(1, id)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.isSubInItem = true\n            ++this.subscribedCountItem\n          }\n        })\n    },\n    /**\n     * 取消收藏歌单\n     */\n    deletePlaylist () {\n      const id = this.albumId || this.dishId || this.idxId\n      api.addOrDeletePlaylistFn(2, id)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.isSubInItem = false\n            --this.subscribedCountItem\n          }\n        })\n    },\n    /**\n     * 去评论页面\n     * 通过传不同的params的属性来判断资源是歌单还是专辑\n     */\n    goComments () {\n      const playlistId = this.albumId ? this.albumId : this.idxComId\n      const albumId = this.dishId\n      const imgUrl = this.imgUrl\n      const title = this.albumTitle\n      const author = this.author\n      this.$router.push({ name: 'comments', params: { playlistId, albumId, imgUrl, title, author } })\n    },\n    update_iTitle (con) {\n      this.iTitle = con\n    },\n    _getDjDetailInfo (id) {\n      api.djDetailFn(id)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            this.name = data.djRadio.name\n            this.coverImgUrl = data.djRadio.picUrl + '?param=300y300'\n            this.subscription = data.djRadio.subCount\n            this.avatarUrl = data.djRadio.dj.avatarUrl + '?param=100y100'\n            this.desc = data.djRadio.desc\n            this.detailName = data.djRadio.dj.nickname\n            this.category = data.djRadio.category\n            this.subed = data.djRadio.subed\n          }\n        })\n    },\n    addDj () {\n      api.djSubFn(this.ridId, 1)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            this.subed = true\n            console.log(data)\n          }\n        })\n    },\n    showSlider (id) {\n      console.log(this.$refs)\n      this.title = '电台节目：' + this.name\n      this.djDetail = true\n      this.itemId = id\n      this.$refs.slider.showSlider()\n    },\n    deleteDj () {\n      api.djSubFn(this.ridId, 0)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            console.log(data)\n            this.subed = false\n          }\n        })\n    },\n    changeToFirst () {\n      this.active = 'first'\n    },\n    changeToSecond () {\n      this.active = 'second'\n    },\n    setAudioList (item, index) {\n      this.selectPlay({\n        list: this.djProgramData,\n        index\n      })\n    },\n    ...mapActions(['selectPlay'])\n  },\n  components: {\n    detailPage,\n    songList,\n    pageLoading,\n    slider\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"//at.alicdn.com/t/font_1394963_t6jt71rtm9.css\");\n@import url(\"~styles/global.less\");\n@textColor: #ccc;\n\n.title {\n  font-size: 0.3rem;\n  height: 1rem;\n  line-height: 1rem;\n  .flex-between();\n  background-color: #fff;\n  .count {\n    color: #999;\n    font-size: small;\n  }\n  .collection {\n    .pd23();\n    font-size: smaller;\n    margin-top: 3px;\n    height: 0.7rem;\n    line-height: 0.7rem;\n    border-radius: 0.4rem;\n    color: #999;\n    &.bg {\n      background-color: @bgcolor;\n      color: #fff;\n    }\n  }\n}\n.info-top {\n  height: 3rem;\n  .flex-between();\n  overflow: hidden;\n  .img-info {\n    @size: 2.6rem;\n    width: @size;\n    height: 0;\n    position: relative;\n    padding-bottom: @size;\n    border-radius: @imgBorderRadius;\n    overflow: hidden;\n    img {\n      width: @size;\n      height: @size;\n    }\n    .play-count {\n      position: absolute;\n      top: 0.1rem;\n      right: 0.1rem;\n      .bofang {\n        font-size: 0.24rem;\n      }\n    }\n  }\n  .info-con {\n    width: 3.6rem;\n    height: 2.6rem;\n    display: flex;\n    flex-direction: column;\n    overflow: hidden;\n    .album-title {\n      font-size: 0.36rem;\n      line-height: 1.5;\n      .twoLinesEllipsis();\n    }\n    .creator {\n      height: 1rem;\n      color: @textColor;\n      display: flex;\n      align-items: center;\n      .img-info {\n        @size: 0.6rem;\n        width: @size;\n        height: 0;\n        padding-bottom: @size;\n        margin-right: 8px;\n        border-radius: 50%;\n        overflow: hidden;\n        img {\n          width: @size;\n          height: @size;\n        }\n      }\n    }\n    .desc-wrapper {\n      display: flex;\n      align-items: center;\n      color: @textColor;\n      .desc {\n        width: 3rem;\n        .twoLinesEllipsis();\n      }\n    }\n  }\n}\n.icons {\n  margin-top: 8px;\n  .flex-around();\n  width: 100%;\n  .comments {\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    flex-direction: column;\n    .date-song {\n      font-size: 0.4rem;\n      margin-bottom: 5px;\n    }\n  }\n}\n.list-info {\n  width: 100%;\n  box-sizing: border-box;\n  padding: 0.1rem 0.23rem;\n  background-color: #fff;\n  transform: translate3d(0, -0.5rem, 0);\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/alert.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-17 17:10:07\n * @Update: 2019-09-23 17:38:12\n * @Update log: 底部错误信息提示组件\n -->\n<template>\n  <div>\n    <transition>\n      <!-- 调用时传入要显示的内容 -->\n      <div class=\"alert\" v-show=\"isAlert\">{{ alert }}</div>\n    </transition>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: 'alert',\n  props: {\n    alert: {\n      type: String\n    },\n    isAlert: {\n      type: Boolean\n    }\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n.alert {\n  position: fixed;\n  bottom: 3rem;\n  left: 50%;\n  transform: translateX(-50%);\n  padding: 0.13rem;\n  background-color: rgba(170, 170, 170, 0.6);\n  font-size: smaller;\n  border-radius: 8px;\n}\n.v-enter-active,\n.v-leave-active {\n  transition: opacity 0.5s;\n}\n.v-enter,\n.v-leave-to {\n  opacity: 0;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/audioAllTitle.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-28 12:56:39\n * @Update: 2019-09-28 12:56:39\n * @Update log: 播放全部的那一行\n *\n * 使用时传入当前列表有几首歌曲，用来显示\n -->\n<template>\n  <div class=\"title\">\n    <span>\n      <!-- 点击事件，点击 播放全部 按钮 -->\n      <span @click=\"beginAudio\">\n        <i class=\"audio_all audio_allbofang\"></i>\n        播放全部\n      </span>\n      <!-- 当歌单组件时，需要显示当前歌单总共有多少首歌曲的信息 -->\n      <span class=\"count\">(共{{trackCount}}首)</span>\n    </span>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: '',\n  props: {\n    trackCount: {\n      type: Number\n    }\n  },\n  methods: {\n    // 触发播放全部事件\n    beginAudio () {\n      this.$emit('beginAudioAll')\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"//at.alicdn.com/t/font_1439756_kjcwl3bv5jo.css\");\n@import url(\"~styles/global.less\");\n\n.title {\n  font-size: 0.3rem;\n  height: 0.8rem;\n  line-height: 0.8rem;\n  .flex-between();\n  background-color: #fff;\n  .count {\n    color: #999;\n    font-size: small;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/button.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-14 16:21:48\n * @Update: 2019-08-18 13:43:11\n * @Update log: 通用 button 登录页按钮\n *\n * 使用时传入 button 内容\n -->\n<template>\n  <div class=\"btn\">\n    <button id=\"btn\"></button>\n    <label class=\"label\" for=\"btn\" ref=\"btnText\">{{ title }}</label>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: 'loginBtn',\n  // 定义默认的 button 内容为下一步\n  props: {\n    title: {\n      type: String,\n      default: '下一步'\n    }\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url(\"~styles/global.less\");\n.btn {\n  .flex-center();\n  text-align: center;\n  #btn {\n    position: absolute;\n    clip: rect(0, 0, 0, 0);\n  }\n  .label {\n    box-sizing: border-box;\n    margin-top: 30px;\n    padding: 8px;\n    border-radius: 20px;\n    line-height: 20px;\n    width: 80%;\n    color: #fff;\n    background: @bgcolor;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/circleLoading.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-11-04 13:58:11\n * @Update: 2019-11-07 19:55:14\n * @Update log: 更新日志\n -->\n<template>\n  <div\n    class=\"circle-load\"\n    :style=\"{width, height}\"\n    v-show=\"load\"\n    :class=\"{absolute: type === 'absolute' }\"\n  >\n    <svg viewBox=\"25 25 50 50\">\n      <circle cx=\"50\" cy=\"50\" r=\"20\" />\n    </svg>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: '',\n  data () {\n    return {\n      load: false\n    }\n  },\n  props: {\n    type: {\n      type: String\n    },\n    width: {\n      type: String\n    },\n    height: {\n      type: String\n    }\n  },\n  methods: {\n    block () {\n      this.load = true\n    },\n    none () {\n      this.load = false\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n.circle-load {\n  top: 0;\n  display: flex;\n  justify-content: center;\n  &.absolute {\n    position: absolute;\n    z-index: 5;\n  }\n}\nsvg {\n  width: 3.75em;\n  transform-origin: center;\n  animation: rotate 2s linear infinite;\n}\n\ncircle {\n  fill: none;\n  stroke: #7b7c7d;\n  stroke-width: 2;\n  stroke-dasharray: 1, 200;\n  stroke-dashoffset: 0;\n  stroke-linecap: round;\n  animation: dash 1.5s ease-in-out infinite;\n}\n\n@keyframes rotate {\n  100% {\n    transform: rotate(360deg);\n  }\n}\n\n@keyframes dash {\n  0% {\n    stroke-dasharray: 1, 200;\n    stroke-dashoffset: 0;\n  }\n  50% {\n    stroke-dasharray: 90, 200;\n    stroke-dashoffset: -35px;\n  }\n  100% {\n    stroke-dashoffset: -125px;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/comments.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-27 09:14:42\n * @Update: 2019-11-12 19:11:06\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\">\n    <h1 class=\"title\">\n      {{title}}\n      <span class=\"num\">{{total}}</span>\n    </h1>\n    <div\n      class=\"item border-bottom\"\n      @click=\"showMenu(item)\"\n      v-for=\"(item, index) in comments\"\n      :key=\"index\"\n    >\n      <div class=\"left-img\">\n        <img :src=\"item.user.avatarUrl + '?param=50y50'\" alt />\n      </div>\n      <div class=\"right-info\">\n        <div class=\"top-info\">\n          <div class=\"data\">\n            <div class=\"nickname\">{{item.user.nickname}}</div>\n            <div class=\"time\">{{ item.time | setTime}}</div>\n          </div>\n          <div\n            class=\"like\"\n            :class=\"{liked: item.liked}\"\n            @click.stop=\"likeThisComment(item.commentId, item.liked)\"\n          >\n            <span v-show=\"item.likedCount > 0\">{{item.likedCount}}</span>\n            <i class=\"comment\" :class=\"{ commentzan: !item.liked, commentzan1:item.liked}\"></i>\n          </div>\n        </div>\n        <!-- 这里使用 v-html 用来解析 当出现 \\n 换行的时候插入 <br />标签 -->\n        <div class=\"content\" v-html=\"setCon(item.content)\"></div>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script>\nimport { filterSetMonth } from 'utils/filters'\nimport Bus from '@/assets/Bus'\nexport default {\n  name: '',\n  props: {\n    total: {\n      type: Number\n    },\n    comments: {\n      type: Array\n    },\n    title: {\n      type: String\n    }\n  },\n  filters: {\n    setTime: function (val) {\n      return filterSetMonth(val, '月', '日')\n    }\n  },\n  methods: {\n    likeThisComment (cid, isLike) {\n      let like = 1\n      // 默认为点赞\n      if (isLike) {\n        // 如果当前歌曲已经赞了，则取消点赞\n        like = 0\n      }\n      this.$emit('likeComment', cid, like)\n    },\n    showMenu (item) {\n      console.log(item)\n      const localUserId = +localStorage.getItem('accountUid')\n      const userId = item.user.userId\n      if (localUserId === userId) {\n        // 当前评论是自己的，可以删除，不能举报\n        Bus.$emit('user', true)\n      }\n      Bus.$emit('comId', item.commentId)\n      this.$emit('showMenu')\n    },\n    /**\n     * 将返回来的数据进行格式化处理\n     * 将 换行符\\n 替换成 <br /> 实现换行\n     * 将 回车符\\r\\n 替换成 <br /> 实现换行\n     */\n    setCon (val) {\n      val = val.replace(/(\\n)|(\\r\\n)/g, '<br />')\n      return val\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n@import url(\"//at.alicdn.com/t/font_1478463_b9awmkqysf8.css\");\n\n.wrapper {\n  margin-top: 0.3rem;\n}\n.title {\n  font-weight: 700;\n}\n.item {\n  display: flex;\n  box-sizing: border-box;\n  margin: 0.3rem 0;\n  padding-bottom: 0.3rem;\n  height: auto;\n  .left-img {\n    width: 0.6rem;\n    height: 0;\n    padding-bottom: 0.6rem;\n    margin-right: 0.2rem;\n    img {\n      width: 0.6rem;\n      height: 0.6rem;\n      border-radius: 50%;\n    }\n  }\n  .right-info {\n    width: 100%;\n    .top-info {\n      color: #999;\n      line-height: 1.3;\n      font-size: 0.24rem;\n      .flex-between();\n      margin-bottom: 0.13rem;\n      .data {\n        .time {\n          font-size: 0.21rem;\n        }\n      }\n      .liked {\n        color: @bgcolor;\n      }\n    }\n    .content {\n      line-height: 1.5;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/djDetailPage/components/changeNav.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-14 13:34:16\n * @Update: 2019-10-28 09:17:00\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"title\">\n    <div class=\"content\" @click=\"changeToFirst\">\n      <span class=\"under-line\" :class=\"{active: active === 'first'}\">{{firstNav}}</span>\n    </div>\n    <div class=\"content\" @click=\"changeToSecond\">\n      <span class=\"under-line\" :class=\"{active: active === 'second'}\">{{secondNav}}</span>\n      <span class=\"num\">{{count}}</span>\n    </div>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: '',\n  props: {\n    active: {\n      type: String,\n      default: 'second'\n    },\n    count: {\n      type: Number\n    },\n    firstNav: {\n      type: String\n    },\n    secondNav: {\n      type: String\n    }\n  },\n  methods: {\n    changeToFirst () {\n      this.$emit('changeToFirst')\n    },\n    changeToSecond () {\n      this.$emit('changeToSecond')\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.under-line {\n  position: relative;\n  padding-bottom: 0.25rem;\n}\n\n.under-line::before {\n  content: \"\";\n  position: absolute;\n  left: 50%;\n  bottom: 0;\n  width: 100%;\n  height: 2px;\n  background-color: #fc2f70;\n  transform-origin: center;\n  transform: translate(-50%, 0) scaleX(0);\n  transition: transform 0.3s ease-in-out;\n}\n\n.under-line.active::before {\n  transform: translate(-50%, 0) scaleX(1);\n}\n.title {\n  height: 0.8rem;\n  line-height: 0.8rem;\n  background-color: #fff;\n  border-top-left-radius: 0.4rem;\n  border-top-right-radius: 0.4rem;\n  display: flex;\n  transform: translateY(-0.7rem);\n  .content {\n    flex: 1;\n    text-align: center;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/djDetailPage/index.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-13 12:03:28\n * @Update: 2019-11-29 13:28:44\n * @Update log: 更新日志\n -->\n<template>\n  <detail-page :title=\"title\" :name=\"name\" :coverImgUrl=\"coverImgUrl\">\n    <div slot=\"data\">\n      <div>\n        <div class=\"name\">{{name}}</div>\n        <div class=\"num\">{{subscription | setCount}}人已订阅</div>\n      </div>\n      <div class=\"subscription\" v-show=\"!subed\" @click.prevent=\"addDj\">\n        <svg\n          t=\"1571198266501\"\n          class=\"icon\"\n          viewBox=\"0 0 1024 1024\"\n          version=\"1.1\"\n          xmlns=\"http://www.w3.org/2000/svg\"\n          p-id=\"1753\"\n          width=\"14\"\n          height=\"14\"\n        >\n          <path\n            d=\"M737.792 910.6944a57.2416 57.2416 0 0 1-26.7264-6.656l-197.5296-103.8336-197.5296 103.8336a57.2416 57.2416 0 0 1-83.0464-60.3648l37.6832-220.16L110.848 467.968a57.2928 57.2928 0 0 1 31.744-97.6896L363.52 338.2272 462.1824 138.24a56.832 56.832 0 0 1 51.2-31.8976 56.9344 56.9344 0 0 1 51.2 31.8976l98.7648 200.1408 220.8256 32.0512A57.2928 57.2928 0 0 1 916.48 467.968l-159.7952 155.7504 37.7344 220.16a57.3952 57.3952 0 0 1-56.32 67.0208zM159.8464 430.08l155.2896 151.3984a57.2416 57.2416 0 0 1 16.4352 50.688l-36.6592 213.5552 192-100.9152a57.088 57.088 0 0 1 53.2992 0L732.16 845.7216l-36.6592-213.76a57.344 57.344 0 0 1 16.4352-50.688L867.2768 430.08l-214.6304-31.1808a57.2928 57.2928 0 0 1-43.1104-31.3344l-96-194.56-96 194.56a57.2416 57.2416 0 0 1-43.1104 31.3344z m715.6736 1.024zM509.7984 165.2736z\"\n            fill=\"#ffffff\"\n            p-id=\"1754\"\n          />\n        </svg>订阅\n      </div>\n      <div class=\"subscription1\" v-show=\"subed\" @click.prevent=\"deleteDj\">\n        <svg\n          t=\"1571203188806\"\n          class=\"icon\"\n          viewBox=\"0 0 1024 1024\"\n          version=\"1.1\"\n          xmlns=\"http://www.w3.org/2000/svg\"\n          p-id=\"2523\"\n          width=\"14\"\n          height=\"14\"\n        >\n          <path\n            d=\"M926.037333 224.256c-22.016-22.016-57.685333-22.016-79.701333 0L384.853333 685.738667 179.370667 480.256c-22.016-22.016-57.685333-22.016-79.701334 0-22.016 22.016-22.016 57.685333 0 79.701333l239.786667 239.786667c12.458667 12.458667 29.184 17.749333 45.397333 16.213333 16.213333 1.536 32.938667-3.754667 45.397334-16.213333l495.786666-495.786667c22.016-22.016 22.016-57.685333 0-79.701333z\"\n            fill=\"#ffffff\"\n            p-id=\"2524\"\n          />\n        </svg>已订阅\n      </div>\n    </div>\n    <change-nav\n      slot=\"nav-list\"\n      :active=\"active\"\n      :count=\"count\"\n      firstNav=\"详情\"\n      secondNav=\"节目\"\n      @changeToSecond=\"changeToSecond\"\n      @changeToFirst=\"changeToFirst\"\n    ></change-nav>\n    <div slot=\"bottom\">\n      <div class=\"song-list\" v-show=\"active==='second'\">\n        <page-loading v-show=\"loading\"></page-loading>\n        <div v-show=\"!loading\">\n          <h1 class=\"sum-num pd23\">共{{count}}期</h1>\n          <song-list\n            class=\"pd23\"\n            v-for=\"(item, index) in djProgramData\"\n            :key=\"index\"\n            :songName=\"item.name\"\n            :num=\"djProgramData.length - index\"\n            :createTime=\"item.createTime\"\n            :listenerCount=\"item.listenerCount\"\n            :duration=\"item.duration\"\n            :twoLine=\"true\"\n            :itemId=\"item.id\"\n            @showSlider=\"showSlider\"\n            type=\"djList\"\n            @beginSong=\"setAudioList(item, index)\"\n            :nowSong=\"item.id === audioSong.id\"\n          ></song-list>\n        </div>\n      </div>\n      <div class=\"detail pd23\" v-show=\"active==='first'\">\n        <h1 class=\"anchor\">主播</h1>\n        <div class=\"content\">\n          <div class=\"img-info\">\n            <img :src=\"avatarUrl\" alt />\n          </div>\n          <div class=\"artist\">\n            <p class=\"name\">{{detailName}}</p>\n            <p class=\"dec\">网易音乐人</p>\n          </div>\n        </div>\n        <h1 class=\"dj-content\">电台内容简介</h1>\n        <div class=\"class\">\n          <span>分类</span>\n          <span class=\"tag\">{{category}}</span>\n        </div>\n        <p class=\"text\">{{desc}}</p>\n      </div>\n    </div>\n    <slider\n      slot=\"slider\"\n      ref=\"slider\"\n      :title=\"title\"\n      :author=\"name\"\n      :imgUrl=\"coverImgUrl\"\n      :id=\"itemId\"\n      :djDetailList=\"djDetail\"\n    ></slider>\n  </detail-page>\n</template>\n\n<script>\nimport { mapActions, mapGetters } from 'vuex'\nimport { filterSetPlayCount } from 'utils/filters'\nimport detailPage from '@/components/detailPage'\nimport changeNav from './components/changeNav'\nimport songList from 'base/song'\nimport pageLoading from 'base/pageLoading'\nimport slider from 'base/slider'\n\nimport api from 'api'\nexport default {\n  name: '',\n  data () {\n    return {\n      djProgramData: [],\n      djDetail: false,\n      coverImgUrl: '',\n      count: 0,\n      name: '',\n      subscription: 0,\n      active: 'second',\n      avatarUrl: '',\n      detailName: '',\n      category: '',\n      desc: '',\n      loading: true,\n      title: '电台',\n      subed: false,\n      ridId: 0,\n      itemId: 0\n    }\n  },\n  computed: {\n    ...mapGetters({ audioSong: 'AUDIO_ING_SONG' })\n  },\n  activated () {\n    this.loading = true\n    this.coverImgUrl = ''\n    this.count = 0\n    this.name = ''\n    this.active = 'second'\n    const params = this.$route.params\n    if (!params.ridId) {\n      this.$router.go(-1)\n      return\n    }\n    this.ridId = params.ridId\n    const ridId = this.ridId\n    this._getDjProgramInfo(ridId)\n    this._getDjDetailInfo(ridId)\n  },\n  filters: {\n    setCount: val => (\n      filterSetPlayCount(val)\n    )\n  },\n  methods: {\n    _getDjProgramInfo (id) {\n      let limit = 30\n      let offset = 0\n      let asc = false\n      api.djProgramFn(id, limit, offset, asc)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            this.count = data.count\n            this.djProgramData = data.programs\n            this.loading = false\n          }\n        })\n    },\n    _getDjDetailInfo (id) {\n      api.djDetailFn(id)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            this.name = data.djRadio.name\n            this.coverImgUrl = data.djRadio.picUrl + '?param=300y300'\n            this.subscription = data.djRadio.subCount\n            this.avatarUrl = data.djRadio.dj.avatarUrl + '?param=100y100'\n            this.desc = data.djRadio.desc\n            this.detailName = data.djRadio.dj.nickname\n            this.category = data.djRadio.category\n            this.subed = data.djRadio.subed\n          }\n        })\n    },\n    addDj () {\n      api.djSubFn(this.ridId, 1)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            this.subed = true\n            console.log(data)\n          }\n        })\n    },\n    showSlider (id) {\n      console.log(this.$refs)\n      this.title = '电台节目：' + this.name\n      this.djDetail = true\n      this.itemId = id\n      this.$refs.slider.showSlider()\n    },\n    deleteDj () {\n      api.djSubFn(this.ridId, 0)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            console.log(data)\n            this.subed = false\n          }\n        })\n    },\n    changeToFirst () {\n      this.active = 'first'\n    },\n    changeToSecond () {\n      this.active = 'second'\n    },\n    setAudioList (item, index) {\n      this.selectPlay({\n        list: this.djProgramData,\n        index\n      })\n    },\n    ...mapActions(['selectPlay'])\n  },\n  components: {\n    detailPage,\n    changeNav,\n    songList,\n    pageLoading,\n    slider\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n\n.name {\n  color: #fff;\n  max-width: 4rem;\n  .twoLinesEllipsis();\n  font-size: 0.3rem;\n  line-height: 1.5;\n}\n.num {\n  color: #eee;\n  line-height: 1.5;\n}\n.subscription {\n  box-sizing: border-box;\n  position: absolute;\n  right: 0.5rem;\n  bottom: 0;\n  display: flex;\n  padding: 0 0.23rem;\n  height: 0.5rem;\n  align-items: center;\n  justify-content: center;\n  color: #fff;\n  background-color: @bgcolor;\n  border-radius: 0.4rem;\n  .icon {\n    margin-right: 0.2rem;\n  }\n}\n.subscription1 {\n  box-sizing: border-box;\n  position: absolute;\n  right: 0.5rem;\n  bottom: 0;\n  display: flex;\n  padding: 0 0.23rem;\n  height: 0.5rem;\n  align-items: center;\n  justify-content: center;\n  color: #fff;\n  border-radius: 0.4rem;\n  border: 1px solid #fff;\n  .icon {\n    margin-right: 0.2rem;\n  }\n}\n.song-list {\n  .sum-num {\n    height: 0.5rem;\n    line-height: 0.5rem;\n    font-weight: 700;\n  }\n}\n.detail {\n  .anchor,\n  .dj-content {\n    font-weight: 700;\n    line-height: 1.5;\n    margin: 0.3rem 0;\n  }\n  .content {\n    display: flex;\n    align-items: center;\n    .img-info {\n      width: 1rem;\n      height: 0;\n      padding-bottom: 1rem;\n      margin-right: 0.2rem;\n      img {\n        border-radius: 50%;\n        width: 1rem;\n        height: 1rem;\n      }\n    }\n    .artist {\n      display: flex;\n      flex-direction: column;\n      line-height: 1.5;\n      .dec {\n        font-size: 0.23rem;\n        color: #999;\n      }\n    }\n  }\n  .class {\n    font-size: 0.23rem;\n    line-height: 1.5;\n    .tag {\n      color: @bgcolor;\n      box-sizing: border-box;\n      padding: 2px;\n      border-radius: 4px;\n      border: 1px solid @bgcolor;\n    }\n  }\n  .text {\n    font-size: 0.23rem;\n    color: #999;\n    margin-top: 0.13rem;\n    line-height: 1.5;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/djDetailPage/index2.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-13 12:03:28\n * @Update: 2019-11-14 14:03:58\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\" @scroll=\"scrollList\">\n    <dj-detail-nav @returnPage=\"returnPage\" class=\"fixed pd23\" style=\"color:#fff;\">\n      <span class=\"text\">{{iTitle}}</span>\n    </dj-detail-nav>\n    <div\n      class=\"container-top\"\n      :class=\"{coverFixed, position}\"\n      :style=\"{backgroundImage: 'url(' + coverImgUrl + ')'}\"\n    >\n      <div class=\"cover\" :style=\"{backgroundColor: `rgba(0, 0, 0, ${cover})`}\"></div>\n      <div class=\"data\" v-show=\"!listFixed\" :style=\"{opacity}\">\n        <div>\n          <div class=\"name\">{{name}}</div>\n          <div class=\"num\">{{subscription}}人已订阅</div>\n        </div>\n        <div class=\"subscription\" v-show=\"!subed\" @click.prevent=\"addDj\">\n          <svg\n            t=\"1571198266501\"\n            class=\"icon\"\n            viewBox=\"0 0 1024 1024\"\n            version=\"1.1\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n            p-id=\"1753\"\n            width=\"14\"\n            height=\"14\"\n          >\n            <path\n              d=\"M737.792 910.6944a57.2416 57.2416 0 0 1-26.7264-6.656l-197.5296-103.8336-197.5296 103.8336a57.2416 57.2416 0 0 1-83.0464-60.3648l37.6832-220.16L110.848 467.968a57.2928 57.2928 0 0 1 31.744-97.6896L363.52 338.2272 462.1824 138.24a56.832 56.832 0 0 1 51.2-31.8976 56.9344 56.9344 0 0 1 51.2 31.8976l98.7648 200.1408 220.8256 32.0512A57.2928 57.2928 0 0 1 916.48 467.968l-159.7952 155.7504 37.7344 220.16a57.3952 57.3952 0 0 1-56.32 67.0208zM159.8464 430.08l155.2896 151.3984a57.2416 57.2416 0 0 1 16.4352 50.688l-36.6592 213.5552 192-100.9152a57.088 57.088 0 0 1 53.2992 0L732.16 845.7216l-36.6592-213.76a57.344 57.344 0 0 1 16.4352-50.688L867.2768 430.08l-214.6304-31.1808a57.2928 57.2928 0 0 1-43.1104-31.3344l-96-194.56-96 194.56a57.2416 57.2416 0 0 1-43.1104 31.3344z m715.6736 1.024zM509.7984 165.2736z\"\n              fill=\"#ffffff\"\n              p-id=\"1754\"\n            />\n          </svg>订阅\n        </div>\n        <div class=\"subscription1\" v-show=\"subed\" @click.prevent=\"deleteDj\">\n          <svg\n            t=\"1571203188806\"\n            class=\"icon\"\n            viewBox=\"0 0 1024 1024\"\n            version=\"1.1\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n            p-id=\"2523\"\n            width=\"14\"\n            height=\"14\"\n          >\n            <path\n              d=\"M926.037333 224.256c-22.016-22.016-57.685333-22.016-79.701333 0L384.853333 685.738667 179.370667 480.256c-22.016-22.016-57.685333-22.016-79.701334 0-22.016 22.016-22.016 57.685333 0 79.701333l239.786667 239.786667c12.458667 12.458667 29.184 17.749333 45.397333 16.213333 16.213333 1.536 32.938667-3.754667 45.397334-16.213333l495.786666-495.786667c22.016-22.016 22.016-57.685333 0-79.701333z\"\n              fill=\"#ffffff\"\n              p-id=\"2524\"\n            />\n          </svg>已订阅\n        </div>\n      </div>\n    </div>\n    <change-nav\n      :class=\"{listFixed}\"\n      :active=\"active\"\n      :count=\"count\"\n      firstNav=\"详情\"\n      secondNav=\"节目\"\n      @changeToSecond=\"changeToSecond\"\n      @changeToFirst=\"changeToFirst\"\n    ></change-nav>\n    <div class=\"container-bottom\" :style=\"{ marginTop: top}\">\n      <div class=\"song-list\" v-show=\"active==='second'\">\n        <page-loading v-show=\"loading\"></page-loading>\n        <div v-show=\"!loading\">\n          <h1 class=\"sum-num pd23\">共{{count}}期</h1>\n          <song-list\n            class=\"pd23\"\n            v-for=\"(item, index) in djProgramData\"\n            :key=\"index\"\n            :songName=\"item.name\"\n            :num=\"djProgramData.length - index\"\n            :createTime=\"item.createTime\"\n            :listenerCount=\"item.listenerCount\"\n            :duration=\"item.duration\"\n            :twoLine=\"true\"\n            :itemId=\"item.id\"\n            @showSlider=\"showSlider\"\n            type=\"djList\"\n            @beginSong=\"setAudioList(item, index)\"\n            :nowSong=\"item.id === audioSong.id\"\n          ></song-list>\n        </div>\n      </div>\n      <div class=\"detail pd23\" v-show=\"active==='first'\">\n        <h1 class=\"anchor\">主播</h1>\n        <div class=\"content\">\n          <div class=\"img-info\">\n            <img :src=\"avatarUrl\" alt />\n          </div>\n          <div class=\"artist\">\n            <p class=\"name\">{{detailName}}</p>\n            <p class=\"dec\">网易音乐人</p>\n          </div>\n        </div>\n        <h1 class=\"dj-content\">电台内容简介</h1>\n        <div class=\"class\">\n          <span>分类</span>\n          <span class=\"tag\">{{category}}</span>\n        </div>\n        <p class=\"text\">{{desc}}</p>\n      </div>\n    </div>\n    <slider\n      ref=\"slider\"\n      :title=\"title\"\n      :author=\"name\"\n      :imgUrl=\"coverImgUrl\"\n      :id=\"itemId\"\n      :djDetailList=\"djDetail\"\n    ></slider>\n  </div>\n</template>\n\n<script>\nimport { mapActions, mapGetters } from 'vuex'\nimport djDetailNav from 'base/generalNav'\nimport changeNav from './components/changeNav'\nimport songList from 'base/song'\nimport pageLoading from 'base/pageLoading'\nimport slider from 'base/slider'\n\nimport api from 'api'\nexport default {\n  name: '',\n  data () {\n    return {\n      djProgramData: [],\n      djDetail: false,\n      coverImgUrl: '',\n      count: 0,\n      name: '',\n      subscription: 0,\n      active: 'second',\n      avatarUrl: '',\n      detailName: '',\n      category: '',\n      desc: '',\n      loading: true,\n      cover: '0.2',\n      iTitle: '电台',\n      title: '电台',\n      listFixed: false,\n      coverFixed: false,\n      position: true,\n      top: '0rem',\n      subed: false,\n      ridId: 0,\n      itemId: 0,\n      opacity: 1\n    }\n  },\n  computed: {\n    ...mapGetters({ audioSong: 'AUDIO_ING_SONG' })\n  },\n  activated () {\n    this.loading = true\n    this.coverImgUrl = ''\n    this.count = 0\n    this.name = ''\n    this.active = 'second'\n    const params = this.$route.params\n    if (!params.ridId) {\n      this.$router.go(-1)\n      return\n    }\n    this.ridId = params.ridId\n    const ridId = this.ridId\n    this._getDjProgramInfo(ridId)\n    this._getDjDetailInfo(ridId)\n  },\n  methods: {\n    _getDjProgramInfo (id) {\n      let limit = 30\n      let offset = 0\n      let asc = false\n      api.djProgramFn(id, limit, offset, asc)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            this.count = data.count\n            this.djProgramData = data.programs\n            this.loading = false\n          }\n        })\n    },\n    _getDjDetailInfo (id) {\n      api.djDetailFn(id)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            this.name = data.djRadio.name\n            this.coverImgUrl = data.djRadio.picUrl + '?param=300y300'\n            this.subscription = data.djRadio.subCount\n            this.avatarUrl = data.djRadio.dj.avatarUrl + '?param=100y100'\n            this.desc = data.djRadio.desc\n            this.detailName = data.djRadio.dj.nickname\n            this.category = data.djRadio.category\n            this.subed = data.djRadio.subed\n          }\n        })\n    },\n    addDj () {\n      api.djSubFn(this.ridId, 1)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            this.subed = true\n            console.log(data)\n          }\n        })\n    },\n    showSlider (id) {\n      this.title = '电台节目：' + this.name\n      this.djDetail = true\n      this.itemId = id\n      this.$refs.slider.showSlider()\n    },\n    deleteDj () {\n      api.djSubFn(this.ridId, 0)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            console.log(data)\n            this.subed = false\n          }\n        })\n    },\n    changeToFirst () {\n      this.active = 'first'\n    },\n    changeToSecond () {\n      this.active = 'second'\n    },\n    setAudioList (item, index) {\n      this.selectPlay({\n        list: this.djProgramData,\n        index\n      })\n    },\n    returnPage () {\n      this.$router.go(-1)\n    },\n    /**\n     * 定义页面滚动事件，\n     * 这里需要添加在滚动过程中样式的变化\n     */\n    scrollList (e) {\n      // 获取到 top 值\n      let top = this.$el.scrollTop\n      this.cover = top / 1000 + 0.3\n      this.opacity = 1 - top / 500\n      if (this.cover > 0.6) {\n        this.cover = 0.6\n        this.opacity = 0.4\n      } else {\n        this.cover = top / 1000 + 0.3\n        this.opacity = 1 - top / 500\n      }\n      if (top >= 282) {\n        this.iTitle = this.name\n        this.listFixed = true\n        this.coverFixed = true\n        this.position = false\n        this.top = '6.6rem'\n      } else {\n        this.iTitle = this.title\n        this.listFixed = false\n        this.coverFixed = false\n        this.position = true\n        this.top = '0'\n      }\n    },\n    ...mapActions(['selectPlay'])\n  },\n  components: {\n    djDetailNav,\n    changeNav,\n    songList,\n    pageLoading,\n    slider\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.topFixed {\n  position: fixed;\n  width: 100%;\n  height: 0.8rem;\n  z-index: 9;\n}\n.fixed {\n  .topFixed();\n  top: 0;\n}\n.listFixed {\n  .topFixed();\n  top: 1.6rem;\n}\n.coverFixed {\n  position: fixed;\n  width: 100%;\n  z-index: 3;\n  top: 0;\n  transform: translateY(-5.4rem);\n}\n.wrapper {\n  width: 100vw;\n  height: 100vh;\n  position: relative;\n  overflow-y: scroll;\n  overflow-x: hidden;\n  .text {\n    font-size: 0.4rem;\n    vertical-align: 5px;\n  }\n  .container-top {\n    width: 100%;\n    height: 0;\n    padding-bottom: 7rem;\n    background-size: 100%;\n    background-repeat: no-repeat;\n    &.position {\n      position: relative;\n    }\n    .cover {\n      position: absolute;\n      left: 0;\n      top: 0;\n      right: 0;\n      bottom: 0;\n      width: 100%;\n      height: 100%;\n    }\n    .data {\n      position: absolute;\n      bottom: 1rem;\n      left: 0.3rem;\n      .flex-between();\n      width: 100%;\n      box-sizing: border-box;\n      padding-right: 0.8rem;\n      .name {\n        color: #fff;\n        max-width: 4rem;\n        .twoLinesEllipsis();\n        font-size: 0.3rem;\n        line-height: 1.5;\n      }\n      .num {\n        color: #eee;\n        line-height: 1.5;\n      }\n      .subscription {\n        box-sizing: border-box;\n        position: absolute;\n        right: 0.5rem;\n        bottom: 0;\n        display: flex;\n        padding: 0 0.23rem;\n        height: 0.5rem;\n        align-items: center;\n        justify-content: center;\n        color: #fff;\n        background-color: @bgcolor;\n        border-radius: 0.4rem;\n        .icon {\n          margin-right: 0.2rem;\n        }\n      }\n      .subscription1 {\n        box-sizing: border-box;\n        position: absolute;\n        right: 0.5rem;\n        bottom: 0;\n        display: flex;\n        padding: 0 0.23rem;\n        height: 0.5rem;\n        align-items: center;\n        justify-content: center;\n        color: #fff;\n        border-radius: 0.4rem;\n        border: 1px solid #fff;\n        .icon {\n          margin-right: 0.2rem;\n        }\n      }\n    }\n  }\n  .container-bottom {\n    transform: translate3d(0, -0.8rem, 0);\n    .song-list {\n      .sum-num {\n        height: 0.5rem;\n        line-height: 0.5rem;\n        font-weight: 700;\n      }\n    }\n    .detail {\n      .anchor,\n      .dj-content {\n        font-weight: 700;\n        line-height: 1.5;\n        margin: 0.3rem 0;\n      }\n      .content {\n        display: flex;\n        align-items: center;\n        .img-info {\n          width: 1rem;\n          height: 0;\n          padding-bottom: 1rem;\n          margin-right: 0.2rem;\n          img {\n            border-radius: 50%;\n            width: 1rem;\n            height: 1rem;\n          }\n        }\n        .artist {\n          display: flex;\n          flex-direction: column;\n          line-height: 1.5;\n          .dec {\n            font-size: 0.23rem;\n            color: #999;\n          }\n        }\n      }\n      .class {\n        font-size: 0.23rem;\n        line-height: 1.5;\n        .tag {\n          color: @bgcolor;\n          box-sizing: border-box;\n          padding: 2px;\n          border-radius: 4px;\n          border: 1px solid @bgcolor;\n        }\n      }\n      .text {\n        font-size: 0.23rem;\n        color: #999;\n        margin-top: 0.13rem;\n        line-height: 1.5;\n      }\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/djSublistCard.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-01 15:14:42\n * @Update: 2019-10-04 13:38:23\n * @Update log: 长卡片组件\n -->\n<template>\n  <div class=\"dj_sublist_card\">\n    <h1 class=\"title\" v-if=\"title\">\n      {{title}}\n      <span class=\"num\">({{count}})</span>\n    </h1>\n    <!-- 要遍历的数组 -->\n    <div class=\"card\" v-for=\"(item, index) in djSublist\" :key=\"index\">\n      <div class=\"img-info\" :class=\"{circle,bigImg}\">\n        <!-- 列表项图片信息 -->\n        <img :src=\"item.picUrl ? item.picUrl : item.coverUrl\" alt />\n        <span class=\"count\" v-if=\"item.playTime\">\n          <i class=\"dj_sublist dj_sublist_bofang1\"></i>\n          {{item.playTime | numRule}}\n        </span>\n      </div>\n      <div class=\"info\" v-if=\"type === 'dj'\">\n        <!-- 列表项名字 -->\n        <p class=\"name\">{{ item.name }}</p>\n        <!-- 作者名字 -->\n        <p class=\"artist\">by {{item.dj.nickname}}</p>\n        <!-- 其他信息 -->\n        <p class=\"text\">{{item.lastProgramName}}</p>\n      </div>\n      <div class=\"info\" v-if=\"type === 'albums'\">\n        <!-- 列表项名字 -->\n        <p class=\"name\">{{ item.name }}</p>\n        <!-- 作者名字 -->\n        <div>\n          <span class=\"artist\" v-for=\"(item, index) in item.artists\" :key=\"index\">{{item.name}}</span>\n          <!-- 其他信息 -->\n          <span class=\"text\">{{item.size}}首</span>\n        </div>\n      </div>\n      <div class=\"info\" v-if=\"type === 'artists'\">\n        <!-- 列表项名字 -->\n        <p class=\"name\">{{ item.name }}</p>\n        <!-- 作者名字 -->\n        <div>\n          <span class=\"artist\">专辑：{{item.albumSize}}</span>\n          <!-- 其他信息 -->\n          <span class=\"text\">MV：{{item.mvSize}}</span>\n        </div>\n      </div>\n      <div class=\"info\" v-if=\"type === 'video'\">\n        <!-- 列表项名字 -->\n        <p class=\"name\">{{ item.title }}</p>\n        <!-- 作者名字 -->\n        <div>\n          <span class=\"artist\">{{item.durationms | setTime}} by</span>\n          <!-- 其他信息 -->\n          <span class=\"text\" v-for=\"(item, index) in item.creator\" :key=\"index\">{{item.userName}}</span>\n        </div>\n      </div>\n      <!-- 右边的三个点按钮 -->\n      <div class=\"icon\">\n        <i class=\"dj_sublist dj_sublist_diandian\"></i>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: '',\n  props: {\n    djSublist: {\n      type: Array\n    },\n    count: {\n      type: Number\n    },\n    title: {\n      type: String\n    },\n    type: {\n      type: String\n    },\n    circle: {\n      type: Boolean\n    },\n    bigImg: {\n      type: Boolean\n    }\n  },\n  filters: {\n    numRule: function (value) {\n      if (!value) return ''\n      if (value > 10000) {\n        value = parseInt(value / 10000) + '万'\n      } else if (value > 100000000) {\n        value = (value / 100000000).toFixed(1) + '亿'\n      }\n      return value\n    },\n    setTime: function (value) {\n      if (!value) return ''\n      let min = parseInt(value / (1000 * 60))\n      if (min < 10) {\n        min = '0' + min\n      }\n      let sec = parseInt(value % (1000 * 60) / 1000)\n      if (sec < 10) {\n        sec = '0' + sec\n      }\n      value = `${min}:${sec}`\n      return value\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"//at.alicdn.com/t/font_1443044_ba7y88tq60o.css\");\n@import url(\"~styles/global.less\");\n.dj_sublist_bofang1 {\n  font-size: 0.13rem;\n  color: #fff;\n}\n\n.dj_sublist_card {\n  background-color: #fff;\n  margin-top: 0.2rem;\n  .title {\n    font-weight: 700;\n  }\n  .card {\n    margin-top: 0.2rem;\n    height: 1.2rem;\n    display: flex;\n    align-items: center;\n    .img-info {\n      width: 1rem;\n      height: 0;\n      padding-bottom: 1rem;\n      overflow: hidden;\n      position: relative;\n      &.circle {\n        border-radius: 50%;\n      }\n      img {\n        width: 1rem;\n        height: 1rem;\n      }\n      &.bigImg {\n        width: 2.8rem;\n        padding-bottom: 1.4rem;\n        img {\n          width: 2.8rem;\n          height: 1.4rem;\n        }\n      }\n      .count {\n        position: absolute;\n        color: #fff;\n        right: 5px;\n        top: 5px;\n        font-size: 0.13rem;\n      }\n    }\n    .info {\n      flex: 1;\n      display: flex;\n      flex-direction: column;\n      margin-left: 0.2rem;\n      .name {\n        .twoLinesEllipsis();\n      }\n      .name,\n      .artist,\n      .text {\n        line-height: 1.5;\n      }\n      .artist,\n      .text {\n        color: #999;\n        font-size: 0.2rem;\n      }\n    }\n    .icon {\n      width: 0.4rem;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/generalNav.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-14 15:44:26\n * @Update: 2019-11-19 22:01:42\n * @Update log: 登录页通用顶部导航\n -->\n<template>\n  <nav class=\"phone-nav\" ref=\"nav\" :class=\"{height: height === 'all'}\">\n    <i class=\"phone iconzuojiantou\" @click=\"returnPage\"></i>\n    <!-- slot 插槽将不同页面的标题信息显示 -->\n    <slot></slot>\n  </nav>\n</template>\n\n<script>\nexport default {\n  name: 'loginNav',\n  props: {\n    nav: {\n      type: String,\n      default: ''\n    },\n    height: {\n      type: String,\n      default: 'all'\n    }\n  },\n  methods: {\n    visible () {\n      this.$refs.nav.style.visibility = 'visible'\n    },\n    hidden () {\n      this.$refs.nav.style.visibility = 'hidden'\n    },\n    returnPage () {\n      // 这个方法的参数是一个整数，意思是在 history 记录中向前或者后退多少步\n      // 类似 window.history.go(n)。\n      this.$emit('returnPage')\n    }\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url(\"//at.alicdn.com/t/font_1351323_oxqdjg3rufq.css\");\n\n.phone-nav {\n  display: flex;\n  align-items: center;\n  &.height {\n    height: 1rem;\n    line-height: 1rem;\n  }\n  .phone {\n    font-size: 0.7rem;\n    margin-right: 5px;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/icon.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-30 20:21:12\n * @Update: 2019-10-11 13:10:30\n * @Update log: 公共图标组件\n -->\n<template>\n  <div class=\"icon-list\" :class=\"{width}\" @click=\"linkTo\">\n    <div class=\"icon\" :class=\"{bgcolor}\">\n      <i :class=\"icons.icon\"></i>\n      <slot></slot>\n    </div>\n    <span class=\"icon-text\">{{icons.text}}</span>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: '',\n  props: {\n    icons: {\n      type: [Object, Array]\n    },\n    width: {\n      type: Boolean\n    },\n    bgcolor: {\n      type: Boolean\n    }\n  },\n  methods: {\n    linkTo () {\n      this.$emit('goPage')\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n// 这部分样式是对于 我的页面设置的\n.width {\n  min-width: 1.6rem;\n  &:last-of-type > .icon {\n    background: #ccc;\n  }\n}\n.icon-list {\n  // 每项 icon 样式\n  height: 100%;\n  display: flex;\n  justify-content: space-around;\n  flex-direction: column;\n  align-items: center;\n  color: #000;\n  .bgcolor {\n    background: linear-gradient(to right, #ff5a4c, #ff1d11);\n  }\n  .icon {\n    width: 0.8rem;\n    height: 0.8rem;\n    line-height: 0.8rem;\n    border-radius: 50%;\n    text-align: center;\n    position: relative;\n    color: #fff;\n    .home {\n      font-size: 0.4rem;\n    }\n    .find {\n      font-size: 0.5rem;\n    }\n    .dj {\n      font-size: 0.4rem;\n    }\n    .login {\n      font-size: 0.4rem;\n      background-color: transparent;\n      color: #ff1d11;\n    }\n  }\n  .icon-text {\n    font-size: 0.24rem;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/idxCard.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-09 13:31:02\n * @Update: 2019-10-08 12:45:15\n * @Update log: 排行榜中官方榜展示组件\n -->\n<template>\n  <div>\n    <div class=\"list\" @click=\"searchIdx(idx)\">\n      <div class=\"img-info\">\n        <img :src=\"imgUrl + '?param=200y200'\" alt />\n        <span class=\"time\">{{ updateTime }}</span>\n      </div>\n      <div class=\"list-con\">\n        <div class=\"info\" v-for=\"(item, index) in tracks\" :key=\"index\">\n          {{index + 1 + '.'}}\n          <span>{{item.first}}</span> -\n          <span>{{item.second}}</span>\n        </div>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: '',\n  props: {\n    imgUrl: {\n      type: String\n    },\n    tracks: {\n      type: Array\n    },\n    updateTime: {\n      type: String\n    },\n    idx: {\n      type: String\n    }\n  },\n  methods: {\n    searchIdx (idx) {\n      switch (idx) {\n        case '云音乐新歌榜':\n          idx = 0\n          break\n        case '云音乐热歌榜':\n          idx = 1\n          break\n        case '网易原创歌曲榜':\n          idx = 2\n          break\n        case '云音乐飙升榜':\n          idx = 3\n          break\n        case '云音乐说唱榜':\n          idx = 23\n          break\n        case '云音乐ACG音乐榜':\n          idx = 22\n          break\n        case 'KTV唛榜':\n          idx = 7\n          break\n        case 'iTunes榜':\n          idx = 8\n          break\n        case '日本Oricon周榜':\n          idx = 10\n          break\n        case 'Hit FM Top榜':\n          idx = 9\n          break\n        case '台湾Hito排行榜':\n          idx = 20\n          break\n        case 'Beatport全球电子舞曲榜':\n          idx = 21\n          break\n        case '法国 NRJ Vos Hits 周榜':\n          idx = 20\n          break\n        case 'UK排行榜':\n          idx = 5\n          break\n        case '美国Billboard周榜':\n          idx = 6\n          break\n      }\n      this.$emit('showIdxPage', idx)\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n\n.list {\n  height: 2rem;\n  display: flex;\n  align-items: center;\n  .img-info {\n    position: relative;\n    width: 1.7rem;\n    height: 0;\n    padding-bottom: 1.7rem;\n    border-radius: 0.13rem;\n    overflow: hidden;\n    img {\n      width: 1.7rem;\n      height: 1.7rem;\n    }\n    .time {\n      position: absolute;\n      bottom: 3px;\n      left: 3px;\n      font-size: 12px;\n      color: #fff;\n    }\n  }\n  .list-con {\n    margin-left: 0.2rem;\n    .info {\n      height: 0.5rem;\n      line-height: 0.5rem;\n      width: 4.5rem;\n      .ellipsis();\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/imgCard.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-08 14:37:08\n * @Update: 2019-11-12 21:42:40\n * @Update log: 通用的方形展示组件\n -->\n<template>\n  <div class=\"img-card\" @click=\"searchIdx(idx)\" :style=\"{width, marginTop:top}\">\n    <span class=\"tag\" v-if=\"playCount\">\n      <i class=\"card cardbofang\"></i>\n      {{playCount | setPlayCount}}\n    </span>\n    <span class=\"swiper-tag\" v-if=\"swiper\">\n      <i class=\"card cardbofang1\"></i>\n    </span>\n    <span class=\"fine-tag\" v-if=\"fine\">\n      <i class=\"card cardhuangguan\"></i>\n    </span>\n    <span class=\"time-tag\" v-if=\"updateTime\">{{ updateTime }}</span>\n    <div class=\"img-con\" :style=\"{width,paddingBottom:width}\">\n      <div class=\"shadow\"></div>\n      <!-- 增加key属性，是可以动态切换图片，解决了在none到block时不能正确显示 -->\n      <img v-lazy=\"imgUrl + '?param=200y200'\" :key=\"imgUrl\" class=\"image\" />\n      <span class=\"dj-name\" v-show=\"type === 'dj'\">{{name}}</span>\n      <!-- 跳转到专辑详情页 -->\n      <!-- <router-link class=\"cover\"  @click=\"toAlbum(albumId)\" :to=\"'/albumPage/'+albumId\"></router-link> -->\n    </div>\n    <div class=\"dec\" :class=\"{lines:lines === 'one',twoLines:lines === 'two'}\">{{ dec }}</div>\n    <div class=\"artists\" v-if=\"artists\">\n      <span v-for=\"(item, index) in artists\" :key=\"index\" class=\"artist\">{{ item.name }}</span>\n    </div>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: '',\n  props: {\n    playCount: {\n      type: Number\n    },\n    updateTime: {\n      type: String\n    },\n    imgUrl: {\n      type: String\n    },\n    dec: {\n      type: String\n    },\n    type: {\n      type: String\n    },\n    name: {\n      type: String\n    },\n    width: {\n      type: String,\n      default: '2.1rem'\n    },\n    lines: {\n      type: String,\n      default: 'two'\n    },\n    artists: {\n      type: Array\n    },\n    top: {\n      type: String,\n      default: '0.3rem'\n    },\n    // 如果是轮播图，则显示大播放按钮\n    swiper: {\n      type: Boolean,\n      default: false\n    },\n    fine: {\n      type: Boolean,\n      default: false\n    },\n    albumId: {\n      type: Number\n    },\n    dishId: {\n      type: Number\n    },\n    ridId: {\n      type: Number\n    },\n    idx: {\n      type: String\n    }\n  },\n  filters: {\n    setPlayCount: function (val) {\n      if (!val) {\n        return ''\n      }\n      if (val > 100000000) {\n        val = ((val / 100000000).toFixed(1)) + '亿'\n      } else if (val > 10000) {\n        val = Math.floor(val / 10000) + '万'\n      }\n      return val\n    }\n  },\n  methods: {\n    /**\n     * 给图片卡片注册点击事件\n     *\n     * 当没有idx时，查看是否有albumId，如果有跳转歌单页面\n     * 如果有idx时说明是排行榜页面，跳转到排行榜页面\n     */\n    searchIdx (idx) {\n      if (!idx) {\n        if (this.albumId) {\n          // [vue-router] Route with name 'albumPage' does not exist\n          // 需要给路由设置name\n          // 并且这个路由在配置的时候不能加 /:id\n          this.$router.push({ name: 'albumPage', params: { albumId: this.albumId } })\n          // this.$router.push(`/albumPage/${this.albumId}`)\n          return\n        }\n        if (this.dishId) {\n          this.$router.push({ name: 'albumPage', params: { dishId: this.dishId } })\n          return\n        }\n        if (this.ridId) {\n          console.log('go')\n\n          this.$router.push({ name: 'djDetailPage', params: { ridId: this.ridId } })\n          return\n        }\n        return\n      }\n      switch (idx) {\n        case '云音乐新歌榜':\n          idx = 0\n          break\n        case '云音乐热歌榜':\n          idx = 1\n          break\n        case '网易原创歌曲榜':\n          idx = 2\n          break\n        case '云音乐飙升榜':\n          idx = 3\n          break\n        case '云音乐说唱榜':\n          idx = 23\n          break\n        case '云音乐ACG音乐榜':\n          idx = 22\n          break\n        case 'KTV唛榜':\n          idx = 7\n          break\n        case 'iTunes榜':\n          idx = 8\n          break\n        case '日本Oricon周榜':\n          idx = 10\n          break\n        case 'Hit FM Top榜':\n          idx = 9\n          break\n        case '台湾Hito排行榜':\n          idx = 20\n          break\n        case 'Beatport全球电子舞曲榜':\n          idx = 21\n          break\n        case '法国 NRJ Vos Hits 周榜':\n          idx = 20\n          break\n        case '云音乐国电榜':\n          idx = 4\n          break\n        case 'UK排行榜周榜':\n          idx = 5\n          break\n        case '美国Billboard周榜':\n          idx = 6\n          break\n        case '云音乐古典音乐榜':\n          idx = 24\n          break\n        case '云音乐电音榜':\n          idx = 25\n          break\n        case '抖音排行榜':\n          idx = 26\n          break\n        case '新声榜':\n          idx = 27\n          break\n        case '云音乐韩语榜':\n          idx = 28\n          break\n        case '英国Q杂志中文版周榜':\n          idx = 29\n          break\n        case '电竞音乐榜':\n          idx = 30\n          break\n        case '云音乐欧美热歌榜':\n          idx = 31\n          break\n        case '云音乐欧美新歌榜':\n          idx = 32\n          break\n        case '说唱TOP榜':\n          idx = 33\n          break\n      }\n      this.$emit('showIdxPage', idx)\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"//at.alicdn.com/t/font_1396631_tp8pq8axas.css\");\n@import url(\"~styles/global.less\");\n.img-card {\n  position: relative;\n  background-color: #fff;\n  .time-tag {\n    position: absolute;\n    bottom: 0.54rem;\n    left: 3px;\n    font-size: 12px;\n    color: #fff;\n  }\n  .tag {\n    position: absolute;\n    z-index: 1;\n    top: 0.11rem;\n    right: 0.11rem;\n    font-size: 0.2rem;\n    color: #fff;\n    .cardbofang {\n      font-size: 0.18rem;\n    }\n  }\n  .swiper-tag {\n    position: absolute;\n    bottom: 1rem;\n    right: 0.11rem;\n    .cardbofang1 {\n      font-size: 1rem;\n      color: #fff;\n      opacity: 0.6;\n    }\n  }\n  .fine-tag {\n    position: absolute;\n    transform: rotate(-45deg);\n    top: 0;\n    left: 0;\n    .cardhuangguan {\n      color: #f39c12;\n      font-size: 0.5rem;\n    }\n  }\n  .img-con {\n    position: relative;\n    height: 0;\n    background-color: #aaa;\n    border-radius: 0.2rem;\n    overflow: hidden;\n    .shadow {\n      position: absolute;\n      height: 2.1rem;\n      width: 100%;\n      box-shadow: 0 15px 21px -9px #777 inset;\n    }\n    .dj-name {\n      position: absolute;\n      bottom: 8px;\n      left: 8px;\n      color: #fff;\n      font-size: 0.2rem;\n      width: 100%;\n      .ellipsis();\n    }\n    img {\n      width: 100%;\n    }\n  }\n  .dec {\n    margin-top: 0.2rem;\n    font-size: 0.23rem;\n    line-height: 0.3rem;\n    letter-spacing: 1px;\n    &.lines {\n      .ellipsis();\n      height: 0.3rem;\n    }\n    &.twoLines {\n      height: 0.6rem;\n      .twoLinesEllipsis();\n    }\n  }\n  .artists {\n    .ellipsis();\n    .artist {\n      font-size: 0.2rem;\n      color: #aaa;\n      &::after {\n        content: \"/\";\n      }\n      &:last-child::after {\n        content: \"\";\n      }\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/interchangeable.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-02 13:36:42\n * @Update: 2019-11-16 13:54:29\n * @Update log: 这是一个公共的组件，用来展示搜索展示页面除单曲以外的项目\n * 通过props接收对应的结果，渲染。\n * 组件调用是通过 for 循环组件，来循环组件渲染的\n -->\n<template>\n  <div class=\"list-item\">\n    <!-- 左边的图片展示区域，用不同的类名展示不同的效果 -->\n    <!-- 在歌单 视频 用户 等三种的图片展示样式不同 -->\n    <div\n      class=\"img-info\"\n      :class=\"{ bigImg: videoList,\n                smallImg: songList,\n                circle,\n                album,\n                dj\n                }\"\n    >\n      <!-- 视频的播放量 -->\n      <span class=\"count\" v-if=\"playTime\">\n        <i class=\"result bofang1\"></i>\n        {{playTime | numRule}}\n      </span>\n      <!-- 图片链接 -->\n      <img :src=\"ImgUrl + `?param=${videoList ? 200 : 100}y${videoList ? 120 : 100}`\" alt />\n    </div>\n    <!-- 右侧的相关文字信息 -->\n    <div class=\"info-content\">\n      <!-- 标题文字 -->\n      <div\n        class=\"play-name\"\n        :style=\"{maxWidth}\"\n        :class=\"{oneLine: line === 'one', twoLines: line === 'two'}\"\n      >\n        <span v-if=\"isMv\" class=\"mv\">MV</span>\n        <span v-html=\"name\"></span>\n        <span class=\"alia\" v-show=\"alia\">({{alia}})</span>\n        <!-- 在用户区域用类名显示不同的用户性别图标 -->\n        <i\n          class=\"result\"\n          :class=\"{\n                  nan: gender === 1,\n                  nv: gender === 2\n                  }\"\n          v-if=\"gender\"\n        ></i>\n      </div>\n      <!-- 右侧信息说明文字 由于各项的展示方式不同，所以分开编写 -->\n      <div class=\"play-tag\">\n        <!-- 作者 -->\n        <p class=\"user\">{{nickname}}</p>\n        <!-- 电台展示 -->\n        <p class=\"dj\" v-if=\"dj\">\n          <span class=\"dj-art\">{{nicknames.nickname}}</span>\n        </p>\n        <!-- 专辑展示 -->\n        <p class=\"album\" v-if=\"artists\">\n          <span>\n            <span class=\"album-art\" v-for=\"(item, index) in artists\" :key=\"index\">{{item.name}}</span>\n          </span>\n          <span class=\"time\">{{durationms | setYear}}</span>\n        </p>\n        <!-- 视频展示 -->\n        <p class=\"video-show\" v-if=\"videoList\">\n          <span class=\"time\">\n            {{durationms | setTime}}\n            <span>\n              by\n              <span\n                class=\"video-art\"\n                v-for=\"(item, index) in nicknames\"\n                :key=\"index\"\n              >{{item.userName}}</span>\n            </span>\n          </span>\n        </p>\n        <!-- 歌单列表展示 -->\n        <p class=\"song-list\" v-if=\"songList\">\n          <span class=\"song-num\">{{trackCount}}首</span>\n          <span class=\"song-art\">by {{nickname}},</span>\n          <span class=\"play-count\">播放{{playCount | numRule}}次</span>\n        </p>\n      </div>\n    </div>\n    <!-- 展示歌手是否已入驻 -->\n    <span class=\"artist-is-in\" v-if=\"isIn\">\n      <i class=\"result yonghufangkeshu\"></i> 已入驻\n    </span>\n  </div>\n</template>\n\n<script>\nimport { filterSetPlayCount, filterSetTime, filterSetYear } from 'utils/filters'\nexport default {\n  name: '',\n  props: {\n    videoList: {\n      type: Boolean,\n      default: false\n    },\n    isMv: {\n      type: Boolean,\n      default: false\n    },\n    gender: {\n      type: Number,\n      default: 0\n    },\n    artists: {\n      type: Array\n    },\n    line: {\n      type: String\n    },\n    maxWidth: {\n      type: String\n    },\n    dj: {\n      type: Boolean,\n      default: false\n    },\n    album: {\n      type: Boolean,\n      default: false\n    },\n    isIn: {\n      type: Number\n    },\n    circle: {\n      type: Boolean,\n      default: false\n    },\n    playTime: {\n      type: Number\n    },\n    durationms: {\n      type: Number\n    },\n    nicknames: {\n      type: [Array, Object]\n    },\n    songList: {\n      type: Boolean,\n      default: false\n    },\n    name: {\n      type: String\n    },\n    alia: {\n      type: String\n    },\n    trackCount: {\n      type: Number\n    },\n    nickname: {\n      type: String\n    },\n    playCount: {\n      type: Number\n    },\n    title: {\n      type: String\n    },\n    ImgUrl: {\n      type: String\n    },\n    more: {\n      type: Boolean\n    },\n    moreText: {\n      type: String\n    }\n  },\n  filters: {\n    /**\n     * 将播放次数进行格式转换\n     */\n    numRule: function (value) {\n      return filterSetPlayCount(value)\n    },\n    /**\n     * 将毫秒数转换为正常的时间\n     *  212245 ==> 03:32\n    */\n    setTime: function (value) {\n      return filterSetTime(value)\n    },\n    /**\n     * 将毫秒转换为 年月日\n     */\n    setYear: function (value) {\n      return filterSetYear(value)\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.list-item {\n  margin-top: 0.26rem;\n  width: 100%;\n  height: 1.6rem;\n  position: relative;\n  display: flex;\n  align-items: center;\n  overflow: hidden;\n  .img-info {\n    position: relative;\n    box-sizing: border-box;\n    height: 0;\n    background-color: #ccc;\n    border-radius: 0.1rem;\n    img {\n      overflow: hidden;\n      border-radius: 0.1rem;\n    }\n    &.bigImg {\n      width: 2.8rem;\n      padding-bottom: 1.4rem;\n      img {\n        width: 2.8rem;\n        height: 1.4rem;\n      }\n    }\n    &.smallImg {\n      width: 1.6rem;\n      padding-bottom: 1.6rem;\n      img {\n        width: 100%;\n      }\n    }\n    &.circle {\n      width: 1.3rem;\n      height: 1.3rem;\n      border-radius: 50%;\n      overflow: hidden;\n      img {\n        width: 100%;\n      }\n    }\n    &.album {\n      width: 1.6rem;\n      padding-bottom: 1.6rem;\n      img {\n        width: 100%;\n      }\n    }\n    &.dj {\n      width: 1.6rem;\n      padding-bottom: 1.6rem;\n      img {\n        width: 100%;\n      }\n    }\n    .count {\n      position: absolute;\n      color: #fff;\n      right: 5px;\n      top: 5px;\n      font-size: 0.13rem;\n      .bofang1 {\n        font-size: 0.13rem;\n      }\n    }\n  }\n  .info-content {\n    margin-left: 0.23rem;\n    .play-name {\n      line-height: 0.4rem;\n      .mv {\n        box-sizing: border-box;\n        padding: 0.01rem 0.05rem;\n        border: 1px solid @bgcolor;\n        font-size: 0.2rem;\n        font-weight: 700;\n        color: @bgcolor;\n      }\n      .alia {\n        color: #7c7b7d;\n      }\n      &.oneLine {\n        max-width: 3.8rem;\n        .ellipsis();\n      }\n      &.twoLines {\n        .twoLinesEllipsis();\n      }\n      .nan {\n        color: #00cec9;\n      }\n      .nv {\n        color: #fd79a8;\n      }\n    }\n    .play-tag {\n      max-width: 5rem;\n      height: 0.5rem;\n      line-height: 0.5rem;\n      font-size: 0.2rem;\n      color: #666;\n      .user {\n        .ellipsis();\n      }\n      .album-art {\n        &::after {\n          content: \"/\";\n        }\n        &:last-child::after {\n          content: \"\";\n        }\n      }\n      .time {\n        margin-left: 0.13rem;\n      }\n      .song-num {\n        margin-right: 0.13rem;\n      }\n      .song-art {\n        margin-right: 0.13rem;\n      }\n    }\n  }\n  .artist-is-in {\n    margin-left: auto;\n    .yonghufangkeshu {\n      color: @bgcolor;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/loading.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-17 17:10:07\n * @Update: 2019-08-17 18:46:40\n * @Update log: 页面加载样式\n -->\n<template>\n  <div>\n    <transition>\n      <div class=\"loading\" v-show=\"isLoading\">\n        <p></p>\n      </div>\n    </transition>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: 'alert',\n  props: {\n    isLoading: {\n      type: Boolean\n    }\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@keyframes rotate {\n  from {\n    transform: rotate(0deg);\n  }\n\n  to {\n    transform: rotate(360deg);\n  }\n}\n.loading {\n  position: fixed;\n  bottom: 5rem;\n  left: 50%;\n  transform: translateX(-50%);\n  padding: 0.13rem;\n  font-size: smaller;\n  border-radius: 8px;\n  p {\n    width: 50px;\n    height: 50px;\n    border: 3px solid #ccc;\n    border-top-color: #666;\n    border-radius: 50%;\n    margin: 0 auto;\n    animation: rotate 1s linear infinite;\n  }\n}\n.v-enter-active,\n.v-leave-active {\n  transition: opacity 0.5s;\n}\n.v-enter,\n.v-leave-to {\n  opacity: 0;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/loginPageIsShow.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-11 07:56:48\n * @Update: 2019-10-11 08:10:27\n * @Update log: 更新日志\n -->\n<template>\n  <div>\n    <transition name=\"mask-show\">\n      <div class=\"mask\" v-show=\"loginPage\" @click=\"HIDE_LOGIN\" @touchmove.prevent></div>\n    </transition>\n    <transition name=\"login-show\" mode=\"out-in\">\n      <login v-show=\"loginPage\" @touchmove.prevent></login>\n    </transition>\n  </div>\n</template>\n\n<script>\nimport login from '../pages/nav/components/login'\nimport { mapGetters, mapMutations } from 'vuex'\n\nexport default {\n  name: '',\n  components: {\n    login\n  },\n  computed: {\n    ...mapGetters({ loginPage: 'LOGIN_PAGE' })\n  },\n  methods: {\n    ...mapMutations(['HIDE_LOGIN'])\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n\n// 遮罩层动画\n.mask-show-enter,\n.mask-show-leave-to {\n  opacity: 0;\n}\n\n.mask-show-enter-active,\n.mask-show-leave-active {\n  transition: opacity linear 0.3s;\n}\n// 左侧侧边栏显示隐藏动画\n.login-show-enter,\n.login-show-leave-to {\n  transform: translateX(-6rem);\n}\n\n.login-show-enter-active,\n.login-show-leave-active {\n  transition: transform linear 0.3s;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/pageErrorInfo.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-05 09:21:33\n * @Update: 2019-10-03 20:01:31\n * @Update log: 搜索展示页如果没有搜索结果展示的信息页面\n -->\n<template>\n  <div v-if=\"info\" class=\"info\">未找到与\"{{keywords}}\"相关的内容</div>\n</template>\n\n<script>\nexport default {\n  name: '',\n  props: {\n    info: {\n      type: Boolean,\n      default: false\n    },\n    keywords: {\n      type: String\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n.info {\n  text-align: center;\n  line-height: 1rem;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/pageLoading.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-31 10:19:23\n * @Update: 2019-10-24 08:50:52\n * @Update log: 展示页面加载动画\n -->\n<template>\n  <div class=\"container\">\n    <div class=\"page-loading\">\n      <span class=\"span\"></span>\n      <span class=\"span\"></span>\n      <span class=\"span\"></span>\n      <span class=\"span\"></span>\n    </div>努力加载中...\n  </div>\n</template>\n\n<script>\nexport default {\n  name: 'pageLoading'\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.container {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  height: 1rem;\n  line-height: 1rem;\n  z-index: 999;\n}\n.page-loading {\n  display: flex;\n  flex-flow: row nowrap;\n  align-items: center;\n  justify-content: space-between;\n  width: 0.5rem;\n  margin-right: 0.2rem;\n  .span {\n    width: 0.05rem;\n    height: 0.2rem;\n    background-color: @bgcolor;\n  }\n\n  .span:nth-of-type(1) {\n    animation: grow 1s -0.45s ease-in-out infinite;\n  }\n\n  .span:nth-of-type(2) {\n    animation: grow 1s -0.3s ease-in-out infinite;\n  }\n\n  .span:nth-of-type(3) {\n    animation: grow 1s -0.15s ease-in-out infinite;\n  }\n\n  .span:nth-of-type(4) {\n    animation: grow 1s ease-in-out infinite;\n  }\n\n  @keyframes grow {\n    0%,\n    100% {\n      transform: scaleY(1);\n    }\n\n    50% {\n      transform: scaleY(2);\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/searchInput.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-27 12:42:24\n * @Update: 2019-11-14 13:38:05\n * @Update log: 搜索框\n -->\n<template>\n  <div class=\"wrapper pd23\">\n    <!-- 左边的返回箭头 -->\n    <i class=\"iconfont zuojiantou\" @click=\"returnPage\"></i>\n    <!-- input 框，设置使得 input 页面加载input自动聚焦 -->\n    <!-- 聚焦后显示搜索建议 -->\n    <input\n      class=\"search\"\n      type=\"text\"\n      :placeholder=\"placeholder\"\n      ref=\"inp\"\n      autofocus=\"autofocus\"\n      v-model.trim=\"keywords\"\n      @focus=\"displayList\"\n    />\n    <!-- 通过观测输入框中是否有内容用来控制右侧的叉按钮是否显示 -->\n    <!-- 为叉按钮定义点击事件，点击清空输入框 -->\n    <i v-show=\"keywords\" @click=\"clearInp\" class=\"iconfont guanbi\" :style=\"{right: Right}\"></i>\n    <i class=\"iconfont geshou\" v-if=\"page\" @click=\"goSingerPage\"></i>\n    <!-- 搜索建议列表信息 -->\n    <div class=\"floatInfo\" v-show=\"showList\">\n      <ul>\n        <li @click=\"searchKey(keywords)\" class=\"blue border-bottom\">\n          搜索\n          <span class=\"text\">\"{{ keywords }}\"</span>\n        </li>\n        <li\n          @click=\"searchKey(item.keyword)\"\n          class=\"border-bottom\"\n          v-for=\"(item, index) in searchList\"\n          :key=\"index\"\n        >\n          <i class=\"iconfont sousuo\"></i>\n          {{ item.keyword }}\n        </li>\n      </ul>\n    </div>\n    <!-- 蒙层，当搜索建议显示，蒙层显示，控制列表不能滚动 -->\n    <div class=\"mask\" v-show=\"showList\" @click=\"hideList\"></div>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport Bus from '../assets/Bus'\nexport default {\n  name: 'searchInp',\n  props: {\n    page: {\n      type: String\n    },\n    Right: {\n      default: '0.23rem'\n    },\n    keyword: {\n      type: String,\n      default: ''\n    }\n  },\n  data () {\n    return {\n      searchList: [],\n      keywords: '',\n      showList: false,\n      // 将 history 存入 vuex\n      history: [],\n      // 防抖定时器\n      time: null,\n      placeholder: ''\n    }\n  },\n  created () {\n    // 获取焦点\n    this.changFocus()\n    // 先将默认搜索建议显示\n    this._getPlaceholder()\n    // 历史记录项点击搜索\n    this.historySearch()\n    // 页面首次加载，由于 keyword 没有被watch监听，所以使用函数方法进行赋值\n    this.setKeyword()\n  },\n  mounted () {\n    // 获取历史搜索记录\n    this.getHistory()\n  },\n  watch: {\n    /**\n     * 是否显示搜索建议\n     */\n    keywords: function (val, oldVal) {\n      // 这是对于输入框内容定义的事件，当是跳转过来的\n      // 说明内容相等，不显示搜索建议列表\n      if (this.keywords === this.keyword) {\n        this.hideList()\n        return\n      }\n      // 在内容变化时，并且当内容长度大于0 说明有内容时\n      if (this.keywords.length > 0) {\n        // 显示建议列表\n        this.displayList()\n      } else {\n        // 隐藏建议列表\n        this.hideList()\n      }\n    },\n    // 对于prop传过来的值，在第一次使用方法进行修改，随后监听keyword变化，对搜索内容进行修改\n    keyword: function (val, oldVal) {\n      if (val) {\n        this.keywords = val\n      }\n    }\n  },\n  methods: {\n    /**\n     * 第一次访问需要调用方法更改数据\n     * 随后是监听 keyword 改变后赋值\n     */\n    setKeyword () {\n      if (this.keyword) {\n        this.keywords = this.keyword\n      }\n    },\n    /**\n     * 点击歌手分类图标，跳转到歌手分类页面\n     */\n    goSingerPage () {\n      this.$router.push('/singer')\n    },\n    /**\n     * 历史记录项目点击搜索\n     */\n    historySearch () {\n      Bus.$on('search', (keywords) => {\n        this.searchKey(keywords)\n      })\n    },\n    /**\n     * 点击清除按钮清除搜索框的内容\n     */\n    clearInp () {\n      this.keywords = ''\n    },\n    /**\n     * 自动获取焦点\n     * 当是搜索展示页时不自动获取焦点\n     */\n    changFocus () {\n      if (!this.keyword) {\n        this.$nextTick(x => {\n          this.$refs.inp.focus()\n        })\n      }\n    },\n    /**\n     * 返回上一页\n     */\n    returnPage () {\n      this.$router.go(-1)\n    },\n    /**\n     * 设置输入框的默认显示\n     */\n    _getPlaceholder () {\n      api.defaultSearchFn()\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.placeholder = data.data.showKeyword\n          }\n        })\n    },\n    /**\n     * 隐藏搜索建议列表\n     */\n    hideList () {\n      this.showList = false\n    },\n    /**\n     * 显示搜索列表建议\n     */\n    displayList () {\n      if (!this.keywords) {\n        return\n      }\n      this.showList = true\n      // 搜索建议列表内容获取\n      this.setSearchList(this.keywords)\n    },\n    /**\n     * 请求搜索建议数据\n     */\n    _getSuggestList (keyword) {\n      api.suggestSearchFn(keyword)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.searchList = data.result.allMatch\n          }\n        })\n    },\n    /**\n     * 根据搜索内容展示搜索建议列表\n     * 使用防抖\n     */\n    setSearchList (keywords) {\n      if (this.time) {\n        clearTimeout(this.time)\n        this.time = null\n      }\n      this.time = setTimeout(() => {\n        this._getSuggestList(keywords)\n      }, 50)\n    },\n    /**\n     * 获取历史搜索记录\n     */\n    getHistory (key) {\n      let keys = localStorage.getItem('keys') ? localStorage.getItem('keys').split(',') : []\n      if (key) {\n        // 将关键字插入到数组最前面\n        keys.unshift(key)\n        // 存入本地之前进行去重\n        keys = this.unique(keys)\n        // 存入本地\n        localStorage.setItem('keys', keys)\n      }\n      this.history = keys\n      // 通过Bus 进行兄弟组件之间传值\n      // 通过 Bus.$emit('方法名',要传的值)\n      Bus.$emit('history', this.history)\n    },\n    /**\n     * 向导航标签传递key值\n     */\n    pushKey (key) {\n      this.$nextTick(() => {\n        // DOM 现在更新了\n        Bus.$emit('push', key)\n      })\n    },\n    /**\n     * 搜索\n     * 搜索功能跳转到搜索展示页面\n     */\n    searchKey (key) {\n      this.getHistory(key)\n      this.hideList()\n      this.clearInp()\n      // 这里解决了Bus传值第一次无法获取到的问题\n      // 后需解决！！！！\n      setTimeout(() => {\n        this.pushKey(key)\n      }, 0)\n      this.$router.push({\n        path: `/composite/${key}`\n      })\n    },\n    /**\n     * 数组去重\n     */\n    unique (arr) {\n      if (!Array.isArray(arr)) {\n        console.log('type error!')\n        return\n      }\n      return Array.prototype.filter.call(arr, function (item, index) {\n        return arr.indexOf(item) === index\n      })\n    },\n    beforeDestroy () {\n      // 销毁监听事件\n      this.$Bus.$off('push', 'history')\n    }\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url(\"~styles/global.less\");\n@import url(\"//at.alicdn.com/t/font_1379594_vh7eh105cbo.css\");\n.wrapper {\n  .flex-between();\n  height: 0.7rem;\n  line-height: 0.7rem;\n  .guanbi {\n    position: absolute;\n    right: 0.23rem;\n  }\n  .geshou {\n    margin-left: 0.3rem;\n  }\n  .iconfont {\n    font-size: 0.5rem;\n  }\n  .search {\n    flex: 1;\n    margin-left: 0.3rem;\n    border-bottom: 1px solid #aaa;\n  }\n  .floatInfo {\n    width: 5.7rem;\n    position: absolute;\n    top: 0.8rem;\n    box-shadow: 0 4px 16px #aaa;\n    background-color: #fff;\n    z-index: 2;\n    .pd23();\n    li {\n      height: 0.8rem;\n      line-height: 0.8rem;\n      color: #888;\n      .text {\n        margin-left: 8px;\n      }\n      .iconfont {\n        font-size: 0.4rem;\n        vertical-align: -0.04rem;\n      }\n    }\n    .blue {\n      color: #38f;\n    }\n  }\n  .mask {\n    position: fixed;\n    top: 0.7rem;\n    left: 0;\n    bottom: 0;\n    right: 0;\n    z-index: 1;\n    opacity: 0;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/shouldLogin.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-11 07:51:34\n * @Update: 2019-10-11 08:12:58\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"center\">\n    <p class=\"m3\">当前未登录，请您跳转登陆页面进行登陆</p>\n    <router-link to=\"/login\">点我去登陆</router-link>\n  </div>\n</template>\n\n<script>\nimport { mapMutations } from 'vuex'\n\nexport default {\n  name: '',\n  methods: {\n    ...mapMutations(['SHOW_LOGIN'])\n  }\n}\n</script>\n\n<style lang='less' scoped>\n.center {\n  text-align: center;\n  .m3 {\n    margin: 0.3rem 0;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/slider.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-27 12:49:09\n * @Update: 2019-11-29 13:18:49\n * @Update log: 更新日志\n -->\n<template>\n  <div>\n    <van-action-sheet v-model=\"drawer\" class=\"van-ellipsis\" :title=\"title\">\n      <div>\n        <p v-for=\"(item, index) in data\" :key=\"index\" class=\"item pd23 border-bottom\">\n          <a class=\"cover\" @click=\"itemHandle(item.text, id)\"></a>\n          <i class=\"slider\" :class=\"item.icon\"></i>\n          {{item.text}}\n        </p>\n      </div>\n    </van-action-sheet>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport { Dialog, Toast } from 'vant'\nexport default {\n  data () {\n    return {\n      drawer: false,\n      direction: 'btt',\n      show: false,\n      homePlaylist: [{\n        icon: 'sliderxiazai',\n        text: '下载'\n      }, {\n        icon: 'sliderfenxiang',\n        text: '分享'\n      }, {\n        icon: 'sliderbianji',\n        text: '编辑歌单信息'\n      }, {\n        icon: 'slidericonfont-shanchu',\n        text: '删除'\n      }],\n      homeFavoritelist: [{\n        icon: 'sliderxiazai',\n        text: '下载'\n      }, {\n        icon: 'sliderfenxiang',\n        text: '分享'\n      }, {\n        icon: 'slidericonfont-shanchu',\n        text: '删除'\n      }],\n      djDetail: [{\n        icon: 'sliderxiazai',\n        text: '下载'\n      }, {\n        icon: 'sliderpinglun',\n        text: '评论'\n      }, {\n        icon: 'sliderfenxiang',\n        text: '分享'\n      }, {\n        icon: 'sliderjubao',\n        text: '举报'\n      }]\n    }\n  },\n  props: {\n    title: {\n      type: String\n    },\n    author: {\n      type: String\n    },\n    imgUrl: {\n      type: String\n    },\n    id: {\n      type: Number\n    },\n    homePlaylistSlider: {\n      type: Boolean,\n      default: false\n    },\n    homeFavoritelistSlider: {\n      type: Boolean,\n      default: false\n    },\n    djDetailList: {\n      type: Boolean,\n      default: false\n    }\n  },\n  computed: {\n    data: function () {\n      return this.homePlaylistSlider ? this.homePlaylist : this.homeFavoritelistSlider ? this.homeFavoritelist : this.djDetailList ? this.djDetail : []\n    },\n    size: function () {\n      return this.data.length * 10 + '%'\n    }\n  },\n  methods: {\n    /**\n     * 删除此项\n     */\n    deleteItem (id) {\n      this.drawer = false\n      this.$dialog.confirm({\n        message: '确认删除此歌单吗？'\n      }).then(_ => {\n        if (this.homeFavoritelistSlider) {\n          // 取消收藏此歌单\n          this._cancelPlayList(id)\n        } else {\n          // 删除创建的歌单\n          this._deleteCreatedList(id)\n        }\n      })\n        .catch(_ => {\n          this.drawer = false\n        })\n    },\n    /**\n     * 取消收藏\n     */\n    _cancelPlayList (id) {\n      api.addOrDeletePlaylistFn(2, id)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            Toast({\n              position: 'bottom',\n              message: '已删除'\n            })\n          }\n        })\n        .catch(err => {\n          console.log(err)\n        })\n    },\n    /**\n     * 删除歌单\n     */\n    _deleteCreatedList (id) {\n      api.deletePlaylistFn(id)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            Toast({\n              position: 'bottom',\n              message: '已删除'\n            })\n          }\n        })\n        .catch(err => {\n          console.log(err)\n        })\n    },\n    commentsItem (id) {\n      const djId = id\n      const title = this.title\n      const author = this.author\n      const imgUrl = this.imgUrl\n      this.$router.push({ name: 'comments', params: { djId, imgUrl, title, author } })\n    },\n    showSlider () {\n      console.log('kkk')\n      this.drawer = true\n    },\n    itemHandle (name, id) {\n      switch (name) {\n        case '删除':\n          this.deleteItem(id)\n          break\n        case '评论':\n          this.commentsItem(id)\n          break\n        default:\n          break\n      }\n    }\n  },\n  components: {\n    [Dialog.Component.name]: Dialog.Component\n  }\n}\n</script>\n\n<style lang=\"less\">\n@import url(\"~styles/global\");\n@import url(\"//at.alicdn.com/t/font_1439316_22v2kqpozkoh.css\");\n.item {\n  height: 0.9rem;\n  line-height: 0.9rem;\n  .slider {\n    margin-right: 0.2rem;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/sliderNav.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-01 14:30:50\n * @Update: 2019-10-29 13:07:19\n * @Update log: 可左右滑动的标签导航\n -->\n<template>\n  <div class=\"wrapper pd23\" ref=\"navs\">\n    <!-- 使用 replace 它不会向 history 添加新记录 -->\n    <router-link\n      class=\"nav-list\"\n      :style=\"{minWidth}\"\n      v-for=\"(item, index) in list\"\n      :key=\"index\"\n      :to=\"item.path\"\n      replace\n    >{{ item.text }}{{item.num | empty}}</router-link>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: '',\n  props: {\n    list: {\n      type: Array\n    },\n    minWidth: {\n      type: String,\n      default: '1.2rem'\n    }\n  },\n  filters: {\n    empty: function (val) {\n      if (val) {\n        return ' ' + val\n      } else {\n        return ''\n      }\n    }\n  },\n  methods: {\n    /**\n     * 该方法用来滚动跳转到对应的标签项，\n     * 传入要跳转标签项的index值和每个标签项的宽度来使得标签行滚动\n     */\n    handleScroll (index, num) {\n      this.$refs.navs.scrollLeft = index * num\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.wrapper {\n  display: flex;\n  margin-top: 0.16rem;\n  overflow-x: auto;\n  flex-wrap: nowrap;\n  border-bottom: 1px solid #ddd;\n  .nav-list {\n    position: relative;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    height: 0.7rem;\n    box-sizing: border-box;\n    padding: 0.03rem;\n    margin: 0 0.2rem;\n    color: #000;\n    &::before {\n      content: \"\";\n      position: absolute;\n      bottom: 0;\n      left: 0;\n      right: 0;\n      height: 2px;\n      background-color: @bgcolor;\n      transform-origin: bottom right;\n      transform: scaleX(0);\n      transition: transform 0.5s ease;\n    }\n    &.ac {\n      color: @bgcolor;\n    }\n    &.ac::before {\n      transform-origin: bottom left;\n      transform: scaleX(1);\n    }\n  }\n}\n::-webkit-scrollbar {\n  display: none;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/song.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-07 12:09:22\n * @Update: 2019-11-08 13:45:23\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"list-item\" @click=\"startSong\">\n    <div class=\"img-info\" v-if=\"imgUrl\">\n      <img v-lazy=\"imgUrl + '?param=50y50'\" :key=\"imgUrl\" v-show=\"!nowSong\" />\n      <i class=\"result yinliang\" v-show=\"nowSong\"></i>\n    </div>\n    <div class=\"index\" v-if=\"num\">\n      <span v-show=\"!nowSong\">{{ num }}</span>\n      <i class=\"result yinliang\" v-show=\"nowSong\"></i>\n    </div>\n    <div class=\"song-info\">\n      <p class=\"song-name\" :class=\"{twoLine}\">\n        <!-- {{songName | setKeyWords}} -->\n        <!-- 注意 如果使用 v-html 显示内容可能会把子节点内容覆盖 -->\n        <span v-html=\"songName\"></span>\n        <span class=\"alia\" v-show=\"alia\">({{alia}})</span>\n      </p>\n      <p class=\"song-art\" v-if=\"type==='songList'\">\n        <span>\n          <span class=\"artist\" v-for=\"(item, index) in artists\" :key=\"index\">{{ item.name }}</span>\n        </span>\n        <span class=\"album-name\">{{ albumName }}</span>\n      </p>\n      <p class=\"dj-info\" v-if=\"type==='djList'\">\n        <span class=\"data\">{{createTime | setMonth}}</span>\n        <span class=\"count\">\n          <i class=\"result bofang1\"></i>\n          {{listenerCount | setNum}}\n        </span>\n        <span class=\"time\">\n          <i class=\"result shijian\"></i>\n          {{duration | setTime}}\n        </span>\n      </p>\n    </div>\n    <div class=\"icon\" @click.stop=\"showSlider(itemId)\">\n      <i class=\"result diandiandian\"></i>\n    </div>\n  </div>\n</template>\n\n<script>\nimport { filterSetMonth, filterSetPlayCount, filterSetTime } from 'utils/filters'\n\nexport default {\n  name: '',\n  props: {\n    songName: {\n      type: String\n    },\n    artists: {\n      type: Array\n    },\n    albumName: {\n      type: String\n    },\n    alia: {\n      type: String\n    },\n    imgUrl: {\n      type: String\n    },\n    num: {\n      type: Number\n    },\n    type: {\n      type: String,\n      default: 'songList'\n    },\n    itemId: {\n      type: Number\n    },\n    createTime: {\n      type: Number\n    },\n    listenerCount: {\n      type: Number\n    },\n    duration: {\n      type: Number\n    },\n    nowSong: {\n      type: Boolean,\n      default: false\n    },\n    twoLine: {\n      type: Boolean\n    },\n    keywords: {\n      type: String\n    }\n  },\n  filters: {\n    setMonth: function (value) {\n      return filterSetMonth(value)\n    },\n    setNum: function (value) {\n      return filterSetPlayCount(value)\n    },\n    setTime: function (value) {\n      return filterSetTime(value)\n    }\n  },\n  methods: {\n    startSong () {\n      this.$emit('beginSong')\n    },\n    showSlider (id) {\n      this.$emit('showSlider', id)\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n@import url(\"//at.alicdn.com/t/font_1380711_cftenqb5flc.css\");\n\n.list-item {\n  .flex-between();\n  align-items: center;\n  height: 1.2rem;\n  .index {\n    color: #999;\n  }\n  .yinliang {\n    color: @bgcolor;\n  }\n  .img-info {\n    width: 0.7rem;\n    height: 0;\n    padding-bottom: 0.7rem;\n    margin-right: 0.2rem;\n    position: relative;\n    img {\n      border-radius: 0.1rem;\n      width: 0.7rem;\n      height: 0.7rem;\n    }\n    .yinliang {\n      position: absolute;\n      left: 50%;\n      top: 50%;\n      transform: translate3d(-50%, -50%, 0);\n    }\n  }\n  .song-info {\n    display: flex;\n    flex-direction: column;\n    .song-name {\n      width: 75vw;\n      max-height: 0.4rem;\n      line-height: 0.4rem;\n      .ellipsis();\n      .alia {\n        color: #7c7b7d;\n      }\n      &.twoLine {\n        max-height: 0.8rem;\n        white-space: normal;\n        .twoLinesEllipsis();\n      }\n    }\n    .song-art {\n      height: 0.4rem;\n      line-height: 0.4rem;\n      font-size: 0.23rem;\n      color: #dacdcd;\n      width: 75vw;\n      .ellipsis();\n      .artist {\n        &::after {\n          content: \"/\";\n        }\n        &:last-child::after {\n          content: \"\";\n        }\n      }\n      .album-name {\n        &::before {\n          content: \"-\";\n        }\n      }\n    }\n    .dj-info {\n      font-size: 0.2rem;\n      line-height: 1.5;\n      color: #ccc;\n      .result {\n        font-size: 0.2rem;\n      }\n      .data,\n      .count {\n        margin-right: 0.2rem;\n      }\n    }\n  }\n  .icon {\n    color: #ccc;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/songListPage/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-06 11:33:42\n * @Update: 2020-05-04 17:41:34\n * @Update log: 这是一个用来展示歌曲列表的基础组件\n -->\n<template>\n  <!-- 页面需要监听滚动事件，滚动到某个位置时标题栏要固定 -->\n  <!-- 这里需要增加动态的改变样式信息，不是只有显示隐藏！！！！！！！！！ -->\n  <div class=\"wrapper\" @scroll=\"scrollList\">\n    <!-- 由于歌单页和今日推荐页面的顶部展示区域高度不同，所以通过动态的 height 进行设置 -->\n    <div class=\"container-top\" :style=\"{height}\">\n      <!-- 通过传值 isAlbum 的布尔值进行判断，因为在今日推荐页面的页面标题是通过滚动显示隐藏的 -->\n      <global-nav class=\"fixed pd23\" v-if=\"!isAlbum\" @returnPage=\"returnPage\">\n        <!-- 通过改变 listFixed 来控制 title 的显示与否-->\n        <span class=\"text\" v-show=\"listFixed\">{{iTitle}}</span>\n      </global-nav>\n      <!-- 这里是在歌单页面时，页面标题是一直显示的 -->\n      <global-nav class=\"fixed pd23\" v-if=\"isAlbum\" @returnPage=\"returnPage\">\n        <span class=\"text\">{{iTitle}}</span>\n      </global-nav>\n      <!-- 这里包裹的是每日推荐页面额外显示的日期信息 -->\n      <div class=\"pd23\" v-if=\"!isAlbum\">\n        <div class=\"date\">\n          <span class=\"day\">{{day}}</span>\n          <span class=\"month\">{{month}}</span>\n        </div>\n        <div class=\"info\">查收属于您的今日推荐</div>\n      </div>\n      <!-- 这里包裹的是歌单页面的图片，作者，介绍等信息 -->\n      <div class=\"album-info pd23\" v-if=\"isAlbum\">\n        <div class=\"info-top\">\n          <div class=\"img-info\">\n            <img v-lazy=\"imgUrl + '?param=200y200'\" :key=\"imgUrl\" alt />\n            <span class=\"play-count\">\n              <i class=\"date-song bofang\"></i>\n              {{playCount | setPlay}}\n            </span>\n          </div>\n          <div class=\"info-con\">\n            <p class=\"album-title\">{{iAlbumTitle}}</p>\n            <div class=\"creator\">\n              <div class=\"img-info\">\n                <img v-lazy=\"creatorImgUrl + '?param=200y200'\" :key=\"imgUrl\" alt />\n              </div>\n              <span class=\"authorName\">\n                <div class=\"authorNameCon ellipsis\">{{author}}</div>\n                <i class=\"date-song iconfontjiantou5\"></i>\n              </span>\n            </div>\n            <div class=\"desc-wrapper\">\n              <span class=\"desc\">{{description}}</span>\n              <i class=\"date-song iconfontjiantou5\"></i>\n            </div>\n          </div>\n        </div>\n        <div class=\"icons\">\n          <div class=\"comments\" @click=\"goComments\">\n            <i class=\"date-song pinglun\"></i>\n            <span>{{commentCount | setCom}}</span>\n          </div>\n          <div class=\"comments\">\n            <i class=\"date-song fenxiang\"></i>\n            <span>{{shareCount | setShare}}</span>\n          </div>\n          <div class=\"comments\">\n            <i class=\"date-song xiazai\"></i>\n            <span>下载</span>\n          </div>\n          <div class=\"comments\">\n            <i class=\"date-song duoxuankuang\"></i>\n            <span>多选</span>\n          </div>\n        </div>\n      </div>\n    </div>\n    <!-- 这里是 播放全部 那一行的信息，因为要操作是否固定，所以需要单独设置 -->\n    <div class=\"title pd23\" :class=\"{listFixed}\">\n      <span>\n        <span @click=\"beginAudio\">\n          <i class=\"date-song cbofang\"></i>\n          播放全部\n        </span>\n        <!-- 当歌单组件时，需要显示当前歌单总共有多少首歌曲的信息 -->\n        <span class=\"count\" v-if=\"isAlbum\">(共{{trackCount}}首)</span>\n      </span>\n      <!-- 当在每日推荐界面时，这里显示的是一个多选按钮 -->\n      <!-- 这里的多选需要设置一个多选页面的组件！！！！！！！！！ -->\n      <span v-if=\"!isAlbum\">\n        <i class=\"date-song caidan\"></i>\n        多选\n      </span>\n      <!-- 当时歌单组件时有收藏歌单的按钮选项 -->\n      <!-- 这里需要添加判断用户是否已经收藏歌单！！！！来显示不同的样式 -->\n      <div class=\"collection\" :class=\"{ 'bg': !isSubInItem }\" ref=\"collection\" v-if=\"isAlbum\">\n        <span v-show=\"!isSubInItem\" @click=\"addPlaylist\">+ 收藏({{subscribedCountItem | setCol}})</span>\n        <span v-show=\"isSubInItem\" @click=\"deletePlaylist\">\n          <i class=\"date-song wenjianjia\"></i>\n          {{subscribedCountItem | setCol}}\n        </span>\n      </div>\n    </div>\n    <!-- 这里将列表进行包裹统一的通过 load 属性进行判断是否展示 -->\n    <div class=\"list-info\" v-show=\"!load\" :style=\"{ marginTop: top}\">\n      <slot></slot>\n    </div>\n    <!-- 页面 loading 组件 -->\n    <page-loading v-show=\"load\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport globalNav from 'base/generalNav'\nimport pageLoading from 'base/pageLoading'\nimport api from 'api'\n\nconst setNum = function (val) {\n  if (!val) {\n    return ''\n  }\n  if (val > 100000000) {\n    val = ((val / 100000000).toFixed(1)) + '亿'\n  } else if (val > 10000) {\n    val = ((val / 10000).toFixed(1)) + '万'\n  }\n  return val\n}\n\nexport default {\n  name: '',\n  components: {\n    globalNav,\n    pageLoading\n  },\n  /**\n   * 这里使用 data 把 props 接收的值进行存储，因为 vue 不允许子组件直接修改父组件传过来的值\n   */\n  data () {\n    return {\n      iTitle: this.title,\n      iAlbumTitle: this.albumTitle,\n      listFixed: false,\n      top: '0.5rem',\n      isSubInItem: false,\n      subscribedCountItem: 0\n    }\n  },\n  /**\n   * 当已经加载了一次页面后，再次进入页面时标题信息不能更新\n   *\n   * 这里需要监听 props 的改变，如果改变了将新值接受进行改变\n   */\n  watch: {\n    title: function (val) {\n      this.iTitle = val\n    },\n    albumTitle: function (val) {\n      this.iAlbumTitle = val\n    },\n    subscribedCount: function (val) {\n      this.subscribedCountItem = val\n      if (val === 0 || !val) {\n        this.$refs.collection.style.display = 'none'\n      } else {\n        this.$refs.collection.style.display = ''\n      }\n    },\n    isSubIn: function (val) {\n      this.isSubInItem = val\n    }\n  },\n  /**\n   * 所有的 props 值信息\n   */\n  props: {\n    albumId: {\n      type: Number\n    },\n    idxId: {\n      type: Number\n    },\n    // 排行榜id，用来正确获取评论信息\n    idxComId: {\n      type: Number\n    },\n    dishId: {\n      type: Number\n    },\n    playCount: {\n      type: Number\n    },\n    height: {\n      // 顶部展示区域高度\n      type: String,\n      default: '6rem'\n    },\n    subscribedCount: {\n      type: Number\n    },\n    subscribed: {\n      type: Boolean\n    },\n    trackCount: {\n      type: Number\n    },\n    shareCount: {\n      type: Number\n    },\n    commentCount: {\n      type: Number\n    },\n    description: {\n      type: String\n    },\n    author: {\n      type: String\n    },\n    creatorImgUrl: {\n      type: String\n    },\n    albumTitle: {\n      type: String\n    },\n    imgUrl: {\n      type: String\n    },\n    title: {\n      type: String\n    },\n    isAlbum: {\n      type: Boolean,\n      default: true\n    },\n    load: {\n      type: Boolean,\n      default: true\n    },\n    isSubIn: {\n      type: Boolean,\n      default: false\n    }\n  },\n  filters: {\n    setCom: function (val) {\n      if (!val) {\n        return '评论'\n      }\n      return setNum(val)\n    },\n    setShare: function (val) {\n      if (!val) {\n        return '分享'\n      }\n      return setNum(val)\n    },\n    setCol: function (val) {\n      if (!val) {\n        return ''\n      }\n      return setNum(val)\n    },\n    setPlay: function (val) {\n      if (!val) {\n        return ''\n      }\n      return setNum(val)\n    }\n  },\n  // 对日期信息提取展示\n  computed: {\n    /**\n     * 返回日\n     */\n    day: function () {\n      const day = new Date().getDate() < 10\n        ? '0' + new Date().getDate()\n        : new Date().getDate()\n      return day\n    },\n    /**\n     * 返回月份\n     */\n    month: function () {\n      const month = new Date().getMonth() + 1 < 10\n        ? '0' + (new Date().getMonth() + 1)\n        : new Date().getMonth() + 1\n      return month\n    }\n  },\n  methods: {\n    /**\n     * 收藏歌单\n     */\n    addPlaylist () {\n      const id = this.albumId || this.dishId || this.idxId\n      api.addOrDeletePlaylistFn(1, id)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.isSubInItem = true\n            ++this.subscribedCountItem\n          }\n        })\n    },\n    /**\n     * 取消收藏歌单\n     */\n    deletePlaylist () {\n      const id = this.albumId || this.dishId || this.idxId\n      api.addOrDeletePlaylistFn(2, id)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.isSubInItem = false\n            --this.subscribedCountItem\n          }\n        })\n    },\n    /**\n     * 播放全部，向父组件传递事件\n     */\n    beginAudio () {\n      this.$emit('startPlayAll')\n    },\n    /**\n     * 去评论页面\n     * 通过传不同的params的属性来判断资源是歌单还是专辑\n     */\n    goComments () {\n      const playlistId = this.albumId ? this.albumId : this.idxComId\n      const albumId = this.dishId\n      const imgUrl = this.imgUrl\n      const title = this.albumTitle\n      const author = this.author\n      this.$router.push({ name: 'comments', params: { playlistId, albumId, imgUrl, title, author } })\n    },\n    /**\n     * 返回上一页\n     */\n    returnPage () {\n      this.$router.go(-1)\n    },\n    /**\n     * 定义页面滚动事件，\n     * 这里需要添加在滚动过程中样式的变化\n     */\n    scrollList (e) {\n      // 获取到 top 值\n      let top = this.$el.scrollTop\n      // 当当前组件不是歌单组件时，就是每日推荐页面\n      if (!this.isAlbum) {\n        if (top >= 148) {\n          this.listFixed = true\n          this.top = '1.3rem'\n        } else {\n          this.listFixed = false\n          this.top = '0.5rem'\n        }\n      } else {\n        // 当是歌单组件时，当页面滚动到一定位置的时候顶部的标题会变\n        if (top >= 148) {\n          // 这里使用data存下了props的值进行修改，子组件不能直接修改props传过来的值\n          this.iTitle = this.albumTitle\n        } else {\n          this.iTitle = this.title\n        }\n        // 当 top 到了 250 的时候会改变标题行的是否固定样式\n        if (top >= 250) {\n          this.listFixed = true\n          this.top = '1.3rem'\n        } else {\n          this.listFixed = false\n          this.top = '0.5rem'\n        }\n      }\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"//at.alicdn.com/t/font_1394963_t6jt71rtm9.css\");\n@import url(\"~styles/global.less\");\n.topFixed {\n  position: fixed;\n  width: 100%;\n  height: 1rem;\n  background-color: #ee5253;\n  z-index: 9;\n}\n@textColor: #ccc;\n.fixed {\n  .topFixed();\n  top: 0;\n}\n.listFixed {\n  .topFixed();\n  top: 1rem;\n}\n\n.wrapper {\n  height: 100vh;\n  position: relative;\n  overflow: scroll;\n  // 组件的title\n  .title {\n    font-size: 0.3rem;\n    height: 1rem;\n    line-height: 1rem;\n    .flex-between();\n    background-color: #fff;\n    .count {\n      color: #999;\n      font-size: small;\n    }\n    .collection {\n      .pd23();\n      font-size: smaller;\n      margin-top: 3px;\n      height: 0.7rem;\n      line-height: 0.7rem;\n      border-radius: 0.4rem;\n      color: #999;\n      &.bg {\n        background-color: @bgcolor;\n        color: #fff;\n      }\n    }\n  }\n  .container-top {\n    width: 100%;\n    color: #fff;\n    background-color: #ee5253;\n    .date {\n      padding-top: 1.5rem;\n      .day {\n        font-size: 0.7rem;\n      }\n      .month {\n        font-size: 0.4rem;\n        color: #c8d6e5;\n        &::before {\n          content: \"/\";\n        }\n      }\n    }\n    .info {\n      margin-top: 0.7rem;\n    }\n    .text {\n      font-size: 0.4rem;\n      vertical-align: 5px;\n      width: 8rem;\n      .ellipsis();\n    }\n    .album-info {\n      padding-top: 1.5rem;\n      .info-top {\n        height: 3rem;\n        .flex-between();\n        overflow: hidden;\n        .img-info {\n          @size: 2.6rem;\n          width: @size;\n          height: 0;\n          position: relative;\n          padding-bottom: @size;\n          border-radius: @imgBorderRadius;\n          overflow: hidden;\n          img {\n            width: @size;\n            height: @size;\n          }\n          .play-count {\n            position: absolute;\n            top: 0.1rem;\n            right: 0.1rem;\n            .bofang {\n              font-size: 0.24rem;\n            }\n          }\n        }\n        .info-con {\n          width: 3.6rem;\n          height: 2.6rem;\n          display: flex;\n          flex-direction: column;\n          overflow: hidden;\n          .album-title {\n            font-size: 0.36rem;\n            line-height: 1.5;\n            .twoLinesEllipsis();\n          }\n          .creator {\n            height: 1rem;\n            color: @textColor;\n            display: flex;\n            align-items: center;\n            .img-info {\n              @size: 0.6rem;\n              width: @size;\n              height: 0;\n              padding-bottom: @size;\n              margin-right: 8px;\n              border-radius: 50%;\n              overflow: hidden;\n              img {\n                width: @size;\n                height: @size;\n              }\n            }\n          }\n          .desc-wrapper {\n            display: flex;\n            align-items: center;\n            color: @textColor;\n            .desc {\n              width: 3rem;\n              .twoLinesEllipsis();\n            }\n          }\n        }\n      }\n      .icons {\n        margin-top: 8px;\n        .flex-around();\n        width: 100%;\n        .comments {\n          display: flex;\n          justify-content: center;\n          align-items: center;\n          flex-direction: column;\n          .date-song {\n            font-size: 0.4rem;\n            margin-bottom: 5px;\n          }\n        }\n      }\n    }\n  }\n  .list-info {\n    width: 100%;\n    box-sizing: border-box;\n    padding: 0.1rem 0.23rem;\n    background-color: #fff;\n    transform: translate3d(0, -0.5rem, 0);\n  }\n}\n\n.authorName {\n  display: flex;\n  .authorNameCon {\n    max-width: 2.2rem;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/base/titleFooter.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-02 18:07:09\n * @Update: 2019-09-03 18:00:27\n * @Update log: 搜索展示页面公共的标题和底部组件\n -->\n<template>\n  <div class=\"list-global\">\n    <div class=\"title\">\n      <span class=\"title-content\">{{title}}</span>\n      <span class=\"smallTag\" v-if=\"songList\">\n        <i class=\"result cbofang\"></i>\n        播放全部\n      </span>\n    </div>\n    <slot></slot>\n    <div class=\"more\" v-if=\"more\" @click=\"toLInk\">\n      {{moreText}}\n      <i class=\"result youjiantou\"></i>\n    </div>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: '',\n  props: {\n    title: {\n      type: String\n    },\n    more: {\n      type: Boolean,\n      default: false\n    },\n    moreText: {\n      type: String\n    },\n    songList: {\n      type: Boolean\n    },\n    linkPage: {\n      type: String\n    },\n    keyW: {\n      type: String\n    }\n  },\n  methods: {\n    toLInk () {\n      /**\n       * 点击的时候把要跳转的页面传到state中，\n       * 标签导航组件获取到当前的state。根据index值计算出要滚动的距离\n       */\n      this.$store.commit('SET_LINK_PAGE', this.linkPage)\n      this.$router.push({\n        path: `/${this.linkPage}/${this.keyW}`\n      })\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n\n.list-global {\n  margin-top: 0.36rem;\n  .title {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    .title-content {\n      font-weight: 700;\n      height: 0.3rem;\n      line-height: 0.3rem;\n    }\n  }\n  .more {\n    height: 1rem;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    font-size: 0.26rem;\n    color: #ccc;\n    .youjiantou {\n      color: #aaa;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/components/detailPage/index.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-13 12:03:28\n * @Update: 2019-11-30 13:27:53\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\" @scroll=\"scrollList\">\n    <detail-nav @returnPage=\"returnPage\" class=\"fixed pd23\" style=\"color:#fff;\">\n      <span class=\"text\">{{$title}}</span>\n    </detail-nav>\n    <div\n      class=\"container-top\"\n      :class=\"{coverFixed, position}\"\n      :style=\"{backgroundImage: 'url(' + coverImgUrl + ')'}\"\n    >\n      <div class=\"cover\" :style=\"{backgroundColor: `rgba(0, 0, 0, ${cover})`}\"></div>\n      <div class=\"data\" v-show=\"!listFixed\" :style=\"{opacity}\">\n        <slot name=\"data\">上半部区域</slot>\n      </div>\n    </div>\n    <div :class=\"{listFixed}\">\n      <slot name=\"nav-list\">这里显示吸顶标签行</slot>\n    </div>\n    <div class=\"container-bottom\" :style=\"{ marginTop: top}\">\n      <slot name=\"bottom\">下边展示音乐列表</slot>\n    </div>\n    <slot name=\"slider\">这里是显示下方滑块</slot>\n  </div>\n</template>\n\n<script>\nimport detailNav from 'base/generalNav'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      cover: '0.2',\n      listFixed: false,\n      coverFixed: false,\n      position: true,\n      top: '0rem',\n      opacity: 1,\n      $title: ''\n    }\n  },\n  props: {\n    title: {\n      type: String\n    },\n    name: {\n      type: String\n    },\n    coverImgUrl: {\n      type: String\n    }\n  },\n  methods: {\n    returnPage () {\n      this.$router.go(-1)\n    },\n    /**\n     * 定义页面滚动事件，\n     * 这里需要添加在滚动过程中样式的变化\n     */\n    scrollList (e) {\n      // 获取到 top 值\n      let top = this.$el.scrollTop\n      this.cover = top / 1000 + 0.3\n      this.opacity = 1 - top / 500\n      if (this.cover > 0.6) {\n        this.cover = 0.6\n        this.opacity = 0.4\n      } else {\n        this.cover = top / 1000 + 0.3\n        this.opacity = 1 - top / 500\n      }\n      if (top >= 282) {\n        this.$title = this.name\n        this.listFixed = true\n        this.coverFixed = true\n        this.position = false\n        this.top = '7.8rem'\n      } else {\n        this.$title = this.title\n        this.listFixed = false\n        this.coverFixed = false\n        this.position = true\n        this.top = '0'\n      }\n    }\n  },\n  components: {\n    detailNav\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.topFixed {\n  position: fixed;\n  width: 100%;\n  height: 0.8rem;\n  z-index: 9;\n}\n.fixed {\n  .topFixed();\n  top: 0;\n}\n.listFixed {\n  .topFixed();\n  top: 1.6rem;\n}\n.coverFixed {\n  position: fixed;\n  width: 100%;\n  z-index: 3;\n  top: 0;\n  transform: translateY(-5.4rem);\n}\n.wrapper {\n  width: 100vw;\n  height: 100vh;\n  position: relative;\n  overflow-y: scroll;\n  overflow-x: hidden;\n  .text {\n    font-size: 0.4rem;\n    vertical-align: 5px;\n  }\n  .container-top {\n    width: 100%;\n    height: 0;\n    padding-bottom: 7rem;\n    background-size: 100%;\n    background-repeat: no-repeat;\n    &.position {\n      position: relative;\n    }\n    .cover {\n      position: absolute;\n      left: 0;\n      top: 0;\n      right: 0;\n      bottom: 0;\n      width: 100%;\n      height: 100%;\n    }\n    .data {\n      position: absolute;\n      bottom: 1rem;\n      left: 0.3rem;\n      .flex-between();\n      width: 100%;\n      box-sizing: border-box;\n      padding-right: 0.8rem;\n    }\n  }\n  .container-bottom {\n    transform: translate3d(0, -0.8rem, 0);\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/components/top-tip/index.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-11-24 11:11:37\n * @Update: 2019-11-24 12:19:31\n * @Update log: 更新日志\n -->\n<template>\n  <transition name=\"tip-show\" mode=\"out-in\">\n    <div class=\"tip\" v-show=\"isTip\">\n      <slot></slot>\n    </div>\n  </transition>\n</template>\n\n<script>\nlet timer = null\nexport default {\n  name: '',\n  data () {\n    return {\n      isTip: false\n    }\n  },\n  methods: {\n    showTip () {\n      this.isTip = true\n      if (timer) {\n        clearTimeout(timer)\n      }\n      timer = setTimeout(() => {\n        this.hideTip()\n      }, 3000)\n    },\n    hideTip () {\n      this.isTip = false\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n.tip-show-enter,\n.tip-show-leave-to {\n  transform: translateY(-1rem);\n}\n\n.tip-show-enter-active,\n.tip-show-leave-active {\n  transition: transform linear 0.3s;\n}\n.tip {\n  position: fixed;\n  top: 1.2rem;\n  left: 0;\n  right: 0;\n  display: flex;\n  justify-content: center;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/getInfos/getData.js",
    "content": "/*\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-07-30 16:42:30\n * @Update log: 更新日志\n */\nimport Icons from './icons'\n\n/**\n * 获取我的页面上边的图标\n */\nexport const homeIcons = () => {\n  return Icons.homeIcons\n}\n\n/**\n * 获取我的页面列表图标\n */\nexport const homeList = () => {\n  return Icons.homeList\n}\n\n/**\n * 获取发现页面上边的图标\n */\nexport const findIcons = () => {\n  return Icons.findIcons\n}\n\n/**\n * 获取登陆页面上边的图标\n */\nexport const loginIcons = () => {\n  return Icons.loginIcons\n}\n\n/**\n * 获取登陆列表上边的图标\n */\nexport const loginIconsTop = () => {\n  return Icons.loginIconsTop\n}\n\n/**\n * 获取登陆列表下边的图标\n */\nexport const loginIconsBottom = () => {\n  return Icons.loginIconsBottom\n}\n\n/**\n * 获取电台页面图标数据\n */\nexport const djIcons = () => {\n  return Icons.djIcons\n}\n"
  },
  {
    "path": "musicPlayer/src/getInfos/icons.js",
    "content": "/*\n * @Author: Lambda\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-10-18 11:25:41\n * @Update log: 更新日志\n */\nlet homeIcons = [{\n  text: '私藏推荐',\n  icon: 'home iconxindian'\n}, {\n  text: '私人FM',\n  icon: 'home iconshouyinji'\n}, {\n  text: 'Sati空间',\n  icon: 'home iconyueliang'\n}, {\n  text: '最新电音',\n  icon: 'home iconduodian'\n}, {\n  text: '因乐交友',\n  icon: 'home iconjiaoyou'\n}, {\n  text: '亲子频道',\n  icon: 'home iconertong'\n}, {\n  text: '古典专区',\n  icon: 'home icongangqin'\n}, {\n  text: '跑步FM',\n  icon: 'home iconorder-received'\n}, {\n  text: '小冰电台',\n  icon: 'home iconbingjiling'\n}, {\n  text: '爵士电台',\n  icon: 'home iconyandou'\n}, {\n  text: '驾驶模式',\n  icon: 'home iconqiche'\n}, {\n  text: '编辑',\n  icon: 'home icontoggle'\n}]\n\nlet findIcons = [{\n  text: '每日推荐',\n  icon: 'find rili',\n  linkTo: 'dateRecommend'\n}, {\n  text: '歌单',\n  icon: 'find gedan',\n  linkTo: 'recommend'\n}, {\n  text: '排行榜',\n  icon: 'find paixingbang',\n  linkTo: 'idx'\n}, {\n  text: '电台',\n  icon: 'find diantai',\n  linkTo: 'dj'\n}, {\n  text: '私人FM',\n  icon: 'find shouyin',\n  linkTo: 'personalFm'\n}]\n\nlet djIcons = [{\n  text: '电台分类',\n  icon: 'dj dj-caidan1',\n  linkTo: 'classification'\n}, {\n  text: '电台排行',\n  icon: 'dj dj-paixing',\n  linkTo: 'ranking'\n}, {\n  text: '付费精品',\n  icon: 'dj dj-gerenzhongxin_wodeguizu',\n  linkTo: 'pay_fine'\n}, {\n  text: '主播学院',\n  icon: 'dj dj-shucopy',\n  linkTo: 'anchor_college'\n}]\n\nlet homeList = [{\n  icon: 'iconyinyue',\n  text: '本地音乐',\n  num: 0\n}, {\n  icon: 'iconzuijinbofang',\n  text: '最近播放',\n  num: 0\n}, {\n  icon: 'iconxiazai',\n  text: '下载管理',\n  num: 0\n}, {\n  icon: 'icondiantai',\n  text: '我的电台',\n  num: 0\n}, {\n  icon: 'iconicon-31',\n  text: '我的收藏',\n  num: 0\n}]\n\nlet loginIcons = [{\n  icon: 'login iconwodexiaoxi',\n  text: '我的消息'\n}, {\n  icon: 'login iconyonghu',\n  text: '我的好友'\n}, {\n  icon: 'login iconpifu',\n  text: '个性皮肤'\n}, {\n  icon: 'login icontinggeshiqu40x40',\n  text: '听歌识曲'\n}]\n\nlet loginIconsTop = [{\n  icon: 'iconhuopiaotongxing',\n  text: '演出'\n}, {\n  icon: 'icongouwuche',\n  text: '商城'\n}, {\n  icon: 'icondibiao',\n  text: '附近的人'\n}, {\n  icon: 'iconicon--',\n  text: '口袋铃声'\n}, {\n  icon: 'icondingdan',\n  text: '我的订单'\n}]\n\nlet loginIconsBottom = [{\n  icon: 'iconicon--2',\n  text: '定时停止播放'\n}, {\n  icon: 'iconsaoyisao',\n  text: '扫一扫'\n}, {\n  icon: 'iconicon--1',\n  text: '音乐闹钟'\n}, {\n  icon: 'iconhezi501',\n  text: '在线听歌免流量'\n}, {\n  icon: 'iconyouxi',\n  text: '游戏推荐'\n}, {\n  icon: 'iconCoupon',\n  text: '优惠券'\n}, {\n  icon: 'iconmaikefeng',\n  text: '我要直播'\n}]\n\nexport default {\n  homeIcons,\n  findIcons,\n  homeList,\n  loginIcons,\n  loginIconsTop,\n  loginIconsBottom,\n  djIcons\n}\n"
  },
  {
    "path": "musicPlayer/src/main.js",
    "content": "/*\n * @Author: Lambda\n * @Begin: 2019-08-30 19:47:55\n * @Update: 2020-03-13 22:29:57\n * @Update log: 更新日志\n */\n// The Vue build version to load with the `import` command\n// (runtime-only or standalone) has been set in webpack.base.conf with an alias.\nimport Vue from 'vue'\nimport App from './App'\nimport router from './router'\nimport store from './store'\nimport fastclick from 'fastclick'\nimport VueLazyload from 'vue-lazyload'\nimport topTip from '@/components/top-tip'\nimport {\n  Search,\n  ActionSheet,\n  Swipe,\n  SwipeItem,\n  Button,\n  Checkbox,\n  CheckboxGroup,\n  PasswordInput,\n  NumberKeyboard,\n  PullRefresh\n} from 'vant'\n\nimport 'styles/reset.css'\nimport 'styles/border.css'\n\nfastclick.attach(document.body)\n// import \"\"\nVue.use(Search)\nVue.use(Button)\nVue.use(ActionSheet)\nVue.use(PullRefresh)\nVue.use(Swipe).use(SwipeItem)\nVue.use(Checkbox).use(CheckboxGroup)\nVue.use(PasswordInput).use(NumberKeyboard)\n\nVue.config.productionTip = false\n\nVue.use(VueLazyload, {\n  preLoad: 1.3,\n  error: './assets/load.gif',\n  loading: 'data:image/png;base64,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',\n  attempt: 1,\n  listenEvents: ['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend', 'touchmove']\n})\n\nVue.component('top-tip', topTip)\n\n/* eslint-disable no-new */\n// eslint-disable-next-line no-unused-vars\nvar vm = new Vue({\n  el: '#app',\n  router,\n  store,\n  components: {\n    App\n  },\n  template: '<App/>'\n})\nwindow.vm = vm\n"
  },
  {
    "path": "musicPlayer/src/pages/audioIndex/components/audioList.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-21 14:37:20\n * @Update: 2019-11-07 12:02:35\n * @Update log: 更新日志\n -->\n<template>\n  <div @click.stop>\n    <div class=\"mask\" v-show=\"isShowAudioList\" @click=\"showAudioList\"></div>\n    <transition name=\"list-show\" mode=\"out-in\">\n      <div class=\"audio-list pd23\" v-show=\"isShowAudioList\">\n        <div class=\"list-title border-bottom\">\n          <div class=\"left\">\n            <span @click=\"changeMode\">\n              <i class=\"audio\" :class=\"[modeClass]\"></i>\n              <span>{{ modeText }}</span>\n              <span class=\"list-num\">({{ num }})</span>\n            </span>\n          </div>\n          <div class=\"right\">\n            <span>\n              <i class=\"audio audiowenjianjia\"></i>\n              收藏全部\n            </span>\n            <span>\n              <i class=\"audio audiolajitong\"></i>\n            </span>\n          </div>\n        </div>\n        <ul class=\"scroll\">\n          <li\n            class=\"list-item\"\n            v-for=\"(item, index) in audioList\"\n            :key=\"index\"\n            @click=\"audioThis(item, index)\"\n            :class=\"isActive(item)\"\n          >\n            <i class=\"audio audiovolume\"></i>\n            <div class=\"info\">\n              <span class=\"name\">\n                <i>{{item.name}}</i>\n              </span>\n              <span class=\"artist\">\n                <i v-for=\"(item, index) in artist(item)\" :key=\"index\">{{ item.name }}</i>\n              </span>\n            </div>\n            <!-- 删除此项歌曲 -->\n            <span @click.stop=\"deleteSong(item)\">\n              <i class=\"audio audiochushaixuanxiang\"></i>\n            </span>\n          </li>\n        </ul>\n      </div>\n    </transition>\n  </div>\n</template>\n\n<script>\nimport { audio } from 'mixins/Mixins'\nimport { mapGetters, mapMutations, mapActions } from 'vuex'\nexport default {\n  mixins: [audio],\n  name: '',\n  props: {\n    num: {\n      type: Number\n    },\n    isShowAudioList: {\n      type: Boolean,\n      default: false\n    }\n  },\n  computed: {\n    modeText: function () {\n      switch (this.mode) {\n        case 0: // 列表循环\n          return '列表循环'\n        case 1: // 单曲循环\n          return '单曲循环'\n        case 2: // 随机播放\n          return '随机播放'\n      }\n    },\n    ...mapGetters({\n      audioList: 'AUDIO_LIST',\n      audioIng: 'AUDIO_ING_SONG',\n      playList: 'PLAY_LIST'\n    })\n  },\n  methods: {\n    isActive (item) {\n      if (item.id === this.audioIng.id) {\n        return 'active'\n      }\n      return ''\n    },\n    artist (artist) {\n      if (artist.artists) {\n        return artist.artists\n      } else {\n        return artist.ar\n      }\n    },\n    audioThis (item, index) {\n      // 随机播放情况\n      if (this.mode === 2) {\n        /**\n         * 找到对应歌曲的索引\n         */\n        index = this.playList.findIndex((song) => {\n          return song.id === item.id\n        })\n      }\n      this.setAudioIndex(index)\n    },\n    ...mapMutations({\n      setAudioIndex: 'SET_AUDIO_INDEX'\n    }),\n    ...mapActions(['deleteSong'])\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n\n.list-show-enter,\n.list-show-leave-to {\n  transform: translateY(7rem);\n}\n\n.list-show-enter-active,\n.list-show-leave-active {\n  transition: transform linear 0.3s;\n}\n\n.audio-list {\n  width: 100%;\n  margin-right: 0.23rem;\n  position: fixed;\n  bottom: 0;\n  z-index: 11;\n  background-color: #fff;\n  border-top-right-radius: 0.5rem;\n  border-top-left-radius: 0.5rem;\n  .list-title {\n    display: flex;\n    .flex-between();\n    align-items: center;\n    height: 1rem;\n  }\n  .scroll {\n    &::-webkit-scrollbar {\n      width: 0 !important;\n    }\n    max-height: 6rem;\n    overflow: scroll;\n    .list-item {\n      display: flex;\n      .flex-between();\n      align-items: center;\n      height: 1rem;\n      .audiovolume {\n        display: none;\n      }\n      &.active {\n        color: @bgcolor;\n        .audiovolume {\n          display: block;\n        }\n        .artist {\n          color: @bgcolor;\n        }\n      }\n      .info {\n        width: 80vw;\n        .ellipsis();\n      }\n      .artist {\n        font-size: 0.24rem;\n        color: #999;\n        i {\n          &::after {\n            content: \"/\";\n          }\n          &:last-child::after {\n            content: \"\";\n          }\n          &:first-child::before {\n            content: \"-\";\n          }\n        }\n      }\n      .audiochushaixuanxiang {\n        color: #bbb;\n      }\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/audioIndex/components/bar.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-13 14:01:18\n * @Update: 2019-11-05 13:59:06\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"bar\">\n    <span>{{ time }}</span>\n    <div class=\"bar-bg\" ref=\"barBg\" @touchstart.prevent=\"clickBg\">\n      <div class=\"bar-layer\" :style=\"{width:length}\"></div>\n      <div\n        class=\"point\"\n        :style=\"{left:length}\"\n        @touchstart.prevent=\"start\"\n        @touchmove.prevent=\"move\"\n        @touchend=\"end\"\n      ></div>\n    </div>\n    <span>{{ allTime | setTime }}</span>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: '',\n  data () {\n    return {\n      length,\n      touch: {}\n    }\n  },\n  props: {\n    allTime: {\n      type: Number\n    },\n    time: {\n      type: String\n    },\n    width: {\n      type: Number\n    },\n    index: {\n      type: Number\n    }\n  },\n  watch: {\n    width: function (val) {\n      if (val && !this.touch.state) {\n        val = val + '%'\n        this.length = val\n      }\n    }\n  },\n  methods: {\n    /**\n     * 点击小圆点\n     */\n    start (e) {\n      this.touch.state = true\n      const left = this.$refs.barBg.offsetLeft\n      this.touch.startX = e.changedTouches[0].pageX - left\n      this.touch.width = this.$refs.barBg.clientWidth\n    },\n    clickBg (e) {\n      this.touch.width = this.$refs.barBg.clientWidth\n      const left = this.$refs.barBg.offsetLeft\n      this.touch.endX = e.changedTouches[0].pageX - left\n      const offsetWidth = this.touch.endX / this.touch.width * 100\n      console.log(offsetWidth)\n\n      this._changeWidth(offsetWidth)\n      this.$emit('time', offsetWidth, isNaN(this.index) ? '' : this.index)\n    },\n    move (e) {\n      if (!this.touch.state) {\n        return\n      }\n      const left = this.$refs.barBg.offsetLeft\n      const deltaX = e.changedTouches[0].pageX - left\n      const width = Math.min(Math.max(0, deltaX), this.touch.width)\n      this.touch.offsetWidth = width / this.touch.width * 100\n      this._changeWidth(this.touch.offsetWidth)\n    },\n    _changeWidth (val) {\n      this.length = val + '%'\n    },\n    end () {\n      this.touch.state = false\n      this.$emit('time', this.touch.offsetWidth, isNaN(this.index) ? '' : this.index)\n    }\n  },\n  filters: {\n    /**\n     * 将毫秒数转换为正常的时间\n     *  212245 ==> 03:32\n    */\n    setTime: function (value) {\n      if (!value) return ''\n      let min = parseInt(value / (1000 * 60))\n      if (min < 10) {\n        min = '0' + min\n      }\n      let sec = parseInt(value % (1000 * 60) / 1000)\n      if (sec < 10) {\n        sec = '0' + sec\n      }\n      value = `${min}:${sec}`\n      return value\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n.bar {\n  margin: 0.6rem 0;\n  display: flex;\n  align-items: center;\n  color: #bdc3c7;\n  font-size: 0.2rem;\n  .bar-bg {\n    width: 100%;\n    margin: 0 0.16rem;\n    height: 2px;\n    background-color: #95a5a6;\n    position: relative;\n    .bar-layer {\n      height: 2px;\n      background-color: #ecf0f1;\n    }\n    .point {\n      position: absolute;\n      top: -3px;\n      border-radius: 50%;\n      width: 8px;\n      height: 8px;\n      background-color: #ecf0f1;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/audioIndex/components/functionButton.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-13 13:33:12\n * @Update: 2019-11-07 11:42:11\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\">\n    <i class=\"audio\" :class=\"[modeClass]\" @click.self=\"changeMode\"></i>\n    <i class=\"audio audioxiayishou1\" @click.self=\"prev\"></i>\n    <i class=\"audio\" @click=\"play\" :class=\"{audiobofang1: isPlay, audiobofang: !isPlay}\"></i>\n    <i class=\"audio audioxiayishou\" @click.self=\"next\"></i>\n    <i class=\"audio audioliebiao\" @click.self=\"showAudioList\"></i>\n  </div>\n</template>\n\n<script>\nimport { mapGetters } from 'vuex'\nexport default {\n  name: '',\n  computed: {\n    ...mapGetters({ isPlay: 'PLAY_STATE' }),\n    modeClass: function () {\n      switch (this.mode) {\n        case 0: // 列表循环\n          return 'audioxunhuan'\n        case 1: // 单曲循环\n          return 'audiosingle-loop'\n        case 2: // 随机播放\n          return 'audiosuiji'\n      }\n    }\n  },\n  props: {\n    mode: {\n      type: Number\n    }\n  },\n  methods: {\n    play () {\n      this.$emit('play')\n    },\n    prev () {\n      this.$emit('prev')\n    },\n    next () {\n      this.$emit('next')\n    },\n    changeMode () {\n      this.$emit('changeMode')\n    },\n    showAudioList () {\n      this.$emit('showAudioList')\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n.wrapper {\n  display: flex;\n  justify-content: space-around;\n  align-items: center;\n  .pinglun {\n    position: relative;\n    .com-num {\n      position: absolute;\n      top: 0;\n      right: 0;\n      font-size: 0.24rem;\n      padding: 0.03rem;\n      box-sizing: border-box;\n      background-color: #7f8c8d;\n      color: #bdc3c7;\n    }\n  }\n  .audio {\n    font-size: 0.5rem;\n    color: #bdc3c7;\n    &:nth-of-type(3) {\n      font-size: 1rem;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/audioIndex/components/lyricPage.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-16 13:26:47\n * @Update: 2020-03-14 13:47:25\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\">\n    <div class=\"full\" v-if=\"noLyric\">{{noLyricText}}</div>\n    <ul :style=\"{marginTop: marginTop}\">\n      <li\n        v-for=\"(item, index) in lyricArray\"\n        :key=\"index\"\n        :class=\"{active: index === nowLyricIndex}\"\n      >{{ item | setWords }}</li>\n    </ul>\n  </div>\n</template>\n\n<script>\nconst midHeight = 3.5\nexport default {\n  name: '',\n  props: {\n    lyricArray: {\n      type: Array\n    },\n    // 当前播放的歌词索引\n    nowLyricIndex: {\n      type: Number\n    },\n    noLyric: {\n      type: Boolean\n    },\n    noLyricText: {\n      type: String\n    }\n  },\n  data () {\n    return {\n      marginTop: '0rem'\n    }\n  },\n  filters: {\n    setWords: function (val) {\n      if (val && val.words) {\n        return val.words\n      }\n    }\n  },\n  methods: {\n    setCurrent (index) {\n      // 这里求出中线的位置为 8.3 rem\n      // 通过 歌词容器的高度 / 2 - 每个 li 的高度 / 2\n      // 每次移动是移动一行歌词的高度，一行歌词高度是 0.6 rem\n      let top = midHeight - index * 0.6\n      if (top > 0) {\n        // top 不能为正数\n        top = 0\n      }\n      this.marginTop = top + 'rem'\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n\n.wrapper {\n  height: 7.6rem;\n  // box-sizing: border-box;\n  margin: 0.6rem 0;\n  color: #ccc;\n  overflow: hidden;\n  ul {\n    margin: 0;\n    padding: 0;\n    list-style: none;\n    text-align: center;\n    /* ul元素的margin-top值变化，在0.7秒内完成 */\n    transition: margin-top 0.7s;\n    li {\n      height: 0.6rem;\n      line-height: 1.5;\n      .ellipsis();\n      &.active {\n        color: #fff;\n      }\n    }\n  }\n  .full {\n    width: 100%;\n    height: 100%;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/audioIndex/components/playIcons.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-13 13:33:12\n * @Update: 2019-10-24 09:42:28\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\">\n    <i\n      class=\"audio\"\n      @click=\"changeLikeStatus(audioSong.id)\"\n      :class=\"{audioshoucang: isLike, audioshoucang1:!isLike}\"\n    ></i>\n    <i class=\"audio audioxiazai\"></i>\n    <i class=\"audio audiocaidan\"></i>\n  </div>\n</template>\n\n<script>\nimport { mapGetters } from 'vuex'\nimport api from 'api'\nexport default {\n  name: '',\n  props: {\n    isLike: {\n      type: Boolean\n    }\n  },\n  computed: {\n    _isLike: {\n      get () {\n        return this.isLike\n      },\n      set (val) {\n        this.$emit('update_isLike', val)\n      }\n    },\n    ...mapGetters({ audioSong: 'AUDIO_ING_SONG' })\n  },\n  methods: {\n    /**\n     * 添加喜欢歌曲\n     * 删除已喜欢歌曲\n     */\n    changeLikeStatus (id) {\n      api.likeMusicFn(id, !this.isLike)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            // 成功\n            this._isLike = !this.isLike\n          }\n        })\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n.wrapper {\n  display: flex;\n  justify-content: space-around;\n  align-items: center;\n  .pinglun {\n    position: relative;\n    .com-num {\n      position: absolute;\n      top: 0;\n      right: 0;\n      font-size: 0.24rem;\n      padding: 0.03rem;\n      box-sizing: border-box;\n      background-color: #7f8c8d;\n      color: #bdc3c7;\n    }\n  }\n  .audio {\n    font-size: 0.5rem;\n    color: #bdc3c7;\n    &.audioshoucang {\n      color: #e74c3c;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/audioIndex/components/playing.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-13 12:44:14\n * @Update: 2019-10-11 11:40:19\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\">\n    <div class=\"great\" :class=\"{rotate: !isPlay}\"></div>\n    <div class=\"circle-bg\" ref=\"circle\">\n      <div class=\"song-img\">\n        <img :src=\"imgUrl + '?param=200y200'\" alt />\n      </div>\n    </div>\n  </div>\n</template>\n\n<script>\nimport { mapGetters } from 'vuex'\nexport default {\n  name: '',\n  props: {\n    imgUrl: {\n      type: String\n    }\n  },\n  computed: {\n    ...mapGetters({ isPlay: 'PLAY_STATE' })\n  },\n  watch: {\n    isPlay: function (val) {\n      if (val) {\n        this.$refs.circle.style.animationPlayState = 'running'\n      } else {\n        this.$refs.circle.style.animationPlayState = 'paused'\n      }\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n.wrapper {\n  height: 7.6rem;\n  margin: 0.6rem 0;\n  position: relative;\n  overflow: hidden;\n  .great {\n    position: absolute;\n    z-index: 1;\n    left: 50%;\n    transform-origin: top left;\n    transform: translate(-50%) rotate(0deg);\n    transition: transform 0.2s;\n    width: 2rem;\n    height: 0;\n    padding-bottom: 2.5rem;\n    background-image: url(\"data:image/png;base64,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\");\n    background-size: 100% 100%;\n    background-repeat: no-repeat;\n    &.rotate {\n      transform: translate(-50%) rotate(-16deg);\n    }\n  }\n  .circle-bg {\n    display: flex;\n    justify-content: center;\n    width: 80vw;\n    margin: 1.4rem auto;\n    height: 0;\n    padding-bottom: 80vw;\n    background-image: url(\"data:image/png;base64,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\");\n    background-size: 100% 100%;\n    background-repeat: no-repeat;\n    animation: rotating 24s linear infinite;\n    transform-origin: center;\n    .song-img {\n      border: 1px solid #000;\n      width: 3.6rem;\n      height: 0;\n      padding-bottom: 3.6rem;\n      border-radius: 50%;\n      margin-top: 1rem;\n      overflow: hidden;\n      img {\n        width: 3.6rem;\n        height: 3.6rem;\n      }\n    }\n  }\n}\n@keyframes rotating {\n  0% {\n    transform: rotate(0deg);\n  }\n  100% {\n    transform: rotate(360deg);\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/audioIndex/components/small.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-14 17:51:26\n * @Update: 2019-11-07 12:10:02\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"bottom-audio border-top pd23\" @click=\"returnFull\">\n    <div class=\"img-info\" ref=\"circle\">\n      <img :src=\"imgUrl\" alt />\n    </div>\n    <div class=\"con-info\">\n      <p class=\"name\">{{name}}</p>\n      <p class=\"lrc\">{{ lyric | emptyCon }}</p>\n    </div>\n    <div class=\"button\">\n      <span class=\"circle\">\n        <i\n          class=\"audio\"\n          @click.stop=\"play\"\n          :class=\"{audiozantingtingzhi: isPlay, audiobofang2: !isPlay}\"\n        ></i>\n      </span>\n      <i class=\"audio audioliebiao\" @click.stop=\"showAudioList\"></i>\n    </div>\n  </div>\n</template>\n\n<script>\nimport { audio } from 'mixins/Mixins'\nimport { mapGetters } from 'vuex'\nexport default {\n  mixins: [audio],\n  name: '',\n  props: {\n    imgUrl: {\n      type: String\n    },\n    name: {\n      type: String\n    },\n    lyric: {\n      type: String\n    },\n    artist: {\n      type: [Array, String]\n    }\n  },\n  filters: {\n    emptyCon: function (val) {\n      if (!val) {\n        return '-'\n      }\n      return val\n    }\n  },\n  computed: {\n    ...mapGetters({ isPlay: 'PLAY_STATE' })\n  },\n  methods: {\n    play () {\n      this.$emit('play')\n    },\n    returnFull () {\n      this.$emit('returnFull')\n    }\n  },\n  watch: {\n    isPlay: function (val) {\n      if (val) {\n        this.$refs.circle.style.animationPlayState = 'running'\n      } else {\n        this.$refs.circle.style.animationPlayState = 'paused'\n      }\n    },\n    lyric: function (val) {\n      let artistName\n      if (!val) {\n        this.artist.forEach(element => {\n          artistName += element.name\n        })\n        val = artistName\n\n        console.log(val)\n      }\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n\n.bottom-audio {\n  display: flex;\n  align-items: center;\n  position: fixed;\n  width: 100vw;\n  height: 1rem;\n  bottom: 0;\n  z-index: 9;\n  background-color: #fff;\n  .img-info {\n    width: 0.7rem;\n    height: 0;\n    padding-bottom: 0.7rem;\n    border-radius: 50%;\n    overflow: hidden;\n    animation: rotating 24s linear infinite;\n    transform-origin: center;\n    img {\n      width: 0.7rem;\n      height: 0.7rem;\n    }\n  }\n  .con-info {\n    margin-left: 0.16rem;\n    width: 4.6rem;\n    .name {\n      font-size: 0.26rem;\n      line-height: 1.5;\n      .ellipsis();\n    }\n    .lrc {\n      font-size: 0.2rem;\n      line-height: 1.5;\n      .ellipsis();\n    }\n  }\n  .button {\n    .audio {\n      box-sizing: border-box;\n      margin-left: 0.12rem;\n      font-size: 0.4rem;\n    }\n    .circle {\n      display: inline-block;\n      text-align: center;\n      line-height: 0.4rem;\n      width: 0.4rem;\n      height: 0.4rem;\n      border-radius: 50%;\n      margin-left: 0.1rem;\n      .audio {\n        margin-left: 0;\n        font-size: 0.3rem;\n      }\n    }\n  }\n}\n@keyframes rotating {\n  0% {\n    transform: rotate(0deg);\n  }\n  100% {\n    transform: rotate(360deg);\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/audioIndex/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-12 13:02:20\n * @Update: 2020-03-14 13:56:09\n * @Update log: 点击歌单中的某一项，将歌单列表信息传入vuex，用来展示歌曲列表，\n *              点击的index 用列表[index]来设置当前要播放的歌曲\n -->\n<template>\n  <div class=\"audioPage\">\n    <div class=\"mask\" v-show=\"isFull\"></div>\n    <div class=\"full pd23\" v-show=\"isFull\">\n      <audio-nav class=\"color\" height=\"0\" @returnPage=\"returnPage\">\n        <div>\n          <p class=\"title\">{{name}}</p>\n          <p class=\"text\">\n            <span class=\"art\" v-for=\"(item, index) in artist\" :key=\"index\">{{item.name}}</span>\n          </p>\n        </div>\n      </audio-nav>\n      <playing :imgUrl=\"imgUrl\" v-show=\"playingShow\" @click.native=\"setPlayingShow(false)\"></playing>\n      <lyric-page\n        :lyricArray=\"ruleLyric\"\n        :nowLyricIndex=\"nowLyricIndex\"\n        ref=\"lyric\"\n        :noLyric=\"noLyric\"\n        :noLyricText=\"noLyricText\"\n        v-show=\"!playingShow\"\n        @click.native=\"setPlayingShow(true)\"\n      ></lyric-page>\n      <play-icons :isLike=\"isLike\" @update_isLike=\"update_isLike\"></play-icons>\n      <bar :allTime=\"allTime\" :time=\"playTime\" :width=\"progressWidth\" @time=\"changeTime\"></bar>\n      <function-button\n        @play=\"toggle\"\n        @prev=\"prevSong\"\n        @next=\"nextSong\"\n        @changeMode=\"changeMode\"\n        :mode=\"mode\"\n        @showAudioList=\"showAudioList\"\n      ></function-button>\n    </div>\n    <small-audio\n      v-show=\"!isFull\"\n      :imgUrl=\"imgUrl\"\n      @returnFull=\"returnFull\"\n      @play=\"toggle\"\n      @changeMode=\"changeMode\"\n      @showAudioList=\"showAudioList\"\n      :name=\"name\"\n      :artist=\"artist\"\n      :mode=\"mode\"\n      :lyric=\"nowLyric\"\n    ></small-audio>\n    <audio-list\n      :isShowAudioList=\"isShowAudioList\"\n      @showAudioList=\"showAudioList\"\n      :num=\"playList.length\"\n      :mode=\"mode\"\n      @changeMode=\"changeMode\"\n    ></audio-list>\n    <audio\n      :src=\"url\"\n      ref=\"audio\"\n      autoplay\n      @canplay=\"ready\"\n      @error=\"error\"\n      preload=\"auto\"\n      @ended=\"end\"\n    ></audio>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport audioNav from 'base/generalNav'\nimport playing from './components/playing'\nimport playIcons from './components/playIcons'\nimport bar from './components/bar'\nimport functionButton from './components/functionButton'\nimport smallAudio from './components/small'\nimport lyricPage from './components/lyricPage'\nimport audioList from './components/audioList'\nimport { mapGetters, mapMutations } from 'vuex'\nexport default {\n  name: '',\n  data () {\n    return {\n      url: '',\n      playTime: '00:00',\n      allTime: 0,\n      progressWidth: 0,\n      artist: [],\n      imgUrl: '',\n      readySong: false,\n      canSong: true,\n      name: '',\n      lyric: '',\n      nowLyric: '',\n      nowLyricIndex: -1,\n      ruleLyric: [],\n      noLyric: false,\n      isShowAudioList: false,\n      noLyricText: '',\n      isLike: false\n    }\n  },\n  computed: {\n    ...mapGetters({ audioSong: 'AUDIO_ING_SONG',\n      state: 'PLAY_STATE',\n      index: 'AUDIO_ING_INDEX',\n      list: 'AUDIO_LIST',\n      isFull: 'FULL_SCREEN',\n      mode: 'MODE',\n      playList: 'PLAY_LIST',\n      offsetLyric: 'OFFSET_LYRIC',\n      playingShow: 'PLAYING_SHOW' })\n  },\n  filters: {\n    setName: function (val) {\n      let reg = /<\\/?.+?\\/?>/g\n      val = val.replace(reg, '')\n      return val\n    }\n  },\n  watch: {\n    /**\n     * 当前歌曲变化，首先查看能不能播放\n     * 将一些歌曲信息设置\n     */\n    audioSong: function (val, oldVal) {\n      // 查看当前播放歌曲是否已喜欢\n      this._getLikeMusicList(val.id)\n      if (val.id === oldVal.id) {\n        return\n      }\n      this.$nextTick(() => {\n        if (val.dj) {\n          this._checkSong(val.mainTrackId)\n        } else {\n          this._checkSong(val.id)\n        }\n        this.allTime = val.duration ? val.duration : val.dt ? val.dt : ''\n        this.artist = val.album ? val.album.artists : val.ar ? val.ar : ''\n        this.imgUrl = val.album\n          ? val.album.picUrl\n          : val.al\n            ? val.al.picUrl\n            : val.album\n              ? val.album.artist.img1v1Url : val.coverUrl ? val.coverUrl : ''\n        this.name = this.setName(val.name)\n      })\n    }\n  },\n  methods: {\n    /**\n     * 去除名字的标签\n     */\n    setName (val) {\n      let reg = /<\\/?.+?\\/?>/g\n      val = val.replace(reg, '')\n      return val\n    },\n    /**\n     * 获取音乐url\n     */\n    _getSongUrl (id) {\n      api.songUrlFn(id)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.url = data.data[0].url\n            this.audioTimeUpdate()\n            this.toPlay()\n          }\n        })\n    },\n    /**\n     * 获取已喜欢的歌曲列表\n     * 得到列表数组后遍历查看当前歌曲是否在已喜欢列表中\n     */\n    _getLikeMusicList (id) {\n      const uid = localStorage.getItem('accountUid')\n      api.likeMusicListFn(uid)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            this.filterAudio(data.ids, id)\n          }\n        })\n    },\n    /**\n     * 判断当前歌曲是否在已喜欢数组中\n     */\n    filterAudio (arr, id) {\n      if (arr.indexOf(id) > -1) {\n        console.log('已喜欢')\n        this.isLike = true\n      } else {\n        console.log('未喜欢')\n        this.isLike = false\n      }\n    },\n    /**\n     * 更新当前歌曲喜欢状态\n     */\n    update_isLike (val) {\n      this.isLike = val\n    },\n    /**\n     * 获取歌曲歌词\n     */\n    _getSongLyric (id) {\n      api.songLyricFn(id)\n        .then(res => {\n          const data = res.data\n          if (data.nolyric) {\n            // 当前歌曲没有歌词\n            this.ruleLyric = []\n            this.nowLyric = ''\n            this.noLyric = true\n            this.noLyricText = '纯音乐，请欣赏'\n            return\n          }\n          this.noLyric = false\n          this.lyric = data.lrc.lyric\n          if (!this.lyric.trim()) {\n            // 歌词为空\n            this.noLyricText = '暂时没有歌词'\n            this.ruleLyric = []\n            this.nowLyric = ''\n            this.noLyric = true\n            return\n          }\n          this.ruleLyric = this.createLrcArray(this.lyric)\n        })\n    },\n    /**\n     * 显示歌曲列表\n     */\n    showAudioList () {\n      console.log('列表信息')\n      this.isShowAudioList = !this.isShowAudioList\n    },\n    /**\n     * 查看歌曲是否可以播放\n     */\n    _checkSong (id) {\n      api.checkSongFn(id)\n        .then(res => {\n          const data = res.data\n          // 当可以播放的时候请求歌曲url\n          if (data.success) {\n            this.canSong = true\n            this._getSongUrl(id)\n            this._getSongLyric(id)\n          }\n        })\n        .catch(err => {\n          if (err) {\n            console.log(err)\n            // 不能播放的时候选择下一首进行播放\n            this.canSong = false\n            this.readySong = true\n            this.nextSong()\n            this.readySong = true\n          }\n        })\n    },\n    /**\n     * 创建歌词数组\n     * 通过换行符分割字符串，形成数组，数组的每一项是一个对象，对象返回格式如下\n     * {time：， word：}\n     * @param {String} lrc 歌词字符串\n     */\n    createLrcArray (lrc) {\n      const parts = lrc.split('\\n')\n      for (let index = 0; index < parts.length; index++) {\n        const element = parts[index]\n        parts[index] = this.changeToObject(element)\n      }\n      return parts\n    },\n    /**\n     * 根据一行歌词 转换为对象\n     * @param {string} str 一行歌词\n     */\n    changeToObject (str) {\n      const words = str.split(']')[1]\n      // 这个正则返回时间信息\n      const reg = /\\w{0,}:\\w{0,}.\\w{0,}/g\n      let timeArray = reg.exec(str)\n      if (!timeArray) {\n        return\n      }\n      timeArray = timeArray[0].split(':')\n      const minute = parseInt(timeArray[0]) // 分钟数\n      const second = parseFloat(timeArray[1]) // 秒数\n      const time = minute * 60 + second\n      return {\n        time,\n        words\n      }\n    },\n    /**\n     * 播放暂停事件\n     */\n    toggle () {\n      if (this.state) {\n        this.toPause()\n      } else {\n        this.toPlay()\n      }\n    },\n    /**\n     * 改变歌曲播放模式\n     */\n    changeMode () {\n      const mode = (this.mode + 1) % 3\n      this.setMode(mode)\n      let shufflePlayList\n      if (mode === 2) {\n        console.log('随机模式')\n        shufflePlayList = this.shuffle(this.list)\n      } else {\n        shufflePlayList = this.list\n      }\n      this.resetCurrentIndex(shufflePlayList)\n      this.setPlayList(shufflePlayList)\n    },\n    /**\n     * 设置当前播放索引\n     * 当在切换随机播放时，通过寻找原来的歌曲id来实现不会切换歌曲index\n     */\n    resetCurrentIndex (list) {\n      const index = list.findIndex(item => {\n        return item.id === this.audioSong.id\n      })\n      this.setIndex(index)\n    },\n    /**\n     * 获取随机值\n     */\n    getRandomIndex (min, max) {\n      return Math.floor(Math.random() * (max - min + 1) + min)\n    },\n    /**\n     * 打乱一个数组\n     */\n    shuffle (arr) {\n      const _arr = arr.slice()\n      for (let i = 0; i < _arr.length; i++) {\n        const j = this.getRandomIndex(0, i)\n        const t = _arr[i]\n        _arr[i] = _arr[j]\n        _arr[j] = t\n      }\n      console.log('_arr: ', _arr)\n      return _arr\n    },\n    /**\n     * 当改变进度条时改变歌曲播放时间\n     */\n    changeTime (time) {\n      const audio = this.$refs.audio\n      const current = time * audio.duration / 100\n      audio.currentTime = current\n    },\n    /**\n     * 上一首歌曲切换\n     */\n    prevSong () {\n      if (!this.readySong) {\n        return\n      }\n      let nowIndex = this.index - 1\n      if (nowIndex === -1) {\n        nowIndex = this.list.length - 1\n      }\n      this.setIndex(nowIndex)\n      this.readySong = false\n    },\n    /**\n     * 下一首歌曲切换\n     */\n    nextSong () {\n      if (!this.readySong) {\n        return\n      }\n      let nowIndex = this.index + 1\n      if (nowIndex === this.list.length) {\n        nowIndex = 0\n      }\n      this.setIndex(nowIndex)\n      this.readySong = false\n    },\n    /**\n     * 播放歌曲\n     */\n    toPlay () {\n      this.$refs.audio.play()\n      this.setState(true)\n    },\n    /**\n     * 暂停歌曲\n     */\n    toPause () {\n      this.$refs.audio.pause()\n      this.setState(false)\n    },\n    /**\n     *  当浏览器可以播放资源时\n     */\n    ready () {\n      this.readySong = true\n    },\n    /**\n     * 当在资源加载期间发生错误时\n     */\n    error () {\n      this.readySong = true\n    },\n    /**\n     * 当歌曲播放完成之后\n     * 根据不同的播放模式进行不同的事件\n     */\n    end () {\n      switch (this.mode) {\n        case 0:\n          this.nextSong()\n          break\n        case 1:\n          this.loop()\n          break\n        case 2:\n          this.nextSong()\n          break\n      }\n    },\n    /**\n     * 单曲循环模式\n     */\n    loop () {\n      this.$refs.audio.currentTime = 0\n      this.toPlay()\n    },\n    /**\n     * 添加歌曲时间更新事件\n     */\n    audioTimeUpdate () {\n      this.$refs.audio.addEventListener('timeupdate', this.setTime)\n    },\n    /**\n     * 设置当前播放时长\n     */\n    setTime () {\n      // 首先我们计算到当前的播放时间\n      const audio = this.$refs.audio\n      let minutes = Math.floor(audio.currentTime / 60)\n      let seconds = Math.floor(audio.currentTime - minutes * 60)\n      let minuteValue\n      let secondValue\n      // 进行格式转换，当分钟小于10的时候，在前面加0\n      if (minutes < 10) {\n        minuteValue = '0' + minutes\n      } else {\n        minuteValue = minutes\n      }\n      // 秒数的格式设置\n      if (seconds < 10) {\n        secondValue = '0' + seconds\n      } else {\n        secondValue = seconds\n      }\n      // 进行时间值拼接，展示到页面\n      let audioTime = minuteValue + ':' + secondValue\n      this.playTime = audioTime\n      // // 进度条的长度计算\n      let barLength = audio.currentTime / audio.duration * 100\n      this.setProgress(barLength)\n      // 设置歌词偏移\n      const playTime = audio.currentTime + this.offsetLyric\n      const index = this.getCurrentIndex(playTime, this.ruleLyric)\n      this.nowLyricIndex = index\n      // 设置歌词显示\n      this.showLyric(index, this.ruleLyric)\n      // 设置歌词页面的显示规则,传入当前歌词索引信息\n      this.$refs.lyric.setCurrent(this.nowLyricIndex)\n    },\n    /**\n     * 获取当前歌词索引\n     */\n    getCurrentIndex (time, lyricArray) {\n      for (let i = lyricArray.length - 2; i >= 0; i--) {\n        const element = lyricArray[i].time\n        if (time > element) {\n          return i\n        }\n        if (!element) {\n          return -1\n        }\n      }\n      return -1\n    },\n    /**\n     * 设置当前歌词显示信息\n     */\n    showLyric (index, array) {\n      if (index !== -1) {\n        const words = array[index].words\n        this.nowLyric = words\n      }\n    },\n    /**\n     * 设置进度条长度\n     */\n    setProgress (val) {\n      if (val < 0 || val > 100) {\n        return\n      }\n      this.progressWidth = val\n    },\n    /**\n     * 转换为小播放器\n     */\n    returnPage () {\n      this.setFull(false)\n    },\n    /**\n     * 转换为大播放器\n     */\n    returnFull () {\n      this.setFull(true)\n    },\n    ...mapMutations({\n      setState: 'SET_PLAY_SATE',\n      setIndex: 'SET_AUDIO_INDEX',\n      setFull: 'SET_FULL_SCREEN',\n      setMode: 'SET_AUDIO_MODE',\n      setPlayList: 'SET_PLAY_LIST',\n      setPlayingShow: 'SET_PLAYING_SHOW' })\n  },\n  components: {\n    audioNav,\n    playing,\n    playIcons,\n    bar,\n    functionButton,\n    smallAudio,\n    lyricPage,\n    audioList\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"//at.alicdn.com/t/font_1410851_orgxdud5s8j.css\");\n@import url(\"~styles/global.less\");\n.full {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  right: 0;\n  z-index: 10;\n  background-color: #7f8c8d;\n  .color {\n    color: #fff;\n  }\n  .title {\n    color: #fff;\n    line-height: 1.5;\n  }\n  .text {\n    font-size: 0.24rem;\n    color: #bdc3c7;\n    .art {\n      &::after {\n        content: \"/\";\n      }\n      &:last-child::after {\n        content: \"\";\n      }\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/commentsIndex/components/albumListInfo.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-27 08:29:46\n * @Update: 2019-10-29 21:38:43\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper pd23\">\n    <div class=\"left-img\">\n      <img :src=\"info.imgUrl + '?param=100y100'\" alt />\n    </div>\n    <div class=\"right-info\">\n      <div class=\"title\">{{info.title}}</div>\n      <div class=\"author\">\n        by\n        <span class=\"name\">{{info.author}}</span>\n      </div>\n    </div>\n    <span class=\"arrow\">\n      <i class=\"comment commenticon-copy\"></i>\n    </span>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: '',\n  props: {\n    info: {\n      type: Object\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.wrapper {\n  height: 1.8rem;\n  display: flex;\n  align-items: center;\n  .left-img {\n    width: 1.5rem;\n    height: 0;\n    padding-bottom: 1.5rem;\n    margin-right: 0.3rem;\n    img {\n      width: 1.5rem;\n      height: 1.5rem;\n      border-radius: 0.1rem;\n    }\n  }\n  .right-info {\n    flex: 1;\n    display: flex;\n    flex-direction: column;\n    .title {\n      .twoLinesEllipsis();\n      font-size: 0.3rem;\n      line-height: 1.5;\n    }\n    .author {\n      font-size: 0.24rem;\n      line-height: 1.5;\n      .name {\n        color: #328ffe;\n      }\n    }\n  }\n  .arrow {\n    margin-left: 0.3rem;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/commentsIndex/components/centerMenu.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-11-09 08:32:08\n * @Update: 2019-11-09 09:32:15\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"container\" v-show=\"_isShow\">\n    <div class=\"mask\" @click=\"hideCon\"></div>\n    <ul class=\"list-wra\">\n      <li class=\"list-item\">回复评论</li>\n      <li class=\"list-item\">分享评论</li>\n      <li class=\"list-item\">复制评论</li>\n      <li class=\"list-item\" v-if=\"!user\">举报评论</li>\n      <li class=\"list-item\" v-if=\"user\" @click=\"delCom\">删除评论</li>\n    </ul>\n  </div>\n</template>\n\n<script>\nimport Bus from '@/assets/Bus'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      user: false,\n      comId: 0\n    }\n  },\n  props: {\n    isShow: {\n      type: Boolean\n    }\n  },\n  created () {\n    Bus.$on('user', content => {\n      this.user = content\n    })\n    Bus.$on('comId', content => {\n      this.comId = content\n    })\n  },\n  computed: {\n    _isShow: {\n      get () {\n        return this.isShow\n      },\n      set (val) {\n        this.$emit('update:show', val)\n      }\n    }\n  },\n  methods: {\n    hideCon () {\n      this._isShow = false\n    },\n    delCom () {\n      this.$emit('delCom', this.comId)\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.container {\n  position: fixed;\n  top: 0;\n  z-index: 2;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  width: 100vw;\n  height: 100vh;\n}\n// 这里给ul设置border-radius无效\n// 所以通过给第一个li元素和最后一个元素设置圆角，形成对应的形状\n.list-wra {\n  width: 6rem;\n  height: auto;\n  background: maroon;\n  position: absolute;\n  left: 50%;\n  top: 50%;\n  transform: translate(-50%, -50%);\n  border-radius: 0.2rem;\n  z-index: 11;\n  .list-item {\n    display: flex;\n    align-items: center;\n    width: 100%;\n    height: 0.8rem;\n    box-sizing: border-box;\n    padding: 0.2rem;\n    background-color: #fff;\n    &:first-child {\n      border-top-left-radius: 0.2rem;\n      border-top-right-radius: 0.2rem;\n    }\n    &:last-child {\n      border-bottom-left-radius: 0.2rem;\n      border-bottom-right-radius: 0.2rem;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/commentsIndex/index.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-27 07:48:55\n * @Update: 2019-11-12 19:35:25\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\">\n    <general-nav @returnPage=\"returnPage\" class=\"titleFixed\">\n      <!-- 通过改变 listFixed 来控制 title 的显示与否-->\n      <span class=\"text\">评论({{total}})</span>\n    </general-nav>\n    <album-list :info=\"albumInfo\"></album-list>\n    <div class=\"split\"></div>\n    <page-loading v-show=\"load\"></page-loading>\n    <comments\n      v-show=\"!load && hotComments.length\"\n      title=\"精彩评论\"\n      :comments=\"hotComments\"\n      class=\"pd23\"\n      @showMenu=\"showMenu\"\n      @likeComment=\"likeComment\"\n    ></comments>\n    <comments\n      v-show=\"!load && comments.length\"\n      title=\"最新评论\"\n      :comments=\"comments\"\n      :total=\"total\"\n      class=\"pd23\"\n      @showMenu=\"showMenu\"\n      @likeComment=\"likeComment\"\n    ></comments>\n    <div class=\"pb1\"></div>\n    <van-search\n      class=\"border-top commentInp\"\n      v-model=\"input\"\n      :placeholder=\"placeholder\"\n      show-action\n      :clearable=\"false\"\n      background=\"#fff\"\n      left-icon\n      @search=\"pushCom(input)\"\n    >\n      <div slot=\"action\" :class=\"{disable: !input}\" @click=\"pushCom(input)\">发送</div>\n    </van-search>\n    <center-menu @update:show=\"updateShow\" @delCom=\"delCom\" :isShow=\"isShow\"></center-menu>\n  </div>\n</template>\n\n<script>\nimport { Toast } from 'vant'\nimport generalNav from 'base/generalNav'\nimport pageLoading from 'base/pageLoading'\nimport albumList from './components/albumListInfo'\nimport comments from 'base/comments'\nimport centerMenu from './components/centerMenu'\nimport api from 'api'\nexport default {\n  name: '',\n  data () {\n    return {\n      total: 0,\n      isShow: false,\n      hotComments: [],\n      comments: [],\n      load: true,\n      albumInfo: {\n        author: '',\n        imgUrl: '',\n        title: ''\n      },\n      input: '',\n      placeholder: ''\n    }\n  },\n  activated () {\n    this.load = true\n    this.params = this.$route.params\n    const params = this.params\n    if (Object.keys(params).length === 0) {\n      this.$router.back()\n    }\n    /**\n     * 获取到歌单信息\n     */\n    this.albumInfo = { ...params }\n    /**\n     * 判断当前资源是歌单还是专辑\n     */\n    if (params.playlistId) {\n      // 歌单\n      this.type = 2\n      this.id = params.playlistId\n      this._getPlaylistComments(this.id)\n      return\n    }\n    if (params.albumId) {\n      // 专辑\n      this.type = 3\n      this.id = params.albumId\n      this._getAlbumComments(this.id)\n      return\n    }\n    if (params.djId) {\n      // 专辑\n      this.type = 4\n      this.id = params.djId\n      this._getDjComments(this.id)\n    }\n  },\n  methods: {\n    /**\n     * 评论内容\n     */\n    pushCom (content) {\n      if (!content) {\n        Toast({\n          position: 'bottom',\n          message: '评论为空'\n        })\n        return\n      }\n      Toast.allowMultiple()\n      let loadingToast = Toast.loading({\n        forbidClick: true,\n        duration: 1000\n      })\n      const params = this.params\n      const id = params.playlistId || params.albumId || params.djId\n      const type = params.playlistId ? 2 : params.albumId ? 3 : params.djId ? 4 : ''\n      api.pushComFn(type, id, content)\n        .then(res => {\n          const { data } = res\n          console.log(data)\n          if (data.code === 200) {\n            this.input = ''\n            loadingToast.clear()\n            Toast({\n              position: 'bottom',\n              message: '发表成功'\n            })\n            this.pushComInCon(params)\n          }\n        })\n        .catch(err => {\n          if (err) {\n            loadingToast.clear()\n            Toast(err.msg || '发表失败')\n          }\n        })\n    },\n    delCom (comId) {\n      const params = this.params\n      const id = params.playlistId || params.albumId || params.djId\n      const type = params.playlistId ? 2 : params.albumId ? 3 : params.djId ? 4 : ''\n      api.delComFn(type, id, comId)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            // 删除成功\n            this.hideMenu()\n            this.pushComInCon(params)\n          }\n        }).catch(err => {\n          if (err) {\n            Toast(err.msg || '删除失败')\n          }\n        })\n    },\n    /**\n     * 获取歌单评论\n     */\n    _getPlaylistComments (id) {\n      api.commentPlaylistFn(id)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            this.getOver(data)\n          }\n        })\n    },\n    /**\n      获取电台节目评论\n     */\n    _getDjComments (id) {\n      api.commentDjFn(id)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            this.getOver(data)\n          }\n        })\n    },\n    /**\n     * 获取专辑评论\n     */\n    _getAlbumComments (id) {\n      api.commentAlbumFn(id)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            this.getOver(data)\n          }\n        })\n    },\n    /**\n     * 通过传入的params判断应该使用哪个方法进行再请求\n     */\n    pushComInCon (params) {\n      if (params.playlistId) {\n        this._getPlaylistComments(this.id)\n      } else if (params.albumId) {\n        this._getAlbumComments(this.id)\n      } else if (params.djId) {\n        this._getDjComments(this.id)\n      }\n    },\n    /**\n     * 获取评论结束后\n     * 存下total信息\n     * 存下热门评论和最新评论信息\n     * loading 关闭\n     */\n    getOver (data) {\n      this.total = data.total\n      this.hotComments = data.hotComments\n      this.comments = data.comments\n      this.load = false\n    },\n    /**\n     * 喜欢，点赞该评论\n     */\n    likeComment (cid, like) {\n      const params = this.params\n      const id = params.playlistId || params.albumId || params.djId\n      const type = params.playlistId ? 2 : params.albumId ? 3 : params.djId ? 4 : ''\n      api.commentLikeFn(id, cid, like, type)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            this.pushComInCon(params)\n          }\n        }).catch(err => {\n          if (err) {\n            console.log(err)\n            Toast(err.msg || '点赞失败')\n          }\n        })\n    },\n    /**\n     * 显示回复评论，\n     * 如果是自己的评论显示删除评论\n     */\n    showMenu () {\n      this.isShow = true\n    },\n    /**\n     * 隐藏\n     */\n    hideMenu () {\n      this.isShow = false\n    },\n    updateShow (val) {\n      this.isShow = val\n    },\n    returnPage () {\n      this.$router.go(-1)\n    }\n  },\n  components: {\n    generalNav,\n    albumList,\n    comments,\n    pageLoading,\n    centerMenu\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.wrapper {\n  .text {\n    font-size: 0.4rem;\n  }\n  .commentInp {\n    position: fixed;\n    bottom: 0;\n    left: 0;\n    right: 0;\n    z-index: 1;\n    .disable {\n      color: #ccc;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/dateRecommend/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-06 11:33:42\n * @Update: 2019-11-25 15:43:52\n * @Update log: 更新日志\n -->\n<template>\n  <song-list-page\n    title=\"每日推荐\"\n    :load=\"load\"\n    :isAlbum=\"false\"\n    height=\"3.6rem\"\n    @startPlayAll=\"startPlay\"\n  >\n    <song-list\n      v-for=\"(item, index) in songLists\"\n      :key=\"index\"\n      :songName=\"item.name\"\n      :artists=\"item.artists\"\n      :albumName=\"item.album.name\"\n      :imgUrl=\"item.album.picUrl\"\n      @beginSong=\"setAudioList(item, index)\"\n      :nowSong=\"item.id === audioSong.id\"\n    ></song-list>\n    <should-login v-show=\"isLogin === 0\"></should-login>\n  </song-list-page>\n</template>\n\n<script>\nimport api from 'api'\nimport songList from 'base/song'\nimport songListPage from 'base/songListPage'\nimport shouldLogin from 'base/shouldLogin'\nimport { mapActions, mapGetters } from 'vuex'\nexport default {\n  name: '',\n  data () {\n    return {\n      songLists: [],\n      load: '',\n      isLogin: +localStorage.getItem('loginState') || 0\n    }\n  },\n  created () {\n    this._getRecSongs()\n  },\n  computed: {\n    ...mapGetters({ audioSong: 'AUDIO_ING_SONG' })\n  },\n  methods: {\n    _getRecSongs () {\n      if (this.isLogin !== 0) {\n        api.recSongsFn()\n          .then(res => {\n            const data = res.data\n            if (data.code === 200) {\n              this.songLists = data.recommend\n              this.load = false\n            }\n          })\n          .catch(err => {\n            if (err) {\n              this.load = false\n            }\n          })\n      } else {\n        this.load = false\n      }\n    },\n    startPlay () {\n      this.startPlayAll({\n        list: this.songLists\n      })\n    },\n    setAudioList (item, index) {\n      this.selectPlay({\n        list: this.songLists,\n        index\n      })\n    },\n    ...mapActions(['selectPlay', 'startPlayAll'])\n  },\n  components: {\n    songList,\n    songListPage,\n    shouldLogin\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/dj/childrenPage/class.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-13 10:32:53\n * @Update: 2019-10-26 08:18:44\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper pd23\">\n    <general-nav @returnPage=\"returnPage\">\n      <span class=\"text\">电台分类</span>\n    </general-nav>\n    <page-loading v-show=\"load\"></page-loading>\n    <div v-show=\"!load\">\n      <class-ification title=\"热门分类\" :data=\"hotClass\" type=\"class\"></class-ification>\n      <class-ification title=\"更多分类\" :data=\"moreClass\" type=\"class\"></class-ification>\n    </div>\n  </div>\n</template>\n\n<script>\nimport classIfication from '../publicClass'\nimport generalNav from 'base/generalNav'\nimport pageLoading from 'base/pageLoading'\n\nimport api from 'api'\nexport default {\n  name: '',\n  data () {\n    return {\n      hotClass: [],\n      moreClass: [],\n      load: true\n    }\n  },\n  created () {\n    this._getDjClass()\n  },\n  methods: {\n    /**\n     * 获取电台分类\n     */\n    _getDjClass () {\n      api.djClassificationFn()\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            const categories = data.categories\n            this.jsonTarget = this.getJsonData(categories)\n            this.hotClass = this.jsonTarget.slice(0, 6)\n            this.moreClass = this.jsonTarget.slice(6)\n            this.load = false\n          }\n        })\n    },\n    /**\n     * 获取json数据中的id，name，img信息\n     * 返回一个数组\n     */\n    getJsonData (data) {\n      let jsonTarget = []\n      data.map((item) => {\n        jsonTarget.push({\n          id: item.id,\n          name: item.name,\n          imgUrl: item.pic56x56Url\n        })\n      })\n      return jsonTarget\n    },\n    returnPage () {\n      this.$router.go(-1)\n    }\n  },\n  components: {\n    classIfication,\n    generalNav,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.wrapper {\n  .text {\n    font-size: 0.4rem;\n    vertical-align: 5px;\n    width: 8rem;\n    .ellipsis();\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/dj/childrenPage/classRecommend.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-12-07 13:04:21\n * @Update: 2019-12-08 12:58:10\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"pd23\">\n    <dj-top-con-detail class=\"titleFixed\" @returnPage=\"returnPage\">\n      <span class=\"text\">{{title}}</span>\n    </dj-top-con-detail>\n    <div v-show=\"!loading\">\n      <public-con :data=\"data\"></public-con>\n    </div>\n    <page-loading v-show=\"loading\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport djTopConDetail from 'base/generalNav'\nimport publicCon from '../public'\nimport { filterSetMonth } from 'utils/filters'\nimport pageLoading from 'base/pageLoading'\n\nimport api from 'api'\nexport default {\n  name: '',\n  data () {\n    return {\n      data: [],\n      title: '',\n      loading: true\n    }\n  },\n  filters: {\n    setTime: val => (filterSetMonth(val))\n  },\n  activated () {\n    this.pageId = this.$route.params.id\n    this.title = this.$route.params.title\n    this._getClassRecommend(this.pageId)\n  },\n  methods: {\n    async _getClassRecommend (id) {\n      const { data: { code, djRadios } } = await api.djClassificationInfoFn(id)\n      if (code === 200) {\n        this.data = djRadios\n        this.loading = false\n      }\n    },\n    returnPage () {\n      this.$router.go(-1)\n    }\n  },\n  deactivated () {\n    this.pageId = ''\n    this.data = []\n    this.title = ''\n    this.loading = true\n  },\n  components: {\n    djTopConDetail,\n    publicCon,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.text {\n  font-size: 0.4rem;\n  vertical-align: 5px;\n}\n.update {\n  margin: 0.3rem 0;\n  font-size: 0.24rem;\n  font-weight: 600;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/dj/childrenPage/djPayGift.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-13 10:59:26\n * @Update: 2019-10-18 11:19:53\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper pd23\">\n    <general-nav @returnPage=\"returnPage\">\n      <span class=\"text\">付费精品</span>\n    </general-nav>\n    <div v-show=\"!loading\">\n      <div class=\"card\" v-for=\"(item, index) in djPayGiftData\" :key=\"index\">\n        <div class=\"img-info\">\n          <img :src=\"item.picUrl + '?param=200y200'\" alt />\n        </div>\n        <div class=\"content\">\n          <h1 class=\"name\">{{item.name}}</h1>\n          <div class=\"detail\">\n            <p class=\"dec-text\">{{item.rcmdText}}</p>\n            <p class=\"new\">最新上架</p>\n          </div>\n          <p class=\"price\">￥ {{item.originalPrice | price}}</p>\n        </div>\n      </div>\n    </div>\n    <page-loading v-show=\"loading\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport generalNav from 'base/generalNav'\nimport pageLoading from 'base/pageLoading'\n\nimport api from 'api'\nexport default {\n  name: '',\n  data () {\n    return {\n      djPayGiftData: [],\n      loading: true\n    }\n  },\n  filters: {\n    price: function (val) {\n      if (val) {\n        return parseInt(val / 100)\n      }\n    }\n  },\n  created () {\n    this._getDjPayGiftInfo()\n  },\n  methods: {\n    _getDjPayGiftInfo (limit, offset) {\n      api.djPayGiftFn(limit, offset)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            this.djPayGiftData = data.data.list\n            this.loading = false\n          }\n        })\n    },\n    returnPage () {\n      this.$router.go(-1)\n    }\n  },\n  components: {\n    generalNav,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n\n.wrapper {\n  .text {\n    font-size: 0.4rem;\n    vertical-align: 5px;\n    width: 8rem;\n    .ellipsis();\n  }\n  .card {\n    height: 2rem;\n    margin: 0.2rem 0;\n    display: flex;\n    .img-info {\n      width: 2rem;\n      height: 0;\n      padding-bottom: 2rem;\n      margin-right: 0.2rem;\n      img {\n        border-radius: @imgBorderRadius;\n        width: 2rem;\n        height: 2rem;\n      }\n    }\n    .content {\n      width: 4.7rem;\n      display: flex;\n      flex-direction: column;\n      justify-content: center;\n      .name {\n        font-weight: 700;\n        .ellipsis();\n      }\n      .detail {\n        color: #aaa;\n        font-size: 0.24rem;\n        margin: 0.2rem 0;\n        line-height: 1.5;\n        .dec-text {\n          .ellipsis();\n        }\n      }\n      .price {\n        color: @bgcolor;\n      }\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/dj/childrenPage/ranking-anchor.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-17 13:04:41\n * @Update: 2019-12-07 13:27:46\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"pd23\">\n    <div v-show=\"!loading\">\n      <top-con type=\"circle\" title=\"24小时榜\" :data=\"djTopListHours\" pageId=\"anchorHours\"></top-con>\n      <div class=\"split\"></div>\n      <top-con title=\"新人榜\" type=\"circle\" :data=\"djTopListNewComers\" pageId=\"newcomer\"></top-con>\n      <div class=\"split\"></div>\n      <public-con\n        title=\"最热主播\"\n        :data=\"djToplistPopular\"\n        type=\"rank\"\n        content=\"popular\"\n        :hotRank=\"true\"\n      ></public-con>\n    </div>\n    <page-loading v-show=\"loading\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport publicCon from '../public'\nimport topCon from '../titleAndThree'\nimport api from 'api'\nimport pageLoading from 'base/pageLoading'\nexport default {\n  name: '',\n  data () {\n    return {\n      djTopListHours: [],\n      djTopListNewComers: [],\n      djToplistPopular: [],\n      loading: true\n    }\n  },\n  async created () {\n    await this._getDjToplistHours()\n    await this._getDjToplistNewComers()\n    await this._getDjToplistPopular()\n  },\n  methods: {\n    async _getDjToplistHours () {\n      const { data } = await api.djToplistHoursFn(3)\n      if (data.code === 200) {\n        this.djTopListHours = data.data.list\n      }\n    },\n    async _getDjToplistNewComers () {\n      const { data } = await api.djToplistNewComersFn(3)\n      if (data.code === 200) {\n        this.djTopListNewComers = data.data.list\n      }\n    },\n    async _getDjToplistPopular () {\n      const { data } = await api.djToplistPopularsFn()\n      if (data.code === 200) {\n        this.djToplistPopular = data.data.list\n        this.loading = false\n      }\n    }\n  },\n  components: {\n    publicCon,\n    pageLoading,\n    topCon\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/dj/childrenPage/ranking-program.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-17 13:04:59\n * @Update: 2019-12-03 18:38:16\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"pd23\">\n    <div v-show=\"!loading\">\n      <top-con title=\"24小时榜\" :data=\"topData\" pageId=\"programHours\"></top-con>\n      <div class=\"split\"></div>\n      <public-con title=\"最热节目\" :data=\"djToplist\" type=\"rank\"></public-con>\n    </div>\n    <page-loading v-show=\"loading\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport publicCon from '../public'\nimport topCon from '../titleAndThree'\nimport api from 'api'\nimport pageLoading from 'base/pageLoading'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      djToplist: [],\n      loading: true,\n      topData: []\n    }\n  },\n  async created () {\n    await this._getDjProgramTopHours()\n    await this._getDjToplist()\n  },\n  methods: {\n    async _getDjToplist () {\n      let limit, offset\n      const { data } = await api.djToplistFn(limit, offset)\n      if (data.code === 200) {\n        this.djToplist = data.toplist\n        this.loading = false\n      }\n    },\n    async _getDjProgramTopHours () {\n      const { data } = await api.djProgramTopHoursFn(3)\n      if (data.code === 200) {\n        this.topData = data.data.list\n      }\n    }\n  },\n  components: {\n    publicCon,\n    pageLoading,\n    topCon\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/dj/childrenPage/ranking-radio.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-17 13:05:15\n * @Update: 2019-12-07 13:18:14\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"pd23\">\n    <div v-show=\"!loading\">\n      <top-con title=\"付费精品榜\" :data=\"djTopListPay\" pageId=\"pay\"></top-con>\n      <div class=\"split\"></div>\n      <public-con title=\"最热电台\" :data=\"djToplist\" type=\"rank\" :hotRank=\"true\"></public-con>\n    </div>\n    <page-loading v-show=\"loading\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport publicCon from '../public'\nimport topCon from '../titleAndThree'\nimport api from 'api'\nimport pageLoading from 'base/pageLoading'\nexport default {\n  name: '',\n  data () {\n    return {\n      djToplist: [],\n      djTopListPay: [],\n      loading: true\n    }\n  },\n  async created () {\n    await this._getDjTopListPay()\n    await this._getDjHotToplist()\n  },\n  methods: {\n    async _getDjHotToplist () {\n      let limit, offset, type\n      const { data } = await api.djHotToplistFn(limit, offset, type)\n      if (data.code === 200) {\n        this.djToplist = data.toplist\n        this.loading = false\n      }\n    },\n    async _getDjTopListPay () {\n      const { data } = await api.djToplistPaysFn(3)\n      if (data.code === 200) {\n        this.djTopListPay = data.data.list\n      }\n    }\n  },\n  components: {\n    publicCon,\n    pageLoading,\n    topCon\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/dj/childrenPage/ranking.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-17 12:44:36\n * @Update: 2019-10-26 08:16:59\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\">\n    <div class=\"titleFixed\">\n      <dj-ranking class=\"pd23\" @returnPage=\"returnPage\">\n        <span class=\"text\">主播电台排行榜</span>\n      </dj-ranking>\n      <slider-nav :list=\"list\" minWidth=\"1.7rem\"></slider-nav>\n    </div>\n    <keep-alive>\n      <router-view></router-view>\n    </keep-alive>\n  </div>\n</template>\n\n<script>\nimport djRanking from 'base/generalNav'\nimport sliderNav from 'base/sliderNav'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      list: [{\n        path: `/anchor`,\n        text: `主播榜`\n      }, {\n        path: `/program`,\n        text: `节目榜`\n      }, {\n        path: `/radio`,\n        text: `电台榜`\n      }]\n    }\n  },\n  methods: {\n    returnPage () {\n      this.$router.go(-1)\n    }\n  },\n  components: {\n    djRanking,\n    sliderNav\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.wrapper {\n  .text {\n    font-size: 0.4rem;\n    vertical-align: 5px;\n    width: 8rem;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/dj/childrenPage/topConDetail.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-12-07 13:04:21\n * @Update: 2019-12-07 14:01:20\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"pd23\">\n    <dj-top-con-detail class=\"titleFixed\" @returnPage=\"returnPage\">\n      <span class=\"text\">{{title}}</span>\n    </dj-top-con-detail>\n    <div v-show=\"!loading\">\n      <h1 class=\"update\">更新时间: {{updateTime | setTime}}</h1>\n      <public-con :data=\"data\" type=\"rank\" :hotRank=\"hotRank\" :content=\"content\" :noImg=\"noImg\"></public-con>\n    </div>\n    <page-loading v-show=\"loading\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport djTopConDetail from 'base/generalNav'\nimport publicCon from '../public'\nimport { filterSetMonth } from 'utils/filters'\nimport pageLoading from 'base/pageLoading'\n\nimport api from 'api'\nexport default {\n  name: '',\n  data () {\n    return {\n      data: [],\n      hotRank: false,\n      title: '',\n      updateTime: 0,\n      content: '',\n      noImg: true,\n      loading: true\n    }\n  },\n  filters: {\n    setTime: val => (filterSetMonth(val))\n  },\n  activated () {\n    this.pageId = this.$route.params.id\n    this.switchFunction(this.pageId)\n  },\n  methods: {\n    switchFunction (id) {\n      switch (id) {\n        case 'anchorHours':\n          this.title = '24小时榜'\n          this.content = 'popular'\n          this.hotRank = true\n          this._getDjToplistHours()\n          break\n        case 'newcomer':\n          this.title = '新人榜'\n          this.content = 'popular'\n          this.hotRank = true\n          this._getDjToplistNewComers()\n          break\n        case 'pay':\n          this.title = '付费精品榜'\n          this.hotRank = true\n          this.noImg = false\n          this._getDjTopListPay()\n          break\n        case 'programHours':\n          this.title = '24小时新人榜'\n          this._getDjProgramTopHours()\n          break\n        default: this.returnPage()\n          break\n      }\n    },\n    async _getDjToplistHours () {\n      const { data } = await api.djToplistHoursFn()\n      if (data.code === 200) {\n        this.updateTime = data.data.updateTime\n        this.data = data.data.list\n        this.loading = false\n      }\n    },\n    async _getDjToplistNewComers () {\n      const { data } = await api.djToplistNewComersFn()\n      if (data.code === 200) {\n        this.updateTime = data.data.updateTime\n        this.data = data.data.list\n        this.loading = false\n      }\n    },\n    async _getDjProgramTopHours () {\n      const { data } = await api.djProgramTopHoursFn()\n      if (data.code === 200) {\n        this.data = data.data.list\n        this.updateTime = data.data.updateTime\n        this.loading = false\n      }\n    },\n    async _getDjTopListPay () {\n      const { data } = await api.djToplistPaysFn()\n      if (data.code === 200) {\n        this.data = data.data.list\n        this.updateTime = data.data.updateTime\n        this.loading = false\n      }\n    },\n    returnPage () {\n      this.$router.go(-1)\n    }\n  },\n  deactivated () {\n    this.pageId = ''\n    this.title = ''\n    this.data = []\n    this.updateTime = 1546300800000\n    this.content = ''\n    this.hotRank = false\n    this.noImg = true\n    this.loading = true\n  },\n  components: {\n    djTopConDetail,\n    publicCon,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.text {\n  font-size: 0.4rem;\n  vertical-align: 5px;\n}\n.update {\n  margin: 0.3rem 0;\n  font-size: 0.24rem;\n  font-weight: 600;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/dj/components/boutiqueRecom.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-11 13:11:46\n * @Update: 2019-12-10 18:59:09\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\">\n    <div class=\"title\">\n      <h1 class=\"text\">精品推荐</h1>\n      <span class=\"smallTag\" @click=\"goPage\">全部精品</span>\n    </div>\n    <div class=\"img-col\">\n      <img-card\n        v-for=\"(item, index) in boutiqueRecomList\"\n        :key=\"index\"\n        type=\"dj\"\n        :name=\"item.name\"\n        :imgUrl=\"item.picUrl\"\n        :dec=\"item.rcmdText\"\n        :ridId=\"item.id\"\n      ></img-card>\n    </div>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport imgCard from 'base/imgCard'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      boutiqueRecomList: []\n    }\n  },\n  created () {\n    this._getBoutiqueRecom()\n  },\n  methods: {\n    _getBoutiqueRecom () {\n      api.boutiqueRecomFn()\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.boutiqueRecomList = data.data.list\n          }\n        })\n    },\n    goPage () {\n      this.$router.push('/pay_fine')\n    }\n  },\n  components: {\n    imgCard\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.wrapper {\n  margin-top: 0.5rem;\n  .title {\n    .flex-between();\n    align-items: center;\n    .text {\n      font-weight: 700;\n    }\n  }\n  .img-col {\n    .flex-between();\n    flex-wrap: wrap;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/dj/components/icons.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-10-11 13:10:20\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"container border-bottom\">\n    <icon\n      v-for=\"(item, index) in djIcons\"\n      :icons=\"item\"\n      :bgcolor=\"true\"\n      :key=\"index\"\n      @goPage=\"goPage(item.linkTo)\"\n    ></icon>\n  </div>\n</template>\n\n<script>\nimport { djIcons } from 'getInfos/getData'\nimport icon from 'base/icon'\n\nexport default {\n  name: 'findIcon',\n  data () {\n    return {\n      djIcons\n    }\n  },\n  components: {\n    icon\n  },\n  mounted () {\n    this.iniData()\n  },\n  methods: {\n    iniData () {\n      this.djIcons = djIcons()\n    },\n    goPage (link) {\n      this.$router.push(link)\n    }\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url(\"~styles/global.less\");\n\n.container {\n  .flex-around();\n  width: 100%;\n  height: 1.6rem;\n  align-items: center;\n  padding: 0.2rem 0 0.3rem;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/dj/components/radioRecom.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-11 13:11:46\n * @Update: 2019-10-13 12:07:08\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\">\n    <div class=\"title\">\n      <h1 class=\"text\">电台推荐</h1>\n    </div>\n    <div class=\"img-col\">\n      <img-card\n        v-for=\"(item, index) in radioRecomList\"\n        :key=\"index\"\n        type=\"dj\"\n        :name=\"item.name\"\n        :imgUrl=\"item.picUrl\"\n        :dec=\"item.rcmdText\"\n        :ridId=\"item.id\"\n      ></img-card>\n    </div>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport imgCard from 'base/imgCard'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      radioRecomList: []\n    }\n  },\n  created () {\n    this._getRadioRecom()\n  },\n  methods: {\n    _getRadioRecom () {\n      api.radioRecomFn()\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.radioRecomList = data.data\n          }\n        })\n    }\n  },\n  components: {\n    imgCard\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.wrapper {\n  margin-top: 0.5rem;\n  .title {\n    .flex-between();\n    align-items: center;\n    .text {\n      font-weight: 700;\n    }\n  }\n  .img-col {\n    .flex-between();\n    flex-wrap: wrap;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/dj/components/swiper.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-11-03 12:07:07\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"banner-container\">\n    <van-swipe :autoplay=\"5000\" indicator-color=\"#dd001b\">\n      <van-swipe-item v-for=\"(item, index) in swiperList\" :key=\"index\">\n        <img class=\"banner-img\" :src=\"item.pic\" alt />\n        <span class=\"title\">{{item.typeTitle}}</span>\n      </van-swipe-item>\n    </van-swipe>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\n\nexport default {\n  name: 'findSwiper',\n  data () {\n    return {\n      // //存放图片组信息\n      swiperList: []\n    }\n  },\n  methods: {\n    _getDjBanner () {\n      api.djBannerFn()\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            this.swiperList = data.data\n          }\n        })\n    }\n  },\n  mounted () {\n    this._getDjBanner()\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url(\"~styles/global.less\");\n\n.banner-container {\n  box-sizing: border-box;\n  overflow: hidden;\n  padding: 0.2rem;\n  width: 100%;\n  height: 0;\n  padding-bottom: 40%;\n  .banner-img {\n    border-radius: @imgBorderRadius;\n    width: 100%;\n    height: 100%;\n  }\n  .title {\n    position: absolute;\n    right: 0;\n    bottom: 0;\n    color: #fff;\n    font-size: smaller;\n    padding: 3px 6px;\n    opacity: 0.8;\n    border-top-left-radius: @imgBorderRadius;\n    background-color: @bgcolor;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/dj/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-06 11:39:29\n * @Update: 2019-10-24 08:41:43\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper pd23\">\n    <dj-nav @returnPage=\"returnPage\" class=\"titleFixed\">\n      <span class=\"text\">电台</span>\n    </dj-nav>\n    <swiper></swiper>\n    <icons></icons>\n    <radio-recom></radio-recom>\n    <boutique-recom></boutique-recom>\n    <div v-show=\"!load\">\n      <public-con title=\"创作|翻唱\" :data=\"createData.slice(0,4)\"></public-con>\n      <public-img-wrap title=\"有声书\" :data=\"soundBookData.slice(0,3)\"></public-img-wrap>\n      <public-con title=\"情感调频\" :data=\"emotionData.slice(0,4)\"></public-con>\n      <public-img-wrap title=\"广播剧\" :data=\"broadcastingData.slice(0,3)\"></public-img-wrap>\n      <public-con title=\"音乐故事\" :data=\"musicData.slice(0,4)\"></public-con>\n      <public-img-wrap title=\"娱乐|影视\" :data=\"entertainmentData.slice(0,3)\"></public-img-wrap>\n      <public-con title=\"3D|电子\" :data=\"electronicData.slice(0,4)\"></public-con>\n      <public-img-wrap title=\"美文读物\" :data=\"mevinData.slice(0,3)\"></public-img-wrap>\n      <public-con title=\"二次元\" :data=\"secondaryData.slice(0,4)\"></public-con>\n      <public-img-wrap title=\"脱口秀\" :data=\"talkData.slice(0,3)\"></public-img-wrap>\n      <public-img-wrap title=\"知识技能\" :data=\"knowledgeData.slice(0,3)\"></public-img-wrap>\n      <public-img-wrap title=\"商业财经\" :data=\"businessData.slice(0,3)\"></public-img-wrap>\n      <public-img-wrap title=\"人文历史\" :data=\"historyData.slice(0,3)\"></public-img-wrap>\n      <public-img-wrap title=\"外文世界\" :data=\"englishData.slice(0,3)\"></public-img-wrap>\n      <public-img-wrap title=\"亲子宝贝\" :data=\"babyData.slice(0,3)\"></public-img-wrap>\n      <public-img-wrap title=\"相声曲艺\" :data=\"crosstalkData.slice(0,3)\"></public-img-wrap>\n      <public-img-wrap title=\"旅途|城市\" :data=\"journeyData.slice(0,3)\"></public-img-wrap>\n      <public-class title=\"热门分类\" :data=\"hotClass\"></public-class>\n      <public-class title=\"更多分类\" :data=\"moreClass\"></public-class>\n    </div>\n    <page-loading v-show=\"load\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport djNav from 'base/generalNav'\nimport swiper from './components/swiper'\nimport icons from './components/icons'\nimport radioRecom from './components/radioRecom'\nimport boutiqueRecom from './components/boutiqueRecom'\nimport publicCon from './public'\nimport publicImgWrap from './publicImgWrap'\nimport publicClass from './publicClass'\nimport pageLoading from 'base/pageLoading'\n\nimport api from 'api'\nexport default {\n  name: '',\n  data () {\n    return {\n      load: true,\n      jsonTarget: [],\n      hotClass: [],\n      moreClass: [],\n      // 创作|翻唱\n      createData: [],\n      // 有声书\n      soundBookData: [],\n      // 情感调频\n      emotionData: [],\n      // 广播剧\n      broadcastingData: [],\n      // 音乐故事\n      musicData: [],\n      // 娱乐影视\n      entertainmentData: [],\n      // 3d电子\n      electronicData: [],\n      // 美文读物\n      mevinData: [],\n      // 二次元\n      secondaryData: [],\n      // 脱口秀\n      talkData: [],\n      // 知识技能\n      knowledgeData: [],\n      // 商业经济\n      businessData: [],\n      // 人文历史\n      historyData: [],\n      // 外语世界\n      englishData: [],\n      // 亲子宝贝\n      babyData: [],\n      // 相声曲艺\n      crosstalkData: [],\n      // 旅途城市\n      journeyData: []\n    }\n  },\n  created () {\n    this._getDjClass()\n  },\n  methods: {\n    /**\n     * 获取电台分类\n     */\n    _getDjClass () {\n      api.djClassificationFn()\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            const categories = data.categories\n            this.jsonTarget = this.getJsonData(categories)\n            this.hotClass = this.jsonTarget.slice(0, 6)\n            this.moreClass = this.jsonTarget.slice(6)\n            this._getAllClassInfo(this.jsonTarget)\n          }\n        })\n    },\n    /**\n     * 获取电台各类信息\n     */\n    _getAllClassInfo (data) {\n      let item = []\n      const length = data.length\n      data.forEach(element => {\n        api.djClassificationInfoFn(element.id)\n          .then(res => {\n            const { data } = res\n            if (data.code === 200) {\n              const { djRadios } = data\n              item.push({\n                name: element.name,\n                data: djRadios\n              })\n              if (item.length === length) {\n                this.setData(item)\n              }\n            }\n          })\n      })\n    },\n    /**\n     * 将data中的数据进行填充\n     */\n    setData (arr) {\n      this.createData = this.ruleData(arr, '创作|翻唱')\n      this.soundBookData = this.ruleData(arr, '有声书')\n      this.emotionData = this.ruleData(arr, '情感调频')\n      this.broadcastingData = this.ruleData(arr, '广播剧')\n      this.musicData = this.ruleData(arr, '音乐故事')\n      this.entertainmentData = this.ruleData(arr, '娱乐|影视')\n      this.electronicData = this.ruleData(arr, '3D|电子')\n      this.mevinData = this.ruleData(arr, '美文读物')\n      this.secondaryData = this.ruleData(arr, '二次元')\n      this.talkData = this.ruleData(arr, '脱口秀')\n      this.knowledgeData = this.ruleData(arr, '知识技能')\n      this.businessData = this.ruleData(arr, '商业财经')\n      this.historyData = this.ruleData(arr, '人文历史')\n      this.englishData = this.ruleData(arr, '外语世界')\n      this.babyData = this.ruleData(arr, '亲子宝贝')\n      this.crosstalkData = this.ruleData(arr, '相声曲艺')\n      this.journeyData = this.ruleData(arr, '旅途|城市')\n      this.load = false\n    },\n    /**\n     * 定义一个方法，用来筛选数据，将所有数据分类筛选出对应的数据\n     */\n    ruleData (arr, name) {\n      const ruleArr = arr.filter(item => {\n        if (item.name === name) {\n          return true\n        }\n      })\n      return ruleArr[0].data\n    },\n    returnPage () {\n      this.$router.go(-1)\n    },\n    /**\n     * 获取json数据中的id，name，img信息\n     * 返回一个数组\n     */\n    getJsonData (data) {\n      let jsonTarget = []\n      data.map((item) => {\n        jsonTarget.push({\n          id: item.id,\n          name: item.name,\n          imgUrl: item.pic56x56Url\n        })\n      })\n      return jsonTarget\n    }\n  },\n  components: {\n    djNav,\n    swiper,\n    icons,\n    radioRecom,\n    boutiqueRecom,\n    publicCon,\n    publicClass,\n    publicImgWrap,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n@import url(\"//at.alicdn.com/t/font_1452410_k59z7sgowgp.css\");\n\n.wrapper {\n  .text {\n    font-size: 0.4rem;\n    vertical-align: 5px;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/dj/public.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-12 13:19:59\n * @Update: 2019-12-07 13:56:18\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\">\n    <div class=\"title\" v-if=\"title\">\n      <h1 class=\"text\">\n        {{ title }}\n        <i class=\"dj dj-arrow-right\" v-show=\"!type === 'rank'\"></i>\n      </h1>\n      <span class=\"smallTag\" v-show=\"!type === 'rank'\">\n        <i class=\"dj dj-bofang\"></i>\n        播放全部\n      </span>\n    </div>\n    <ul>\n      <li class=\"list-item\" :class=\"{hotRank}\" v-for=\"(item, index) in data\" :key=\"index\">\n        <div class=\"index\" v-show=\"type === 'rank'\">\n          <span>{{index + 1}}</span>\n          <span>\n            <i\n              class=\"dj-public\"\n              :class=\"{publicjiantou : item.lastRank !== -1 && item.lastRank - item.rank > 0,\n              publicjiantou1: item.lastRank !== -1 && item.lastRank - item.rank < 0,\n              publicico17: item.lastRank === -1,\n              publichengxian: item.lastRank !== -1 && item.lastRank - item.rank === 0}\"\n            ></i>\n            <i class=\"num\" v-show=\"item.lastRank !== -1\">{{(item.lastRank - item.rank) | setNum1}}</i>\n          </span>\n        </div>\n        <div class=\"img-info\" :class=\"{hotRank, circle : content === 'popular'}\">\n          <img\n            v-lazy=\"item.picUrl ? item.picUrl  + '?param=100y100' : item.program ? item.program.coverUrl  + '?param=100y100' :  item.avatarUrl ? item.avatarUrl + '?param=100y100' : ''\"\n            alt\n          />\n        </div>\n        <div class=\"content\">\n          <p\n            class=\"name\"\n          >{{item.name ? item.name : item.program ? item.program.name : item.nickName }}</p>\n          <div class=\"dec\" v-if=\"content !== 'popular'\" :class=\"{hotRank}\">\n            <div class=\"name\">\n              <div class=\"img-info\" v-show=\"noImg\">\n                <img\n                  v-lazy=\"item.dj  ? item.dj.avatarUrl + '?param=50y50' : item.program ? item.program.coverUrl + '?param=50y50' : item.avatarUrl ? item.avatarUrl + '?param=50y50' : ''\"\n                  alt\n                />\n              </div>\n              <span\n                class=\"name-con\"\n              >{{item.dj ? item.dj.nickname : item.program ? item.program.dj.nickname : item.creatorName ? item.creatorName : ''}}</span>\n            </div>\n            <div class=\"hot-num\">\n              <span class=\"num\">\n                <i class=\"dj-public publichuo\"></i>\n                {{ hotRank ? item.score : item.subCount ? item.subCount : item.score ? item.score : '' | setNum }}\n              </span>\n            </div>\n          </div>\n        </div>\n        <span class=\"num\" v-if=\"content === 'popular'\">\n          <i class=\"dj-public publichuo\"></i>\n          {{ hotRank ? item.score : item.subCount ? item.subCount : item.score ? item.score : '' | setNum }}\n        </span>\n        <span class=\"icon\" v-if=\"!hotRank\">\n          <i class=\"dj-public publicbofang1\"></i>\n        </span>\n      </li>\n    </ul>\n  </div>\n</template>\n\n<script>\nimport { filterSetPlayCount } from 'utils/filters'\nexport default {\n  name: '',\n  data () {\n    return {\n      top: false,\n      bottom: false,\n      isNew: false\n    }\n  },\n  filters: {\n    setNum: function (val) {\n      return filterSetPlayCount(val)\n    },\n    setNum1: function (val) {\n      if (val < 0) {\n        return -val\n      }\n      return val\n    }\n  },\n  props: {\n    title: {\n      type: String\n    },\n    data: {\n      type: Array\n    },\n    type: {\n      type: String\n    },\n    hotRank: {\n      type: Boolean\n    },\n    content: {\n      type: String\n    },\n    noImg: {\n      type: Boolean,\n      default: true\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n@import url(\"//at.alicdn.com/t/font_1463228_6ejm47f2r6h.css\");\n.wrapper {\n  margin-top: 0.5rem;\n  .title {\n    .flex-between();\n    .text {\n      font-weight: 700;\n    }\n  }\n  .list-item {\n    display: flex;\n    align-items: center;\n    height: 1.5rem;\n    &.hotRank {\n      height: 1.8rem;\n    }\n    &:nth-of-type(1) .index {\n      color: @bgcolor;\n    }\n    &:nth-of-type(2) .index {\n      color: @bgcolor;\n    }\n    &:nth-of-type(3) .index {\n      color: @bgcolor;\n    }\n    .index {\n      width: 0.5rem;\n      height: 0.5rem;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      margin-right: 0.2rem;\n      font-size: 0.3rem;\n      font-weight: 500;\n      .num {\n        margin-left: -0.06rem;\n      }\n      .dj-public {\n        font-size: 0.2rem;\n        &.publicjiantou1 {\n          color: #3388ff;\n        }\n        &.publicjiantou {\n          color: @bgcolor;\n        }\n        &.publicico17 {\n          color: #278230;\n          font-size: 0.4rem;\n        }\n        &.publichengxian {\n          color: #999;\n        }\n      }\n    }\n    .img-info {\n      width: 1rem;\n      height: 0;\n      padding-bottom: 1rem;\n      margin-right: 0.2rem;\n      &.hotRank {\n        width: 1.3rem;\n        padding-bottom: 1.3rem;\n        img {\n          width: 1.3rem;\n          height: 1.3rem;\n        }\n      }\n      img {\n        border-radius: @imgBorderRadius;\n        width: 1rem;\n        height: 1rem;\n      }\n      &.circle {\n        width: 0.9rem;\n        padding-bottom: 0.9rem;\n        img {\n          border-radius: 50%;\n          width: 0.9rem;\n          height: 0.9rem;\n        }\n      }\n    }\n    .content {\n      min-width: 3rem;\n      flex: 1;\n      display: flex;\n      flex-direction: column;\n      justify-content: center;\n      .name {\n        .ellipsis();\n        line-height: 1.5;\n      }\n      .dec {\n        display: flex;\n        align-items: center;\n        color: #aaa;\n        font-size: 0.24rem;\n        &.hotRank {\n          flex-direction: column;\n          align-items: baseline;\n          justify-content: center;\n          line-height: 1.5;\n          .name {\n            &::after {\n              content: \"\";\n            }\n          }\n        }\n        .name {\n          display: flex;\n          align-items: center;\n          .img-info {\n            width: 0.5rem;\n            height: 0;\n            padding-bottom: 0.5rem;\n            img {\n              width: 0.5rem;\n              height: 0.5rem;\n              border-radius: 50%;\n            }\n          }\n          &::after {\n            content: \" | \";\n          }\n        }\n        .publichuo {\n          font-size: 0.24rem;\n        }\n      }\n    }\n    .icon {\n      .publicbofang1 {\n        color: #aaa;\n        font-size: 0.5rem;\n      }\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/dj/publicClass.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-12 14:24:51\n * @Update: 2019-12-08 12:24:40\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\">\n    <div class=\"title border-bottom\" :class=\"{center: type ==='class'}\">{{title}}</div>\n    <ul class=\"list-wrap\" @click=\"toClassDetailPage\">\n      <li\n        class=\"list-item\"\n        ref=\"item\"\n        :data-id=\"item.id\"\n        :data-title=\"item.name\"\n        v-for=\"(item, index) in data\"\n        :key=\"index\"\n      >\n        <div class=\"img-info\">\n          <img :src=\"item.imgUrl\" alt />\n        </div>\n        <span class=\"name\">{{item.name}}</span>\n      </li>\n    </ul>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: '',\n  props: {\n    title: {\n      type: String\n    },\n    data: {\n      type: Array\n    },\n    type: {\n      type: String\n    }\n  },\n  methods: {\n    toClassDetailPage (e) {\n      const nodeName = e.target.nodeName.toLowerCase()\n      if (nodeName === 'li') {\n        const id = e.target.dataset.id\n        const title = e.target.dataset.title\n        this.$router.push({ name: 'classDetail', params: { id, title } })\n      }\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n.wrapper {\n  margin-top: 0.5rem;\n  .title {\n    font-weight: 700;\n    padding-bottom: 0.3rem;\n    margin: 0.3rem;\n    &.center {\n      text-align: center;\n    }\n  }\n  .list-wrap {\n    display: flex;\n    flex-wrap: wrap;\n    .list-item {\n      width: 3rem;\n      display: flex;\n      align-items: center;\n      justify-content: left;\n      box-sizing: border-box;\n      padding: 0.2rem;\n      .img-info {\n        position: relative;\n        z-index: -1;\n        width: 0.5rem;\n        height: 0;\n        padding-bottom: 0.5rem;\n        margin-right: 0.2rem;\n        img {\n          width: 0.5rem;\n          height: 0.5rem;\n        }\n      }\n      .name {\n        position: relative;\n        z-index: -1;\n      }\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/dj/publicImgWrap.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-12 18:39:19\n * @Update: 2019-10-13 11:59:19\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\">\n    <div class=\"title\">\n      <h1 class=\"text\">\n        {{ title }}\n        <i class=\"dj dj-arrow-right\"></i>\n      </h1>\n    </div>\n    <div class=\"img-col\">\n      <img-card\n        v-for=\"(item, index) in data\"\n        :key=\"index\"\n        type=\"dj\"\n        :name=\"item.name\"\n        :imgUrl=\"item.picUrl\"\n        :dec=\"item.desc || item.rcmdtext\"\n        :ridId=\"item.id\"\n      ></img-card>\n    </div>\n  </div>\n</template>\n\n<script>\nimport imgCard from 'base/imgCard'\nexport default {\n  name: '',\n  props: {\n    data: {\n      type: Array\n    },\n    title: {\n      type: String\n    }\n  },\n  components: {\n    imgCard\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.wrapper {\n  margin-top: 0.5rem;\n  .title {\n    .flex-between();\n    .text {\n      font-weight: 700;\n    }\n  }\n  .img-col {\n    .flex-between();\n    flex-wrap: wrap;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/dj/titleAndThree.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-12-03 12:34:55\n * @Update: 2019-12-10 13:09:16\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\">\n    <div class=\"title\" @click=\"goDetailPage\">\n      {{title}}\n      <i class=\"threeTitle threeTitleiconfontxiangxia1copy19\"></i>\n    </div>\n    <div class=\"three-item\" @click=\"toDetailPage\">\n      <div class=\"item-info\" v-for=\"(item, index) in data\" :key=\"index\">\n        <div class=\"img-info\" :class=\"{circle: type === 'circle'}\">\n          <img\n            :data-id=\"item.id ? item.id : ''\"\n            :src=\"item.program ? item.program.coverUrl : item.avatarUrl ? item.avatarUrl : item.picUrl\"\n            alt\n          />\n          <i v-if=\"!type === 'circle'\" class=\"threeTitle threeTitlebofang\"></i>\n        </div>\n        <span\n          class=\"name twoLinesEllipsis\"\n        >{{item.program ? item.program.name : item.nickName ? item.nickName : item.name}}</span>\n        <span v-if=\"type === 'circle'\" class=\"num small\">\n          <i class=\"threeTitle threeTitlehuo\"></i>\n          {{ item.score | setCount}}\n        </span>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script>\nimport { filterSetPlayCount } from 'utils/filters'\nexport default {\n  name: '',\n  props: {\n    title: {\n      type: String\n    },\n    data: {\n      type: Array\n    },\n    type: {\n      type: String\n    },\n    pageId: {\n      type: String\n    }\n  },\n  filters: {\n    setCount: function (val) {\n      return filterSetPlayCount(val)\n    }\n  },\n  methods: {\n    goDetailPage () {\n      this.$router.push({ name: 'conDetail', params: { id: this.pageId } })\n    },\n    toDetailPage (e) {\n      const { nodeName, dataset } = e.target\n      if (nodeName.toLocaleLowerCase() === 'img') {\n        const id = dataset.id\n        this.$router.push({ name: 'user_info', params: { id } })\n      }\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n@import url(\"//at.alicdn.com/t/font_1542558_8cdf5fh6xcr.css\");\n.wrapper {\n  margin-top: 0.5rem;\n  .title {\n    font-size: 0.3rem;\n    font-weight: 700;\n    margin-bottom: 0.3rem;\n    .threeTitleiconfontxiangxia1copy19 {\n      font-size: 0.24rem;\n    }\n  }\n  .three-item {\n    .flex-around();\n    .item-info {\n      width: 1.7rem;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      .img-info {\n        box-sizing: border-box;\n        position: relative;\n        width: 1.6rem;\n        height: 0;\n        padding-bottom: 1.6rem;\n        &.circle {\n          border-radius: 50%;\n          overflow: hidden;\n        }\n        img {\n          border-radius: 0.1rem;\n          width: 100%;\n        }\n        .threeTitlebofang {\n          position: absolute;\n          color: #ccc;\n          font-size: 0.5rem;\n          bottom: 0.1rem;\n          right: 0.13rem;\n          z-index: 1;\n        }\n      }\n      .name {\n        box-sizing: border-box;\n        margin-top: 0.15rem;\n        padding: 0 0.1rem;\n        font-size: 0.23rem;\n        line-height: 1.3;\n      }\n      .small {\n        margin-top: 0.13rem;\n        font-size: 0.2rem;\n        .threeTitlehuo {\n          font-size: 0.2rem;\n        }\n      }\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/djSublist/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-01 15:08:21\n * @Update: 2019-10-16 13:29:19\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"dj_sub_list pd23\">\n    <general-nav @returnPage=\"returnPage\">\n      <span class=\"text\">我的电台</span>\n    </general-nav>\n    <dj-sublist-card :djSublist=\"djSublist\" :count=\"count\" type=\"dj\" title=\"我订阅的电台\"></dj-sublist-card>\n  </div>\n</template>\n\n<script>\nimport generalNav from 'base/generalNav'\nimport djSublistCard from 'base/djSublistCard'\nimport api from 'api'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      djSublist: [],\n      count: 0\n    }\n  },\n  activated () {\n    this._getDjSublist()\n  },\n  methods: {\n    _getDjSublist () {\n      const data = +new Date()\n      api.djSublistFn(data)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.djSublist = data.djRadios\n            this.count = data.count\n          }\n        })\n    },\n    returnPage () {\n      this.$router.go(-1)\n    }\n  },\n  components: {\n    generalNav,\n    djSublistCard\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.dj_sub_list {\n  background-color: #fff;\n  .text {\n    font-size: 0.4rem;\n    vertical-align: 5px;\n    width: 8rem;\n    .ellipsis();\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/findIndex/components/chinese.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-08 11:28:42\n * @Update: 2019-10-08 12:37:13\n * @Update log: 更新日志\n -->\n<template>\n  <div>\n    <div class=\"load\" v-show=\"loading\">\n      <page-loading></page-loading>\n    </div>\n    <div v-show=\"!loading\">\n      <audio-all-title @beginAudioAll=\"beginAudioAll\" :trackCount=\"trackCount\" class=\"titleMt\"></audio-all-title>\n      <song-list\n        v-for=\"(item, index) in chineseList\"\n        :key=\"index\"\n        :songName=\"item.name\"\n        :artists=\"item.artists\"\n        :albumName=\"item.album.name\"\n        :imgUrl=\"item.album.picUrl\"\n        @beginSong=\"setAudioList(item, index)\"\n        :nowSong=\"item.id === audioSong.id\"\n      ></song-list>\n    </div>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport audioAllTitle from 'base/audioAllTitle'\nimport pageLoading from 'base/pageLoading'\nimport songList from 'base/song'\nimport { mapActions, mapGetters } from 'vuex'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      trackCount: 0,\n      chineseList: [],\n      loading: true\n    }\n  },\n  computed: {\n    ...mapGetters({ audioSong: 'AUDIO_ING_SONG' })\n  },\n  created () {\n    this._getChineseInfo(7)\n  },\n  methods: {\n    /**\n     * 获取相关数据\n     * @param {Number} type 接口参数\n     */\n    _getChineseInfo (type) {\n      api.newSongsFn(type)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.chineseList = data.data\n            this.trackCount = data.data.length\n            this.loading = false\n          }\n        })\n    },\n    beginAudioAll () {\n      this.startPlayAll({\n        list: this.chineseList\n      })\n    },\n    setAudioList (item, index) {\n      this.selectPlay({\n        list: this.chineseList,\n        index\n      })\n    },\n    ...mapActions(['selectPlay', 'startPlayAll'])\n  },\n  components: {\n    audioAllTitle,\n    songList,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n.titleMt {\n  margin-top: 0.2rem;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/findIndex/components/europe.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-08 11:29:02\n * @Update: 2019-10-08 11:29:02\n * @Update log: 更新日志\n -->\n<template>\n  <div>\n    <div class=\"load\" v-show=\"loading\">\n      <page-loading></page-loading>\n    </div>\n    <div v-show=\"!loading\">\n      <audio-all-title @beginAudioAll=\"beginAudioAll\" :trackCount=\"trackCount\" class=\"titleMt\"></audio-all-title>\n      <song-list\n        v-for=\"(item, index) in chineseList\"\n        :key=\"index\"\n        :songName=\"item.name\"\n        :artists=\"item.artists\"\n        :albumName=\"item.album.name\"\n        :imgUrl=\"item.album.picUrl\"\n        @beginSong=\"setAudioList(item, index)\"\n        :nowSong=\"item.id === audioSong.id\"\n      ></song-list>\n    </div>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport audioAllTitle from 'base/audioAllTitle'\nimport pageLoading from 'base/pageLoading'\nimport songList from 'base/song'\nimport { mapActions, mapGetters } from 'vuex'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      trackCount: 0,\n      chineseList: [],\n      loading: true\n    }\n  },\n  computed: {\n    ...mapGetters({ audioSong: 'AUDIO_ING_SONG' })\n  },\n  created () {\n    this._getChineseInfo(96)\n  },\n  methods: {\n    /**\n     * 获取相关数据\n     * @param {Number} type 接口参数\n     */\n    _getChineseInfo (type) {\n      api.newSongsFn(type)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.chineseList = data.data\n            this.trackCount = data.data.length\n            this.loading = false\n          }\n        })\n    },\n    beginAudioAll () {\n      this.startPlayAll({\n        list: this.chineseList\n      })\n    },\n    setAudioList (item, index) {\n      this.selectPlay({\n        list: this.chineseList,\n        index\n      })\n    },\n    ...mapActions(['selectPlay', 'startPlayAll'])\n  },\n  components: {\n    audioAllTitle,\n    songList,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n.titleMt {\n  margin-top: 0.2rem;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/findIndex/components/icons.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-10-09 12:16:40\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"container border-bottom\">\n    <icon\n      v-for=\"(item, index) in findIcons\"\n      :icons=\"item\"\n      :bgcolor=\"true\"\n      :key=\"index\"\n      @goPage=\"goPage(item.linkTo)\"\n    >\n      <span class=\"today\" v-if=\"item.text === '每日推荐'\">{{today}}</span>\n    </icon>\n  </div>\n</template>\n\n<script>\nimport { mapActions } from 'vuex'\nimport { findIcons } from 'getInfos/getData'\nimport icon from 'base/icon'\nimport api from 'api'\n\nexport default {\n  name: 'findIcon',\n  data () {\n    return {\n      findIcons\n    }\n  },\n  components: {\n    icon\n  },\n  computed: {\n    today: function () {\n      return new Date().getDate()\n    }\n  },\n  mounted () {\n    this.iniData()\n  },\n  methods: {\n    iniData () {\n      this.findIcons = findIcons()\n    },\n    goPage (link) {\n      if (link === 'personalFm') {\n        // 当如果是点击私人Fm时需要做的操作\n        // 获取私人FM信息\n        this._getPersonalFm()\n      } else {\n        // 正常的是点击图标跳转\n        this.$router.push(link)\n      }\n    },\n    /**\n     * 播放全部\n     */\n    startPlay (list) {\n      this.startPlayAll({\n        list\n      })\n    },\n    _getPersonalFm () {\n      api.personalFmFn()\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            const list = data.data\n            // 将信息传到播放页面进行播放\n            this.startPlay(list)\n          }\n        })\n    },\n    ...mapActions(['startPlayAll'])\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url(\"~styles/global.less\");\n\n.container {\n  .flex-around();\n  width: 100%;\n  height: 1.6rem;\n  align-items: center;\n  padding: 0.2rem 0 0.3rem;\n  .today {\n    position: absolute;\n    top: 0.09rem;\n    left: 50%;\n    transform: translateX(-50%);\n    font-size: 0.2rem;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/findIndex/components/japan.vue",
    "content": "<template>\n  <div>\n    <div class=\"load\" v-show=\"loading\">\n      <page-loading></page-loading>\n    </div>\n    <div v-show=\"!loading\">\n      <audio-all-title @beginAudioAll=\"beginAudioAll\" :trackCount=\"trackCount\" class=\"titleMt\"></audio-all-title>\n      <song-list\n        v-for=\"(item, index) in chineseList\"\n        :key=\"index\"\n        :songName=\"item.name\"\n        :artists=\"item.artists\"\n        :albumName=\"item.album.name\"\n        :imgUrl=\"item.album.picUrl\"\n        @beginSong=\"setAudioList(item, index)\"\n        :nowSong=\"item.id === audioSong.id\"\n      ></song-list>\n    </div>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport audioAllTitle from 'base/audioAllTitle'\nimport pageLoading from 'base/pageLoading'\nimport songList from 'base/song'\nimport { mapActions, mapGetters } from 'vuex'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      trackCount: 0,\n      chineseList: [],\n      loading: true\n    }\n  },\n  computed: {\n    ...mapGetters({ audioSong: 'AUDIO_ING_SONG' })\n  },\n  created () {\n    this._getChineseInfo(8)\n  },\n  methods: {\n    /**\n     * 获取相关数据\n     * @param {Number} type 接口参数\n     */\n    _getChineseInfo (type) {\n      api.newSongsFn(type)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.chineseList = data.data\n            this.trackCount = data.data.length\n            this.loading = false\n          }\n        })\n    },\n    beginAudioAll () {\n      this.startPlayAll({\n        list: this.chineseList\n      })\n    },\n    setAudioList (item, index) {\n      this.selectPlay({\n        list: this.chineseList,\n        index\n      })\n    },\n    ...mapActions(['selectPlay', 'startPlayAll'])\n  },\n  components: {\n    audioAllTitle,\n    songList,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n.titleMt {\n  margin-top: 0.2rem;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/findIndex/components/korea.vue",
    "content": "<template>\n  <div>\n    <div class=\"load\" v-show=\"loading\">\n      <page-loading></page-loading>\n    </div>\n    <div v-show=\"!loading\">\n      <audio-all-title @beginAudioAll=\"beginAudioAll\" :trackCount=\"trackCount\" class=\"titleMt\"></audio-all-title>\n      <song-list\n        v-for=\"(item, index) in chineseList\"\n        :key=\"index\"\n        :songName=\"item.name\"\n        :artists=\"item.artists\"\n        :albumName=\"item.album.name\"\n        :imgUrl=\"item.album.picUrl\"\n        @beginSong=\"setAudioList(item, index)\"\n        :nowSong=\"item.id === audioSong.id\"\n      ></song-list>\n    </div>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport audioAllTitle from 'base/audioAllTitle'\nimport pageLoading from 'base/pageLoading'\nimport songList from 'base/song'\nimport { mapActions, mapGetters } from 'vuex'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      trackCount: 0,\n      chineseList: [],\n      loading: true\n    }\n  },\n  computed: {\n    ...mapGetters({ audioSong: 'AUDIO_ING_SONG' })\n  },\n  created () {\n    this._getChineseInfo(16)\n  },\n  methods: {\n    /**\n     * 获取相关数据\n     * @param {Number} type 接口参数\n     */\n    _getChineseInfo (type) {\n      api.newSongsFn(type)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.chineseList = data.data\n            this.trackCount = data.data.length\n            this.loading = false\n          }\n        })\n    },\n    beginAudioAll () {\n      this.startPlayAll({\n        list: this.chineseList\n      })\n    },\n    setAudioList (item, index) {\n      this.selectPlay({\n        list: this.chineseList,\n        index\n      })\n    },\n    ...mapActions(['selectPlay', 'startPlayAll'])\n  },\n  components: {\n    audioAllTitle,\n    songList,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n.titleMt {\n  margin-top: 0.2rem;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/findIndex/components/moreNewDish.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-06 12:57:04\n * @Update: 2019-10-26 08:21:52\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper pd23\">\n    <general-nav @returnPage=\"returnPage\">\n      <span class=\"text\">新碟上架</span>\n    </general-nav>\n    <page-loading v-show=\"load\"></page-loading>\n    <div v-show=\"!load\">\n      <div class=\"nowWeekNewDish\">\n        <h1 class=\"title\">本周新碟</h1>\n        <div class=\"img-card-wrapper\">\n          <img-card\n            v-for=\"(item, index) in nowWeekNewDish\"\n            :key=\"index\"\n            width=\"2.4rem\"\n            :imgUrl=\"item.picUrl\"\n            :dec=\"item.name\"\n            :dishId=\"item.id\"\n            :artists=\"item.artists\"\n            lines=\"one\"\n          ></img-card>\n        </div>\n      </div>\n      <div class=\"nowWeekNewDish\" v-show=\"nowMonth\">\n        <h1>\n          <span class=\"month\">{{month}}月</span>\n          <span class=\"year\">/{{year}}</span>\n        </h1>\n        <div class=\"img-card-wrapper\">\n          <img-card\n            v-for=\"(item, index) in nowMonth\"\n            :key=\"index\"\n            width=\"2.4rem\"\n            :imgUrl=\"item.picUrl\"\n            :dec=\"item.name\"\n            :dishId=\"item.id\"\n            :artists=\"item.artists\"\n            lines=\"one\"\n          ></img-card>\n        </div>\n      </div>\n      <div class=\"nowWeekNewDish\" v-show=\"lastMonth.length\">\n        <h1>\n          <span class=\"month\">{{prevMonth}}月</span>\n          <span class=\"year\">/{{prevYear}}</span>\n        </h1>\n        <div class=\"img-card-wrapper\">\n          <img-card\n            v-for=\"(item, index) in lastMonth\"\n            :key=\"index\"\n            width=\"2.4rem\"\n            :imgUrl=\"item.picUrl\"\n            :dec=\"item.name\"\n            :dishId=\"item.id\"\n            :artists=\"item.artists\"\n            lines=\"one\"\n          ></img-card>\n        </div>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script>\nimport generalNav from 'base/generalNav'\nimport imgCard from 'base/imgCard'\nimport pageLoading from 'base/pageLoading'\nimport api from 'api'\nexport default {\n  name: '',\n  data () {\n    return {\n      // 本周新碟\n      // 将新碟数据的前四个设置为本周新碟\n      nowWeekNewDish: [],\n      // 当前月的合集\n      nowMonth: [],\n      // 上一个月的合集\n      lastMonth: [],\n      offset: 0,\n      albums: [],\n      load: true\n    }\n  },\n  created () {\n    this._getAllInfo(this.offset)\n  },\n  computed: {\n    year: function () {\n      return new Date().getFullYear()\n    },\n    month: function () {\n      return new Date().getMonth() + 1\n    },\n    prevYear: function () {\n      if (this.prevMonth === 12) {\n        return this.year - 1\n      }\n      return this.year\n    },\n    prevMonth: function () {\n      let prev = this.month - 1\n      if (prev === 0) {\n        prev = 12\n      }\n      return prev\n    }\n  },\n  methods: {\n    returnPage () {\n      this.$router.go(-1)\n    },\n    _getAllInfo (offset) {\n      console.log(offset)\n      api.newDishFn(80, offset)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            if (this.albums.length === 0) {\n              console.log('===0')\n              this.albums = data.albums\n              this.nowWeekNewDish = this.albums.splice(0, 4)\n            } else {\n              this.albums.push(...data.albums)\n            }\n            // 存下来所有的数据\n            // 对数据中的时间进行筛选出当月数据和上一个月的数据\n            this.filterTime(this.albums)\n            this.load = false\n          }\n        })\n    },\n    /**\n     * 对数据进行时间上的筛选\n     */\n    filterTime (arr) {\n      const months = {}\n      const nowMonth = new Date().getMonth() + 1\n      const lastMonth = new Date().getMonth()\n      // 将当前月和上一个月初始化为空数组\n      months[nowMonth] = []\n      months[lastMonth] = []\n      // 遍历数据，筛选出当前月和上一个月的数据信息\n      arr.forEach(element => {\n        if (new Date(element.publishTime).getMonth() + 1 === nowMonth) {\n          months[nowMonth].push(element)\n        }\n        if (new Date(element.publishTime).getMonth() + 1 === lastMonth) {\n          months[lastMonth].push(element)\n        }\n      })\n      this.nowMonth = months[nowMonth]\n      this.lastMonth = months[lastMonth]\n    }\n  },\n  components: {\n    generalNav,\n    imgCard,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.wrapper {\n  .text {\n    font-size: 0.4rem;\n    vertical-align: 5px;\n    width: 8rem;\n    .ellipsis();\n  }\n  .month {\n    font-size: 0.26rem;\n    font-weight: 700;\n  }\n  .year {\n    font-size: 0.23rem;\n  }\n  .nowWeekNewDish {\n    margin-top: 0.2rem;\n    .title {\n      font-size: 0.3rem;\n      font-weight: 700;\n    }\n    .img-card-wrapper {\n      flex-wrap: wrap;\n      .flex-around();\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/findIndex/components/moreNewSongs.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-08 11:12:45\n * @Update: 2019-11-02 12:30:05\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper pd23\">\n    <div class=\"titleFixed\">\n      <general-nav @returnPage=\"returnPage\">\n        <span class=\"text\">最新音乐</span>\n      </general-nav>\n      <slider-nav :list=\"list\"></slider-nav>\n    </div>\n    <keep-alive>\n      <router-view></router-view>\n    </keep-alive>\n  </div>\n</template>\n\n<script>\nimport generalNav from 'base/generalNav'\nimport sliderNav from 'base/sliderNav'\n\nexport default {\n  name: '',\n  computed: {\n    list: function () {\n      let arr = [{\n        path: `/chinese`,\n        text: `华语`\n      }, {\n        path: `/europe`,\n        text: `欧美`\n      }, {\n        path: `/korea`,\n        text: `韩国`\n      }, {\n        path: `/japan`,\n        text: `日本`\n      }]\n      return arr\n    }\n  },\n  methods: {\n    returnPage () {\n      this.$router.go(-1)\n    }\n  },\n  components: {\n    generalNav,\n    sliderNav\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.wrapper {\n  .text {\n    font-size: 0.4rem;\n    vertical-align: 5px;\n    width: 8rem;\n    .ellipsis();\n  }\n  .fixed {\n    position: fixed;\n    top: 0;\n    z-index: 1;\n    background-color: #fff;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/findIndex/components/newDish.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-07-27 17:08:42\n * @Update: 2019-12-05 15:50:04\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper pd23\">\n    <div class=\"title\">\n      <div class=\"recommended\">\n        <span :class=\"{active:type==='dish'}\" @click=\"type='dish'\">新碟</span>\n        <i style=\"color:#ddd\">|</i>\n        <span :class=\"{active:type==='newSong'}\" @click=\"type='newSong'\">新歌</span>\n      </div>\n      <div class=\"square\">\n        <span v-show=\"type==='dish'\" @click.stop=\"moreNewDish\">更多新碟</span>\n        <span v-show=\"type==='newSong'\" @click.stop=\"moreNewSongs\">新歌推荐</span>\n      </div>\n    </div>\n    <page-loading style=\"height:3rem\" v-show=\"load\"></page-loading>\n    <div v-show=\"!load\">\n      <div class=\"img-col\" v-show=\"type==='dish'\">\n        <img-card\n          v-for=\"(item, index) in dishList\"\n          :key=\"index\"\n          :imgUrl=\"item.picUrl\"\n          :dec=\"item.name\"\n          :dishId=\"item.id\"\n        ></img-card>\n      </div>\n      <div class=\"img-col\" v-show=\"type==='newSong'\">\n        <img-card\n          v-for=\"(item, index) in newSongsList\"\n          :key=\"index\"\n          :imgUrl=\"item.album.blurPicUrl\"\n          :dec=\"item.name\"\n          @click.native=\"beginAudio(item)\"\n        ></img-card>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport imgCard from 'base/imgCard'\nimport pageLoading from 'base/pageLoading'\nimport { mapActions } from 'vuex'\n\nexport default {\n  name: 'newDish',\n  components: {\n    imgCard,\n    pageLoading\n  },\n  data () {\n    return {\n      dishList: [],\n      newSongsList: [],\n      type: 'dish',\n      load: true\n    }\n  },\n  async created () {\n    await this._getDishListInfo()\n    await this._getNewSongsInfo()\n  },\n  methods: {\n    _getDishListInfo () {\n      api.newDishFn()\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            const arr = data.albums\n            this.dishList = this.getRandomArrayElements(arr, 3)\n          }\n        })\n        .catch(error => {\n          if (error) {\n            console.log(error, '请求超时')\n          }\n        })\n    },\n    beginAudio (list) {\n      this.addToAudioList(list)\n    },\n    _getNewSongsInfo () {\n      api.newSongsFn()\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            const arr = data.data\n            this.newSongsList = this.getRandomArrayElements(arr, 3)\n            this.load = false\n          }\n        })\n        .catch(error => {\n          if (error) {\n            this.load = false\n            console.log(error, '请求超时')\n          }\n        })\n    },\n    /**\n     * 更多新碟\n     */\n    moreNewDish () {\n      this.$router.push('/moreNewDish')\n    },\n    /**\n     * 新歌推荐\n     */\n    moreNewSongs () {\n      this.$router.push('/moreNewSongs')\n    },\n    getRandomArrayElements (arr, count) {\n      // eslint-disable-next-line one-var\n      let shuffled = arr.slice(0),\n        // 克隆一个数组，为了不影响外边的数据\n        i = arr.length,\n        min = i - count,\n        temp,\n        index\n      // 存下来数组信息  数组的长度\n      // 通过改变数组项的位置 输出后边的几位\n      while (--i > min) {\n        // 随机生成出一个索引\n        index = Math.floor((i + 1) * Math.random())\n        // 将随机索引项暂存\n        // 将数组后边的项与随机项调换\n        temp = shuffled[index]\n        shuffled[index] = shuffled[i]\n        shuffled[i] = temp\n      }\n      return shuffled.slice(min)\n    },\n    ...mapActions(['addToAudioList'])\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url(\"~styles/global.less\");\n\n.wrapper {\n  .title {\n    width: 100%;\n    height: 1.2rem;\n    box-sizing: border-box;\n    display: flex;\n    flex-direction: row;\n    align-items: center;\n    .recommended {\n      font-size: 0.24rem;\n      .active {\n        font-size: 0.3rem;\n        font-weight: 700;\n      }\n    }\n    .square {\n      .smallTag();\n      margin-left: auto;\n    }\n  }\n  .img-col {\n    .flex-between();\n    flex-wrap: wrap;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/findIndex/components/personalizedSongList.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-12-05 15:47:01\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper pd23\">\n    <div class=\"title\">\n      <div class=\"recommended\">推荐歌单</div>\n      <router-link to=\"recommend\" tag=\"div\" class=\"square\">歌单广场</router-link>\n    </div>\n    <page-loading style=\"height:5rem\" v-show=\"load\"></page-loading>\n    <div class=\"img-col\" v-show=\"!load\">\n      <!-- 因为两个接口的属性名不同，这里使用了或 -->\n      <img-card\n        v-for=\"(item, index) in songList\"\n        :key=\"index\"\n        :imgUrl=\"item.picUrl || item.coverImgUrl\"\n        :dec=\"item.name\"\n        :playCount=\"item.playCount || item.playcount\"\n        :albumId=\"item.id\"\n      ></img-card>\n    </div>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport imgCard from 'base/imgCard'\nimport pageLoading from 'base/pageLoading'\n\nimport { getRandomArrayElements } from 'utils/getRandomArrayElements'\n\nimport { mapGetters } from 'vuex'\nexport default {\n  name: 'songList',\n  data () {\n    return {\n      load: true,\n      songList: [],\n      isGetOver: false\n    }\n  },\n  created () {\n    this._getImgCard()\n  },\n  computed: {\n    ...mapGetters({ loginState: 'LOGIN_STATE' })\n  },\n  methods: {\n    /**\n     * 获取推荐歌单的入口函数\n     */\n    async _getImgCard () {\n      let getFlag = +localStorage.getItem('loginState')\n      if (this.loginState || getFlag) {\n        // 用户已经登录\n        const isGetOver = await this.loadGetSongListInfo()\n        this.isGetOver = isGetOver\n      } else {\n        const isGetOver = await this.getSongListInfo()\n        this.isGetOver = isGetOver\n      }\n    },\n    /**\n     * 在用户没有登陆的情况下随机取出6项进行展示\n     */\n    async getSongListInfo () {\n      try {\n        const { data } = await api.recSongListFn()\n        if (data.code === 200) {\n          this.songList = getRandomArrayElements(data.playlists, 6)\n          this.load = false\n          return true\n        }\n        return false\n      } catch (error) {\n        this.load = false\n        console.log(error, '请求超时')\n      }\n    },\n    /**\n     * 在用户登陆情况下执行这个函数获取每日推荐歌单\n     */\n    async loadGetSongListInfo () {\n      try {\n        const { data } = await api.dateRecSongListFn()\n        if (data.code === 200) {\n          const arr = data.recommend\n          this.songList = getRandomArrayElements(arr, 6)\n          this.load = false\n          return true\n        }\n        return false\n      } catch (error) {\n        console.log(error, '请求超时')\n      }\n    }\n  },\n  components: {\n    imgCard,\n    pageLoading\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url(\"~styles/global.less\");\n\n.wrapper {\n  .title {\n    width: 100%;\n    height: 1.2rem;\n    box-sizing: border-box;\n    display: flex;\n    flex-direction: row;\n    align-items: center;\n    .recommended {\n      font-size: 0.3rem;\n      font-weight: 700;\n    }\n    .square {\n      .smallTag();\n      margin-left: auto;\n    }\n  }\n  .img-col {\n    .flex-between();\n    flex-wrap: wrap;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/findIndex/components/swiper.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-11-12 21:36:15\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"banner-container\">\n    <van-swipe :autoplay=\"5000\" indicator-color=\"#dd001b\">\n      <van-swipe-item v-for=\"(item, index) in swiperList\" :key=\"index\">\n        <img class=\"banner-img\" :src=\"item.pic\" alt />\n        <span class=\"title\" :style=\"{background:item.titleColor}\">{{item.typeTitle}}</span>\n      </van-swipe-item>\n    </van-swipe>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\n\nexport default {\n  name: 'findSwiper',\n  data () {\n    return {\n      // 存放图片组信息\n      swiperList: []\n    }\n  },\n  methods: {\n    _getFindInfo () {\n      api.bannerSwiperFn()\n        .then(this.getFindInfoSuc)\n    },\n    getFindInfoSuc (res) {\n      if (res.status === 200 && res.statusText === 'OK') {\n        res = res.data.banners\n        this.swiperList = res\n      }\n    }\n  },\n  mounted () {\n    this._getFindInfo()\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url(\"~styles/global.less\");\n\n.banner-container {\n  box-sizing: border-box;\n  overflow: hidden;\n  padding: 0.2rem;\n  width: 100%;\n  height: 0;\n  padding-bottom: 40%;\n  .banner-img {\n    width: 100%;\n    height: 100%;\n    border-radius: @imgBorderRadius;\n  }\n  .title {\n    position: absolute;\n    right: 0;\n    bottom: 0;\n    color: #fff;\n    font-size: smaller;\n    padding: 3px 6px;\n    opacity: 0.8;\n    border-top-left-radius: @imgBorderRadius;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/findIndex/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2020-03-13 22:37:42\n * @Update log: 更新日志\n -->\n<template>\n  <div>\n    <swiper></swiper>\n    <icon></icon>\n    <song-list ref=\"songList\"></song-list>\n    <new-dish></new-dish>\n    <top-tip ref=\"tip\">\n      <span class=\"tips\">{{tips}}</span>\n    </top-tip>\n    <div id=\"audio_pb1\" v-show=\"!isMiniAudio\"></div>\n  </div>\n</template>\n\n<script>\nimport swiper from './components/swiper'\nimport icon from './components/icons'\nimport songList from './components/personalizedSongList'\nimport newDish from './components/newDish'\nimport {mapGetters} from 'vuex'\nexport default {\n  name: 'findIndex',\n  mounted () {\n    this.$refs.tip.showTip()\n  },\n  data () {\n    return {\n      isLoading: false,\n      tips: '为你推荐更多有趣的内容'\n    }\n  },\n  beforeRouteEnter (to, from, next) {\n    next()\n    if (from.path === '/pwd') {\n      location.reload()\n    }\n  },\n  computed: {\n    ...mapGetters({\n      isMiniAudio: 'FULL_SCREEN'\n    })\n  },\n  methods: {\n    onRefresh () {\n      this.$refs.songList._getImgCard()\n      if (this.isGetOver()) {\n        setTimeout(() => {\n          this.isLoading = false\n          this.tips = '已为你推荐新的个性化内容'\n          this.$refs.tip.showTip()\n        }, 500)\n      }\n    },\n    /**\n     * 子组件传过来是否获取数据成功\n     */\n    isGetOver () {\n      return this.$refs.songList.isGetOver\n    }\n  },\n  components: {\n    swiper,\n    icon,\n    songList,\n    newDish\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url(\"//at.alicdn.com/t/font_1295705_yfxum6q2gip.css\");\n.tips {\n  box-sizing: border-box;\n  padding: 0.1rem 0.2rem;\n  background-color: rgba(0, 0, 0, 0.6);\n  color: #fff;\n  font-size: 0.23rem;\n  border-radius: 0.3rem;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/friendIndex/index.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-26 10:32:15\n * @Update: 2019-11-12 21:55:07\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"friend-wra\">\n    静待...\n    <br />\n    <br />欢迎访问我的 GitHub\n    <br />\n    <br />\n\n    <a\n      href=\"https://github.com/powerdong/Music-player\"\n      target=\"_blank\"\n      rel=\"noopener noreferrer\"\n    >项目地址</a>\n    <br />\n    <br />您的 star 是我最大的鼓励\n  </div>\n  <!-- <public-info :data=\"dataInfo\"></public-info> -->\n</template>\n\n<script>\n// import publicInfo from './public'\nimport api from 'api'\nexport default {\n  name: '',\n  data () {\n    return {\n      dataInfo: []\n    }\n  },\n  created () {\n    // this._getFriendInfo()\n  },\n  methods: {\n    async _getFriendInfo () {\n      const { data } = await api.friendFn()\n      if (data.code === 200) {\n        const { event } = data\n        this.dataInfo = this.getJson(event)\n      }\n    },\n    /**\n     * 将json字符串传换为js对象\n     * 将数组中每一项添加一项 userReason\n     */\n    getJson (arr) {\n      let res = []\n      arr.forEach((ele, index) => {\n        res.push(JSON.parse(ele.json))\n        let reason = ele.rcmdInfo ? ele.rcmdInfo.userReason : ''\n        res[index].userReason = reason\n        // 刚开始是使用下边这个写法。是错误的！！\n        // 形成了命名冲突，但是不会报错，造成最后的key值名称不正确\n        // let {userReason} = ele.rcmdInfo\n        // res[i].userReason = userReason\n      })\n      return res\n    }\n  },\n  components: {\n    // publicInfo\n  }\n}\n</script>\n\n<style lang='less' scoped>\n.friend-wra {\n  width: 4rem;\n  margin: 0.5rem auto;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/friendIndex/public.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-26 10:49:45\n * @Update: 2019-11-07 19:57:21\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"pd23\">\n    <div class=\"wrapper border-bottom\" v-for=\"(item, index) in data\" :key=\"index\">\n      <div class=\"img-info\">\n        <img :src=\"item.video.creator.backgroundUrl + '?param=100y100'\" alt />\n      </div>\n      <div class=\"author\">\n        <h1 class=\"nickname\">\n          {{item.video.creator.nickname}}\n          <span class=\"category\">发布</span>\n        </h1>\n        <span class=\"fans\">{{item.userReason}}</span>\n        <h1 class=\"title\">{{item.msg}}</h1>\n        <div class=\"videoInfo\">\n          <img ref=\"videoImg\" :src=\"item.video.coverUrl + '?param=360y170'\" alt />\n          <circle-loading type=\"absolute\" class=\"none\" width=\"5.4rem\" height=\"2.8rem\" ref=\"load\"></circle-loading>\n          <div class=\"play-video\" ref=\"playVideo\" @touchstart=\"hideFnBtn(index)\">\n            <video\n              @canplay=\"startPlay(index)\"\n              @timeupdate=\"setBarTime(index)\"\n              class=\"video_tag\"\n              ref=\"video\"\n              src=\"localhost\"\n            ></video>\n            <!-- 阻止工具条冒泡 -->\n            <div class=\"fn-btn\" ref=\"fnBtn\" @click.stop>\n              <!-- 这里是视频按钮集合 -->\n              <span class=\"center-bofang\" ref=\"button\">\n                <i\n                  class=\"video\"\n                  :class=\"{videobofang1: pause === `pause${index}`, videozantingtingzhi: play === `play${index}`}\"\n                  @click=\"playVideo(index)\"\n                ></i>\n              </span>\n              <bar\n                class=\"bar\"\n                :index=\"index\"\n                :allTime=\"item.video.durationms\"\n                :time=\"playTime\"\n                :width=\"progressWidth\"\n              ></bar>\n              <!-- @time=\"changeTime\" -->\n            </div>\n          </div>\n          <span class=\"center-bofang\">\n            <i class=\"video videobofang1\" @click=\"playVideo(index, item.video.videoId)\"></i>\n          </span>\n          <span class=\"go-count\">\n            <i class=\"video videobofang\"></i>\n            {{item.video.playTime | setCount}}\n          </span>\n          <span class=\"go-time\">\n            <i class=\"video videoyinlebofangxuanlvjiezou\"></i>\n            {{item.video.durationms | setTime}}\n          </span>\n        </div>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script>\nimport { filterSetPlayCount, filterSetTime } from 'utils/filters'\nimport circleLoading from 'base/circleLoading'\nimport bar from '../audioIndex/components/bar'\nimport api from 'api'\n\nlet lastIndex\nexport default {\n  name: '',\n  data () {\n    return {\n      pause: '',\n      play: '',\n      timer: null,\n      playTime: '00:00',\n      allTime: 0,\n      progressWidth: 0\n    }\n  },\n  props: {\n    data: {\n      type: Array\n    }\n  },\n  filters: {\n    setCount: function (val) {\n      return filterSetPlayCount(val)\n    },\n    setTime: function (val) {\n      return filterSetTime(val)\n    }\n  },\n  methods: {\n    /**\n    视频点击播放思路：\n    首先视频标签使用 data-src 获取真正地址，src为空，video标签隐藏\n    点击播放按钮，图片隐藏，video 获取到真正的 src 地址，显示，播放\n    当播放时下方的数据隐藏显示\n    */\n    /**\n    * 这里使用了 async/await处理异步\n    */\n    playVideo (index, id) {\n      // 当点击了播放按钮时，判断是否有上一次的播放\n      if (!isNaN(lastIndex)) {\n        // 如果有过播放，并且当前播放的与上一个播放的不是一个\n        if (lastIndex !== index) {\n          // 获取到上一个的视频标签，执行隐藏，并且停止视频的播放\n          this.stopVideoTag(lastIndex)\n        }\n      }\n      // 更新上一个视频索引\n      lastIndex = index\n      this.$nextTick(async () => {\n        const video = this.$refs.video[index]\n        // // 当没有值的时候，src默认为 http://localhost:8080/，通过判断是否包含localhost来判断当前src的值是否是真正的视频地址\n        // 给src设置默认值为localhost\n        if (video.src.includes('localhost')) {\n          // 显示loading样式\n          this.$refs.load[index].block()\n          // 这里会等待请求数据\n          const res = await api.getVideoUrlFn(id)\n          // 赋值给src开始加载\n          video.src = res.data.urls[0].url\n        }\n        // 显示视频元素\n        this.showVideoTag(index)\n        // 显示相关btn按钮\n        this.showFnBtn(index)\n        if (video.paused) {\n          // 暂停 -> 播放\n          this.videoPlay(video, index)\n        } else {\n          // 播放 -> 暂停\n          this.videoPause(video, index)\n        }\n      })\n    },\n    stopVideoTag (index) {\n      console.log(index, lastIndex)\n      const i = index || lastIndex\n      // 时常注意在判断0的时候会成false\n      // 如果需要可以使用 isNaN() 判断是否是非数 再取反 就可以获得正确的结果\n      if (!isNaN(i)) {\n        const video = this.$refs.video[i]\n        this.hideVideoTag(i)\n        // 停止视频播放\n        video.pause()\n        video.currentTime = 0\n      }\n    },\n    /**\n     * 显示相关按钮\n     */\n    showFnBtn (index) {\n      this.$refs.fnBtn[index].style.zIndex = 1\n      this.play = `play${index}`\n    },\n    /**\n     * 设置当前播放时长\n     */\n    setBarTime (index) {\n      // 首先我们计算到当前的播放时间\n      const video = this.$refs.video[index]\n      let minutes = Math.floor(video.currentTime / 60)\n      let seconds = Math.floor(video.currentTime - minutes * 60)\n      let minuteValue\n      let secondValue\n      // 进行格式转换，当分钟小于10的时候，在前面加0\n      if (minutes < 10) {\n        minuteValue = '0' + minutes\n      } else {\n        minuteValue = minutes\n      }\n      // 秒数的格式设置\n      if (seconds < 10) {\n        secondValue = '0' + seconds\n      } else {\n        secondValue = seconds\n      }\n      // 进行时间值拼接，展示到页面\n      let audioTime = minuteValue + ':' + secondValue\n      this.playTime = audioTime\n      // // 进度条的长度计算\n      let barLength = video.currentTime / video.duration * 100\n      this.setProgress(barLength)\n    },\n    /**\n     * 设置进度条长度\n     */\n    setProgress (val) {\n      if (val < 0 || val > 100) {\n        return\n      }\n      this.progressWidth = val\n    },\n    /**\n     * 当前可以播放了\n     */\n    startPlay (index) {\n      this.$refs.load[index].none()\n    },\n    /**\n     * 显示整个video区域\n     */\n    showVideoTag (index) {\n      const videoBtn = this.$refs.playVideo[index]\n      videoBtn.style.zIndex = 1\n    },\n    /**\n     * 隐藏整个 video 区域\n     */\n    hideVideoTag (index) {\n      const videoBtn = this.$refs.playVideo[index]\n      videoBtn.style.zIndex = '-1'\n    },\n    /**\n     * 播放视频\n     */\n    videoPlay (video, index) {\n      video.play()\n      this.play = `play${index}`\n      this.pause = ``\n      this.hideFnBtn(index)\n    },\n    /**\n     * 当视频正在播放时的事件\n     */\n    changeTime (time, index) {\n      const video = this.$refs.video[index]\n      const current = time * video.duration / 100\n      video.currentTime = current\n      this.videoPlay(video, index)\n    },\n    /**\n     * 暂停视频\n     */\n    videoPause (video, index) {\n      video.pause()\n      this.hideFnBtn(index)\n      this.pause = `pause${index}`\n      this.play = ``\n    },\n    /**\n     * 在一段时间没有操作后隐藏工具按钮\n     */\n    hideFnBtn (index) {\n      const _self = this\n      this.showFnBtn(index)\n      _self.$refs.fnBtn[index].style.display = 'block'\n      if (this.timer) {\n        clearTimeout(this.timer)\n      }\n      this.timer = setTimeout(function () {\n        _self.$refs.fnBtn[index].style.display = 'none'\n      }, 2000)\n    }\n  },\n  components: {\n    circleLoading,\n    bar\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"//at.alicdn.com/t/font_1477601_lo5yxiay04f.css\");\n\n@import url(\"~styles/global.less\");\n\n@imgWidth: 5.4rem;\n@imgHeight: 2.8rem;\n\n.none {\n  display: none;\n}\n\n.videotag {\n  box-sizing: border-box;\n  font-size: 0.2rem;\n  color: #ccc;\n  padding: 0.04rem 0.13rem;\n}\n.wrapper {\n  display: flex;\n  padding-bottom: 0.3rem;\n  margin: 0.3rem 0;\n  .img-info {\n    width: 1rem;\n    height: 0;\n    padding-bottom: 1rem;\n    margin-right: 0.2rem;\n    img {\n      width: 100%;\n      border-radius: 50%;\n    }\n  }\n  .author {\n    flex: 1;\n    line-height: 1.5;\n    .nickname {\n      color: #3399ea;\n      .category {\n        color: #7b7c7d;\n      }\n    }\n    .fans {\n      font-size: 0.2rem;\n      color: #7b7c7d;\n    }\n    .img-content {\n      width: 5.4rem;\n      height: 0;\n      padding-bottom: 2rem;\n      img {\n        width: 100%;\n        border-radius: 0.2rem;\n      }\n    }\n    .videoInfo {\n      position: relative;\n      width: @imgWidth;\n      padding-bottom: @imgHeight;\n      height: 0;\n      margin-top: 0.23rem;\n      .play-video {\n        position: absolute;\n        top: 0;\n        width: @imgWidth;\n        height: @imgHeight;\n        background-color: #222;\n        border-radius: 0.2rem;\n        z-index: -1;\n        .video_tag {\n          position: absolute;\n          width: @imgWidth;\n          border-radius: 0.2rem;\n          height: @imgHeight;\n        }\n        .fn-btn {\n          width: @imgWidth;\n          height: @imgHeight;\n          .bar {\n            position: absolute;\n            bottom: -0.3rem;\n            left: 0;\n            right: 0;\n          }\n        }\n      }\n      .center-bofang {\n        position: absolute;\n        top: 50%;\n        left: 50%;\n        transform: translate(-50%, -50%);\n        .videobofang1,\n        .videozantingtingzhi {\n          font-size: 0.8rem;\n          color: rgba(255, 255, 255, 0.7);\n        }\n      }\n      .go-count {\n        position: absolute;\n        bottom: 0.1rem;\n        left: 0.1rem;\n        .videotag();\n        .videobofang {\n          font-size: 0.24rem;\n          margin-right: 3px;\n        }\n      }\n      .go-time {\n        position: absolute;\n        bottom: 0.1rem;\n        right: 0.1rem;\n        .videotag();\n        .videoyinlebofangxuanlvjiezou {\n          font-size: 0.2rem;\n          margin-right: 3px;\n        }\n      }\n      .tag {\n        position: absolute;\n        top: 0.2rem;\n        right: 0.13rem;\n        .videotag();\n        border-radius: 0.3rem;\n        border: 1px solid #777;\n      }\n      img {\n        width: @imgWidth;\n        border-radius: 0.2rem;\n        height: @imgHeight;\n      }\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/homeIndex/components/addNewPlayList.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-26 13:09:11\n * @Update: 2019-11-03 13:02:37\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"middle\">\n    <div class=\"mask\" v-show=\"isShow\" @click=\"hide\"></div>\n    <div class=\"addInfo pd23\" v-show=\"isShow\">\n      <h1 class=\"title\">新建歌单</h1>\n      <div class=\"inp\">\n        <input\n          class=\"playlistName\"\n          type=\"text\"\n          placeholder=\"请输入歌单标题\"\n          ref=\"inp\"\n          autofocus=\"autofocus\"\n          v-model.trim=\"playListName\"\n        />\n        <i v-show=\"playListName\" @click=\"clearInp\" class=\"search search-guanbi\"></i>\n      </div>\n      <div class=\"line\">\n        <van-checkbox v-model=\"checked\" shape=\"square\" checked-color=\"#dd001b\">设置为隐私歌单</van-checkbox>\n        <span class=\"length\">{{ playListName.length }}/40</span>\n      </div>\n      <div class=\"button\">\n        <div class=\"btn\" @click=\"hide\">取消</div>\n        <div class=\"btn\" :class=\"{disable: !playListName}\" @click=\"pushNewPlaylist\">提交</div>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nexport default {\n  data () {\n    return {\n      isShow: false,\n      playListName: '',\n      checked: false\n    }\n  },\n  created () {\n    this.changeFocus()\n  },\n  methods: {\n    open () {\n      this.isShow = true\n    },\n    hide () {\n      this.isShow = false\n    },\n    open2 () {\n      this.$message({\n        message: '成功添加歌单,请2分钟后刷新查看',\n        type: 'success'\n      })\n    },\n    /**\n     * 添加歌单\n     * 如果隐私选框选中则checked为true，设置 privacy 值为 10\n     * 点击确定按钮提交数据\n     * 隐藏弹框\n     */\n    pushNewPlaylist () {\n      let privacy\n      if (this.checked) {\n        privacy = 10\n      }\n      api.addPlaylistFn(this.playListName, privacy)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.open2()\n            this.clearInp()\n            this.hide()\n          }\n        }).catch(err => {\n          console.log(err)\n        })\n    },\n    changeFocus () {\n      this.$nextTick(x => {\n        this.$refs.inp.focus()\n      })\n    },\n    clearInp () {\n      this.playListName = ''\n    }\n  }\n}\n</script>\n\n<style lang=\"less\">\n@import url(\"~styles/global.less\");\n@import url(\"//at.alicdn.com/t/font_1436508_eifw3uhnvb.css\");\n\n.addInfo {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  z-index: 11;\n  transform: translate3d(-50%, -50%, 0);\n  width: 90vw;\n  height: 3.3rem;\n  background-color: #fff;\n  border-radius: 0.2rem;\n  .title {\n    margin-top: 0.33rem;\n    font-weight: 700;\n  }\n  .inp {\n    position: relative;\n    .playlistName {\n      margin-top: 0.3rem;\n      padding: 0.1rem 0;\n      width: 5.5rem;\n      border-bottom: 1px solid #999;\n    }\n    .search-guanbi {\n      position: absolute;\n      bottom: 0.1rem;\n      right: 0.1rem;\n    }\n  }\n  .line {\n    margin-top: 0.1rem;\n    .flex-between();\n  }\n  .button {\n    margin-top: 0.2rem;\n    display: flex;\n    justify-content: flex-end;\n    color: @bgcolor;\n    .btn {\n      margin: 0.3rem 0.2rem;\n    }\n    .disable {\n      opacity: 0.3;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/homeIndex/components/homeList.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-11-14 13:34:02\n * @Update log: 我的页面的列表项\n -->\n<template>\n  <div class=\"container pd13\">\n    <ul>\n      <li v-for=\"(item, index) in homeListContext\" :key=\"index\" class=\"list-item\">\n        <i class=\"home\" :class=\"item.icon\"></i>\n        <div class=\"border-bottom wrapper\" @click.stop=\"handleClick(item.text)\">\n          <span class=\"list-content\">{{item.text}}</span>\n          <span class=\"num\" ref=\"homeNum\">({{item.num}})</span>\n        </div>\n      </li>\n    </ul>\n  </div>\n</template>\n\n<script>\nimport { homeList } from 'getInfos/getData'\n\nexport default {\n  name: 'homeList',\n  data () {\n    return {\n      homeListContext: []\n    }\n  },\n  props: ['num'],\n  mounted () {\n    // 存取props 传过来的数据\n    this.recordNum = this.num.recordNum\n    this.djNum = this.num.djNum\n    // 首先获取到初始化的数据，防止页面坍塌\n    this.homeListContext = homeList()\n  },\n  watch: {\n    // props 异步请求，初始加载时无法获取到props传过来的值\n    num: {\n      // 为了发现对象内部值的变化，可以在选项参数中指定 deep: true 。\n      // 这样设置后 props 成功可以获取到\n      deep: true,\n      handler (val, oldVal) {\n        this.recordNum = val.recordNum\n        this.djNum = val.djNum\n        this.setData()\n      }\n    }\n  },\n  methods: {\n    /**\n     * 对传过来的原数据进行修改\n     */\n    setData () {\n      // 初始化图标和文字\n      let item = homeList()\n      /**\n       * 通过筛选 对传入的数据进行修改\n       */\n      this.$set(item[1], 'num', this.recordNum)\n      this.$set(item[3], 'num', this.djNum)\n      this.homeListContext = item\n    },\n    handleClick (name) {\n      console.log(name)\n      switch (name) {\n        case '最近播放':\n          this.$router.push('/recently')\n          break\n        case '我的收藏':\n          this.$router.push('/favorite')\n          break\n        case '我的电台':\n          this.$router.push('/dj_sublist')\n          break\n        default:\n          break\n      }\n    }\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url(\"~styles/global.less\");\n.list-item {\n  .flex-between();\n  margin: 0.1rem 0;\n  line-height: 0.76rem;\n  .ripple();\n  &:last-child .wrapper::before {\n    border: none;\n  }\n  .list-content {\n    font-size: 0.3rem;\n  }\n  .wrapper {\n    flex: 1;\n    .num {\n      .num();\n    }\n  }\n  .home {\n    font-size: 0.5rem;\n    margin: 0 0.4rem;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/homeIndex/components/icons.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-10-03 19:52:18\n * @Update log: 我的页面图标展示\n *              可左右滑动\n -->\n<template>\n  <div class=\"wrapper border-bottom\">\n    <div class=\"container\">\n      <ul class=\"icons-group\">\n        <!-- <li class=\"icon-list\" v-for=\"(item, index) in homeIcons\" :key=\"index\">\n          <div class=\"icon\">\n            <el-button type=\"danger\" :class=\"item.icon\" class=\"home\" size=\"small\" circle></el-button>\n          </div>\n          <span class=\"icon-text\">{{item.text}}</span>\n        </li>-->\n        <li\n          v-for=\"(item, index) in homeIcons\"\n          :icons=\"item\"\n          :key=\"index\"\n          is=\"icon\"\n          :width=\"true\"\n          :bgcolor=\"true\"\n        ></li>\n      </ul>\n    </div>\n  </div>\n</template>\n\n<script>\nimport { homeIcons } from 'getInfos/getData'\nimport icon from 'base/icon'\nexport default {\n  name: 'homeIcons',\n  data () {\n    return {\n      homeIcons\n    }\n  },\n  mounted () {\n    this.iniData()\n  },\n  methods: {\n    async iniData () {\n      this.homeIcons = homeIcons()\n    }\n  },\n  components: {\n    icon\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url(\"~styles/global.less\");\n.wrapper {\n  box-sizing: border-box;\n  padding: 0.2rem 0 0;\n  overflow: hidden;\n  height: 1.8rem;\n  // 定义可左右滑动的图标组\n  .container {\n    // 横向滚动条\n    overflow-x: scroll;\n    .icons-group {\n      // flex布局 溢出不换行\n      height: 1.5rem;\n      display: flex;\n      flex-wrap: nowrap;\n      align-items: center;\n      white-space: nowrap;\n      width: auto;\n      min-width: 100%;\n      // .icon-list {\n      //   // 每项 icon 样式\n      //   min-width: 1.6rem;\n      //   height: 100%;\n      //   .flex-around();\n      //   flex-direction: column;\n      //   align-items: center;\n      //   .icon {\n      //     width: @iconWidth * 0.72;\n      //     height: @iconWidth * 0.72;\n      //     line-height: @iconWidth * 0.72;\n      //     .icons();\n      //     .home {\n      //       font-size: 0.4rem;\n      //     }\n      //   }\n      //   .exit-icon {\n      //     background: #ccc;\n      //   }\n      //   .icon-text {\n      //     font-size: @iconText;\n      //   }\n      // }\n    }\n  }\n}\n::-webkit-scrollbar {\n  display: none;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/homeIndex/components/songList.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-11-14 13:45:17\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"container pd13\" @click.stop>\n    <div class=\"wrapper-title\">\n      <div class=\"left-title\">\n        <i class=\"home iconarrow\"></i>\n        <span class=\"title\">创建的歌单</span>\n        <span class=\"num\">({{index.createNum}})</span>\n      </div>\n      <div class=\"right-title\">\n        <!-- 点击添加按钮显示新建歌单 -->\n        <i class=\"home iconincrease\" @click=\"showAddNewPlayList\"></i>\n        <i class=\"home icondiandiandian\"></i>\n      </div>\n    </div>\n    <ul class=\"song-group\">\n      <!-- 没登录的情况下会有我喜欢的音乐列表项显示 -->\n      <li class=\"song-list\" v-if=\"!myLoveList.length\">\n        <div class=\"list-cover\">\n          <i class=\"home iconxin\"></i>\n        </div>\n        <div class=\"list-info\">\n          <p class=\"list-title\">我喜欢的音乐</p>\n          <p class=\"list-num\">0首</p>\n        </div>\n        <div class=\"heart-module\">\n          <span class=\"heart-text\">\n            <i class=\"home iconxintiao\"></i>心动模式\n          </span>\n        </div>\n      </li>\n      <!-- 登录后的歌单项显示 -->\n      <li class=\"song-list\" v-for=\"(item, index) in myLoveList\" :key=\"index\">\n        <a class=\"cover\" style=\"width:70%;\" @click=\"goAlbumPage(item.id)\"></a>\n        <div class=\"list-img\">\n          <img :src=\"item.coverImgUrl + '?param=100y100'\" />\n        </div>\n        <div class=\"list-info\">\n          <p class=\"list-title\">{{ item.name | setName}}</p>\n          <p class=\"list-num\">{{item.trackCount}}首</p>\n        </div>\n        <div class=\"heart-module\">\n          <span class=\"heart-text\" @click.stop=\"heartMode(item.id)\">\n            <i class=\"home iconxintiao\"></i>心动模式\n          </span>\n        </div>\n      </li>\n      <!-- Duplicate keys detected: '0'. This may cause an update error -->\n      <!-- key 值重复 -->\n      <li class=\"song-list\" v-for=\"(item, index) in createList\" :key=\"index + 1\">\n        <a class=\"cover\" @click=\"goAlbumPage(item.id)\"></a>\n        <div class=\"list-img\">\n          <img :src=\"item.coverImgUrl + '?param=100y100'\" />\n          <i class=\"home iconsuo\" v-show=\"item.privacy\"></i>\n        </div>\n        <div class=\"list-info\">\n          <p class=\"list-title\">{{ item.name}}</p>\n          <p class=\"list-num\">{{item.trackCount}}首</p>\n        </div>\n        <div class=\"heart\">\n          <i\n            class=\"home icondiandiandian\"\n            @click.stop=\"showSlider(item.name, item.id, item.subscribed)\"\n          ></i>\n        </div>\n      </li>\n    </ul>\n    <div class=\"wrapper-title\" v-if=\"index.favoritesNum\">\n      <div class=\"left-title\">\n        <i class=\"home iconarrow\"></i>\n        <span class=\"title\">收藏的歌单</span>\n        <span class=\"num\">({{index.favoritesNum}})</span>\n      </div>\n      <div class=\"right-title\">\n        <i class=\"home iconincrease\"></i>\n        <i class=\"home icondiandiandian\"></i>\n      </div>\n    </div>\n    <!-- 收藏的歌单 -->\n    <ul class=\"song-group\">\n      <li class=\"song-list\" v-for=\"(item, index) in favoritesList\" :key=\"index\">\n        <a class=\"cover\" @click=\"goAlbumPage(item.id)\"></a>\n        <div class=\"list-img\">\n          <img :src=\"item.coverImgUrl + '?param=100y100'\" />\n        </div>\n        <div class=\"list-info\">\n          <p class=\"list-title ellipsis\">{{ item.name}}</p>\n          <p class=\"list-num\">\n            {{item.trackCount}}首\n            <span class=\"nickname\">by {{item.creator.nickname}}</span>\n          </p>\n        </div>\n        <div class=\"heart\">\n          <i\n            class=\"home icondiandiandian\"\n            @click.stop=\"showSlider(item.name, item.id, item.subscribed)\"\n          ></i>\n        </div>\n      </li>\n    </ul>\n    <add-new-playlist ref=\"addNewPlaylist\"></add-new-playlist>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport addNewPlaylist from './addNewPlayList'\nexport default {\n  name: 'songList',\n  data () {\n    return {\n      // 收藏歌单详情\n      favoritesList: [],\n      // 创建歌单详情\n      createList: [],\n      // 我的喜欢歌单\n      myLoveList: []\n    }\n  },\n  // 使用筛选功能，将列表中的 我喜欢的音乐 标题正确渲染\n  filters: {\n    setName: function (value) {\n      let reg = new RegExp(/喜欢的音乐$/)\n      if (reg.test(value)) {\n        value = '我喜欢的音乐'\n      }\n      return value\n      // value = value.toString()\n      // return value.charAt(0).toUpperCase() + value.slice(1)\n    }\n  },\n  props: ['index'],\n  mounted () {\n    this.favoritesIndex = this.index.favoritesNum\n    this.createIndex = this.index.createNum\n    this.getPlaylist(this.$store.state.accountUid)\n  },\n  watch: {\n    index: {\n      deep: true,\n      handler (val, oldVal) {\n        this.createIndex = val.createNum\n        this.favoritesIndex = val.favoritesNum\n        this.getPlaylist(this.$store.state.accountUid)\n      }\n    }\n  },\n  methods: {\n    showAddNewPlayList () {\n      this.$refs.addNewPlaylist.open()\n    },\n    showSlider (name, id, type) {\n      this.$emit('showSlider', name, id, type)\n    },\n    /**\n     * 跳转到歌单详情页面\n     */\n    goAlbumPage (id) {\n      this.$router.push({ name: 'albumPage', params: { albumId: id } })\n    },\n    /**\n     * 返回一个随机数\n     */\n    randomNum (min, max) {\n      return parseInt(Math.random() * (max - min + 1) + min, 10)\n    },\n    /**\n     * 开启心动模式\n     * 需要获取到歌单id\n     * 歌曲id\n     * 请求到歌单的歌曲信息，随机从中选择一项歌曲开始播放\n     */\n    heartMode (listId) {\n      const pid = listId\n      let id\n      api.albumDetailFn(pid)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            const arr = data.playlist.trackIds\n            const index = this.randomNum(0, arr.length)\n            const item = arr[index]\n            id = item.id\n            this.$emit('heartMode', id, pid)\n          }\n        })\n    },\n    /**\n     * 获取用户歌单\n     * 增加时间戳\n     */\n    getPlaylist (id) {\n      // 时间戳\n      const data = +new Date()\n      api.playlistFn(id, data).then(res => {\n        let data = res.data\n        if (data.code === 200) {\n          this.sliceInfo(data.playlist)\n        }\n      })\n    },\n    /**\n     * 得到数组，分割赋值\n     * 根据传入的 index 值分割总歌单数组\n     * @param {Array} arr\n     */\n    sliceInfo (arr) {\n      let from = this.createIndex\n      let len = this.createIndex + this.favoritesIndex\n      this.createList = arr.slice(0, from)\n      this.myLoveList = this.createList.slice(0, 1)\n      this.createList = this.createList.slice(1)\n      this.favoritesList = arr.slice(from, len)\n    }\n  },\n  components: {\n    addNewPlaylist\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url(\"~styles/global.less\");\n\n@listHeight: 1rem;\n\n.wrapper-title {\n  width: 100%;\n  height: @listHeight;\n  line-height: @listHeight;\n  .flex-between();\n  .left-title {\n    .title {\n      font-size: 0.32rem;\n      font-weight: 700;\n    }\n    .num {\n      .num();\n    }\n  }\n  .right-title {\n    .icondiandiandian {\n      margin-left: 0.13rem;\n    }\n  }\n}\n.song-group {\n  .song-list {\n    width: 100%;\n    margin: 0.16rem 0;\n    .flex-between();\n    .ripple();\n    .list-cover {\n      border-radius: @imgBorderRadius;\n      width: @listHeight;\n      height: @listHeight;\n      line-height: @listHeight;\n      text-align: center;\n      margin-right: 0.3rem;\n      overflow: hidden;\n      background: rgba(0, 0, 0, 0.8);\n      .iconxin {\n        font-size: 0.5rem;\n        color: #fff;\n      }\n    }\n    .list-img {\n      position: relative;\n      border-radius: @imgBorderRadius;\n      width: @listHeight;\n      height: @listHeight;\n      line-height: @listHeight;\n      text-align: center;\n      margin-right: 0.3rem;\n      overflow: hidden;\n      img {\n        width: 100%;\n        height: 100%;\n      }\n      .iconsuo {\n        position: absolute;\n        right: 0.15rem;\n        bottom: 0.45rem;\n        color: #fff;\n        width: 0.13rem;\n        height: 0.13rem;\n      }\n    }\n    .list-info {\n      flex: 1;\n      display: flex;\n      flex-direction: column;\n      align-items: flex-start;\n      justify-content: center;\n      .list-title {\n        max-width: 5rem;\n        font-size: 0.3rem;\n      }\n      .list-num {\n        margin-top: 0.13rem;\n        font-size: 0.2rem;\n        color: #ccc;\n        .nickname {\n          margin-left: 0.2rem;\n        }\n      }\n    }\n    .heart,\n    .heart-module {\n      height: @listHeight;\n      display: flex;\n      align-items: center;\n      justify-content: flex-end;\n      .icondiandiandian {\n        color: rgba(0, 0, 0, 0.5);\n      }\n      .heart-text {\n        .smallTag();\n        .iconxintiao {\n          font-size: 0.2rem;\n          font-weight: 700;\n        }\n      }\n    }\n    .heart {\n      width: 0.3rem;\n    }\n    .heart-module {\n      width: 2rem;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/homeIndex/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-10-12 13:17:54\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"container\">\n    <home-icons></home-icons>\n    <home-list :num=\"homeListNum\"></home-list>\n    <div class=\"split\"></div>\n    <song-list ref=\"songList\" :index=\"songListNum\" @showSlider=\"showSlider\" @heartMode=\"_heartMode\"></song-list>\n    <slider\n      ref=\"slider\"\n      :title=\"title\"\n      :id=\"id\"\n      :homeFavoritelistSlider=\"homeFavoritelistSlider\"\n      :homePlaylistSlider=\"homePlaylistSlider\"\n    ></slider>\n    <div id=\"audio_pb1\" v-show=\"!isMiniAudio\"></div>\n  </div>\n</template>\n\n<script>\nimport { mapGetters, mapActions } from 'vuex'\nimport homeIcons from './components/icons'\nimport homeList from './components/homeList'\nimport songList from './components/songList'\nimport slider from 'base/slider'\nimport api from 'api'\n\nexport default {\n  name: 'homeIndex',\n  data () {\n    return {\n      // 我的页面上部列表\n      homeListNum: {\n        // 播放记录\n        recordNum: 0,\n        // 我的电台\n        djNum: 0\n      },\n      songListNum: {\n        // 创建的歌单\n        createNum: 0,\n        // 收藏的歌单\n        favoritesNum: 0\n      },\n      heartModeList: [],\n      title: '',\n      id: 0,\n      homePlaylistSlider: false,\n      homeFavoritelistSlider: false\n    }\n  },\n  components: {\n    homeIcons,\n    homeList,\n    songList,\n    slider\n  },\n  methods: {\n    /**\n     * 开启心动模式\n     */\n    _heartMode (id, pid) {\n      api.heartModeFn(id, pid)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            let arr = data.data\n            this.ruleModeList(arr, 'songInfo')\n            console.log(this.heartModeList)\n            this.startPlayAll({\n              list: this.heartModeList\n            })\n          }\n        })\n    },\n    /**\n     * 对请求到的心动模式数据进行修改，使得可以播放\n     */\n    ruleModeList (arr, item) {\n      arr.forEach(ele => {\n        this.heartModeList.push(ele[item])\n      })\n    },\n    /**\n     * 显示下方的滑块\n     */\n    showSlider (name, id, type) {\n      this.title = '歌单：' + name\n      this.id = id\n      if (type) {\n        this.homeFavoritelistSlider = true\n        this.homePlaylistSlider = false\n      } else {\n        this.homeFavoritelistSlider = false\n        this.homePlaylistSlider = true\n      }\n      this.$refs.slider.showSlider()\n    },\n    /**\n     * 获取用户播放记录\n     * @param id 用户 uid\n     */\n    getRecord (id) {\n      // 当用户刷新页面时 vuex 状态失效，采用本地存储\n      let uid = localStorage.getItem('accountUid')\n      id = id || uid\n      api\n        .userRecordFn(id)\n        .then(res => {\n          this.homeListNum.recordNum = res.data.weekData.length\n        })\n        .catch(err => {\n          console.log(err)\n        })\n    },\n    /**\n     * 获取用户信息\n     * 更新我的电台、创建的歌单、收藏的歌单数\n     */\n    _getInfo () {\n      const data = +new Date()\n      api.userInfoFn(data).then(res => {\n        let data = res.data\n        if (data.code === 200) {\n          // 更新我的电台数\n          this.homeListNum.djNum = data.djRadioCount\n          // 更新创建的歌单数\n          this.songListNum.createNum = data.createdPlaylistCount\n          // 更新收藏的歌单数\n          this.songListNum.favoritesNum = data.subPlaylistCount\n        }\n      })\n    },\n    ...mapActions(['startPlayAll'])\n  },\n  computed: {\n    ...mapGetters({\n      loginState: 'LOGIN_STATE',\n      isMiniAudio: 'FULL_SCREEN',\n      accountUid: 'ACCOUNT_UID'\n    })\n  },\n  activated () {\n    /**\n     *\n     * 需要增加判断，要不然每次跳转到这个路由都会有事件\n     *\n     */\n    // 获取用户登录成功后储存的登录标志\n    let getFlag = +localStorage.getItem('loginState')\n    if (this.loginState || getFlag) {\n      // 用户已经登录\n      // 获取用户信息\n      this._getInfo()\n      // 获取用户播放记录\n      this.getRecord(this.accountUid)\n      // this.$refs.songList.getPlaylist()\n    }\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url(\"~styles/global.less\");\n@import url(\"//at.alicdn.com/t/font_1322300_t3s39ptd6ao.css\");\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/idx/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-06 11:39:05\n * @Update: 2019-10-24 08:44:46\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper pd23\">\n    <general-nav @returnPage=\"returnPage\" class=\"titleFixed\">\n      <span class=\"text\">排行榜</span>\n    </general-nav>\n    <page-loading v-show=\"load\"></page-loading>\n    <div v-show=\"!load\">\n      <div class=\"title\">官方榜</div>\n      <idx-card\n        v-for=\"(item, index) in officialIdxList\"\n        :key=\"index\"\n        :imgUrl=\"item.coverImgUrl\"\n        :tracks=\"item.tracks\"\n        :idx=\"item.name\"\n        :updateTime=\"item.updateFrequency\"\n        @showIdxPage=\"showIdxPage\"\n      ></idx-card>\n      <div class=\"title\">推荐榜</div>\n      <div class=\"img-col\">\n        <img-card\n          v-for=\"(item, index) in recommendedIdxList\"\n          :key=\"index\"\n          :imgUrl=\"item.coverImgUrl\"\n          :dec=\"item.name\"\n          :updateTime=\"item.updateFrequency\"\n          :idx=\"item.name\"\n          @showIdxPage=\"showIdxPage\"\n        ></img-card>\n      </div>\n      <div class=\"title\">更多榜单</div>\n      <div class=\"img-col\">\n        <img-card\n          v-for=\"(item, index) in moreIdxList\"\n          :key=\"index\"\n          :imgUrl=\"item.coverImgUrl\"\n          :dec=\"item.name\"\n          :updateTime=\"item.updateFrequency\"\n          :idx=\"item.name\"\n          @showIdxPage=\"showIdxPage\"\n        ></img-card>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script>\nimport generalNav from 'base/generalNav'\nimport idxCard from 'base/idxCard'\nimport imgCard from 'base/imgCard'\nimport pageLoading from 'base/pageLoading'\n\nimport api from 'api'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      load: true,\n      officialIdxList: [],\n      recommendedIdxList: [],\n      moreIdxList: []\n    }\n  },\n  created () {\n    this._getIdxInfo()\n  },\n  methods: {\n    _getIdxInfo () {\n      api.topListFn()\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.officialIdxList = data.list.slice(0, 4)\n            this.recommendedIdxList = data.list.slice(4, 10)\n            this.moreIdxList = data.list.slice(10)\n            this.load = false\n          }\n        })\n    },\n    returnPage () {\n      this.$router.go(-1)\n    },\n    showIdxPage (id) {\n      this.$router.push({ name: 'albumPage', params: { idxId: id } })\n    }\n  },\n  components: {\n    generalNav,\n    idxCard,\n    imgCard,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.wrapper {\n  .text {\n    font-size: 0.4rem;\n    vertical-align: 5px;\n  }\n  .title {\n    font-weight: 700;\n    height: 1rem;\n    line-height: 1rem;\n  }\n  .img-col {\n    .flex-between();\n    flex-wrap: wrap;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/loginIndex/components/accountLogin.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-25 13:23:44\n * @Update: 2019-12-04 18:37:14\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\">\n    <login-nav @returnPage=\"returnPage\">\n      <span class=\"text\">{{text}}</span>\n    </login-nav>\n    <slot></slot>\n  </div>\n</template>\n\n<script>\nimport loginNav from 'base/generalNav'\n\nexport default {\n  name: 'loginIndex',\n  components: {\n    loginNav\n  },\n  data () {\n    return {\n      text: '手机号登录'\n    }\n  },\n  methods: {\n    returnPage () {\n      console.log('111')\n\n      this.$router.go(-1)\n    }\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n.wrapper {\n  box-sizing: border-box;\n  padding: 0.23rem;\n}\n.text {\n  font-size: 0.4rem;\n  vertical-align: 5px;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/loginIndex/components/phoneAccount.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-12 18:16:59\n * @Update: 2019-12-04 18:32:14\n * @Update log: 手机号登陆账号页面\n -->\n<template>\n  <account-login>\n    <div class=\"wrapper\">\n      <div class=\"info\">未注册手机号登录后将自动创建账号</div>\n      <!-- 绑定内联样式 使用 对象 -->\n      <div class=\"inp border-bottom\" :style=\"{opacity}\">\n        <span>+86</span>\n        <input\n          type=\"text\"\n          v-model.trim=\"phone\"\n          placeholder=\"请输入手机号\"\n          ref=\"inputs\"\n          autofocus=\"autofocus\"\n          @input=\"canShow\"\n        />\n        <i v-show=\"isShow\" class=\"phone iconguanbi\" @click=\"clearInput\"></i>\n      </div>\n      <login-btn @click.native=\"clickEvent\"></login-btn>\n      <transition>\n        <!-- 提示语 -->\n        <alert :is-alert=\"alert\" alert=\"请输入11位数字的手机号\"></alert>\n      </transition>\n    </div>\n  </account-login>\n</template>\n\n<script>\nimport loginBtn from 'base/button'\nimport accountLogin from './accountLogin'\nimport alert from 'base/alert'\nimport api from 'api'\n\nexport default {\n  name: 'phoneAccount',\n  data () {\n    return {\n      phone: '',\n      isShow: false,\n      opacity: 0.5,\n      alert: false,\n      timer: null,\n      flag: true\n    }\n  },\n  components: {\n    loginBtn,\n    alert,\n    accountLogin\n  },\n  methods: {\n    // 在vue生命周期的created()钩子函数进行的DOM操作要放在Vue.nextTick()的回调函数中，\n    // 因为created()钩子函数执行的时候DOM并未进行任何渲染，而此时进行DOM操作是徒劳的，所以此处一定要将DOM操作的JS代码放进Vue.nextTick()的回调函数中。\n    changFocus () {\n      this.$nextTick(x => {\n        this.$refs.inputs.focus()\n      })\n    },\n    /**\n     * 判断当前输入内容是否合法\n     * @param {String} text 手机号\n     */\n    contextIsTrue (text) {\n      let exp = /^1[345789]\\d{9}$/\n      return exp.test(text)\n    },\n    /**\n     * 给 叉  添加点击事件，点击清空 input\n     */\n    clearInput () {\n      this.phone = ''\n      this.canShow()\n    },\n    /**\n     * input事件 判断 叉 是否显示\n     * 通过里面是否为空，设置input框样式\n     * 空的时候input有opacity\n     */\n    canShow () {\n      this.isShow = this.phone\n      if (this.isShow) {\n        this.opacity = 1\n      } else {\n        this.opacity = 0.5\n      }\n    },\n    /**\n     * 提示组件的事件\n     */\n    alertEvent () {\n      // 如果输入内容不合法，提示组件显示\n      // 显示一段时间后隐藏\n      if (this.timer) {\n        clearTimeout(this.timer)\n        this.timer = null\n      }\n      this.alert = true\n      // 1s 后隐藏组件\n      this.timer = setTimeout(() => {\n        this.alert = false\n      }, 1000)\n    },\n    /**\n     * 由于在点击时会触发两次请求 设置锁\n     * 点击调用事件 进行判断\n     */\n    clickEvent () {\n      if (this.flag) {\n        // 将按钮禁用\n        this.flag = false\n        if (this.contextIsTrue(this.phone)) {\n          // 如果输入内容合法 进行下一步操作\n          this._determineRegistered(this.phone)\n        } else {\n          // 如果输入内容不合法\n          this.alertEvent()\n          // 输入框内容为空\n          this.clearInput()\n          // 按钮恢复\n          this.flag = true\n        }\n      }\n    },\n    /**\n     * 判断手机号有没有被注册\n     * @param {number} phone\n     */\n    _determineRegistered (phone) {\n      let self = this\n      api.phoneRegisteredFn(phone)\n        .then(res => {\n          if (res.data.exist !== -1) {\n            // 已经注册 跳转到输入密码页面\n            // 携带参数（手机号）跳转\n            this.$router.push({\n              path: '/pwd',\n              query: { phone: self.phone }\n            })\n          } else if (res.data.exist === -1) {\n            // 没有注册 跳转到接收验证码页面\n            this.$router.push({\n              path: '/verify',\n              query: { phone: self.phone }\n            })\n          }\n          this.flag = true\n        })\n    },\n    /**\n     * 当内存中有账号信息时自动填写\n     */\n    autoFill () {\n      let phone = localStorage.getItem('account')\n      if (phone) {\n        this.phone = phone\n        this.canShow()\n        return true\n      }\n      return false\n    }\n  },\n  /**\n   * Vue 实例销毁后调用。\n   * 离开时清除定时器，有利于内存释放\n   */\n  destroyed () {\n    clearTimeout(this.timer)\n  },\n  created () {\n    // 当自动填写后就不自动获取焦点\n    if (this.autoFill()) {\n      this.changFocus()\n    }\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n.wrapper {\n  box-sizing: border-box;\n  padding: 0.23rem;\n  .info {\n    width: 100vw;\n    height: 2rem;\n    display: flex;\n    align-items: center;\n    font-size: small;\n    color: #ccc;\n  }\n  .inp {\n    padding-bottom: 0.1rem;\n    display: flex;\n    align-items: center;\n    input[type=\"text\"] {\n      // IE：不管该行有没有文字，光标高度与font-size一致。\n      // FF：该行有文字时，光标高度与font-size一致。该行无文字时，光标高度与input的height一致。\n      // Chrome：该行无文字时，光标高度与line-height一致；该行有文字时，光标高度从input顶部到文字底部(这两种情况都是在有设定line-height的时候)，如果没有line-height，则是与font-size一致。\n      // 解决的方案：\n      // 给input的height设定一个较小的高度，然后用padding去填充，基本上可以解决所有浏览器的问题\n      height: 16px;\n      padding: 4px 0px;\n      font-size: 0.24rem;\n      // ---------------------------\n      margin-left: 10px;\n      flex: 1;\n      // 修改 input 输入框里闪烁光标的颜色\n      caret-color: red;\n    }\n  }\n  .border-bottom::before {\n    border-color: #aaa;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/loginIndex/components/phonePwd.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-14 15:42:41\n * @Update: 2020-03-13 22:05:44\n * @Update log: 手机号登录密码页面\n -->\n<template>\n  <account-login>\n    <div class=\"wrapper\">\n      <div class=\"inp border-bottom\">\n        <input type=\"password\" v-model=\"pwd\" placeholder=\"请输入密码\" ref=\"inputs\" autofocus=\"autofocus\" />\n        <span @click=\"goForget\">忘记密码</span>\n      </div>\n      <login-btn @click.native=\"logon\" :title=\"title\"></login-btn>\n      <!-- 设置提示语 -->\n      <alert :is-alert=\"alert\" :alert=\"alertText\"></alert>\n      <loading :is-loading=\"loading\"></loading>\n    </div>\n  </account-login>\n</template>\n\n<script>\nimport { getPhone } from 'utils/getPhone'\nimport loginBtn from 'base/button'\nimport alert from 'base/alert'\nimport loading from 'base/loading'\nimport api from 'api'\nimport accountLogin from './accountLogin'\nexport default {\n  name: 'phonePwd',\n  data () {\n    return {\n      pwd: '',\n      alert: false,\n      alertText: '用户名或密码错误',\n      title: '登录',\n      loading: false,\n      flag: true\n    }\n  },\n  components: {\n    loginBtn,\n    alert,\n    loading,\n    accountLogin\n  },\n  methods: {\n    /**\n     * 输入框内容为空\n     */\n    clearInput () {\n      this.pwd = ''\n    },\n    /**\n     * 提示组件的事件\n     */\n    alertEvent () {\n      // 如果输入内容不合法，提示组件显示\n      // 显示一段时间后隐藏\n      if (this.timer) {\n        clearTimeout(this.timer)\n        this.timer = null\n      }\n      this.alert = true\n      // 1s 后隐藏组件\n      this.timer = setTimeout(() => {\n        this.alert = false\n      }, 1000)\n    },\n    /**\n     * 登陆成功后存取登录状态及信息\n     */\n    _getLoginState () {\n      api.loginStatusFn()\n        .then(res => {\n          // 存取用户 id\n          let userId = res.data.profile.userId\n          if (res.data.code === 200) {\n            // 存取用户信息\n            let accountInfo = res.data.profile\n            // 成功登陆\n            // 修改状态为 1\n            this.$store.commit('LOGIN_STATE', 1)\n            // Vuex在用户刷新的时候loginState会回到默认值false\n            // 所以我们需要用到HTML5储存\n            // 我们设置一个名为loginState\n            localStorage.setItem('loginState', 1)\n            // 存入用户头像 昵称\n            localStorage.setItem('avatarUrl', accountInfo.avatarUrl)\n            localStorage.setItem('nickname', accountInfo.nickname)\n            // 存取用户 uid信息\n            this.$store.commit('ACCOUNT_UID', userId)\n            localStorage.setItem('accountUid', userId)\n            this._getUserDetail(userId)\n          }\n        })\n        .catch(err => {\n          console.log(err)\n        })\n    },\n    goForget () {\n      const phone = getPhone()\n      this.$router.push(`/verify?phone=${phone}`)\n    },\n    /**\n     * 获取用户详情\n     * 等级数据\n     * 到获取完成之后跳转到发现页面\n     * 刷新页面\n     */\n    _getUserDetail (uid) {\n      api.userDetailFn(uid)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            this.$store.commit('SET_LEVEL', data.level)\n            localStorage.setItem('level', data.level)\n            // 跳转到发现页面\n            this.$router.push({ path: '/find' })\n            console.log('跳转了')\n            // location.reload()\n          }\n        })\n    },\n    /**\n     * 判断密码是否正确\n     * @param pwd 传入密码内容\n     */\n    passwordIsCorrect (pwd) {\n      if (!pwd) {\n        this.alertText = '请输入密码'\n        this.alertEvent()\n      }\n      let phone = getPhone()\n      this._isSure(phone, pwd)\n    },\n    /**\n     * 判断密码是否正确\n     */\n    _isSure (phone, pwd) {\n      api.phoneLoginFn(phone, pwd)\n        .then(res => {\n          console.log(res)\n          if (res.data.code === 200) {\n            // 密码正确\n            // 将账号存下，以后登录时账号输入框自动填写\n            localStorage.setItem('account', phone)\n            this.success()\n          } else {\n            this.error(res.data.msg)\n          }\n        })\n        // eslint 报 handle-callback-err 错误 添加 if 判断\n        .catch(error => {\n          if (error) {\n            // 密码错误\n            this.error()\n          }\n        })\n    },\n    /**\n     * 登录成功\n     */\n    success () {\n      // loading 样式隐藏\n      this.LoadingEnd()\n      // 存取登陆状态\n      this._getLoginState()\n    },\n    /**\n     * 密码错误登录失败\n     */\n    error (msg) {\n      this.alertText = msg || '用户名或密码错误'\n      // 显示提示信息\n      this.alertEvent()\n      // 输入框内容为空\n      this.clearInput()\n      // loading 样式隐藏\n      this.LoadingEnd()\n      // 登陆按钮的锁去掉\n      this.flag = true\n    },\n    /**\n     * 由于在点击时会触发两次请求 设置flag锁\n     * 点击登录按钮要发生的事件\n     */\n    logon () {\n      if (this.flag) {\n        if (!this.pwd) {\n          this.alertText = '请输入密码'\n          // 显示提示信息\n          this.alertEvent()\n          return\n        }\n        this.flag = false\n        this.Loading()\n        // 判断密码是否正确\n        this.passwordIsCorrect(this.pwd)\n      }\n    },\n    /**\n     * 登陆完成 按钮内容复位\n     * loading样式隐藏\n     */\n    LoadingEnd () {\n      // 将按钮内容设置为 登录.\n      this.title = '登录'\n      // 页面显示loading 样式\n      this.loading = false\n    },\n    /**\n     * 登录中的 loading 设置\n     */\n    Loading () {\n      // 将按钮内容设置为 登录中...\n      this.title = '登录中...'\n      // 页面显示loading 样式\n      this.loading = true\n    },\n    // 在vue生命周期的created()钩子函数进行的DOM操作要放在Vue.nextTick()的回调函数中，\n    // 因为created()钩子函数执行的时候DOM并未进行任何渲染，而此时进行DOM操作是徒劳的，所以此处一定要将DOM操作的JS代码放进Vue.nextTick()的回调函数中。\n    changFocus () {\n      this.$nextTick(x => {\n        this.$refs.inputs.focus()\n      })\n    }\n  },\n  created () {\n    this.changFocus()\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url(\"~styles/global.less\");\n\n.wrapper {\n  box-sizing: border-box;\n  padding: 0.23rem;\n  .inp {\n    padding-bottom: 0.1rem;\n    display: flex;\n    align-items: center;\n    margin-top: 1rem;\n    input[type=\"password\"] {\n      // IE：不管该行有没有文字，光标高度与font-size一致。\n      // FF：该行有文字时，光标高度与font-size一致。该行无文字时，光标高度与input的height一致。\n      // Chrome：该行无文字时，光标高度与line-height一致；该行有文字时，光标高度从input顶部到文字底部(这两种情况都是在有设定line-height的时候)，如果没有line-height，则是与font-size一致。\n      // 解决的方案：\n      // 给input的height设定一个较小的高度，然后用padding去填充，基本上可以解决所有浏览器的问题\n      height: 16px;\n      padding: 4px 0px;\n      font-size: 0.24rem;\n      // ---------------------------\n      margin-left: 10px;\n      flex: 1;\n      // 修改 input 输入框里闪烁光标的颜色\n      caret-color: @bgcolor;\n    }\n  }\n  .border-bottom::before {\n    border-color: #aaa;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/loginIndex/components/phoneVerify.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-18 13:45:09\n * @Update: 2019-12-04 18:35:37\n * @Update log: 手机号验证\n -->\n<template>\n  <account-login>\n    <div class=\"wrapper\">\n      <verify-info></verify-info>\n      <verify-code></verify-code>\n    </div>\n  </account-login>\n</template>\n\n<script>\nimport verifyInfo from './verifyInfo'\nimport verifyCode from './verifyCode'\nimport accountLogin from './accountLogin'\nexport default {\n  name: 'phoneVerify',\n  components: {\n    verifyInfo,\n    verifyCode,\n    accountLogin\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n.wrapper {\n  box-sizing: border-box;\n  padding: 0.23rem;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/loginIndex/components/verifyCode.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-18 14:11:40\n * @Update: 2019-11-05 19:21:06\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"code\">\n    <van-password-input\n      :value=\"value\"\n      :length=\"4\"\n      :gutter=\"15\"\n      :focused=\"showKeyboard\"\n      @focus=\"showKeyboard = true\"\n    />\n    <van-number-keyboard\n      :show=\"showKeyboard\"\n      @input=\"onInput\"\n      @delete=\"onDelete\"\n      @blur=\"showKeyboard = false\"\n    />\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport { Toast } from 'vant'\nimport { getPhone } from 'utils/getPhone'\n\nexport default {\n  name: 'verifyCode',\n  data () {\n    return {\n      value: '',\n      showKeyboard: true\n    }\n  },\n  methods: {\n    async onInput (key) {\n      this.value = (this.value + key).slice(0, 4)\n      if (this.value.length === 4) {\n        const phone = getPhone()\n        const captcha = this.value\n        try {\n          const { data } = await api.verifyFn(phone, captcha)\n          if (data.code === 200) {\n            Toast('验证成功')\n          }\n        } catch (error) {\n          if (error) {\n            Toast(error.msg || '验证失败')\n            this.value = ''\n          }\n        }\n      }\n    },\n    onDelete () {\n      this.value = this.value.slice(0, this.value.length - 1)\n    }\n  }\n\n}\n</script>\n\n<style lang=\"less\" scoped>\n.code /deep/ li {\n  border-bottom: 2px solid #aaa;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/loginIndex/components/verifyInfo.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-18 13:55:05\n * @Update: 2019-08-26 14:30:37\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"container\">\n    <div class=\"info\">\n      <p>验证码已发送至</p>\n      <p>\n        <span>+86</span>\n        <span>\n          {{phone1}}\n          <span class=\"middle\">****</span>\n          {{phone2}}\n        </span>\n      </p>\n    </div>\n    <div class=\"renew\">重新获取</div>\n  </div>\n</template>\n\n<script>\nimport { getPhone } from 'utils/getPhone'\nimport api from 'api'\nexport default {\n  name: 'verifyInfo',\n  // 通过 url 传过来的手机号，存取后进行验证码发送操作\n  data () {\n    return {\n      phone1: 133,\n      phone2: 1234\n    }\n  },\n  watch: {\n    'phone1': {\n      handler: function (val) {\n        this.phone1 = val\n      }\n    },\n    'phone2': {\n      handler: function (val) {\n        this.phone2 = val\n      }\n    }\n  },\n  methods: {\n    /**\n     * 发送验证码\n     */\n    _sendVerify () {\n      let phone = getPhone()\n      // 发送验证码\n      api.sendVerifyFn(phone)\n        .then(res => {\n          console.log(res)\n        })\n        .catch(error => console.log(error))\n    },\n    /**\n     * 截取手机号码进行页面显示\n     */\n    showPhone (phone) {\n      this.phone1 = Array.from(phone).slice(0, 3).join('')\n      this.phone2 = Array.from(phone).slice(-4).join('')\n    },\n    /**\n     * 验证验证码\n     */\n    verify () {\n      let phone = getPhone()\n      let captcha = '111'\n      api.verifyFn(phone, captcha)\n        .then(res => console.log(res))\n        .catch(error => console.log(error))\n    }\n  },\n  created () {\n    const phone = this.$route.query.phone\n    this.showPhone(phone)\n    this._sendVerify()\n  },\n  beforeDestroy () {\n    Object.assign(this.$data, this.$options.data())\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n.container {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  height: 3rem;\n  p:first-child {\n    margin-bottom: 0.3rem;\n  }\n  span {\n    color: #ccc;\n    .middle {\n      vertical-align: -3px;\n    }\n  }\n  .renew {\n    color: #1a73e8;\n    cursor: pointer;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/loginIndex/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-07-30 10:40:39\n * @Update: 2019-12-04 18:36:37\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\" @click=\"goBack\">\n    <div class=\"phoneLogin\" @click.stop=\"goPhone\">手机号登陆</div>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: 'loginPage',\n  methods: {\n    goBack () {\n      history.go(-1)\n    },\n    goPhone () {\n      this.$router.push('/phone')\n    }\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url(\"~styles/global.less\");\n\n.wrapper {\n  width: 100vw;\n  height: 100vh;\n  background-color: @bgcolor;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  .phoneLogin {\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    width: 5.3rem;\n    height: 0.8rem;\n    border-radius: 0.4rem;\n    background-color: #fff;\n    color: @bgcolor;\n    font-weight: 500;\n    letter-spacing: 3px;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/myFavorite/components/albums.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-01 14:47:32\n * @Update: 2019-10-04 13:05:28\n * @Update log: 更新日志\n -->\n<template>\n  <div>\n    <sublist-card :djSublist=\"albumsInfo\" :count=\"albumsNum\" type=\"albums\" title=\"收藏的专辑\"></sublist-card>\n  </div>\n</template>\n\n<script>\nimport sublistCard from 'base/djSublistCard'\nexport default {\n  name: '',\n  props: {\n    albumsInfo: {\n      type: Array\n    },\n    albumsNum: {\n      type: Number\n    }\n  },\n  components: {\n    sublistCard\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/myFavorite/components/artists.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-01 14:47:43\n * @Update: 2019-10-04 13:22:14\n * @Update log: 更新日志\n -->\n<template>\n  <div>\n    <sublist-card :djSublist=\"artistsInfo\" type=\"artists\" :circle=\"true\"></sublist-card>\n  </div>\n</template>\n\n<script>\nimport sublistCard from 'base/djSublistCard'\n\nexport default {\n  name: '',\n  props: {\n    artistsInfo: {\n      type: Array\n    }\n  },\n  components: {\n    sublistCard\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/myFavorite/components/column.vue",
    "content": "<template>\n  <div>专栏页面</div>\n</template>\n\n<script>\nexport default {\n  name: '',\n  props: {\n    columnInfo: {\n      type: Array\n    },\n    columnNum: {\n      type: Number\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/myFavorite/components/mlog.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-01 14:48:35\n * @Update: 2019-10-01 14:48:35\n * @Update log: 更新日志\n -->\n<template>\n  <div>Mlog 页面</div>\n</template>\n\n<script>\nexport default {\n  name: '',\n  props: {\n    mlogInfo: {\n      type: Array\n    },\n    mlogNum: {\n      type: Number\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/myFavorite/components/videos.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-01 14:48:10\n * @Update: 2019-10-04 13:36:59\n * @Update log: 更新日志\n -->\n<template>\n  <div>\n    <sublist-card :djSublist=\"videosInfo\" :bigImg=\"true\" type=\"video\"></sublist-card>\n  </div>\n</template>\n\n<script>\nimport sublistCard from 'base/djSublistCard'\n\nexport default {\n  name: '',\n  props: {\n    videosInfo: {\n      type: Array\n    },\n    videosNum: {\n      type: Number\n    }\n  },\n  components: {\n    sublistCard\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/myFavorite/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-01 14:23:14\n * @Update: 2019-10-04 12:48:02\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"my_favorite pd23\">\n    <general-nav @returnPage=\"returnPage\">\n      <span class=\"text\">我的收藏</span>\n    </general-nav>\n    <slider-nav :list=\"list\" minWidth=\"1rem\"></slider-nav>\n    <router-view\n      :albumsInfo=\"albumsInfo\"\n      :videosInfo=\"videosInfo\"\n      :columnInfo=\"columnInfo\"\n      :artistsInfo=\"artistsInfo\"\n      :mlogInfo=\"mlogInfo\"\n      :albumsNum=\"albumsNum\"\n      :videosNum=\"videosNum\"\n      :columnNum=\"columnNum\"\n      :artistsNum=\"artistsNum\"\n      :mlogNum=\"mlogNum\"\n    ></router-view>\n  </div>\n</template>\n\n<script>\nimport generalNav from 'base/generalNav'\nimport sliderNav from 'base/sliderNav'\nimport api from 'api'\nexport default {\n  name: '',\n  data () {\n    return {\n      albumsNum: 0,\n      artistsNum: 0,\n      videosNum: 0,\n      columnNum: 0,\n      mlogNum: 0,\n      albumsInfo: [],\n      artistsInfo: [],\n      videosInfo: [],\n      columnInfo: [],\n      mlogInfo: []\n    }\n  },\n  computed: {\n    list: function () {\n      let arr = [{\n        path: `/albums`,\n        text: `专辑`,\n        num: this.albumsNum\n      }, {\n        path: `/artists`,\n        text: `歌手`,\n        num: this.artistsNum\n      }, {\n        path: `/videos`,\n        text: `视频`,\n        num: this.videosNum\n      }, {\n        path: `/column`,\n        text: `专栏`,\n        num: this.columnNum\n      }, {\n        path: `/mlog`,\n        text: `Mlog`,\n        num: this.mlogNum\n      }]\n      return arr\n    }\n  },\n  created () {\n    this._getAllInfo()\n  },\n  methods: {\n    _getAllInfo () {\n      this._getFavoriteAlbums()\n      this._getFavoriteArtists()\n      this._getFavoriteVideosFn()\n    },\n    /**\n     * 获取已收藏专辑列表\n     */\n    _getFavoriteAlbums () {\n      api.favoriteAlbumsFn()\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.albumsNum = data.count\n            this.albumsInfo = data.data\n          }\n        })\n    },\n    /**\n     * 获取已收藏的歌手列表\n     */\n    _getFavoriteArtists () {\n      api.favoriteArtistsFn()\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.artistsNum = data.count\n            this.artistsInfo = data.data\n          }\n        })\n    },\n    /**\n     * 获取已收藏的视频\n     */\n    _getFavoriteVideosFn () {\n      api.favoriteVideosFn()\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.videosNum = data.count\n            this.videosInfo = data.data\n          }\n        })\n    },\n    /**\n     * 返回上一页\n     */\n    returnPage () {\n      this.$router.go(-1)\n    }\n  },\n  components: {\n    generalNav,\n    sliderNav\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.my_favorite {\n  background-color: #fff;\n  .text {\n    font-size: 0.4rem;\n    vertical-align: 5px;\n    width: 8rem;\n    .ellipsis();\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/nav/components/login-bottom.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-10-30 13:05:17\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper border-top\">\n    <span @click=\"TOGGLE_MODE\">\n      <i class=\"login\" :class=\"{ iconyueliang1,  icontaiyang }\"></i>\n      <!-- 在 vue 中，通过 v-once 指令，可以有效提高静态内容展示效率 -->\n      <span>{{ modeText }}间模式</span>\n    </span>\n    <span>\n      <i class=\"login iconshezhi\"></i>\n      <span>设置</span>\n    </span>\n    <span @click=\"logout\">\n      <i class=\"login icondianyuan\"></i>\n      <span>退出</span>\n    </span>\n  </div>\n</template>\n\n<script>\nimport { mapGetters, mapMutations } from 'vuex'\nexport default {\n  name: 'loginBottom',\n  computed: {\n    ...mapGetters({ iconyueliang1: 'ICON_NIGHT',\n      icontaiyang: 'ICON_SUN',\n      modeText: 'MODE_TEXT' })\n  },\n  methods: {\n    logout () {\n      this.$emit('logout')\n    },\n    ...mapMutations(['TOGGLE_MODE'])\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n.wrapper {\n  width: 6rem;\n  height: 0.9rem;\n  background-color: #fff;\n  box-sizing: border-box;\n  padding: 0.2rem 0.23rem;\n  position: fixed;\n  bottom: 0;\n  z-index: 2;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  font-size: 0.3rem;\n  .login {\n    font-size: 0.4rem;\n    vertical-align: -2px;\n    margin-right: 0.08rem;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/nav/components/login-icons-bottom.vue",
    "content": "<template>\n  <div class=\"wrapper pd23 border-bottom\">\n    <ul>\n      <li class=\"list\" v-for=\"(item, index) in loginIconsBottom\" :key=\"index\">\n        <i class=\"login\" :class=\"item.icon\"></i>\n        <span class=\"list-text\">{{ item.text }}</span>\n      </li>\n    </ul>\n  </div>\n</template>\n\n<script>\nimport { loginIconsBottom } from 'getInfos/getData'\n\nexport default {\n  name: 'loginIconsBottom',\n  data () {\n    return {\n      loginIconsBottom\n    }\n  },\n  mounted () {\n    this.initData()\n  },\n  methods: {\n    async initData () {\n      this.loginIconsBottom = loginIconsBottom()\n    }\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url('~styles/global.less');\n@fontSize:0.31rem;\n@height:0.87rem;\n.wrapper{\n  padding-top: 0.2rem;\n  padding-bottom: 0.9rem;\n  .list{\n    box-sizing: border-box;\n    padding: 0.2rem 0;\n    font-size: @fontSize;\n    height: @height;\n    .login{\n      font-size: @fontSize * 1.3;\n      margin-right: @fontSize / 2;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/nav/components/login-icons-top.vue",
    "content": "<template>\n  <div class=\"wrapper pd23 border-bottom\">\n    <ul>\n      <li class=\"list\" v-for=\"(item, index) in loginIconsTop\" :key=\"index\">\n        <i class=\"login\" :class=\"item.icon\"></i>\n        <span class=\"list-text\">{{ item.text }}</span>\n      </li>\n    </ul>\n  </div>\n</template>\n\n<script>\nimport { loginIconsTop } from 'getInfos/getData'\n\nexport default {\n  name: 'loginIconsTop',\n  data () {\n    return {\n      loginIconsTop\n    }\n  },\n  mounted () {\n    this.initData()\n  },\n  methods: {\n    async initData () {\n      this.loginIconsTop = loginIconsTop()\n    }\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url('~styles/global.less');\n@fontSize:0.31rem;\n@height:0.87rem;\n.wrapper{\n  padding-top: 0.2rem;\n  padding-bottom: 0.2rem;\n  .list{\n    box-sizing: border-box;\n    padding: 0.2rem 0;\n    font-size: @fontSize;\n    height: @height;\n    .login{\n      font-size: @fontSize * 1.3;\n      margin-right: @fontSize / 2;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/nav/components/login-icons.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-10-03 19:51:17\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"container border-bottom\">\n    <ul class=\"icons-wrapper\">\n      <!-- <li v-for=\"(item, index) in loginIcons\" :key=\"index\"\n          :icons=\"item\"\n          is=\"icon\"></li> -->\n      <li class=\"icon-list\" v-for=\"(item, index) in loginIcons\" :key=\"index\">\n        <div class=\"icon\">\n          <i class=\"login\" :class=\"item.icon\"></i>\n        </div>\n        <span class=\"icon-text\">{{item.text}}</span>\n      </li>\n    </ul>\n  </div>\n</template>\n\n<script>\nimport { loginIcons } from 'getInfos/getData'\nimport icon from 'base/icon'\nexport default {\n  name: 'loginIcons',\n  components: {\n    icon\n  },\n  data () {\n    return {\n      loginIcons\n    }\n  },\n  mounted () {\n    this.iniData()\n  },\n  methods: {\n    async iniData () {\n      this.loginIcons = loginIcons()\n    }\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url('~styles/global.less');\n\n.icons-wrapper {\n  box-sizing: border-box;\n  width: 100%;\n  padding: 1rem 0.13rem 0.5rem;\n  .flex-around();\n  .icon-list {\n    height: 100%;\n    text-align: center;\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    .icon {\n      width: @iconWidth * 0.72;\n      height: @iconWidth * 0.72;\n      line-height: @iconWidth * 0.72;\n      .login {\n        font-size: 0.4rem;\n        color: @bgcolor;\n      }\n    }\n    .icon-text {\n      font-size: @iconText - 0.04;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/nav/components/login-top.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-12-04 18:47:09\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\" :class=\"{loginBg:!loginState}\">\n    <!-- 没有登录状态样式 -->\n    <div class=\"no-login\" v-if=\"!loginState\">\n      <div class=\"content\">\n        <p>登陆网易云音乐</p>\n        <p>手机电脑多端同步，尽享海量高品质音乐</p>\n      </div>\n      <!-- 在一个组件的根元素上直接监听一个原生事件 使用native修饰-->\n      <router-link to=\"/login\" tag=\"button\" class=\"to-login\" @click.native=\"HIDE_LOGIN\">立即登录</router-link>\n    </div>\n    <!-- 已经登陆状态样式 -->\n    <div class=\"login-ed\" @click=\"goUserInfo\" v-if=\"loginState\">\n      <div class=\"img-info\">\n        <img class=\"account-bg\" :src=\"avatarUrl + '?param=200y200'\" alt />\n      </div>\n      <div class=\"nickname\">\n        <span class=\"account-nickname\">{{nickname}}</span>\n        <span class=\"level\">Lv.{{level}}</span>\n      </div>\n      <div class=\"daily_sign-in\">\n        <!-- 这里添加stop 修饰符，防止冒泡跳转到个人信息页面 -->\n        <van-button\n          type=\"primary\"\n          size=\"small\"\n          color=\"#dd001b\"\n          round\n          @click.stop=\"sign\"\n          v-show=\"!isSign\"\n        >\n          <i class=\"login icontubiaozhizuo-\"></i>签到\n        </van-button>\n        <van-button size=\"small\" class=\"sign\" round v-show=\"isSign\">\n          已签到\n          <i class=\"login iconyoujiantou\"></i>\n        </van-button>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script>\nimport { mapMutations } from 'vuex'\nimport { getCookie, setCookie } from 'utils/cookie'\nimport api from 'api'\nexport default {\n  name: 'loginTop',\n  data () {\n    return {\n      avatarUrl: '',\n      nickname: '',\n      level: 0,\n      is_Sign: false\n    }\n  },\n  props: {\n    loginState: {\n      type: Number,\n      default: 0\n    }\n  },\n  created () {\n    this.$nextTick(() => {\n      this.getUserInfo(this.loginState)\n    })\n  },\n  computed: {\n    _loginState: {\n      get () {\n        return this.loginState\n      },\n      set (val) {\n        this.$emit('update_state', val)\n      }\n    },\n    isSign: {\n      get () {\n        /**\n         * 如果在其他地方签到，这里没有设置上签到的cookie\n         * 在点击签到后会设置上data值，设置为签到，改变页面样式\n         * 当在刷新页面时，data值会清空，这时已经有cookie\n         * get到cookie\n         */\n        if (this.is_Sign) {\n          return this.is_Sign\n        } else {\n          return getCookie('sign').slice(1)\n        }\n      },\n      /**\n       * 因为要get值，所以通过一个中间变量设置从而改变\n       */\n      set (val) {\n        this.is_Sign = val\n      }\n    }\n  },\n  methods: {\n    getUserInfo (bool) {\n      if (bool) {\n        // 通过本地存储获取用户头像和昵称\n        this.level = localStorage.getItem('level')\n        this.avatarUrl = localStorage.getItem('avatarUrl')\n        this.nickname = localStorage.getItem('nickname')\n      }\n    },\n    /**\n     * 跳转到展示用户详情信息的页面\n     */\n    goUserInfo () {\n      this.HIDE_LOGIN()\n      setTimeout(() => {\n        this.$router.push('/user_info')\n      }, 500)\n    },\n    /**\n     * 签到成功后设置cookie，标记用户已经签到\n     * cookie有效期是从当前时间点到当日的23:59:59\n     * 当第二天打开时cookie失效，页面会显示未签到的样子\n     */\n    setSignCookie () {\n      var curDate = new Date()\n      // 当前时间戳\n      var curTamp = curDate.getTime()\n      // 当日凌晨的时间戳,减去一毫秒是为了防止后续得到的时间不会达到00:00:00的状态\n      var curWeeHours = new Date(curDate.toLocaleDateString()).getTime() - 1\n      // 当日已经过去的时间（毫秒）\n      var passedTamp = curTamp - curWeeHours\n      // 当日剩余时间\n      var leftTamp = 24 * 60 * 60 * 1000 - passedTamp\n      var leftTime = new Date()\n      leftTime.setTime(leftTamp + curTamp)\n      setCookie('sign', true, leftTime)\n    },\n    sign () {\n      api.signInFn()\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            // 签到成功\n            console.log('签到成功')\n            this.isSign = true\n            this.setSignCookie()\n          }\n        })\n        .catch(err => {\n          if (err) {\n            console.log('用户已经签到')\n            this.is_Sign = true\n            this.setSignCookie()\n          }\n        })\n    },\n    ...mapMutations(['HIDE_LOGIN'])\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url(\"~styles/global.less\");\n@color: rgba(0, 0, 0, 0.4);\n@font-size : 0.2rem;\n.loginBg {\n  // 如果没有登陆，背景是灰色\n  background-color: rgba(204, 204, 204, 0.3);\n}\n.wrapper {\n  // 左侧上部大背景\n  position: relative;\n  overflow: hidden;\n  box-sizing: border-box;\n  padding: 0.6rem 0.23rem 0.9rem;\n  width: 100%;\n  height: 3rem;\n  .login-ed {\n    display: flex;\n    width: 100%;\n    height: 100%;\n    justify-content: space-between;\n    .nickname {\n      position: absolute;\n      bottom: 0;\n      .level {\n        box-sizing: border-box;\n        padding: 0.04rem 0.1rem;\n        background-color: #ccc;\n        border-radius: 0.4rem;\n        font-size: 0.2rem;\n      }\n    }\n    .img-info {\n      // 用户信息 包括头像和昵称\n      text-align: center;\n      width: 1.3rem;\n      height: 1.3rem;\n      .account-bg {\n        width: 100%;\n        height: 100%;\n        border-radius: 50%;\n      }\n    }\n    .daily_sign-in {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      box-sizing: border-box;\n      padding: 0.07rem;\n      font-size: 0.2rem;\n      margin-top: auto;\n      color: #fff;\n      .sign {\n        color: #7b7c7d;\n      }\n      .iconyoujiantou {\n        font-size: 0.24rem;\n      }\n    }\n  }\n  .no-login {\n    width: 100%;\n    height: 100%;\n    .flex-around();\n    flex-direction: column;\n    align-items: center;\n    .content {\n      text-align: center;\n      p {\n        // 两句话\n        font-size: @font-size;\n        line-height: @font-size*1.5;\n        color: @color;\n      }\n    }\n    .to-login {\n      // 立即登录按钮\n      background-color: transparent;\n      box-sizing: border-box;\n      padding: 0.1rem 0.5rem;\n      border: 1px solid @color;\n      border-radius: 0.5rem;\n      font-size: @font-size;\n      color: @color;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/nav/components/login.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-11-05 18:46:36\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"login-menu\">\n    <login-top :loginState=\"loginState\"></login-top>\n    <login-icons></login-icons>\n    <login-icons-top></login-icons-top>\n    <login-icons-bottom></login-icons-bottom>\n    <login-bottom @logout=\"logout\"></login-bottom>\n  </div>\n</template>\n\n<script>\nimport loginTop from './login-top'\nimport loginIcons from './login-icons'\nimport loginIconsTop from './login-icons-top'\nimport loginIconsBottom from './login-icons-bottom'\nimport loginBottom from './login-bottom'\nimport { mapGetters, mapMutations } from 'vuex'\nimport api from 'api'\nexport default {\n  name: 'login',\n  data () {\n    return {\n      // 显式的将获取到的登陆标签设置为Number类型\n      loginState: +localStorage.getItem('loginState')\n    }\n  },\n  computed: {\n    ...mapGetters(['LEVEL'])\n  },\n  methods: {\n    /**\n     * 退出登录\n     * 将本地标签设置为 0 意为 false 未登录【但是localStorage获取的是字符串，需要转换为数字】\n     * 页面刷新使得信息可以重新获取\n     */\n    logout () {\n      api.logoutFn()\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            console.log(data)\n            localStorage.setItem('loginState', 0)\n            this.LOGIN_STATE(0)\n            location.reload()\n          }\n        })\n    },\n    ...mapMutations(['LOGIN_STATE'])\n  },\n  components: {\n    loginTop,\n    loginIcons,\n    loginIconsTop,\n    loginIconsBottom,\n    loginBottom\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url(\"//at.alicdn.com/t/font_1322263_rqiqhmq0u9o.css\");\n.login-menu {\n  // 左侧侧边栏 宽度设置为6rem\n  position: absolute;\n  z-index: 99;\n  height: 100vh;\n  overflow-y: auto;\n  top: 0;\n  left: 0;\n  width: 6rem;\n  background: #fff;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/nav/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-11-02 12:49:39\n * @Update log: 更新日志\n -->\n<template>\n  <div>\n    <!-- 顶部导航条 -->\n    <nav class=\"nav-wrapper\">\n      <div class=\"nav-left\">\n        <i class=\"nav iconnav ripple\" @click=\"SHOW_LOGIN\"></i>\n      </div>\n      <ul class=\"nav-center\">\n        <router-link tag=\"li\" class=\"nav-title ripple\" replace to=\"/home\">我的</router-link>\n        <router-link tag=\"li\" class=\"nav-title ripple\" replace to=\"/find\">发现</router-link>\n        <router-link tag=\"li\" class=\"nav-title ripple\" replace to=\"/friend\">朋友</router-link>\n        <router-link tag=\"li\" class=\"nav-title ripple\" replace to=\"/videoPage\">视频</router-link>\n      </ul>\n      <div class=\"nav-right\">\n        <!-- 注意link时要加上/ 要不然会出现异常情况 -->\n        <router-link to=\"/search\" tag=\"i\" class=\"nav iconsousuo ripple\"></router-link>\n      </div>\n      <login-page-is-show></login-page-is-show>\n    </nav>\n    <keep-alive>\n      <router-view></router-view>\n    </keep-alive>\n  </div>\n</template>\n\n<script>\nimport loginPageIsShow from 'base/loginPageIsShow'\nimport { mapMutations } from 'vuex'\nexport default {\n  name: 'defaultNav',\n  methods: {\n    ...mapMutations(['SHOW_LOGIN'])\n  },\n  components: {\n    loginPageIsShow\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url(\"~styles/global.less\");\n@import url(\"//at.alicdn.com/t/font_1298894_8b2aso7zegl.css\");\n@height: 1rem;\n.navIcon {\n  width: @height;\n  height: @height;\n  border-radius: 50%;\n  text-align: center;\n}\n// 遮罩层动画\n.mask-show-enter,\n.mask-show-leave-to {\n  opacity: 0;\n}\n\n.mask-show-enter-active,\n.mask-show-leave-active {\n  transition: opacity linear 0.3s;\n}\n// 左侧侧边栏显示隐藏动画\n.login-show-enter,\n.login-show-leave-to {\n  transform: translateX(-6rem);\n}\n\n.login-show-enter-active,\n.login-show-leave-active {\n  transition: transform linear 0.3s;\n}\n// 顶部的导航条\n.nav-wrapper {\n  display: flex;\n  box-sizing: border-box;\n  width: 100%;\n  height: @height;\n  padding: 0 0.23rem;\n  position: -webkit-sticky;\n  position: sticky;\n  top: 0;\n  z-index: 2;\n  background-color: #fff;\n  line-height: @height;\n  .nav-left {\n    flex: 2;\n    display: flex;\n    justify-content: left;\n    align-items: center;\n    .iconnav {\n      .navIcon();\n    }\n  }\n  .nav-center {\n    flex: 6;\n    display: flex;\n    justify-content: space-around;\n    align-items: center;\n    color: #999;\n    font-size: 0.24rem;\n    .nav-title {\n      .navIcon();\n    }\n  }\n  .nav-right {\n    flex: 2;\n    display: flex;\n    justify-content: flex-end;\n    align-items: center;\n    .iconsousuo {\n      .navIcon();\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/recentlyPlayed/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-27 21:51:00\n * @Update: 2019-10-26 08:12:47\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"recentlyPlayed pd23\">\n    <general-nav @returnPage=\"returnPage\" class=\"titleFixed\">\n      <span class=\"text\">最近播放</span>\n    </general-nav>\n    <audio-all-title @beginAudioAll=\"beginAudioAll\" :trackCount=\"trackCount\" class=\"titleMt\"></audio-all-title>\n    <song-list\n      v-for=\"(item, index) in recordList\"\n      :key=\"index\"\n      :songName=\"item.name\"\n      :artists=\"item.ar\"\n      :albumName=\"item.al.name\"\n      :num=\"index + 1\"\n      @beginSong=\"setAudioList(item, index)\"\n      :nowSong=\"item.id === audioSong.id\"\n    ></song-list>\n  </div>\n</template>\n\n<script>\nimport { mapActions, mapGetters } from 'vuex'\n\nimport generalNav from 'base/generalNav'\nimport audioAllTitle from 'base/audioAllTitle'\nimport songList from 'base/song'\nimport api from 'api'\nexport default {\n  name: '',\n  data () {\n    return {\n      trackCount: 0,\n      recordList: []\n    }\n  },\n  computed: {\n    ...mapGetters({ audioSong: 'AUDIO_ING_SONG' })\n  },\n  created () {\n    this._getRecord()\n  },\n  methods: {\n    setRuleArr (data) {\n      let songArr = []\n      data.forEach(element => {\n        songArr.push(element.song)\n      })\n      return songArr\n    },\n    _getRecord () {\n      // 当用户刷新页面时 vuex 状态失效，采用本地存储\n      let uid = localStorage.getItem('accountUid')\n      api.userRecordFn(uid)\n        .then(res => {\n          this.recordList = this.setRuleArr(res.data.weekData)\n          this.trackCount = this.recordList.length\n        })\n        .catch(err => {\n          console.log(err)\n        })\n    },\n    returnPage () {\n      this.$router.go(-1)\n    },\n    beginAudioAll () {\n      this.startPlayAll({\n        list: this.recordList\n      })\n    },\n    setAudioList (item, index) {\n      this.selectPlay({\n        list: this.recordList,\n        index\n      })\n    },\n    ...mapActions(['selectPlay', 'startPlayAll'])\n  },\n  components: {\n    generalNav,\n    audioAllTitle,\n    songList\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.recentlyPlayed {\n  background-color: #fff;\n  .text {\n    font-size: 0.4rem;\n    vertical-align: 5px;\n    width: 8rem;\n    .ellipsis();\n  }\n  .titleMt {\n    margin-top: 0.2rem;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/recommend/fine/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-08 13:17:12\n * @Update: 2019-09-08 16:10:05\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"pd23\">\n    <div v-show=\"!load\">\n      <div class=\"wrapper-top\">\n        <span class=\"title\">全部</span>\n        <span class=\"filter smallTag\">\n          <i class=\"recommend shaixuan\"></i> 筛选\n        </span>\n      </div>\n      <div class=\"img-col\">\n        <img-card\n          v-for=\"(item, index) in list\"\n          :key=\"index\"\n          :playCount=\"item.playCount\"\n          :imgUrl=\"item.coverImgUrl\"\n          :albumId=\"item.id\"\n          :dec=\"item.name\"\n          :fine=\"true\"\n        ></img-card>\n      </div>\n    </div>\n    <page-loading v-show=\"load\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport imgCard from 'base/imgCard'\nimport pageLoading from 'base/pageLoading'\n\nexport default {\n  name: '',\n  components: {\n    imgCard,\n    pageLoading\n  },\n  data () {\n    return {\n      list: [],\n      load: true\n    }\n  },\n  created () {\n    this._getFineList()\n  },\n  methods: {\n    _getFineList () {\n      api.highqualityFn()\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.list = data.playlists\n            this.load = false\n          }\n        })\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.wrapper-top {\n  .flex-between();\n  margin-top: 0.3rem;\n  .shaixuan {\n    font-size: 0.23rem;\n  }\n}\n\n.img-col {\n  .flex-between();\n  flex-wrap: wrap;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/recommend/general/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-08 13:17:34\n * @Update: 2019-09-17 10:32:47\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper pd23\">\n    <div class=\"img-col\" v-show=\"!load\">\n      <img-card\n        v-for=\"(item, index) in list\"\n        :key=\"index\"\n        :playCount=\"item.playCount\"\n        :imgUrl=\"item.coverImgUrl\"\n        :dec=\"item.name\"\n        :albumId=\"item.id\"\n      ></img-card>\n    </div>\n    <page-loading v-show=\"load\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport imgCard from 'base/imgCard'\nimport pageLoading from 'base/pageLoading'\n\nexport default {\n  name: '',\n  components: {\n    imgCard,\n    pageLoading\n  },\n  data () {\n    return {\n      cat: '',\n      list: [],\n      load: true\n    }\n  },\n  beforeRouteUpdate (to, from, next) {\n    // 在当前路由改变，但是该组件被复用时调用\n    // 举例来说，对于一个带有动态参数的路径 /foo/:id，在 /foo/1 和 /foo/2 之间跳转的时候，\n    // 由于会渲染同样的 Foo 组件，因此组件实例会被复用。而这个钩子就会在这个情况下被调用。\n    // 可以访问组件实例 `this`\n    this.load = true\n    console.log(to, from)\n    this.cat = to.params.id\n    this._getCatInfo(this.cat)\n    next()\n  },\n  created () {\n    this.getCat()\n  },\n  methods: {\n    getCat () {\n      this.cat = this.$route.params.id\n      this._getCatInfo(this.cat)\n    },\n    _getCatInfo (key) {\n      api.recSongListFn(undefined, undefined, key)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.list = data.playlists\n            this.load = false\n          }\n        })\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n\n.img-col {\n  .flex-between();\n  flex-wrap: wrap;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/recommend/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-06 11:38:30\n * @Update: 2019-09-13 14:52:55\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\">\n    <general-nav class=\"pd23\" @returnPage=\"returnPage\">\n      <span class=\"text\">歌单广场</span>\n    </general-nav>\n    <nav-list></nav-list>\n    <keep-alive>\n      <router-view style=\"height: 87vh; overflow-y: scroll;\"></router-view>\n    </keep-alive>\n  </div>\n</template>\n\n<script>\nimport navList from './navIndex/navList'\nimport generalNav from 'base/generalNav'\nexport default {\n  name: '',\n  components: {\n    navList,\n    generalNav\n  },\n  methods: {\n    returnPage () {\n      this.$router.go(-1)\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url('//at.alicdn.com/t/font_1396524_tr1owjj5u5.css');\n@import url('~styles/global.less');\n.wrapper{\n  .text{\n    font-size: 0.4rem;\n    vertical-align: 5px;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/recommend/navIndex/navList.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-31 19:54:27\n * @Update: 2019-11-12 21:44:53\n * @Update log: 因为存在 url地址自动将中文转换为编码\n *              在第一次加载时，默认组件不能正确添加active样式\n -->\n<template>\n  <div class=\"wrapper pd23\" ref=\"navs\">\n    <!-- 使用 replace 它不会向 history 添加新记录 -->\n    <router-link\n      :to=\"item.text | setPage\"\n      class=\"nav-list\"\n      v-for=\"(item, index) in list\"\n      :key=\"index\"\n      exact\n      replace\n    >{{ item.text }}</router-link>\n    <span class=\"more\">\n      <i class=\"recommend ziyuanxhdpi\"></i>\n    </span>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: '',\n  methods: {\n    handleScroll (index) {\n      this.$refs.navs.scrollLeft = index * 85\n    },\n    getPage (val) {\n      let index = this.toLink.indexOf(val)\n      this.handleScroll(index)\n    }\n  },\n  filters: {\n    setPage: function (val) {\n      if (val) {\n        if (val === '推荐') {\n          val = '/recommended'\n        } else if (val === '精品') {\n          val = '/fine'\n        } else {\n          val = `/general/${val}`\n        }\n      }\n      return val\n    }\n  },\n  data () {\n    return {\n      linkPage: '',\n      list: [\n        {\n          text: '推荐'\n        }, {\n          text: '精品'\n        }, {\n          text: '欧美'\n        }, {\n          text: '电子'\n        }, {\n          text: '民谣'\n        }, {\n          text: '轻音乐'\n        }, {\n          text: '韩语'\n        }\n      ]\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.wrapper {\n  position: relative;\n  display: flex;\n  flex-wrap: nowrap;\n  box-sizing: border-box;\n  margin-top: 0.16rem;\n  overflow-x: auto;\n  border-bottom: 1px solid #ddd;\n  margin-right: 0.6rem;\n  .nav-list {\n    position: relative;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    min-width: 1.2rem;\n    height: 0.7rem;\n    box-sizing: border-box;\n    padding: 0.03rem;\n    margin: 0 0.2rem;\n    color: #000;\n    &::before {\n      content: \"\";\n      position: absolute;\n      bottom: 0;\n      left: 0;\n      right: 0;\n      height: 2px;\n      background-color: @bgcolor;\n      transform-origin: bottom right;\n      transform: scaleX(0);\n      transition: transform 0.5s ease;\n    }\n    &.ac {\n      color: @bgcolor;\n    }\n    &.ac::before {\n      transform-origin: bottom left;\n      transform: scaleX(1);\n    }\n  }\n  .more {\n    position: fixed;\n    right: 8px;\n    top: 1.3rem;\n    // transform: translateY(-50%);\n    .recommend {\n      font-size: 0.4rem;\n    }\n  }\n}\n::-webkit-scrollbar {\n  display: none;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/recommend/recommended/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-09-08 13:17:01\n * @Update: 2019-11-03 14:15:34\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"pd23\">\n    <div v-show=\"!load\">\n      <!-- 这里缺少歌单页面的轮播图 -->\n      <div class=\"img-col\">\n        <img-card\n          v-for=\"(item, index) in swiper\"\n          :key=\"index\"\n          :playCount=\"item.playCount\"\n          :imgUrl=\"item.coverImgUrl\"\n          :dec=\"item.name\"\n          :albumId=\"item.id\"\n        ></img-card>\n        <img-card\n          v-for=\"(item, index) in list\"\n          :key=\"index\"\n          :playCount=\"item.playCount\"\n          :imgUrl=\"item.coverImgUrl\"\n          :dec=\"item.name\"\n          :albumId=\"item.id\"\n        ></img-card>\n      </div>\n    </div>\n    <page-loading v-show=\"load\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport imgCard from 'base/imgCard'\nimport pageLoading from 'base/pageLoading'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      swiper: [],\n      list: [],\n      load: true\n    }\n  },\n  created () {\n    this._getListInfo()\n  },\n  methods: {\n    change (start, end) {\n      console.log(start, end)\n    },\n    _getListInfo () {\n      api.recSongListFn(33)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            if (this.swiper.length === 0) {\n              this.swiper = data.playlists.splice(0, 3)\n            }\n            this.list = data.playlists\n            this.load = false\n          }\n        })\n    }\n  },\n  components: {\n    imgCard,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.swiper {\n  margin: 0.3rem 0;\n}\n.img-col {\n  .flex-between();\n  flex-wrap: wrap;\n}\nel-carousel__item h3 {\n  color: #475669;\n  font-size: 14px;\n  opacity: 0.75;\n  line-height: 200px;\n  margin: 0;\n}\n\n.el-carousel__item:nth-child(2n) {\n  background-color: #99a9bf;\n}\n\n.el-carousel__item:nth-child(2n + 1) {\n  background-color: #d3dce6;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchIndex/components/history.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-27 13:29:51\n * @Update: 2019-08-31 10:06:52\n * @Update log: 更新日志\n -->\n<template>\n <div class=\"history pd23\" v-if=\"history.length\">\n   <div class=\"history-title\">\n     <span>历史记录</span>\n     <i class=\"search iconlajitong\" @click=\"clearHistory\"></i>\n   </div>\n   <div class=\"wrapper\">\n    <div class=\"container \">\n      <ul class=\"icons-group\">\n        <li class=\"icon-list\"\n            @click=\"toSearch(item)\"\n            v-for=\"(item, index) in history\"\n            :key=\"index\">{{item}}\n        </li>\n      </ul>\n    </div>\n  </div>\n </div>\n</template>\n\n<script>\nimport Bus from '../../../assets/Bus'\nexport default {\n  name: 'history',\n  data () {\n    return {\n      history\n    }\n  },\n  created () {\n    this.getHistory()\n  },\n  methods: {\n    /**\n     * 获取历史记录\n     */\n    getHistory () {\n      // 兄弟组件进行值的接收\n      // Bus.$on('方法名(与兄弟组件方法名一致), 回调函数 参数为传过来的值')\n      Bus.$on('history', (history) => {\n        this.history = history\n      })\n    },\n    /**\n     * 清除历史记录\n     */\n    clearHistory () {\n      localStorage.removeItem('keys')\n      this.history = []\n    },\n    toSearch (keywords) {\n      Bus.$emit('search', keywords)\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url('~styles/global.less');\n.history{\n  margin-top: 0.5rem;\n  .history-title{\n    .flex-between();\n    height: 0.8rem;\n    line-height: 0.8rem;\n    .iconlajitong{\n      width: 0.8rem;\n      height: 0.8rem;\n      text-align: center;\n      font-size: 0.4rem\n    }\n  }\n  .wrapper {\n    box-sizing: border-box;\n    overflow: hidden;\n    height: 0.5rem;\n    // 定义可左右滑动的图标组\n    .container {\n      // 横向滚动条\n      overflow-x: scroll;\n      .icons-group {\n        // flex布局 溢出不换行\n        height: 0.5rem;\n        display: flex;\n        flex-wrap: nowrap;\n        align-items: center;\n        white-space: nowrap;\n        width: auto;\n        min-width: 100%;\n        .icon-list {\n          height: 0.44rem;\n          box-sizing: border-box;\n          padding: 0 0.13rem;\n          font-size: small;\n          display: flex;\n          justify-content: center;\n          align-items: center;\n          margin-right: 5px;\n          border-radius: 0.3rem;\n          background: #eee;\n        }\n      }\n    }\n  }\n}\n::-webkit-scrollbar {\n  display: none;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchIndex/components/hotSearch.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-28 10:41:47\n * @Update: 2019-08-28 12:29:24\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"song-hot-search\">\n    <p class=\"hot-search-title\">热搜榜</p>\n    <ul>\n      <li\n        class=\"hot-search-list\"\n        v-for=\"(item, index) in hotSearchList\"\n        :key=\"index\"\n        @click=\"returnKey(item.searchWord)\"\n      >\n        <span class=\"num\">{{ index + 1 }}</span>\n        <div class=\"song-info\">\n          <div class=\"song-info-title\">\n            <p class=\"song-name\">{{ item.searchWord }}</p>\n            <span class=\"num\">{{ item.score }}</span>\n            <img v-if=\"item.iconUrl\" class=\"search-png\" :src=\"item.iconUrl\" />\n          </div>\n          <!-- 歌曲介绍 -->\n          <div class=\"song-Introduced\">{{ item.content }}</div>\n        </div>\n      </li>\n    </ul>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nexport default {\n  name: 'hotSearch',\n  data () {\n    return {\n      hotSearchList: []\n    }\n  },\n  created () {\n    this._getList()\n  },\n  methods: {\n    /**\n     * 获取热搜榜单\n     */\n    _getList () {\n      api.hotSearchListFn()\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.hotSearchList = data.data\n            this.$emit('childFn', false)\n          }\n        })\n        .catch(error => {\n          console.log(error)\n        })\n    },\n    /**\n     * 通过点击热歌榜将关键字返回给父组件，父组件调用搜索组件的搜索功能\n     */\n    returnKey (key) {\n      this.$emit('returnKey', key)\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.song-hot-search {\n  .pd23();\n  margin-top: 0.6rem;\n  .hot-search-list {\n    display: flex;\n    margin: 0.2rem 0;\n    &:nth-of-type(1) > .num {\n      color: @bgcolor;\n    }\n    &:nth-of-type(2) > .num {\n      color: @bgcolor;\n    }\n    &:nth-of-type(3) > .num {\n      color: @bgcolor;\n    }\n    > .num {\n      line-height: 1rem;\n      font-size: 0.26rem;\n    }\n    .song-info {\n      margin-left: 20px;\n      height: 100%;\n      .song-info-title {\n        display: flex;\n        line-height: 0.6rem;\n        .song-name {\n          margin-right: 0.1rem;\n        }\n        .search-png {\n          margin-left: 0.2rem;\n          // width: 0.3rem;\n          height: 0.2rem;\n          margin-top: 0.2rem;\n        }\n      }\n    }\n    .song-Introduced {\n      font-size: 0.23rem;\n      color: #aaa;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchIndex/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-27 12:37:42\n * @Update: 2019-09-01 21:49:23\n * @Update log: 这里用到了父组件调用子组件方法\n -->\n<template>\n  <div>\n    <search-inp ref=\"search\" page=\"search\" Right=\"1rem\"></search-inp>\n    <history v-show=\"!loading\"></history>\n    <!-- 父组件在组件上定义了一个自定义事件childFn，事件名为parentFn用于接受子组件传过来的message值。 -->\n    <hot-search v-show=\"!loading\" @returnKey = \"setKey\" @childFn=\"parentFn\"></hot-search>\n    <page-loading v-if=\"loading\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport searchInp from 'base/searchInput'\nimport history from './components/history'\nimport hotSearch from './components/hotSearch'\nimport pageLoading from 'base/pageLoading'\nexport default {\n  name: 'search',\n  data () {\n    return {\n      hotSearchKey: '',\n      loading: true\n    }\n  },\n  components: {\n    searchInp,\n    history,\n    hotSearch,\n    pageLoading\n  },\n  activated () {\n    this.setKey()\n  },\n  methods: {\n    setKey (key) {\n      if (key) {\n        // 父组件调用子组件方法\n        this.$refs.search.searchKey(key)\n      }\n    },\n    parentFn (result) {\n      this.loading = result\n    }\n  }\n}\n</script>\n\n<style lang=\"less\" scoped>\n@import url('//at.alicdn.com/t/font_1371990_3libmbu82og.css');\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/albumIndex/album.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-31 11:26:25\n * @Update: 2019-11-02 12:45:02\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper pd23\">\n    <div v-show=\"!load\">\n      <album\n        @click.native=\"toDishPage(item.id)\"\n        v-for=\"(item, index) in allAlbumList\"\n        :key=\"index\"\n        :album=\"true\"\n        line=\"one\"\n        :ImgUrl=\"item.blurPicUrl\"\n        :alia=\"item.alias.length > 0 ? item.alias[0] : ''\"\n        maxWidth=\"4.7rem\"\n        :name=\"item.name\"\n        :artists=\"item.artists\"\n        :durationms=\"item.publishTime\"\n      ></album>\n      <info :info=\"info\" :keywords=\"keywords\"></info>\n    </div>\n    <page-loading v-show=\"load\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport info from 'base/pageErrorInfo'\nimport album from 'base/interchangeable'\nimport pageLoading from 'base/pageLoading'\nimport { filterSetKeyWords } from 'utils/setKeyWords'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      allAlbumList: [],\n      info: false,\n      load: true\n    }\n  },\n  props: {\n    // 搜索关键字\n    keywords: {\n      type: String\n    }\n  },\n  created () {\n    this.load = true\n    this._getAllAlbumList(this.keywords)\n  },\n  methods: {\n    _getAllAlbumList (key) {\n      api.searchFn(key, undefined, undefined, 10)\n        .then((res) => {\n          const data = res.data\n          if (data.code === 200) {\n            if (this.allAlbumList.length) {\n              this.allAlbumList = [this.allAlbumList, ...data.result.albums]\n            } else {\n              this.allAlbumList = data.result.albums\n            }\n            this.allAlbumList = filterSetKeyWords(this.keywords, this.allAlbumList, 'name')\n            this.load = false\n            if (data.result.albumCount === 0) {\n              this.info = true\n            }\n          }\n        })\n        .catch(error => {\n          this.load = false\n          this.info = true\n          console.log(error)\n        })\n    },\n    toDishPage (id) {\n      this.$router.push({ name: 'albumPage', params: { dishId: id } })\n    }\n  },\n  components: {\n    album,\n    info,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/artistIndex/artist.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-31 11:26:07\n * @Update: 2019-11-14 15:29:23\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper pd23\">\n    <div v-show=\"!load\">\n      <artist\n        v-for=\"(item, index) in allArtistList\"\n        :key=\"index\"\n        :circle=\"true\"\n        :ImgUrl=\"item.img1v1Url\"\n        :alia=\"item.alias.length > 0 ? item.alias[0] : ''\"\n        line=\"one\"\n        :name=\"item.name\"\n        :isIn=\"item.accountId\"\n      ></artist>\n      <info :info=\"info\" :keywords=\"keywords\"></info>\n    </div>\n    <page-loading v-show=\"load\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport info from 'base/pageErrorInfo'\nimport artist from 'base/interchangeable'\nimport pageLoading from 'base/pageLoading'\nimport { filterSetKeyWords } from 'utils/setKeyWords'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      allArtistList: [],\n      info: false,\n      load: true\n    }\n  },\n  props: {\n    // 搜索关键字\n    keywords: {\n      type: String\n    }\n  },\n  created () {\n    this.load = true\n    this._getAllArtistList(this.keywords)\n  },\n  methods: {\n    _getAllArtistList (key) {\n      api.searchFn(key, undefined, undefined, 100)\n        .then((res) => {\n          const data = res.data\n          if (data.code === 200) {\n            if (this.allArtistList.length) {\n              this.allArtistList = [this.allArtistList, ...data.result.artists]\n            } else {\n              this.allArtistList = data.result.artists\n            }\n            this.allArtistList = filterSetKeyWords(this.keywords, this.allArtistList, 'name')\n            this.load = false\n            if (data.result.artistCount === 0) {\n              this.info = true\n            }\n          }\n        })\n        .catch(error => {\n          this.load = false\n          this.info = true\n          console.log(error)\n        })\n    }\n  },\n  components: {\n    artist,\n    info,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/composite/components/album.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-31 10:58:10\n * @Update: 2019-11-16 13:44:29\n * @Update log: 更新日志\n -->\n<template>\n  <list-global\n    title=\"专辑\"\n    :more=\"album.more\"\n    :moreText=\"album.moreText\"\n    linkPage=\"album\"\n    :keyW=\"keyword\"\n  >\n    <list-con\n      @click.native=\"toDishPage(item.id)\"\n      v-for=\"(item, index) in album \"\n      :key=\"index\"\n      :album=\"true\"\n      line=\"one\"\n      :ImgUrl=\"item.blurPicUrl\"\n      :alia=\"item.alias.length > 0 ? item.alias[0] : ''\"\n      :name=\"item.name\"\n      :artists=\"item.artists\"\n      maxWidth=\"4.7rem\"\n      :durationms=\"item.publishTime\"\n    ></list-con>\n  </list-global>\n</template>\n\n<script>\nimport listGlobal from 'base/titleFooter'\nimport listCon from 'base/interchangeable'\n\nexport default {\n  name: '',\n  props: {\n    album: {\n      type: Array\n    },\n    keyword: {\n      type: String\n    }\n  },\n  methods: {\n    toDishPage (id) {\n      this.$router.push({ name: 'albumPage', params: { dishId: id } })\n    }\n  },\n  components: {\n    listGlobal,\n    listCon\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/composite/components/artist.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-31 10:57:52\n * @Update: 2019-11-26 13:01:35\n * @Update log: 更新日志\n -->\n<template>\n  <div>\n    <list-global\n      title=\"歌手\"\n      :more=\"artist.more\"\n      :moreText=\"artist.moreText\"\n      linkPage=\"artist\"\n      :keyW=\"keyword\"\n    >\n      <list-con\n        v-for=\"(item, index) in artist\"\n        :key=\"index\"\n        :circle=\"true\"\n        :ImgUrl=\"item.img1v1Url\"\n        @click.native=\"toArtistDetail\"\n        :alia=\"item.alias.length > 0 ? item.alias[0] : ''\"\n        :name=\"item.name\"\n        :isIn=\"item.accountId\"\n      ></list-con>\n    </list-global>\n  </div>\n</template>\n\n<script>\nimport listGlobal from 'base/titleFooter'\nimport listCon from 'base/interchangeable'\n\nexport default {\n  name: '',\n  props: {\n    artist: {\n      type: Array\n    },\n    keyword: {\n      type: String\n    }\n  },\n  methods: {\n    toArtistDetail () {\n      this.$router.push('/artistDetailPage')\n    }\n  },\n  components: {\n    listGlobal,\n    listCon\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/composite/components/djRadio.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-31 10:58:24\n * @Update: 2019-09-03 10:50:45\n * @Update log: 更新日志\n -->\n<template>\n  <list-global\n    title=\"电台\"\n    :more=\"djRadio.more\"\n    :moreText=\"djRadio.moreText\"\n    linkPage=\"djRadio\"\n    :keyW=\"keyword\"\n  >\n    <list-con\n      v-for=\"(item, index) in djRadio\"\n      @click.native=\"goDjDetailPage(item.id)\"\n      :key=\"index\"\n      :dj=\"true\"\n      maxWidth=\"4.7rem\"\n      line=\"one\"\n      :ImgUrl=\"item.picUrl\"\n      :name=\"item.name\"\n      :nicknames=\"item.dj\"\n    ></list-con>\n  </list-global>\n</template>\n\n<script>\nimport listGlobal from 'base/titleFooter'\nimport listCon from 'base/interchangeable'\n\nexport default {\n  name: '',\n  props: {\n    djRadio: {\n      type: Array\n    },\n    keyword: {\n      type: String\n    }\n  },\n  methods: {\n    goDjDetailPage (id) {\n      this.$router.push({ name: 'djDetailPage', params: { ridId: id } })\n    }\n  },\n  components: {\n    listGlobal,\n    listCon\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/composite/components/playList.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-31 10:56:55\n * @Update: 2019-11-01 13:31:54\n * @Update log: 更新日志\n -->\n<template>\n  <list-global\n    title=\"歌单\"\n    :more=\"playList.more\"\n    :moreText=\"playList.moreText\"\n    linkPage=\"playList\"\n    :keyW=\"keyword\"\n  >\n    <list-con\n      :songList=\"true\"\n        @click.native=\"goAlbumPage(item.id)\"\n      v-for=\"(item, index) in playList\"\n      :key=\"index\"\n      :ImgUrl=\"item.coverImgUrl\"\n      line=\"one\"\n      maxWidth=\"4.7rem\"\n      :name=\"item.name\"\n      :trackCount=\"item.trackCount\"\n      :nickname=\"item.creator.nickname\"\n      :playCount=\"item.playCount\"\n    ></list-con>\n  </list-global>\n</template>\n\n<script>\nimport listCon from 'base/interchangeable'\nimport listGlobal from 'base/titleFooter'\nexport default {\n  name: '',\n  components: {\n    listCon,\n    listGlobal\n  },\n  props: {\n    playList: {\n      type: Array\n    },\n    keyword: {\n      type: String\n    }\n  },\n  data () {\n    return {\n      lists: this.playList.playLists\n    }\n  },\n  methods: {\n    goAlbumPage (id) {\n      this.$router.push({ name: 'albumPage', params: { albumId: id } })\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/composite/components/simQuery.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-31 10:57:31\n * @Update: 2019-11-26 12:50:04\n * @Update log: 更新日志\n -->\n<template>\n  <list-global title=\"相关搜索\" :more=\"simQuery.more\" :moreText=\"simQuery.moreText\">\n    <ul class=\"sim-group\">\n      <li\n        class=\"sim-list\"\n        v-for=\"(item, index) in simQuery.sim_querys\"\n        @click=\"toSearch(item.keyword)\"\n        :key=\"index\"\n      >{{item.keyword}}</li>\n    </ul>\n  </list-global>\n</template>\n\n<script>\nimport listGlobal from 'base/titleFooter'\nimport Bus from '../../../../assets/Bus'\n\nexport default {\n  name: '',\n  props: {\n    simQuery: {\n      type: Object\n    }\n  },\n  methods: {\n    toSearch (keywords) {\n      Bus.$emit('search', keywords)\n    }\n  },\n  components: {\n    listGlobal\n  }\n}\n</script>\n\n<style lang='less' scoped>\n.sim-group {\n  display: flex;\n  flex-wrap: wrap;\n  .sim-list {\n    height: 0.5rem;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    font-size: 0.24rem;\n    box-sizing: border-box;\n    padding: 0.2rem;\n    background-color: #ddd;\n    border-radius: 0.3rem;\n    margin-right: 0.3rem;\n    margin-top: 0.2rem;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/composite/components/song.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-31 10:56:42\n * @Update: 2019-11-01 13:25:31\n * @Update log: 更新日志\n -->\n<template>\n  <list-global\n    title=\"单曲\"\n    :songList=\"true\"\n    :more=\"songList.more\"\n    :moreText=\"songList.moreText\"\n    linkPage=\"song\"\n    :keyW=\"keyword\"\n  >\n    <ul class=\"song-group\">\n      <song-list\n        v-for=\"(item, index) in songList\"\n        :key=\"index\"\n        tag=\"li\"\n        class=\"list-item\"\n        :songName=\"item.name\"\n        :alia=\"item.alia.length > 0 ? item.alia[0] : ''\"\n        :artists=\"item.ar\"\n        :albumName=\"item.al.name\"\n        :keyword=\"keyword\"\n        @beginSong=\"setAudioList(item)\"\n        :nowSong=\"item.id === audioSong.id\"\n      ></song-list>\n    </ul>\n  </list-global>\n</template>\n\n<script>\nimport listGlobal from 'base/titleFooter'\nimport songList from 'base/song'\nimport { mapGetters, mapActions } from 'vuex'\nexport default {\n  name: '',\n  props: {\n    songList: {\n      type: Array\n    },\n    keyword: {\n      type: String\n    }\n  },\n  computed: {\n    ...mapGetters({ audioSong: 'AUDIO_ING_SONG' })\n  },\n  filters: {\n    artName: function (value) {\n      if (!value) return ''\n      value = '/' + value\n      return value\n    }\n  },\n  methods: {\n    setAudioList (song) {\n      this.addToAudioList(song)\n    },\n    ...mapActions(['addToAudioList'])\n  },\n  components: {\n    listGlobal,\n    songList\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.song-group {\n  margin-top: 0.16rem;\n  .list-item {\n    .flex-between();\n    align-items: center;\n    height: 1rem;\n    .song-info {\n      display: flex;\n      flex-direction: column;\n      .song-name {\n        height: 0.4rem;\n        width: 6rem;\n        line-height: 0.4rem;\n        .ellipsis();\n      }\n      .song-art {\n        height: 0.4rem;\n        line-height: 0.4rem;\n        font-size: 0.23rem;\n        color: #dacdcd;\n        .artist {\n          &::after {\n            content: \"/\";\n          }\n          &:last-child::after {\n            content: \"\";\n          }\n        }\n      }\n    }\n    .icon {\n      color: #ccc;\n    }\n  }\n}\n.more {\n  height: 1rem;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  font-size: 0.26rem;\n  color: #ccc;\n  .youjiantou {\n    color: #aaa;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/composite/components/user.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-31 10:58:35\n * @Update: 2019-11-02 12:48:36\n * @Update log: 更新日志\n -->\n<template>\n  <list-global\n    title=\"用户\"\n    :more=\"user.more\"\n    :moreText=\"user.moreText\"\n    linkPage=\"user\"\n    :keyW=\"keyword\"\n  >\n    <list-con\n      v-for=\"(item, index) in user\"\n      :key=\"index\"\n      :circle=\"true\"\n      :ImgUrl=\"item.avatarUrl\"\n      :name=\"item.nickname\"\n      :gender=\"item.gender\"\n      :nickname=\"item.signature\"\n      line=\"one\"\n      maxWidth=\"4.7rem\"\n    ></list-con>\n  </list-global>\n</template>\n\n<script>\nimport listGlobal from 'base/titleFooter'\nimport listCon from 'base/interchangeable'\n\nexport default {\n  name: '',\n  props: {\n    user: {\n      type: Array\n    },\n    keyword: {\n      type: String\n    }\n  },\n  components: {\n    listGlobal,\n    listCon\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/composite/components/video.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-31 10:57:13\n * @Update: 2019-11-01 13:30:26\n * @Update log: 更新日志\n -->\n<template>\n  <list-global\n    title=\"视频\"\n    :more=\"videoList.more\"\n    :moreText=\"videoList.moreText\"\n    linkPage=\"video\"\n    :keyW=\"keyword\"\n  >\n    <list-con\n      :videoList=\"true\"\n      v-for=\"(item, index) in videoList\"\n      :key=\"index\"\n      @click.native=\"toVideoCom(item.vid)\"\n      line=\"two\"\n      :ImgUrl=\"item.coverUrl\"\n      :name=\"item.title\"\n      :isMv=\"item.vid.length < 20\"\n      :durationms=\"item.durationms\"\n      :nicknames=\"item.creator\"\n      :playTime=\"item.playTime\"\n    ></list-con>\n  </list-global>\n</template>\n\n<script>\nimport listCon from 'base/interchangeable'\nimport listGlobal from 'base/titleFooter'\n\nexport default {\n  name: '',\n  components: {\n    listCon,\n    listGlobal\n  },\n  props: {\n    videoList: {\n      type: Array\n    },\n    keyword: {\n      type: String\n    }\n  },\n  methods: {\n    toVideoCom (id) {\n      this.$router.push({ name: 'videoComments', params: { id } })\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n.video-list {\n  margin-top: 0.26rem;\n  .title {\n    height: 0.3rem;\n    line-height: 0.3rem;\n  }\n  .more {\n    height: 1rem;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    font-size: 0.26rem;\n    color: #ccc;\n    .youjiantou {\n      color: #aaa;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/composite/composite.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-31 11:17:07\n * @Update: 2020-03-13 23:04:01\n * @Update log: 综合页面展示\n -->\n<template>\n  <div class=\"wrapper pd23\">\n    <div v-show=\"!load\">\n      <div v-if=\"!info\">\n        <song-list :songList=\"songList\" :keyword=\"keywords\" v-if=\"orderList.includes('song')\"></song-list>\n        <play-list\n          :playList=\"playListList\"\n          :keyword=\"keywords\"\n          v-if=\"orderList.includes('playList')\"\n        ></play-list>\n        <video-list :videoList=\"videoList\" :keyword=\"keywords\" v-if=\"orderList.includes('video')\"></video-list>\n        <sim-query\n          :simQuery=\"sim_queryList\"\n          :keyword=\"keywords\"\n          v-if=\"orderList.includes('sim_query')\"\n        ></sim-query>\n        <artist :artist=\"artistList\" :keyword=\"keywords\" v-if=\"orderList.includes('artist')\"></artist>\n        <album :album=\"albumList\" :keyword=\"keywords\" v-if=\"orderList.includes('album')\"></album>\n        <dj-radio :djRadio=\"djRadioList\" :keyword=\"keywords\" v-if=\"orderList.includes('djRadio')\"></dj-radio>\n        <user :user=\"userList\" :keyword=\"keywords\" v-if=\"orderList.includes('user')\"></user>\n      </div>\n      <info :info=\"info\" :keywords=\"keywords\"></info>\n    </div>\n    <page-loading v-show=\"load\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport songList from './components/song'\nimport playList from './components/playList'\nimport videoList from './components/video'\nimport simQuery from './components/simQuery'\nimport artist from './components/artist'\nimport album from './components/album'\nimport djRadio from './components/djRadio'\nimport user from './components/user'\nimport info from 'base/pageErrorInfo'\nimport pageLoading from 'base/pageLoading'\nimport { filterSetKeyWords } from 'utils/setKeyWords'\n\nimport api from 'api'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      // 这个搜索结果都包含哪些部分\n      orderList: [],\n      // 查看同名歌曲\n      songList: {},\n      // 查看全部歌单\n      playListList: {},\n      // 查看全部视频\n      videoList: {},\n      // 相关搜索\n      sim_queryList: {},\n      // 查看全部歌手\n      artistList: {},\n      // 查看全部专辑\n      albumList: {},\n      // 查看全部电台\n      djRadioList: {},\n      // 查看全部用户\n      userList: {},\n      info: false,\n      load: true\n    }\n  },\n  props: {\n    // 搜索关键字\n    keywords: {\n      type: String\n    }\n  },\n  watch: {\n    keywords: function (val) {\n      this.load = true\n      if (val) {\n        this._searchShow(val)\n      }\n    }\n  },\n  created () {\n    this._searchShow(this.keywords)\n  },\n  methods: {\n    /**\n     * 通过获取到的 动态的搜索关键字\n     * 来获取数据，返回到页面\n     */\n    _searchShow (key) {\n      api.searchFn(key)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            let { album,\n              order,\n              song,\n              playList,\n              video,\n              artist,\n              djRadio,\n              user\n            } = data.result\n            let simQuery = data.result.sim_query\n            this.orderList = order\n            this.songList = song ? song.songs : []\n            this.playListList = playList ? playList.playLists : []\n            this.videoList = video ? video.videos : []\n            this.sim_queryList = simQuery || {}\n            this.artistList = artist ? artist.artists : []\n            this.albumList = album ? album.albums : []\n            this.djRadioList = djRadio ? djRadio.djRadios : []\n            this.userList = user ? user.users : []\n            this.songList = filterSetKeyWords(this.keywords, this.songList, 'name')\n            this.videoList = filterSetKeyWords(this.keywords, this.videoList, 'title')\n            this.playListList = filterSetKeyWords(this.keywords, this.playListList, 'name')\n            this.albumList = filterSetKeyWords(this.keywords, this.albumList, 'name')\n            this.djRadioList = filterSetKeyWords(this.keywords, this.djRadioList, 'name')\n            this.userList = filterSetKeyWords(this.keywords, this.userList, 'nickname')\n            this.artistList = filterSetKeyWords(this.keywords, this.artistList, 'name')\n            this.load = false\n            // 没有信息展示\n            if (this.orderList.length === 0) {\n              this.info = true\n            }\n          }\n        })\n        .catch(error => {\n          this.load = false\n          this.info = true\n          console.log(error)\n        })\n    }\n  },\n  components: {\n    songList,\n    playList,\n    videoList,\n    simQuery,\n    artist,\n    album,\n    djRadio,\n    user,\n    info,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/djRadioIndex/djRadio.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-31 11:25:40\n * @Update: 2019-11-14 13:57:40\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper pd23\">\n    <div v-show=\"!load\">\n      <dj-radio\n        @click.native=\"goDjDetailPage(item.id)\"\n        v-for=\"(item, index) in allDjRadioList\"\n        :key=\"index\"\n        :dj=\"true\"\n        maxWidth=\"4.7rem\"\n        line=\"one\"\n        :ImgUrl=\"item.picUrl\"\n        :name=\"item.name\"\n        :nicknames=\"item.dj\"\n      ></dj-radio>\n      <info :info=\"info\" :keywords=\"keywords\"></info>\n    </div>\n    <page-loading v-show=\"load\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport info from 'base/pageErrorInfo'\nimport djRadio from 'base/interchangeable'\nimport pageLoading from 'base/pageLoading'\nimport { filterSetKeyWords } from 'utils/setKeyWords'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      allDjRadioList: [],\n      info: false,\n      load: true\n    }\n  },\n  props: {\n    // 搜索关键字\n    keywords: {\n      type: String\n    }\n  },\n  created () {\n    this.load = true\n    this._getAllDjRadioList(this.keywords)\n  },\n  methods: {\n    _getAllDjRadioList (key) {\n      api.searchFn(key, undefined, undefined, 1009)\n        .then((res) => {\n          const data = res.data\n          if (data.code === 200) {\n            if (this.allDjRadioList.length) {\n              this.allDjRadioList = [this.allDjRadioList, ...data.result.albums]\n            } else {\n              this.allDjRadioList = data.result.djRadios\n            }\n            this.allDjRadioList = filterSetKeyWords(this.keywords, this.allDjRadioList, 'name')\n            this.load = false\n            /**\n             * 这里使用Es6 判断一个对象是否为空\n             */\n            if (Object.keys(data.result).length === 0) {\n              this.info = true\n            }\n          }\n        })\n        .catch(error => {\n          this.load = false\n          this.info = true\n          console.log(error)\n        })\n    },\n    goDjDetailPage (id) {\n      this.$router.push({ name: 'djDetailPage', params: { ridId: id } })\n    }\n  },\n  components: {\n    djRadio,\n    info,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-30 12:05:38\n * @Update: 2019-11-15 13:48:06\n * @Update log: 更新日志\n * 建立各个组件，将对象传给对应的组件进行渲染\n -->\n<template>\n  <div>\n    <search-input :keyword=\"key\"></search-input>\n    <nav-list></nav-list>\n    <router-view :keywords=\"key\" style=\"height: 87vh; overflow-y: scroll;\"></router-view>\n  </div>\n</template>\n\n<script>\nimport searchInput from 'base/searchInput'\nimport navList from './navIndex'\n\nimport { mapGetters } from 'vuex'\nexport default {\n  name: 'searchResults',\n  components: {\n    searchInput,\n    navList\n  },\n  data () {\n    return {\n      key: ''\n    }\n  },\n  watch: {\n    '$route' (to, from) {\n      // 对路由变化作出响应...\n      this.key = to.params.id\n    }\n  },\n  computed: {\n    ...mapGetters({ 'load': 'LOAD' })\n  },\n  created () {\n    this.setKey()\n  },\n  methods: {\n    setKey () {\n      this.key = this.$route.params.id\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"//at.alicdn.com/t/font_1380711_5p2kgyidw5.css\");\n\n@import url(\"~styles/global.less\");\n.el-button--info {\n  background: #fff;\n  color: #000;\n}\n.btn {\n  width: 100px;\n  height: 50px;\n}\n.button {\n  position: relative;\n  overflow: hidden;\n  user-select: none;\n}\n.button:after {\n  position: absolute;\n  content: \"\";\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  pointer-events: none;\n  //设置径向渐变\n  background-image: radial-gradient(circle, #666 10%, transparent 10.01%);\n  background-repeat: no-repeat;\n  background-position: 50%;\n  transform: scale(10, 10);\n  opacity: 0;\n  transition: transform 0.3s, opacity 0.5s;\n}\n.button:active:after {\n  transform: scale(0, 0);\n  opacity: 0.3;\n  //设置初始状态\n  transition: 0s;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/navIndex/index.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-31 19:54:27\n * @Update: 2019-10-29 13:04:54\n * @Update log: 因为存在 url地址自动将中文转换为编码\n *              在第一次加载时，默认组件不能正确添加active样式\n -->\n<template>\n  <slider-nav :list=\"list\" ref=\"navs\"></slider-nav>\n</template>\n\n<script>\nimport { mapGetters } from 'vuex'\nimport Bus from '../../../assets/Bus'\nimport sliderNav from 'base/sliderNav'\nexport default {\n  name: '',\n  mounted () {\n    // 页面刷新时通过 params 获取关键字\n    this.setLinkPage()\n    // 通过Bus传值获取\n    this.getKey()\n  },\n  computed: {\n    ...mapGetters({ page: 'LINK_PAGE' })\n  },\n  methods: {\n    /**\n     * 页面刷新时使用 params 获取\n     */\n    setLinkPage () {\n      let id = this.$route.params.id\n      this.linkPage = id\n    },\n    /**\n     * 获取Bus传过来的值\n     */\n    getKey () {\n      Bus.$on('push', key => {\n        this.linkPage = key\n      })\n    },\n    getPage (val) {\n      let index = this.toLink.indexOf(val)\n      this.$refs.navs.handleScroll(index, 85)\n    }\n  },\n  /**\n   * 监听linkPage变化，对循环的list数组进行改变赋值\n   */\n  watch: {\n    linkPage: function (newKey) {\n      /**\n       * 循环遍历数组，渲染标签导航\n       */\n      this.list = [\n        {\n          path: `/composite/${newKey}`,\n          text: '综合'\n        }, {\n          path: `/song/${newKey}`,\n          text: '单曲'\n        }, {\n          path: `/video/${newKey}`,\n          text: '视频'\n        }, {\n          path: `/artist/${newKey}`,\n          text: '歌手'\n        }, {\n          path: `/album/${newKey}`,\n          text: '专辑'\n        }, {\n          path: `/playList/${newKey}`,\n          text: '歌单'\n        }, {\n          path: `/djRadio/${newKey}`,\n          text: '主播电台'\n        }, {\n          path: `/user/${newKey}`,\n          text: '用户'\n        }\n      ]\n    },\n    page: function (val) {\n      /**\n       * 获取到当前要跳转的路由页\n       * 寻找下标\n       * 0 : 0\n       * 1 : 85\n       * 2 : 170\n       */\n      this.getPage(val)\n    }\n  },\n  data () {\n    return {\n      linkPage: '',\n      list: [],\n      toLink: ['composite', 'song', 'video', 'artist', 'album', 'playList', 'djRadio', 'user']\n    }\n  },\n  components: {\n    sliderNav\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/playListIndex/playList.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-31 11:25:20\n * @Update: 2019-11-14 13:53:22\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper pd23\">\n    <div v-show=\"!load\">\n      <song-list\n        v-for=\"(item, index) in allSongListList\"\n        :key=\"index\"\n        @click.native=\"goAlbumPage(item.id)\"\n        :songList=\"true\"\n        line=\"one\"\n        maxWidth=\"4.7rem\"\n        :ImgUrl=\"item.coverImgUrl\"\n        :name=\"item.name\"\n        :trackCount=\"item.trackCount\"\n        :nickname=\"item.creator.nickname\"\n        :playCount=\"item.playCount\"\n      ></song-list>\n      <info :info=\"info\" :keywords=\"keywords\"></info>\n    </div>\n    <page-loading v-show=\"load\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport songList from 'base/interchangeable'\nimport pageLoading from 'base/pageLoading'\nimport info from 'base/pageErrorInfo'\nimport { filterSetKeyWords } from 'utils/setKeyWords'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      allSongListList: [],\n      info: false,\n      load: true\n    }\n  },\n  props: {\n    // 搜索关键字\n    keywords: {\n      type: String\n    }\n  },\n  created () {\n    this.load = true\n    this._getAllSongListList(this.keywords)\n  },\n  methods: {\n    _getAllSongListList (key) {\n      api.searchFn(key, undefined, undefined, 1000)\n        .then((res) => {\n          const data = res.data\n          if (data.code === 200) {\n            if (data.result.playlistCount === 0) {\n              // 没有内容，展示提示信息\n              this.info = true\n            }\n            if (this.allSongListList.length) {\n              // 这里的歌单获取有问题\n              this.allSongListList = [this.allSongListList, ...data.result.playlists]\n            } else {\n              this.allSongListList = data.result.playlists\n            }\n            this.allSongListList = filterSetKeyWords(this.keywords, this.allSongListList, 'name')\n            this.load = false\n          }\n        })\n        .catch(error => {\n          console.log(error)\n        })\n    },\n    goAlbumPage (id) {\n      this.$router.push({ name: 'albumPage', params: { albumId: id } })\n    }\n  },\n  components: {\n    songList,\n    info,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/singerIndex/select.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-10 12:40:09\n * @Update: 2019-11-03 13:59:40\n * @Update log: 这是一个歌手分类页面的选择组件\n  通过点击第一列和第二列进行不同的数据渲染\n  默认是华语 + 男\n  点击时传入id\n -->\n<template>\n  <div>\n    <ul class=\"list-wrap\">\n      <li\n        class=\"list-item\"\n        :class=\"{active : item.id === _firstId }\"\n        v-for=\"(item) in firstList\"\n        :key=\"item.id\"\n        @click=\"selectFirst(item.id)\"\n      >{{item.text}}</li>\n    </ul>\n    <ul class=\"list-wrap\">\n      <li\n        class=\"list-item\"\n        :class=\"{active : item.id === _secondId }\"\n        v-for=\"(item) in secondList\"\n        :key=\"item.id\"\n        @click=\"selectSecond(item.id)\"\n      >{{item.text}}</li>\n    </ul>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: '',\n  props: {\n    firstList: {\n      type: Array\n    },\n    secondList: {\n      type: Array\n    },\n    firstId: {\n      type: String\n    },\n    secondId: {\n      type: String\n    }\n  },\n  computed: {\n    /**\n     * 定义子组件可以进行获取和修改的值\n     */\n    _firstId: {\n      get () {\n        return this.firstId\n      },\n      /**\n       * 通过提出事件父组件进行更新，将更新后的数据返回给子组件\n       */\n      set (val) {\n        this.$emit('update_firstID', val)\n      }\n    },\n    _secondId: {\n      get () {\n        return this.secondId\n      },\n      set (val) {\n        this.$emit('update_secondID', val)\n      }\n    }\n  },\n  methods: {\n    selectFirst (id) {\n      this._firstId = id\n    },\n    selectSecond (id) {\n      this._secondId = id\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.list-wrap {\n  display: flex;\n  padding: 0.2rem 0;\n  // margin: 0.3rem 0;\n  .list-item {\n    margin-right: 0.4rem;\n  }\n}\n.active {\n  color: @bgcolor;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/singerIndex/singer.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-10-10 08:19:51\n * @Update: 2019-11-03 13:58:32\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\">\n    <div class=\"titleFixed\">\n      <general-nav class=\"pd23\" @returnPage=\"returnPage\">\n        <span class=\"text\">歌手分类</span>\n      </general-nav>\n      <select-list\n        class=\"pd23\"\n        :firstList=\"firstList\"\n        :secondList=\"secondList\"\n        :firstId.sync=\"firstId\"\n        :secondId.sync=\"secondId\"\n        @update_firstID=\"updateFirst\"\n        @update_secondID=\"updateSecond\"\n      ></select-list>\n    </div>\n    <h1 class=\"title pd23\" ref=\"title\">热门歌手</h1>\n    <page-loading v-show=\"loading\"></page-loading>\n    <artist\n      v-show=\"!loading\"\n      class=\"pd23\"\n      v-for=\"(item, index) in allArtistList\"\n      :key=\"index\"\n      :circle=\"true\"\n      :ImgUrl=\"item.img1v1Url\"\n      :name=\"item.name\"\n      :isIn=\"item.accountId\"\n    ></artist>\n  </div>\n</template>\n\n<script>\nimport generalNav from 'base/generalNav'\nimport artist from 'base/interchangeable'\nimport pageLoading from 'base/pageLoading'\nimport selectList from './select'\n\nimport api from 'api'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      loading: true,\n      allArtistList: [],\n      firstId: '10',\n      secondId: '01',\n      firstList: [{\n        text: '华语',\n        id: '10'\n      }, {\n        text: '欧美',\n        id: '20'\n      }, {\n        text: '日本',\n        id: '60'\n      }, {\n        text: '韩国',\n        id: '70'\n      }, {\n        text: '其他',\n        id: '40'\n      }],\n      secondList: [{\n        text: '男',\n        id: '01'\n      }, {\n        text: '女',\n        id: '02'\n      }, {\n        text: '乐队/组合',\n        id: '03'\n      }]\n    }\n  },\n  created () {\n    this.load = true\n    this._getSingerInfo(this.firstId, this.secondId)\n  },\n  mounted () {\n    window.addEventListener('scroll', this.handleScroll, true)\n  },\n  methods: {\n    /**\n     * 获取歌手分类信息\n     * @param {*} limit  返回数量 , 默认为 30\n     * @param {*} offset 偏移数量，用于分页，默认为 0\n     * @param {*} initial 按首字母索引查找参数\n     */\n    _getSingerInfo (firstId, secondId, limit, offset, initial) {\n      const cat = firstId + '' + secondId\n      api.singerClassFn(cat, limit, offset, initial)\n        .then(res => {\n          const data = res.data\n          if (data.code === 200) {\n            this.allArtistList = data.artists\n            this.loading = false\n          }\n        })\n    },\n    /**\n     * 子组件修改父组件的值\n     */\n    updateFirst (val) {\n      this.firstId = val\n      this.changeId()\n    },\n    /**\n     * 子组件修改父组件的值\n     */\n    updateSecond (val) {\n      this.secondId = val\n      this.changeId()\n    },\n    /**\n     * 当切换了要显示的分类信息时\n     * 显示页面loading\n     * 进行数据请求\n     */\n    changeId () {\n      this.loading = true\n      this._getSingerInfo(this.firstId, this.secondId)\n    },\n    returnPage () {\n      this.$router.go(-1)\n    }\n  },\n  components: {\n    selectList,\n    generalNav,\n    artist,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"//at.alicdn.com/t/font_1396524_tr1owjj5u5.css\");\n@import url(\"~styles/global.less\");\n.wrapper {\n  .fixed {\n    position: fixed;\n    top: 0;\n    z-index: 1;\n    box-sizing: border-box;\n    background-color: #fff;\n  }\n  .text {\n    font-size: 0.4rem;\n    vertical-align: 5px;\n    width: 8rem;\n    .ellipsis();\n  }\n  .title {\n    background-color: #ddd;\n    line-height: 1.8;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/songIndex/song.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-31 11:24:50\n * @Update: 2019-11-01 13:28:52\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper pd23\" @scroll=\"handleScroll\">\n    <div v-show=\"!load\">\n      <div v-if=\"!info\">\n        <div class=\"title\">\n          <span @click=\"startPlay\">\n            <i class=\"result cbofang\"></i>\n            播放全部\n          </span>\n        </div>\n        <div class=\"song-group\">\n          <song-list\n            v-for=\"(item, index) in allSongList\"\n            :key=\"index\"\n            :songName=\"item.name\"\n            :artists=\"item.artists\"\n            :alia=\"item.alias.length > 0 ? item.alias[0] : ''\"\n            :albumName=\"item.album.name\"\n            @beginSong=\"setAudioList(item)\"\n            :nowSong=\"item.id === audioSong.id\"\n          ></song-list>\n        </div>\n        <page-loading v-show=\"scroll\"></page-loading>\n      </div>\n      <info :info=\"info\" :keywords=\"keywords\"></info>\n    </div>\n    <page-loading v-show=\"load\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport info from 'base/pageErrorInfo'\nimport pageLoading from 'base/pageLoading'\nimport songList from 'base/song'\nimport { filterSetKeyWords } from 'utils/setKeyWords'\n\nimport { mapActions, mapGetters } from 'vuex'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      allSongList: [],\n      offset: 0,\n      scroll: false,\n      info: false,\n      load: true\n    }\n  },\n  props: {\n    // 搜索关键字\n    keywords: {\n      type: String\n    }\n  },\n  computed: {\n    ...mapGetters({ audioSong: 'AUDIO_ING_SONG' })\n  },\n  created () {\n    this.load = true\n    this._getAllSongList(this.keywords)\n  },\n  methods: {\n    ...mapActions(['addToAudioList', 'startPlayAll']),\n    _getAllSongList (key, offset) {\n      api.searchFn(key, undefined, offset, 1)\n        .then((res) => {\n          const data = res.data\n          if (data.code === 200) {\n            if (this.allSongList.length) {\n              this.allSongList = [this.allSongList, ...data.result.songs]\n            } else {\n              this.allSongList = data.result.songs\n            }\n            this.allSongList = filterSetKeyWords(this.keywords, this.allSongList, 'name')\n            this.load = false\n            this.scroll = false\n            if (data.result.songCount === 0) {\n              this.info = true\n            }\n          }\n        })\n        .catch(error => {\n          this.load = false\n          this.info = true\n          console.log(error)\n        })\n    },\n    /**\n     * 滚动触底\n     */\n    handleScroll () {\n      // if (this.$el.scrollTop + this.$el.offsetHeight > this.$el.scrollHeight) {\n      //   this.scroll = true\n      //   const offset = this.offset += 1\n      //   this._getAllSongList(this.keywords, offset)\n      // }\n    },\n    setAudioList (item) {\n      this.addToAudioList(item)\n    },\n    startPlay () {\n      this.startPlayAll({\n        list: this.allSongList\n      })\n    }\n  },\n  components: {\n    pageLoading,\n    info,\n    songList\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n\n.wrapper {\n  .title {\n    margin: 0.23rem 0;\n    font-size: 0.3rem;\n  }\n  .song-group {\n    margin-top: 0.16rem;\n    .list-item {\n      .flex-between();\n      align-items: center;\n      height: 1rem;\n      .song-info {\n        display: flex;\n        flex-direction: column;\n        .song-name {\n          width: 6rem;\n          height: 0.4rem;\n          line-height: 0.4rem;\n          .ellipsis();\n        }\n        .song-art {\n          height: 0.4rem;\n          line-height: 0.4rem;\n          font-size: 0.23rem;\n          color: #dacdcd;\n          .artist {\n            &::after {\n              content: \"/\";\n            }\n            &:last-child::after {\n              content: \"\";\n            }\n          }\n          .album-name {\n            &::before {\n              content: \"-\";\n            }\n          }\n        }\n      }\n      .icon {\n        color: #ccc;\n      }\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/userIndex/user.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-31 11:24:13\n * @Update: 2019-11-02 12:47:57\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper pd23\">\n    <div v-show=\"!load\">\n      <user\n        v-for=\"(item, index) in allUserList\"\n        :key=\"index\"\n        :circle=\"true\"\n        :ImgUrl=\"item.avatarUrl\"\n        :name=\"item.nickname\"\n        :gender=\"item.gender\"\n        line=\"one\"\n        maxWidth=\"4.7rem\"\n        :nickname=\"item.signature\"\n      ></user>\n      <info :info=\"info\" :keywords=\"keywords\"></info>\n    </div>\n    <page-loading v-show=\"load\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport info from 'base/pageErrorInfo'\nimport user from 'base/interchangeable'\nimport pageLoading from 'base/pageLoading'\nimport { filterSetKeyWords } from 'utils/setKeyWords'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      allUserList: [],\n      info: false,\n      load: true\n    }\n  },\n  props: {\n    // 搜索关键字\n    keywords: {\n      type: String\n    }\n  },\n  created () {\n    this.load = true\n    this._getAllUserList(this.keywords)\n  },\n  methods: {\n    _getAllUserList (key) {\n      api.searchFn(key, undefined, undefined, 1002)\n        .then((res) => {\n          const data = res.data\n          if (data.code === 200) {\n            this.allUserList = data.result.userprofiles\n            if (data.result.userprofileCount === 0) {\n              this.info = true\n            }\n            this.allUserList = filterSetKeyWords(this.keywords, this.allUserList, 'nickname')\n            this.load = false\n          }\n        })\n        .catch(error => {\n          this.load = false\n          this.info = true\n          console.log(error)\n        })\n    }\n  },\n  components: {\n    user,\n    info,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/searchResults/videoIndex/video.vue",
    "content": "<!--\n * @Author: 李浩栋\n * @Begin: 2019-08-31 11:23:42\n * @Update: 2019-11-14 15:30:47\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper pd23\">\n    <div v-show=\"!load\">\n      <video-list\n        @click.native=\"toVideoCom(item.vid)\"\n        v-for=\"(item, index) in allVideoList\"\n        :key=\"index\"\n        :videoList=\"true\"\n        line=\"two\"\n        :ImgUrl=\"item.coverUrl\"\n        :name=\"item.title\"\n        :durationms=\"item.durationms\"\n        :nicknames=\"item.creator\"\n        :playTime=\"item.playTime\"\n      ></video-list>\n      <info :info=\"info\" :keywords=\"keywords\"></info>\n    </div>\n    <page-loading v-show=\"load\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport info from 'base/pageErrorInfo'\nimport videoList from 'base/interchangeable'\nimport pageLoading from 'base/pageLoading'\nimport { filterSetKeyWords } from 'utils/setKeyWords'\n\nimport api from 'api'\nexport default {\n  name: '',\n  data () {\n    return {\n      allVideoList: [],\n      info: false,\n      load: true\n    }\n  },\n  props: {\n    // 搜索关键字\n    keywords: {\n      type: String\n    }\n  },\n  created () {\n    this.load = true\n    this._getAllVideoList(this.keywords)\n  },\n  methods: {\n    _getAllVideoList (key) {\n      api.searchFn(key, undefined, undefined, 1014)\n        .then((res) => {\n          const data = res.data\n          if (data.code === 200) {\n            if (this.allVideoList.length) {\n              this.allVideoList = [this.allVideoList, ...data.result.videos]\n            } else {\n              this.allVideoList = data.result.videos\n            }\n            this.allVideoList = filterSetKeyWords(this.keywords, this.allVideoList, 'title')\n            this.load = false\n            // 当没有视频信息的时候\n            if (data.result.videoCount === 0) {\n              this.info = true\n            }\n          }\n        })\n        .catch(error => {\n          this.load = false\n          this.info = true\n          console.log(error)\n        })\n    },\n    toVideoCom (id) {\n      this.$router.push({ name: 'videoComments', params: { id } })\n    }\n  },\n  components: {\n    info,\n    videoList,\n    pageLoading\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/userInfoIndex/components/userDynamic.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-28 13:07:27\n * @Update: 2019-12-10 18:56:39\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"dynamic\">\n    <div class=\"data-info\" v-show=\"!dataInfo\">暂时还没有动态哦</div>\n    <div class=\"wrapper border-bottom\" v-for=\"(item, index) in dataMsg\" :key=\"index\">\n      <div class=\"img-info\">\n        <img :src=\"item.program.dj.avatarUrl + '?param=100y100'\" alt />\n      </div>\n      <div class=\"author\">\n        <h1 class=\"nickname\">\n          {{item.program.dj.nickname}}\n          <span class=\"category\">发布</span>\n        </h1>\n        <span class=\"fans\">{{item.program.createTime | setTime}}</span>\n        <h1 class=\"title\">{{item.msg}}</h1>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script>\nimport { filterSetMonth } from 'utils/filters'\nimport api from 'api'\nexport default {\n  name: '',\n  data () {\n    return {\n      dataInfo: true,\n      dataMsg: []\n    }\n  },\n  props: {\n    uid: {\n      type: [String, Number]\n    }\n  },\n  watch: {\n    uid: function (newVal, old) {\n      if (newVal === 0) {\n        return\n      }\n      this._getUserEvent(newVal)\n    },\n    deep: true\n  },\n  filters: {\n    setTime: function (val) {\n      return filterSetMonth(val)\n    }\n  },\n  methods: {\n    /**\n     * 获取用户动态\n     */\n    _getUserEvent (id) {\n      api.userEventFn(id)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            if (data.events.length === 0) {\n              this.dataInfo = false\n              return\n            }\n            this.dataMsg = this.getJson(data.events)\n          }\n        })\n    },\n    getJson (arr) {\n      let res = []\n      arr.forEach((ele, index) => {\n        res.push(JSON.parse(ele.json))\n        let reason = ele.rcmdInfo ? ele.rcmdInfo.userReason : ''\n        res[index].userReason = reason\n        // 刚开始是使用下边这个写法。是错误的！！\n        // 形成了命名冲突，但是不会报错，造成最后的key值名称不正确\n        // let {userReason} = ele.rcmdInfo\n        // res[i].userReason = userReason\n      })\n      return res\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.data-info {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  height: 5rem;\n}\n\n@imgWidth: 5.4rem;\n@imgHeight: 2.8rem;\n\n.none {\n  display: none;\n}\n\n.videotag {\n  box-sizing: border-box;\n  font-size: 0.2rem;\n  color: #ccc;\n  padding: 0.04rem 0.13rem;\n}\n.wrapper {\n  display: flex;\n  padding-bottom: 0.3rem;\n  margin: 0.3rem 0;\n  .img-info {\n    width: 1rem;\n    height: 0;\n    padding-bottom: 1rem;\n    margin-right: 0.2rem;\n    img {\n      width: 100%;\n      border-radius: 50%;\n    }\n  }\n  .author {\n    flex: 1;\n    line-height: 1.5;\n    .nickname {\n      color: #3399ea;\n      .category {\n        color: #7b7c7d;\n      }\n    }\n    .fans {\n      font-size: 0.2rem;\n      color: #7b7c7d;\n    }\n    .img-content {\n      width: 5.4rem;\n      height: 0;\n      padding-bottom: 2rem;\n      img {\n        width: 100%;\n        border-radius: 0.2rem;\n      }\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/userInfoIndex/components/userHome.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-28 09:05:41\n * @Update: 2019-10-28 13:15:05\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"home\">\n    <h1 class=\"title\">基本信息</h1>\n    <p class=\"list-info\">\n      <span class=\"list-name\">个人介绍：</span>\n      <span class=\"list-con\">{{signature}}</span>\n    </p>\n    <p class=\"list-info\">\n      <span class=\"list-name\">村龄：</span>\n      <span class=\"list-con\">{{age}}年（{{year}}年{{month}}月注册）</span>\n    </p>\n    <p class=\"list-info\">\n      <span class=\"list-name\">年龄：</span>\n      <span class=\"list-con-age\">{{ birthday | setAge }}后</span>\n      <span class=\"list-con-astro\">{{astro}}座</span>\n    </p>\n    <p class=\"list-info\">\n      <span class=\"list-name\">累计听歌：</span>\n      <span class=\"list-con-con\">{{ listenSongs }}首</span>\n    </p>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: ''\n}\n</script>\n\n<style lang='less' scoped>\n.home {\n  .title {\n    font-weight: 700;\n    margin: 0.4rem 0;\n  }\n  .list-info {\n    color: #7b7c7e;\n    font-size: 0.23rem;\n    line-height: 2;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/userInfoIndex/index.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-28 08:56:16\n * @Update: 2019-12-10 18:55:16\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"wrapper\" @scroll=\"scrollList\">\n    <general-nav @returnPage=\"returnPage\" class=\"fixed nav-color\">\n      <span class=\"text\">{{iTitle}}</span>\n    </general-nav>\n    <div\n      :class=\"{coverFixed, position}\"\n      :style=\"{backgroundImage: 'url(' + coverImgUrl + ')'}\"\n      class=\"container-top\"\n    >\n      <div class=\"cover\" :style=\"{backgroundColor: `rgba(0, 0, 0, ${cover})`}\"></div>\n      <div class=\"data\" v-show=\"!listFixed\" :style=\"{opacity}\">\n        <div class=\"user-img\">\n          <img v-lazy=\"avatarUrl + '?param=200y200'\" :key=\"avatarUrl\" alt />\n        </div>\n        <div class=\"user-info-content\">\n          <div class=\"user-info-left\">\n            <div class=\"user-nickname\">{{nickname}}</div>\n            <div class=\"follow-wrapper\">\n              <span class=\"follows\">关注 {{newFollows}}</span>\n              <span class=\"item\">|</span>\n              <span class=\"followed\">粉丝 {{followeds}}</span>\n            </div>\n            <div class=\"age-level\">\n              <span class=\"age\">\n                <i class=\"userInfo\" :class=\"{userInfonv: gender === 2,userInfonan: gender === 1}\"></i>\n                {{ birthday | setAge }}后\n              </span>\n              <span class=\"level\">Lv.{{level}}</span>\n            </div>\n          </div>\n          <div class=\"user-info-right\">\n            <div class=\"edit\">编辑</div>\n            <div class=\"change-bg\">更换背景</div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <change-nav\n      :class=\"{listFixed}\"\n      :active=\"active\"\n      firstNav=\"主页\"\n      secondNav=\"动态\"\n      @changeToSecond=\"changeToSecond\"\n      @changeToFirst=\"changeToFirst\"\n    ></change-nav>\n    <div class=\"container-bottom pd23\" :style=\"{ marginTop: top}\">\n      <div class=\"home\" v-show=\"active==='first'\">\n        <h1 class=\"title\">基本信息</h1>\n        <p class=\"list-info\">\n          <span class=\"list-name\">个人介绍：</span>\n          <span class=\"list-con\">{{signature}}</span>\n        </p>\n        <p class=\"list-info\">\n          <span class=\"list-name\">村龄：</span>\n          <span class=\"list-con\">{{age}}年（{{year}}年{{month}}月注册）</span>\n        </p>\n        <p class=\"list-info\">\n          <span class=\"list-name\">年龄：</span>\n          <span class=\"list-con-age\">{{ birthday | setAge }}后</span>\n          <span class=\"list-con-astro\">{{astro}}座</span>\n        </p>\n        <p class=\"list-info\">\n          <span class=\"list-name\">累计听歌：</span>\n          <span class=\"list-con-con\">{{ listenSongs }}首</span>\n        </p>\n      </div>\n      <user-dynamic v-show=\"active==='second'\" :uid=\"uid\"></user-dynamic>\n    </div>\n  </div>\n</template>\n\n<script>\nimport generalNav from 'base/generalNav'\nimport userDynamic from './components/userDynamic'\nimport { filterAge } from 'utils/filters'\nimport { getAstro } from 'utils/getAstro'\nimport api from 'api'\nimport changeNav from 'base/djDetailPage/components/changeNav'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      active: 'first',\n      iTitle: '',\n      cover: '0.2',\n      opacity: 1,\n      listFixed: false,\n      position: true,\n      coverFixed: false,\n      top: '0rem',\n      level: 0,\n      gender: 0,\n      signature: '',\n      age: 0,\n      listenSongs: 0,\n      year: 0,\n      astro: '',\n      month: 0,\n      newFollows: 0,\n      followeds: 0,\n      birthday: 0,\n      nickname: '',\n      avatarUrl: '',\n      events: [],\n      uid: 0,\n      coverImgUrl: 'http://p1.music.126.net/2zSNIqTcpHL2jIvU6hG0EA==/109951162868128395.jpg'\n    }\n  },\n  filters: {\n    setAge: function (val) {\n      return filterAge(val)\n    }\n  },\n  activated () {\n    const { id } = this.$route.params\n    this.active = 'first'\n    this.uid = id || localStorage.getItem('accountUid')\n    this._getUserInfo(this.uid)\n  },\n  methods: {\n    /**\n     * 获取用户信息\n     */\n    _getUserInfo (id) {\n      if (!id) {\n        // 用户未登录\n        return\n      }\n      api.userDetailFn(id)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            const { nickname, newFollows, followeds, backgroundUrl, birthday, signature, gender, avatarUrl } = data.profile\n            this.nickname = nickname\n            this.newFollows = newFollows\n            this.followeds = followeds\n            this.birthday = birthday\n            this.gender = gender\n            this.signature = signature\n            this.level = data.level\n            const createTime = data.createTime\n            const createDate = new Date(createTime)\n            const setAstro = new Date(birthday)\n            this.listenSongs = data.listenSongs\n            this.year = createDate.getFullYear()\n            this.month = createDate.getMonth() + 1\n            this.age = parseInt(data.createDays / 365)\n            this.avatarUrl = avatarUrl\n            this.coverImgUrl = backgroundUrl\n            console.log(setAstro.getMonth())\n            this.astro = getAstro(setAstro.getMonth() + 1, createDate.getDate())\n          }\n        })\n    },\n    /**\n     * 定义页面滚动事件，\n     * 这里需要添加在滚动过程中样式的变化\n     */\n    scrollList (e) {\n      // 获取到 top 值\n      let top = this.$el.scrollTop\n      this.cover = top / 1000 + 0.3\n      this.opacity = 1 - top / 500\n      if (this.cover > 0.6) {\n        this.cover = 0.6\n        this.opacity = 0.4\n      } else {\n        this.cover = top / 1000 + 0.3\n        this.opacity = 1 - top / 500\n      }\n      if (top >= 220) {\n        this.iTitle = this.nickname\n        this.listFixed = true\n        this.coverFixed = true\n        this.position = false\n        this.top = '6.6rem'\n      } else {\n        this.iTitle = ''\n        this.listFixed = false\n        this.coverFixed = false\n        this.position = true\n        this.top = '0'\n      }\n    },\n    returnPage () {\n      this.$router.go(-1)\n    },\n    changeToFirst () {\n      this.active = 'first'\n    },\n    changeToSecond () {\n      this.active = 'second'\n    }\n  },\n  deactivated () {\n    this.uid = 0\n  },\n  components: {\n    generalNav,\n    changeNav,\n    userDynamic\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n@import url(\"//at.alicdn.com/t/font_1479172_fftra1vturg.css\");\n.topFixed {\n  position: fixed;\n  width: 100%;\n  height: 0.8rem;\n  z-index: 9;\n}\n.fixed {\n  .topFixed();\n  top: 0;\n}\n.listFixed {\n  .topFixed();\n  top: 1.6rem;\n}\n.coverFixed {\n  position: fixed;\n  width: 100%;\n  z-index: 3;\n  top: 0;\n  transform: translateY(-4.4rem);\n}\n.nav-color {\n  color: #fff;\n}\n.wrapper {\n  width: 100vw;\n  height: 100vh;\n  position: relative;\n  overflow-y: scroll;\n  overflow-x: hidden;\n  .text {\n    font-size: 0.4rem;\n  }\n}\n.container-top {\n  width: 100%;\n  height: 0;\n  padding-bottom: 6rem;\n  background-size: 100%;\n  background-repeat: no-repeat;\n  &.position {\n    position: relative;\n  }\n  .cover {\n    position: absolute;\n    left: 0;\n    top: 0;\n    right: 0;\n    bottom: 0;\n    width: 100%;\n    height: 100%;\n  }\n  .data {\n    position: absolute;\n    bottom: 1rem;\n    left: 0.3rem;\n    width: 100%;\n    box-sizing: border-box;\n    padding-right: 0.8rem;\n    .user-img {\n      width: 100%;\n      height: 0;\n      padding-bottom: 1.5rem;\n      margin-bottom: 0.3rem;\n      img {\n        width: 1.5rem;\n        height: 1.5rem;\n        border-radius: 50%;\n      }\n    }\n    .user-info-content {\n      color: #fbfbfb;\n      .flex-between();\n      .user-info-left {\n        display: flex;\n        flex-direction: column;\n        line-height: 1.5;\n        .user-nickname {\n          font-size: 0.28rem;\n        }\n        .follow-wrapper {\n          color: #999;\n          font-size: 0.22rem;\n          .item {\n            margin: 0 0.1rem;\n            color: #777;\n          }\n        }\n        .age-level {\n          .age {\n            box-sizing: border-box;\n            background-color: #37677f;\n            padding: 0.05rem 0.1rem;\n            border-radius: 0.3rem;\n            font-size: 0.22rem;\n            margin-right: 0.1rem;\n            .userInfonan {\n              font-size: 0.22rem;\n              color: #6eccff;\n              margin-right: 0.03rem;\n            }\n            .userInfonv {\n              font-size: 0.22rem;\n              color: #fd79a8;\n              margin-right: 0.03rem;\n            }\n          }\n          .level {\n            box-sizing: border-box;\n            background-color: #7b7c7e;\n            padding: 0.05rem 0.1rem;\n            border-radius: 0.3rem;\n            font-size: 0.22rem;\n          }\n        }\n      }\n      .user-info-right {\n        display: flex;\n        align-items: flex-end;\n        .edit,\n        .change-bg {\n          box-sizing: border-box;\n          background-color: #7b7c7e;\n          padding: 0.13rem 0.25rem;\n          border-radius: 0.3rem;\n          font-size: 0.22rem;\n          margin-right: 0.1rem;\n        }\n      }\n    }\n  }\n}\n.container-bottom {\n  transform: translate3d(0, -0.8rem, 0);\n  .home {\n    .title {\n      font-weight: 700;\n      margin: 0.4rem 0;\n    }\n    .list-info {\n      color: #7b7c7e;\n      font-size: 0.23rem;\n      line-height: 1.5;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/videoIndex/components/acg.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-25 13:32:12\n * @Update: 2019-11-23 11:49:13\n * @Update log: 更新日志\n -->\n<template>\n  <div @scroll=\"hideVideo\">\n    <page-loading v-show=\"load\"></page-loading>\n    <public-img-card :data=\"data\" @index=\"getIndex\" v-show=\"!load\" ref=\"public\"></public-img-card>\n    <should-login v-show=\"isLogin === 0\"></should-login>\n  </div>\n</template>\n\n<script>\nimport { videoPage } from 'mixins/Mixins'\nimport publicImgCard from '../public'\nimport pageLoading from 'base/pageLoading'\nimport shouldLogin from 'base/shouldLogin'\n\nexport default {\n  mixins: [videoPage],\n  name: '',\n  components: {\n    publicImgCard,\n    pageLoading,\n    shouldLogin\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/videoIndex/components/animation.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-25 13:32:38\n * @Update: 2019-11-23 11:49:40\n * @Update log: 更新日志\n -->\n<template>\n  <div @scroll=\"hideVideo\">\n    <page-loading v-show=\"load\"></page-loading>\n    <public-img-card :data=\"data\" @index=\"getIndex\" v-show=\"!load\" ref=\"public\"></public-img-card>\n    <should-login v-show=\"isLogin === 0\"></should-login>\n  </div>\n</template>\n\n<script>\nimport { videoPage } from 'mixins/Mixins'\nimport publicImgCard from '../public'\nimport pageLoading from 'base/pageLoading'\nimport shouldLogin from 'base/shouldLogin'\nexport default {\n  mixins: [videoPage],\n  name: '',\n  components: {\n    publicImgCard,\n    pageLoading,\n    shouldLogin\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/videoIndex/components/dance.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-25 13:32:06\n * @Update: 2019-11-23 11:49:54\n * @Update log: 更新日志\n -->\n<template>\n  <div @scroll=\"hideVideo\">\n    <page-loading v-show=\"load\"></page-loading>\n    <public-img-card :data=\"data\" @index=\"getIndex\" v-show=\"!load\" ref=\"public\"></public-img-card>\n    <should-login v-show=\"isLogin === 0\"></should-login>\n  </div>\n</template>\n\n<script>\nimport { videoPage } from 'mixins/Mixins'\nimport publicImgCard from '../public'\nimport pageLoading from 'base/pageLoading'\nimport shouldLogin from 'base/shouldLogin'\nexport default {\n  mixins: [videoPage],\n  name: '',\n  components: {\n    publicImgCard,\n    pageLoading,\n    shouldLogin\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/videoIndex/components/game.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-25 13:32:24\n * @Update: 2019-11-23 11:50:09\n * @Update log: 更新日志\n -->\n<template>\n  <div @scroll=\"hideVideo\">\n    <page-loading v-show=\"load\"></page-loading>\n    <public-img-card :data=\"data\" @index=\"getIndex\" v-show=\"!load\" ref=\"public\"></public-img-card>\n    <should-login v-show=\"isLogin === 0\"></should-login>\n  </div>\n</template>\n\n<script>\nimport { videoPage } from 'mixins/Mixins'\nimport publicImgCard from '../public'\nimport pageLoading from 'base/pageLoading'\nimport shouldLogin from 'base/shouldLogin'\nexport default {\n  mixins: [videoPage],\n  name: '',\n  components: {\n    publicImgCard,\n    pageLoading,\n    shouldLogin\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/videoIndex/components/listenBGM.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-25 13:31:56\n * @Update: 2019-11-23 11:50:21\n * @Update log: 更新日志\n -->\n<template>\n  <div @scroll=\"hideVideo\">\n    <page-loading v-show=\"load\"></page-loading>\n    <public-img-card :data=\"data\" @index=\"getIndex\" v-show=\"!load\" ref=\"public\"></public-img-card>\n    <should-login v-show=\"isLogin === 0\"></should-login>\n  </div>\n</template>\n\n<script>\nimport { videoPage } from 'mixins/Mixins'\nimport publicImgCard from '../public'\nimport pageLoading from 'base/pageLoading'\nimport shouldLogin from 'base/shouldLogin'\nexport default {\n  mixins: [videoPage],\n  name: '',\n  components: {\n    publicImgCard,\n    pageLoading,\n    shouldLogin\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/videoIndex/components/musicFestival.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-25 13:31:37\n * @Update: 2019-11-23 11:47:13\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"container-wra\" @scroll=\"hideVideo\">\n    <page-loading v-show=\"load\"></page-loading>\n    <public-img-card :data=\"data\" @index=\"getIndex\" v-show=\"!load\" ref=\"public\"></public-img-card>\n    <should-login v-show=\"isLogin === 0\"></should-login>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport publicImgCard from '../public'\nimport pageLoading from 'base/pageLoading'\nimport isInSport from 'utils/scrollStopVideo'\nimport shouldLogin from 'base/shouldLogin'\n\nlet timer = null\nexport default {\n  name: '',\n  data () {\n    return {\n      data: [],\n      load: true,\n      index: 0,\n      isLogin: +localStorage.getItem('loginState') || 0\n    }\n  },\n  created () {\n    this._getVideoDetail(58104)\n  },\n  methods: {\n    _getVideoDetail (id) {\n      api.getVideoGroupFn(id)\n        .then(res => {\n          const {\n            data\n          } = res\n          if (data.code === 200) {\n            this.data = data.datas\n            this.load = false\n          }\n        })\n        .catch(err => {\n          if (err) {\n            this.load = false\n          }\n        })\n    },\n    hideVideo () {\n      const self = this\n      if (timer) {\n        clearTimeout(timer)\n        timer = null\n      }\n      timer = setTimeout(() => {\n        this.stopVideo(self)\n      }, 300)\n    },\n    /**\n     * 这里或得到子组件传过来的当前播放的video索引\n     */\n    getIndex (index) {\n      this.index = index\n    },\n    stopVideo (self) {\n      // 父容器\n      const wra = self.$el\n      // video集合\n      const videos = [...wra.querySelectorAll('.video-item')]\n      // 获取到当前正在播放的video\n      const ele = videos[this.index]\n      // 查看当前播放的video是否已经出去！！！\n      if (!isInSport(ele, wra)) {\n        // 出去的话调用方法，停止视频播放\n        self.$refs.public.stopVideoTag()\n      }\n    }\n  },\n  components: {\n    publicImgCard,\n    pageLoading,\n    shouldLogin\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/videoIndex/components/rock.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-25 13:32:17\n * @Update: 2019-11-23 11:50:36\n * @Update log: 更新日志\n -->\n<template>\n  <div @scroll=\"hideVideo\">\n    <page-loading v-show=\"load\"></page-loading>\n    <public-img-card :data=\"data\" @index=\"getIndex\" v-show=\"!load\" ref=\"public\"></public-img-card>\n    <should-login v-show=\"isLogin === 0\"></should-login>\n  </div>\n</template>\n\n<script>\nimport { videoPage } from 'mixins/Mixins'\nimport publicImgCard from '../public'\nimport pageLoading from 'base/pageLoading'\nimport shouldLogin from 'base/shouldLogin'\nexport default {\n  mixins: [videoPage],\n  name: '',\n  components: {\n    publicImgCard,\n    pageLoading,\n    shouldLogin\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/videoIndex/components/scene.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-25 13:31:45\n * @Update: 2019-11-23 11:50:47\n * @Update log: 更新日志\n -->\n<template>\n  <div @scroll=\"hideVideo\">\n    <page-loading v-show=\"load\"></page-loading>\n    <public-img-card :data=\"data\" @index=\"getIndex\" v-show=\"!load\" ref=\"public\"></public-img-card>\n    <should-login v-show=\"isLogin === 0\"></should-login>\n  </div>\n</template>\n\n<script>\nimport { videoPage } from 'mixins/Mixins'\nimport publicImgCard from '../public'\nimport pageLoading from 'base/pageLoading'\nimport shouldLogin from 'base/shouldLogin'\nexport default {\n  mixins: [videoPage],\n  name: '',\n  components: {\n    publicImgCard,\n    pageLoading,\n    shouldLogin\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/videoIndex/components/singing.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-25 13:32:01\n * @Update: 2019-11-23 11:51:00\n * @Update log: 更新日志\n -->\n<template>\n  <div @scroll=\"hideVideo\">\n    <page-loading v-show=\"load\"></page-loading>\n    <public-img-card :data=\"data\" @index=\"getIndex\" v-show=\"!load\" ref=\"public\"></public-img-card>\n    <should-login v-show=\"isLogin === 0\"></should-login>\n  </div>\n</template>\n\n<script>\nimport { videoPage } from 'mixins/Mixins'\nimport publicImgCard from '../public'\nimport pageLoading from 'base/pageLoading'\nimport shouldLogin from 'base/shouldLogin'\nexport default {\n  mixins: [videoPage],\n  name: '',\n  components: {\n    publicImgCard,\n    pageLoading,\n    shouldLogin\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/videoIndex/index.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-25 12:55:37\n * @Update: 2019-11-24 12:22:25\n * @Update log: 更新日志\n -->\n<template>\n  <div>\n    <slider-nav :list=\"chooseListTag\"></slider-nav>\n    <keep-alive>\n      <router-view class=\"router-view\" style=\"height: 87vh; overflow-y: scroll;\"></router-view>\n    </keep-alive>\n  </div>\n</template>\n\n<script>\nimport api from 'api'\nimport sliderNav from 'base/sliderNav'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      chooseListTag: [\n        {\n          path: '/videoPage/musicFestival',\n          text: '音乐节'\n        }, {\n          path: '/videoPage/scene',\n          text: '广告'\n        }, {\n          path: '/videoPage/listenBGM',\n          text: '听BGM'\n        }, {\n          path: '/videoPage/singing',\n          text: '娱乐'\n        }, {\n          path: '/videoPage/dance',\n          text: '流行'\n        }, {\n          path: '/videoPage/ACG',\n          text: 'ACG'\n        }, {\n          path: '/videoPage/rock',\n          text: '摇滚'\n        }, {\n          path: '/videoPage/game',\n          text: '游戏'\n        }, {\n          path: '/videoPage/animation',\n          text: '动漫'\n        }\n      ],\n      list: [{\n        id: 0\n      }]\n    }\n  },\n  created () {\n    this._getVideoTag()\n  },\n  methods: {\n    _getVideoTag () {\n      api.getVideoTagFn()\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            // 存储所有的标签数据\n            const tags = data.data\n            tags.filter(ele => {\n              this.chooseListTag.forEach(element => {\n                if (ele.name === element.text) {\n                  if (element.text === '音乐节') {\n                    element.path = element.path\n                  } else {\n                    element.path = element.path + '/' + ele.id\n                    element.text = ele.name\n                  }\n                }\n              })\n            })\n          }\n          console.log(this.list)\n        })\n    }\n  },\n  components: {\n    sliderNav\n  }\n}\n</script>\n\n<style lang='less' scoped>\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/videoIndex/public.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-10-26 08:48:50\n * @Update: 2019-11-19 13:51:47\n * @Update log: 更新日志\n -->\n<template>\n  <div>\n    <div class=\"video-item\" v-for=\"(item, index) in data\" :key=\"index\">\n      <div class=\"videoInfo pd23\">\n        <img ref=\"videoImg\" :src=\"item.data.coverUrl + '?param=360y170'\" alt />\n        <circle-loading type=\"absolute\" width=\"6.7rem\" height=\"3.8rem\" class=\"none\" ref=\"load\"></circle-loading>\n        <div class=\"play-video\" ref=\"playVideo\" @touchstart=\"hideFnBtn(index)\">\n          <video\n            @canplay=\"startPlay(index)\"\n            @timeupdate=\"setBarTime(index)\"\n            class=\"video_tag\"\n            ref=\"video\"\n            src=\"localhost\"\n          ></video>\n          <!-- 阻止工具条冒泡 -->\n          <div class=\"fn-btn\" ref=\"fnBtn\" @click.stop>\n            <!-- 这里是视频按钮集合 -->\n            <span class=\"center-bofang\" ref=\"button\">\n              <i\n                class=\"video\"\n                :class=\"{videobofang1: pause === `pause${index}`, videozantingtingzhi: play === `play${index}`}\"\n                @click=\"playVideo(index)\"\n              ></i>\n            </span>\n            <bar\n              class=\"bar\"\n              :index=\"index\"\n              :allTime=\"item.data.durationms\"\n              :time=\"playTime\"\n              :width=\"progressWidth\"\n              @time=\"changeTime\"\n            ></bar>\n          </div>\n        </div>\n        <span class=\"tag\">{{ item.data.videoGroup ? item.data.videoGroup[0].name : ''}}</span>\n        <span class=\"center-bofang\">\n          <i class=\"video videobofang1\" @click=\"playVideo(index, item.data.vid)\"></i>\n        </span>\n        <span class=\"go-count\">\n          <i class=\"video videobofang\"></i>\n          {{item.data.playTime | setCount}}\n        </span>\n        <span class=\"go-time\">\n          <i class=\"video videoyinlebofangxuanlvjiezou\"></i>\n          {{item.data.durationms | setTime}}\n        </span>\n      </div>\n      <h1 class=\"title pd23\">{{item.data.title}}</h1>\n      <div class=\"bottom border-top pd23\">\n        <div class=\"creator\">\n          <div class=\"img-info\">\n            <img :src=\"item.data.creator.avatarUrl + '?param=50y50'\" alt />\n          </div>\n          <span class=\"name\">{{item.data.creator.nickname}}</span>\n        </div>\n        <div class=\"button\">\n          <!-- 点赞 -->\n          <span class=\"praised\" @click=\"likeVideo(item.data.vid)\">\n            <i class=\"video videozan\"></i>\n            <i class=\"num\">{{item.data.praisedCount | setCount}}</i>\n          </span>\n          <!-- 评论 -->\n          <span class=\"comment\" @click=\"toVideoCom(item.data.vid)\">\n            <i class=\"video videopinglun\"></i>\n            <i class=\"num\">{{item.data.commentCount | setCount}}</i>\n          </span>\n          <!-- 分享 -->\n          <span class=\"share\">\n            <i class=\"video videodiandiandian\"></i>\n          </span>\n        </div>\n      </div>\n      <div class=\"split\"></div>\n    </div>\n  </div>\n</template>\n\n<script>\nimport { filterSetPlayCount, filterSetTime } from 'utils/filters'\nimport circleLoading from 'base/circleLoading'\nimport bar from '../audioIndex/components/bar'\nimport api from 'api'\n// 定义一个上一个播放的视频索引，初始值为undefined\nlet lastIndex\nexport default {\n  name: '',\n  data () {\n    return {\n      pause: '',\n      play: '',\n      timer: null,\n      playTime: '00:00',\n      allTime: 0,\n      progressWidth: 0\n    }\n  },\n  props: {\n    data: {\n      type: Array\n    }\n  },\n  filters: {\n    setCount: function (val) {\n      return filterSetPlayCount(val)\n    },\n    setTime: function (val) {\n      return filterSetTime(val)\n    }\n  },\n  methods: {\n    /**\n    视频点击播放思路：\n    首先视频标签使用 data-src 获取真正地址，src为空，video标签隐藏\n    点击播放按钮，图片隐藏，video 获取到真正的 src 地址，显示，播放\n    当播放时下方的数据隐藏显示\n    */\n    /**\n    * 这里使用了 async/await处理异步\n    */\n    playVideo (index, id) {\n      // 当点击了播放按钮时，判断是否有上一次的播放\n      if (!isNaN(lastIndex)) {\n        // 如果有过播放，并且当前播放的与上一个播放的不是一个\n        if (lastIndex !== index) {\n          // 获取到上一个的视频标签，执行隐藏，并且停止视频的播放\n          this.stopVideoTag(lastIndex)\n        }\n      }\n      // 更新上一个视频索引\n      lastIndex = index\n      this.$emit('index', index)\n      this.$nextTick(async () => {\n        const video = this.$refs.video[index]\n        // // 当没有值的时候，src默认为 http://localhost:8080/，通过判断是否包含localhost来判断当前src的值是否是真正的视频地址\n        // 给src设置默认值为localhost\n        if (video.src.includes('localhost')) {\n          // 显示loading样式\n          this.$refs.load[index].block()\n          // 这里会等待请求数据\n          const res = await api.getVideoUrlFn(id)\n          // 赋值给src开始加载\n          video.src = res.data.urls[0].url\n        }\n        // 显示视频元素\n        this.showVideoTag(index)\n        // 显示相关btn按钮\n        this.showFnBtn(index)\n        if (video.paused) {\n          // 暂停 -> 播放\n          this.videoPlay(video, index)\n        } else {\n          // 播放 -> 暂停\n          this.videoPause(video, index)\n        }\n      })\n    },\n    stopVideoTag (index) {\n      const i = index || lastIndex\n      // 时常注意在判断0的时候会成false\n      // 如果需要可以使用 isNaN() 判断是否是非数 再取反 就可以获得正确的结果\n      if (!isNaN(i)) {\n        const video = this.$refs.video[i]\n        this.hideVideoTag(i)\n        // 停止视频播放\n        video.pause()\n        video.currentTime = 0\n      }\n    },\n    likeVideo (id) {\n      const type = 5\n      this.$emit('likeVideo', type, id)\n      api.resourceLikeOutFn(type, id)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            console.log(data)\n          }\n        })\n    },\n    /**\n     * 显示相关按钮\n     */\n    showFnBtn (index) {\n      this.$refs.fnBtn[index].style.zIndex = 1\n      this.play = `play${index}`\n    },\n    /**\n     * 设置当前播放时长\n     */\n    setBarTime (index) {\n      // 首先我们计算到当前的播放时间\n      const video = this.$refs.video[index]\n      let minutes = Math.floor(video.currentTime / 60)\n      let seconds = Math.floor(video.currentTime - minutes * 60)\n      let minuteValue\n      let secondValue\n      // 进行格式转换，当分钟小于10的时候，在前面加0\n      if (minutes < 10) {\n        minuteValue = '0' + minutes\n      } else {\n        minuteValue = minutes\n      }\n      // 秒数的格式设置\n      if (seconds < 10) {\n        secondValue = '0' + seconds\n      } else {\n        secondValue = seconds\n      }\n      // 进行时间值拼接，展示到页面\n      let audioTime = minuteValue + ':' + secondValue\n      this.playTime = audioTime\n      // // 进度条的长度计算\n      let barLength = video.currentTime / video.duration * 100\n      this.setProgress(barLength)\n    },\n    /**\n     * 设置进度条长度\n     */\n    setProgress (val) {\n      if (val < 0 || val > 100) {\n        return\n      }\n      this.progressWidth = val\n    },\n    /**\n     * 当前可以播放了\n     */\n    startPlay (index) {\n      this.$refs.load[index].none()\n    },\n    /**\n     * 显示整个video区域\n     */\n    showVideoTag (index) {\n      const videoBtn = this.$refs.playVideo[index]\n      videoBtn.style.zIndex = 1\n    },\n    /**\n     * 隐藏整个 video 区域\n     */\n    hideVideoTag (index) {\n      const videoBtn = this.$refs.playVideo[index]\n      videoBtn.style.zIndex = '-1'\n    },\n    /**\n     * 播放视频\n     */\n    videoPlay (video, index) {\n      video.play()\n      this.play = `play${index}`\n      this.pause = ``\n      this.hideFnBtn(index)\n    },\n    /**\n     * 当视频正在播放时的事件\n     */\n    changeTime (time, index) {\n      const video = this.$refs.video[index]\n      const current = time * video.duration / 100\n      video.currentTime = current\n      this.videoPlay(video, index)\n    },\n    /**\n     * 暂停视频\n     */\n    videoPause (video, index) {\n      video.pause()\n      this.hideFnBtn(index)\n      this.pause = `pause${index}`\n      this.play = ``\n    },\n    /**\n     * 在一段时间没有操作后隐藏工具按钮\n     */\n    hideFnBtn (index) {\n      const _self = this\n      this.showFnBtn(index)\n      _self.$refs.fnBtn[index].style.display = 'block'\n      if (this.timer) {\n        clearTimeout(this.timer)\n      }\n      this.timer = setTimeout(function () {\n        _self.$refs.fnBtn[index].style.display = 'none'\n      }, 2000)\n    },\n    toVideoCom (id) {\n      this.$router.push({ name: 'videoComments', params: { id } })\n    }\n  },\n  components: {\n    circleLoading,\n    bar\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n@import url(\"//at.alicdn.com/t/font_1477601_lo5yxiay04f.css\");\n@imgWidth: 6.7rem;\n@imgHeight: 3.8rem;\n\n.none {\n  display: none;\n}\n\n.videotag {\n  box-sizing: border-box;\n  font-size: 0.2rem;\n  color: #ccc;\n  padding: 0.04rem 0.13rem;\n}\n.videoInfo {\n  position: relative;\n  width: @imgWidth;\n  padding-bottom: @imgHeight;\n  height: 0;\n  margin-top: 0.23rem;\n  .play-video {\n    position: absolute;\n    top: 0;\n    width: @imgWidth;\n    height: @imgHeight;\n    background-color: #222;\n    border-radius: 0.2rem;\n    z-index: -1;\n    .video_tag {\n      position: absolute;\n      width: @imgWidth;\n      border-radius: 0.2rem;\n      height: @imgHeight;\n    }\n    .fn-btn {\n      width: @imgWidth;\n      height: @imgHeight;\n      .bar {\n        position: absolute;\n        bottom: -0.3rem;\n        left: 0;\n        right: 0;\n      }\n    }\n  }\n  .center-bofang {\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    transform: translate(-50%, -50%);\n    .videobofang1,\n    .videozantingtingzhi {\n      font-size: 0.8rem;\n      color: rgba(255, 255, 255, 0.7);\n    }\n  }\n  .go-count {\n    position: absolute;\n    bottom: 0.1rem;\n    left: 0.1rem;\n    .videotag();\n    .videobofang {\n      font-size: 0.24rem;\n      margin-right: 3px;\n    }\n  }\n  .go-time {\n    position: absolute;\n    bottom: 0.1rem;\n    right: 0.1rem;\n    .videotag();\n    .videoyinlebofangxuanlvjiezou {\n      font-size: 0.2rem;\n      margin-right: 3px;\n    }\n  }\n  .tag {\n    position: absolute;\n    top: 0.2rem;\n    right: 0.13rem;\n    .videotag();\n    border-radius: 0.3rem;\n    border: 1px solid #777;\n  }\n  img {\n    width: @imgWidth;\n    border-radius: 0.2rem;\n    height: @imgHeight;\n  }\n}\n.title {\n  line-height: 1.5;\n  margin: 0.2rem 0;\n  .twoLinesEllipsis();\n}\n.bottom {\n  height: 1rem;\n  .flex-between();\n  align-items: center;\n  .creator {\n    display: flex;\n    align-items: center;\n    .name {\n      max-width: 3rem;\n      .ellipsis();\n    }\n    .img-info {\n      width: 0.5rem;\n      height: 0;\n      padding-bottom: 0.5rem;\n      margin-right: 3px;\n      img {\n        width: 0.5rem;\n        height: 0.5rem;\n        border-radius: 50%;\n      }\n    }\n  }\n  .button {\n    .praised,\n    .comment {\n      position: relative;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/videoIndex/videoComments/components/video.vue",
    "content": "<template>\n  <div class=\"play-video\" ref=\"playVideo\" @touchstart=\"hideFnBtn\">\n    <circle-loading type=\"absolute\" width=\"6.7rem\" height=\"3.8rem\" class=\"none\" ref=\"load\"></circle-loading>\n    <video\n      @canplay=\"startPlay\"\n      @timeupdate=\"setBarTime\"\n      class=\"video_tag\"\n      ref=\"video\"\n      src=\"localhost\"\n    ></video>\n    <!-- 阻止工具条冒泡 -->\n    <div class=\"fn-btn\" ref=\"fnBtn\" @click.stop>\n      <!-- 这里是视频按钮集合 -->\n      <span class=\"center-bofang\" ref=\"button\">\n        <i\n          class=\"video\"\n          :class=\"{videobofang1: pause === `pause`, videozantingtingzhi: play === `play`}\"\n          @click=\"playVideo(videoId)\"\n        ></i>\n      </span>\n      <!-- :allTime=\"item.data.durationms\" -->\n      <bar\n        class=\"bar\"\n        :time=\"playTime\"\n        :width=\"progressWidth\"\n        @time=\"changeTime\"\n        :allTime=\"allTime\"\n      ></bar>\n    </div>\n  </div>\n</template>\n\n<script>\nimport circleLoading from 'base/circleLoading'\nimport bar from '../../../audioIndex/components/bar'\nimport { filterSetPlayCount, filterSetTime } from 'utils/filters'\nimport api from 'api'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      pause: 'pause',\n      play: '',\n      timer: null,\n      playTime: '00:00',\n      progressWidth: 0\n    }\n  },\n  props: {\n    videoId: {\n      type: String\n    },\n    allTime: {\n      type: Number\n    }\n  },\n  filters: {\n    setCount: function (val) {\n      return filterSetPlayCount(val)\n    },\n    setTime: function (val) {\n      return filterSetTime(val)\n    }\n  },\n  methods: {\n    /**\n    * 这里使用了 async/await处理异步\n    */\n    playVideo (id) {\n      this.$nextTick(async () => {\n        const video = this.$refs.video\n        if (video.src.includes('localhost')) {\n          // 显示loading样式\n          this.$refs.load.block()\n          // 这里会等待请求数据\n          const res = await api.getVideoUrlFn(id)\n          // 赋值给src开始加载\n          video.src = res.data.urls[0].url\n        }\n        // 显示相关btn按钮\n        if (video.paused) {\n          // 暂停 -> 播放\n          this.videoPlay(video)\n        } else {\n          // 播放 -> 暂停\n          this.videoPause(video)\n        }\n      })\n    },\n    /**\n     * 设置当前播放时长\n     */\n    setBarTime () {\n      // 首先我们计算到当前的播放时间\n      const video = this.$refs.video\n      let minutes = Math.floor(video.currentTime / 60)\n      let seconds = Math.floor(video.currentTime - minutes * 60)\n      let minuteValue\n      let secondValue\n      // 进行格式转换，当分钟小于10的时候，在前面加0\n      if (minutes < 10) {\n        minuteValue = '0' + minutes\n      } else {\n        minuteValue = minutes\n      }\n      // 秒数的格式设置\n      if (seconds < 10) {\n        secondValue = '0' + seconds\n      } else {\n        secondValue = seconds\n      }\n      // 进行时间值拼接，展示到页面\n      let audioTime = minuteValue + ':' + secondValue\n      this.playTime = audioTime\n      // // 进度条的长度计算\n      let barLength = video.currentTime / video.duration * 100\n      this.setProgress(barLength)\n    },\n    /**\n     * 设置进度条长度\n     */\n    setProgress (val) {\n      if (val < 0 || val > 100) {\n        return\n      }\n      this.progressWidth = val\n    },\n    /**\n     * 当前可以播放了\n     */\n    startPlay () {\n      this.$refs.load.none()\n    },\n    /**\n     * 播放视频\n     */\n    videoPlay (video) {\n      video.play()\n      this.play = `play`\n      this.pause = ``\n      this.hideFnBtn()\n    },\n    /**\n     * 当视频正在播放时的事件\n     */\n    changeTime (time) {\n      const video = this.$refs.video\n      const current = time * video.duration / 100\n      video.currentTime = current\n      this.videoPlay(video)\n    },\n    /**\n     * 暂停视频\n     */\n    videoPause (video) {\n      video.pause()\n      this.hideFnBtn()\n      this.pause = `pause`\n      this.play = ``\n    },\n    /**\n     * 在一段时间没有操作后隐藏工具按钮\n     */\n    hideFnBtn () {\n      const _self = this\n      _self.$refs.fnBtn.style.display = 'block'\n      _self.$emit('blockNav')\n      if (this.timer) {\n        clearTimeout(this.timer)\n      }\n      this.timer = setTimeout(function () {\n        _self.$refs.fnBtn.style.display = 'none'\n        _self.$emit('hideNav')\n      }, 2000)\n    }\n  },\n  components: {\n    circleLoading,\n    bar\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n@imgWidth: 100vw;\n@imgHeight: 3.8rem;\n\n.none {\n  display: none;\n}\n.videotag {\n  box-sizing: border-box;\n  font-size: 0.2rem;\n  color: #ccc;\n  padding: 0.04rem 0.13rem;\n}\n.play-video {\n  position: relative;\n  width: @imgWidth;\n  height: @imgHeight;\n  background-color: #222;\n  .video_tag {\n    position: absolute;\n    width: @imgWidth;\n    height: @imgHeight;\n  }\n  .fn-btn {\n    width: @imgWidth;\n    height: @imgHeight;\n    .bar {\n      position: absolute;\n      bottom: -0.3rem;\n      left: 0;\n      right: 0;\n    }\n  }\n  .center-bofang {\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    transform: translate(-50%, -50%);\n    .videobofang1,\n    .videozantingtingzhi {\n      font-size: 0.8rem;\n      color: rgba(255, 255, 255, 0.7);\n    }\n  }\n  .go-count {\n    position: absolute;\n    bottom: 0.1rem;\n    left: 0.1rem;\n    .videotag();\n    .videobofang {\n      font-size: 0.24rem;\n      margin-right: 3px;\n    }\n  }\n  .go-time {\n    position: absolute;\n    bottom: 0.1rem;\n    right: 0.1rem;\n    .videotag();\n    .videoyinlebofangxuanlvjiezou {\n      font-size: 0.2rem;\n      margin-right: 3px;\n    }\n  }\n  .tag {\n    position: absolute;\n    top: 0.2rem;\n    right: 0.13rem;\n    .videotag();\n    border-radius: 0.3rem;\n    border: 1px solid #777;\n  }\n  img {\n    width: @imgWidth;\n    border-radius: 0.2rem;\n    height: @imgHeight;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/videoIndex/videoComments/components/videoCreator.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-11-12 13:30:45\n * @Update: 2019-11-12 20:59:21\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"video-creator border-top\">\n    <div class=\"left\">\n      <div class=\"img-info\">\n        <img :src=\"avatarUrl + '?param=50y50'\" alt />\n      </div>\n      <span class=\"author\">{{nickname}}</span>\n    </div>\n    <div class=\"concern tag-group\">+ 关注</div>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: '',\n  props: {\n    avatarUrl: {\n      type: String\n    },\n    nickname: {\n      type: String\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n.video-creator {\n  height: 0.8rem;\n  .flex-between();\n  align-items: center;\n  padding: 0.2rem 0.23rem;\n  .left {\n    display: flex;\n    align-items: center;\n    .img-info {\n      width: 0.5rem;\n      height: 0;\n      padding-bottom: 0.5rem;\n      margin-right: 0.2rem;\n      img {\n        width: 100%;\n        border-radius: 50%;\n      }\n    }\n  }\n  .concern {\n    background-color: @bgcolor;\n    color: #fff;\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/videoIndex/videoComments/components/videoInfo.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-11-12 13:28:45\n * @Update: 2019-11-12 19:57:30\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"video-info-wra\">\n    <h1 class=\"video-title twoLinesEllipsis\">{{title}}</h1>\n    <div class=\"video-info-top\">\n      <span class=\"num\">{{playTime | setNum}}次观看</span>\n      <span\n        class=\"tag-group\"\n        v-for=\"(item, index) in videoGroup\"\n        :key=\"index\"\n      >#{{item.name | setName}}#</span>\n    </div>\n    <div class=\"video-btn\">\n      <span class=\"icon-btn\">\n        <i class=\"video-info zan\"></i>\n        <i class=\"num\">{{praisedCount | setNum}}</i>\n      </span>\n      <span class=\"icon-btn\">\n        <i class=\"video-info tianjiawenjian\"></i>\n        <i class=\"num\">{{subscribeCount | setNum}}</i>\n      </span>\n      <span class=\"icon-btn\">\n        <i class=\"video-info videopinglun\"></i>\n        <i class=\"num\">{{commentCount | setNum}}</i>\n      </span>\n      <span class=\"icon-btn\">\n        <i class=\"video-info videofenxiang\"></i>\n        <i class=\"num\">{{shareCount | setNum}}</i>\n      </span>\n    </div>\n  </div>\n</template>\n\n<script>\nimport { filterSetPlayCount } from 'utils/filters'\nexport default {\n  name: '',\n  props: {\n    title: {\n      type: String\n    },\n    playTime: {\n      type: Number\n    },\n    praisedCount: {\n      type: Number\n    },\n    commentCount: {\n      type: Number\n    },\n    shareCount: {\n      type: Number\n    },\n    subscribeCount: {\n      type: Number\n    },\n    videoGroup: {\n      type: Array\n    }\n  },\n  filters: {\n    setNum: function (val) {\n      return filterSetPlayCount(val)\n    },\n    setName: function (val) {\n      val = val.replace(/#/g, '')\n      return val\n    }\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"//at.alicdn.com/t/font_1506186_kz71sqzq2o.css\");\n@import url(\"~styles/global.less\");\n.video-info-wra {\n  margin: 0.2rem 0;\n  .video-title {\n    font-size: 0.3rem;\n    line-height: 1.5;\n    font-weight: 600;\n  }\n  .video-info-top {\n    height: 0.8rem;\n    line-height: 0.8rem;\n  }\n  .video-btn {\n    .flex-between();\n    .icon-btn {\n      display: flex;\n      align-items: center;\n      flex-direction: column;\n      .video-info {\n        margin: 0.1rem;\n        font-size: 0.4rem;\n      }\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/pages/videoIndex/videoComments/index.vue",
    "content": "<!--\n * @Author: Lambda\n * @Begin: 2019-11-11 11:49:45\n * @Update: 2019-11-12 22:07:06\n * @Update log: 更新日志\n -->\n<template>\n  <div class=\"video-com\">\n    <div class=\"titleFixed\">\n      <general-nav @returnPage=\"returnPage\" ref=\"nav\" class=\"fixed nav-color\">\n        <span class=\"text\">{{title}}</span>\n      </general-nav>\n      <video-card :videoId=\"videoId\" :allTime=\"allTime\" @blockNav=\"blockNav\" @hideNav=\"hideNav\"></video-card>\n    </div>\n    <div v-show=\"!load\" class=\"bottom-wra\" ref=\"wra\" @scroll=\"scroll\">\n      <video-info\n        class=\"pd23\"\n        :title=\"title\"\n        :playTime=\"playTime\"\n        :praisedCount=\"praisedCount\"\n        :commentCount=\"commentCount\"\n        :shareCount=\"shareCount\"\n        :subscribeCount=\"subscribeCount\"\n        :videoGroup=\"videoGroup.slice(0,3)\"\n      ></video-info>\n      <video-creator :class=\"{creatorFixed}\" :avatarUrl=\"avatarUrl\" :nickname=\"nickname\"></video-creator>\n      <div class=\"split\" :style=\"{marginTop: top}\"></div>\n      <h1 class=\"pd23 title\">相关视频</h1>\n      <video-list\n        class=\"pd23\"\n        v-for=\"(item, index) in allVideoList\"\n        :key=\"index\"\n        :videoList=\"true\"\n        line=\"two\"\n        :ImgUrl=\"item.coverUrl\"\n        :name=\"item.title\"\n        :durationms=\"item.durationms\"\n        :nicknames=\"item.creator\"\n        :playTime=\"item.playTime\"\n      ></video-list>\n      <div class=\"split\"></div>\n      <comments\n        v-show=\"hotComments.length\"\n        title=\"精彩评论\"\n        :comments=\"hotComments\"\n        class=\"pd23\"\n        @showMenu=\"showMenu\"\n        @likeComment=\"likeComment\"\n      ></comments>\n      <comments\n        v-show=\"comments.length\"\n        title=\"最新评论\"\n        :total=\"total\"\n        :comments=\"comments\"\n        class=\"pd23\"\n        @showMenu=\"showMenu\"\n        @likeComment=\"likeComment\"\n      ></comments>\n      <van-search\n        class=\"border-top commentInp\"\n        v-model=\"input\"\n        :placeholder=\"placeholder\"\n        show-action\n        :clearable=\"false\"\n        background=\"#fff\"\n        left-icon\n        @search=\"pushCom(input)\"\n      >\n        <div slot=\"action\" :class=\"{disable: !input}\" @click=\"pushCom(input)\">发送</div>\n      </van-search>\n      <center-menu @update:show=\"updateShow\" @delCom=\"delCom\" :isShow=\"isShow\"></center-menu>\n    </div>\n    <page-loading v-show=\"load\"></page-loading>\n  </div>\n</template>\n\n<script>\nimport pageLoading from 'base/pageLoading'\nimport comments from 'base/comments'\nimport videoCard from './components/video'\nimport videoCreator from './components/videoCreator'\nimport videoInfo from './components/videoInfo'\nimport videoList from 'base/interchangeable'\nimport generalNav from 'base/generalNav'\nimport centerMenu from '../../commentsIndex/components/centerMenu'\nimport api from 'api'\nimport { Toast } from 'vant'\n\nexport default {\n  name: '',\n  data () {\n    return {\n      load: true,\n      allLoad: { detail: false, comments: false, videoRelated: false },\n      videoId: '',\n      allTime: 0,\n      title: '',\n      total: 0,\n      playTime: 0,\n      praisedCount: 0,\n      commentCount: 0,\n      shareCount: 0,\n      subscribeCount: 0,\n      avatarUrl: '',\n      nickname: '',\n      videoComments: [],\n      hotComments: [],\n      comments: [],\n      isShow: false,\n      input: '',\n      top: '',\n      placeholder: '',\n      creatorFixed: false,\n      allVideoList: [],\n      videoGroup: []\n    }\n  },\n  activated () {\n    this.load = true\n    this.title = ''\n    this.videoId = ''\n    this.params = this.$route.params\n    const params = this.params\n    if (Object.keys(params).length === 0) {\n      this.$router.back()\n    }\n    this.videoId = params.id\n    this.getAllInfo(params.id)\n  },\n  methods: {\n    /**\n     * 通过 async/await 使得等待函数请求，当全部函数正确请求成功后\n     * 改变页面的 loading 状态\n     */\n    async getAllInfo (id) {\n      const detail = await this._getVideoDetail(id)\n      const related = await this._getVideoRelated(id)\n      const comments = await this._getVideoComments(id)\n      if (detail && related && comments) {\n        this.load = false\n      }\n    },\n    /**\n     * 获取视频详情\n     */\n    async _getVideoDetail (id) {\n      const res = await api.getVideoDetailFn(id)\n      const { data } = res\n      if (data.code === 200) {\n        const { durationms, title, videoGroup, playTime, praisedCount, commentCount, shareCount, subscribeCount } = data.data\n        const { avatarUrl, nickname } = data.data.creator\n        this.allTime = durationms\n        this.title = title\n        this.playTime = playTime\n        this.praisedCount = praisedCount\n        this.commentCount = commentCount\n        this.shareCount = shareCount\n        this.subscribeCount = subscribeCount\n        this.avatarUrl = avatarUrl\n        this.nickname = nickname\n        this.videoGroup = videoGroup\n        return true\n      }\n      return false\n    },\n    /**\n     * 获取相关视频列表信息\n     */\n    async _getVideoRelated (id) {\n      const res = await api.getVideoRelatedFn(id)\n      const { data } = res\n      if (data.code === 200) {\n        this.allVideoList = data.data\n        return true\n      }\n      return false\n    },\n    /**\n     * 获取视频评论\n     */\n    async _getVideoComments (id) {\n      const res = await api.getVideoCommentsFn(id)\n      const { data } = res\n      if (data.code === 200) {\n        this.total = data.total\n        this.hotComments = data.hotComments\n        this.comments = data.comments\n        return true\n      }\n      return false\n    },\n    /**\n     * 显示回复评论，\n     * 如果是自己的评论显示删除评论\n     */\n    showMenu () {\n      this.isShow = true\n    },\n    scroll (e) {\n      let top = this.$refs.wra.scrollTop\n      if (top >= 148) {\n        this.creatorFixed = true\n        this.top = '1.2rem'\n      } else {\n        this.creatorFixed = false\n        this.top = '0'\n      }\n    },\n    /**\n     * 评论内容\n     */\n    pushCom (content) {\n      if (!content) {\n        Toast({\n          position: 'bottom',\n          message: '评论为空'\n        })\n        return\n      }\n      Toast.allowMultiple()\n      let loadingToast = Toast.loading({\n        forbidClick: true,\n        duration: 1000\n      })\n      const params = this.params\n      const id = params.id\n      const type = 5\n      api.pushComFn(type, id, content)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            this.input = ''\n            loadingToast.clear()\n            Toast({\n              position: 'bottom',\n              message: '发表成功'\n            })\n            this._getVideoComments(id)\n          }\n        })\n        .catch(err => {\n          if (err) {\n            loadingToast.clear()\n            Toast('当前未登录')\n          }\n        })\n    },\n    delCom (comId) {\n      const params = this.params\n      const id = params.id\n      const type = 5\n      api.delComFn(type, id, comId)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            // 删除成功\n            this.hideMenu()\n            this._getVideoComments(id)\n          }\n        })\n    },\n    updateShow (val) {\n      this.isShow = val\n    },\n    /**\n     * 隐藏标题行\n     */\n    hideNav () {\n      this.$refs.nav.hidden()\n    },\n    /**\n     * 喜欢，点赞该评论\n     */\n    likeComment (cid, like) {\n      const params = this.params\n      const id = params.id\n      const type = 5\n      api.commentLikeFn(id, cid, like, type)\n        .then(res => {\n          const { data } = res\n          if (data.code === 200) {\n            this._getVideoComments(id)\n          }\n        })\n    },\n    /**\n     * 显示标题行\n     */\n    blockNav () {\n      this.$refs.nav.visible()\n    },\n    returnPage () {\n      this.$router.go(-1)\n    }\n  },\n  components: {\n    pageLoading,\n    videoCard,\n    videoInfo,\n    videoCreator,\n    generalNav,\n    comments,\n    videoList,\n    centerMenu\n  }\n}\n</script>\n\n<style lang='less' scoped>\n@import url(\"~styles/global.less\");\n\n@import url(\"//at.alicdn.com/t/font_1477601_lo5yxiay04f.css\");\n.topFixed {\n  position: fixed;\n  width: 100%;\n  height: 0.8rem;\n  z-index: 9;\n}\n.fixed {\n  .topFixed();\n  top: 0;\n}\n.creatorFixed {\n  position: fixed;\n  left: 0;\n  right: 0;\n  background: #fff;\n  z-index: 1;\n  top: 3.8rem;\n}\n.video-com {\n  .nav-color {\n    color: #fff;\n  }\n  .text {\n    font-size: 0.4rem;\n    .ellipsis();\n  }\n}\n.title {\n  font-weight: 700;\n  margin: 0.3rem 0;\n}\n.bottom-wra {\n  height: 8rem;\n  overflow: scroll;\n}\n.commentInp {\n  position: fixed;\n  bottom: 0;\n  left: 0;\n  right: 0;\n}\n</style>\n"
  },
  {
    "path": "musicPlayer/src/router/index.js",
    "content": "/*\n * @Author: 李浩栋\n * @Begin: 2019-07-27 17:08:42\n * @Update: 2019-12-07 13:17:07\n * @Update log: 更新日志\n */\nimport Vue from 'vue'\nimport Router from 'vue-router'\n\nconst navIndex = () => import(/* webpackChunkName: \"group-nav\" */ '@/pages/nav/index')\nconst findIndex = () => import(/* webpackChunkName: \"group-findPage\" */ '@/pages/findIndex/index')\nconst homeIndex = () => import(/* webpackChunkName: \"group-homePage\" */ '@/pages/homeIndex/index')\nconst videoIndex = () => import(/* webpackChunkName: \"group-homePage\" */ '@/pages/videoIndex/index')\nconst videoComments = () => import(/* webpackChunkName: \"group-homePage\" */ '@/pages/videoIndex/videoComments/index')\nconst userInfoIndex = () => import(/* webpackChunkName: \"group-homePage\" */ '@/pages/userInfoIndex/index')\nconst musicFestival = () => import(/* webpackChunkName: \"group-homePage\" */ '@/pages/videoIndex/components/musicFestival')\nconst scene = () => import(/* webpackChunkName: \"group-homePage\" */ '@/pages/videoIndex/components/scene')\nconst listenBGM = () => import(/* webpackChunkName: \"group-homePage\" */ '@/pages/videoIndex/components/listenBGM')\nconst singing = () => import(/* webpackChunkName: \"group-homePage\" */ '@/pages/videoIndex/components/singing')\nconst dance = () => import(/* webpackChunkName: \"group-homePage\" */ '@/pages/videoIndex/components/dance')\nconst acg = () => import(/* webpackChunkName: \"group-homePage\" */ '@/pages/videoIndex/components/acg')\nconst rock = () => import(/* webpackChunkName: \"group-homePage\" */ '@/pages/videoIndex/components/rock')\nconst game = () => import(/* webpackChunkName: \"group-homePage\" */ '@/pages/videoIndex/components/game')\nconst animation = () => import(/* webpackChunkName: \"group-homePage\" */ '@/pages/videoIndex/components/animation')\nconst friend = () => import(/* webpackChunkName: \"group-homePage\" */ '@/pages/friendIndex/index')\nconst loginIndex = () => import(/* webpackChunkName: \"group-loginPage\" */ '@/pages/loginIndex/index')\nconst phoneAccount = () => import(/* webpackChunkName: \"group-login-phonePage\" */ '@/pages/loginIndex/components/phoneAccount')\nconst phonePwd = () => import(/* webpackChunkName: \"group-login-pwdPage\" */ '@/pages/loginIndex/components/phonePwd')\nconst phoneVerify = () => import(/* webpackChunkName: \"group-login-verifyPage\" */ '@/pages/loginIndex/components/phoneVerify')\nconst search = () => import(/* webpackChunkName: \"group-searchPage\" */ '@/pages/searchIndex/index')\nconst searchResults = () => import(/* webpackChunkName: \"group-resultPage\" */ '@/pages/searchResults/index')\nconst singer = () => import(/* webpackChunkName: \"group-resultPage\" */ '@/pages/searchResults/singerIndex/singer')\nconst composite = () => import(/* webpackChunkName: \"group-result-comPage\" */ '@/pages/searchResults/composite/composite')\nconst song = () => import(/* webpackChunkName: \"group-result-songPage\" */ '@/pages/searchResults/songIndex/song')\nconst video = () => import(/* webpackChunkName: \"group-result-videoPage\" */ '@/pages/searchResults/videoIndex/video')\nconst artist = () => import(/* webpackChunkName: \"group-result-artistPage\" */ '@/pages/searchResults/artistIndex/artist')\nconst album = () => import(/* webpackChunkName: \"group-result-albumPage\" */ '@/pages/searchResults/albumIndex/album')\nconst playList = () => import(/* webpackChunkName: \"group-result-playlistPage\" */ '@/pages/searchResults/playListIndex/playList')\nconst djRadio = () => import(/* webpackChunkName: \"group-result-djRadioPage\" */ '@/pages/searchResults/djRadioIndex/djRadio')\nconst user = () => import(/* webpackChunkName: \"group-result-userPage\" */ '@/pages/searchResults/userIndex/user')\nconst dateRecommend = () => import(/* webpackChunkName: \"group-date-recommendPage\" */ '@/pages/dateRecommend')\nconst recommend = () => import(/* webpackChunkName: \"group-recommendPage\" */ '@/pages/recommend')\nconst recommended = () => import(/* webpackChunkName: \"group-recommendedPage\" */ '@/pages/recommend/recommended')\nconst fine = () => import(/* webpackChunkName: \"group-recommendedPage\" */ '@/pages/recommend/fine')\nconst general = () => import(/* webpackChunkName: \"group-recommendedPage\" */ '@/pages/recommend/general')\nconst idx = () => import(/* webpackChunkName: \"group-idxPage\" */ '@/pages/idx')\nconst dj = () => import(/* webpackChunkName: \"group-djPage\" */ '@/pages/dj')\nconst classification = () => import(/* webpackChunkName: \"group-myFavorite\" */ '@/pages/dj/childrenPage/class')\nconst djPayGift = () => import(/* webpackChunkName: \"group-myFavorite\" */ '@/pages/dj/childrenPage/djPayGift')\nconst djRanking = () => import(/* webpackChunkName: \"group-myFavorite\" */ '@/pages/dj/childrenPage/ranking')\nconst djRankingAnchor = () => import(/* webpackChunkName: \"group-myFavorite\" */ '@/pages/dj/childrenPage/ranking-anchor')\nconst djRankingProgram = () => import(/* webpackChunkName: \"group-myFavorite\" */ '@/pages/dj/childrenPage/ranking-program')\nconst djRankingRadio = () => import(/* webpackChunkName: \"group-myFavorite\" */ '@/pages/dj/childrenPage/ranking-radio')\nconst albumPage = () => import(/* webpackChunkName: \"group-albumPage\" */ 'base/albumPage')\nconst djDetailPage = () => import(/* webpackChunkName: \"group-djDetailPage\" */ 'base/djDetailPage')\nconst djTopConDetailPage = () => import(/* webpackChunkName: \"group-djDetailPage\" */ '@/pages/dj/childrenPage/topConDetail')\nconst djClassRecommendDetailPage = () => import(/* webpackChunkName: \"group-djDetailPage\" */ '@/pages/dj/childrenPage/classRecommend')\nconst artistDetailPage = () => import(/* webpackChunkName: \"group-djDetailPage\" */ '@/components/detailPage')\nconst recentlyPlayed = () => import(/* webpackChunkName: \"group-recentlyPlayed\" */ '@/pages/recentlyPlayed')\nconst djSublist = () => import(/* webpackChunkName: \"group-djSublist\" */ '@/pages/djSublist')\nconst myFavorite = () => import(/* webpackChunkName: \"group-myFavorite\" */ '@/pages/myFavorite')\nconst albums = () => import(/* webpackChunkName: \"group-myFavorite\" */ '@/pages/myFavorite/components/albums')\nconst artists = () => import(/* webpackChunkName: \"group-myFavorite\" */ '@/pages/myFavorite/components/artists')\nconst column = () => import(/* webpackChunkName: \"group-myFavorite\" */ '@/pages/myFavorite/components/column')\nconst mlog = () => import(/* webpackChunkName: \"group-myFavorite\" */ '@/pages/myFavorite/components/mlog')\nconst videos = () => import(/* webpackChunkName: \"group-myFavorite\" */ '@/pages/myFavorite/components/videos')\nconst moreNewDish = () => import(/* webpackChunkName: \"group-myFavorite\" */ '@/pages/findIndex/components/moreNewDish')\nconst moreNewSongs = () => import(/* webpackChunkName: \"group-myFavorite\" */ '@/pages/findIndex/components/moreNewSongs')\nconst chinese = () => import(/* webpackChunkName: \"group-myFavorite\" */ '@/pages/findIndex/components/chinese')\nconst europe = () => import(/* webpackChunkName: \"group-myFavorite\" */ '@/pages/findIndex/components/europe')\nconst korea = () => import(/* webpackChunkName: \"group-myFavorite\" */ '@/pages/findIndex/components/korea')\nconst japan = () => import(/* webpackChunkName: \"group-myFavorite\" */ '@/pages/findIndex/components/japan')\nconst comments = () => import(/* webpackChunkName: \"group-myFavorite\" */ '@/pages/commentsIndex/index')\n\nVue.use(Router)\n\nexport default new Router({\n  /**************************************************\n   *\n   * 设置 链接激活时使用的 CSS 类名\n   * 默认值: \"router-link-active\"\n   * 可以通过路由的构造选项 linkActiveClass 来全局配置。\n   *\n   * 通过设置 meta: { keepAlive: true },来定义一个页面是否需要做缓存\n   *\n   **************************************************/\n  linkActiveClass: 'ac',\n  routes: [{\n    /**\n       * 设置页面初次加载后默认显示 find 页面\n       */\n    path: '/',\n    name: 'main',\n    component: navIndex,\n    redirect: '/find',\n    children: [{\n      path: '/find',\n      component: findIndex\n    }, {\n      path: '/home',\n      name: 'home',\n      component: homeIndex\n    }, {\n      path: '/friend',\n      component: friend\n    }, {\n      path: '/videoPage',\n      name: 'videoPage',\n      component: videoIndex,\n      redirect: '/videoPage/musicFestival',\n      children: [{\n        path: '/videoPage/musicFestival',\n        component: musicFestival\n      }, {\n        path: '/videoPage/scene/:id',\n        component: scene\n      }, {\n        path: '/videoPage/listenBGM/:id',\n        component: listenBGM\n      }, {\n        path: '/videoPage/singing/:id',\n        component: singing\n      }, {\n        path: '/videoPage/dance/:id',\n        component: dance\n      }, {\n        path: '/videoPage/ACG/:id',\n        component: acg\n      }, {\n        path: '/videoPage/rock/:id',\n        component: rock\n      }, {\n        path: '/videoPage/game/:id',\n        component: game\n      }, {\n        path: '/videoPage/animation/:id',\n        component: animation\n      }]\n    }]\n  }, {\n    // 视频评论页面\n    // 使用  this.$router.push({ name: 'videoComments', params: { id } })\n    // 可以使得地址栏不显示 id 信息，并且可以通过 this.$route.params 获取到值\n    // 要注意这时候在path中不能再写 /:id\n    path: '/videoComments',\n    name: 'videoComments',\n    component: videoComments\n  }, {\n    // 更多新碟\n    path: '/moreNewDish',\n    component: moreNewDish\n  }, {\n    // 新歌推荐\n    path: '/moreNewSongs',\n    component: moreNewSongs,\n    redirect: '/chinese',\n    children: [{\n      path: '/chinese',\n      component: chinese\n    }, {\n      path: '/europe',\n      component: europe\n    }, {\n      path: '/korea',\n      component: korea\n    }, {\n      path: '/japan',\n      component: japan\n    }]\n  }, {\n    // 最近播放\n    path: '/recently',\n    component: recentlyPlayed\n  }, {\n    path: '/dj_sublist',\n    component: djSublist\n  }, {\n    path: '/favorite',\n    component: myFavorite,\n    redirect: '/albums',\n    children: [{\n      path: '/albums',\n      component: albums\n    }, {\n      path: '/artists',\n      component: artists\n    }, {\n      path: '/videos',\n      component: videos\n    }, {\n      path: '/column',\n      component: column\n    }, {\n      path: '/mlog',\n      component: mlog\n    }]\n  }, {\n    path: '/login',\n    name: 'login',\n    component: loginIndex\n  }, {\n    // 登录的一系列路由\n    path: '/phone',\n    component: phoneAccount\n  }, {\n    path: '/pwd',\n    name: 'phonePwd',\n    component: phonePwd\n  }, {\n    path: '/verify',\n    name: 'phoneVerify',\n    component: phoneVerify\n  },\n  {\n    // 搜索页\n    path: '/search',\n    component: search\n  },\n  {\n    // 搜索展示页面\n    path: '/searchResults/:id',\n    component: searchResults,\n    redirect: '/composite/:id',\n    children: [{\n      // 综合页面\n      path: '/composite/:id',\n      component: composite\n    }, {\n      // 单曲页面\n      path: '/song/:id',\n      component: song\n    }, {\n      // 视频页面\n      path: '/video/:id',\n      component: video\n    }, {\n      // 歌手页面\n      path: '/artist/:id',\n      component: artist\n    }, {\n      // 专辑页面\n      path: '/album/:id',\n      component: album\n    }, {\n      // 歌单页面\n      path: '/playList/:id',\n      component: playList\n    }, {\n      // 主播电台页面\n      path: '/djRadio/:id',\n      component: djRadio\n    }, {\n      // 用户页面\n      path: '/user/:id',\n      component: user\n    }]\n  },\n  {\n    // 歌手分类页面\n    path: '/singer',\n    component: singer\n  },\n  {\n    // 用户信息展示页面\n    path: '/user_info',\n    name: 'user_info',\n    component: userInfoIndex\n  },\n  {\n    // 每日推荐页面\n    path: '/dateRecommend',\n    component: dateRecommend\n  },\n  {\n    // 歌单广场页面\n    path: '/recommend',\n    component: recommend,\n    redirect: '/recommended',\n    children: [{\n      // 推荐歌单\n      path: '/recommended',\n      component: recommended\n    }, {\n      // 精品歌单\n      path: '/fine',\n      component: fine\n    }, {\n      // 通用歌单\n      path: '/general/:id',\n      component: general\n    }]\n  },\n  {\n    // 排行榜页面\n    path: '/idx',\n    component: idx\n  },\n  {\n    // 电台页面\n    path: '/dj',\n    component: dj\n  },\n  {\n    path: '/conDetail',\n    name: 'conDetail',\n    component: djTopConDetailPage\n  },\n  {\n    // 电台分类\n    path: '/classification',\n    component: classification\n  },\n  {\n    // 电台分类详情\n    path: '/classDetail',\n    name: 'classDetail',\n    component: djClassRecommendDetailPage\n  },\n  {\n    path: '/pay_fine',\n    component: djPayGift\n  },\n  {\n    path: '/ranking',\n    component: djRanking,\n    redirect: '/program',\n    children: [{\n      path: '/anchor',\n      component: djRankingAnchor\n    }, {\n      path: '/program',\n      component: djRankingProgram\n    }, {\n      path: '/radio',\n      component: djRankingRadio\n    }]\n  },\n  {\n    // 通用专辑展示页面\n    path: '/albumPage',\n    name: 'albumPage',\n    component: albumPage\n  },\n  {\n    // 通用电台详情展示页面\n    path: '/djDetailPage',\n    name: 'djDetailPage',\n    component: djDetailPage\n  },\n  {\n    // 通用歌手展示页面\n    path: '/artistDetailPage',\n    name: 'artistDetailPage',\n    component: artistDetailPage\n  },\n  {\n    // 通用评论展示页面\n    path: '/comments',\n    name: 'comments',\n    component: comments\n  }\n  ]\n})\n"
  },
  {
    "path": "musicPlayer/src/store/actions.js",
    "content": "/*\n * @Author: 李浩栋\n * @Begin: 2019-09-12 14:11:33\n * @Update: 2019-09-22 12:15:54\n * @Update log: 更新日志\n */\nimport {\n  SET_PLAY_SATE,\n  SET_FULL_SCREEN,\n  SET_AUDIO_LIST,\n  SET_AUDIO_INDEX,\n  SET_AUDIO_MODE,\n  SET_PLAY_LIST\n} from './mutation-types'\n\n/**\n * 获取随机值\n */\nfunction getRandomIndex (min, max) {\n  return Math.floor(Math.random() * (max - min + 1) + min)\n}\n/**\n * 打乱一个数组\n */\nfunction shuffle (arr) {\n  const _arr = arr.slice()\n  for (let i = 0; i < _arr.length; i++) {\n    const j = getRandomIndex(0, i)\n    const t = _arr[i]\n    _arr[i] = _arr[j]\n    _arr[j] = t\n  }\n  return _arr\n}\n\nfunction findIndex (list, song) {\n  return list.findIndex(item => {\n    return item.id === song.id\n  })\n}\n\nexport default {\n  /**\n   * 点击歌曲项进行播放\n   */\n  selectPlay ({\n    commit,\n    state\n  }, {\n    list,\n    index\n  }) {\n    commit(SET_AUDIO_LIST, list)\n    if (state.mode === 2) {\n      const randomList = shuffle(list)\n      commit(SET_PLAY_LIST, randomList)\n      index = findIndex(randomList, state.audioList[index])\n    } else {\n      commit(SET_PLAY_LIST, list)\n    }\n    commit(SET_AUDIO_INDEX, index)\n    commit(SET_PLAY_SATE, true)\n    commit(SET_FULL_SCREEN, true)\n  },\n  /**\n   * 播放全部\n   * 传入播放列表\n   */\n  startPlayAll ({\n    commit\n  }, {\n    list\n  }) {\n    commit(SET_AUDIO_LIST, list)\n    commit(SET_AUDIO_INDEX, 0)\n    commit(SET_PLAY_LIST, list)\n    commit(SET_PLAY_SATE, true)\n    commit(SET_FULL_SCREEN, true)\n    commit(SET_AUDIO_MODE, 0)\n  },\n  /**\n   * 向播放列表添加歌曲\n   * 当播放列表为空时添加后开始播放\n   */\n  addToAudioList ({\n    commit,\n    state\n  }, song) {\n    let audioList = state.audioList\n    let playList = state.playList\n    let currentIndex = state.audioIngIndex\n    // 记录当前歌曲\n    let audioIng = audioList[currentIndex]\n    // 查找当前列表中是否有要插入的歌曲,并返回它的索引\n    let findAudioIndex = findIndex(audioList, song)\n    // 因为是插入歌曲，所以索引要+1\n    currentIndex++\n    // 插入这首歌到当前索引位置\n    audioList.splice(currentIndex, 0, song)\n    // 如果已经有了这首歌\n    if (findAudioIndex > -1) {\n      // 如果当前插入序号大于列表中的序号\n      if (currentIndex > findAudioIndex) {\n        audioList.splice(findAudioIndex, 1)\n        currentIndex--\n      } else {\n        audioList.splice(currentIndex + 1, 1)\n      }\n    }\n\n    let currentPlayIndex = findIndex(playList, audioIng) + 1\n\n    let findPlayIndex = findIndex(playList, song)\n\n    playList.splice(currentPlayIndex, 0, song)\n\n    if (findPlayIndex > -1) {\n      if (currentPlayIndex > findPlayIndex) {\n        playList.splice(findPlayIndex, 1)\n      } else {\n        playList.splice(findPlayIndex + 1, 1)\n      }\n    }\n    commit(SET_AUDIO_INDEX, currentIndex)\n    commit(SET_PLAY_SATE, true)\n  },\n  deleteSong ({\n    commit,\n    state\n  }, song) {\n    let audioList = state.audioList.slice()\n    let playList = state.playList.slice()\n    let currentIndex = state.audioIngIndex\n    // 删除的歌曲是当前播放歌曲之前\n    let pIndex = findIndex(audioList, song)\n    audioList.splice(pIndex, 1)\n    // 删除的歌曲是当前歌曲之后\n    let sIndex = findIndex(playList, song)\n    playList.splice(sIndex, 1)\n\n    if (currentIndex > pIndex || currentIndex === audioList.length) {\n      currentIndex--\n    }\n\n    commit(SET_AUDIO_LIST, audioList)\n    commit(SET_PLAY_LIST, playList)\n    commit(SET_AUDIO_INDEX, currentIndex)\n\n    if (!audioList.length) {\n      commit(SET_PLAY_SATE, false)\n    }\n  }\n}\n"
  },
  {
    "path": "musicPlayer/src/store/getters.js",
    "content": "/*\n * @Author: 李浩栋\n * @Begin: 2019-08-24 11:44:49\n * @Update: 2019-09-15 12:29:49\n * @Update log: 更新日志\n */\nconst getters = {\n  LOGIN_PAGE: state => state.loginPage,\n  ICON_SUN: state => state.icontaiyang,\n  ICON_NIGHT: state => state.iconyueliang1,\n  MODE_TEXT: state => state.modeText,\n  LOGIN_STATE: state => state.loginState,\n  LEVEL: state => state.level,\n  ACCOUNT_UID: state => state.accountUid,\n  LOAD: state => state.load,\n  LINK_PAGE: state => state.linkPage,\n  PLAY_STATE: state => state.playState,\n  FULL_SCREEN: state => state.fullScreen,\n  AUDIO_LIST: state => state.audioList,\n  AUDIO_ING_INDEX: state => state.audioIngIndex,\n  PLAY_LIST: state => state.playList,\n  MODE: state => state.mode,\n  OFFSET_LYRIC: state => state.offsetLyric,\n  PLAYING_SHOW: state => state.playingShow,\n  AUDIO_ING_SONG: state => {\n    // 返回当前播放歌曲对象的信息\n    return state.playList[state.audioIngIndex] || {}\n  }\n}\n\nexport default getters\n"
  },
  {
    "path": "musicPlayer/src/store/index.js",
    "content": "/*\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-09-12 14:23:38\n * @Update log: 更新日志\n */\nimport Vue from 'vue'\nimport Vuex from 'vuex'\nimport state from './state'\nimport mutations from './mutations'\nimport getters from './getters'\nimport actions from './actions'\n\nVue.use(Vuex)\n\nconst store = new Vuex.Store({\n  state,\n  mutations,\n  getters,\n  actions\n})\n\nexport default store\n"
  },
  {
    "path": "musicPlayer/src/store/mutation-types.js",
    "content": "/*\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-08-11 18:00:46\n * @Update log: 更新日志\n */\nexport const SHOW_LOGIN = 'SHOW_LOGIN' // 显示侧边栏\nexport const HIDE_LOGIN = 'HIDE_LOGIN' // 隐藏侧边栏\nexport const TOGGLE_MODE = 'TOGGLE_MODE' // 日夜模式切换\nexport const TOGGLE_MODE_TEXT = 'TOGGLE_MODE_TEXT' // 日夜文字切换\nexport const TO_SUN = 'TO_SUN' // 由夜转换到日\nexport const TO_YUE = 'TO_YUE' // 由日转换到夜\nexport const LOGIN_STATE = 'LOGIN_STATE' // 登陆状态\nexport const SET_LEVEL = 'SET_LEVEL' // 设置用户等级\nexport const ACCOUNT_UID = 'ACCOUNT_UID' // 存取用户id\nexport const SET_LOAD = 'SET_LOAD' // 设置当前已经返回数据，显示界面\nexport const RETURN_LOAD = 'RETURN_LOAD' // 将load返回默认的true\nexport const SET_LINK_PAGE = 'SET_LINK_PAGE' // 将load返回默认的true\nexport const SET_PLAY_SATE = 'SET_PLAY_SATE' // 设置当前的播放状态\nexport const SET_FULL_SCREEN = 'SET_FULL_SCREEN' // 设置当前的播放器的状态，是大还是小\nexport const SET_AUDIO_LIST = 'SET_AUDIO_LIST' // 设置当前的播放列表的展示\nexport const SET_PLAY_LIST = 'SET_PLAY_LIST' // 设置当前的播放列表\nexport const SET_AUDIO_INDEX = 'SET_AUDIO_INDEX' // 设置当前的播放歌曲是第几个，索引值\nexport const SET_AUDIO_MODE = 'SET_AUDIO_MODE' // 设置当前的播放模式\nexport const SET_PLAYING_SHOW = 'SET_PLAYING_SHOW' // 设置当前是否显示转盘播放页面\n"
  },
  {
    "path": "musicPlayer/src/store/mutations.js",
    "content": "/*\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-09-12 13:48:12\n * @Update log: 更新日志\n */\nimport {\n  SHOW_LOGIN,\n  HIDE_LOGIN,\n  TOGGLE_MODE,\n  TOGGLE_MODE_TEXT,\n  TO_SUN,\n  TO_YUE,\n  LOGIN_STATE,\n  ACCOUNT_UID,\n  SET_LOAD,\n  RETURN_LOAD,\n  SET_LINK_PAGE,\n  SET_PLAY_SATE,\n  SET_FULL_SCREEN,\n  SET_AUDIO_LIST,\n  SET_AUDIO_INDEX,\n  SET_PLAY_LIST,\n  SET_AUDIO_MODE,\n  SET_PLAYING_SHOW,\n  SET_LEVEL\n} from './mutation-types'\n\n// 实现侧边栏显示时底部不跟随滚动\nimport ModalHelper from 'utils/modalScroll'\n\nexport default {\n  // 显示左侧侧边栏页面\n  [SHOW_LOGIN] (state) {\n    state.loginPage = true\n    ModalHelper.afterOpen()\n  },\n  // 隐藏左侧侧边栏页面\n  [HIDE_LOGIN] (state) {\n    state.loginPage = false\n    ModalHelper.beforeClose()\n  },\n  // 从日间模式切换到夜间模式\n  [TO_YUE] (state) {\n    console.log('切换到夜间')\n    state.iconyueliang1 = false\n    state.icontaiyang = true\n    this._mutations.TOGGLE_MODE_TEXT[0](state)\n  },\n  // 从夜间模式切换到日间模式\n  [TO_SUN] (state) {\n    console.log('切换到日间')\n    state.iconyueliang1 = true\n    state.icontaiyang = false\n    this._mutations.TOGGLE_MODE_TEXT[0](state)\n  },\n  // 切换夜间 日间模式\n  [TOGGLE_MODE] (state) {\n    if (state.iconyueliang1) {\n      this._mutations.TO_YUE[0](state)\n    } else if (state.icontaiyang) {\n      this._mutations.TO_SUN[0](state)\n    }\n  },\n  // 切换夜间 日间模式文本\n  [TOGGLE_MODE_TEXT] (state) {\n    if (state.icontaiyang) {\n      state.modeText = '日'\n    } else {\n      state.modeText = '夜'\n    }\n  },\n  // 设置用户登陆状态\n  [LOGIN_STATE] (state, num) {\n    state.loginState = num\n  },\n  [SET_LEVEL] (state, num) {\n    state.level = num\n  },\n  // 存取用户 uid\n  [ACCOUNT_UID] (state, id) {\n    state.accountUid = id\n  },\n  // 设置搜索展示页面的loading图标\n  [SET_LOAD] (state) {\n    state.load = false\n  },\n  [RETURN_LOAD] (state) {\n    state.load = true\n  },\n  /**\n   * 设置搜索展示页标签导航条\n   */\n  [SET_LINK_PAGE] (state, page) {\n    state.linkPage = page\n  },\n  /**\n   * 设置播放状态\n   * @param {*} state state 数据\n   * @param {*} flag 播放状态\n   */\n  [SET_PLAY_SATE] (state, flag) {\n    state.playState = flag\n  },\n  /**\n   * 设置播放器是大还是小\n   */\n  [SET_FULL_SCREEN] (state, flag) {\n    if (flag) {\n      ModalHelper.afterOpen()\n    } else {\n      ModalHelper.beforeClose()\n    }\n    state.fullScreen = flag\n  },\n  /**\n   * 设置播放列表信息\n   */\n  [SET_AUDIO_LIST] (state, list) {\n    state.audioList = list\n  },\n  /**\n   * 设置索引\n   */\n  [SET_AUDIO_INDEX] (state, index) {\n    state.audioIngIndex = index\n  },\n  /**\n   * 设置当前播放列表\n   */\n  [SET_PLAY_LIST] (state, list) {\n    state.playList = list\n  },\n  /**\n   * 设置当前播放模式\n   * @param {*} state state数据\n   * @param {*} mode 模式索引\n   */\n  [SET_AUDIO_MODE] (state, mode) {\n    state.mode = mode\n  },\n  /**\n   * 设置当前是否显示转盘播放页面\n   */\n  [SET_PLAYING_SHOW] (state, boolean) {\n    state.playingShow = boolean\n  }\n}\n"
  },
  {
    "path": "musicPlayer/src/store/state.js",
    "content": "/*\n * @Author: 李浩栋\n * @Begin: 2019-07-30 16:42:30\n * @Update: 2019-10-09 12:15:26\n * @Update log: 更新日志\n */\nexport default {\n  loginPage: false, // 侧边栏显示与否\n  icontaiyang: false, // 日间模式\n  iconyueliang1: true, // 夜间模式\n  modeText: '夜', // 日夜模式文字信息\n  loginState: 0, // 登陆状态，初始值为 0 未登录，登陆成功设置为 1\n  accountUid: 0, // 存取用户 uid\n  load: true, // 定义搜索展示界面 loading 图标的展示与否\n  linkPage: 'composite', // 定义搜索展示页的标签导航条应该根据路由信息进行滚动\n  playState: false, // 是否正在播放，\n  fullScreen: false, // 是否是全屏展示播放页\n  audioList: [], // 用来展示播放列表项\n  playList: [], // 用来存储各种播放模式的列表\n  mode: 0, // 用来记录当前播放模式 0：列表循环，1：单曲循环 2：随机播放\n  audioIngIndex: -1, // 正在播放的这一首歌曲索引\n  playingShow: true, // 是否显示转盘播放页面\n  offsetLyric: 0, // 设置歌词偏移\n  level: 0 // 用户等级\n}\n"
  },
  {
    "path": "musicPlayer/static/.gitkeep",
    "content": ""
  }
]