├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .postcssrc.js ├── README.md ├── build ├── build.js ├── check-versions.js ├── 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 ├── index.html ├── index ├── favicon.ico ├── index.html └── static │ ├── css │ └── app.23d78d1283196c7a2ca572ec6c35bd52.css │ ├── favicon.ico │ ├── img │ └── headerimg.5188326.png │ └── js │ ├── 0.4f93e6f06540dc6b7883.js │ ├── 1.e4a28d8a3ad3874bcc7c.js │ ├── 10.c35412e4685b51529ed4.js │ ├── 11.2da1574d1c1e56fac7e6.js │ ├── 12.a887f15a87f5cdb6537b.js │ ├── 13.59eceb797215acbc2e75.js │ ├── 14.cdf808f21ad7b5d580ca.js │ ├── 15.8c3bf566c995d9acf253.js │ ├── 2.d9656f039ff8850b6a31.js │ ├── 3.061eb08b572f43338856.js │ ├── 4.4dceb37acc5b6de681a2.js │ ├── 5.917fb52c254a2f6f7947.js │ ├── 6.13af6133c05481ccfde0.js │ ├── 7.da9738e1c673fd03a2b5.js │ ├── 8.d09ddaf8ad78ecfe9209.js │ ├── 9.ced33813b20f8fbc515f.js │ ├── app.fe612eb2356245aa083c.js │ ├── manifest.4bb79e78960fd7ed2aec.js │ └── vendor.f8064ad7a544f87cfeac.js ├── package-lock.json ├── package.json ├── src ├── App.vue ├── components │ ├── cart │ │ ├── index.vue │ │ └── order │ │ │ ├── addressbar.png │ │ │ └── index.vue │ ├── cate │ │ └── index.vue │ ├── common │ │ ├── base │ │ │ ├── bubble.vue │ │ │ ├── loading.gif │ │ │ ├── loding.vue │ │ │ ├── number.vue │ │ │ ├── plant.vue │ │ │ ├── scroll.vue │ │ │ └── svgicon.vue │ │ ├── css │ │ │ └── common.css │ │ ├── icon │ │ │ ├── index.js │ │ │ └── svg │ │ │ │ ├── add.svg │ │ │ │ ├── address-list.svg │ │ │ │ ├── address.svg │ │ │ │ ├── back.svg │ │ │ │ ├── cart.svg │ │ │ │ ├── cart2.svg │ │ │ │ ├── cate.svg │ │ │ │ ├── close.svg │ │ │ │ ├── delete.svg │ │ │ │ ├── edit.svg │ │ │ │ ├── express.svg │ │ │ │ ├── help.svg │ │ │ │ ├── home.svg │ │ │ │ ├── master.svg │ │ │ │ ├── member.svg │ │ │ │ ├── message.svg │ │ │ │ ├── min.svg │ │ │ │ ├── more.svg │ │ │ │ ├── order-all.svg │ │ │ │ ├── order-finish.svg │ │ │ │ ├── order-send.svg │ │ │ │ ├── order-wait-pay.svg │ │ │ │ ├── order-wait-send.svg │ │ │ │ ├── order.svg │ │ │ │ ├── password.svg │ │ │ │ ├── right.svg │ │ │ │ ├── right2.svg │ │ │ │ ├── setting.svg │ │ │ │ └── username.svg │ │ ├── img │ │ │ └── 404.png │ │ └── js │ │ │ ├── cityData.js │ │ │ ├── mixin.js │ │ │ ├── public.js │ │ │ └── request.js │ ├── error.vue │ ├── index.vue │ ├── index │ │ ├── ProductDetail │ │ │ └── index.vue │ │ └── index.vue │ └── member │ │ ├── address │ │ ├── addAddress.vue │ │ └── index.vue │ │ ├── headerimg.png │ │ ├── index.vue │ │ ├── login │ │ ├── index.vue │ │ ├── master.png │ │ └── master1.png │ │ ├── order │ │ ├── index.vue │ │ └── orderDetail.vue │ │ ├── reg │ │ ├── index.vue │ │ ├── master.png │ │ └── master1.png │ │ └── setting │ │ ├── headerimg.png │ │ └── index.vue ├── main.js ├── permission.js ├── router │ └── index.js └── store │ ├── actions.js │ ├── getters.js │ ├── index.js │ ├── mutation-types.js │ ├── mutations.js │ └── state.js └── static ├── .gitkeep └── favicon.ico /.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-vue-jsx", "transform-runtime"] 12 | } 13 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 4 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /config/ 3 | /node_modules/ 4 | /test/ -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: 'babel-eslint', 4 | parserOptions: { 5 | sourceType: 'module' 6 | }, 7 | env: { 8 | browser: true, 9 | node: true, 10 | es6: true, 11 | }, 12 | extends: 'eslint:recommended', 13 | // required to lint *.vue files 14 | plugins: [ 15 | 'html' 16 | ], 17 | // check if imports actually resolve 18 | 'settings': { 19 | 'import/resolver': { 20 | 'webpack': { 21 | 'config': 'build/webpack.base.conf.js' 22 | } 23 | } 24 | }, 25 | // add your custom rules here 26 | //it is base on https://github.com/vuejs/eslint-config-vue 27 | 'rules': { 28 | 'accessor-pairs': 2, 29 | // 箭头函数加空格 30 | // 'arrow-spacing': [2, { 31 | // 'before': true, 32 | // 'after': true 33 | // }], 34 | 'block-spacing': [2, 'always'], 35 | 'brace-style': [2, '1tbs', { 36 | 'allowSingleLine': true 37 | }], 38 | 'camelcase': [0, { 39 | 'properties': 'always' 40 | }], 41 | // 最后一个加逗号 42 | // 'comma-dangle': [2, 'never'], 43 | // 'comma-spacing': [2, { 44 | // 'before': false, 45 | // 'after': true 46 | // }], 47 | // 'comma-style': [2, 'last'], 48 | 'constructor-super': 2, 49 | 'curly': [2, 'multi-line'], 50 | 'dot-location': [2, 'property'], 51 | // 在文件末尾加一个空行 52 | // 'eol-last': 2, 53 | // 全等于 54 | // 'eqeqeq': [2, 'allow-null'], 55 | 'generator-star-spacing': [2, { 56 | 'before': true, 57 | 'after': true 58 | }], 59 | // 强调错误处理 60 | // 'handle-callback-err': [2, '^(err|error)$'], 61 | 'indent': [2, 4, { 62 | 'SwitchCase': 1 63 | }], 64 | // 使用单引号 65 | // 'jsx-quotes': [2, 'prefer-single'], 66 | 'key-spacing': [2, { 67 | 'beforeColon': false, 68 | 'afterColon': true 69 | }], 70 | 'keyword-spacing': [2, { 71 | 'before': true, 72 | 'after': true 73 | }], 74 | 'new-cap': [2, { 75 | 'newIsCap': true, 76 | 'capIsNew': false 77 | }], 78 | 'new-parens': 2, 79 | 'no-array-constructor': 2, 80 | 'no-caller': 2, 81 | 'no-console': 'off', 82 | 'no-class-assign': 2, 83 | 'no-cond-assign': 2, 84 | 'no-const-assign': 2, 85 | 'no-control-regex': 0, 86 | 'no-delete-var': 2, 87 | 'no-dupe-args': 2, 88 | 'no-dupe-class-members': 2, 89 | 'no-dupe-keys': 2, 90 | 'no-duplicate-case': 2, 91 | 'no-empty-character-class': 2, 92 | 'no-empty-pattern': 2, 93 | 'no-eval': 2, 94 | 'no-ex-assign': 2, 95 | 'no-extend-native': 2, 96 | 'no-extra-bind': 2, 97 | 'no-extra-boolean-cast': 2, 98 | 'no-extra-parens': [2, 'functions'], 99 | 'no-fallthrough': 2, 100 | 'no-floating-decimal': 2, 101 | 'no-func-assign': 2, 102 | 'no-implied-eval': 2, 103 | 'no-inner-declarations': [2, 'functions'], 104 | 'no-invalid-regexp': 2, 105 | 'no-irregular-whitespace': 2, 106 | 'no-iterator': 2, 107 | 'no-label-var': 2, 108 | 'no-labels': [2, { 109 | 'allowLoop': false, 110 | 'allowSwitch': false 111 | }], 112 | 'no-lone-blocks': 2, 113 | 'no-mixed-spaces-and-tabs': 2, 114 | // 'no-multi-spaces': 2, 115 | 'no-multi-str': 2, 116 | 'no-multiple-empty-lines': [2, { 117 | 'max': 1 118 | }], 119 | 'no-native-reassign': 2, 120 | 'no-negated-in-lhs': 2, 121 | 'no-new-object': 2, 122 | 'no-new-require': 2, 123 | 'no-new-symbol': 2, 124 | 'no-new-wrappers': 2, 125 | 'no-obj-calls': 2, 126 | 'no-octal': 2, 127 | 'no-octal-escape': 2, 128 | 'no-path-concat': 2, 129 | 'no-proto': 2, 130 | 'no-redeclare': 2, 131 | 'no-regex-spaces': 2, 132 | 'no-return-assign': [2, 'except-parens'], 133 | 'no-self-assign': 2, 134 | 'no-self-compare': 2, 135 | 'no-sequences': 2, 136 | 'no-shadow-restricted-names': 2, 137 | 'no-spaced-func': 2, 138 | 'no-sparse-arrays': 2, 139 | 'no-this-before-super': 2, 140 | 'no-throw-literal': 2, 141 | 'no-trailing-spaces': 2, 142 | 'no-undef': 2, 143 | 'no-undef-init': 2, 144 | 'no-unexpected-multiline': 2, 145 | 'no-unmodified-loop-condition': 2, 146 | 'no-unneeded-ternary': [2, { 147 | 'defaultAssignment': false 148 | }], 149 | 'no-unreachable': 2, 150 | 'no-unsafe-finally': 2, 151 | 'no-unused-vars': [2, { 152 | 'vars': 'all', 153 | 'args': 'none' 154 | }], 155 | 'no-useless-call': 2, 156 | 'no-useless-computed-key': 2, 157 | 'no-useless-constructor': 2, 158 | 'no-useless-escape': 0, 159 | 'no-whitespace-before-property': 2, 160 | 'no-with': 2, 161 | 'one-var': [2, { 162 | 'initialized': 'never' 163 | }], 164 | 'operator-linebreak': [2, 'after', { 165 | 'overrides': { 166 | '?': 'before', 167 | ':': 'before' 168 | } 169 | }], 170 | 'padded-blocks': [2, 'never'], 171 | // 使用单引号 172 | // 'quotes': [2, 'single', { 173 | // 'avoidEscape': true, 174 | // 'allowTemplateLiterals': true 175 | // }], 176 | 'semi': [2, 'never'], 177 | 'semi-spacing': [2, { 178 | 'before': false, 179 | 'after': true 180 | }], 181 | // 大括号前加空格 182 | 'space-before-blocks': [2, 'always'], 183 | // 空格之前的函数括号 184 | // 'space-before-function-paren': [2, 'never'], 185 | 'space-in-parens': [2, 'never'], 186 | 'space-infix-ops': 2, 187 | 'space-unary-ops': [2, { 188 | 'words': true, 189 | 'nonwords': false 190 | }], 191 | // 注释需要加空格 192 | // 'spaced-comment': [2, 'always', { 193 | // 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] 194 | // }], 195 | 'template-curly-spacing': [2, 'never'], 196 | 'use-isnan': 2, 197 | 'valid-typeof': 2, 198 | 'wrap-iife': [2, 'any'], 199 | 'yield-star-spacing': [2, 'both'], 200 | 'yoda': [2, 'never'], 201 | 'prefer-const': 2, 202 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, 203 | // 对象左右加空格 204 | // 'object-curly-spacing': [2, 'always', { 205 | // objectsInObjects: false 206 | // }], 207 | 'array-bracket-spacing': [2, 'never'] 208 | } 209 | } 210 | 211 | -------------------------------------------------------------------------------- /.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 | .vscode 11 | *.suo 12 | *.ntvs* 13 | *.njsproj 14 | *.sln 15 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | "postcss-import": {}, 6 | "postcss-url": {}, 7 | // to edit target browsers: use "browserslist" field in package.json 8 | "autoprefixer": {} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 前言 2 | * 本项目仅供交流和学习使用 3 | * 项目出现的任何BUG和需要优化的地方请 PR 或 ISSUES, 作者不保证会第一时间会修改,只有在业余时间才会进行修改 4 | * 如果觉得不错,请帮忙点个star ,举手之劳 5 | * 作者一直都是把github当U盘用, 所以请不要在意master分支提交那么多次 6 | 7 | # 项目地址 8 | * [商城前台-Mobil版 演示地址](http://www.masterjoy.top) 9 | * [商城前台-Mobil版 github](https://github.com/MasterJoyHunan/app) 10 | * [商城后台-PC版 演示地址](http://www.masterjoy.top/root) 11 | * [商城后台-PC版 github](https://github.com/MasterJoyHunan/adminForVue) 12 | * [商城后台 php源码 github](https://github.com/MasterJoyHunan/shopAdmin) 13 | 14 | # 项目介绍 15 | #### 商城前台-Mobil版 16 | ___ 17 | > 使用VUE作为主框架编写的一套简单的商城系统, 使用vux作为css框架(作者css太弱了,其实里面的css有能力的完全可以自己重写).麻雀虽小,五脏俱全. 能实现完整的购物流程, 该项目没有使用各种复杂的代码 18 | > > 定位: 适合初学者想学习VUE,又没有几个合适的项目练手的朋友.学习和使用VUE的各种特性和语法. 19 | > 本项目没有文档和测试,不保证安全和性能,仅仅用来学习交流 20 | 21 | 该项目的功能含有: 22 | 23 | * 登录 24 | * 首页 25 | * 分类 26 | * 购物车 27 | * 个人中心 28 | * 商品详情 29 | * 商品SKU选择 30 | * 立即购买 31 | * 加入购物车 32 | * 订单列表 33 | * 订单详情 34 | * .... 35 | 36 | 有些功能由于能力,精力限制,暂时还不完善,请不要纠结 37 | 图片展示: 38 | ![登录](http://www.masterjoy.top/uploads/app/login.png) 39 | ![首页](http://www.masterjoy.top/uploads/app/index.png) 40 | ![分类](http://www.masterjoy.top/uploads/app/cate.png) 41 | ![个人中心](http://www.masterjoy.top/uploads/app/member.png) 42 | ![商品](http://www.masterjoy.top/uploads/app/detail2.png) 43 | ![商品](http://www.masterjoy.top/uploads/app/detail.png) 44 | ![订单](http://www.masterjoy.top/uploads/app/order.png) 45 | #### 商城后台-PC版 46 | ___ 47 | > 使用VUE作为主框架编写的一套简单的商城后台系统, 使用element-ui为css框架(作者css太弱了,其实里面的css有能力的完全可以自己重写).麻雀虽小,五脏俱全. 能实现完整的购物流程, 该项目没有使用各种复杂的代码 48 | > > 定位: 适合初学者想学习VUE,又没有几个合适的项目练手的朋友.学习和使用VUE的各种特性和语法. 49 | > 本项目没有文档和测试,不保证安全和性能,仅仅用来学习交流 50 | 51 | * 权限管理 52 | * 列表 53 | * 分页 54 | * 对应前台的功能 55 | * .... 56 | 57 | 有些功能由于能力,精力限制,暂时还不完善,请不要纠结 58 | 图片展示: 59 | ![登录](http://www.masterjoy.top/uploads/root/login.png) 60 | ![首页](http://www.masterjoy.top/uploads/root/index.png) 61 | ![分类](http://www.masterjoy.top/uploads/root/cate.png) 62 | ![权限管理](http://www.masterjoy.top/uploads/root/node.png) 63 | 64 | # 作者简介 65 | 作者是半路出家自学的PHP的程序员,fu南人, 主要从事后端PHP开发, 从业3年,PHP也不是很熟, 前端也不是很强, 就这样吧, 如有对项目有疑问或需要联系作者, 请 PR 或者 issuse 或者发邮箱 386442876@qq.com 66 | # 基于 67 | 本项目或多或少用到了别人的代码,确实做了很多次伸手党(注: 在MIT协议情况下),在此谢谢在GitHub上的大神 68 | 感谢他们开源精神,以下 69 | * [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin/blob/master/README.zh-CN.md) 70 | * vue-element-admin 是一个后台集成解决方案,它基于 Vue.js 和 element。它使用了最新的前端技术栈,内置了i18国际化解决方案,动态路由,权限验证等很多功能特性,相信不管你的需求是什么,本项目都能帮助到你。 71 | # 多说两句 72 | 前端的变化速度日新月异, 以前很火的Jquery我们公司已经不怎么用了,而新的MVVM的框架将成为主流,而VUE又是其中佼佼者, 由国人大神尤雨溪主导开发,中文文档非常友好,社区非常繁荣. 73 | 现在学习前端可以构建单页面应用,可以打包成APP IOS, 甚至可以打包成桌面应用,让我这个学PHP的也心动不已.前端实在是太棒了!希望大家能早日精通前端, 升职加薪,赢取白富美 74 | # 技术栈 75 | * 商城前台-Mobil版 76 | * vue 77 | * vue-cli 78 | * less 79 | * vue-router 80 | * vuex 81 | * vux 82 | * axios 83 | * es-lint 84 | * better-scroll 85 | * 商城后台-PC版 86 | * vue 87 | * vue-cli 88 | * scss 89 | * vue-router 90 | * vuex 91 | * element-ui 92 | * axios 93 | * es-lint 94 | * echarts 95 | * es6-promise 96 | * 商城后台 97 | * think-php 5.0 98 | 99 | # 搭建本地服务 100 | > 1. 克隆https://github.com/MasterJoyHunan/shopAdmin到本地,并把项目根目录的里的/data/xxx.sql的数据库文件给导入 101 | 102 | 注意: 103 | * 先创建shop_template数据库 104 | * 再运行进行导入 105 | * github上上传的时候,我忽略了database.php文件,请自己创建 106 | * database.php下 107 | * database = '你的数据库', 108 | * prefix = 'mj_' , 109 | * mysql_path' => '备份文件所在的目录' 110 | 111 | 以上运行,如果没报错,可以进行下一步了 112 | > 2.克隆https://github.com/MasterJoyHunan/shopAdmin到本地, npm install && npm run dev 113 | 114 | 注意: 115 | * 由于shopAdmin是单独项目, js请求会跨域, 导致请求不成功, 所幸vue-cli提供了一个代理的功能. 进入shopAdmin/config/index.js, 修改以下内容 116 | 117 | proxyTable: { 118 | "/shop": { 119 | target: "http://localhost/web/public/shop", //修改为你需要调用api入口 120 | changeOrigin: true, 121 | pathRewrite: { 122 | "^/shop": "/" 123 | } 124 | } 125 | }, 126 | // 该代码是指, 所有调用/shop的地方都换装换成http://localhost/web/public/shop 127 | 128 | 接下来,运行下面的操作 129 | 130 | # 运行VUE项目 131 | ``` bash 132 | # 安装依赖 133 | npm install 134 | 135 | # 运行项目 136 | npm run dev 137 | 138 | # 打包 139 | npm run build 140 | 141 | # build for production and view the bundle analyzer report 142 | npm run build --report 143 | ``` 144 | 145 | # 协议 146 | > license MIT -------------------------------------------------------------------------------- /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/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MasterJoyHunan/app/a5199424830c1b892ee52ff28d4f96e392124be0/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 | publicPath: '../../', 50 | use: loaders, 51 | fallback: 'vue-style-loader' 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 | const vuxLoader = require('vux-loader') 7 | function resolve (dir) { 8 | return path.join(__dirname, '..', dir) 9 | } 10 | 11 | const createLintingRule = () => ({ 12 | test: /\.(js|vue)$/, 13 | loader: 'eslint-loader', 14 | enforce: 'pre', 15 | include: [resolve('src'), resolve('test')], 16 | options: { 17 | formatter: require('eslint-friendly-formatter'), 18 | emitWarning: !config.dev.showEslintErrorsInOverlay 19 | } 20 | }) 21 | 22 | 23 | const webpackConfig = { 24 | context: path.resolve(__dirname, '../'), 25 | entry: { 26 | app: './src/main.js' 27 | }, 28 | output: { 29 | path: config.build.assetsRoot, 30 | filename: '[name].js', 31 | publicPath: process.env.NODE_ENV === 'production' 32 | ? config.build.assetsPublicPath 33 | : config.dev.assetsPublicPath 34 | }, 35 | resolve: { 36 | extensions: ['.js', '.vue', '.json'], 37 | alias: { 38 | 'vue$': 'vue/dist/vue.esm.js', 39 | '@': resolve('src'), 40 | } 41 | }, 42 | module: { 43 | rules: [ 44 | ...(config.dev.useEslint ? [createLintingRule()] : []), 45 | { 46 | test: /\.vue$/, 47 | loader: 'vue-loader', 48 | options: vueLoaderConfig 49 | }, 50 | { 51 | test: /\.js$/, 52 | loader: 'babel-loader', 53 | include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] 54 | }, 55 | { 56 | test: /\.svg$/, 57 | loader: 'svg-sprite-loader', 58 | include: [resolve('src/components/common/icon')], 59 | options: { 60 | symbolId: 'icon-[name]' 61 | } 62 | }, 63 | { 64 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 65 | loader: 'url-loader', 66 | exclude: [resolve('src/components/common/icon')], 67 | options: { 68 | limit: 10000, 69 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 70 | } 71 | }, 72 | { 73 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 74 | loader: 'url-loader', 75 | options: { 76 | limit: 10000, 77 | name: utils.assetsPath('media/[name].[hash:7].[ext]') 78 | } 79 | }, 80 | { 81 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 82 | loader: 'url-loader', 83 | options: { 84 | limit: 10000, 85 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 86 | } 87 | } 88 | ] 89 | }, 90 | node: { 91 | // prevent webpack from injecting useless setImmediate polyfill because Vue 92 | // source contains it (although only uses it if it's native). 93 | setImmediate: false, 94 | // prevent webpack from injecting mocks to Node native modules 95 | // that does not make sense for the client 96 | dgram: 'empty', 97 | fs: 'empty', 98 | net: 'empty', 99 | tls: 'empty', 100 | child_process: 'empty' 101 | } 102 | } 103 | 104 | module.exports = vuxLoader.merge(webpackConfig, { 105 | plugins: ['vux-ui'] 106 | }) -------------------------------------------------------------------------------- /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 | 13 | const HOST = process.env.HOST 14 | const PORT = process.env.PORT && Number(process.env.PORT) 15 | 16 | const devWebpackConfig = merge(baseWebpackConfig, { 17 | module: { 18 | rules: utils.styleLoaders({ 19 | sourceMap: config.dev.cssSourceMap, 20 | usePostCSS: true 21 | }) 22 | }, 23 | // cheap-module-eval-source-map is faster for development 24 | devtool: config.dev.devtool, 25 | 26 | // these devServer options should be customized in /config/index.js 27 | devServer: { 28 | clientLogLevel: "warning", 29 | historyApiFallback: { 30 | rewrites: [ 31 | { 32 | from: /.*/, 33 | to: path.posix.join( 34 | config.dev.assetsPublicPath, 35 | "index.html" 36 | ) 37 | } 38 | ] 39 | }, 40 | hot: true, 41 | contentBase: false, // since we use CopyWebpackPlugin. 42 | compress: true, 43 | host: HOST || config.dev.host, 44 | port: PORT || config.dev.port, 45 | open: config.dev.autoOpenBrowser, 46 | overlay: config.dev.errorOverlay 47 | ? { warnings: false, errors: true } 48 | : false, 49 | publicPath: config.dev.assetsPublicPath, 50 | proxy: config.dev.proxyTable, 51 | quiet: true, // necessary for FriendlyErrorsPlugin 52 | watchOptions: { 53 | poll: config.dev.poll 54 | } 55 | }, 56 | plugins: [ 57 | new webpack.DefinePlugin({ 58 | "process.env": require("../config/dev.env") 59 | }), 60 | new webpack.HotModuleReplacementPlugin(), 61 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. 62 | new webpack.NoEmitOnErrorsPlugin(), 63 | // https://github.com/ampedandwired/html-webpack-plugin 64 | new HtmlWebpackPlugin({ 65 | filename: "index.html", 66 | template: "index.html", 67 | favicon: "./static/favicon.ico", 68 | inject: true 69 | }), 70 | // copy custom static assets 71 | new CopyWebpackPlugin([ 72 | { 73 | from: path.resolve(__dirname, "../static"), 74 | to: config.dev.assetsSubDirectory, 75 | ignore: [".*"] 76 | } 77 | ]) 78 | ] 79 | }) 80 | 81 | module.exports = new Promise((resolve, reject) => { 82 | portfinder.basePort = process.env.PORT || config.dev.port 83 | portfinder.getPort((err, port) => { 84 | if (err) { 85 | reject(err) 86 | } else { 87 | // publish the new Port, necessary for e2e tests 88 | process.env.PORT = port 89 | // add port to devServer config 90 | devWebpackConfig.devServer.port = port 91 | 92 | // Add FriendlyErrorsPlugin 93 | devWebpackConfig.plugins.push( 94 | new FriendlyErrorsPlugin({ 95 | compilationSuccessInfo: { 96 | messages: [ 97 | `Your application is running here: http://${ 98 | devWebpackConfig.devServer.host 99 | }:${port}` 100 | ] 101 | }, 102 | onErrors: config.dev.notifyOnErrors 103 | ? utils.createNotifierCallback() 104 | : undefined 105 | }) 106 | ) 107 | 108 | resolve(devWebpackConfig) 109 | } 110 | }) 111 | }) 112 | -------------------------------------------------------------------------------- /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 | 14 | const env = require("../config/prod.env") 15 | 16 | const webpackConfig = merge(baseWebpackConfig, { 17 | module: { 18 | rules: utils.styleLoaders({ 19 | sourceMap: config.build.productionSourceMap, 20 | extract: true, 21 | usePostCSS: true 22 | }) 23 | }, 24 | devtool: config.build.productionSourceMap ? config.build.devtool : false, 25 | output: { 26 | path: config.build.assetsRoot, 27 | filename: utils.assetsPath("js/[name].[chunkhash].js"), 28 | chunkFilename: utils.assetsPath("js/[id].[chunkhash].js") 29 | }, 30 | plugins: [ 31 | // http://vuejs.github.io/vue-loader/en/workflow/production.html 32 | new webpack.DefinePlugin({ 33 | "process.env": env 34 | }), 35 | new UglifyJsPlugin({ 36 | uglifyOptions: { 37 | compress: { 38 | warnings: false 39 | } 40 | }, 41 | sourceMap: config.build.productionSourceMap, 42 | parallel: true 43 | }), 44 | // extract css into its own file 45 | new ExtractTextPlugin({ 46 | filename: utils.assetsPath("css/[name].[contenthash].css"), 47 | // Setting the following option to `false` will not extract CSS from codesplit chunks. 48 | // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. 49 | // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, 50 | // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 51 | allChunks: true 52 | }), 53 | // Compress extracted CSS. We are using this plugin so that possible 54 | // duplicated CSS from different components can be deduped. 55 | new OptimizeCSSPlugin({ 56 | cssProcessorOptions: config.build.productionSourceMap 57 | ? { safe: true, map: { inline: false } } 58 | : { safe: true } 59 | }), 60 | // generate dist index.html with correct asset hash for caching. 61 | // you can customize output by editing /index.html 62 | // see https://github.com/ampedandwired/html-webpack-plugin 63 | new HtmlWebpackPlugin({ 64 | filename: config.build.index, 65 | template: "index.html", 66 | favicon: "./static/favicon.ico", 67 | inject: true, 68 | minify: { 69 | removeComments: true, 70 | collapseWhitespace: true, 71 | removeAttributeQuotes: true 72 | // more options: 73 | // https://github.com/kangax/html-minifier#options-quick-reference 74 | }, 75 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin 76 | chunksSortMode: "dependency" 77 | }), 78 | // keep module.id stable when vendor modules does not change 79 | new webpack.HashedModuleIdsPlugin(), 80 | // enable scope hoisting 81 | new webpack.optimize.ModuleConcatenationPlugin(), 82 | // split vendor js into its own file 83 | new webpack.optimize.CommonsChunkPlugin({ 84 | name: "vendor", 85 | minChunks(module) { 86 | // any required modules inside node_modules are extracted to vendor 87 | return ( 88 | module.resource && 89 | /\.js$/.test(module.resource) && 90 | module.resource.indexOf( 91 | path.join(__dirname, "../node_modules") 92 | ) === 0 93 | ) 94 | } 95 | }), 96 | // extract webpack runtime and module manifest to its own file in order to 97 | // prevent vendor hash from being updated whenever app bundle is updated 98 | new webpack.optimize.CommonsChunkPlugin({ 99 | name: "manifest", 100 | minChunks: Infinity 101 | }), 102 | // This instance extracts shared chunks from code splitted chunks and bundles them 103 | // in a separate chunk, similar to the vendor chunk 104 | // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk 105 | new webpack.optimize.CommonsChunkPlugin({ 106 | name: "app", 107 | async: "vendor-async", 108 | children: true, 109 | minChunks: 3 110 | }), 111 | 112 | // copy custom static assets 113 | new CopyWebpackPlugin([ 114 | { 115 | from: path.resolve(__dirname, "../static"), 116 | to: config.build.assetsSubDirectory, 117 | ignore: [".*"] 118 | } 119 | ]) 120 | ] 121 | }) 122 | 123 | if (config.build.productionGzip) { 124 | const CompressionWebpackPlugin = require("compression-webpack-plugin") 125 | 126 | webpackConfig.plugins.push( 127 | new CompressionWebpackPlugin({ 128 | asset: "[path].gz[query]", 129 | algorithm: "gzip", 130 | test: new RegExp( 131 | "\\.(" + config.build.productionGzipExtensions.join("|") + ")$" 132 | ), 133 | threshold: 10240, 134 | minRatio: 0.8 135 | }) 136 | ) 137 | } 138 | 139 | if (config.build.bundleAnalyzerReport) { 140 | const BundleAnalyzerPlugin = require("webpack-bundle-analyzer") 141 | .BundleAnalyzerPlugin 142 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 143 | } 144 | 145 | module.exports = webpackConfig 146 | -------------------------------------------------------------------------------- /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 | CDN: '"http://localhost/web/public/uploads/"', 8 | BASE_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 | "/shop": { 14 | target: "http://localhost/web/public/shop", 15 | changeOrigin: true, 16 | pathRewrite: { 17 | "^/shop": "/" 18 | } 19 | } 20 | }, 21 | 22 | // Various Dev Server settings 23 | host: "localhost", // can be overwritten by process.env.HOST 24 | port: 9000, // 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 | // Use Eslint Loader? 31 | // If true, your code will be linted during bundling and 32 | // linting errors and warnings will be shown in the console. 33 | useEslint: true, 34 | // If true, eslint errors and warnings will also be shown in the error overlay 35 | // in the browser. 36 | showEslintErrorsInOverlay: false, 37 | 38 | /** 39 | * Source Maps 40 | */ 41 | 42 | // https://webpack.js.org/configuration/devtool/#development 43 | devtool: "cheap-module-eval-source-map", 44 | 45 | // If you have problems debugging vue-files in devtools, 46 | // set this to false - it *may* help 47 | // https://vue-loader.vuejs.org/en/options.html#cachebusting 48 | cacheBusting: true, 49 | 50 | cssSourceMap: true 51 | }, 52 | 53 | build: { 54 | // Template for index.html 55 | index: path.resolve(__dirname, "../index/index.html"), 56 | 57 | // Paths 58 | assetsRoot: path.resolve(__dirname, "../index"), 59 | assetsSubDirectory: "static", 60 | assetsPublicPath: "./", 61 | 62 | /** 63 | * Source Maps 64 | */ 65 | 66 | productionSourceMap: false, 67 | // https://webpack.js.org/configuration/devtool/#production 68 | devtool: "#source-map", 69 | 70 | // Gzip off by default as many popular static hosts such as 71 | // Surge or Netlify already gzip all static assets for you. 72 | // Before setting to `true`, make sure to: 73 | // npm install --save-dev compression-webpack-plugin 74 | productionGzip: false, 75 | productionGzipExtensions: ["js", "css"], 76 | 77 | // Run the build command with an extra argument to 78 | // View the bundle analyzer report after build finishes: 79 | // `npm run build --report` 80 | // Set to `true` or `false` to always turn it on or off 81 | bundleAnalyzerReport: process.env.npm_config_report 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | module.exports = { 3 | NODE_ENV: '"production"', 4 | CDN: '"/uploads/"', 5 | BASE_API: '"/"', 6 | } 7 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | masterJoy商城 8 | 9 | 10 | 14 |
15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /index/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MasterJoyHunan/app/a5199424830c1b892ee52ff28d4f96e392124be0/index/favicon.ico -------------------------------------------------------------------------------- /index/index.html: -------------------------------------------------------------------------------- 1 | masterJoy商城
-------------------------------------------------------------------------------- /index/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MasterJoyHunan/app/a5199424830c1b892ee52ff28d4f96e392124be0/index/static/favicon.ico -------------------------------------------------------------------------------- /index/static/img/headerimg.5188326.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MasterJoyHunan/app/a5199424830c1b892ee52ff28d4f96e392124be0/index/static/img/headerimg.5188326.png -------------------------------------------------------------------------------- /index/static/js/0.4f93e6f06540dc6b7883.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([0],{"0FxO":function(t,e,n){"use strict";e.a=function(t,e){if(/^javas/.test(t)||!t)return;"object"===(void 0===t?"undefined":r()(t))||e&&"string"==typeof t&&!/http/.test(t)?"object"===(void 0===t?"undefined":r()(t))&&!0===t.replace?e.replace(t):"BACK"===t?e.go(-1):e.push(t):window.location.href=t};var i=n("pFYg"),r=n.n(i)},"4f4V":function(t,e){},"8sKR":function(t,e){},DA34:function(t,e,n){"use strict";String,String,Object;var i={name:"plant",data:function(){return{cdn:"/uploads/"}},props:{backColor:{type:String,default:"#ddd"},img:{type:String,default:""},item:{type:Object,default:function(){return{img:""}}}},methods:{clickItem:function(t,e){0===e?this.$emit("clickPlant",t):this.$emit("clickImg",t)}},computed:{thisImg:function(){return(this.cdn+(this.img?this.img:this.item.img)).replace(/\\/g,"/")}}},r={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"mj-plant product",on:{click:function(e){e.stopPropagation(),t.clickItem(t.item,0)}}},[n("div",{staticClass:"masker",style:{backgroundImage:"url("+t.thisImg+")"},on:{click:function(e){e.stopPropagation(),t.clickItem(t.item,1)}}}),t._v(" "),n("div",{staticClass:"blur-container",style:{backgroundColor:t.backColor}}),t._v(" "),t._t("content")],2)},staticRenderFns:[]};var a=n("VU/8")(i,r,!1,function(t){n("4f4V")},null,null);e.a=a.exports},Dd8w:function(t,e,n){"use strict";e.__esModule=!0;var i,r=n("woOf"),a=(i=r)&&i.__esModule?i:{default:i};e.default=a.default||function(t){for(var e=1;e0&&void 0!==arguments[0]?arguments[0]:[];return(arguments.length>1&&void 0!==arguments[1]?arguments[1]:[]).map(function(e){return function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],e=arguments[1];if(!t.length)return e;if("string"==typeof t[0])return e;var n=t.filter(function(t){return t.key===e});return n.length?n[0].value||n[0].label:e}(t,e)})},y=n("HHx2"),b=n.n(y);h.a,d.a,u.a,String,Boolean,String,Boolean,Array,Array,Number,Number,Boolean,Boolean,Boolean,String,Boolean;var x={name:"checklist",components:{Tip:l,Icon:h.a,InlineDesc:d.a},filters:{getValue:m,getKey:v},mixins:[u.a],props:{name:String,showError:Boolean,title:String,required:{type:Boolean,default:!1},options:{type:Array,required:!0},value:{type:Array,default:function(){return[]}},max:Number,min:Number,fillMode:Boolean,randomOrder:Boolean,checkDisabled:{type:Boolean,default:!0},labelPosition:{type:String,default:"right"},disabled:Boolean},data:function(){return{currentValue:[],currentOptions:this.options,tempValue:""}},beforeUpdate:function(){if(this.isRadio){var t=this.currentValue.length;t>1&&(this.currentValue=[this.currentValue[t-1]]);var e=V(this.currentValue);this.tempValue=e.length?e[0]:""}},created:function(){this.handleChangeEvent=!0,this.value&&(this.currentValue=this.value,this.isRadio&&(this.tempValue=this.isRadio?this.value[0]:this.value)),this.randomOrder?this.currentOptions=b()(this.options):this.currentOptions=this.options},methods:{getValue:m,getKey:v,getInlineDesc:g,getFullValue:function(){var t=_(this.options,this.value);return this.currentValue.map(function(e,n){return{value:e,label:t[n]}})},isDisabled:function(t){return!!this.checkDisabled&&(this._max>1&&(-1===this.currentValue.indexOf(t)&&this.currentValue.length===this._max))}},computed:{isRadio:function(){return void 0!==this.max&&1===this.max},_total:function(){return this.fillMode?this.options.length+1:this.options.length},_min:function(){if(!this.required&&!this.min)return 0;if(!this.required&&this.min)return Math.min(this._total,this.min);if(this.required){if(this.min){var t=Math.max(1,this.min);return Math.min(this._total,t)}return 1}},_max:function(){return(this.required||this.max)&&this.max?this.max>this._total?this._total:this.max:this._total},valid:function(){return this.currentValue.length>=this._min&&this.currentValue.length<=this._max}},watch:{tempValue:function(t){var e=t?[t]:[];this.$emit("input",e),this.$emit("on-change",e,_(this.options,e))},value:function(t){s()(t)!==s()(this.currentValue)&&(this.currentValue=t)},options:function(t){this.currentOptions=t},currentValue:function(t){var e=V(t);if(!this.isRadio){this.$emit("input",e),this.$emit("on-change",e,_(this.options,e));var n={};this._min&&(this.required?this.currentValue.length-1:t.currentValue},on:{change:function(n){var i=t.currentValue,r=n.target,a=!!r.checked;if(Array.isArray(i)){var s=t.getKey(e),u=t._i(i,s);r.checked?u<0&&(t.currentValue=i.concat([s])):u>-1&&(t.currentValue=i.slice(0,u).concat(i.slice(u+1)))}else t.currentValue=a}}}),t._v(" "),n("i",{staticClass:"weui-icon-checked vux-checklist-icon-checked"})]),t._v(" "),n("div",{staticClass:"weui-cell__bd"},[n("p",{domProps:{innerHTML:t._s(t.getValue(e))}}),t._v(" "),t.getInlineDesc(e)?n("inline-desc",[t._v(t._s(t.getInlineDesc(e)))]):t._e()],1)])})),t._v(" "),t._t("footer")],2)},staticRenderFns:[]};var w=n("VU/8")(x,k,!1,function(t){n("UCg8")},null,null);e.a=w.exports},f6Hi:function(t,e,n){"use strict";var i=n("OFgA");e.a={mixins:[i.a],props:{required:{type:Boolean,default:!1}},created:function(){this.handleChangeEvent=!1},computed:{dirty:{get:function(){return!this.pristine},set:function(t){this.pristine=!t}},invalid:function(){return!this.valid}},methods:{setTouched:function(){this.touched=!0}},watch:{value:function(t){!0===this.pristine&&(this.pristine=!1),this.handleChangeEvent||(this.$emit("on-change",t),this.$emit("input",t))}},data:function(){return{errors:{},pristine:!0,touched:!1}}}},jCps:function(t,e,n){"use strict";n.d(e,"b",function(){return i}),n.d(e,"a",function(){return r});var i={data:function(){return{payFlag:!1,options:[{key:"1",value:"内置支付"},{key:"2",value:"微信支付(开发中)"},{key:"3",value:"支付宝支付(开发中)"}],checklist:[]}}},r={data:function(){return{current_page:1,last_page:0,per_page:10,total:0}},methods:{_getData:function(){throw new Error("请先请求数据")}}}},kbG3:function(t,e,n){"use strict";var i={render:function(){var t=this.$createElement;return(this._self._c||t)("span",{staticClass:"vux-label-desc"},[this._t("default")],2)},staticRenderFns:[]};var r=n("VU/8")({name:"inline-desc"},i,!1,function(t){n("b1Ix")},null,null);e.a=r.exports},mvHQ:function(t,e,n){t.exports={default:n("qkKv"),__esModule:!0}},oWtu:function(t,e,n){"use strict";String,Boolean;var i={name:"icon",props:{type:String,isMsg:Boolean},computed:{className:function(){return"weui-icon weui_icon_"+this.type+" weui-icon-"+this.type.replace(/_/g,"-")}}},r={render:function(){var t=this.$createElement;return(this._self._c||t)("i",{class:[this.className,this.isMsg?"weui-icon_msg":""]})},staticRenderFns:[]};var a=n("VU/8")(i,r,!1,function(t){n("qzB0")},null,null);e.a=a.exports},qkKv:function(t,e,n){var i=n("FeBl"),r=i.JSON||(i.JSON={stringify:JSON.stringify});t.exports=function(t){return r.stringify.apply(r,arguments)}},qzB0:function(t,e){},wxAW:function(t,e,n){"use strict";e.__esModule=!0;var i,r=n("C4MV"),a=(i=r)&&i.__esModule?i:{default:i};e.default=function(){function t(t,e){for(var n=0;n=1?a("div",{staticClass:"flex-between"},[a("span",[t._v("支付方式: ")]),t._v(" "),a("span",[t._v(t._s(t.payWay[t.order.pay_way]))])]):t._e(),t._v(" "),a("div",{staticClass:"flex-between"},[a("span",[t._v("下单时间: ")]),t._v(" "),a("span",[t._v(t._s(t.order.add_date))])]),t._v(" "),t.order.status>=1?a("div",{staticClass:"flex-between"},[a("span",[t._v("支付时间: ")]),t._v(" "),a("span",[t._v(t._s(t.order.pay_date))])]):t._e(),t._v(" "),t.order.status>=2?a("div",{staticClass:"flex-between"},[a("span",[t._v("发货时间: ")]),t._v(" "),a("span",[t._v(t._s(t.order.send_date))])]):t._e(),t._v(" "),t.order.status>=3?a("div",{staticClass:"flex-between"},[a("span",[t._v("收货时间: ")]),t._v(" "),a("span",[t._v(t._s(t.order.get_date))])]):t._e()]),t._v(" "),t.order.status>=2?a("div",{staticClass:"express"},[a("div",{staticClass:"flex-between"},[a("span",[t._v("快递公司: ")]),t._v(" "),a("span",[t._v(t._s(t.order.express))])]),t._v(" "),a("div",{staticClass:"flex-between"},[t._m(0),t._v(" "),a("span",{staticClass:"express-no"},[t._v(t._s(t.order.express_no))])])]):t._e(),t._v(" "),a("x-dialog",{attrs:{"hide-on-blur":""},model:{value:t.payFlag,callback:function(s){t.payFlag=s},expression:"payFlag"}},[a("div",{staticClass:"pay"},[a("checklist",{attrs:{"label-position":"right",required:"",options:t.options,max:1},model:{value:t.checklist,callback:function(s){t.checklist=s},expression:"checklist"}}),t._v(" "),a("div",{staticClass:"btn",on:{click:function(s){t.handelPay()}}},[t._v("确定")])],1)])],1)},staticRenderFns:[function(){var t=this.$createElement,s=this._self._c||t;return s("span",[this._v("快递单号:\n "),s("span",{staticStyle:{"font-size":"12px"}},[this._v("(点击查看物流)")])])}]};var c=a("VU/8")(o,d,!1,function(t){a("NMlo")},null,null);s.default=c.exports},NMlo:function(t,s){}}); -------------------------------------------------------------------------------- /index/static/js/15.8c3bf566c995d9acf253.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([15],{Mx6r:function(t,s,o){"use strict";Object.defineProperty(s,"__esModule",{value:!0});var e=o("HulU"),i={name:"reg",data:function(){return{info:{tel:"",password:"",confirm_password:""}}},methods:{doLogin:function(){var t=this;Object(e.a)({url:"/shop/login/register",method:"post",data:this.info}).then(function(s){t.$router.push("/index")}).catch(function(t){console.log(t)})},login:function(){this.$router.push("/login")}}},n={render:function(){var t=this,s=t.$createElement,o=t._self._c||s;return o("div",{attrs:{id:"reg"}},[t._m(0),t._v(" "),o("div",{staticClass:"container"},[o("div",{staticClass:"login-input username"},[o("svg-icon",{attrs:{"icon-class":"username",size:"24"}}),t._v(" "),o("input",{directives:[{name:"model",rawName:"v-model",value:t.info.tel,expression:"info.tel"}],attrs:{placeholder:"请输入手机号",type:"text"},domProps:{value:t.info.tel},on:{input:function(s){s.target.composing||t.$set(t.info,"tel",s.target.value)}}})],1),t._v(" "),o("div",{staticClass:"login-input password"},[o("svg-icon",{attrs:{"icon-class":"password",size:"24"}}),t._v(" "),o("input",{directives:[{name:"model",rawName:"v-model",value:t.info.password,expression:"info.password"}],attrs:{placeholder:"请输入密码",type:"password"},domProps:{value:t.info.password},on:{input:function(s){s.target.composing||t.$set(t.info,"password",s.target.value)}}})],1),t._v(" "),o("div",{staticClass:"login-input password"},[o("svg-icon",{attrs:{"icon-class":"password",size:"24"}}),t._v(" "),o("input",{directives:[{name:"model",rawName:"v-model",value:t.info.confirm_password,expression:"info.confirm_password"}],attrs:{placeholder:"请再次输入密码",type:"password"},domProps:{value:t.info.confirm_password},on:{input:function(s){s.target.composing||t.$set(t.info,"confirm_password",s.target.value)}}})],1),t._v(" "),o("button",{staticClass:"submit",on:{click:t.doLogin}},[t._v("注册")]),t._v(" "),o("a",{staticClass:"reg",on:{click:t.login}},[t._v("已有账号? 去登录")])])])},staticRenderFns:[function(){var t=this.$createElement,s=this._self._c||t;return s("div",{staticClass:"container"},[s("div",{staticClass:"logo"}),this._v(" "),s("h1",{staticClass:"title-1"},[this._v("MasterJoy")]),this._v(" "),s("h1",{staticClass:"title-2"},[this._v("SHOP")])])}]};var a=o("VU/8")(i,n,!1,function(t){o("bEw0")},null,null);s.default=a.exports},bEw0:function(t,s){}}); -------------------------------------------------------------------------------- /index/static/js/8.d09ddaf8ad78ecfe9209.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([8],{EmH9:function(e,t,s){"use strict";var n=s("oWtu"),a=(n.a,Boolean,String,{name:"check-icon",components:{Icon:n.a},methods:{updateValue:function(){this.$emit("update:value",!this.value)}},props:{value:{type:Boolean,default:!1},type:{type:String,default:"default"}}}),d={render:function(){var e=this,t=e.$createElement,s=e._self._c||t;return s("div",{staticClass:"vux-check-icon",on:{click:e.updateValue}},[s("icon",{directives:[{name:"show",rawName:"v-show",value:"default"===e.type&&e.value,expression:"type === 'default' && value"}],attrs:{type:"success"}}),e._v(" "),s("icon",{directives:[{name:"show",rawName:"v-show",value:"plain"===e.type&&e.value,expression:"type === 'plain' && value"}],attrs:{type:"success_circle"}}),e._v(" "),s("icon",{directives:[{name:"show",rawName:"v-show",value:!e.value,expression:"!value"}],attrs:{type:"circle"}}),e._v(" "),s("span",[e._t("default")],2)],1)},staticRenderFns:[]};var i=s("VU/8")(a,d,!1,function(e){s("HqiX")},null,null);t.a=i.exports},HqiX:function(e,t){},gsnN:function(e,t){},rK3p:function(e,t,s){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=s("Dd8w"),a=s.n(n),d=s("NYxO"),i=s("EmH9"),c=s("HulU"),o=(a()({addnew:function(){this.$router.push("/addAddress")},handelEdit:function(e,t){this.$router.push({path:"/addAddress",query:{id:e.id,index:t}})},handelDelete:function(e,t){var s=this;1!=e.is_default?this.$vux.confirm.show({title:"警告",content:"是否确认删除",onConfirm:function(){Object(c.a)({url:"/shop/address/deleteAddress",method:"post",data:{address_id:e.id}}).then(function(e){s.deleteAddress(t)}).catch(function(e){console.log(e)})}}):this.$vux.alert.show("请不要删除默认地址")},handelSetDefault:function(e,t){var s=this;this.$vux.confirm.show({title:"警告",content:"是否将其设为默认地址",onConfirm:function(){Object(c.a)({url:"/shop/address/setDefault",method:"post",data:{address_id:e.id}}).then(function(e){s.setDefautl(t)}).catch(function(e){console.log(e)})}})}},Object(d.d)({deleteAddress:"DELETE_ADDRESS",setDefautl:"SET_ADDRESS_DEFAULT"}),Object(d.b)(["initAddress"])),a()({},Object(d.c)(["addressList"])),i.a,{name:"address-list",created:function(){},methods:a()({addnew:function(){this.$router.push("/addAddress")},handelEdit:function(e,t){this.$router.push({path:"/addAddress",query:{id:e.id,index:t}})},handelDelete:function(e,t){var s=this;1!=e.is_default?this.$vux.confirm.show({title:"警告",content:"是否确认删除",onConfirm:function(){Object(c.a)({url:"/shop/address/deleteAddress",method:"post",data:{address_id:e.id}}).then(function(e){s.deleteAddress(t)}).catch(function(e){console.log(e)})}}):this.$vux.alert.show("请不要删除默认地址")},handelSetDefault:function(e,t){var s=this;this.$vux.confirm.show({title:"警告",content:"是否将其设为默认地址",onConfirm:function(){Object(c.a)({url:"/shop/address/setDefault",method:"post",data:{address_id:e.id}}).then(function(e){s.setDefautl(t)}).catch(function(e){console.log(e)})}})}},Object(d.d)({deleteAddress:"DELETE_ADDRESS",setDefautl:"SET_ADDRESS_DEFAULT"}),Object(d.b)(["initAddress"])),computed:a()({},Object(d.c)(["addressList"])),components:{CheckIcon:i.a}}),l={render:function(){var e=this,t=e.$createElement,s=e._self._c||t;return s("transition",{attrs:{name:"address-list"}},[s("div",{attrs:{id:"address-list"}},[0==e.addressList.length?s("div",{staticClass:"not-address"},[s("svg-icon",{attrs:{"icon-class":"address",color:"#dc7433",size:"100"}}),e._v(" "),s("p",{staticClass:"text"},[e._v("暂时没有添加地址")]),e._v(" "),s("div",{staticClass:"add-new-address",on:{click:e.addnew}},[e._v("添加新的地址")])],1):s("div",{staticClass:"address-list"},[e._l(e.addressList,function(t,n){return s("div",{key:n,staticClass:"address"},[s("div",{staticClass:"name"},[s("span",[e._v(e._s(t.name))]),e._v(" "),s("span",[e._v(e._s(t.tel))])]),e._v(" "),s("div",{staticClass:"address-detail"},[e._v(e._s(t.province)+","+e._s(t.city)+","+e._s(t.area)+","+e._s(t.address))]),e._v(" "),s("div",{staticClass:"action"},[1==t.is_default?s("div",[e._v("默认地址")]):s("div",{on:{click:function(s){e.handelSetDefault(t,n)}}},[s("check-icon"),e._v("设为默认")],1),e._v(" "),s("div",{staticClass:"action-btn"},[s("div",{staticClass:"btn",on:{click:function(s){e.handelEdit(t,n)}}},[s("svg-icon",{attrs:{size:"15","icon-class":"edit"}}),e._v("修改")],1),e._v(" "),s("div",{staticClass:"btn",on:{click:function(s){e.handelDelete(t,n)}}},[s("svg-icon",{attrs:{size:"15","icon-class":"delete"}}),e._v("删除")],1)])])])}),e._v(" "),s("div",{staticClass:"add-new-address2",on:{click:e.addnew}},[e._v("添加新的地址")])],2)])])},staticRenderFns:[]};var r=s("VU/8")(o,l,!1,function(e){s("gsnN")},null,null);t.default=r.exports}}); -------------------------------------------------------------------------------- /index/static/js/manifest.4bb79e78960fd7ed2aec.js: -------------------------------------------------------------------------------- 1 | !function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,o,a){for(var f,d,i,u=0,s=[];u= 6.0.0", 76 | "npm": ">= 3.0.0" 77 | }, 78 | "browserslist": [ 79 | "> 1%", 80 | "last 2 versions", 81 | "not ie <= 8" 82 | ] 83 | } 84 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /src/components/cart/order/addressbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MasterJoyHunan/app/a5199424830c1b892ee52ff28d4f96e392124be0/src/components/cart/order/addressbar.png -------------------------------------------------------------------------------- /src/components/cart/order/index.vue: -------------------------------------------------------------------------------- 1 | 59 | 60 | 159 | 160 | 276 | 277 | -------------------------------------------------------------------------------- /src/components/common/base/bubble.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 126 | 127 | -------------------------------------------------------------------------------- /src/components/common/base/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MasterJoyHunan/app/a5199424830c1b892ee52ff28d4f96e392124be0/src/components/common/base/loading.gif -------------------------------------------------------------------------------- /src/components/common/base/loding.vue: -------------------------------------------------------------------------------- 1 | 6 | 12 | -------------------------------------------------------------------------------- /src/components/common/base/number.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 75 | 76 | 95 | -------------------------------------------------------------------------------- /src/components/common/base/plant.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 50 | 51 | 86 | -------------------------------------------------------------------------------- /src/components/common/base/scroll.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 125 | 126 | -------------------------------------------------------------------------------- /src/components/common/base/svgicon.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 44 | 45 | 50 | -------------------------------------------------------------------------------- /src/components/common/css/common.css: -------------------------------------------------------------------------------- 1 | * { 2 | /* font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", 3 | "Microsoft YaHei", "微软雅黑", Arial, sans-serif; */ 4 | font-weight: lighter; 5 | font-family: "Microsoft YaHei", "微软雅黑"; 6 | } 7 | -------------------------------------------------------------------------------- /src/components/common/icon/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import SvgIcon from '@/components/common/base/svgicon'// svg组件 3 | Vue.component('svg-icon', SvgIcon) 4 | 5 | const requireAll = requireContext => requireContext.keys().map(requireContext) 6 | const req = require.context('./svg', false, /\.svg$/) 7 | requireAll(req) 8 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/add.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/address-list.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/address.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/back.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/cart.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/cart2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/cate.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/delete.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/edit.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/express.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/help.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/home.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/master.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/member.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/message.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/min.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/more.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/order-all.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/order-finish.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/order-send.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/order-wait-pay.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/order-wait-send.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/order.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/password.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/right2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/setting.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/icon/svg/username.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/common/img/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MasterJoyHunan/app/a5199424830c1b892ee52ff28d4f96e392124be0/src/components/common/img/404.png -------------------------------------------------------------------------------- /src/components/common/js/mixin.js: -------------------------------------------------------------------------------- 1 | export const payWayMixin = { 2 | data() { 3 | return { 4 | payFlag: false, // 是否显示加载 5 | options: [ 6 | { key: "1", value: "内置支付" }, 7 | { key: "2", value: "微信支付(开发中)" }, 8 | { key: "3", value: "支付宝支付(开发中)" } 9 | ], 10 | checklist: [] 11 | } 12 | } 13 | } 14 | export const pageMixin = { 15 | data() { 16 | return { 17 | current_page: 1, // 当前页 18 | last_page: 0, // 后面还有多少页? 19 | per_page: 10, // 每页条数 20 | total: 0 // 数据总条数 21 | } 22 | }, 23 | methods: { 24 | // 每页显示条目改变 25 | _getData() { 26 | throw new Error("请先请求数据") 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/components/common/js/public.js: -------------------------------------------------------------------------------- 1 | export function changeTwoDecimal_f (x) { 2 | var f_x = parseFloat(x) 3 | if (isNaN(f_x)) { 4 | // alert('不能输入负数') 5 | return false 6 | } 7 | f_x = Math.round(x * 100) / 100 8 | var s_x = f_x.toString() 9 | var pos_decimal = s_x.indexOf('.') 10 | if (pos_decimal < 0) { 11 | pos_decimal = s_x.length 12 | s_x += '.' 13 | } 14 | while (s_x.length <= pos_decimal + 2) { 15 | s_x += '0' 16 | } 17 | return s_x 18 | } 19 | 20 | export function trueImgUrl(url) { 21 | return url.replace(/\\/g, "/") 22 | } 23 | -------------------------------------------------------------------------------- /src/components/common/js/request.js: -------------------------------------------------------------------------------- 1 | import axios from "axios" 2 | import vue from "vue" 3 | import router from "@/router" 4 | 5 | // 创建axios实例 6 | const service = axios.create({ 7 | baseURL: process.env.BASE_API, // api的base_url 8 | timeout: 15000 // 请求超时时间 9 | }) 10 | 11 | // respone拦截器 12 | service.interceptors.response.use( 13 | response => { 14 | const res = response.data 15 | if (res.status == 404 || res.status == 304) { 16 | //被挤掉线 17 | // vue.$vux.toast.show({ 18 | // text: res.msg, 19 | // type: 'warn', 20 | // width: '80%' 21 | // }) 22 | // 判断是否在是登录和注册页面 23 | if ( 24 | location.href.indexOf("/login") === -1 && 25 | location.href.indexOf("/reg") === -1 26 | ) { 27 | router.push({ path: "/login" }) 28 | } 29 | } 30 | if (res.status == 500) { 31 | //服务器维护 32 | vue.$vux.toast.show({ 33 | text: res.msg, 34 | type: "warn", 35 | width: "80%" 36 | }) 37 | router.push({ path: "/login" }) 38 | } 39 | if (res.status !== 1) { 40 | if (res.msg !== '') { 41 | vue.$vux.toast.text(res.msg) 42 | } 43 | return Promise.reject(response.data) 44 | } 45 | return response.data 46 | }, 47 | error => { 48 | console.log("err" + error) // for debug 49 | return Promise.reject(error) 50 | } 51 | ) 52 | 53 | export default service 54 | -------------------------------------------------------------------------------- /src/components/error.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 28 | 29 | 55 | -------------------------------------------------------------------------------- /src/components/index.vue: -------------------------------------------------------------------------------- 1 | 66 | 67 | 113 | 114 | 125 | -------------------------------------------------------------------------------- /src/components/index/index.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 92 | 93 | 142 | -------------------------------------------------------------------------------- /src/components/member/address/addAddress.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 122 | 123 | 178 | -------------------------------------------------------------------------------- /src/components/member/address/index.vue: -------------------------------------------------------------------------------- 1 | 46 | 47 | 119 | 120 | 222 | -------------------------------------------------------------------------------- /src/components/member/headerimg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MasterJoyHunan/app/a5199424830c1b892ee52ff28d4f96e392124be0/src/components/member/headerimg.png -------------------------------------------------------------------------------- /src/components/member/index.vue: -------------------------------------------------------------------------------- 1 | 132 | 133 | 170 | 171 | 274 | 275 | -------------------------------------------------------------------------------- /src/components/member/login/index.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 62 | 63 | 121 | -------------------------------------------------------------------------------- /src/components/member/login/master.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MasterJoyHunan/app/a5199424830c1b892ee52ff28d4f96e392124be0/src/components/member/login/master.png -------------------------------------------------------------------------------- /src/components/member/login/master1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MasterJoyHunan/app/a5199424830c1b892ee52ff28d4f96e392124be0/src/components/member/login/master1.png -------------------------------------------------------------------------------- /src/components/member/reg/index.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | 69 | 70 | 129 | -------------------------------------------------------------------------------- /src/components/member/reg/master.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MasterJoyHunan/app/a5199424830c1b892ee52ff28d4f96e392124be0/src/components/member/reg/master.png -------------------------------------------------------------------------------- /src/components/member/reg/master1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MasterJoyHunan/app/a5199424830c1b892ee52ff28d4f96e392124be0/src/components/member/reg/master1.png -------------------------------------------------------------------------------- /src/components/member/setting/headerimg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MasterJoyHunan/app/a5199424830c1b892ee52ff28d4f96e392124be0/src/components/member/setting/headerimg.png -------------------------------------------------------------------------------- /src/components/member/setting/index.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 38 | 39 | 105 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue" 2 | import App from "./App" 3 | import router from "./router" 4 | import store from "./store" 5 | import fastclick from "fastclick" 6 | import "@/components/common/icon" // icon 7 | import "./permission" 8 | 9 | fastclick.attach(document.body) 10 | 11 | import { ConfirmPlugin, ToastPlugin, AlertPlugin } from "vux" 12 | Vue.use(ConfirmPlugin) 13 | Vue.use(ToastPlugin) 14 | Vue.use(AlertPlugin) 15 | 16 | import "vux/src/styles/reset.less" 17 | import "@/components/common/css/common.css" 18 | Vue.config.productionTip = false 19 | 20 | /* eslint-disable no-new */ 21 | new Vue({ 22 | el: "#app", 23 | router, 24 | store, 25 | render: h => h(App) 26 | }) 27 | -------------------------------------------------------------------------------- /src/permission.js: -------------------------------------------------------------------------------- 1 | import router from './router' 2 | import store from './store' 3 | import request from '@/components/common/js/request' 4 | 5 | router.beforeEach((to, from, next) => { 6 | if (to.matched.length === 0) { 7 | next('/404') 8 | } else { 9 | if (Object.keys(store.state.user).length === 0) { 10 | request({ 11 | url: '/shop/user/index' 12 | }).then(res => { 13 | if (res.status == 1) { 14 | store.commit('SET_USER_INFO', res.data.user) 15 | } 16 | }) 17 | } 18 | store.commit('SET_TITLE', to.meta.title) 19 | store.commit('SET_SHOW_BACK', to.meta.showBack) 20 | store.commit('SET_SHOW_MORE', to.meta.showMore) 21 | store.commit('SET_SHOW_TITLE', to.meta.showTitle) 22 | store.commit('SET_SHOW_BOTTOM', to.meta.showBottom) 23 | next() 24 | } 25 | }) -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue" 2 | import Router from "vue-router" 3 | 4 | Vue.use(Router) 5 | 6 | export default new Router({ 7 | routes: [ 8 | { 9 | path: "/", 10 | name: "index", 11 | component: () => import("@/components/index"), 12 | redirect: "/index", 13 | children: [ 14 | { 15 | path: "index", 16 | name: "home", 17 | component: () => import("@/components/index/index"), 18 | meta: { 19 | showBottom: true, 20 | keepAlive: true 21 | } 22 | }, 23 | { 24 | path: "product", 25 | name: "product", 26 | component: () => 27 | import("@/components/index/ProductDetail/index") 28 | }, 29 | { 30 | path: "cate", 31 | name: "cate", 32 | component: () => import("@/components/cate/index"), 33 | meta: { 34 | showBottom: true, 35 | keepAlive: true 36 | } 37 | }, 38 | { 39 | path: "cart", 40 | name: "cart", 41 | component: () => import("@/components/cart/index"), 42 | meta: { 43 | showBottom: true, 44 | keepAlive: true 45 | } 46 | }, 47 | { 48 | path: "cartOrder", 49 | name: "cartOrder", 50 | component: () => import("@/components/cart/order/index"), 51 | meta: { 52 | title: "订单提交", 53 | showTitle: true, 54 | showBack: true 55 | } 56 | }, 57 | { 58 | path: "member", 59 | name: "member", 60 | component: () => import("@/components/member/index"), 61 | meta: { 62 | showBottom: true, 63 | keepAlive: true 64 | } 65 | }, 66 | { 67 | path: "order", 68 | name: "order", 69 | component: () => import("@/components/member/order/index"), 70 | meta: { 71 | title: "订单列表", 72 | showTitle: true, 73 | showBack: true 74 | // keepAlive: true, 75 | } 76 | }, 77 | { 78 | path: "orderDetail", 79 | name: "orderDetail", 80 | component: () => 81 | import("@/components/member/order/orderDetail"), 82 | meta: { 83 | title: "订单详情", 84 | showTitle: true, 85 | showBack: true 86 | } 87 | }, 88 | { 89 | path: "address", 90 | name: "address", 91 | component: () => 92 | import("@/components/member/address/index"), 93 | meta: { 94 | title: "收货地址", 95 | showTitle: true, 96 | showBack: true, 97 | keepAlive: true 98 | } 99 | }, 100 | { 101 | path: "addAddress", 102 | name: "addAddress", 103 | component: () => 104 | import("@/components/member/address/addAddress"), 105 | meta: { 106 | title: "编辑收货地址", 107 | showTitle: true, 108 | showBack: true 109 | } 110 | }, 111 | { 112 | path: "setting", 113 | name: "setting", 114 | component: () => 115 | import("@/components/member/setting/index"), 116 | meta: { 117 | title: "设置", 118 | showTitle: true, 119 | showBack: true 120 | } 121 | } 122 | ] 123 | }, 124 | { 125 | path: "/login", 126 | name: "login", 127 | component: () => import("@/components/member/login/index") 128 | }, 129 | { 130 | path: "/reg", 131 | name: "reg", 132 | component: () => import("@/components/member/reg/index") 133 | }, 134 | { 135 | path: "/404", 136 | name: "page404", 137 | component: () => import("@/components/error") 138 | } 139 | ] 140 | }) 141 | -------------------------------------------------------------------------------- /src/store/actions.js: -------------------------------------------------------------------------------- 1 | import * as types from "./mutation-types" 2 | import request from "@/components/common/js/request" 3 | 4 | export const reloadUser = ({ commit }) => { 5 | request({ url: "/shop/user/index" }) 6 | .then(res => { 7 | commit(types.SET_USER_INFO, res.data.user) 8 | }) 9 | .catch(err => { 10 | console.log(err) 11 | }) 12 | } 13 | 14 | export const initCart = ({ commit }) => { 15 | request({ url: "/shop/cart/index" }) 16 | .then(res => { 17 | commit(types.INIT_CART, res.data ? res.data : []) 18 | }) 19 | .catch(err => { 20 | console.log(err) 21 | }) 22 | } 23 | 24 | export const cartChange = ({ commit }, { cart_id, index, flag }) => { 25 | request({ 26 | url: "/shop/cart/changeCartNumber", 27 | method: "post", 28 | data: { 29 | cart_id, 30 | type: flag 31 | } 32 | }) 33 | .then(res => { 34 | commit(types.CHANGE_CART_NUMBER, { index, flag }) 35 | }) 36 | .catch(err => { 37 | console.log(err) 38 | }) 39 | } 40 | 41 | export const initAddress = ({ commit }) => { 42 | request({ 43 | url: "/shop/address/index", 44 | method: "get" 45 | }) 46 | .then(res => { 47 | commit(types.SET_ADDRESS, res.data) 48 | }) 49 | .catch(err => { 50 | console.log(err) 51 | }) 52 | } 53 | -------------------------------------------------------------------------------- /src/store/getters.js: -------------------------------------------------------------------------------- 1 | export const title = state => state.title 2 | export const showBack = state => state.showBack 3 | export const showTitle = state => state.showTitle 4 | export const showMore = state => state.showMore 5 | export const user = state => state.user 6 | export const showBottom = state => state.showBottom 7 | export const cart = state => state.cart 8 | export const cartNum = state => { 9 | let i = 0 10 | state.cart.map(item => { 11 | i += item.num 12 | }) 13 | return i 14 | } 15 | export const addressList = state => state.addressList 16 | export const order_current_index = state => state.order_current_index 17 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import * as getters from './getters' 4 | import * as actions from './actions' 5 | import mutations from './mutations' 6 | import state from './state' 7 | import createLog from 'vuex/dist/logger' 8 | Vue.use(Vuex) 9 | const debug = process.env.NODE_ENV !== 'production' 10 | 11 | export default new Vuex.Store({ 12 | state, 13 | actions, 14 | mutations, 15 | getters, 16 | strict: debug, 17 | plugins: debug ? [createLog()] : [] 18 | }) -------------------------------------------------------------------------------- /src/store/mutation-types.js: -------------------------------------------------------------------------------- 1 | //头部导航 and 底部按相关 2 | export const SET_TITLE = "SET_TITLE" 3 | export const SET_SHOW_BACK = "SET_SHOW_BACK" 4 | export const SET_SHOW_MORE = "SET_SHOW_MORE" 5 | export const SET_SHOW_TITLE = "SET_SHOW_TITLE" 6 | export const SET_USER_INFO = "SET_USER_INFO" 7 | export const SET_SHOW_BOTTOM = "SET_SHOW_BOTTOM" 8 | 9 | //购物车相关 10 | export const INIT_CART = "INIT_CART" 11 | export const JOIN_TO_CART = "JOIN_TO_CART" 12 | export const DROP_TO_CART = "DROP_TO_CART" 13 | export const CLEAR_CART = "CLEAR_CART" 14 | export const SET_CART_CHECKED = "SET_CART_CHECKED" 15 | export const CHANGE_CART_NUMBER = "CHANGE_CART_NUMBER" 16 | export const DELETE_CART = "DELETE_CART" 17 | 18 | //收货地址相关 19 | export const SET_ADDRESS = "SET_ADDRESS" 20 | export const ADD_NEW_ADDRESS = "ADD_NEW_ADDRESS" 21 | export const DELETE_ADDRESS = "DELETE_ADDRESS" 22 | export const EDIT_ADDRESS = "EDIT_ADDRESS" 23 | export const SET_ADDRESS_DEFAULT = "SET_ADDRESS_DEFAULT" 24 | 25 | // 订单相关 26 | export const SET_ORDER_CURRENT_INDEX = "SET_ORDER_CURRENT_INDEX" 27 | 28 | // 退出登录 29 | export const LOGOUT = "LOGOUT" 30 | -------------------------------------------------------------------------------- /src/store/mutations.js: -------------------------------------------------------------------------------- 1 | import * as types from "./mutation-types" 2 | import vue from "vue" 3 | const mutations = { 4 | // 头部导航 and 底部按钮 相关 5 | [types.SET_TITLE](state, title) { 6 | state.title = title 7 | }, 8 | [types.SET_SHOW_BACK](state, flag) { 9 | state.showBack = flag 10 | }, 11 | [types.SET_SHOW_TITLE](state, flag) { 12 | state.showTitle = flag 13 | }, 14 | [types.SET_SHOW_MORE](state, flag) { 15 | state.showMore = flag 16 | }, 17 | [types.SET_USER_INFO](state, user) { 18 | state.user = user 19 | }, 20 | [types.SET_SHOW_BOTTOM](state, flag) { 21 | state.showBottom = flag 22 | }, 23 | 24 | // 购物车相关 25 | [types.INIT_CART](state, cart) { 26 | cart.map(item => { 27 | item.check = false 28 | }) 29 | state.cart = cart 30 | }, 31 | [types.JOIN_TO_CART](state, pro) { 32 | state.cart.push(pro) 33 | }, 34 | [types.DROP_TO_CART](state, index) { 35 | state.cart.splice(index, 1) 36 | }, 37 | [types.CLEAR_CART](state) { 38 | state.cart = [] 39 | }, 40 | [types.SET_CART_CHECKED](state, { index, flag }) { 41 | state.cart[index].check = flag 42 | }, 43 | [types.CHANGE_CART_NUMBER](state, { index, flag }) { 44 | flag === 0 ? state.cart[index].num-- : state.cart[index].num++ 45 | }, 46 | [types.DELETE_CART](state, index) { 47 | state.cart.splice(index, 1) 48 | }, 49 | 50 | // 收货地址相关 51 | [types.SET_ADDRESS](state, addressList) { 52 | state.addressList = addressList 53 | }, 54 | [types.ADD_NEW_ADDRESS](state, address) { 55 | if (state.addressList.length > 0) { 56 | state.addressList.map(item => { 57 | return (item.is_default = 0) 58 | }) 59 | } 60 | address.is_default = 1 61 | state.addressList.push(address) 62 | }, 63 | [types.DELETE_ADDRESS](state, index) { 64 | state.addressList.splice(index, 1) 65 | }, 66 | [types.SET_ADDRESS_DEFAULT](state, index) { 67 | if (state.addressList.length > 0) { 68 | state.addressList.map((item, i) => { 69 | if (i == index) { 70 | item.is_default = 1 71 | } else { 72 | item.is_default = 0 73 | } 74 | }) 75 | } 76 | }, 77 | [types.EDIT_ADDRESS](state, { address, index }) { 78 | vue.set(state.addressList, index, address) 79 | }, 80 | 81 | // 订单相关 82 | [types.SET_ORDER_CURRENT_INDEX](state, index) { 83 | state.order_current_index = index 84 | }, 85 | 86 | // 退出登录.初始化 87 | [types.LOGOUT](state) { 88 | state.user = {} //用户信息 89 | state.cart = [] 90 | state.addressList = [] // 用户地址信息 91 | } 92 | } 93 | 94 | export default mutations 95 | -------------------------------------------------------------------------------- /src/store/state.js: -------------------------------------------------------------------------------- 1 | const state = { 2 | title: "", //标题 3 | showBack: false, //是否显示返回 4 | showTitle: false, //是否显示头部 5 | showMore: false, //是否显示更多按钮 6 | showBottom: false, //是否显示更多按钮 7 | user: {}, //用户信息 8 | cart: [], 9 | cartNum: 0, 10 | addressList: [], // 用户地址信息 11 | order_current_index: -1 // 订单active 12 | } 13 | export default state 14 | -------------------------------------------------------------------------------- /static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MasterJoyHunan/app/a5199424830c1b892ee52ff28d4f96e392124be0/static/.gitkeep -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MasterJoyHunan/app/a5199424830c1b892ee52ff28d4f96e392124be0/static/favicon.ico --------------------------------------------------------------------------------