├── .babelrc
├── .editorconfig
├── .gitignore
├── .postcssrc.js
├── README.md
├── build
├── build.js
├── check-versions.js
├── dev-client.js
├── dev-server.js
├── 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
├── imgs
├── edit-goods.jpg
├── goods-detail.jpg
├── goods-list.png
├── order-detail.jpg
└── order-list.jpg
├── index.html
├── package.json
├── src
├── App.vue
├── base
│ └── goods-menu
│ │ └── goods-menu.vue
├── common
│ ├── image
│ │ └── logo.png
│ ├── js
│ │ ├── Axios.js
│ │ ├── mixins.js
│ │ └── setTitle.js
│ └── scss
│ │ ├── index.scss
│ │ ├── mixins.scss
│ │ ├── normalize.scss
│ │ ├── utility.scss
│ │ └── variables.scss
├── components
│ ├── goods
│ │ ├── goods-detail
│ │ │ ├── edit-comment-layout.vue
│ │ │ ├── goods-comment-layout.vue
│ │ │ └── goods-detail.vue
│ │ └── goods-list
│ │ │ ├── goods-list.vue
│ │ │ └── goods-table-layout.vue
│ ├── login
│ │ └── login.vue
│ └── order
│ │ ├── order-detail
│ │ ├── edit-goods-layout.vue
│ │ ├── order-detail.vue
│ │ ├── order-table-layout.vue
│ │ └── other-goods-layout.vue
│ │ └── order-list
│ │ └── order-list.vue
├── main.js
├── router
│ └── index.js
└── store
│ ├── actions.js
│ ├── getters.js
│ ├── index.js
│ ├── mutation-types.js
│ ├── mutations.js
│ └── state.js
└── static
└── .gitkeep
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", {
4 | "modules": false,
5 | "targets": {
6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
7 | }
8 | }],
9 | "stage-2"
10 | ],
11 | "plugins": ["transform-runtime"],
12 | "env": {
13 | "test": {
14 | "presets": ["env", "stage-2"],
15 | "plugins": ["istanbul"]
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Editor directories and files
9 | .idea
10 | *.suo
11 | *.ntvs*
12 | *.njsproj
13 | *.sln
14 |
--------------------------------------------------------------------------------
/.postcssrc.js:
--------------------------------------------------------------------------------
1 | // https://github.com/michael-ciniawsky/postcss-load-config
2 |
3 | module.exports = {
4 | "plugins": {
5 | // to edit target browsers: use "browserslist" field in package.json
6 | "autoprefixer": {}
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # order-admin
2 |
3 | > 用 Vue 全家桶搭建的商品订单管理后台系统
4 |
5 | ## 本地启动项目
6 | ```bash
7 | npm install
8 | npm start
9 | ```
10 | - 测试账号/密码:test/1
11 |
12 | ## 技术栈
13 | - Vue 2.0
14 | - vue-router
15 | - Vuex
16 | - Axios
17 | - Element-UI
18 | - ES6 && ES7
19 | - Sass
20 |
21 | ## 网站功能
22 | 主要是对订单和商品的管理,所以项目分为订单和商品两个部分
23 | ### 一. 订单
24 | ##### 订单列表页
25 | - 展示订单列表,并分页
26 | - 搜索订单功能
27 | - 添加订单功能
28 | ##### 订单详情页
29 | - 给订单添加/修改备注功能
30 | - 删除订单里的商品功能
31 | - 增加/减少订单里的某个商品数量和利润,并动态计算总额
32 | - 第三方商品的增删改查/上传图片功能
33 | ### 二. 商品
34 | ##### 商品列表页
35 | - 点击商品菜单动态展示商品
36 | - 搜索商品/按颜色筛选商品
37 | - 商品分页
38 | - 指定商品选择不同颜色功能
39 | - 添加商品到订单功能
40 | ##### 商品详情页
41 | - 商品详情展示
42 | - 商品评论的增删改查/上传图片功能/商品评分功能
43 |
44 |
45 | ## 网站部分展示
46 | ### 订单列表页
47 | 
48 |
49 | ### 订单详情页
50 | 
51 |
52 | ### 商品列表页
53 | 
54 |
55 | ### 商品详情页
56 | 
57 |
58 | ### 编辑商品页
59 | 
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/build/build.js:
--------------------------------------------------------------------------------
1 | require('./check-versions')()
2 |
3 | process.env.NODE_ENV = 'production'
4 |
5 | var ora = require('ora')
6 | var rm = require('rimraf')
7 | var path = require('path')
8 | var chalk = require('chalk')
9 | var webpack = require('webpack')
10 | var config = require('../config')
11 | var webpackConfig = require('./webpack.prod.conf')
12 |
13 | var spinner = ora('building for production...')
14 | spinner.start()
15 |
16 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
17 | if (err) throw err
18 | webpack(webpackConfig, function (err, stats) {
19 | spinner.stop()
20 | if (err) throw err
21 | process.stdout.write(stats.toString({
22 | colors: true,
23 | modules: false,
24 | children: false,
25 | chunks: false,
26 | chunkModules: false
27 | }) + '\n\n')
28 |
29 | console.log(chalk.cyan(' Build complete.\n'))
30 | console.log(chalk.yellow(
31 | ' Tip: built files are meant to be served over an HTTP server.\n' +
32 | ' Opening index.html over file:// won\'t work.\n'
33 | ))
34 | })
35 | })
36 |
--------------------------------------------------------------------------------
/build/check-versions.js:
--------------------------------------------------------------------------------
1 | var chalk = require('chalk')
2 | var semver = require('semver')
3 | var packageConfig = require('../package.json')
4 | var shell = require('shelljs')
5 | function exec (cmd) {
6 | return require('child_process').execSync(cmd).toString().trim()
7 | }
8 |
9 | var versionRequirements = [
10 | {
11 | name: 'node',
12 | currentVersion: semver.clean(process.version),
13 | versionRequirement: packageConfig.engines.node
14 | },
15 | ]
16 |
17 | if (shell.which('npm')) {
18 | versionRequirements.push({
19 | name: 'npm',
20 | currentVersion: exec('npm --version'),
21 | versionRequirement: packageConfig.engines.npm
22 | })
23 | }
24 |
25 | module.exports = function () {
26 | var warnings = []
27 | for (var i = 0; i < versionRequirements.length; i++) {
28 | var mod = versionRequirements[i]
29 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
30 | warnings.push(mod.name + ': ' +
31 | chalk.red(mod.currentVersion) + ' should be ' +
32 | chalk.green(mod.versionRequirement)
33 | )
34 | }
35 | }
36 |
37 | if (warnings.length) {
38 | console.log('')
39 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
40 | console.log()
41 | for (var i = 0; i < warnings.length; i++) {
42 | var warning = warnings[i]
43 | console.log(' ' + warning)
44 | }
45 | console.log()
46 | process.exit(1)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/build/dev-client.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | require('eventsource-polyfill')
3 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
4 |
5 | hotClient.subscribe(function (event) {
6 | if (event.action === 'reload') {
7 | window.location.reload()
8 | }
9 | })
10 |
--------------------------------------------------------------------------------
/build/dev-server.js:
--------------------------------------------------------------------------------
1 | require('./check-versions')()
2 |
3 | var config = require('../config')
4 | if (!process.env.NODE_ENV) {
5 | process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
6 | }
7 |
8 | var opn = require('opn')
9 | var path = require('path')
10 | var express = require('express')
11 | var webpack = require('webpack')
12 | var proxyMiddleware = require('http-proxy-middleware')
13 | var webpackConfig = require('./webpack.dev.conf')
14 |
15 | // default port where dev server listens for incoming traffic
16 | var port = process.env.PORT || config.dev.port
17 | // automatically open browser, if not set will be false
18 | var autoOpenBrowser = !!config.dev.autoOpenBrowser
19 | // Define HTTP proxies to your custom API backend
20 | // https://github.com/chimurai/http-proxy-middleware
21 | var proxyTable = config.dev.proxyTable
22 |
23 | var app = express()
24 | var compiler = webpack(webpackConfig)
25 |
26 | var devMiddleware = require('webpack-dev-middleware')(compiler, {
27 | publicPath: webpackConfig.output.publicPath,
28 | quiet: true
29 | })
30 |
31 | var hotMiddleware = require('webpack-hot-middleware')(compiler, {
32 | log: false,
33 | heartbeat: 2000
34 | })
35 | // force page reload when html-webpack-plugin template changes
36 | compiler.plugin('compilation', function (compilation) {
37 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
38 | hotMiddleware.publish({ action: 'reload' })
39 | cb()
40 | })
41 | })
42 |
43 | // proxy api requests
44 | Object.keys(proxyTable).forEach(function (context) {
45 | var options = proxyTable[context]
46 | if (typeof options === 'string') {
47 | options = { target: options }
48 | }
49 | app.use(proxyMiddleware(options.filter || context, options))
50 | })
51 |
52 | // handle fallback for HTML5 history API
53 | app.use(require('connect-history-api-fallback')())
54 |
55 | // serve webpack bundle output
56 | app.use(devMiddleware)
57 |
58 | // enable hot-reload and state-preserving
59 | // compilation error display
60 | app.use(hotMiddleware)
61 |
62 | // serve pure static assets
63 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
64 | app.use(staticPath, express.static('./static'))
65 |
66 | var uri = 'http://localhost:' + port
67 |
68 | var _resolve
69 | var readyPromise = new Promise(resolve => {
70 | _resolve = resolve
71 | })
72 |
73 | console.log('> Starting dev server...')
74 | devMiddleware.waitUntilValid(() => {
75 | console.log('> Listening at ' + uri + '\n')
76 | // when env is testing, don't need open it
77 | if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
78 | opn(uri)
79 | }
80 | _resolve()
81 | })
82 |
83 | var server = app.listen(port)
84 |
85 | module.exports = {
86 | ready: readyPromise,
87 | close: () => {
88 | server.close()
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/build/utils.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var config = require('../config')
3 | var ExtractTextPlugin = require('extract-text-webpack-plugin')
4 |
5 | exports.assetsPath = function (_path) {
6 | var assetsSubDirectory = process.env.NODE_ENV === 'production'
7 | ? config.build.assetsSubDirectory
8 | : config.dev.assetsSubDirectory
9 | return path.posix.join(assetsSubDirectory, _path)
10 | }
11 |
12 | exports.cssLoaders = function (options) {
13 | options = options || {}
14 |
15 | var cssLoader = {
16 | loader: 'css-loader',
17 | options: {
18 | minimize: process.env.NODE_ENV === 'production',
19 | sourceMap: options.sourceMap
20 | }
21 | }
22 |
23 | // generate loader string to be used with extract text plugin
24 | function generateLoaders (loader, loaderOptions) {
25 | var loaders = [cssLoader]
26 | if (loader) {
27 | loaders.push({
28 | loader: loader + '-loader',
29 | options: Object.assign({}, loaderOptions, {
30 | sourceMap: options.sourceMap
31 | })
32 | })
33 | }
34 |
35 | // Extract CSS when that option is specified
36 | // (which is the case during production build)
37 | if (options.extract) {
38 | return ExtractTextPlugin.extract({
39 | use: loaders,
40 | fallback: 'vue-style-loader'
41 | })
42 | } else {
43 | return ['vue-style-loader'].concat(loaders)
44 | }
45 | }
46 |
47 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html
48 | return {
49 | css: generateLoaders(),
50 | postcss: generateLoaders(),
51 | less: generateLoaders('less'),
52 | sass: generateLoaders('sass', { indentedSyntax: true }),
53 | scss: generateLoaders('sass'),
54 | stylus: generateLoaders('stylus'),
55 | styl: generateLoaders('stylus')
56 | }
57 | }
58 |
59 | // Generate loaders for standalone style files (outside of .vue)
60 | exports.styleLoaders = function (options) {
61 | var output = []
62 | var loaders = exports.cssLoaders(options)
63 | for (var extension in loaders) {
64 | var loader = loaders[extension]
65 | output.push({
66 | test: new RegExp('\\.' + extension + '$'),
67 | use: loader
68 | })
69 | }
70 | return output
71 | }
72 |
--------------------------------------------------------------------------------
/build/vue-loader.conf.js:
--------------------------------------------------------------------------------
1 | var utils = require('./utils')
2 | var config = require('../config')
3 | var isProduction = process.env.NODE_ENV === 'production'
4 |
5 | module.exports = {
6 | loaders: utils.cssLoaders({
7 | sourceMap: isProduction
8 | ? config.build.productionSourceMap
9 | : config.dev.cssSourceMap,
10 | extract: isProduction
11 | }),
12 | transformToRequire: {
13 | video: 'src',
14 | source: 'src',
15 | img: 'src',
16 | image: 'xlink:href'
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/build/webpack.base.conf.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var utils = require('./utils')
3 | var config = require('../config')
4 | var vueLoaderConfig = require('./vue-loader.conf')
5 |
6 | function resolve (dir) {
7 | return path.join(__dirname, '..', dir)
8 | }
9 |
10 | module.exports = {
11 | entry: {
12 | app: './src/main.js'
13 | },
14 | output: {
15 | path: config.build.assetsRoot,
16 | filename: '[name].js',
17 | publicPath: process.env.NODE_ENV === 'production'
18 | ? config.build.assetsPublicPath
19 | : config.dev.assetsPublicPath
20 | },
21 | resolve: {
22 | extensions: ['.js', '.vue', '.json'],
23 | alias: {
24 | 'common': resolve('src/common'),
25 | 'goods': resolve('src/components/goods'),
26 | 'order': resolve('src/components/order'),
27 | 'login': resolve('src/components/login'),
28 | 'base': resolve('src/base'),
29 | 'store': resolve('src/store'),
30 | }
31 | },
32 | module: {
33 | rules: [
34 | {
35 | test: /\.vue$/,
36 | loader: 'vue-loader',
37 | options: vueLoaderConfig
38 | },
39 | {
40 | test: /\.js$/,
41 | loader: 'babel-loader',
42 | include: [resolve('src'), resolve('test')]
43 | },
44 | {
45 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
46 | loader: 'url-loader',
47 | options: {
48 | limit: 10000,
49 | name: utils.assetsPath('img/[name].[hash:7].[ext]')
50 | }
51 | },
52 | {
53 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
54 | loader: 'url-loader',
55 | options: {
56 | limit: 10000,
57 | name: utils.assetsPath('media/[name].[hash:7].[ext]')
58 | }
59 | },
60 | {
61 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
62 | loader: 'url-loader',
63 | options: {
64 | limit: 10000,
65 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
66 | }
67 | }
68 | ]
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/build/webpack.dev.conf.js:
--------------------------------------------------------------------------------
1 | var utils = require('./utils')
2 | var webpack = require('webpack')
3 | var config = require('../config')
4 | var merge = require('webpack-merge')
5 | var baseWebpackConfig = require('./webpack.base.conf')
6 | var HtmlWebpackPlugin = require('html-webpack-plugin')
7 | var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
8 |
9 | // add hot-reload related code to entry chunks
10 | Object.keys(baseWebpackConfig.entry).forEach(function (name) {
11 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
12 | })
13 |
14 | module.exports = merge(baseWebpackConfig, {
15 | module: {
16 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
17 | },
18 | // cheap-module-eval-source-map is faster for development
19 | devtool: '#cheap-module-eval-source-map',
20 | plugins: [
21 | new webpack.DefinePlugin({
22 | 'process.env': config.dev.env
23 | }),
24 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
25 | new webpack.HotModuleReplacementPlugin(),
26 | new webpack.NoEmitOnErrorsPlugin(),
27 | // https://github.com/ampedandwired/html-webpack-plugin
28 | new HtmlWebpackPlugin({
29 | filename: 'index.html',
30 | template: 'index.html',
31 | inject: true
32 | }),
33 | new FriendlyErrorsPlugin()
34 | ]
35 | })
36 |
--------------------------------------------------------------------------------
/build/webpack.prod.conf.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var utils = require('./utils')
3 | var webpack = require('webpack')
4 | var config = require('../config')
5 | var merge = require('webpack-merge')
6 | var baseWebpackConfig = require('./webpack.base.conf')
7 | var CopyWebpackPlugin = require('copy-webpack-plugin')
8 | var HtmlWebpackPlugin = require('html-webpack-plugin')
9 | var ExtractTextPlugin = require('extract-text-webpack-plugin')
10 | var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
11 |
12 | var env = config.build.env
13 |
14 | var webpackConfig = merge(baseWebpackConfig, {
15 | module: {
16 | rules: utils.styleLoaders({
17 | sourceMap: config.build.productionSourceMap,
18 | extract: true
19 | })
20 | },
21 | devtool: config.build.productionSourceMap ? '#source-map' : false,
22 | output: {
23 | path: config.build.assetsRoot,
24 | filename: utils.assetsPath('js/[name].[chunkhash].js'),
25 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
26 | },
27 | plugins: [
28 | // http://vuejs.github.io/vue-loader/en/workflow/production.html
29 | new webpack.DefinePlugin({
30 | 'process.env': env
31 | }),
32 | new webpack.optimize.UglifyJsPlugin({
33 | compress: {
34 | warnings: false
35 | },
36 | sourceMap: true
37 | }),
38 | // extract css into its own file
39 | new ExtractTextPlugin({
40 | filename: utils.assetsPath('css/[name].[contenthash].css')
41 | }),
42 | // Compress extracted CSS. We are using this plugin so that possible
43 | // duplicated CSS from different components can be deduped.
44 | new OptimizeCSSPlugin({
45 | cssProcessorOptions: {
46 | safe: true
47 | }
48 | }),
49 | // generate dist index.html with correct asset hash for caching.
50 | // you can customize output by editing /index.html
51 | // see https://github.com/ampedandwired/html-webpack-plugin
52 | new HtmlWebpackPlugin({
53 | filename: config.build.index,
54 | template: 'index.html',
55 | inject: true,
56 | minify: {
57 | removeComments: true,
58 | collapseWhitespace: true,
59 | removeAttributeQuotes: true
60 | // more options:
61 | // https://github.com/kangax/html-minifier#options-quick-reference
62 | },
63 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin
64 | chunksSortMode: 'dependency'
65 | }),
66 | // split vendor js into its own file
67 | new webpack.optimize.CommonsChunkPlugin({
68 | name: 'vendor',
69 | minChunks: function (module, count) {
70 | // any required modules inside node_modules are extracted to vendor
71 | return (
72 | module.resource &&
73 | /\.js$/.test(module.resource) &&
74 | module.resource.indexOf(
75 | path.join(__dirname, '../node_modules')
76 | ) === 0
77 | )
78 | }
79 | }),
80 | // extract webpack runtime and module manifest to its own file in order to
81 | // prevent vendor hash from being updated whenever app bundle is updated
82 | new webpack.optimize.CommonsChunkPlugin({
83 | name: 'manifest',
84 | chunks: ['vendor']
85 | }),
86 | // copy custom static assets
87 | new CopyWebpackPlugin([
88 | {
89 | from: path.resolve(__dirname, '../static'),
90 | to: config.build.assetsSubDirectory,
91 | ignore: ['.*']
92 | }
93 | ])
94 | ]
95 | })
96 |
97 | if (config.build.productionGzip) {
98 | var CompressionWebpackPlugin = require('compression-webpack-plugin')
99 |
100 | webpackConfig.plugins.push(
101 | new CompressionWebpackPlugin({
102 | asset: '[path].gz[query]',
103 | algorithm: 'gzip',
104 | test: new RegExp(
105 | '\\.(' +
106 | config.build.productionGzipExtensions.join('|') +
107 | ')$'
108 | ),
109 | threshold: 10240,
110 | minRatio: 0.8
111 | })
112 | )
113 | }
114 |
115 | if (config.build.bundleAnalyzerReport) {
116 | var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
117 | webpackConfig.plugins.push(new BundleAnalyzerPlugin())
118 | }
119 |
120 | module.exports = webpackConfig
121 |
--------------------------------------------------------------------------------
/config/dev.env.js:
--------------------------------------------------------------------------------
1 | var merge = require('webpack-merge')
2 | var prodEnv = require('./prod.env')
3 |
4 | module.exports = merge(prodEnv, {
5 | NODE_ENV: '"development"',
6 | BASE_API: '"/api"',
7 | })
8 |
--------------------------------------------------------------------------------
/config/index.js:
--------------------------------------------------------------------------------
1 | // see http://vuejs-templates.github.io/webpack for documentation.
2 | var path = require('path')
3 |
4 | module.exports = {
5 | build: {
6 | env: require('./prod.env'),
7 | index: path.resolve(__dirname, '../dist/index.html'),
8 | assetsRoot: path.resolve(__dirname, '../dist'),
9 | assetsSubDirectory: 'static',
10 | assetsPublicPath: '/',
11 | productionSourceMap: false,
12 | // Gzip off by default as many popular static hosts such as
13 | // Surge or Netlify already gzip all static assets for you.
14 | // Before setting to `true`, make sure to:
15 | // npm install --save-dev compression-webpack-plugin
16 | productionGzip: false,
17 | productionGzipExtensions: ['js', 'css'],
18 | // Run the build command with an extra argument to
19 | // View the bundle analyzer report after build finishes:
20 | // `npm run build --report`
21 | // Set to `true` or `false` to always turn it on or off
22 | bundleAnalyzerReport: process.env.npm_config_report
23 | },
24 | dev: {
25 | env: require('./dev.env'),
26 | port: 3000,
27 | autoOpenBrowser: true,
28 | assetsSubDirectory: 'static',
29 | assetsPublicPath: '/',
30 | proxyTable: {
31 | '/api': {
32 | target: 'http://rzk-in.wo946.com/api',
33 | changeOrigin: true,
34 | pathRewrite: {
35 | '^/api': '/api'
36 | }
37 | }
38 | },
39 | // CSS Sourcemaps off by default because relative paths are "buggy"
40 | // with this option, according to the CSS-Loader README
41 | // (https://github.com/webpack/css-loader#sourcemaps)
42 | // In our experience, they generally work as expected,
43 | // just be aware of this issue when enabling this option.
44 | cssSourceMap: false
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/config/prod.env.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | NODE_ENV: '"production"',
3 | BASE_API: '"http://rzk-in.wo946.com/api/api/"',
4 | }
5 |
--------------------------------------------------------------------------------
/imgs/edit-goods.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kele59/vue-order-admin/e39835d380bb3cce017c9f12815fb44c10f91a97/imgs/edit-goods.jpg
--------------------------------------------------------------------------------
/imgs/goods-detail.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kele59/vue-order-admin/e39835d380bb3cce017c9f12815fb44c10f91a97/imgs/goods-detail.jpg
--------------------------------------------------------------------------------
/imgs/goods-list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kele59/vue-order-admin/e39835d380bb3cce017c9f12815fb44c10f91a97/imgs/goods-list.png
--------------------------------------------------------------------------------
/imgs/order-detail.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kele59/vue-order-admin/e39835d380bb3cce017c9f12815fb44c10f91a97/imgs/order-detail.jpg
--------------------------------------------------------------------------------
/imgs/order-list.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kele59/vue-order-admin/e39835d380bb3cce017c9f12815fb44c10f91a97/imgs/order-list.jpg
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 软装库
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rzk-order",
3 | "version": "1.0.0",
4 | "description": "A Vue.js project",
5 | "author": "zaxlct ",
6 | "private": true,
7 | "scripts": {
8 | "dev": "node build/dev-server.js",
9 | "start": "node build/dev-server.js",
10 | "build": "node build/build.js",
11 | "analyz": "NODE_ENV=production npm_config_report=true npm run build"
12 | },
13 | "dependencies": {
14 | "axios": "^0.16.2",
15 | "babel-runtime": "^6.25.0",
16 | "element-ui": "^1.4.1",
17 | "vue": "^2.3.3",
18 | "vue-router": "^2.6.0",
19 | "vuex": "^2.3.1"
20 | },
21 | "devDependencies": {
22 | "autoprefixer": "^7.1.2",
23 | "babel-core": "^6.22.1",
24 | "babel-loader": "^7.1.1",
25 | "babel-plugin-transform-runtime": "^6.22.0",
26 | "babel-polyfill": "^6.23.0",
27 | "babel-preset-env": "^1.3.2",
28 | "babel-preset-stage-2": "^6.22.0",
29 | "babel-register": "^6.22.0",
30 | "chalk": "^2.0.1",
31 | "connect-history-api-fallback": "^1.3.0",
32 | "copy-webpack-plugin": "^4.0.1",
33 | "css-loader": "^0.28.0",
34 | "cssnano": "^3.10.0",
35 | "eventsource-polyfill": "^0.9.6",
36 | "express": "^4.14.1",
37 | "extract-text-webpack-plugin": "^2.0.0",
38 | "file-loader": "^0.11.1",
39 | "friendly-errors-webpack-plugin": "^1.1.3",
40 | "html-webpack-plugin": "^2.28.0",
41 | "http-proxy-middleware": "^0.17.3",
42 | "node-sass": "^4.5.2",
43 | "opn": "^5.1.0",
44 | "optimize-css-assets-webpack-plugin": "^2.0.0",
45 | "ora": "^1.2.0",
46 | "rimraf": "^2.6.0",
47 | "sass-loader": "^6.0.3",
48 | "semver": "^5.3.0",
49 | "shelljs": "^0.7.6",
50 | "url-loader": "^0.5.8",
51 | "vue-loader": "^12.1.0",
52 | "vue-style-loader": "^3.0.1",
53 | "vue-template-compiler": "^2.3.3",
54 | "webpack": "^2.6.1",
55 | "webpack-bundle-analyzer": "^2.2.1",
56 | "webpack-dev-middleware": "^1.10.0",
57 | "webpack-hot-middleware": "^2.18.0",
58 | "webpack-merge": "^4.1.0"
59 | },
60 | "engines": {
61 | "node": ">= 4.0.0",
62 | "npm": ">= 3.0.0"
63 | },
64 | "browserslist": [
65 | "> 1%",
66 | "last 2 versions",
67 | "not ie <= 8"
68 | ]
69 | }
70 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
--------------------------------------------------------------------------------
/src/base/goods-menu/goods-menu.vue:
--------------------------------------------------------------------------------
1 |
2 |
44 |
45 |
46 |
47 |
110 |
111 |
190 |
--------------------------------------------------------------------------------
/src/common/image/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kele59/vue-order-admin/e39835d380bb3cce017c9f12815fb44c10f91a97/src/common/image/logo.png
--------------------------------------------------------------------------------
/src/common/js/Axios.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import { Message } from 'element-ui'
3 |
4 | export const Axios = axios.create({
5 | baseURL: process.env.BASE_API,
6 | timeout: 5000,
7 | withCredentials: true, //带上 cookie
8 | })
9 |
10 | Axios.interceptors.request.use(config => {
11 | //POST传参序列化
12 | if(config.method === 'post'){
13 | // 数据序列化成表单
14 | const formData = new FormData()
15 | Object.keys(config.data).forEach(key => formData.append(key, config.data[key]))
16 | config.data = formData
17 | }
18 |
19 | return config
20 | },error =>{
21 | alert("错误的传参", 'fail')
22 | return Promise.reject(error)
23 | })
24 |
25 |
26 | Axios.interceptors.response.use(res => {
27 | const { data } = res
28 | if(data.success) {
29 | return data
30 | } else if (data.errCode === '00002' && !data.success) {
31 | location.href = location.origin + '/#/login'
32 | } else {
33 | Message.error(data.errMsg)
34 | return Promise.reject(data.errMsg)
35 | }
36 | },error => {
37 | Message.error('网络错误,请检查网络再试!')
38 | return Promise.reject(error)
39 | })
40 |
41 |
42 | export default {
43 | install(Vue) {
44 | Object.defineProperty(Vue.prototype, '$http', { value: Axios })
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/common/js/mixins.js:
--------------------------------------------------------------------------------
1 | export const backgroundImage = {
2 | methods: {
3 | backgroundImage(url, size = 'contain') {
4 | return {
5 | backgroundImage: 'url('+ url +')',
6 | backgroundSize: size,
7 | backgroundRepeat: 'no-repeat',
8 | backgroundPosition: 'center',
9 | }
10 | }
11 | },
12 | }
13 |
--------------------------------------------------------------------------------
/src/common/js/setTitle.js:
--------------------------------------------------------------------------------
1 | let setTitle = {
2 |
3 | }
4 |
5 | setTitle.title = function (title) {
6 | title = title ? title + '' : '';
7 | window.document.title = title;
8 | }
9 |
10 | export default setTitle
11 |
--------------------------------------------------------------------------------
/src/common/scss/index.scss:
--------------------------------------------------------------------------------
1 | @import "normalize";
2 | @import "variables";
3 | @import "mixins";
4 | @import "utility";
5 |
--------------------------------------------------------------------------------
/src/common/scss/mixins.scss:
--------------------------------------------------------------------------------
1 | @import 'variables';
2 |
3 | %text-ellipsis {
4 | overflow: hidden;
5 | white-space: nowrap;
6 | text-overflow: ellipsis;
7 | -o-text-overflow: ellipsis;
8 | word-break:break-all;
9 | word-wrap: normal;
10 | }
11 | %text_ellipsis {
12 | @extend %text-ellipsis;
13 | }
14 |
15 | @mixin text-multiLine-ellipsis($line: 2, $lineHeight: 20px){
16 | line-height: $lineHeight;
17 | overflow: hidden;
18 | height: $lineHeight * $line;
19 | display: -webkit-box;
20 | display: -moz-box;
21 | display: box;
22 | text-overflow: ellipsis;
23 | -webkit-line-clamp: $line;
24 | -moz-line-clamp: $line;
25 | line-clamp: $line;
26 | -webkit-box-orient: vertical;
27 | -moz-box-orient: vertical;
28 | box-orient: vertical;
29 | }
30 |
31 | %text-breakWord {
32 | word-wrap: break-word;
33 | word-break: break-word;
34 | }
35 |
36 | %text_breakWord {
37 | @extend %text-breakWord;
38 | }
39 |
--------------------------------------------------------------------------------
/src/common/scss/normalize.scss:
--------------------------------------------------------------------------------
1 | /*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */
2 |
3 | /* Document
4 | ========================================================================== */
5 |
6 | /**
7 | * 1. Correct the line height in all browsers.
8 | * 2. Prevent adjustments of font size after orientation changes in
9 | * IE on Windows Phone and in iOS.
10 | */
11 |
12 | html {
13 | line-height: 1.15; /* 1 */
14 | -ms-text-size-adjust: 100%; /* 2 */
15 | -webkit-text-size-adjust: 100%; /* 2 */
16 | }
17 |
18 | /* Sections
19 | ========================================================================== */
20 |
21 | /**
22 | * Remove the margin in all browsers (opinionated).
23 | */
24 |
25 | body {
26 | margin: 0;
27 | }
28 |
29 | /**
30 | * Add the correct display in IE 9-.
31 | */
32 |
33 | article,
34 | aside,
35 | footer,
36 | header,
37 | nav,
38 | section {
39 | display: block;
40 | }
41 |
42 | /**
43 | * Correct the font size and margin on `h1` elements within `section` and
44 | * `article` contexts in Chrome, Firefox, and Safari.
45 | */
46 |
47 | h1 {
48 | font-size: 2em;
49 | margin: 0.67em 0;
50 | }
51 |
52 | /* Grouping content
53 | ========================================================================== */
54 |
55 | /**
56 | * Add the correct display in IE 9-.
57 | * 1. Add the correct display in IE.
58 | */
59 |
60 | figcaption,
61 | figure,
62 | main { /* 1 */
63 | display: block;
64 | }
65 |
66 | /**
67 | * Add the correct margin in IE 8.
68 | */
69 |
70 | figure {
71 | margin: 1em 40px;
72 | }
73 |
74 | /**
75 | * 1. Add the correct box sizing in Firefox.
76 | * 2. Show the overflow in Edge and IE.
77 | */
78 |
79 | hr {
80 | box-sizing: content-box; /* 1 */
81 | height: 0; /* 1 */
82 | overflow: visible; /* 2 */
83 | }
84 |
85 | /**
86 | * 1. Correct the inheritance and scaling of font size in all browsers.
87 | * 2. Correct the odd `em` font sizing in all browsers.
88 | */
89 |
90 | pre {
91 | font-family: monospace, monospace; /* 1 */
92 | font-size: 1em; /* 2 */
93 | }
94 |
95 | /* Text-level semantics
96 | ========================================================================== */
97 |
98 | /**
99 | * 1. Remove the gray background on active links in IE 10.
100 | * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
101 | */
102 |
103 | a {
104 | background-color: transparent; /* 1 */
105 | -webkit-text-decoration-skip: objects; /* 2 */
106 | }
107 |
108 | /**
109 | * 1. Remove the bottom border in Chrome 57- and Firefox 39-.
110 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
111 | */
112 |
113 | abbr[title] {
114 | border-bottom: none; /* 1 */
115 | text-decoration: underline; /* 2 */
116 | text-decoration: underline dotted; /* 2 */
117 | }
118 |
119 | /**
120 | * Prevent the duplicate application of `bolder` by the next rule in Safari 6.
121 | */
122 |
123 | b,
124 | strong {
125 | font-weight: inherit;
126 | }
127 |
128 | /**
129 | * Add the correct font weight in Chrome, Edge, and Safari.
130 | */
131 |
132 | b,
133 | strong {
134 | font-weight: bolder;
135 | }
136 |
137 | /**
138 | * 1. Correct the inheritance and scaling of font size in all browsers.
139 | * 2. Correct the odd `em` font sizing in all browsers.
140 | */
141 |
142 | code,
143 | kbd,
144 | samp {
145 | font-family: monospace, monospace; /* 1 */
146 | font-size: 1em; /* 2 */
147 | }
148 |
149 | /**
150 | * Add the correct font style in Android 4.3-.
151 | */
152 |
153 | dfn {
154 | font-style: italic;
155 | }
156 |
157 | /**
158 | * Add the correct background and color in IE 9-.
159 | */
160 |
161 | mark {
162 | background-color: #ff0;
163 | color: #000;
164 | }
165 |
166 | /**
167 | * Add the correct font size in all browsers.
168 | */
169 |
170 | small {
171 | font-size: 80%;
172 | }
173 |
174 | /**
175 | * Prevent `sub` and `sup` elements from affecting the line height in
176 | * all browsers.
177 | */
178 |
179 | sub,
180 | sup {
181 | font-size: 75%;
182 | line-height: 0;
183 | position: relative;
184 | vertical-align: baseline;
185 | }
186 |
187 | sub {
188 | bottom: -0.25em;
189 | }
190 |
191 | sup {
192 | top: -0.5em;
193 | }
194 |
195 | /* Embedded content
196 | ========================================================================== */
197 |
198 | /**
199 | * Add the correct display in IE 9-.
200 | */
201 |
202 | audio,
203 | video {
204 | display: inline-block;
205 | }
206 |
207 | /**
208 | * Add the correct display in iOS 4-7.
209 | */
210 |
211 | audio:not([controls]) {
212 | display: none;
213 | height: 0;
214 | }
215 |
216 | /**
217 | * Remove the border on images inside links in IE 10-.
218 | */
219 |
220 | img {
221 | border-style: none;
222 | }
223 |
224 | /**
225 | * Hide the overflow in IE.
226 | */
227 |
228 | svg:not(:root) {
229 | overflow: hidden;
230 | }
231 |
232 | /* Forms
233 | ========================================================================== */
234 |
235 | /**
236 | * 1. Change the font styles in all browsers (opinionated).
237 | * 2. Remove the margin in Firefox and Safari.
238 | */
239 |
240 | button,
241 | input,
242 | optgroup,
243 | select,
244 | textarea {
245 | font-family: sans-serif; /* 1 */
246 | font-size: 100%; /* 1 */
247 | line-height: 1.15; /* 1 */
248 | margin: 0; /* 2 */
249 | }
250 |
251 | /**
252 | * Show the overflow in IE.
253 | * 1. Show the overflow in Edge.
254 | */
255 |
256 | button,
257 | input { /* 1 */
258 | overflow: visible;
259 | }
260 |
261 | /**
262 | * Remove the inheritance of text transform in Edge, Firefox, and IE.
263 | * 1. Remove the inheritance of text transform in Firefox.
264 | */
265 |
266 | button,
267 | select { /* 1 */
268 | text-transform: none;
269 | }
270 |
271 | /**
272 | * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
273 | * controls in Android 4.
274 | * 2. Correct the inability to style clickable types in iOS and Safari.
275 | */
276 |
277 | button,
278 | html [type="button"], /* 1 */
279 | [type="reset"],
280 | [type="submit"] {
281 | -webkit-appearance: button; /* 2 */
282 | }
283 |
284 | /**
285 | * Remove the inner border and padding in Firefox.
286 | */
287 |
288 | button::-moz-focus-inner,
289 | [type="button"]::-moz-focus-inner,
290 | [type="reset"]::-moz-focus-inner,
291 | [type="submit"]::-moz-focus-inner {
292 | border-style: none;
293 | padding: 0;
294 | }
295 |
296 | /**
297 | * Restore the focus styles unset by the previous rule.
298 | */
299 |
300 | button:-moz-focusring,
301 | [type="button"]:-moz-focusring,
302 | [type="reset"]:-moz-focusring,
303 | [type="submit"]:-moz-focusring {
304 | outline: 1px dotted ButtonText;
305 | }
306 |
307 | /**
308 | * Correct the padding in Firefox.
309 | */
310 |
311 | fieldset {
312 | padding: 0.35em 0.75em 0.625em;
313 | }
314 |
315 | /**
316 | * 1. Correct the text wrapping in Edge and IE.
317 | * 2. Correct the color inheritance from `fieldset` elements in IE.
318 | * 3. Remove the padding so developers are not caught out when they zero out
319 | * `fieldset` elements in all browsers.
320 | */
321 |
322 | legend {
323 | box-sizing: border-box; /* 1 */
324 | color: inherit; /* 2 */
325 | display: table; /* 1 */
326 | max-width: 100%; /* 1 */
327 | padding: 0; /* 3 */
328 | white-space: normal; /* 1 */
329 | }
330 |
331 | /**
332 | * 1. Add the correct display in IE 9-.
333 | * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.
334 | */
335 |
336 | progress {
337 | display: inline-block; /* 1 */
338 | vertical-align: baseline; /* 2 */
339 | }
340 |
341 | /**
342 | * Remove the default vertical scrollbar in IE.
343 | */
344 |
345 | textarea {
346 | overflow: auto;
347 | }
348 |
349 | /**
350 | * 1. Add the correct box sizing in IE 10-.
351 | * 2. Remove the padding in IE 10-.
352 | */
353 |
354 | [type="checkbox"],
355 | [type="radio"] {
356 | box-sizing: border-box; /* 1 */
357 | padding: 0; /* 2 */
358 | }
359 |
360 | /**
361 | * Correct the cursor style of increment and decrement buttons in Chrome.
362 | */
363 |
364 | [type="number"]::-webkit-inner-spin-button,
365 | [type="number"]::-webkit-outer-spin-button {
366 | height: auto;
367 | }
368 |
369 | /**
370 | * 1. Correct the odd appearance in Chrome and Safari.
371 | * 2. Correct the outline style in Safari.
372 | */
373 |
374 | [type="search"] {
375 | -webkit-appearance: textfield; /* 1 */
376 | outline-offset: -2px; /* 2 */
377 | }
378 |
379 | /**
380 | * Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
381 | */
382 |
383 | [type="search"]::-webkit-search-cancel-button,
384 | [type="search"]::-webkit-search-decoration {
385 | -webkit-appearance: none;
386 | }
387 |
388 | /**
389 | * 1. Correct the inability to style clickable types in iOS and Safari.
390 | * 2. Change font properties to `inherit` in Safari.
391 | */
392 |
393 | ::-webkit-file-upload-button {
394 | -webkit-appearance: button; /* 1 */
395 | font: inherit; /* 2 */
396 | }
397 |
398 | /* Interactive
399 | ========================================================================== */
400 |
401 | /*
402 | * Add the correct display in IE 9-.
403 | * 1. Add the correct display in Edge, IE, and Firefox.
404 | */
405 |
406 | details, /* 1 */
407 | menu {
408 | display: block;
409 | }
410 |
411 | /*
412 | * Add the correct display in all browsers.
413 | */
414 |
415 | summary {
416 | display: list-item;
417 | }
418 |
419 | /* Scripting
420 | ========================================================================== */
421 |
422 | /**
423 | * Add the correct display in IE 9-.
424 | */
425 |
426 | canvas {
427 | display: inline-block;
428 | }
429 |
430 | /**
431 | * Add the correct display in IE.
432 | */
433 |
434 | template {
435 | display: none;
436 | }
437 |
438 | /* Hidden
439 | ========================================================================== */
440 |
441 | /**
442 | * Add the correct display in IE 10-.
443 | */
444 |
445 | [hidden] {
446 | display: none;
447 | }
448 |
--------------------------------------------------------------------------------
/src/common/scss/utility.scss:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | -webkit-font-smoothing: antialiased;
4 | }
5 |
6 | body {
7 | margin: 0;
8 | padding: 0;
9 | background: #f5f7f9;
10 | font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;
11 | }
12 |
13 | p {
14 | margin: 0;
15 | padding: 0;
16 | }
17 |
18 | a {
19 | color: #0366d6;
20 | text-decoration: none;
21 | }
22 |
23 | .cursor {
24 | cursor: pointer;
25 | }
26 |
27 | .fr { float: right !important; }
28 | .fl { float: left !important; }
29 | .db { display: block; }
30 | .dib { display: inline-block; }
31 |
32 | .black { color: #000 !important; }
33 | .bg_white { background: #fff !important; }
34 |
35 | .pointer { cursor: pointer;}
36 | .u_line { text-decoration: underline; }
37 | .tc { text-align: center !important; }
38 | .tl { text-align: left !important; }
39 | .tr { text-align: right !important; }
40 |
41 | .over_hide {
42 | overflow: hidden;
43 | height: 100px;
44 | word-break: break-all;
45 | text-align: left;
46 | }
47 |
48 | .text_ellipsis {
49 | @extend %text-ellipsis;
50 | }
51 |
52 | .text_breakWord {
53 | @extend %text_breakWord;
54 | }
55 |
56 | .pl30 { padding-left: 30px; }
57 | .pr30 { padding-right: 30px; }
58 | .mt10 { margin-top: 10px; }
59 | .mt20 { margin-top: 20px; }
60 | .mt30 { margin-top: 30px; }
61 | .mb20 { margin-bottom: 20px; }
62 | .mb30 { margin-bottom: 30px; }
63 | .ml20 { margin-left: 20px; }
64 | .mr20 { margin-right: 20px; }
65 | .ml30 { margin-left: 30px !important; }
66 | .mr30 { margin-right: 30px !important; }
67 |
68 | // 调整表格间距
69 | .el-table .cell, .el-table th > div {
70 | padding-left: 10px !important;
71 | padding-right: 10px !important;
72 | }
73 |
74 | // 商品列表页里的评分,icon 小一些
75 | .goods_table,
76 | .order_table {
77 | .el-rate__icon {
78 | font-size: 12px !important;
79 | }
80 |
81 | thead th {
82 | text-align: center !important;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/common/scss/variables.scss:
--------------------------------------------------------------------------------
1 | $container_width: 1200px;
2 | $z_filter: 50;
3 |
--------------------------------------------------------------------------------
/src/components/goods/goods-detail/edit-comment-layout.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{rate.value}}
5 |
10 |
11 |
12 |
13 |
14 | 项目名称:
15 |
16 |
17 |
18 |
19 | 评论:
20 |
25 |
26 |
27 |
28 |
29 |
双击选择要删除的图片
30 |
40 |
41 |
42 | 提交
43 |
44 |
57 | 选取图片
58 | 每次只能上传一张,格式为 jpg/png ,且不超过 10M
59 |
60 |
61 |
62 |
63 |
208 |
209 |
269 |
--------------------------------------------------------------------------------
/src/components/goods/goods-detail/goods-comment-layout.vue:
--------------------------------------------------------------------------------
1 |
2 |
54 |
55 |
56 |
143 |
144 |
227 |
--------------------------------------------------------------------------------
/src/components/goods/goods-detail/goods-detail.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
59 |
60 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
148 |
149 |
254 |
--------------------------------------------------------------------------------
/src/components/goods/goods-list/goods-list.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
22 |
23 |
24 |
25 |
26 | {{item}}
27 |
28 |
29 |
30 |
35 | {{item.codeDesc}}
36 |
41 |
42 |
43 |
44 |
45 |
addedGoodsCount = num"
50 | class="goods_table">
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
178 |
236 |
--------------------------------------------------------------------------------
/src/components/goods/goods-list/goods-table-layout.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | {{scope.row.goods_name}}
21 | {{scope.row.goodsPropertyVos[scope.row.currentSkuIndex].sku}}
22 |
30 |
31 |
32 |
33 | {{scope.row.goods_process_desc}}
34 |
35 |
36 |
37 |
38 |
39 |
40 | {{scope.row.material}}
41 |
42 |
43 |
44 |
45 |
46 | {{scope.row.sizes}}
47 |
48 |
49 |
50 |
51 |
52 | {{scope.row.time_limit}}
53 |
54 |
55 |
56 |
57 |
58 | {{scope.row.price}}
59 |
60 |
61 |
62 |
63 |
64 | {{scope.row.supplier}}
65 |
66 |
67 |
68 |
69 |
70 |
71 | {{rate.value}}
72 |
77 |
78 |
79 | 暂无评分
80 |
81 |
82 |
83 |
84 |
85 | 添加商品
86 |
87 |
92 | CAD
93 |
94 |
99 | SU
100 |
101 |
102 |
103 |
104 |
105 |
106 |
173 |
230 |
--------------------------------------------------------------------------------
/src/components/login/login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | 登录
14 |
15 |
16 |
17 |
18 |
19 |
56 |
69 |
--------------------------------------------------------------------------------
/src/components/order/order-detail/edit-goods-layout.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 | 标题:
6 |
7 | -
8 | 价格:
9 |
10 |
11 | -
12 | 链接:
13 |
14 |
15 | -
16 | 描述:
17 |
22 |
23 |
24 |
25 |
26 |
27 |
双击选择要删除的图片
28 |
38 |
39 |
40 | 提交
41 |
42 |
55 | 选取图片
56 | 每次只能上传一张,格式为 jpg/png ,且不超过 10M
57 |
58 |
59 |
60 |
61 |
192 |
193 |
238 |
--------------------------------------------------------------------------------
/src/components/order/order-detail/order-detail.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
19 |
20 |
21 |
26 |
27 |
28 |
29 |
30 |
31 |
37 |
38 |
42 |
43 |
44 |
45 |
46 |
47 |
51 |
52 |
58 |
59 |
60 |
61 |
66 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
205 |
206 |
268 |
--------------------------------------------------------------------------------
/src/components/order/order-detail/order-table-layout.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | {{scope.row.goods_name}}
24 | {{scope.row.productNum}}
25 | {{scope.row.material}}
26 |
27 | 颜色:
28 |
![]()
29 |
30 |
31 | {{scope.row.goods_process_desc}}
32 |
33 |
34 |
35 |
36 |
37 |
38 | {{scope.row.sizes}}
39 |
40 |
41 |
42 |
43 |
44 | {{scope.row.time_limit}}
45 |
46 |
47 |
48 |
49 |
50 | {{scope.row.price}}
51 |
52 |
53 |
54 |
55 |
56 | changeOrderDetail(value, 'num', scope.$index)">
62 |
63 |
64 |
65 |
66 |
67 |
68 | changeOrderDetail(value, 'profit', scope.$index)">
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | {{scope.row.sum | computedTotal(scope.row.num, scope.row.profit, scope.row.price)}}
83 |
84 |
85 |
86 |
87 |
88 |
89 | {{scope.row.supplier}}
90 |
91 |
92 |
93 |
94 |
95 | {{scope.row.comment || '暂无备注'}}
96 |
97 |
98 |
99 |
100 |
101 |
102 |
106 | 删除
107 |
108 |
109 |
110 |
111 |
112 |
113 |
119 |
120 |
124 |
125 |
126 |
127 |
128 |
207 |
208 |
229 |
--------------------------------------------------------------------------------
/src/components/order/order-detail/other-goods-layout.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | - 标题:{{goods.title}}
6 | - 价格:{{goods.price}}
7 | - 链接:{{goods.link}}
8 | - 描述:{{goods.desc}}
9 |
10 |
11 |
12 | 修改
13 | 删除
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
54 |
55 |
83 |
--------------------------------------------------------------------------------
/src/components/order/order-list/order-list.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
26 |
27 |
28 |
32 |
33 | {{order.order_name}}
34 |
35 |
36 | 备注:{{order.comment || '暂无备注'}}
37 |
38 |
39 | 导出订单
40 |
41 |
42 |
43 | 订单总额:{{order.sum}}
44 |
45 |
46 | 创建时间:{{order.created_time | getLocalTime}}
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
没有数据
56 |
57 |
64 |
65 |
66 |
67 |
68 |
69 |
201 |
202 |
310 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import 'babel-polyfill'
2 | import Vue from 'vue'
3 | import VueRouter from 'vue-router'
4 | import ElementUI from 'element-ui'
5 |
6 | import App from './App'
7 | import store from './store'
8 | import Routers from './router'
9 | import Util from 'common/js/setTitle'
10 | import 'common/scss/index.scss'
11 | import 'element-ui/lib/theme-default/index.css'
12 | import AxiosPlugin from 'common/js/Axios'
13 |
14 | Vue.use(AxiosPlugin)
15 | Vue.use(ElementUI)
16 | Vue.use(VueRouter)
17 |
18 | // route config
19 | const router = new VueRouter({
20 | routes: Routers
21 | })
22 | router.beforeEach((to, from, next) => {
23 | Util.title(to.meta.title)
24 | next()
25 | })
26 |
27 | /* eslint-disable no-new */
28 | new Vue({
29 | el: '#app',
30 | router,
31 | store,
32 | render: h => h(App)
33 | })
34 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | const OrderList = () => import('order/order-list/order-list')
2 | const Login = () => import('login/login')
3 | const GoodsList = () => import('goods/goods-list/goods-list')
4 | const GoodsDetail = () => import('goods/goods-detail/goods-detail')
5 | const OrderDetail = () => import('order/order-detail/order-detail')
6 |
7 | const routers = [
8 | {
9 | path: '/',
10 | redirect: '/order-list'
11 | },
12 |
13 | {
14 | path: '/order-list',
15 | name: 'OrderList',
16 | component: OrderList,
17 | meta: {
18 | title: '订单列表'
19 | },
20 | },
21 |
22 | {
23 | path: '/login',
24 | component: Login,
25 | meta: {
26 | title: '登录'
27 | },
28 | },
29 |
30 | {
31 | path: '/goods-list/:order_id',
32 | name: 'GoodsList',
33 | component: GoodsList,
34 | meta: {
35 | title: '商品列表'
36 | },
37 | },
38 |
39 | {
40 | path: '/goods-detail/:order_id/:code',
41 | name: 'GoodsDetail',
42 | component: GoodsDetail,
43 | meta: {
44 | title: '商品详情页'
45 | },
46 | },
47 |
48 | {
49 | path: '/order-detail/:order_id',
50 | name: 'OrderDetail',
51 | component: OrderDetail,
52 | meta: {
53 | title: '订单详情'
54 | },
55 | }
56 | ]
57 |
58 | export default routers
59 |
--------------------------------------------------------------------------------
/src/store/actions.js:
--------------------------------------------------------------------------------
1 | import * as types from './mutation-types'
2 | import { Axios } from "common/js/Axios"
3 |
4 | export const fetchGoodsList = function({state, commit}, params) {
5 | commit(types.CHANGE_FETCH_GOODS_LIST_PARAMS, params)
6 | // current_id 三个参数只是记录商品菜单的层级,请求 API 时不需要这三个参数
7 | // 列举需要的参数
8 | const paramsList = [
9 | 'menu_id',
10 | 'level',
11 | 'goods_color',
12 | 'page_index',
13 | 'page_size',
14 | 'search_key',
15 | 'order_id',
16 | ]
17 | const newParamsStr = JSON.stringify(state.fetchGoodsListParams, paramsList)
18 |
19 | Axios.get('goods/goods_list', {params: JSON.parse(newParamsStr)}).then(res => {
20 | if(!res) return
21 | if(!res.data) {
22 | commit(types.UPDATE_GOODS_LIST, {})
23 | } else {
24 | commit(types.UPDATE_GOODS_LIST, res.data)
25 | }
26 | })
27 | }
28 |
29 | export const fetchGoodsCategoryList = function({state, commit}){
30 | if(!state.goodsCategoryList.length) {
31 | Axios.get('goods/goods_category').then(res => {
32 | if(!res || !res.data) return
33 | commit(types.FETCH_GOODS_CATEGORY_LIST, res.data)
34 | })
35 | }
36 | }
37 |
38 | export const fetchGoodsColorsList = function({state, commit}){
39 | if(!state.goodsColorsList.length) {
40 | Axios.get('goods/goods_color').then(res => {
41 | if(!res || !res.data) return
42 | commit(types.FETCH_GOODS_COLORS_LIST, res.data)
43 | })
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/store/getters.js:
--------------------------------------------------------------------------------
1 | export const orderAmount = state => {
2 | const amount = state.orderDetail.reduce((num, prev) => {
3 | let profit = (prev.profit + 100) / 100
4 | return num + (prev.price * prev.num * profit)
5 | }, 0)
6 |
7 | return Number(amount.toFixed(2))
8 | }
9 |
10 | export const orderSpList = state => state.orderDetail.map(goods => goods.sku + '@' + goods.profit + '@' + goods.num).join(',')
11 |
12 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import * as actions from './actions'
4 | import * as getters from './getters'
5 | import state from './state'
6 | import mutations from './mutations'
7 | import createLogger from 'vuex/dist/logger'
8 |
9 | Vue.use(Vuex)
10 |
11 | const debug = process.env.NODE_ENV !== 'production'
12 |
13 | export default new Vuex.Store({
14 | actions,
15 | getters,
16 | state,
17 | mutations,
18 | strict: debug,
19 | plugins: debug ? [createLogger()] : []
20 | })
21 |
--------------------------------------------------------------------------------
/src/store/mutation-types.js:
--------------------------------------------------------------------------------
1 | export const CHANGE_FETCH_GOODS_LIST_PARAMS = 'CHANGE_FETCH_GOODS_LIST_PARAMS'
2 | export const CLEAR_FETCH_GOODS_LIST_PARAMS = 'CLEAR_FETCH_GOODS_LIST_PARAMS'
3 | export const UPDATE_GOODS_LIST = 'UPDATE_GOODS_LIST'
4 | export const UPDATE_ORDER_DETAIL = 'UPDATE_ORDER_DETAIL'
5 | export const UPDATE_ORDER_DETAIL_INDEX_VALUE = 'UPDATE_ORDER_DETAIL_INDEX_VALUE'
6 | export const FETCH_GOODS_CATEGORY_LIST = 'FETCH_GOODS_CATEGORY_LIST'
7 | export const FETCH_GOODS_COLORS_LIST = 'FETCH_GOODS_COLORS_LIST'
8 |
--------------------------------------------------------------------------------
/src/store/mutations.js:
--------------------------------------------------------------------------------
1 | import * as types from './mutation-types'
2 |
3 | const matutaions = {
4 | [types.CHANGE_FETCH_GOODS_LIST_PARAMS](state, params) {
5 | state.fetchGoodsListParams = {
6 | ...state.fetchGoodsListParams,
7 | ...params,
8 | }
9 | },
10 |
11 | [types.CLEAR_FETCH_GOODS_LIST_PARAMS](state) {
12 | state.fetchGoodsListParams = {
13 | menu_id: 0,
14 | level: 1,
15 | goods_color: '',
16 | page_index: 1,
17 | page_size: 6,
18 | search_key: '',
19 | order_id: '',
20 | // current_id 三个参数只是记录商品菜单的层级,请求 API 时不需要这三个参数
21 | current_id_a: 0,
22 | current_id_b: 0,
23 | current_id_c: 0,
24 | }
25 | },
26 |
27 | [types.UPDATE_GOODS_LIST](state, newGoodsList) {
28 | state.goodsList = newGoodsList
29 | },
30 |
31 | [types.UPDATE_ORDER_DETAIL](state, newOrderDetail) {
32 | state.orderDetail = newOrderDetail
33 | },
34 |
35 | [types.UPDATE_ORDER_DETAIL_INDEX_VALUE](state, {value, key, keyIndex}) {
36 | state.orderDetail[keyIndex][key] = value
37 | },
38 |
39 | [types.FETCH_GOODS_CATEGORY_LIST](state, newCategoryList) {
40 | state.goodsCategoryList = newCategoryList
41 | },
42 |
43 | [types.FETCH_GOODS_COLORS_LIST](state, newColorsList) {
44 | state.goodsColorsList = newColorsList
45 | },
46 | }
47 |
48 | export default matutaions
49 |
--------------------------------------------------------------------------------
/src/store/state.js:
--------------------------------------------------------------------------------
1 | const state = {
2 | fetchGoodsListParams: {
3 | menu_id: 0,
4 | level: 1,
5 | goods_color: '',
6 | page_index: 1,
7 | page_size: 6,
8 | search_key: '',
9 | order_id: '',
10 | // current_id 三个参数只是记录商品菜单的层级,请求 API 时不需要这三个参数
11 | current_id_a: 0,
12 | current_id_b: 0,
13 | current_id_c: 0,
14 | },
15 | goodsList: {},
16 | orderDetail: [],
17 | goodsCategoryList: [],
18 | goodsColorsList: [],
19 | }
20 |
21 | export default state
22 |
--------------------------------------------------------------------------------
/static/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kele59/vue-order-admin/e39835d380bb3cce017c9f12815fb44c10f91a97/static/.gitkeep
--------------------------------------------------------------------------------
评论列表
4 |8 |-
9 |
10 | 账号:{{comment.userName}}
11 | 项目名:{{comment.orderName || '暂无'}}
12 | 评论时间:{{comment.createdTime}}
13 |
14 |
15 |
16 | 修改评论
17 |
18 | 删除评论
19 |
20 |
21 |
22 |
23 | {{rate.value}}
24 |
29 |
30 |
31 |
32 |
42 |
43 | 44 |评论图片
33 |34 | 35 |
36 | 37 |评论内容
38 |39 | {{comment.comment}} 40 |
41 |{{dialogTitle}}(按 ESC 关闭)
50 |