├── build ├── build.js ├── check-versions.js ├── favicon.ico ├── logo.png ├── utils.js ├── vue-loader.conf.js ├── webpack.base.conf.js ├── webpack.dev.conf.js └── webpack.prod.conf.js ├── config ├── dev.env.js ├── index.js ├── prod.env.js └── test.env.js ├── dist ├── index.html └── static │ ├── css │ ├── app.63b7d8b023a317c6a812570f8fa81170.css │ ├── app.63b7d8b023a317c6a812570f8fa81170.css.map │ ├── app.cdff0faf21957824307888b782827ac8.css │ └── app.cdff0faf21957824307888b782827ac8.css.map │ ├── fonts │ ├── element-icons.535877f.woff │ └── element-icons.732389d.ttf │ ├── img │ ├── art.d8b5770.png │ ├── comment.0149618.png │ ├── logo.068006a.png │ ├── logo2.a44057f.png │ ├── user.0e32cd9.png │ └── user.e7885c0.png │ └── js │ ├── app.8547e0322d263caa4dbd.js │ ├── app.8547e0322d263caa4dbd.js.map │ ├── app.cd1114355fa8291ee8f7.js │ ├── app.cd1114355fa8291ee8f7.js.map │ ├── manifest.3ad1d5771e9b13dbdad2.js │ ├── manifest.3ad1d5771e9b13dbdad2.js.map │ ├── vendor.a4b363d31de06a4dfbfc.js │ ├── vendor.a4b363d31de06a4dfbfc.js.map │ ├── vendor.d598e1fd4ea745d7db4d.js │ └── vendor.d598e1fd4ea745d7db4d.js.map ├── favicon.ico ├── index.html ├── package-lock.json ├── package.json ├── readme.md └── src ├── App.vue ├── api ├── ajax.js ├── fetch.js └── index.js ├── assets ├── css │ └── reset.css └── img │ ├── favicon.ico │ ├── logo.png │ ├── logo2.png │ ├── user.png │ └── user3.png ├── components ├── Breadcrumb │ └── Breadcrumb.vue ├── Header │ └── Header.vue └── LeftMenu │ └── LeftMenu.vue ├── config └── mUtils.js ├── main.js ├── mock ├── data.json └── mockServer.js ├── pages ├── Article │ ├── Article.vue │ └── ArticleDetail │ │ └── ArticleDetail.vue ├── Comment │ └── Comment.vue ├── HomePage │ ├── HomePage.vue │ └── img │ │ ├── art.png │ │ ├── comment.png │ │ ├── plate.png │ │ └── user.png ├── Login │ └── Login.vue ├── Plate │ ├── AddPlate │ │ └── AddPlate.vue │ ├── EditPlate │ │ └── EditPlate.vue │ ├── Plate.vue │ └── PlateDetail │ │ └── PlateDetail.vue ├── System │ └── System.vue └── User │ ├── AddUser │ └── AddUser.vue │ ├── EditUser │ └── EditUser.vue │ ├── User.vue │ └── UserDetail │ └── UserDetail.vue ├── router └── index.js └── store └── actions.js /build/build.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | require('./check-versions')() 3 | 4 | process.env.NODE_ENV = 'production' 5 | 6 | const ora = require('ora') 7 | const rm = require('rimraf') 8 | const path = require('path') 9 | const chalk = require('chalk') 10 | const webpack = require('webpack') 11 | const config = require('../config') 12 | const webpackConfig = require('./webpack.prod.conf') 13 | 14 | const spinner = ora('building for production...') 15 | spinner.start() 16 | 17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 18 | if (err) throw err 19 | webpack(webpackConfig, (err, stats) => { 20 | spinner.stop() 21 | if (err) throw err 22 | process.stdout.write(stats.toString({ 23 | colors: true, 24 | modules: false, 25 | children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. 26 | chunks: false, 27 | chunkModules: false 28 | }) + '\n\n') 29 | 30 | if (stats.hasErrors()) { 31 | console.log(chalk.red(' Build failed with errors.\n')) 32 | process.exit(1) 33 | } 34 | 35 | console.log(chalk.cyan(' Build complete.\n')) 36 | console.log(chalk.yellow( 37 | ' Tip: built files are meant to be served over an HTTP server.\n' + 38 | ' Opening index.html over file:// won\'t work.\n' 39 | )) 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /build/check-versions.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const chalk = require('chalk') 3 | const semver = require('semver') 4 | const packageConfig = require('../package.json') 5 | const shell = require('shelljs') 6 | 7 | function exec (cmd) { 8 | return require('child_process').execSync(cmd).toString().trim() 9 | } 10 | 11 | const versionRequirements = [ 12 | { 13 | name: 'node', 14 | currentVersion: semver.clean(process.version), 15 | versionRequirement: packageConfig.engines.node 16 | } 17 | ] 18 | 19 | if (shell.which('npm')) { 20 | versionRequirements.push({ 21 | name: 'npm', 22 | currentVersion: exec('npm --version'), 23 | versionRequirement: packageConfig.engines.npm 24 | }) 25 | } 26 | 27 | module.exports = function () { 28 | const warnings = [] 29 | 30 | for (let i = 0; i < versionRequirements.length; i++) { 31 | const mod = versionRequirements[i] 32 | 33 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 34 | warnings.push(mod.name + ': ' + 35 | chalk.red(mod.currentVersion) + ' should be ' + 36 | chalk.green(mod.versionRequirement) 37 | ) 38 | } 39 | } 40 | 41 | if (warnings.length) { 42 | console.log('') 43 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 44 | console.log() 45 | 46 | for (let i = 0; i < warnings.length; i++) { 47 | const warning = warnings[i] 48 | console.log(' ' + warning) 49 | } 50 | 51 | console.log() 52 | process.exit(1) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /build/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TanJ2014/vue-element-blog-admin/1ab53bb59cea70215d941881c8c8b12c7a79cace/build/favicon.ico -------------------------------------------------------------------------------- /build/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TanJ2014/vue-element-blog-admin/1ab53bb59cea70215d941881c8c8b12c7a79cace/build/logo.png -------------------------------------------------------------------------------- /build/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const config = require('../config') 4 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 5 | const packageConfig = require('../package.json') 6 | 7 | exports.assetsPath = function (_path) { 8 | const assetsSubDirectory = process.env.NODE_ENV === 'production' 9 | ? config.build.assetsSubDirectory 10 | : config.dev.assetsSubDirectory 11 | 12 | return path.posix.join(assetsSubDirectory, _path) 13 | } 14 | 15 | exports.cssLoaders = function (options) { 16 | options = options || {} 17 | 18 | const cssLoader = { 19 | loader: 'css-loader', 20 | options: { 21 | sourceMap: options.sourceMap 22 | } 23 | } 24 | 25 | const postcssLoader = { 26 | loader: 'postcss-loader', 27 | options: { 28 | sourceMap: options.sourceMap 29 | } 30 | } 31 | 32 | // generate loader string to be used with extract text plugin 33 | function generateLoaders (loader, loaderOptions) { 34 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] 35 | 36 | if (loader) { 37 | loaders.push({ 38 | loader: loader + '-loader', 39 | options: Object.assign({}, loaderOptions, { 40 | sourceMap: options.sourceMap 41 | }) 42 | }) 43 | } 44 | 45 | // Extract CSS when that option is specified 46 | // (which is the case during production build) 47 | if (options.extract) { 48 | return ExtractTextPlugin.extract({ 49 | use: loaders, 50 | fallback: 'vue-style-loader', 51 | publicPath: '../../' 52 | }) 53 | } else { 54 | return ['vue-style-loader'].concat(loaders) 55 | } 56 | } 57 | 58 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 59 | return { 60 | css: generateLoaders(), 61 | postcss: generateLoaders(), 62 | less: generateLoaders('less'), 63 | sass: generateLoaders('sass', { indentedSyntax: true }), 64 | scss: generateLoaders('sass'), 65 | stylus: generateLoaders('stylus'), 66 | styl: generateLoaders('stylus') 67 | } 68 | } 69 | 70 | // Generate loaders for standalone style files (outside of .vue) 71 | exports.styleLoaders = function (options) { 72 | const output = [] 73 | const loaders = exports.cssLoaders(options) 74 | 75 | for (const extension in loaders) { 76 | const loader = loaders[extension] 77 | output.push({ 78 | test: new RegExp('\\.' + extension + '$'), 79 | use: loader 80 | }) 81 | } 82 | 83 | return output 84 | } 85 | 86 | exports.createNotifierCallback = () => { 87 | const notifier = require('node-notifier') 88 | 89 | return (severity, errors) => { 90 | if (severity !== 'error') return 91 | 92 | const error = errors[0] 93 | const filename = error.file && error.file.split('!').pop() 94 | 95 | notifier.notify({ 96 | title: packageConfig.name, 97 | message: severity + ': ' + error.name, 98 | subtitle: filename || '', 99 | icon: path.join(__dirname, 'logo.png') 100 | }) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const config = require('../config') 4 | const isProduction = process.env.NODE_ENV === 'production' 5 | const sourceMapEnabled = isProduction 6 | ? config.build.productionSourceMap 7 | : config.dev.cssSourceMap 8 | 9 | module.exports = { 10 | loaders: utils.cssLoaders({ 11 | sourceMap: sourceMapEnabled, 12 | extract: isProduction 13 | }), 14 | cssSourceMap: sourceMapEnabled, 15 | cacheBusting: config.dev.cacheBusting, 16 | transformToRequire: { 17 | video: ['src', 'poster'], 18 | source: 'src', 19 | img: 'src', 20 | image: 'xlink:href' 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const config = require('../config') 5 | const vueLoaderConfig = require('./vue-loader.conf') 6 | var babelpolyfill = require("babel-polyfill"); 7 | 8 | function resolve (dir) { 9 | return path.join(__dirname, '..', dir) 10 | } 11 | 12 | 13 | 14 | module.exports = { 15 | context: path.resolve(__dirname, '../'), 16 | entry: { 17 | app: './src/main.js' 18 | }, 19 | output: { 20 | path: config.build.assetsRoot, 21 | filename: '[name].js', 22 | publicPath: process.env.NODE_ENV === 'production' 23 | ? config.build.assetsPublicPath 24 | : config.dev.assetsPublicPath 25 | }, 26 | resolve: { 27 | extensions: ['.js', '.vue', '.json'], 28 | alias: { 29 | 'vue$': 'vue/dist/vue.esm.js', 30 | '@': resolve('src'), 31 | } 32 | }, 33 | module: { 34 | rules: [ 35 | { 36 | test: /\.vue$/, 37 | loader: 'vue-loader', 38 | options: vueLoaderConfig 39 | }, 40 | { 41 | test: /\.js$/, 42 | loader: 'babel-loader', 43 | include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] 44 | }, 45 | { 46 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 47 | loader: 'url-loader', 48 | options: { 49 | limit: 10000, 50 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 51 | } 52 | }, 53 | { 54 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 55 | loader: 'url-loader', 56 | options: { 57 | limit: 10000, 58 | name: utils.assetsPath('media/[name].[hash:7].[ext]') 59 | } 60 | }, 61 | { 62 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 63 | loader: 'url-loader', 64 | options: { 65 | limit: 10000, 66 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 67 | } 68 | } 69 | ] 70 | }, 71 | node: { 72 | // prevent webpack from injecting useless setImmediate polyfill because Vue 73 | // source contains it (although only uses it if it's native). 74 | setImmediate: false, 75 | // prevent webpack from injecting mocks to Node native modules 76 | // that does not make sense for the client 77 | dgram: 'empty', 78 | fs: 'empty', 79 | net: 'empty', 80 | tls: 'empty', 81 | child_process: 'empty' 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const webpack = require('webpack') 4 | const config = require('../config') 5 | const merge = require('webpack-merge') 6 | const path = require('path') 7 | const baseWebpackConfig = require('./webpack.base.conf') 8 | const CopyWebpackPlugin = require('copy-webpack-plugin') 9 | const HtmlWebpackPlugin = require('html-webpack-plugin') 10 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') 11 | const portfinder = require('portfinder') 12 | var babelpolyfill = require("babel-polyfill"); 13 | 14 | const HOST = process.env.HOST 15 | const PORT = process.env.PORT && Number(process.env.PORT) 16 | 17 | const devWebpackConfig = merge(baseWebpackConfig, { 18 | module: { 19 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) 20 | }, 21 | // cheap-module-eval-source-map is faster for development 22 | devtool: config.dev.devtool, 23 | 24 | // these devServer options should be customized in /config/index.js 25 | devServer: { 26 | clientLogLevel: 'warning', 27 | historyApiFallback: { 28 | rewrites: [ 29 | { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, 30 | ], 31 | }, 32 | hot: true, 33 | contentBase: false, // since we use CopyWebpackPlugin. 34 | compress: true, 35 | host: HOST || config.dev.host, 36 | port: PORT || config.dev.port, 37 | open: config.dev.autoOpenBrowser, 38 | overlay: config.dev.errorOverlay 39 | ? { warnings: false, errors: true } 40 | : false, 41 | publicPath: config.dev.assetsPublicPath, 42 | proxy: config.dev.proxyTable, 43 | quiet: true, // necessary for FriendlyErrorsPlugin 44 | watchOptions: { 45 | poll: config.dev.poll, 46 | } 47 | }, 48 | plugins: [ 49 | new webpack.DefinePlugin({ 50 | 'process.env': require('../config/dev.env') 51 | }), 52 | new webpack.HotModuleReplacementPlugin(), 53 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. 54 | new webpack.NoEmitOnErrorsPlugin(), 55 | // https://github.com/ampedandwired/html-webpack-plugin 56 | new HtmlWebpackPlugin({ 57 | filename: 'index.html', 58 | template: 'index.html', 59 | inject: true, 60 | favicon: './favicon.ico' 61 | }), 62 | // copy custom static assets 63 | new CopyWebpackPlugin([ 64 | { 65 | from: path.resolve(__dirname, '../static'), 66 | to: config.dev.assetsSubDirectory, 67 | ignore: ['.*'] 68 | } 69 | ]) 70 | ] 71 | }) 72 | 73 | module.exports = new Promise((resolve, reject) => { 74 | portfinder.basePort = process.env.PORT || config.dev.port 75 | portfinder.getPort((err, port) => { 76 | if (err) { 77 | reject(err) 78 | } else { 79 | // publish the new Port, necessary for e2e tests 80 | process.env.PORT = port 81 | // add port to devServer config 82 | devWebpackConfig.devServer.port = port 83 | 84 | // Add FriendlyErrorsPlugin 85 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ 86 | compilationSuccessInfo: { 87 | messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], 88 | }, 89 | onErrors: config.dev.notifyOnErrors 90 | ? utils.createNotifierCallback() 91 | : undefined 92 | })) 93 | 94 | resolve(devWebpackConfig) 95 | } 96 | }) 97 | }) 98 | -------------------------------------------------------------------------------- /build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const webpack = require('webpack') 5 | const config = require('../config') 6 | const merge = require('webpack-merge') 7 | const baseWebpackConfig = require('./webpack.base.conf') 8 | const CopyWebpackPlugin = require('copy-webpack-plugin') 9 | const HtmlWebpackPlugin = require('html-webpack-plugin') 10 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 11 | const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') 12 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin') 13 | var babelpolyfill = require("babel-polyfill"); 14 | 15 | const env = process.env.NODE_ENV === 'testing' 16 | ? require('../config/test.env') 17 | : require('../config/prod.env') 18 | 19 | const webpackConfig = merge(baseWebpackConfig, { 20 | module: { 21 | rules: utils.styleLoaders({ 22 | sourceMap: config.build.productionSourceMap, 23 | extract: true, 24 | usePostCSS: true 25 | }) 26 | }, 27 | devtool: config.build.productionSourceMap ? config.build.devtool : false, 28 | output: { 29 | path: config.build.assetsRoot, 30 | filename: utils.assetsPath('js/[name].[chunkhash].js'), 31 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 32 | }, 33 | plugins: [ 34 | // http://vuejs.github.io/vue-loader/en/workflow/production.html 35 | new webpack.DefinePlugin({ 36 | 'process.env': env 37 | }), 38 | new UglifyJsPlugin({ 39 | uglifyOptions: { 40 | compress: { 41 | warnings: false 42 | } 43 | }, 44 | sourceMap: config.build.productionSourceMap, 45 | parallel: true 46 | }), 47 | // extract css into its own file 48 | new ExtractTextPlugin({ 49 | filename: utils.assetsPath('css/[name].[contenthash].css'), 50 | // Setting the following option to `false` will not extract CSS from codesplit chunks. 51 | // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. 52 | // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, 53 | // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 54 | allChunks: true, 55 | }), 56 | // Compress extracted CSS. We are using this plugin so that possible 57 | // duplicated CSS from different components can be deduped. 58 | new OptimizeCSSPlugin({ 59 | cssProcessorOptions: config.build.productionSourceMap 60 | ? { safe: true, map: { inline: false } } 61 | : { safe: true } 62 | }), 63 | // generate dist index.html with correct asset hash for caching. 64 | // you can customize output by editing /index.html 65 | // see https://github.com/ampedandwired/html-webpack-plugin 66 | new HtmlWebpackPlugin({ 67 | filename: process.env.NODE_ENV === 'testing' 68 | ? 'index.html' 69 | : config.build.index, 70 | template: 'index.html', 71 | inject: true, 72 | minify: { 73 | removeComments: true, 74 | collapseWhitespace: true, 75 | removeAttributeQuotes: true 76 | // more options: 77 | // https://github.com/kangax/html-minifier#options-quick-reference 78 | }, 79 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin 80 | chunksSortMode: 'dependency' 81 | }), 82 | // keep module.id stable when vendor modules does not change 83 | new webpack.HashedModuleIdsPlugin(), 84 | // enable scope hoisting 85 | new webpack.optimize.ModuleConcatenationPlugin(), 86 | // split vendor js into its own file 87 | new webpack.optimize.CommonsChunkPlugin({ 88 | name: 'vendor', 89 | minChunks (module) { 90 | // any required modules inside node_modules are extracted to vendor 91 | return ( 92 | module.resource && 93 | /\.js$/.test(module.resource) && 94 | module.resource.indexOf( 95 | path.join(__dirname, '../node_modules') 96 | ) === 0 97 | ) 98 | } 99 | }), 100 | // extract webpack runtime and module manifest to its own file in order to 101 | // prevent vendor hash from being updated whenever app bundle is updated 102 | new webpack.optimize.CommonsChunkPlugin({ 103 | name: 'manifest', 104 | minChunks: Infinity 105 | }), 106 | // This instance extracts shared chunks from code splitted chunks and bundles them 107 | // in a separate chunk, similar to the vendor chunk 108 | // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk 109 | new webpack.optimize.CommonsChunkPlugin({ 110 | name: 'app', 111 | async: 'vendor-async', 112 | children: true, 113 | minChunks: 3 114 | }), 115 | 116 | // copy custom static assets 117 | new CopyWebpackPlugin([ 118 | { 119 | from: path.resolve(__dirname, '../static'), 120 | to: config.build.assetsSubDirectory, 121 | ignore: ['.*'] 122 | } 123 | ]) 124 | ] 125 | }) 126 | 127 | if (config.build.productionGzip) { 128 | const CompressionWebpackPlugin = require('compression-webpack-plugin') 129 | 130 | webpackConfig.plugins.push( 131 | new CompressionWebpackPlugin({ 132 | asset: '[path].gz[query]', 133 | algorithm: 'gzip', 134 | test: new RegExp( 135 | '\\.(' + 136 | config.build.productionGzipExtensions.join('|') + 137 | ')$' 138 | ), 139 | threshold: 10240, 140 | minRatio: 0.8 141 | }) 142 | ) 143 | } 144 | 145 | if (config.build.bundleAnalyzerReport) { 146 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 147 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 148 | } 149 | 150 | module.exports = webpackConfig 151 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"', 7 | API_HOST:'"http://127.0.0.1:8080"', 8 | API: '"/api"' 9 | }) 10 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // Template version: 1.3.1 3 | // see http://vuejs-templates.github.io/webpack for documentation. 4 | 5 | const path = require('path') 6 | 7 | module.exports = { 8 | dev: { 9 | // Paths 10 | assetsSubDirectory: 'static', 11 | assetsPublicPath: '/', 12 | proxyTable: { 13 | '/api': { // 匹配所有以 '/api' 开头的请求路径 14 | target: 'http://localhost:8080', // 代理目标的基础路径 15 | changeOrigin: true, // 支持跨域 16 | pathRewrite: {// 重写路径 : 去掉路径中开头的 '/api' 17 | '^/api': '' 18 | } 19 | } 20 | }, 21 | 22 | // Various Dev Server settings 23 | host: 'localhost', // can be overwritten by process.env.HOST 24 | port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined 25 | autoOpenBrowser: false, 26 | errorOverlay: true, 27 | notifyOnErrors: true, 28 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- 29 | 30 | 31 | /** 32 | * Source Maps 33 | */ 34 | 35 | // https://webpack.js.org/configuration/devtool/#development 36 | devtool: 'cheap-module-eval-source-map', 37 | 38 | // If you have problems debugging vue-files in devtools, 39 | // set this to false - it *may* help 40 | // https://vue-loader.vuejs.org/en/options.html#cachebusting 41 | cacheBusting: true, 42 | 43 | cssSourceMap: true 44 | }, 45 | 46 | build: { 47 | // Template for index.html 48 | index: path.resolve(__dirname, '../dist/index.html'), 49 | 50 | // Paths 51 | assetsRoot: path.resolve(__dirname, '../dist'), 52 | assetsSubDirectory: 'static', 53 | assetsPublicPath: './', 54 | 55 | /** 56 | * Source Maps 57 | */ 58 | 59 | productionSourceMap: true, 60 | // https://webpack.js.org/configuration/devtool/#production 61 | devtool: '#source-map', 62 | 63 | // Gzip off by default as many popular static hosts such as 64 | // Surge or Netlify already gzip all static assets for you. 65 | // Before setting to `true`, make sure to: 66 | // npm install --save-dev compression-webpack-plugin 67 | productionGzip: false, 68 | productionGzipExtensions: ['js', 'css'], 69 | 70 | // Run the build command with an extra argument to 71 | // View the bundle analyzer report after build finishes: 72 | // `npm run build --report` 73 | // Set to `true` or `false` to always turn it on or off 74 | bundleAnalyzerReport: process.env.npm_config_report 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"', 4 | API_HOST:'"http://127.0.0.1:8080"' 5 | } 6 | -------------------------------------------------------------------------------- /config/test.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const devEnv = require('./dev.env') 4 | 5 | module.exports = merge(devEnv, { 6 | NODE_ENV: '"testing"' 7 | }) 8 | -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | 博客管理系统
-------------------------------------------------------------------------------- /dist/static/fonts/element-icons.535877f.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TanJ2014/vue-element-blog-admin/1ab53bb59cea70215d941881c8c8b12c7a79cace/dist/static/fonts/element-icons.535877f.woff -------------------------------------------------------------------------------- /dist/static/fonts/element-icons.732389d.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TanJ2014/vue-element-blog-admin/1ab53bb59cea70215d941881c8c8b12c7a79cace/dist/static/fonts/element-icons.732389d.ttf -------------------------------------------------------------------------------- /dist/static/img/art.d8b5770.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TanJ2014/vue-element-blog-admin/1ab53bb59cea70215d941881c8c8b12c7a79cace/dist/static/img/art.d8b5770.png -------------------------------------------------------------------------------- /dist/static/img/comment.0149618.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TanJ2014/vue-element-blog-admin/1ab53bb59cea70215d941881c8c8b12c7a79cace/dist/static/img/comment.0149618.png -------------------------------------------------------------------------------- /dist/static/img/logo.068006a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TanJ2014/vue-element-blog-admin/1ab53bb59cea70215d941881c8c8b12c7a79cace/dist/static/img/logo.068006a.png -------------------------------------------------------------------------------- /dist/static/img/logo2.a44057f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TanJ2014/vue-element-blog-admin/1ab53bb59cea70215d941881c8c8b12c7a79cace/dist/static/img/logo2.a44057f.png -------------------------------------------------------------------------------- /dist/static/img/user.0e32cd9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TanJ2014/vue-element-blog-admin/1ab53bb59cea70215d941881c8c8b12c7a79cace/dist/static/img/user.0e32cd9.png -------------------------------------------------------------------------------- /dist/static/img/user.e7885c0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TanJ2014/vue-element-blog-admin/1ab53bb59cea70215d941881c8c8b12c7a79cace/dist/static/img/user.e7885c0.png -------------------------------------------------------------------------------- /dist/static/js/manifest.3ad1d5771e9b13dbdad2.js: -------------------------------------------------------------------------------- 1 | !function(r){var n=window.webpackJsonp;window.webpackJsonp=function(e,u,c){for(var f,i,p,a=0,l=[];a 2 | 3 | 4 | 5 | 6 | 博客管理系统 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "front", 3 | "version": "1.0.0", 4 | "description": "A Vue.js project", 5 | "author": "tanj", 6 | "private": true, 7 | "scripts": { 8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", 9 | "start": "npm run dev", 10 | "unit": "jest --config test/unit/jest.conf.js --coverage", 11 | "e2e": "node test/e2e/runner.js", 12 | "test": "npm run unit && npm run e2e", 13 | "build": "node build/build.js" 14 | }, 15 | "dependencies": { 16 | "axios": "^0.19.0", 17 | "echarts": "^4.2.1", 18 | "element-ui": "^2.10.1", 19 | "mockjs": "^1.1.0", 20 | "vue": "^2.5.2", 21 | "vue-axios": "^2.1.4", 22 | "vue-router": "^3.0.1", 23 | "vuex": "^3.1.1" 24 | }, 25 | "devDependencies": { 26 | "autoprefixer": "^7.1.2", 27 | "babel-core": "^6.22.1", 28 | "babel-helper-vue-jsx-merge-props": "^2.0.3", 29 | "babel-jest": "^21.0.2", 30 | "babel-loader": "^7.1.1", 31 | "babel-plugin-component": "^1.1.1", 32 | "babel-plugin-dynamic-import-node": "^1.2.0", 33 | "babel-plugin-syntax-jsx": "^6.18.0", 34 | "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0", 35 | "babel-plugin-transform-runtime": "^6.23.0", 36 | "babel-plugin-transform-vue-jsx": "^3.5.0", 37 | "babel-polyfill": "^6.26.0", 38 | "babel-preset-env": "^1.3.2", 39 | "babel-preset-stage-2": "^6.22.0", 40 | "babel-register": "^6.22.0", 41 | "chalk": "^2.0.1", 42 | "chromedriver": "^2.27.2", 43 | "copy-webpack-plugin": "^4.0.1", 44 | "cross-spawn": "^5.0.1", 45 | "css-loader": "^0.28.0", 46 | "extract-text-webpack-plugin": "^3.0.0", 47 | "file-loader": "^1.1.4", 48 | "friendly-errors-webpack-plugin": "^1.6.1", 49 | "html-webpack-plugin": "^2.30.1", 50 | "jest": "^22.0.4", 51 | "jest-serializer-vue": "^0.3.0", 52 | "nightwatch": "^0.9.12", 53 | "node-notifier": "^5.1.2", 54 | "optimize-css-assets-webpack-plugin": "^3.2.0", 55 | "ora": "^1.2.0", 56 | "portfinder": "^1.0.13", 57 | "postcss-import": "^11.0.0", 58 | "postcss-loader": "^2.0.8", 59 | "postcss-url": "^7.2.1", 60 | "qs": "^6.8.0", 61 | "rimraf": "^2.6.0", 62 | "selenium-server": "^3.0.1", 63 | "semver": "^5.3.0", 64 | "shelljs": "^0.7.6", 65 | "uglifyjs-webpack-plugin": "^1.1.1", 66 | "url-loader": "^0.5.8", 67 | "vue-jest": "^1.0.2", 68 | "vue-loader": "^13.3.0", 69 | "vue-style-loader": "^3.0.1", 70 | "vue-template-compiler": "^2.5.2", 71 | "webpack": "^3.6.0", 72 | "webpack-bundle-analyzer": "^2.9.0", 73 | "webpack-dev-server": "^2.9.1", 74 | "webpack-merge": "^4.1.0" 75 | }, 76 | "engines": { 77 | "node": ">= 6.0.0", 78 | "npm": ">= 3.0.0" 79 | }, 80 | "browserslist": [ 81 | "> 1%", 82 | "last 2 versions", 83 | "not ie <= 8" 84 | ] 85 | } 86 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # 基于vue-cli + element-ui + mock.js搭建的博客后台管理系统 2 | 3 | # 写在前面: 4 | 5 | 该系统原本是知识共享平台的后台管理系统,使用的是前后端分离的架构模式。后台基于Spring、SpringMVC、MyBatis当下主流框架编写,前端使用VUE.js框架,Element框架,页面简洁大方,知识共享平台的后台管理系统已申请软件著作权。这里我将该系统前端部分抽取出来作为博客后台管理系统分享,使用了Mock.js来模拟后台数据。仅供学习参考,切勿用于商业目的。 6 | 7 | # 主要的功能: 8 | 9 | 博客后台管理系统根据实际需求,设计并实现的功能如下: 10 | 11 | 1. 用户信息管理。记录用户在博客平台中注册过的用户信息,管理员可以对用户信息进行搜索、修改、删除、增加。其中,管理员通过系统可以指派某个用户作为某个版块的版主,协助管理员来管理该版块的文章与评论,减轻管理员的工作量。 12 | 13 | 2. 文章信息管理。记录了用户在博客平台中发表过的文章,管理员可以管理全部文章,版主可以管理自己管理的版块中的文章,两者可对文章进行查看、删除、搜索操作。值得注意的是不能进行编辑操作,编辑只能由该文章的作者在知识共享平台中进行,其他人不能修改文章内容。 14 | 15 | 3. 评论信息管理。记录了用户在博客平台中发表过的评论,管理员可以管理全部评论,版主可以管理对应版块中文章的评论,两者可对评论进行查看、删除、搜索操作。 16 | 17 | 4. 版块信息管理。记录了博客平台中的版块信息,管理员可以自行增加、删除、搜索、查看版块。同时,管理员可以为每个版块委派一个版主,协助管理员管理平台。 18 | 19 | # 项目启动 20 | 21 | 进入项目的根目录,输入以下命令,即可启动 22 | 23 | ``` 24 | cnpm install 25 | cnpm start 26 | ``` 27 | 28 | 或者: 29 | 30 | ``` 31 | npm install 32 | npm start 33 | ``` 34 | 35 | 启动成功后打开 http://localhost:8080 即可访问,随意输入用户名与密码即可登录 36 | 37 | 在线预览:https://tanj2014.github.io/vue-element-blog-admin/dist/ 38 | 39 | 更多详情查看:http://www.tanj.com.cn/resource/detail/5e79c2f3b59f63026ca95b4f 40 | 41 | # 相关API: 42 | 43 | # 1.用户登录 44 | 45 | 只要管理员和版主才能登录成功,并且需要用户名、密码正确,登录成功后前端在localStorage中存储了user_id 46 | 47 | ### 请求URL 48 | 49 | http://localhost:8080/users/login 50 | 51 | ### 示例 52 | 53 | ### 请求方式 54 | 55 | post 56 | 57 | ### 参数类型 58 | 59 | | 参数 | 是否必须 | 类型 | 说明 | 60 | | --------- | -------- | ------ | ------ | 61 | | nick_name | Y | string | 用户名 | 62 | | password | Y | string | m密码 | 63 | 64 | ### 返回示例 65 | 66 | ``` 67 | { 68 | "status": 1, //如果是普通用户则为0,登录失败为0 69 | "message": '登录成功', 70 | "user_id":12 //用户id //如果是普通用户,则为null 71 | } 72 | ``` 73 | 74 | # 2.根据登录用户的id获取用户信息 75 | 76 | ### 请求URL 77 | 78 | http://localhost:8080/users/loginuserinfo 79 | 80 | ### 请求方式 81 | 82 | get 83 | 84 | ### 参数类型 85 | 86 | | 参数 | 是否必须 | 类型 | 说明 | 87 | | ------ | -------- | ---- | ---- | 88 | | userid | Y | int | | 89 | 90 | ### 返回示例 91 | 92 | ``` 93 | { 94 | "nick_name":"它不仅", 95 | "role_name":"版主", 96 | "plate_id":1,//如果是管理员,则为0或空 97 | "plate_name":"学习版块",//如果是管理员,则为空 98 | } 99 | ``` 100 | 101 | # 3.用户退出 102 | 103 | ### 请求URL 104 | 105 | http://localhost:8080/users/logout 106 | 107 | ### 请求方式 108 | 109 | get 110 | 111 | ### 参数类型 112 | 113 | 暂无 114 | 115 | ### 返回示例 116 | 117 | ``` 118 | { 119 | status: 1, 120 | message: '退出成功' 121 | } 122 | ``` 123 | 124 | # 首页中的一些内容 125 | 126 | # 4.返回文章、评论、用户、版块的个数 127 | 128 | ### 请求URL 129 | 130 | http://localhost:8080/homepage/number 131 | 132 | ### 请求方式 133 | 134 | get 135 | 136 | ### 参数类型 137 | 138 | 无 139 | 140 | ### 返回示例 141 | 142 | ``` 143 | { 144 | userNum:100, 145 | plateNum:10, 146 | articleNum:2308, 147 | commentNum:3223 148 | } 149 | ``` 150 | 151 | # 5.返回文章、用户数对比折线图 152 | 153 | 最近五个月的文章、用户新增情况,只计算当月的新增情况 154 | 155 | ### 请求URL 156 | 157 | http://localhost:8080/homepage/userArticleChart 158 | 159 | ### 请求方式 160 | 161 | get 162 | 163 | ### 参数列表 164 | 165 | 无 166 | 167 | ### 返回示例 168 | 169 | ``` 170 | { 171 | "xAxis":['2月','3月','4月','5月','6月'],//x轴横坐标,显示最近五个月 172 | "yAxisUser":[1320, 1330, 1000, 2000, 932], 173 | "yAxisArticle":[2320, 1430, 1100, 2090, 1932] 174 | } 175 | ``` 176 | 177 | # 6.返回版块内的文章数量饼状图 178 | 179 | 展示前五个文章数最多的版块 180 | 181 | ## 请求URL 182 | 183 | http://localhost:8080/homepage/plateArticleChart 184 | 185 | ## 请求方式 186 | 187 | get 188 | 189 | ## 参数列表 190 | 191 | 无 192 | 193 | ## 返回示例 194 | 195 | ``` 196 | [ 197 | {value:135, name:'学习'}, 198 | {value:310, name:'生活'}, 199 | {value:234, name:'跳蚤市场'}, 200 | {value:135, name:'Vue'}, 201 | {value:548, name:'SSM'} 202 | ] 203 | ``` 204 | 205 | # 7.返回最新的五个用户、版块、文章 206 | 207 | ### 请求URL 208 | 209 | http://localhost:8080/homepage/newFive 210 | 211 | ### 请求方式 212 | 213 | get 214 | 215 | ### 参数类型 216 | 217 | 无 218 | 219 | ### 返回示例 220 | 221 | ``` 222 | { 223 | "newUser":[ //五个,只需要五个 224 | { 225 | "id":1, //用户id 226 | "nick_name":"tanj", 227 | "update_time":"2019-05-29 10:17:55" 228 | }, 229 | { 230 | "id":2, //用户id 231 | "nick_name":"zhang", 232 | "update_time":"2019-05-29 10:17:55" 233 | }, 234 | ...... 235 | ], 236 | "newPlate":[ 237 | { 238 | "id":1,//版块id 239 | "plate_name":"学习", 240 | "description":"这是学习的地方", 241 | "update_time":"2019-05-29 10:17:55" 242 | }, 243 | ...... 244 | ], 245 | "newArticle":[ 246 | { 247 | "id":1,//文章的id 248 | "title":"文章的标题", 249 | "nick_name":"tanjiajia",//文章的作者 250 | "update_time":"2019-05-29 10:17:55" 251 | }, 252 | ...... 253 | ] 254 | } 255 | ``` 256 | 257 | # 管理员登录 258 | 259 | # 版块 260 | 261 | # 8.搜索版块 262 | 263 | ### 请求URL 264 | 265 | http://localhost:8080/plates/searchplate 266 | 267 | ### 示例 268 | 269 | http://localhost:8080/plates/searchplate?startTime=20190909&endTime=20190910&plateName=学习 270 | 271 | /plates/searchplate?startTime=2019-08-07&endTime=2019-08-15&plateName=12&pageNum=1 272 | 273 | ### 请求方式 274 | 275 | get 276 | 277 | ### 参数类型 query 278 | 279 | | 参数 | 是否必须 | 类型 | 说明 | 280 | | --------- | -------- | ------ | -------------------------------------- | 281 | | startTime | N | string | 前端控制开始时间和结束时间必须同时输入 | 282 | | endTime | N | string | | 283 | | plateName | N | string | | 284 | | pageNum | N | int | | 285 | 286 | ### 返回示例 287 | 288 | ``` 289 | [ 290 | { 291 | "plate_name": "学习", 292 | "id": 1, 293 | "description|1-10":"这里是讨论学习的地方", 294 | "moderator_name|1-10":"213", 295 | "update_time":"1029-12-21", 296 | "postNum|1-1000":20 297 | } 298 | ] 299 | ``` 300 | 301 | # 9.添加版块 302 | 303 | ### 请求URL 304 | 305 | http://localhost:8080/plates/addplate 306 | 307 | ### 请求方式 308 | 309 | post 310 | 311 | ### 参数类型 312 | 313 | | 参数 | 是否必须 | 类型 | 说明 | 314 | | ------------ | -------- | ------ | ------------------------------- | 315 | | platedetail | Y | {} | 包含下面三个属性 | 316 | | { desciption | Y | string | 版块描述 | 317 | | moderator | N | int | 版主id,默认为0 表示该版块无版主 | 318 | | plate_name } | Y | string | 版块名称 | 319 | 320 | ### 返回示例 321 | 322 | ``` 323 | { 324 | status: 1, 325 | success: '添加版块信息成功', 326 | } 327 | ``` 328 | 329 | # 10.根据版块ID获取版块详情 330 | 331 | ### 请求URL 332 | 333 | http://localhost:8080/plates/platedetail/:plateid 334 | 335 | ### 示例 336 | 337 | ### 请求方式 338 | 339 | get 340 | 341 | ### 参数列表 342 | 343 | | 参数 | 是否必须 | 类型 | 说明 | 344 | | ------- | -------- | ---- | ------ | 345 | | plateid | Y | int | 版块id | 346 | 347 | ### 返回示例 348 | 349 | ``` 350 | { 351 | "plate_name": "学习", 352 | "id": 1, 353 | "description|1-10":"这里是讨论学习的地方", 354 | "moderator_name|1-10":"213", 355 | "update_time":"1029-12-21", 356 | "postNum|1-1000":20 357 | } 358 | ``` 359 | 360 | # 11.根据版块id修改版块内容 361 | 362 | ### 请求URL 363 | 364 | http://localhost:8080/plates/editplate/:plateid 365 | 366 | ### 示例 367 | 368 | ### 请求方式 369 | 370 | post 371 | 372 | ### 参数列表 373 | 374 | | 参数 | 是否必须 | 类型 | 说明 | 375 | | -------------------------------- | -------- | ------ | -------------------- | 376 | | plateid | Y | int | 版块id | 377 | | platedetail | Y | {} | | 378 | | { desciption | Y | string | 版块描述 | 379 | | moderator 改成**moderator_name** | N | int | 版主的id 默认为0 | 380 | | plate_name } | Y | string | 版块名称,不允许重复 | 381 | 382 | ### 返回示例 383 | 384 | ``` 385 | { 386 | status: 1, 387 | success: '修改版块信息成功', 388 | } 389 | ``` 390 | 391 | # 12.删除所选择的版块 392 | 393 | ### 请求URL 394 | 395 | http://localhost:8080/plates/deleteplate/:plateid 396 | 397 | ### 请求方式 398 | 399 | get 400 | 401 | ### 参数列表 402 | 403 | | 参数 | 是否必须 | 类型 | 说明 | 404 | | ------- | -------- | ---- | -------------- | 405 | | plateid | Y | int | 要删除的那个id | 406 | 407 | ### 返回示例 408 | 409 | ``` 410 | { 411 | status: 1, 412 | success: '版块删除成功', 413 | } 414 | ``` 415 | 416 | # 13.批量删除选择的版块 417 | 418 | ### 请求URL 419 | 420 | http://localhost:8080/plates/deleteplate/:plateids 421 | 422 | ### 请求方式 423 | 424 | get 425 | 426 | ### 参数列表 427 | 428 | | 参数 | 是否必须 | 类型 | 说明 | 429 | | -------- | -------- | ---- | ---------------------------- | 430 | | plateids | Y | [] | 所有选中的版块的id组成的数组 | 431 | 432 | ### 返回示例 433 | 434 | ``` 435 | { 436 | status: 1, 437 | success: '版块批量删除成功', 438 | } 439 | ``` 440 | 441 | # 14.获取所有版块名称 442 | 443 | ### 请求URL 444 | 445 | http://localhost:8080/plates/allplatename 446 | 447 | ### 请求方式 448 | 449 | get 450 | 451 | ### 参数列表 452 | 453 | 暂无 454 | 455 | ### 返回示例 456 | 457 | ``` 458 | [ 459 | { 460 | id:"1", 461 | plate_name:"学习" 462 | }, 463 | { 464 | id:"2", 465 | plate_name:"生活" 466 | }, 467 | ....... 468 | ] 469 | ``` 470 | 471 | # 15.返回没有版主的版块列表 472 | 473 | 要求:该版块没有版主 474 | 475 | ### 请求URL 476 | 477 | http://localhost:8080/plates/noplateuser/:userid 478 | 479 | ### 请求方式 480 | 481 | get 482 | 483 | ### 参数类型 484 | 485 | | 参数 | 是否必须 | 类型 | 说明 | 486 | | ------ | -------- | ---- | ------------------------------------------------------------ | 487 | | userid | Y | int | 根据用户id返回版块列表,如果该用户是版主,则返回的列表中应该包括该版块(且该版块应该放在数组中的第一个位置)+没有版主的版块列表,如果该用户不是版主,则返回的列表中只包括没有版主的版块 | 488 | 489 | ### 返回示例 490 | 491 | ``` 492 | [ 493 | { 494 | plateid:1, 495 | plate_name:"学习版块" 496 | }, 497 | { 498 | plateid:11, 499 | plate_name:"生活版块" 500 | } 501 | ] 502 | ``` 503 | 504 | # 16.返回可以选择的版主 505 | 506 | 1.积分数大于50 507 | 508 | 2.未担任其他版块的版主 509 | 510 | ### 请求URL 511 | 512 | http://localhost:8080/users/toplateuser 513 | 514 | ### 请求方式 515 | 516 | get 517 | 518 | ### 参数类型 519 | 520 | 无 521 | 522 | ### 返回示例 523 | 524 | ``` 525 | [ 526 | { 527 | userid:1, 528 | nick_name:"tanjia" 529 | }, 530 | { 531 | userid:12, 532 | nick_name:"tanjia2" 533 | } 534 | ] 535 | ``` 536 | 537 | # 文章 538 | 539 | # 17.搜索文章 540 | 541 | ### 请求URL 542 | 543 | http://localhost:8080/articles/searcharticle 544 | 545 | ### 示例 546 | 547 | http://localhost:8080/articles/searcharticle?plateid=2&startTime=20190909&endTime=20190910&plateName=学习&pageNum=1 548 | 549 | ### 参数列表 550 | 551 | | 参数 | 是否必须 | 类型 | 说明 | 552 | | ------------ | -------- | ------ | ----------------------- | 553 | | plateid | N | int | 版块的id | 554 | | startTime | N | string | | 555 | | endTime | N | string | | 556 | | articleTitle | N | string | 模糊查询文章的标题 | 557 | | pageNum | N | int | 默认传递1,一页显示10条 | 558 | 559 | ### 返回示例 560 | 561 | ``` 562 | [ 563 | { 564 | "id":1, 565 | "title": "如何使用mockjs", 566 | "nick_name": "谭佳tanjjj", 567 | "plate_name":"学习版块", 568 | "update_time":"1029-12-21", 569 | "comment_num|1-500":20, 570 | "click_num|1-50":20, 571 | "is_top":0, 572 | "update_time":"1029-12-21" 573 | } 574 | ] 575 | ``` 576 | 577 | # 18.根据文章ID查看文章详情 578 | 579 | ### 请求URL 580 | 581 | http://localhost:8080/articles/articledetail/:articleid 582 | 583 | ### 请求方式 584 | 585 | get 586 | 587 | ### 参数类型 588 | 589 | | 参数 | 是否必须 | 类型 | 说明 | 590 | | --------- | -------- | ---- | ---- | 591 | | articleid | Y | int | | 592 | 593 | ### 返回示例 594 | 595 | ``` 596 | { 597 | "id":3, 598 | "title": "如何使用ssm", 599 | "content":" 这个假期接触了网页前端的又一个利器,vue.js,它的主要特点在于对数据的双向绑", 600 | "nick_name": "大哥", 601 | "plate_name":"学习版块", 602 | "update_time":"1029-12-21", 603 | "comment_num":20, 604 | "comment_content":[ 605 | { 606 | "id":1, //评论的id 607 | "user_id":1, 608 | "nick_name":"tanj", 609 | "photo":"", 610 | "comment_type":2, 611 | "topic_id":1, 612 | "content":"这是tanj的评论tanj的评论", 613 | "update_time":"2019-07-30 17:30:24" 614 | }, 615 | { 616 | "id":2, 617 | "user_id":2, 618 | "nick_name":"xiaohang", 619 | "photo":"", 620 | "comment_type":2, 621 | "topic_id":1, 622 | "content":"这是xiaohang的评论xiaohang的评论", 623 | "update_time":"2019-07-30 17:30:24" 624 | }, 625 | { 626 | "id":3, 627 | "user_id":3, 628 | "nick_name":"zhang", 629 | "photo":"", 630 | "comment_type":2, 631 | "topic_id":1, 632 | "content":"这是zhang的评论zhang的评论", 633 | "update_time":"2019-07-30 17:30:24" 634 | }, 635 | { 636 | "id":4, 637 | "user_id":4, 638 | "nick_name":"dage", 639 | "photo":"", 640 | "comment_type":2, 641 | "topic_id":1, 642 | "content":"这是dage的评论dage的评论", 643 | "update_time":"2019-07-30 17:30:24" 644 | } 645 | ], 646 | "click_num":20, 647 | "is_top":1, 648 | "update_time":"1029-12-21" 649 | } 650 | ``` 651 | 652 | # 19.给某个文章添加评论 653 | 654 | http://localhost:8080/articles/addcomment 655 | 656 | ### 请求方式 657 | 658 | post 659 | 660 | ### 参数列表 661 | 662 | | 参数 | 是否必须 | 类型 | 说明 | 663 | | ------------------------------------------------------- | -------- | ------ | ------------------------------------------------ | 664 | | comment:{ | | | | 665 | | topic_id | Y | int | 文章的id | 666 | | comment_type | Y | int | 评论的类型 1:给文章进行评论 2:回复评论的评论 | 667 | | content | Y | string | 评论的内容 | 668 | | }(应不应该加上user_id,是前台传过去还是在后台获取??) | | | | 669 | 670 | ### 返回示例 671 | 672 | ``` 673 | { 674 | status: 1, 675 | success: '评论成功' 676 | } 677 | ``` 678 | 679 | # 20.根据文章的id删除文章 680 | 681 | ### 请求URL 682 | 683 | http://localhost:8080/articles/deletearticle/:articleid 684 | 685 | ### 请求方式 686 | 687 | get 688 | 689 | ### 参数列表 690 | 691 | | 参数 | 是否必须 | 类型 | 说明 | 692 | | --------- | -------- | ---- | -------- | 693 | | articleid | Y | int | 文章的id | 694 | 695 | ### 返回示例 696 | 697 | ``` 698 | { 699 | status: 1, 700 | success: '删除文章成功', 701 | } 702 | ``` 703 | 704 | # 21.批量删除所选的文章 705 | 706 | ### 请求URL 707 | 708 | http://localhost:8080/articles/deletearticle/:articleids 709 | 710 | ### 请求方式 711 | 712 | get 713 | 714 | ### 参数列表 715 | 716 | | 参数 | 是否必须 | 类型 | 说明 | 717 | | ---------- | -------- | ---- | ---------------------------- | 718 | | articleids | Y | [] | 所有选中的文章的id组成的数组 | 719 | 720 | ### 返回示例 721 | 722 | ``` 723 | { 724 | status: 1, 725 | success: '批量删除文章信息成功', 726 | } 727 | ``` 728 | 729 | # 22.根据评论的id删除评论 730 | 731 | ### 请求URL 732 | 733 | http://localhost:8080/comments/deletecomment/:commentid 734 | 735 | ### 请求方式 736 | 737 | get 738 | 739 | ### 参数列表 740 | 741 | | 参数 | 是否必须 | 类型 | 说明 | 742 | | --------- | -------- | ---- | -------- | 743 | | commentid | Y | int | 评论的id | 744 | 745 | ### 返回示例 746 | 747 | ``` 748 | { 749 | status: 1, 750 | success: '删除评论信息成功', 751 | } 752 | ``` 753 | 754 | # 评论 755 | 756 | # 23.搜索评论 757 | 758 | ### 请求URL 759 | 760 | http://localhost:8080/comments/searchcomment 761 | 762 | ### 示例 763 | 764 | http://localhost:8080/comments/searchcomment?startTime=2019-08-22&endTime=2019-09-17&commentContent=sd&pageNum=1 765 | 766 | ### 请求方式 767 | 768 | get 769 | 770 | ### 参数类型 query 771 | 772 | | 参数 | 是否必须 | 类型 | 说明 | 773 | | -------------- | -------- | ------ | -------------------------------------- | 774 | | startTime | N | string | 前端控制开始时间和结束时间必须同时输入 | 775 | | endTime | N | string | | 776 | | commentContent | N | string | | 777 | | pageNum | N | int | | 778 | 779 | ### 返回示例 780 | 781 | ``` 782 | [ 783 | { 784 | "id":1, 785 | "topic_id":1, 786 | "topic":"贪贪贪", 787 | "nick_name":"这是评论者", 788 | "content":"这是评论的内容", 789 | "comment_type":"1" 790 | }, 791 | { 792 | ...... 793 | } 794 | ] 795 | ``` 796 | 797 | # 24.根据评论ID删除评论 798 | 799 | ### (前面有一个相同的,实现一个即可) 800 | 801 | ### 请求URL 802 | 803 | http://localhost:8080/comments/deletecomment/:commentid 804 | 805 | ### 请求方式 806 | 807 | get 808 | 809 | ### 参数列表 810 | 811 | | 参数 | 类型 | 是否必须 | 说明 | 812 | | --------- | ---- | -------- | -------- | 813 | | commentid | int | Y | 评论的id | 814 | 815 | ### 返回示例 816 | 817 | ``` 818 | { 819 | status: 1, 820 | success: '版块批量删除成功', 821 | } 822 | ``` 823 | 824 | # 25.批量删除评论 825 | 826 | ### 请求URL 827 | 828 | http://localhost:8080/comments/deletecomments/:comment_ids 829 | 830 | ### 请求方式 831 | 832 | get 833 | 834 | ### 参数列表 835 | 836 | | 参数 | 是否必须 | 类型 | 说明 | 837 | | ---------- | -------- | ---- | ---------------- | 838 | | commentids | Y | [] | 存储选中的版块id | 839 | 840 | ### 返回示例 841 | 842 | ``` 843 | { 844 | status: 1, 845 | success: '版块批量删除成功', 846 | } 847 | ``` 848 | 849 | # 用户 850 | 851 | # 26.搜索用户 852 | 853 | ### 请求URL 854 | 855 | http://localhost:8080/users/searchuser 856 | 857 | ### 示例 858 | 859 | http://localhost:8080/users/searchuser?role_name=&username=tanj&pageNum=1 860 | 861 | ### 请求方式 862 | 863 | get 864 | 865 | ### 参数列表 866 | 867 | | 参数 | 是否必须 | 类型 | 说明 | 868 | | --------- | -------- | ------ | ---------------------------- | 869 | | role_name | N | string | "普通用户" "版主" "管理员" | 870 | | username | N | string | 根据用户名模糊查找 | 871 | | pageNum | N | int | 默认为1 | 872 | 873 | ### 返回示例 874 | 875 | ``` 876 | [ 877 | { 878 | "nick_name": "ddfdsf", 879 | "id": 1, 880 | "sex":"女", 881 | "email":"1232@123.com", 882 | "update_time":"1212-21-21", 883 | "signature":"我只是个传输", 884 | "integral":10, 885 | "role_name":"普通用户", 886 | "plate_id":1, 887 | "plate_name":"学习版块", 888 | "postNum|1-100":20 889 | }, 890 | ...... 891 | ] 892 | ``` 893 | 894 | # 27.添加用户 895 | 896 | ### 请求URL 897 | 898 | http://localhost:8080/users/adduser 899 | 900 | ### 请求方式 901 | 902 | post 903 | 904 | ### 参数列表 905 | 906 | | 参数 | 是否必须 | 类型 | 说明 | 907 | | --------- | -------- | ------ | ---------- | 908 | | nick_name | Y | string | 不允许重复 | 909 | | password | Y | string | | 910 | | email | N | string | | 911 | | photo | N | string | | 912 | | signature | N | string | | 913 | | integral | N | int | 积分 | 914 | 915 | ### 返回示例 916 | 917 | ``` 918 | { 919 | status: 1, 920 | success: '添加版块信息成功', 921 | } 922 | ``` 923 | 924 | # 28.修改用户信息 925 | 926 | 注意:系统管理员只能修改用户的身份和密码 927 | 928 | ### 请求URL 929 | 930 | http://localhost:8080/users/edituserinfo/:userid 931 | 932 | ### 请求方式 933 | 934 | post 935 | 936 | ### 参数列表 937 | 938 | | 参数 | 是否必须 | 类型 | 说明 | 939 | | ------------ | -------- | ------ | ---------------------------------- | 940 | | userid | Y | int | | 941 | | edituserinfo | Y | {} | 包含下面几个属性 | 942 | | { | | | | 943 | | role_name | Y | string | 用户角色:普通用户 版主 管理员 | 944 | | plate_id | Y | int | 如果为版主则是版块的id,否则为NULL | 945 | | password | N | string | 修改的密码 | 946 | | } | | | | 947 | 948 | ### 返回示例 949 | 950 | ``` 951 | { 952 | status: 1, 953 | success: '修改成功' 954 | } 955 | ``` 956 | 957 | # 29.根据用户ID查看用户信息 958 | 959 | ### 请求URL 960 | 961 | http://localhost:8080/users/userdetail/:userid 962 | 963 | ### 示例 964 | 965 | 966 | 967 | ### 参数列表 968 | 969 | | 参数 | 是否必须 | 类型 | 说明 | 970 | | ------ | -------- | ---- | ------ | 971 | | userid | Y | int | 用户id | 972 | 973 | ### 返回示例 974 | 975 | ``` 976 | { 977 | "nick_name": "ddfdsf", 978 | "id": 1, 979 | "sex":"男", 980 | "email":"1232@123.com", 981 | "update_time":"1212-21-21", 982 | "signature":"我只是个传输", 983 | "integral":10, 984 | "role_name":"普通用户", 985 | "plate_id":1, 986 | "photo":"/img/photo.png" 987 | "plate_name":"学习版块", 988 | "postNum|1-100":20 989 | } 990 | ``` 991 | 992 | # 30.根据用户ID删除用户 993 | 994 | ### 请求URL 995 | 996 | http://localhost:8080/users/deleteuser/:userid 997 | 998 | ### 示例 999 | 1000 | ### 请求类型 1001 | 1002 | get 1003 | 1004 | ### 参数列表 1005 | 1006 | | 参数 | 是否必须 | 类型 | 说明 | 1007 | | ------ | -------- | ---- | ---- | 1008 | | userid | Y | int | | 1009 | 1010 | ### 返回示例 1011 | 1012 | ``` 1013 | { 1014 | status: 1, 1015 | success: '版块删除成功', 1016 | } 1017 | ``` 1018 | 1019 | # 31.批量删除用户 1020 | 1021 | ### 请求URL 1022 | 1023 | http://localhost:8080/users/deleteuser/:userids 1024 | 1025 | ### 请求方式 1026 | 1027 | get 1028 | 1029 | ### 参数列表 1030 | 1031 | | 参数 | 是否必须 | 类型 | 说明 | 1032 | | ------- | -------- | ---- | -------------------------- | 1033 | | userids | Y | [] | 所选择的用户的id组成的数组 | 1034 | 1035 | ### 返回示例 1036 | 1037 | ``` 1038 | { 1039 | status: 1, 1040 | success: '版块删除成功', 1041 | } 1042 | ``` 1043 | 1044 | # 版主 1045 | 1046 | # 32.根据版主id返回所管理的版块列表 1047 | 1048 | 如果是版主 则返回他对应的那个版块的情况 1049 | 1050 | ### 请求URL 1051 | 1052 | http://localhost:8080/plates/plateUserPlateList 1053 | 1054 | ### 示例 1055 | 1056 | http://localhost:8080/plates/plateUserPlateList?userid=1 1057 | 1058 | ### 请求方式 1059 | 1060 | get 1061 | 1062 | ### 参数类型 1063 | 1064 | | 参数 | 是否必须 | 类型 | 说明 | 1065 | | ------- | -------- | ---- | -------- | 1066 | | user_id | Y | int | 用户的id | 1067 | 1068 | ### 返回示例 1069 | 1070 | ``` 1071 | [ 1072 | { 1073 | "plate_name": "学习", 1074 | "id": 2, 1075 | "description":"这里是讨论学习的地方", 1076 | "moderator_name":"123", 1077 | "update_time":"1029-12-21", 1078 | "postNum":20, 1079 | } 1080 | ] 1081 | ``` 1082 | 1083 | # 33.根据版主id返回所管理的文章列表 1084 | 1085 | 如果是版主 则返回他对应的那个版块的所有文章情况 1086 | 1087 | ### 请求URL 1088 | 1089 | http://localhost:8080/articles/plateUserArticleList 1090 | 1091 | ### 示例 1092 | 1093 | http://localhost:8080/articles/plateUserArticleList?userid=1&pageNum=1 1094 | 1095 | ### 请求方式 1096 | 1097 | get 1098 | 1099 | ### 参数类型 1100 | 1101 | | 参数 | 是否必须 | 类型 | 说明 | 1102 | | ------- | -------- | ---- | -------- | 1103 | | user_id | Y | int | 用户的id | 1104 | | pageNum | Y | int | | 1105 | 1106 | ### 返回示例 1107 | 1108 | ``` 1109 | [ 1110 | { 1111 | "id":1, 1112 | "is_top":0, 1113 | "title": "如何使用mockjs", 1114 | "nick_name": "谭佳", 1115 | "plate_name":"学习版块", 1116 | "update_time":"1029-12-21", 1117 | "comment_num":20, 1118 | "click_num":20, 1119 | "update_time":"1029-12-21" 1120 | } 1121 | ] 1122 | ``` 1123 | 1124 | # 34.根据版主id返回所管理的评论列表 1125 | 1126 | 如果是版主 则返回他对应的那个版块的所有文章的所有评论情况 1127 | 1128 | ### 请求URL 1129 | 1130 | http://localhost:8080/comments/plateUserCommontList 1131 | 1132 | ### 示例 1133 | 1134 | http://localhost:8080/comments/plateUserCommontList?userid=1&pageNum=1 1135 | 1136 | ### 请求方式 1137 | 1138 | get 1139 | 1140 | ### 参数类型 1141 | 1142 | | 参数 | 是否必须 | 类型 | 说明 | 1143 | | ------- | -------- | ---- | -------- | 1144 | | user_id | Y | int | 用户的id | 1145 | | pageNum | Y | int | | 1146 | 1147 | ### 返回示例 1148 | 1149 | ``` 1150 | [ 1151 | { 1152 | "id":1, 1153 | "topic_id":1, 1154 | "topic":"这是文章的标题", 1155 | "nick_name":"这是评论者", 1156 | "content":"这是评论的内容", 1157 | "comment_type":1,//1:对文章的评论,2:对评论的回复 1158 | } 1159 | ] 1160 | ``` 1161 | 1162 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 20 | 21 | 38 | -------------------------------------------------------------------------------- /src/api/ajax.js: -------------------------------------------------------------------------------- 1 | //ajax请求函数模块 返回值是一个promise对象 (异步返回的数据是response.data) 2 | import Vue from 'vue' 3 | import axios from 'axios' 4 | import Qs from 'qs' 5 | 6 | Vue.prototype.$axios = axios; 7 | export default function ajax(url,data={},type='GET') { 8 | // console.log(url) 9 | // url = "http://127.0.0.1:3000"+url //前后台分离,请求后台 10 | return new Promise(function (resolve,reject) { 11 | //执行异步ajax请求 12 | let promise 13 | if (type === 'GET') { 14 | // 准备 url query 参数数据 15 | let dataStr = '' // 数据拼接字符串 16 | Object.keys(data).forEach(key => { 17 | dataStr += key + '=' + data[key] + '&' 18 | }) 19 | if (dataStr !== '') { 20 | dataStr = dataStr.substring(0, dataStr.lastIndexOf('&')) 21 | url = url + '?' + dataStr 22 | } 23 | // 发送 get 请求 24 | promise = axios.get(url) 25 | } else { 26 | // console.log(postData) 27 | // 发送 post 请求 28 | promise = axios.post(url, Qs.stringify(data)) 29 | } 30 | promise.then(function (response) { 31 | //成功调用resolve() 32 | resolve(response.data); 33 | }).catch(function (error) { 34 | //失败调用reject() 35 | reject(error) 36 | }) 37 | }) 38 | } 39 | -------------------------------------------------------------------------------- /src/api/fetch.js: -------------------------------------------------------------------------------- 1 | 2 | export default async(url = '', data = {}, type = 'GET', method = 'fetch') => { 3 | // let baseUrl = "http://127.0.0.1:3000" 4 | let baseUrl = '' // mock.js拦截 比如拦截请求/user/login 5 | type = type.toUpperCase(); 6 | url = baseUrl + url; 7 | 8 | if (type == 'GET') { 9 | let dataStr = ''; //数据拼接字符串 10 | Object.keys(data).forEach(key => { 11 | dataStr += key + '=' + data[key] + '&'; 12 | }) 13 | 14 | if (dataStr !== '') { 15 | dataStr = dataStr.substr(0, dataStr.lastIndexOf('&')); 16 | url = url + '?' + dataStr; 17 | } 18 | } 19 | 20 | if (window.fetch && method == 'fetch') { 21 | let requestConfig = { 22 | credentials: 'include', 23 | method: type, 24 | headers: { 25 | 'Accept': 'application/json', 26 | 'Content-Type': 'application/json' 27 | }, 28 | mode: "cors", 29 | cache: "force-cache" 30 | } 31 | 32 | if (type == 'POST') { 33 | Object.defineProperty(requestConfig, 'body', { 34 | value: JSON.stringify(data) 35 | }) 36 | } 37 | 38 | try { 39 | const response = await fetch(url, requestConfig); 40 | const responseJson = await response.json(); 41 | return responseJson 42 | } catch (error) { 43 | throw new Error(error) 44 | } 45 | } else { 46 | return new Promise((resolve, reject) => { 47 | let requestObj; 48 | if (window.XMLHttpRequest) { 49 | requestObj = new XMLHttpRequest(); 50 | } else { 51 | requestObj = new ActiveXObject; 52 | } 53 | 54 | let sendData = ''; 55 | if (type == 'POST') { 56 | sendData = JSON.stringify(data); 57 | } 58 | 59 | requestObj.open(type, url, true); 60 | requestObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 61 | requestObj.send(sendData); 62 | 63 | requestObj.onreadystatechange = () => { 64 | if (requestObj.readyState == 4) { 65 | if (requestObj.status == 200) { 66 | let obj = requestObj.response 67 | if (typeof obj !== 'object') { 68 | obj = JSON.parse(obj); 69 | } 70 | resolve(obj) 71 | } else { 72 | reject(requestObj) 73 | } 74 | } 75 | } 76 | }) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/api/index.js: -------------------------------------------------------------------------------- 1 | import fetch from './fetch' 2 | import ajax from './ajax' 3 | const BASE_URL = '/api' 4 | 5 | //1.用户登录 6 | export const reqLogin = (nick_name,password)=>ajax(`/users/login`,{nick_name:nick_name,password:password},'POST') 7 | 8 | //2.根据登录用户的id获取用户信息 9 | export const reqLoginUserInfo = (user_id)=>ajax(`/users/loginuserinfo`,{user_id:user_id}) 10 | 11 | //3.用户退出 12 | export const reqLogout= ()=>ajax(`/users/logout`) 13 | 14 | //首页 15 | //4.获取文章、评论、用户、版块的数量 16 | export const reqNumber = () => ajax(`/homepage/number`) 17 | 18 | //5.获取最近五个月用户、文章的增长情况 19 | export const reqUserArticleChart = () =>ajax(`/homepage/userArticleChart`) 20 | 21 | //6.获取文章数排名前五的版块 22 | export const reqPlateArticleChart = () =>ajax(`/homepage/plateArticleChart`) 23 | 24 | //7.返回最新的五个用户、版块、文章 25 | export const reqNewFive = () =>ajax(`/homepage/newFive`) 26 | 27 | //8.搜索版块 28 | export const searchPlate = (startTime,endTime,plateName,pageNum)=> ajax(`/plates/searchplate`,{startTime,endTime,plateName,pageNum}) 29 | 30 | //9.添加版块 31 | export const addPlate = (data)=> { 32 | let data2 = data 33 | let mod = data.moderator 34 | if(data.moderator<=0){ 35 | mod = 0 36 | } 37 | data2={ 38 | plate_name:data.plate_name, 39 | desciption:data.desciption, 40 | moderator:mod 41 | } 42 | return ajax(`/plates/addplate`,data,'POST') 43 | } 44 | 45 | //10.根据版块ID查询版块详情 46 | export const reqPlateDetail = (plate_id)=> ajax(`/plates/platedetail/${plate_id}`) 47 | 48 | //11.根据版块ID修改版块详情 49 | export const editPlateDetail = (plate_id,data)=> ajax(`/plates/editplate/${plate_id}`,data,'POST') 50 | 51 | //12.根据版块ID删除版块 52 | export const deletePlateOne = (plate_id)=> ajax(`/plates/deleteplate/${plate_id}`) 53 | 54 | //13.批量删除版块 55 | export const deletePlateSelected = (plate_ids)=> ajax(`/plates/deleteplates/${plate_ids}`) 56 | 57 | //14.获取版块名称 58 | export const reqAllPlateName = ()=>ajax(`/plates/allplatename`) 59 | 60 | //15.获取供选择的版块列表(返回没有版主的版块列表) 61 | export const reqNoPlateList = (user_id) => ajax(`/plates/noplateuser/${user_id}`) 62 | 63 | //16.获取可以做版主的用户 64 | export const reqPlateUserList = () => ajax(`/users/toplateuser`) 65 | 66 | //17.搜索文章 67 | export const searchArticle = (plateid,startTime,endTime,articleTitle,pageNum)=> ajax(`/articles/searcharticle`,{plateid,startTime,endTime,articleTitle,pageNum}) 68 | 69 | //18.根据文章的id获取文章的详细情况 70 | export const reqArticleDetail = (article_id)=>ajax(`/articles/articledetail/${article_id}`) 71 | 72 | //19.评论文章,给某个文章添加评论 73 | export const commentArticle = (data)=>ajax(`/articles/addcomment`,data,'POST') 74 | 75 | //20.根据文章ID删除版块 76 | export const deleteArticleOne = (article_id)=>ajax(`/articles/deletearticle/${article_id}`) 77 | 78 | //21.批量删除文章 79 | export const deleteArticleSeleted = (article_ids)=>ajax(`/articles/deletearticles/${article_ids}`) 80 | 81 | //22.根据评论的id删除评论 82 | export const delComment = (comment_id)=>ajax(`/comments/deletecomment/${comment_id}`) 83 | 84 | //23.搜索评论 85 | export const searchComment = (startTime,endTime,commentContent,pageNum)=> ajax(`/comments/searchcomment`,{startTime,endTime,commentContent,pageNum}) 86 | 87 | //24.根据评论的id删除评论 88 | export const deleteCommentOne = (comment_id)=>ajax(`/comments/deletecomment/${comment_id}`) 89 | 90 | //25.批量删除评论 91 | export const deleteCommentSeleted = (comment_ids)=>ajax(`/comments/deletecomments/${comment_ids}`) 92 | 93 | //26.搜索用户 94 | export const searchUser = (role_name,username,pageNum)=> ajax(`/users/searchuser`,{role_name,username,pageNum}) 95 | 96 | //27.添加用户 97 | export const addUser = (data)=> ajax(`/users/adduser`,data,'POST') 98 | 99 | //28.修改用户信息 100 | export const edituserinfo = (user_id,data) => ajax(`/users/edituserinfo/${user_id}`,data,'POST') 101 | 102 | //29.根据用户ID查询用户详情 103 | export const reqUserDetail = (user_id)=> ajax(`/users/userdetail/${user_id}`) 104 | 105 | //30.根据用户ID删除用户 106 | export const deleteUserOne = (user_id)=> ajax(`/users/deleteuser/${user_id}`) 107 | 108 | //31.批量删除用户 109 | export const deleteUserSelected = (user_ids)=> ajax(`/users/deleteusers/${user_ids}`) 110 | 111 | //32.根据版主id返回所管理的版块列表 112 | export const reqPlateUserPlateList = (user_id)=>ajax(`/plates/plateUserPlateList`,user_id) 113 | 114 | //33.根据版主id返回所管理的文章列表 115 | export const reqPlateUserArticleList = (user_id,pageNum)=>ajax(`/articles/plateUserArticleList`,{user_id,pageNum}) 116 | 117 | //34.根据版主id返回所管理的评论列表 118 | export const reqPlateUserCommontList = (user_id)=>ajax(`/comments/plateUserCommontList`,user_id) 119 | 120 | 121 | //获取用户列表 122 | // export const reqUserList = (pageNum) => ajax(`/users/list`,pageNum) 123 | //获取版块列表 124 | // export const reqPlateList = (pageNum)=>ajax('/plates/list',pageNum) 125 | //获取文章列表 126 | // export const reqArticleList = (pageNum)=>ajax('/articles/list',pageNum) 127 | //获取评论列表 128 | // export const reqCommentList = ()=>ajax('/commons/list') 129 | -------------------------------------------------------------------------------- /src/assets/css/reset.css: -------------------------------------------------------------------------------- 1 | html, body, div, span, applet, object, iframe, 2 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 3 | a, abbr, acronym, address, big, cite, code, 4 | del, dfn, em, img, ins, kbd, q, s, samp, 5 | small, strike, strong, sub, sup, tt, var, 6 | b, u, i, center, 7 | dl, dt, dd, ol, ul, li, 8 | fieldset, form, label, legend, 9 | table, caption, tbody, tfoot, thead, tr, th, td, 10 | article, aside, canvas, details, embed, 11 | figure, figcaption, footer, header, hgroup, 12 | menu, nav, output, ruby, section, summary, 13 | time, mark, audio, video { 14 | margin: 0; 15 | padding: 0; 16 | border: 0; 17 | font-size: 100%; 18 | font: inherit; 19 | vertical-align: baseline; 20 | } 21 | /* HTML5 display-role reset for older browsers */ 22 | article, aside, details, figcaption, figure, 23 | footer, header, hgroup, menu, nav, section { 24 | display: block; 25 | } 26 | body { 27 | line-height: 1; 28 | } 29 | ol, ul { 30 | list-style: none; 31 | } 32 | blockquote, q { 33 | quotes: none; 34 | } 35 | blockquote:before, blockquote:after, 36 | q:before, q:after { 37 | content: ''; 38 | content: none; 39 | } 40 | table { 41 | border-collapse: collapse; 42 | border-spacing: 0; 43 | } 44 | -------------------------------------------------------------------------------- /src/assets/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TanJ2014/vue-element-blog-admin/1ab53bb59cea70215d941881c8c8b12c7a79cace/src/assets/img/favicon.ico -------------------------------------------------------------------------------- /src/assets/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TanJ2014/vue-element-blog-admin/1ab53bb59cea70215d941881c8c8b12c7a79cace/src/assets/img/logo.png -------------------------------------------------------------------------------- /src/assets/img/logo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TanJ2014/vue-element-blog-admin/1ab53bb59cea70215d941881c8c8b12c7a79cace/src/assets/img/logo2.png -------------------------------------------------------------------------------- /src/assets/img/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TanJ2014/vue-element-blog-admin/1ab53bb59cea70215d941881c8c8b12c7a79cace/src/assets/img/user.png -------------------------------------------------------------------------------- /src/assets/img/user3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TanJ2014/vue-element-blog-admin/1ab53bb59cea70215d941881c8c8b12c7a79cace/src/assets/img/user3.png -------------------------------------------------------------------------------- /src/components/Breadcrumb/Breadcrumb.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 39 | 40 | 45 | -------------------------------------------------------------------------------- /src/components/Header/Header.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | 88 | 89 | 115 | -------------------------------------------------------------------------------- /src/components/LeftMenu/LeftMenu.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 89 | 90 | 115 | -------------------------------------------------------------------------------- /src/config/mUtils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 存储localStorage 3 | */ 4 | export const setStore = (name, content) => { 5 | if (!name) return; 6 | if (typeof content !== 'string') { 7 | content = JSON.stringify(content); 8 | } 9 | window.localStorage.setItem(name, content); 10 | 11 | } 12 | 13 | /** 14 | * 获取localStorage 15 | */ 16 | export const getStore = name => { 17 | if (!name) return; 18 | return window.localStorage.getItem(name); 19 | } 20 | 21 | /** 22 | * 删除localStorage 23 | */ 24 | export const removeStore = name => { 25 | if (!name) return; 26 | window.localStorage.removeItem(name); 27 | } 28 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import "babel-polyfill" 4 | import Vue from 'vue' 5 | import App from './App' 6 | import router from './router' 7 | import element from 'element-ui' 8 | import './assets/css/reset.css' 9 | import 'element-ui/lib/theme-chalk/index.css' 10 | import './mock/mockServer' 11 | import store from './store' 12 | // import axios from 'axios' 13 | 14 | Vue.config.productionTip = false 15 | 16 | Vue.use(element) 17 | 18 | /* eslint-disable no-new */ 19 | new Vue({ 20 | el: '#app', 21 | router, 22 | components: { App }, 23 | template: '', 24 | store 25 | }) 26 | -------------------------------------------------------------------------------- /src/mock/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "users":[ 3 | { 4 | "nick_name": "ddfdsf", 5 | "id": 1, 6 | "sex":"女", 7 | "email":"1232@123.com", 8 | "update_time":"1212-21-21", 9 | "signature":"我只是个传输", 10 | "integral":10, 11 | "role_name":"普通用户", 12 | "plate_id":1, 13 | "plate_name":"学习版块", 14 | "postNum|1-100":20 15 | }, 16 | { 17 | "nick_name": "下一名", 18 | "id": 2, 19 | "sex":"女", 20 | "email":"1232@123.com", 21 | "update_time":"1212-21-21", 22 | "signature":"我是爸爸", 23 | "integral":30, 24 | "role_name":"版主", 25 | "plate_id":1, 26 | "plate_name":"生活版块", 27 | "postNum|1-100":20 28 | }, 29 | { 30 | "nick_name|3": "王旭航", 31 | "id": 3, 32 | "sex":"女", 33 | "email":"1232@123.com", 34 | "update_time":"1212-21-21", 35 | "signature|3":"我是爸爸", 36 | "integral":566, 37 | "role_name":"普通用户", 38 | "plate_id":4, 39 | "postNum|1-100":100 40 | }, 41 | { 42 | "nick_name": "小航", 43 | "id": 4, 44 | "sex":"女", 45 | "email":"1452@123.com", 46 | "update_time":"1212-21-21", 47 | "signature|3":"我是妹妹", 48 | "integral":96, 49 | "role_name":"普通用户", 50 | "plate_id":4, 51 | "plate_name":"游戏", 52 | "postNum|1-100":100 53 | }, 54 | { 55 | "nick_name": "tan", 56 | "id": 5, 57 | "sex":"女", 58 | "email":"15552@123.com", 59 | "update_time":"1212-21-21", 60 | "signature|3":"我是jiage", 61 | "integral":96, 62 | "role_name":"普通用户", 63 | "plate_id":4, 64 | "plate_name":"完", 65 | "postNum|1-100":130 66 | }, 67 | { 68 | "nick_name": "qixi", 69 | "id": 6, 70 | "sex":"女", 71 | "email":"132@123.com", 72 | "update_time":"1212-21-21", 73 | "signature":"我是爸爸", 74 | "integral":566, 75 | "role_name":"普通用户", 76 | "plate_id":4, 77 | "plate_name":"谭佳版块", 78 | "postNum|1-100":100 79 | }, 80 | { 81 | "nick_name": "ddfdsf", 82 | "id": 1, 83 | "sex":"女", 84 | "email":"1232@123.com", 85 | "update_time":"1212-21-21", 86 | "signature":"我只是个传输", 87 | "integral":10, 88 | "role_name":"普通用户", 89 | "plate_id":1, 90 | "plate_name":"学习版块", 91 | "postNum|1-100":20 92 | }, 93 | { 94 | "nick_name": "下一名", 95 | "id": 2, 96 | "sex":"女", 97 | "email":"1232@123.com", 98 | "update_time":"1212-21-21", 99 | "signature":"我是爸爸", 100 | "integral":30, 101 | "role_name":"版主", 102 | "plate_id":1, 103 | "plate_name":"生活版块", 104 | "postNum|1-100":20 105 | }, 106 | { 107 | "nick_name|3": "王旭航", 108 | "id": 3, 109 | "sex":"女", 110 | "email":"1232@123.com", 111 | "update_time":"1212-21-21", 112 | "signature|3":"我是爸爸", 113 | "integral":566, 114 | "role_name":"普通用户", 115 | "plate_id":4, 116 | "postNum|1-100":100 117 | }, 118 | { 119 | "nick_name": "小航", 120 | "id": 4, 121 | "sex":"女", 122 | "email":"1452@123.com", 123 | "update_time":"1212-21-21", 124 | "signature|3":"我是妹妹", 125 | "integral":96, 126 | "role_name":"普通用户", 127 | "plate_id":4, 128 | "plate_name":"游戏", 129 | "postNum|1-100":100 130 | }, 131 | { 132 | "nick_name": "tan", 133 | "id": 5, 134 | "sex":"女", 135 | "email":"15552@123.com", 136 | "update_time":"1212-21-21", 137 | "signature|3":"我是jiage", 138 | "integral":96, 139 | "role_name":"普通用户", 140 | "plate_id":4, 141 | "plate_name":"完", 142 | "postNum|1-100":130 143 | }, 144 | { 145 | "nick_name": "qixi", 146 | "id": 6, 147 | "sex":"女", 148 | "email":"132@123.com", 149 | "update_time":"1212-21-21", 150 | "signature":"我是爸爸", 151 | "integral":566, 152 | "role_name":"普通用户", 153 | "plate_id":4, 154 | "plate_name":"谭佳版块", 155 | "postNum|1-100":100 156 | }, 157 | { 158 | "nick_name": "ddfdsf", 159 | "id": 1, 160 | "sex":"女", 161 | "email":"1232@123.com", 162 | "update_time":"1212-21-21", 163 | "signature":"我只是个传输", 164 | "integral":10, 165 | "role_name":"普通用户", 166 | "plate_id":1, 167 | "plate_name":"学习版块", 168 | "postNum|1-100":20 169 | }, 170 | { 171 | "nick_name": "下一名", 172 | "id": 2, 173 | "sex":"女", 174 | "email":"1232@123.com", 175 | "update_time":"1212-21-21", 176 | "signature":"我是爸爸", 177 | "integral":30, 178 | "role_name":"版主", 179 | "plate_id":1, 180 | "plate_name":"生活版块", 181 | "postNum|1-100":20 182 | }, 183 | { 184 | "nick_name|3": "王旭航", 185 | "id": 3, 186 | "sex":"女", 187 | "email":"1232@123.com", 188 | "update_time":"1212-21-21", 189 | "signature|3":"我是爸爸", 190 | "integral":566, 191 | "role_name":"普通用户", 192 | "plate_id":4, 193 | "postNum|1-100":100 194 | }, 195 | { 196 | "nick_name": "小航", 197 | "id": 4, 198 | "sex":"女", 199 | "email":"1452@123.com", 200 | "update_time":"1212-21-21", 201 | "signature|3":"我是妹妹", 202 | "integral":96, 203 | "role_name":"普通用户", 204 | "plate_id":4, 205 | "plate_name":"游戏", 206 | "postNum|1-100":100 207 | }, 208 | { 209 | "nick_name": "tan", 210 | "id": 5, 211 | "sex":"女", 212 | "email":"15552@123.com", 213 | "update_time":"1212-21-21", 214 | "signature|3":"我是jiage", 215 | "integral":96, 216 | "role_name":"普通用户", 217 | "plate_id":4, 218 | "plate_name":"完", 219 | "postNum|1-100":130 220 | }, 221 | { 222 | "nick_name": "qixi", 223 | "id": 6, 224 | "sex":"女", 225 | "email":"132@123.com", 226 | "update_time":"1212-21-21", 227 | "signature":"我是爸爸", 228 | "integral":566, 229 | "role_name":"普通用户", 230 | "plate_id":4, 231 | "plate_name":"谭佳版块", 232 | "postNum|1-100":100 233 | }, 234 | { 235 | "nick_name": "航", 236 | "id": 17, 237 | "sex":"女", 238 | "email":"1232@123.com", 239 | "update_time":"1212-21-21", 240 | "signature|3":"我爸爸", 241 | "integral":566, 242 | "role_name":"普通用户", 243 | "plate_id":4, 244 | "plate_name":"不知道", 245 | "postNum|1-100":100 246 | } 247 | ], 248 | "searchuser":[ 249 | { 250 | "nick_name": "qixi", 251 | "id": 6, 252 | "sex":"女", 253 | "email":"132@123.com", 254 | "update_time":"1212-21-21", 255 | "signature":"我是爸爸", 256 | "integral":566, 257 | "role_name":"普通用户", 258 | "plate_id":4, 259 | "plate_name":"谭佳版块", 260 | "postNum|1-100":100 261 | }, 262 | { 263 | "nick_name": "qixi", 264 | "id": 6, 265 | "sex":"女", 266 | "email":"132@123.com", 267 | "update_time":"1212-21-21", 268 | "signature":"我是爸爸", 269 | "integral":566, 270 | "role_name":"普通用户", 271 | "plate_id":4, 272 | "plate_name":"谭佳版块", 273 | "postNum|1-100":100 274 | }, 275 | { 276 | "nick_name": "qixi", 277 | "id": 6, 278 | "sex":"女", 279 | "email":"132@123.com", 280 | "update_time":"1212-21-21", 281 | "signature":"我是爸爸", 282 | "integral":566, 283 | "role_name":"普通用户", 284 | "plate_id":4, 285 | "plate_name":"谭佳版块", 286 | "postNum|1-100":100 287 | }, 288 | { 289 | "nick_name": "qixi", 290 | "id": 6, 291 | "sex":"女", 292 | "email":"132@123.com", 293 | "update_time":"1212-21-21", 294 | "signature":"我是爸爸", 295 | "integral":566, 296 | "role_name":"普通用户", 297 | "plate_id":4, 298 | "plate_name":"谭佳版块", 299 | "postNum|1-100":100 300 | }, 301 | { 302 | "nick_name": "qixi", 303 | "id": 6, 304 | "sex":"女", 305 | "email":"132@123.com", 306 | "update_time":"1212-21-21", 307 | "signature":"我是爸爸", 308 | "integral":566, 309 | "role_name":"普通用户", 310 | "plate_id":4, 311 | "plate_name":"谭佳版块", 312 | "postNum|1-100":100 313 | }, 314 | { 315 | "nick_name": "qixi", 316 | "id": 6, 317 | "sex":"女", 318 | "email":"132@123.com", 319 | "update_time":"1212-21-21", 320 | "signature":"我是爸爸", 321 | "integral":566, 322 | "role_name":"普通用户", 323 | "plate_id":4, 324 | "plate_name":"谭佳版块", 325 | "postNum|1-100":100 326 | }, 327 | { 328 | "nick_name": "qixi", 329 | "id": 6, 330 | "sex":"女", 331 | "email":"132@123.com", 332 | "update_time":"1212-21-21", 333 | "signature":"我是爸爸", 334 | "integral":566, 335 | "role_name":"普通用户", 336 | "plate_id":4, 337 | "plate_name":"谭佳版块", 338 | "postNum|1-100":100 339 | }, 340 | { 341 | "nick_name": "qixi", 342 | "id": 6, 343 | "sex":"女", 344 | "email":"132@123.com", 345 | "update_time":"1212-21-21", 346 | "signature":"我是爸爸", 347 | "integral":566, 348 | "role_name":"普通用户", 349 | "plate_id":4, 350 | "plate_name":"谭佳版块", 351 | "postNum|1-100":100 352 | }, 353 | { 354 | "nick_name": "qixi", 355 | "id": 6, 356 | "sex":"女", 357 | "email":"132@123.com", 358 | "update_time":"1212-21-21", 359 | "signature":"我是爸爸", 360 | "integral":566, 361 | "role_name":"普通用户", 362 | "plate_id":4, 363 | "plate_name":"谭佳版块", 364 | "postNum|1-100":100 365 | }, 366 | { 367 | "nick_name": "qixi", 368 | "id": 6, 369 | "sex":"女", 370 | "email":"132@123.com", 371 | "update_time":"1212-21-21", 372 | "signature":"我是爸爸", 373 | "integral":566, 374 | "role_name":"普通用户", 375 | "plate_id":4, 376 | "plate_name":"谭佳版块", 377 | "postNum|1-100":100 378 | }, 379 | { 380 | "nick_name": "qixi", 381 | "id": 6, 382 | "sex":"女", 383 | "email":"132@123.com", 384 | "update_time":"1212-21-21", 385 | "signature":"我是爸爸", 386 | "integral":566, 387 | "role_name":"普通用户", 388 | "plate_id":4, 389 | "plate_name":"谭佳版块", 390 | "postNum|1-100":100 391 | }, 392 | { 393 | "nick_name": "qixi", 394 | "id": 6, 395 | "sex":"女", 396 | "email":"132@123.com", 397 | "update_time":"1212-21-21", 398 | "signature":"我是爸爸", 399 | "integral":566, 400 | "role_name":"普通用户", 401 | "plate_id":4, 402 | "plate_name":"谭佳版块", 403 | "postNum|1-100":100 404 | }, 405 | { 406 | "nick_name": "qixi", 407 | "id": 6, 408 | "sex":"女", 409 | "email":"132@123.com", 410 | "update_time":"1212-21-21", 411 | "signature":"我是爸爸", 412 | "integral":566, 413 | "role_name":"普通用户", 414 | "plate_id":4, 415 | "plate_name":"谭佳版块", 416 | "postNum|1-100":100 417 | } 418 | ], 419 | "plateUserList":[ 420 | { 421 | "userid":1, 422 | "nick_name":"tanjia" 423 | }, 424 | { 425 | "userid":12, 426 | "nick_name":"tanjia2" 427 | } 428 | ], 429 | "noplateuser":[ 430 | { 431 | "plateid":1, 432 | "plate_name":"学习版块" 433 | }, 434 | { 435 | "plateid":11, 436 | "plate_name":"聊天版块" 437 | } 438 | ], 439 | "plates":[ 440 | { 441 | "plate_name": "学习", 442 | "id": 1, 443 | "description|1-10":"这里是讨论学习的地方", 444 | "moderator_name|1-10":"admin", 445 | "update_time":"1029-12-21", 446 | "postNum|1-1000":20 447 | }, 448 | { 449 | "plate_name": "工作", 450 | "id": 2, 451 | "description|1-10":"工作的地方", 452 | "moderator_name|1-10":"zhang12", 453 | "update_time":"1029-12-21", 454 | "postNum|1-1000":20 455 | }, 456 | { 457 | "plate_name": "休息", 458 | "id": 3, 459 | "description|1-10":"休息的地方", 460 | "moderator_name|1-10":"tan", 461 | "update_time":"1029-12-21", 462 | "postNum|1-1000":20 463 | }, 464 | { 465 | "plate_name": "学习", 466 | "id": 4, 467 | "description|1-10":"这里是讨论学习的地方", 468 | "moderator_name|1-10":"阿弟", 469 | "update_time":"1029-12-21", 470 | "postNum|1-1000":20 471 | }, 472 | { 473 | "plate_name": "学习", 474 | "id": 5, 475 | "description|1-10":"这里是讨论学习的地方", 476 | "moderator_name|1-10":"版主的名字", 477 | "update_time":"1029-12-21", 478 | "postNum|1-1000":20 479 | }, 480 | { 481 | "plate_name": "学习", 482 | "id": 6, 483 | "description|1-10":"这里是讨论学习的地方", 484 | "moderator_name|1-10":"213", 485 | "update_time":"1029-12-21", 486 | "postNum|1-1000":20 487 | } 488 | ], 489 | "plates2":[{ 490 | "plate_name": "学习2222", 491 | "id": 1, 492 | "description|1-10":"这里是讨论学习的地方", 493 | "moderator_name|1-10":"213", 494 | "update_time":"1029-12-21", 495 | "postNum|1-1000":20 496 | }], 497 | "plates3":[ 498 | { 499 | "plate_name": "学习333333333", 500 | "id": 1, 501 | "description|1-10":"这里是讨论学习的地方", 502 | "moderator_name|1-10":"213", 503 | "update_time":"1029-12-21", 504 | "postNum|1-1000":20 505 | } 506 | ], 507 | "plates4":[{ 508 | "plate_name": "学习44444444444", 509 | "id": 1, 510 | "description|1-10":"这里是讨论学习的地方", 511 | "moderator_name|1-10":"213", 512 | "update_time":"1029-12-21", 513 | "postNum|1-1000":20 514 | }], 515 | "plates5":[ 516 | { 517 | "plate_name": "学习5555555555", 518 | "id": 1, 519 | "description|1-10":"这里是讨论学习的地方", 520 | "moderator_name|1-10":"213", 521 | "update_time":"1029-12-21", 522 | "postNum|1-1000":20 523 | } 524 | ], 525 | "articles":[ 526 | { 527 | "id":1, 528 | "title": "关于Vue.js", 529 | "nick_name": "TanJia", 530 | "plate_name":"学习版块", 531 | "update_time":"2019-03-23", 532 | "comment_num|1-500":20, 533 | "click_num|1-50":20, 534 | "is_top":0 535 | }, 536 | { 537 | "id":2, 538 | "title": "第二篇文章", 539 | "nick_name": "大哥", 540 | "plate_name":"学习版块", 541 | "update_time":"1029-12-21", 542 | "comment_num|1-1000":20, 543 | "click_num|1-50":20, 544 | "is_top":1, 545 | "update_time":"1029-12-21" 546 | }, 547 | { 548 | "id":1, 549 | "title": "第3篇文章", 550 | "nick_name": "谭佳", 551 | "plate_name":"学习版块", 552 | "update_time":"1029-12-21", 553 | "comment_num|1-500":20, 554 | "click_num|1-50":20, 555 | "is_top":0, 556 | "update_time":"1029-12-21" 557 | }, 558 | { 559 | "id":1, 560 | "title": "第4篇文章", 561 | "nick_name": "谭佳", 562 | "plate_name":"学习版块", 563 | "update_time":"1029-12-21", 564 | "comment_num|1-500":20, 565 | "click_num|1-50":20, 566 | "is_top":0, 567 | "update_time":"1029-12-21" 568 | }, 569 | { 570 | "id":1, 571 | "title": "第5篇文章", 572 | "nick_name": "谭佳", 573 | "plate_name":"学习版块", 574 | "update_time":"1029-12-21", 575 | "comment_num|1-500":20, 576 | "click_num|1-50":20, 577 | "is_top":0, 578 | "update_time":"1029-12-21" 579 | }, 580 | { 581 | "id":1, 582 | "title": "第6篇文章", 583 | "nick_name": "谭佳", 584 | "plate_name":"学习版块", 585 | "update_time":"1029-12-21", 586 | "comment_num|1-500":20, 587 | "click_num|1-50":20, 588 | "is_top":0, 589 | "update_time":"1029-12-21" 590 | }, 591 | { 592 | "id":1, 593 | "title": "第7篇文章", 594 | "nick_name": "谭佳", 595 | "plate_name":"学习版块", 596 | "update_time":"1029-12-21", 597 | "comment_num|1-500":20, 598 | "click_num|1-50":20, 599 | "is_top":0, 600 | "update_time":"1029-12-21" 601 | }, 602 | { 603 | "id":1, 604 | "title": "如何使用mockjs", 605 | "nick_name": "谭佳", 606 | "plate_name":"学习版块", 607 | "update_time":"1029-12-21", 608 | "comment_num|1-500":20, 609 | "click_num|1-50":20, 610 | "is_top":0, 611 | "update_time":"1029-12-21" 612 | }, 613 | { 614 | "id":1, 615 | "title": "如何使用mockjs", 616 | "nick_name": "谭佳", 617 | "plate_name":"学习版块", 618 | "update_time":"1029-12-21", 619 | "comment_num|1-500":20, 620 | "click_num|1-50":20, 621 | "is_top":0, 622 | "update_time":"1029-12-21" 623 | }, 624 | { 625 | "id":1, 626 | "title": "如何使用mockjs", 627 | "nick_name": "谭佳", 628 | "plate_name":"学习版块", 629 | "update_time":"1029-12-21", 630 | "comment_num|1-500":20, 631 | "click_num|1-50":20, 632 | "is_top":0, 633 | "update_time":"1029-12-21" 634 | }, 635 | { 636 | "id":1, 637 | "title": "如何使用mockjs", 638 | "nick_name": "谭佳", 639 | "plate_name":"学习版块", 640 | "update_time":"1029-12-21", 641 | "comment_num|1-500":20, 642 | "click_num|1-50":20, 643 | "is_top":0, 644 | "update_time":"1029-12-21" 645 | }, 646 | { 647 | "id":1, 648 | "title": "如何使用mockjs", 649 | "nick_name": "谭佳", 650 | "plate_name":"学习版块", 651 | "update_time":"1029-12-21", 652 | "comment_num|1-500":20, 653 | "click_num|1-50":20, 654 | "is_top":0, 655 | "update_time":"1029-12-21" 656 | }, 657 | { 658 | "id":1, 659 | "title": "如何使用mockjs", 660 | "nick_name": "谭佳", 661 | "plate_name":"学习版块", 662 | "update_time":"1029-12-21", 663 | "comment_num|1-500":20, 664 | "click_num|1-50":20, 665 | "is_top":0, 666 | "update_time":"1029-12-21" 667 | }, 668 | { 669 | "id":1, 670 | "title": "如何使用mockjs", 671 | "nick_name": "谭佳", 672 | "plate_name":"学习版块", 673 | "update_time":"1029-12-21", 674 | "comment_num|1-500":20, 675 | "click_num|1-50":20, 676 | "is_top":0, 677 | "update_time":"1029-12-21" 678 | }, 679 | { 680 | "id":1, 681 | "title": "如何使用mockjs", 682 | "nick_name": "谭佳", 683 | "plate_name":"学习版块", 684 | "update_time":"1029-12-21", 685 | "comment_num|1-500":20, 686 | "click_num|1-50":20, 687 | "is_top":0, 688 | "update_time":"1029-12-21" 689 | } 690 | ], 691 | "comments":[ 692 | { 693 | "id":1, 694 | "topic_id":1, 695 | "topic":"这是文章的标题", 696 | "nick_name":"这是评论者", 697 | "content":"这是评论的内容", 698 | "comment_type":"1" 699 | }, 700 | { 701 | "id":2, 702 | "topic_id":12, 703 | "topic":"这是文章的标题2", 704 | "nick_name":"这是评论者2", 705 | "content":"这是评论的内容2这是评论的内容2这是评论的内容2这是评论的内容2这是评论的内容2", 706 | "comment_type":"2" 707 | } 708 | ], 709 | "articleDetail":{ 710 | "id":3, 711 | "title": "关于Vue.js", 712 | "content":" 这个假期接触了网页前端的又一个利器,vue.js,它的主要特点在于对数据的双向绑定。想想之前用最原始的js的时候,我们更改页面上的数据,经常会用到InnerHTML,getElementById的代码,它实际上是在对DOM元素进行添加或修改,包括jQuery,也是通过查找页面源代码中的DOM标签,达到了动态效果的实现,当我们确定要对页面上某一元素进行修改的时候,会用id或name 进行元素查找,然后再找到它对应的value,text去改变它的值。但接触了vue.js之后我再也没有对元素添加过id和name,而是大部分在使用v-bind v-on还有语法糖v-model,以及{{}}。下面的文章中都会有所提到。我主要从 控件 方面,CSS 方面,以及 事件 三方面说起。", 713 | "nick_name": "TanJia", 714 | "plate_name":"学习版块", 715 | "update_time":"1029-12-21", 716 | "comment_num|1-1000":20, 717 | "comment_content":[ 718 | { 719 | "id":1, 720 | "user_id":1, 721 | "nick_name":"tanj", 722 | "photo":"", 723 | "comment_type":2, 724 | "topic_id":1, 725 | "content":"这是tanj的评论tanj的评论", 726 | "update_time":"2019-07-30 17:30:24" 727 | }, 728 | { 729 | "id":2, 730 | "user_id":2, 731 | "nick_name":"xiaohang", 732 | "photo":"", 733 | "comment_type":2, 734 | "topic_id":1, 735 | "content":"这是xiaohang的评论xiaohang的评论", 736 | "update_time":"2019-07-30 17:30:24" 737 | }, 738 | { 739 | "id":3, 740 | "user_id":3, 741 | "nick_name":"zhang", 742 | "photo":"", 743 | "comment_type":2, 744 | "topic_id":1, 745 | "content":"这是zhang的评论zhang的评论", 746 | "update_time":"2019-07-30 17:30:24" 747 | }, 748 | { 749 | "id":4, 750 | "user_id":4, 751 | "nick_name":"dage", 752 | "photo":"", 753 | "comment_type":2, 754 | "topic_id":1, 755 | "content":"这是dage的评论dage的评论", 756 | "update_time":"2019-07-30 17:30:24" 757 | } 758 | ], 759 | "click_num|1-50":20, 760 | "is_top":1, 761 | "update_time":"1029-12-21" 762 | }, 763 | "addplate":{ 764 | "status": 1, 765 | "success": "添加版块信息成功" 766 | }, 767 | "adduser":{ 768 | "status": 1, 769 | "success": "添加用户信息成功" 770 | }, 771 | "userdetail":{ 772 | "nick_name": "ddfdsf", 773 | "id": 1, 774 | "sex":"男", 775 | "email":"1232@123.com", 776 | "update_time":"1212-21-21", 777 | "signature":"我只是个传输", 778 | "integral":10, 779 | "role_name":"版主", 780 | "photo":"../assets/img/user.png", 781 | "plate_id":1, 782 | "plate_name":"学习版块", 783 | "postNum|1-100":20 784 | }, 785 | "platedetail": { 786 | "plate_name": "学习", 787 | "id": 1, 788 | "description|1-10":"这里是讨论学习的地方", 789 | "moderator_name|1-10":"213", 790 | "update_time":"1029-12-21", 791 | "postNum|1-1000":20 792 | }, 793 | "editplate":{ 794 | "status": 1, 795 | "success": "修改版块信息成功" 796 | }, 797 | "delete":{ 798 | "status": 1, 799 | "success": "修改版块信息成功" 800 | }, 801 | "searchplate":[ 802 | { 803 | "plate_name": "学习", 804 | "id": 10, 805 | "description|1-10":"这里是搜索的结果", 806 | "moderator_name|1-10":"213", 807 | "update_time":"1029-12-21", 808 | "postNum|1-1000":20 809 | }, 810 | { 811 | "plate_name": "学习2", 812 | "id": 10, 813 | "description|1-10":"这里是搜索的结果", 814 | "moderator_name|1-10":"213", 815 | "update_time":"1029-12-21", 816 | "postNum|1-1000":20 817 | }, 818 | { 819 | "plate_name": "学习3", 820 | "id": 10, 821 | "description|1-10":"这里是搜索的结果", 822 | "moderator_name|1-10":"213", 823 | "update_time":"1029-12-21", 824 | "postNum|1-1000":20 825 | }, 826 | { 827 | "plate_name": "学习4", 828 | "id": 10, 829 | "description|1-10":"这里是搜索的结果", 830 | "moderator_name|1-10":"213", 831 | "update_time":"1029-12-21", 832 | "postNum|1-1000":20 833 | }, 834 | { 835 | "plate_name": "搜索", 836 | "id": 10, 837 | "description|1-10":"这里是搜索的结果", 838 | "moderator_name|1-10":"213", 839 | "update_time":"1029-12-21", 840 | "postNum|1-1000":20 841 | }, 842 | { 843 | "plate_name": "搜索", 844 | "id": 10, 845 | "description|1-10":"这里是搜索的结果", 846 | "moderator_name|1-10":"213", 847 | "update_time":"1029-12-21", 848 | "postNum|1-1000":20 849 | }, 850 | { 851 | "plate_name": "搜索", 852 | "id": 10, 853 | "description|1-10":"这里是搜索的结果", 854 | "moderator_name|1-10":"213", 855 | "update_time":"1029-12-21", 856 | "postNum|1-1000":20 857 | },{ 858 | "plate_name": "搜索", 859 | "id": 10, 860 | "description|1-10":"这里是搜索的结果", 861 | "moderator_name|1-10":"213", 862 | "update_time":"1029-12-21", 863 | "postNum|1-1000":20 864 | }, 865 | { 866 | "plate_name": "搜索", 867 | "id": 10, 868 | "description|1-10":"这里是搜索的结果", 869 | "moderator_name|1-10":"213", 870 | "update_time":"1029-12-21", 871 | "postNum|1-1000":20 872 | }, 873 | { 874 | "plate_name": "搜索", 875 | "id": 10, 876 | "description|1-10":"这里是搜索的结果", 877 | "moderator_name|1-10":"213", 878 | "update_time":"1029-12-21", 879 | "postNum|1-1000":20 880 | }, 881 | { 882 | "plate_name": "搜索", 883 | "id": 10, 884 | "description|1-10":"这里是搜索的结果", 885 | "moderator_name|1-10":"213", 886 | "update_time":"1029-12-21", 887 | "postNum|1-1000":20 888 | }, 889 | { 890 | "plate_name": "搜索", 891 | "id": 10, 892 | "description|1-10":"这里是搜索的结果", 893 | "moderator_name|1-10":"213", 894 | "update_time":"1029-12-21", 895 | "postNum|1-1000":20 896 | }, 897 | { 898 | "plate_name": "搜索2", 899 | "id": 12, 900 | "description|1-10":"这里是搜索的结果2", 901 | "moderator_name|1-10":"213", 902 | "update_time":"1029-12-21", 903 | "postNum|1-1000":20 904 | } 905 | ], 906 | "searcharticle":[ 907 | { 908 | "id":1, 909 | "title": "如何使用mockjs", 910 | "nick_name": "谭佳tanjjj", 911 | "plate_name":"学习版块", 912 | "update_time":"1029-12-21", 913 | "comment_num|1-500":20, 914 | "click_num|1-50":20, 915 | "is_top":0, 916 | "update_time":"1029-12-21" 917 | }, 918 | { 919 | "id":1, 920 | "title": "如何使用mockjs", 921 | "nick_name": "谭佳tanjjj", 922 | "plate_name":"学习版块", 923 | "update_time":"1029-12-21", 924 | "comment_num|1-500":20, 925 | "click_num|1-50":20, 926 | "is_top":0, 927 | "update_time":"1029-12-21" 928 | }, 929 | { 930 | "id":1, 931 | "title": "如何使用mockjs", 932 | "nick_name": "谭佳tanjjj", 933 | "plate_name":"学习版块", 934 | "update_time":"1029-12-21", 935 | "comment_num|1-500":20, 936 | "click_num|1-50":20, 937 | "is_top":0, 938 | "update_time":"1029-12-21" 939 | }, 940 | { 941 | "id":1, 942 | "title": "如何使用mockjs", 943 | "nick_name": "谭佳tanjjj", 944 | "plate_name":"学习版块", 945 | "update_time":"1029-12-21", 946 | "comment_num|1-500":20, 947 | "click_num|1-50":20, 948 | "is_top":0, 949 | "update_time":"1029-12-21" 950 | }, 951 | { 952 | "id":1, 953 | "title": "如何使用mockjs", 954 | "nick_name": "谭佳tanjjj", 955 | "plate_name":"学习版块", 956 | "update_time":"1029-12-21", 957 | "comment_num|1-500":20, 958 | "click_num|1-50":20, 959 | "is_top":0, 960 | "update_time":"1029-12-21" 961 | }, 962 | { 963 | "id":1, 964 | "title": "如何使用mockjs", 965 | "nick_name": "谭佳tanjjj", 966 | "plate_name":"学习版块", 967 | "update_time":"1029-12-21", 968 | "comment_num|1-500":20, 969 | "click_num|1-50":20, 970 | "is_top":0, 971 | "update_time":"1029-12-21" 972 | }, 973 | { 974 | "id":1, 975 | "title": "如何使用mockjs", 976 | "nick_name": "谭佳tanjjj", 977 | "plate_name":"学习版块", 978 | "update_time":"1029-12-21", 979 | "comment_num|1-500":20, 980 | "click_num|1-50":20, 981 | "is_top":0, 982 | "update_time":"1029-12-21" 983 | }, 984 | { 985 | "id":1, 986 | "title": "如何使用mockjs", 987 | "nick_name": "谭佳tanjjj", 988 | "plate_name":"学习版块", 989 | "update_time":"1029-12-21", 990 | "comment_num|1-500":20, 991 | "click_num|1-50":20, 992 | "is_top":0, 993 | "update_time":"1029-12-21" 994 | }, 995 | { 996 | "id":1, 997 | "title": "如何使用mockjs", 998 | "nick_name": "谭佳tanjjj", 999 | "plate_name":"学习版块", 1000 | "update_time":"1029-12-21", 1001 | "comment_num|1-500":20, 1002 | "click_num|1-50":20, 1003 | "is_top":0, 1004 | "update_time":"1029-12-21" 1005 | }, 1006 | { 1007 | "id":1, 1008 | "title": "如何使用mockjs", 1009 | "nick_name": "谭佳tanjjj", 1010 | "plate_name":"学习版块", 1011 | "update_time":"1029-12-21", 1012 | "comment_num|1-500":20, 1013 | "click_num|1-50":20, 1014 | "is_top":0, 1015 | "update_time":"1029-12-21" 1016 | }, 1017 | { 1018 | "id":1, 1019 | "title": "如何使用mockjs", 1020 | "nick_name": "谭佳tanjjj", 1021 | "plate_name":"学习版块", 1022 | "update_time":"1029-12-21", 1023 | "comment_num|1-500":20, 1024 | "click_num|1-50":20, 1025 | "is_top":0, 1026 | "update_time":"1029-12-21" 1027 | }, 1028 | { 1029 | "id":1, 1030 | "title": "如何使用mockjs", 1031 | "nick_name": "谭佳tanjjj", 1032 | "plate_name":"学习版块", 1033 | "update_time":"1029-12-21", 1034 | "comment_num|1-500":20, 1035 | "click_num|1-50":20, 1036 | "is_top":0, 1037 | "update_time":"1029-12-21" 1038 | } 1039 | ], 1040 | "searchcomment":[ 1041 | { 1042 | "id":1, 1043 | "topic_id":1, 1044 | "topic":"关于Vue.js", 1045 | "nick_name":"这是评论者", 1046 | "content":"这是评论的内容", 1047 | "comment_type":"1" 1048 | }, 1049 | { 1050 | "id":1, 1051 | "topic_id":1, 1052 | "topic":"第二篇文章", 1053 | "nick_name":"这是评论者", 1054 | "content":"这是评论的内容", 1055 | "comment_type":"1" 1056 | }, 1057 | { 1058 | "id":1, 1059 | "topic_id":1, 1060 | "topic":"第3篇文章", 1061 | "nick_name":"这是评论者", 1062 | "content":"这是评论的内容", 1063 | "comment_type":"1" 1064 | }, 1065 | { 1066 | "id":1, 1067 | "topic_id":1, 1068 | "topic":"第4篇文章", 1069 | "nick_name":"这是评论者", 1070 | "content":"这是评论的内容", 1071 | "comment_type":"1" 1072 | }, 1073 | { 1074 | "id":1, 1075 | "topic_id":1, 1076 | "topic":"第5篇文章", 1077 | "nick_name":"这是评论者", 1078 | "content":"这是评论的内容", 1079 | "comment_type":"1" 1080 | }, 1081 | { 1082 | "id":1, 1083 | "topic_id":1, 1084 | "topic":"第6篇文章", 1085 | "nick_name":"这是评论者", 1086 | "content":"这是评论的内容", 1087 | "comment_type":"1" 1088 | }, 1089 | { 1090 | "id":1, 1091 | "topic_id":1, 1092 | "topic":"第7篇文章", 1093 | "nick_name":"这是评论者", 1094 | "content":"这是评论的内容", 1095 | "comment_type":"1" 1096 | }, 1097 | { 1098 | "id":1, 1099 | "topic_id":1, 1100 | "topic":"第5篇文章", 1101 | "nick_name":"这是评论者", 1102 | "content":"这是评论的内容", 1103 | "comment_type":"1" 1104 | }, 1105 | { 1106 | "id":1, 1107 | "topic_id":1, 1108 | "topic":"贪贪贪", 1109 | "nick_name":"这是评论者", 1110 | "content":"这是评论的内容", 1111 | "comment_type":"1" 1112 | }, 1113 | { 1114 | "id":1, 1115 | "topic_id":1, 1116 | "topic":"贪贪贪", 1117 | "nick_name":"这是评论者", 1118 | "content":"这是评论的内容", 1119 | "comment_type":"1" 1120 | } 1121 | 1122 | ], 1123 | "login":{ 1124 | "status": 1, 1125 | "message": "登录成功", 1126 | "user_id":12 1127 | }, 1128 | "loginUser":{ 1129 | "nick_name":"TanJia", 1130 | "role_name":"管理员", 1131 | "plate_id":1, 1132 | "plate_name":"学习版块" 1133 | }, 1134 | "userArticleChart":{ 1135 | "xAxis":["2月","3月","4月","5月","6月"], 1136 | "yAxisUser":[1320, 3330, 1000, 2000, 932], 1137 | "yAxisArticle":[2320, 1430, 1100, 2090, 1932] 1138 | }, 1139 | "plateArticleChart":[ 1140 | {"value":135, "name":"学习"}, 1141 | {"value":310, "name":"生活"}, 1142 | {"value":234, "name":"跳蚤市场"}, 1143 | {"value":135, "name":"Vue"}, 1144 | {"value":548, "name":"SSM"} 1145 | ], 1146 | "allnumber":{ 1147 | "userNum":100, 1148 | "plateNum":10, 1149 | "articleNum":2308, 1150 | "commentNum":3223 1151 | }, 1152 | "newFive":{ 1153 | "newUser":[ 1154 | { 1155 | "id":1, 1156 | "nick_name":"tanj", 1157 | "update_time":"2019-05-29 10:17:55" 1158 | }, 1159 | { 1160 | "id":2, 1161 | "nick_name":"zhang", 1162 | "update_time":"2019-05-29 10:17:55" 1163 | }, 1164 | { 1165 | "id":3, 1166 | "nick_name":"dasudia", 1167 | "update_time":"2019-05-29 10:17:55" 1168 | }, 1169 | { 1170 | "id":4, 1171 | "nick_name":"gdfgdfg", 1172 | "update_time":"2019-05-29 10:17:55" 1173 | }, 1174 | { 1175 | "id":5, 1176 | "nick_name":"此阿姨们", 1177 | "update_time":"2019-05-29 10:17:55" 1178 | } 1179 | ], 1180 | "newPlate":[ 1181 | { 1182 | "id":1, 1183 | "plate_name":"学习", 1184 | "description":"这是学习的地方", 1185 | "update_time":"2019-05-29 10:17:55" 1186 | }, 1187 | { 1188 | "id":2, 1189 | "plate_name":"学习", 1190 | "description":"这是学习的地方", 1191 | "update_time":"2019-05-29 10:17:55" 1192 | }, 1193 | { 1194 | "id":3, 1195 | "plate_name":"学习", 1196 | "description":"这是学习的地方", 1197 | "update_time":"2019-05-29 10:17:55" 1198 | }, 1199 | { 1200 | "id":4, 1201 | "plate_name":"学习", 1202 | "description":"这是学习的地方", 1203 | "update_time":"2019-05-29 10:17:55" 1204 | }, 1205 | { 1206 | "id":5, 1207 | "plate_name":"学习", 1208 | "description":"这是学习的地方", 1209 | "update_time":"2019-05-29 10:17:55" 1210 | } 1211 | ], 1212 | "newArticle":[ 1213 | { 1214 | "id":1, 1215 | "title":"文章的标题", 1216 | "nick_name":"tanjiajia", 1217 | "update_time":"2019-05-29 10:17:55" 1218 | }, 1219 | { 1220 | "id":1, 1221 | "title":"文章的标题", 1222 | "nick_name":"tanjiajia", 1223 | "update_time":"2019-05-29 10:17:55" 1224 | }, 1225 | { 1226 | "id":1, 1227 | "title":"文章的标题", 1228 | "nick_name":"tanjiajia", 1229 | "update_time":"2019-05-29 10:17:55" 1230 | }, 1231 | { 1232 | "id":1, 1233 | "title":"文章的标题", 1234 | "nick_name":"tanjiajia", 1235 | "update_time":"2019-05-29 10:17:55" 1236 | }, 1237 | { 1238 | "id":1, 1239 | "title":"文章的标题", 1240 | "nick_name":"tanjiajia", 1241 | "update_time":"2019-05-29 10:17:55" 1242 | } 1243 | ] 1244 | }, 1245 | "plateUserPlateList":[ 1246 | { 1247 | "plate_name": "版主", 1248 | "id": 1, 1249 | "description|1-10":"版主版主版主", 1250 | "moderator_name|1-10":"213", 1251 | "update_time":"1029-12-21", 1252 | "postNum|1-1000":20 1253 | }, 1254 | { 1255 | "plate_name": "版主", 1256 | "id": 2, 1257 | "description|1-10":"版主版主版主", 1258 | "moderator_name|1-10":"213", 1259 | "update_time":"1029-12-21", 1260 | "postNum|1-1000":20 1261 | } 1262 | ], 1263 | "plateUserArticleList":[ 1264 | { 1265 | "id":1, 1266 | "title": "如何使用mockjs", 1267 | "nick_name": "谭佳", 1268 | "plate_name":"学习版块", 1269 | "update_time":"1029-12-21", 1270 | "comment_num|1-500":20, 1271 | "click_num|1-50":20, 1272 | "is_top":0, 1273 | "update_time":"1029-12-21" 1274 | }, 1275 | { 1276 | "id":1, 1277 | "title": "如何使用mockjs", 1278 | "nick_name": "谭佳", 1279 | "plate_name":"学习版块", 1280 | "update_time":"1029-12-21", 1281 | "comment_num|1-500":20, 1282 | "click_num|1-50":20, 1283 | "is_top":0, 1284 | "update_time":"1029-12-21" 1285 | }, 1286 | { 1287 | "id":1, 1288 | "title": "如何使用mockjs", 1289 | "nick_name": "谭佳", 1290 | "plate_name":"学习版块", 1291 | "update_time":"1029-12-21", 1292 | "comment_num|1-500":20, 1293 | "click_num|1-50":20, 1294 | "is_top":0, 1295 | "update_time":"1029-12-21" 1296 | }, 1297 | { 1298 | "id":1, 1299 | "title": "如何使用mockjs", 1300 | "nick_name": "谭佳", 1301 | "plate_name":"学习版块", 1302 | "update_time":"1029-12-21", 1303 | "comment_num|1-500":20, 1304 | "click_num|1-50":20, 1305 | "is_top":0, 1306 | "update_time":"1029-12-21" 1307 | }, 1308 | { 1309 | "id":1, 1310 | "title": "如何使用mockjs", 1311 | "nick_name": "谭佳", 1312 | "plate_name":"学习版块", 1313 | "update_time":"1029-12-21", 1314 | "comment_num|1-500":20, 1315 | "click_num|1-50":20, 1316 | "is_top":0, 1317 | "update_time":"1029-12-21" 1318 | }, 1319 | { 1320 | "id":1, 1321 | "title": "如何使用mockjs", 1322 | "nick_name": "谭佳", 1323 | "plate_name":"学习版块", 1324 | "update_time":"1029-12-21", 1325 | "comment_num|1-500":20, 1326 | "click_num|1-50":20, 1327 | "is_top":0, 1328 | "update_time":"1029-12-21" 1329 | }, 1330 | { 1331 | "id":1, 1332 | "title": "如何使用mockjs", 1333 | "nick_name": "谭佳", 1334 | "plate_name":"学习版块", 1335 | "update_time":"1029-12-21", 1336 | "comment_num|1-500":20, 1337 | "click_num|1-50":20, 1338 | "is_top":0, 1339 | "update_time":"1029-12-21" 1340 | }, 1341 | { 1342 | "id":1, 1343 | "title": "如何使用mockjs", 1344 | "nick_name": "谭佳", 1345 | "plate_name":"学习版块", 1346 | "update_time":"1029-12-21", 1347 | "comment_num|1-500":20, 1348 | "click_num|1-50":20, 1349 | "is_top":0, 1350 | "update_time":"1029-12-21" 1351 | }, 1352 | { 1353 | "id":1, 1354 | "title": "如何使用mockjs", 1355 | "nick_name": "谭佳", 1356 | "plate_name":"学习版块", 1357 | "update_time":"1029-12-21", 1358 | "comment_num|1-500":20, 1359 | "click_num|1-50":20, 1360 | "is_top":0, 1361 | "update_time":"1029-12-21" 1362 | }, 1363 | { 1364 | "id":1, 1365 | "title": "如何使用mockjs", 1366 | "nick_name": "谭佳", 1367 | "plate_name":"学习版块", 1368 | "update_time":"1029-12-21", 1369 | "comment_num|1-500":20, 1370 | "click_num|1-50":20, 1371 | "is_top":0, 1372 | "update_time":"1029-12-21" 1373 | }, 1374 | { 1375 | "id":1, 1376 | "title": "如何使用mockjs", 1377 | "nick_name": "谭佳", 1378 | "plate_name":"学习版块", 1379 | "update_time":"1029-12-21", 1380 | "comment_num|1-500":20, 1381 | "click_num|1-50":20, 1382 | "is_top":0, 1383 | "update_time":"1029-12-21" 1384 | }, 1385 | { 1386 | "id":1, 1387 | "title": "如何使用mockjs", 1388 | "nick_name": "谭佳", 1389 | "plate_name":"学习版块", 1390 | "update_time":"1029-12-21", 1391 | "comment_num|1-500":20, 1392 | "click_num|1-50":20, 1393 | "is_top":0, 1394 | "update_time":"1029-12-21" 1395 | }, 1396 | { 1397 | "id":1, 1398 | "title": "如何使用mockjs", 1399 | "nick_name": "谭佳", 1400 | "plate_name":"学习版块", 1401 | "update_time":"1029-12-21", 1402 | "comment_num|1-500":20, 1403 | "click_num|1-50":20, 1404 | "is_top":0, 1405 | "update_time":"1029-12-21" 1406 | }, 1407 | { 1408 | "id":1, 1409 | "title": "如何使用mockjs", 1410 | "nick_name": "谭佳", 1411 | "plate_name":"学习版块", 1412 | "update_time":"1029-12-21", 1413 | "comment_num|1-500":20, 1414 | "click_num|1-50":20, 1415 | "is_top":0, 1416 | "update_time":"1029-12-21" 1417 | }, 1418 | { 1419 | "id":1, 1420 | "title": "如何使用mockjs", 1421 | "nick_name": "谭佳", 1422 | "plate_name":"学习版块", 1423 | "update_time":"1029-12-21", 1424 | "comment_num|1-500":20, 1425 | "click_num|1-50":20, 1426 | "is_top":0, 1427 | "update_time":"1029-12-21" 1428 | }, 1429 | { 1430 | "id":1, 1431 | "title": "如何使用mockjs", 1432 | "nick_name": "谭佳", 1433 | "plate_name":"学习版块", 1434 | "update_time":"1029-12-21", 1435 | "comment_num|1-500":20, 1436 | "click_num|1-50":20, 1437 | "is_top":0, 1438 | "update_time":"1029-12-21" 1439 | }, 1440 | { 1441 | "id":1, 1442 | "title": "如何使用mockjs", 1443 | "nick_name": "谭佳", 1444 | "plate_name":"学习版块", 1445 | "update_time":"1029-12-21", 1446 | "comment_num|1-500":20, 1447 | "click_num|1-50":20, 1448 | "is_top":0, 1449 | "update_time":"1029-12-21" 1450 | } 1451 | 1452 | ], 1453 | "plateUserCommontList":[ 1454 | { 1455 | "id":1, 1456 | "topic_id":1, 1457 | "topic":"这是文章的标题", 1458 | "nick_name":"这是评论者", 1459 | "content":"这是评论的内容", 1460 | "comment_type":"1" 1461 | }, 1462 | { 1463 | "id":1, 1464 | "topic_id":1, 1465 | "topic":"这是文章的标题", 1466 | "nick_name":"这是评论者", 1467 | "content":"这是评论的内容", 1468 | "comment_type":"1" 1469 | }, 1470 | { 1471 | "id":1, 1472 | "topic_id":1, 1473 | "topic":"这是文章的标题", 1474 | "nick_name":"这是评论者", 1475 | "content":"这是评论的内容", 1476 | "comment_type":"1" 1477 | }, 1478 | { 1479 | "id":1, 1480 | "topic_id":1, 1481 | "topic":"这是文章的标题", 1482 | "nick_name":"这是评论者", 1483 | "content":"这是评论的内容", 1484 | "comment_type":"1" 1485 | }, 1486 | { 1487 | "id":1, 1488 | "topic_id":1, 1489 | "topic":"这是文章的标题", 1490 | "nick_name":"这是评论者", 1491 | "content":"这是评论的内容", 1492 | "comment_type":"1" 1493 | }, 1494 | { 1495 | "id":1, 1496 | "topic_id":1, 1497 | "topic":"这是文章的标题", 1498 | "nick_name":"这是评论者", 1499 | "content":"这是评论的内容", 1500 | "comment_type":"1" 1501 | }, 1502 | { 1503 | "id":1, 1504 | "topic_id":1, 1505 | "topic":"这是文章的标题", 1506 | "nick_name":"这是评论者", 1507 | "content":"这是评论的内容", 1508 | "comment_type":"1" 1509 | }, 1510 | { 1511 | "id":1, 1512 | "topic_id":1, 1513 | "topic":"这是文章的标题", 1514 | "nick_name":"这是评论者", 1515 | "content":"这是评论的内容", 1516 | "comment_type":"1" 1517 | }, 1518 | { 1519 | "id":1, 1520 | "topic_id":1, 1521 | "topic":"这是文章的标题", 1522 | "nick_name":"这是评论者", 1523 | "content":"这是评论的内容", 1524 | "comment_type":"1" 1525 | }, 1526 | { 1527 | "id":1, 1528 | "topic_id":1, 1529 | "topic":"这是文章的标题", 1530 | "nick_name":"这是评论者", 1531 | "content":"这是评论的内容", 1532 | "comment_type":"1" 1533 | } 1534 | , { 1535 | "id":1, 1536 | "topic_id":1, 1537 | "topic":"这是文章的标题", 1538 | "nick_name":"这是评论者", 1539 | "content":"这是评论的内容", 1540 | "comment_type":"1" 1541 | } 1542 | ], 1543 | "allplatename":[ 1544 | { 1545 | "id":"1", 1546 | "plate_name":"学习" 1547 | }, 1548 | { 1549 | "id":"2", 1550 | "plate_name":"生活" 1551 | }, 1552 | { 1553 | "id":"3", 1554 | "plate_name":"学习" 1555 | }, 1556 | { 1557 | "id":"4", 1558 | "plate_name":"学习" 1559 | }, 1560 | { 1561 | "id":"5", 1562 | "plate_name":"学习" 1563 | }, 1564 | { 1565 | "id":"6", 1566 | "plate_name":"学习" 1567 | } 1568 | ] 1569 | } 1570 | -------------------------------------------------------------------------------- /src/mock/mockServer.js: -------------------------------------------------------------------------------- 1 | //使用mock.js提供mock数据接口 2 | import Mock from 'mockjs' 3 | import data from './data.json' 4 | 5 | 6 | Mock.mock('/users/list?pageNum=1',data.users) 7 | 8 | Mock.mock(`/homepage/userArticleChart`,data.userArticleChart) 9 | Mock.mock(`/homepage/plateArticleChart`,data.plateArticleChart) 10 | Mock.mock(`/homepage/number`,data.allnumber) 11 | Mock.mock(`/homepage/newFive`,data.newFive) 12 | 13 | Mock.mock('/users/toplateuser',data.plateUserList) 14 | 15 | Mock.mock('/plates/list?pageNum=1',data.plates) 16 | Mock.mock('/plates/list?pageNum=2',data.plates2) 17 | Mock.mock('/plates/list?pageNum=3',data.plates3) 18 | Mock.mock('/plates/list?pageNum=4',data.plates4) 19 | Mock.mock('/plates/list?pageNum=5',data.plates5) 20 | 21 | Mock.mock('/articles/list',data.articles) 22 | 23 | Mock.mock('/commons/list',data.comments) 24 | 25 | Mock.mock('/plates/addplate' ,data.addplate) 26 | Mock.mock('/plates/allplatename' ,data.allplatename) 27 | 28 | Mock.mock('/users/adduser' ,data.adduser) 29 | 30 | Mock.mock(RegExp('/users/userdetail/' + ".*") ,data.userdetail) 31 | //应该使用正则表达式 32 | 33 | Mock.mock(RegExp('/plates/platedetail/'+'.*') ,data.platedetail) 34 | //应该使用正则表达式 35 | 36 | // Mock.mock('/plates/editplate/1',data.editplate) 37 | Mock.mock(RegExp('/plates/editplate/'+'.*'),data.editplate) 38 | //不需要向外暴露任何数据,只需要保证执行即可 39 | 40 | Mock.mock(RegExp('/plates/deleteplate/'+'.*'),data.delete) 41 | 42 | Mock.mock(RegExp('/plates/deleteplate/'+'.*'),data.delete) 43 | Mock.mock(RegExp('/users/logout'+'.*'),data.delete) 44 | 45 | Mock.mock(RegExp('/users/deleteuser/'+'.*'),data.delete) 46 | 47 | Mock.mock(RegExp('/users/deleteusers/'+'.*'),data.delete) 48 | 49 | Mock.mock(RegExp('/plates/noplateuser/'+'.*'),data.noplateuser) 50 | 51 | Mock.mock(RegExp('/comments/deletecomment/'+'.*'),data.delete) 52 | 53 | Mock.mock(RegExp('/users/edituserinfo/'+'.*'),data.delete) 54 | 55 | Mock.mock(RegExp('/comments/deletecomments/'+'.*'),data.delete) 56 | 57 | Mock.mock("/articles/addcomment",data.delete) 58 | 59 | Mock.mock(RegExp('/plates/searchplate'+'.*'),data.searchplate) 60 | 61 | Mock.mock(RegExp('/users/searchuser'+'.*'),data.searchuser) 62 | 63 | Mock.mock(RegExp('/articles/searcharticle'+'.*'),data.searcharticle) 64 | 65 | Mock.mock(RegExp('/comments/searchcomment'+'.*'),data.searchcomment) 66 | 67 | Mock.mock(RegExp('/articles/articledetail'+'.*'),data.articleDetail) 68 | 69 | Mock.mock(RegExp('/articles/deletearticle'+'.*'),data.delete) 70 | 71 | Mock.mock(RegExp('/plates/deletearticles'+'.*'),data.delete) 72 | 73 | Mock.mock(RegExp('/users/loginuserinfo'+'.*'),data.loginUser) 74 | 75 | Mock.mock(RegExp('/plates/plateUserPlateList'+'.*'),data.plateUserPlateList) 76 | Mock.mock(RegExp('/articles/plateUserArticleList'+'.*'),data.plateUserArticleList) 77 | Mock.mock(RegExp('/comments/plateUserCommontList'+'.*'),data.plateUserCommontList) 78 | 79 | Mock.mock('/users/login',data.login) 80 | 81 | -------------------------------------------------------------------------------- /src/pages/Article/Article.vue: -------------------------------------------------------------------------------- 1 | 74 | 75 | 217 | 218 | 237 | -------------------------------------------------------------------------------- /src/pages/Article/ArticleDetail/ArticleDetail.vue: -------------------------------------------------------------------------------- 1 | 66 | 67 | 151 | 152 | 258 | -------------------------------------------------------------------------------- /src/pages/Comment/Comment.vue: -------------------------------------------------------------------------------- 1 | 58 | 59 | 196 | 197 | 206 | -------------------------------------------------------------------------------- /src/pages/HomePage/HomePage.vue: -------------------------------------------------------------------------------- 1 | 182 | 183 | 308 | 309 | 445 | -------------------------------------------------------------------------------- /src/pages/HomePage/img/art.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TanJ2014/vue-element-blog-admin/1ab53bb59cea70215d941881c8c8b12c7a79cace/src/pages/HomePage/img/art.png -------------------------------------------------------------------------------- /src/pages/HomePage/img/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TanJ2014/vue-element-blog-admin/1ab53bb59cea70215d941881c8c8b12c7a79cace/src/pages/HomePage/img/comment.png -------------------------------------------------------------------------------- /src/pages/HomePage/img/plate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TanJ2014/vue-element-blog-admin/1ab53bb59cea70215d941881c8c8b12c7a79cace/src/pages/HomePage/img/plate.png -------------------------------------------------------------------------------- /src/pages/HomePage/img/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TanJ2014/vue-element-blog-admin/1ab53bb59cea70215d941881c8c8b12c7a79cace/src/pages/HomePage/img/user.png -------------------------------------------------------------------------------- /src/pages/Login/Login.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 87 | 88 | 139 | -------------------------------------------------------------------------------- /src/pages/Plate/AddPlate/AddPlate.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 83 | 84 | 88 | -------------------------------------------------------------------------------- /src/pages/Plate/EditPlate/EditPlate.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 81 | 82 | 85 | -------------------------------------------------------------------------------- /src/pages/Plate/Plate.vue: -------------------------------------------------------------------------------- 1 | 59 | 60 | 204 | 205 | 230 | -------------------------------------------------------------------------------- /src/pages/Plate/PlateDetail/PlateDetail.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 48 | 49 | 77 | -------------------------------------------------------------------------------- /src/pages/System/System.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 108 | 109 | 114 | -------------------------------------------------------------------------------- /src/pages/User/AddUser/AddUser.vue: -------------------------------------------------------------------------------- 1 | 38 | 39 | 106 | 107 | 110 | -------------------------------------------------------------------------------- /src/pages/User/EditUser/EditUser.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 140 | 141 | 144 | -------------------------------------------------------------------------------- /src/pages/User/User.vue: -------------------------------------------------------------------------------- 1 | 65 | 66 | 219 | 220 | 242 | -------------------------------------------------------------------------------- /src/pages/User/UserDetail/UserDetail.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 56 | 57 | 92 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | 4 | import Plate from '../pages/Plate/Plate.vue' 5 | import HomePage from '../pages/HomePage/HomePage.vue' 6 | import User from '../pages/User/User.vue' 7 | import System from '../pages/System/System.vue' 8 | import Article from '../pages/Article/Article.vue' 9 | import Comment from '../pages/Comment/Comment.vue' 10 | import ArticleDetail from '../pages/Article/ArticleDetail/ArticleDetail.vue' 11 | import EditPlate from '../pages/Plate/EditPlate/EditPlate.vue' 12 | import AddPlate from '../pages/Plate/AddPlate/AddPlate.vue' 13 | import PlateDetail from '../pages/Plate/PlateDetail/PlateDetail.vue' 14 | import AddUser from '../pages/User/AddUser/AddUser.vue' 15 | import EditUser from '../pages/User/EditUser/EditUser.vue' 16 | import UserDetail from '../pages/User/UserDetail/UserDetail.vue' 17 | import Login from '../pages/Login/Login.vue' 18 | 19 | Vue.use(Router) 20 | 21 | export default new Router({ 22 | routes: [ 23 | { 24 | path:'/login', 25 | component: Login, 26 | meta:{ 27 | NoShowLeftMenu:true, 28 | NoShowHeader:true 29 | } 30 | }, 31 | { 32 | path:'/', 33 | redirect: '/login' 34 | }, 35 | { 36 | path:'/plate', 37 | name:'plate', 38 | component: Plate, 39 | meta:{ 40 | title:'版块管理' 41 | }, 42 | children:[ 43 | { 44 | path:'editPlate/:plateid', 45 | component:EditPlate, 46 | meta:{ 47 | title:'编辑版块' 48 | } 49 | }, 50 | { 51 | path:'addPlate', 52 | component:AddPlate, 53 | meta:{ 54 | title:'新增版块' 55 | } 56 | }, 57 | { 58 | path:'plateDetail/:plateid', 59 | component:PlateDetail, 60 | meta:{ 61 | title:'版块详情' 62 | } 63 | }, 64 | ] 65 | }, 66 | { 67 | path:'/homepage', 68 | name:'homepage', 69 | component: HomePage, 70 | meta:{ 71 | title:'首页', 72 | } 73 | }, 74 | { 75 | path:'/comment', 76 | name:'comment', 77 | component: Comment, 78 | meta:{ 79 | title:'评论管理' 80 | } 81 | }, 82 | { 83 | path:'/user', 84 | name:'user', 85 | component: User, 86 | meta:{ 87 | title:'用户管理' 88 | }, 89 | children:[ 90 | { 91 | path: 'adduser', 92 | component: AddUser, 93 | meta: { 94 | title: '添加用户' 95 | } 96 | }, 97 | { 98 | path:'edituser/:userid', 99 | component:EditUser, 100 | meta:{ 101 | title:'编辑用户' 102 | } 103 | }, 104 | { 105 | path:'userdetail/:userid', 106 | component:UserDetail, 107 | meta:{ 108 | title:'查看用户信息' 109 | } 110 | } 111 | ] 112 | 113 | }, 114 | // { 115 | // path:'/system', 116 | // name:'system', 117 | // component: System, 118 | // meta:{ 119 | // title:'系统设置' 120 | // } 121 | // }, 122 | { 123 | path:'/article', 124 | name:'article', 125 | component: Article, 126 | meta:{ 127 | title:'文章管理' 128 | }, 129 | children:[ 130 | { 131 | path:'articleDetail/:articleid', 132 | component: ArticleDetail, 133 | meta:{ 134 | title:'文章详情' 135 | } 136 | } 137 | ] 138 | } 139 | ] 140 | }) 141 | -------------------------------------------------------------------------------- /src/store/actions.js: -------------------------------------------------------------------------------- 1 | import { 2 | RECEIVE_USERLIST, 3 | RECEIVE_PLATELIST, 4 | RECEIVE_ARTICLELIST, 5 | RECORD_USERID, 6 | RECEIVE_COMMONLIST, 7 | RECEIVE_LOGINUSER, 8 | RECEIVE_PLATEUSERCOMMONLIST, 9 | RECEIVE_PLATEUSERARTICLELIST, 10 | RECEIVE_PLATEUSERPLATELIST, 11 | RECEIVE_PLATENAMES, 12 | RECEIVE_TOPLATEUSER, 13 | } from "./mutation-types" 14 | import { 15 | reqUserList, 16 | reqPlateList, 17 | reqArticleList, 18 | reqLogin, 19 | reqCommentList, 20 | reqLoginUserInfo, 21 | reqPlateUserArticleList, 22 | reqPlateUserCommontList, 23 | reqPlateUserPlateList, 24 | reqAllPlateName, 25 | reqPlateUserList 26 | } from "../api/index" 27 | 28 | export default { 29 | //获取用户列表 30 | async getToPlateUser({commit}){ 31 | const result = await reqPlateUserList() 32 | console.log("res0"+result) 33 | commit(RECEIVE_TOPLATEUSER,result) 34 | }, 35 | //获取版块列表 36 | // async getPlateList({commit},pageNum){ 37 | // const result = await reqPlateList(pageNum) 38 | // commit(RECEIVE_PLATELIST,result) 39 | // }, 40 | //获取版块列表 41 | async getAllPlateName({commit}){ 42 | const result = await reqAllPlateName() 43 | commit(RECEIVE_PLATENAMES,result) 44 | }, 45 | //根据版主id返回所管理的版块列表 46 | async getPlateUserPlateList({commit},user_id){ 47 | const result = await reqPlateUserPlateList(user_id) 48 | commit(RECEIVE_PLATEUSERPLATELIST,result) 49 | }, 50 | //获取文章列表 51 | // async getArticleList({commit}){ 52 | // const result = await reqArticleList() 53 | // commit(RECEIVE_ARTICLELIST,result) 54 | // }, 55 | //根据版主id返回所管理的文章列表 56 | async getPlateUserArticleList({commit},data){ 57 | const result = await reqPlateUserArticleList(data.user_id,data.pageNum) 58 | commit(RECEIVE_PLATEUSERARTICLELIST,result) 59 | }, 60 | //获取评论列表 61 | // async getCommentList({commit}){ 62 | // const result = await reqCommentList() 63 | // commit(RECEIVE_COMMONLIST,result) 64 | // }, 65 | //根据版主id返回所管理的评论列表 66 | async getPlateUserCommontList({commit},user_id){ 67 | const result = await reqPlateUserCommontList(user_id) 68 | commit(RECEIVE_PLATEUSERCOMMONLIST,result) 69 | }, 70 | //用户登录系统 71 | async getLoginUserId({commit},{nick_name,password,callback}){ 72 | const result = await reqLogin(nick_name,password) 73 | console.log(result) 74 | commit(RECORD_USERID,result.user_id) 75 | callback&&callback() 76 | }, 77 | 78 | //记录当前用户的信息 79 | async getLoginUserInfo({commit},userid){ 80 | const result = await reqLoginUserInfo(userid) 81 | commit(RECEIVE_LOGINUSER,result) 82 | }, 83 | 84 | } 85 | 86 | --------------------------------------------------------------------------------