├── static ├── .gitkeep ├── 1.jpg ├── icon.png ├── logo.png ├── ok-2.png ├── 九号平衡车.jpg ├── 小米体重秤.jpg ├── 小米米家对讲机.jpg ├── 小米路由器 3.jpg ├── 小米魔方控制器.jpg ├── 平衡车plus.jpg ├── 米兔儿童手表Q.jpg ├── 米兔定位电话.jpg ├── 米兔智能故事机.jpg ├── 米家IH电饭煲.jpg ├── 米家恒温电水壶.jpg ├── 米家扫地机器人.jpg ├── 米家智能摄像机.jpg ├── 小米空气净化器 2.jpg ├── 米兔儿童电话手表2.jpg ├── 米家声波电动牙刷.jpg ├── 米家小白智能摄像机.jpg ├── 米家飞利浦台灯二代.jpg ├── Yeelight床头灯.jpg ├── iHealth智能血压计.jpg ├── 米家PM2.5检测仪.jpg ├── 米家压力 IH 电饭煲.jpg ├── 米家空气净化器Pro.jpg ├── 九号平衡车!220x220.jpg ├── 小方摄像机!220x220.jpg ├── 小方智能摄像机 1080P.jpg ├── 小米AI音箱!220x220.jpg ├── 米家 iHealth 血压计.jpg ├── 米家感应夜灯!220x220.jpg ├── 小米路由器3C!220x220.jpg ├── 米家行车记录仪!220x220.jpg ├── 米家iHealth血压计!220x220.jpg └── loading-svg │ ├── loading-bars.svg │ └── loading-spinning-bubbles.svg ├── server ├── views │ ├── error.html │ └── index.html ├── public │ └── stylesheets │ │ └── style.css ├── routes │ ├── index.js │ ├── goods.js │ └── users.js ├── models │ ├── goods.js │ └── user.js ├── package.json ├── util │ └── util.js ├── bin │ └── www ├── app.js └── package-lock.json ├── config ├── prod.env.js ├── dev.env.js └── index.js ├── resource ├── img │ ├── 1.jpg │ ├── icon.png │ ├── logo.png │ └── ok-2.png ├── css │ ├── nav-bread.css │ ├── nav-footer.css │ ├── nav-header.css │ ├── login.css │ └── goods-list.css └── views │ ├── orderSuccess.html │ ├── goodsList.html │ ├── orderConfirm.html │ ├── address.html │ └── cart.html ├── src ├── assets │ ├── logo.png │ └── css │ │ ├── nav-bread.css │ │ ├── nav-footer.css │ │ ├── nav-header.css │ │ ├── login.css │ │ └── goods-list.css ├── App.vue ├── util │ └── currency.js ├── components │ ├── Modal.vue │ ├── NavBread.vue │ ├── HelloWorld.vue │ ├── NavFooter.vue │ └── NavHeader.vue ├── router │ └── index.js ├── main.js └── views │ ├── OrderSuccess.vue │ ├── OrderConfirm.vue │ ├── GoodsList.vue │ ├── Address.vue │ └── Cart.vue ├── .editorconfig ├── .gitignore ├── .postcssrc.js ├── index.html ├── .babelrc ├── README.md ├── mock └── goods.json └── package.json /static/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /server/views/error.html: -------------------------------------------------------------------------------- 1 |

<%= message %>

2 |

<%= error.status %>

3 | -------------------------------------------------------------------------------- /static/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/1.jpg -------------------------------------------------------------------------------- /static/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/icon.png -------------------------------------------------------------------------------- /static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/logo.png -------------------------------------------------------------------------------- /static/ok-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/ok-2.png -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"' 4 | } 5 | -------------------------------------------------------------------------------- /resource/img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/resource/img/1.jpg -------------------------------------------------------------------------------- /static/九号平衡车.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/九号平衡车.jpg -------------------------------------------------------------------------------- /static/小米体重秤.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/小米体重秤.jpg -------------------------------------------------------------------------------- /static/小米米家对讲机.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/小米米家对讲机.jpg -------------------------------------------------------------------------------- /static/小米路由器 3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/小米路由器 3.jpg -------------------------------------------------------------------------------- /static/小米魔方控制器.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/小米魔方控制器.jpg -------------------------------------------------------------------------------- /static/平衡车plus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/平衡车plus.jpg -------------------------------------------------------------------------------- /static/米兔儿童手表Q.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/米兔儿童手表Q.jpg -------------------------------------------------------------------------------- /static/米兔定位电话.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/米兔定位电话.jpg -------------------------------------------------------------------------------- /static/米兔智能故事机.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/米兔智能故事机.jpg -------------------------------------------------------------------------------- /static/米家IH电饭煲.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/米家IH电饭煲.jpg -------------------------------------------------------------------------------- /static/米家恒温电水壶.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/米家恒温电水壶.jpg -------------------------------------------------------------------------------- /static/米家扫地机器人.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/米家扫地机器人.jpg -------------------------------------------------------------------------------- /static/米家智能摄像机.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/米家智能摄像机.jpg -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/src/assets/logo.png -------------------------------------------------------------------------------- /static/小米空气净化器 2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/小米空气净化器 2.jpg -------------------------------------------------------------------------------- /static/米兔儿童电话手表2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/米兔儿童电话手表2.jpg -------------------------------------------------------------------------------- /static/米家声波电动牙刷.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/米家声波电动牙刷.jpg -------------------------------------------------------------------------------- /static/米家小白智能摄像机.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/米家小白智能摄像机.jpg -------------------------------------------------------------------------------- /static/米家飞利浦台灯二代.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/米家飞利浦台灯二代.jpg -------------------------------------------------------------------------------- /resource/img/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/resource/img/icon.png -------------------------------------------------------------------------------- /resource/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/resource/img/logo.png -------------------------------------------------------------------------------- /resource/img/ok-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/resource/img/ok-2.png -------------------------------------------------------------------------------- /static/Yeelight床头灯.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/Yeelight床头灯.jpg -------------------------------------------------------------------------------- /static/iHealth智能血压计.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/iHealth智能血压计.jpg -------------------------------------------------------------------------------- /static/米家PM2.5检测仪.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/米家PM2.5检测仪.jpg -------------------------------------------------------------------------------- /static/米家压力 IH 电饭煲.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/米家压力 IH 电饭煲.jpg -------------------------------------------------------------------------------- /static/米家空气净化器Pro.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/米家空气净化器Pro.jpg -------------------------------------------------------------------------------- /static/九号平衡车!220x220.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/九号平衡车!220x220.jpg -------------------------------------------------------------------------------- /static/小方摄像机!220x220.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/小方摄像机!220x220.jpg -------------------------------------------------------------------------------- /static/小方智能摄像机 1080P.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/小方智能摄像机 1080P.jpg -------------------------------------------------------------------------------- /static/小米AI音箱!220x220.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/小米AI音箱!220x220.jpg -------------------------------------------------------------------------------- /static/米家 iHealth 血压计.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/米家 iHealth 血压计.jpg -------------------------------------------------------------------------------- /static/米家感应夜灯!220x220.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/米家感应夜灯!220x220.jpg -------------------------------------------------------------------------------- /static/小米路由器3C!220x220.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/小米路由器3C!220x220.jpg -------------------------------------------------------------------------------- /static/米家行车记录仪!220x220.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/米家行车记录仪!220x220.jpg -------------------------------------------------------------------------------- /static/米家iHealth血压计!220x220.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/worldsong/vue2-shop-lesson/HEAD/static/米家iHealth血压计!220x220.jpg -------------------------------------------------------------------------------- /server/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 50px; 3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; 4 | } 5 | 6 | a { 7 | color: #00B7FF; 8 | } 9 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /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 | }) 8 | -------------------------------------------------------------------------------- /.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 | .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 | // to edit target browsers: use "browserslist" field in package.json 6 | "autoprefixer": {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vue2-shop-lesson 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /server/routes/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET home page. */ 5 | router.get('/', function(req, res, next) { 6 | res.render('index', { title: '商城后台' }); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /server/views/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%= title %> 5 | 6 | 7 | 8 |

<%= title %>

9 |

Welcome to <%= title %>

10 | 11 | 12 | -------------------------------------------------------------------------------- /server/models/goods.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose') 2 | var Schema = mongoose.Schema; 3 | 4 | var produtSchema = new Schema({ 5 | "productId":{type:String}, 6 | "productName":String, 7 | "salePrice":Number, 8 | "checked":String, 9 | "productNum":Number, 10 | "productImage":String 11 | }); 12 | 13 | module.exports = mongoose.model('Good',produtSchema); 14 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "body-parser": "~1.18.2", 10 | "cookie-parser": "~1.4.3", 11 | "debug": "~2.6.9", 12 | "ejs": "~2.5.7", 13 | "express": "~4.15.5", 14 | "mongoose": "^4.13.0", 15 | "morgan": "~1.9.0", 16 | "serve-favicon": "~2.4.5" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue2-shop-lesson 2 | 3 | > A Vue.js project 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | 17 | # build for production and view the bundle analyzer report 18 | npm run build --report 19 | ``` 20 | 21 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 22 | -------------------------------------------------------------------------------- /server/models/user.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | 3 | var userSchema = new mongoose.Schema({ 4 | "userId":String, 5 | "userName":String, 6 | "userPwd":String, 7 | "orderList":Array, 8 | "cartList":[ 9 | { 10 | "productId":String, 11 | "productName":String, 12 | "salePrice":String, 13 | "productImage":String, 14 | "checked":String, 15 | "productNum":String 16 | } 17 | ], 18 | "addressList":[ 19 | { 20 | "addressId": String, 21 | "userName": String, 22 | "streetName": String, 23 | "postCode": Number, 24 | "tel": Number, 25 | "isDefault": Boolean 26 | } 27 | ] 28 | }); 29 | 30 | module.exports = mongoose.model("User",userSchema); 31 | -------------------------------------------------------------------------------- /resource/css/nav-bread.css: -------------------------------------------------------------------------------- 1 | /** the page max width **/ 2 | .container { 3 | max-width: 1280px; 4 | margin: 0 auto; 5 | padding: 0 10px; 6 | } 7 | 8 | .nav-breadcrumb-wrap { 9 | background: #f0f0f0; 10 | } 11 | 12 | 13 | /** 面包屑 **/ 14 | .nav-breadcrumb { 15 | padding: 10px 0; 16 | line-height: 25px; 17 | font-size: 14px; 18 | } 19 | 20 | .nav-breadcrumb a { 21 | position: relative; 22 | margin-right: 16px; 23 | color: #999; 24 | } 25 | 26 | .nav-breadcrumb a:after { 27 | position: absolute; 28 | top: 3px; 29 | right: -12px; 30 | content: "/"; 31 | line-height: 1.2; 32 | } 33 | 34 | .nav-breadcrumb a:hover { 35 | color: #d1434a; 36 | } 37 | 38 | .nav-breadcrumb span { 39 | color: #d1434a; 40 | } 41 | -------------------------------------------------------------------------------- /src/assets/css/nav-bread.css: -------------------------------------------------------------------------------- 1 | /** the page max width **/ 2 | .container { 3 | max-width: 1280px; 4 | margin: 0 auto; 5 | padding: 0 10px; 6 | } 7 | 8 | .nav-breadcrumb-wrap { 9 | background: #f0f0f0; 10 | } 11 | 12 | 13 | /** 面包屑 **/ 14 | .nav-breadcrumb { 15 | padding: 10px 0; 16 | line-height: 25px; 17 | font-size: 14px; 18 | } 19 | 20 | .nav-breadcrumb a { 21 | position: relative; 22 | margin-right: 16px; 23 | color: #999; 24 | } 25 | 26 | .nav-breadcrumb a:after { 27 | position: absolute; 28 | top: 3px; 29 | right: -12px; 30 | content: "/"; 31 | line-height: 1.2; 32 | } 33 | 34 | .nav-breadcrumb a:hover { 35 | color: #d1434a; 36 | } 37 | 38 | .nav-breadcrumb span { 39 | color: #d1434a; 40 | } 41 | -------------------------------------------------------------------------------- /src/util/currency.js: -------------------------------------------------------------------------------- 1 | const digitsRE = /(\d{3})(?=\d)/g 2 | 3 | export function currency (value, currency, decimals) { 4 | value = parseFloat(value) 5 | if (!isFinite(value) || (!value && value !== 0)) return '' 6 | currency = currency != null ? currency : '¥' 7 | decimals = decimals != null ? decimals : 2 8 | var stringified = Math.abs(value).toFixed(decimals) 9 | var _int = decimals 10 | ? stringified.slice(0, -1 - decimals) 11 | : stringified 12 | var i = _int.length % 3 13 | var head = i > 0 14 | ? (_int.slice(0, i) + (_int.length > 3 ? ',' : '')) 15 | : '' 16 | var _float = decimals 17 | ? stringified.slice(-1 - decimals) 18 | : '' 19 | var sign = value < 0 ? '-' : '' 20 | return sign + currency + head + 21 | _int.slice(i).replace(digitsRE, '$1,') + 22 | _float 23 | } 24 | -------------------------------------------------------------------------------- /server/util/util.js: -------------------------------------------------------------------------------- 1 | Date.prototype.Format = function (fmt) { 2 | var o = { 3 | "M+": this.getMonth() + 1, //月份 4 | "d+": this.getDate(), //日 5 | "h+": this.getHours(), //小时 6 | "m+": this.getMinutes(), //分 7 | "s+": this.getSeconds(), //秒 8 | "q+": Math.floor((this.getMonth() + 3) / 3), //季度 9 | "S": this.getMilliseconds() //毫秒 10 | }; 11 | if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); 12 | for (var k in o) 13 | if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); 14 | return fmt; 15 | } 16 | 17 | module.exports = {}; 18 | 19 | var now = new Date(); 20 | var data = now.Format("yyyyMMddhhmmss"); 21 | console.log(now); 22 | console.log(data); 23 | -------------------------------------------------------------------------------- /resource/css/nav-footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | background-color: #f5f7fc; 3 | color: #333; 4 | position: relative; 5 | } 6 | 7 | .footer__wrap { 8 | max-width: 1280px; 9 | margin: 0 auto; 10 | } 11 | 12 | .footer__secondary { 13 | border-top: 1px solid rgba(51, 51, 51, 0.15); 14 | } 15 | 16 | .footer__secondary .footer__inner { 17 | height: 100px; 18 | } 19 | 20 | .footer__inner { 21 | max-width: 1280px; 22 | margin: 0 auto; 23 | position: relative; 24 | } 25 | 26 | .footer__secondary__nav { 27 | position: absolute; 28 | top: 50%; 29 | -webkit-transform: translateY(-50%); 30 | -ms-transform: translateY(-50%); 31 | transform: translateY(-50%); 32 | right: 36px; 33 | } 34 | 35 | .footer__secondary__nav a, 36 | .footer__secondary__nav span { 37 | color: #ada9a5; 38 | margin-left: 3.3125em; 39 | } 40 | 41 | .footer__secondary__nav a:first-child, 42 | .footer__secondary__nav span:first-child { 43 | margin-left: 0; 44 | } 45 | -------------------------------------------------------------------------------- /src/assets/css/nav-footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | background-color: #f5f7fc; 3 | color: #333; 4 | position: relative; 5 | } 6 | 7 | .footer__wrap { 8 | max-width: 1280px; 9 | margin: 0 auto; 10 | } 11 | 12 | .footer__secondary { 13 | border-top: 1px solid rgba(51, 51, 51, 0.15); 14 | } 15 | 16 | .footer__secondary .footer__inner { 17 | height: 100px; 18 | } 19 | 20 | .footer__inner { 21 | max-width: 1280px; 22 | margin: 0 auto; 23 | position: relative; 24 | } 25 | 26 | .footer__secondary__nav { 27 | position: absolute; 28 | top: 50%; 29 | -webkit-transform: translateY(-50%); 30 | -ms-transform: translateY(-50%); 31 | transform: translateY(-50%); 32 | right: 36px; 33 | } 34 | 35 | .footer__secondary__nav a, 36 | .footer__secondary__nav span { 37 | color: #ada9a5; 38 | margin-left: 3.3125em; 39 | } 40 | 41 | .footer__secondary__nav a:first-child, 42 | .footer__secondary__nav span:first-child { 43 | margin-left: 0; 44 | } 45 | -------------------------------------------------------------------------------- /src/components/Modal.vue: -------------------------------------------------------------------------------- 1 | 21 | 24 | 39 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | const GoodsList = () => import('@/views/GoodsList'); 4 | const Cart = () => import('@/views/Cart'); 5 | const Address = () => import('@/views/Address'); 6 | const OrderConfirm = () => import('@/views/OrderConfirm'); 7 | const OrderSuccess = () => import('@/views/OrderSuccess'); 8 | 9 | Vue.use(Router) 10 | 11 | export default new Router({ 12 | routes: [ 13 | { 14 | path: '/', 15 | name: 'home', 16 | component: GoodsList 17 | }, 18 | { 19 | path: '/GoodsList', 20 | name: 'GoodsList', 21 | component: GoodsList 22 | }, 23 | { 24 | path: '/goods', 25 | name: 'GoodsList', 26 | component: GoodsList 27 | }, 28 | { 29 | path: '/Cart', 30 | name: 'Cart', 31 | component: Cart 32 | }, 33 | { 34 | path: '/Address', 35 | name: 'Address', 36 | component: Address 37 | }, 38 | { 39 | path: '/OrderConfirm', 40 | name: 'OrderConfirm', 41 | component: OrderConfirm 42 | }, 43 | { 44 | path: '/OrderSuccess', 45 | name: 'OrderSuccess', 46 | component: OrderSuccess 47 | } 48 | ] 49 | }) 50 | -------------------------------------------------------------------------------- /src/components/NavBread.vue: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Song on 2017/11/1. 3 | */ 4 | 16 | 17 | 26 | 27 | 28 | 70 | -------------------------------------------------------------------------------- /src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 33 | 34 | 35 | 54 | -------------------------------------------------------------------------------- /mock/goods.json: -------------------------------------------------------------------------------- 1 | { 2 | "status":"0", 3 | "result":[ 4 | { 5 | "productId":"10001", 6 | "productName":"小米空气净化器 2", 7 | "salePrice":"699", 8 | "productImage":"小米空气净化器 2.jpg" 9 | }, 10 | { 11 | "productId":"10002", 12 | "productName":"米家空气净化器Pro", 13 | "salePrice":"1499", 14 | "productImage":"米家空气净化器Pro.jpg" 15 | }, 16 | { 17 | "productId":"10003", 18 | "productName":"米家PM2.5检测仪", 19 | "salePrice":"399", 20 | "productImage":"米家PM2.5检测仪.jpg" 21 | }, 22 | { 23 | "productId":"10004", 24 | "productName":"九号平衡车", 25 | "salePrice":"1999", 26 | "productImage":"九号平衡车.jpg" 27 | }, 28 | { 29 | "productId":"10005", 30 | "productName":"小米路由器 3", 31 | "salePrice":"139", 32 | "productImage":"小米路由器 3.jpg" 33 | }, 34 | { 35 | "productId":"10006", 36 | "productName":"米家压力 IH 电饭煲", 37 | "salePrice":"999", 38 | "productImage":"米家压力 IH 电饭煲.jpg" 39 | }, 40 | { 41 | "productId":"10007", 42 | "productName":"米家IH电饭煲", 43 | "salePrice":"399", 44 | "productImage":"米家IH电饭煲.jpg" 45 | }, 46 | { 47 | "productId":"10008", 48 | "productName":"米家恒温电水壶", 49 | "salePrice":"199", 50 | "productImage":"米家恒温电水壶.jpg" 51 | }, 52 | { 53 | "productId":"10009", 54 | "productName":"米家小白智能摄像机", 55 | "salePrice":"399", 56 | "productImage":"米家小白智能摄像机.jpg" 57 | }, 58 | { 59 | "productId":"10010", 60 | "productName":"Yeelight床头灯", 61 | "salePrice":"249", 62 | "productImage":"Yeelight床头灯.jpg" 63 | } 64 | ] 65 | } 66 | -------------------------------------------------------------------------------- /resource/css/nav-header.css: -------------------------------------------------------------------------------- 1 | .header { 2 | width: 100%; 3 | background-color: white; 4 | font-family: "moderat",sans-serif; 5 | font-size: 16px; 6 | } 7 | 8 | .goods-svg { 9 | position: absolute; 10 | width: 0; 11 | height: 0; 12 | overflow: hidden; 13 | } 14 | .navbar { 15 | display: flex; 16 | justify-content: space-between; 17 | align-content: center; 18 | width: 100%; 19 | height: 70px; 20 | max-width: 1280px; 21 | margin: 0 auto; 22 | padding: 5px 20px 10px 20px; 23 | } 24 | .navbar-left-container { 25 | display: flex; 26 | justify-content: flex-start; 27 | align-items: center; 28 | margin-left: -20px; 29 | } 30 | .header a, .footer a { 31 | color: #666; 32 | text-decoration: none; 33 | } 34 | .navbar-brand-logo { 35 | /*width: 120px;*/ 36 | margin-top: 10px; 37 | } 38 | a { 39 | -webkit-transition: color .3s ease-out; 40 | transition: color .3s ease-out; 41 | } 42 | .navbar-right-container { 43 | display: flex; 44 | justify-content: flex-start; 45 | align-items: center; 46 | } 47 | .navbar-menu-container { 48 | display: flex; 49 | justify-content: flex-end; 50 | align-items: center; 51 | padding-top: 10px; 52 | } 53 | .navbar-link { 54 | padding-left: 15px; 55 | } 56 | .navbar-cart-container { 57 | position: relative; 58 | } 59 | .navbar-cart-count { 60 | justify-content: center; 61 | align-items: center; 62 | position: absolute; 63 | top: -9px; 64 | right: -11px; 65 | width: 20px; 66 | border-radius: 10px; 67 | color: white; 68 | background-color: #eb767d; 69 | font-size: 16px; 70 | font-weight: bold; 71 | text-align: center; 72 | } 73 | .navbar-cart-logo { 74 | width: 25px; 75 | height: 25px; 76 | transform: scaleX(-1); 77 | } 78 | -------------------------------------------------------------------------------- /src/assets/css/nav-header.css: -------------------------------------------------------------------------------- 1 | .header { 2 | width: 100%; 3 | background-color: white; 4 | font-family: "moderat",sans-serif; 5 | font-size: 16px; 6 | } 7 | 8 | .goods-svg { 9 | position: absolute; 10 | width: 0; 11 | height: 0; 12 | overflow: hidden; 13 | } 14 | .navbar { 15 | display: flex; 16 | justify-content: space-between; 17 | align-content: center; 18 | width: 100%; 19 | height: 70px; 20 | max-width: 1280px; 21 | margin: 0 auto; 22 | padding: 5px 20px 10px 20px; 23 | } 24 | .navbar-left-container { 25 | display: flex; 26 | justify-content: flex-start; 27 | align-items: center; 28 | margin-left: -20px; 29 | } 30 | .header a, .footer a { 31 | color: #666; 32 | text-decoration: none; 33 | } 34 | .navbar-brand-logo { 35 | /*width: 120px;*/ 36 | margin-top: 10px; 37 | } 38 | a { 39 | -webkit-transition: color .3s ease-out; 40 | transition: color .3s ease-out; 41 | } 42 | .navbar-right-container { 43 | display: flex; 44 | justify-content: flex-start; 45 | align-items: center; 46 | } 47 | .navbar-menu-container { 48 | display: flex; 49 | justify-content: flex-end; 50 | align-items: center; 51 | padding-top: 10px; 52 | } 53 | .navbar-link { 54 | padding-left: 15px; 55 | } 56 | .navbar-cart-container { 57 | position: relative; 58 | } 59 | .navbar-cart-count { 60 | justify-content: center; 61 | align-items: center; 62 | position: absolute; 63 | top: -9px; 64 | right: -11px; 65 | width: 20px; 66 | border-radius: 10px; 67 | color: white; 68 | background-color: #eb767d; 69 | font-size: 16px; 70 | font-weight: bold; 71 | text-align: center; 72 | } 73 | .navbar-cart-logo { 74 | width: 25px; 75 | height: 25px; 76 | transform: scaleX(-1); 77 | } 78 | -------------------------------------------------------------------------------- /static/loading-svg/loading-bars.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict' 3 | // Template version: 1.1.3 4 | // see http://vuejs-templates.github.io/webpack for documentation. 5 | 6 | const path = require('path') 7 | 8 | module.exports = { 9 | build: { 10 | env: require('./prod.env'), 11 | index: path.resolve(__dirname, '../dist/index.html'), 12 | assetsRoot: path.resolve(__dirname, '../dist'), 13 | assetsSubDirectory: 'static', 14 | assetsPublicPath: '/', 15 | productionSourceMap: true, 16 | // Gzip off by default as many popular static hosts such as 17 | // Surge or Netlify already gzip all static assets for you. 18 | // Before setting to `true`, make sure to: 19 | // npm install --save-dev compression-webpack-plugin 20 | productionGzip: false, 21 | productionGzipExtensions: ['js', 'css'], 22 | // Run the build command with an extra argument to 23 | // View the bundle analyzer report after build finishes: 24 | // `npm run build --report` 25 | // Set to `true` or `false` to always turn it on or off 26 | bundleAnalyzerReport: process.env.npm_config_report 27 | }, 28 | dev: { 29 | env: require('./dev.env'), 30 | port: process.env.PORT || 8080, 31 | autoOpenBrowser: true, 32 | assetsSubDirectory: 'static', 33 | assetsPublicPath: '/', 34 | proxyTable: { 35 | '/goods':{ 36 | target:'http://localhost:3000/' 37 | }, 38 | '/users':{ 39 | target:'http://localhost:3000/' 40 | } 41 | }, 42 | // CSS Sourcemaps off by default because relative paths are "buggy" 43 | // with this option, according to the CSS-Loader README 44 | // (https://github.com/webpack/css-loader#sourcemaps) 45 | // In our experience, they generally work as expected, 46 | // just be aware of this issue when enabling this option. 47 | cssSourceMap: false 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue' 4 | import App from './App' 5 | import router from './router' 6 | import VueLazyload from 'vue-lazyload' 7 | import infiniteScroll from 'vue-infinite-scroll' 8 | import axios from 'axios'; 9 | axios.defaults.withCredentials = true; 10 | import Vuex from 'vuex' 11 | 12 | Vue.use(infiniteScroll); 13 | Vue.use(Vuex); 14 | Vue.use(VueLazyload, { 15 | loading: 'static/loading-svg/loading-bars.svg', 16 | attempt: 3 // default 1 17 | }) 18 | Vue.config.productionTip = false 19 | const store = new Vuex.Store({ 20 | state: { 21 | nickName:'', 22 | cartCount:0 23 | }, 24 | mutations: { 25 | //更新用户信息 26 | updateUserInfo(state, nickName) { 27 | state.nickName = nickName; 28 | }, 29 | //更新购物车信息 30 | updateCartCount(state,cartCount){ 31 | state.cartCount += cartCount; 32 | } 33 | } 34 | }); 35 | /* eslint-disable no-new */ 36 | new Vue({ 37 | el: '#app', 38 | store, 39 | router, 40 | mounted(){ 41 | this.checkLogin(); 42 | this.getCartCount(); 43 | }, 44 | methods:{ 45 | checkLogin(){ 46 | axios.get("http://localhost:3000/users/checkLogin").then(res=> { 47 | var res = res.data; 48 | if (res.status == "0") { 49 | this.$store.commit("updateUserInfo", res.result); 50 | }else{ 51 | if(this.$route.path!="/goods"){ 52 | this.$router.push("/goods"); 53 | } 54 | } 55 | }); 56 | }, 57 | getCartCount(){ 58 | axios.get("http://localhost:3000/users/getCartCount").then(res=>{ 59 | var res = res.data; 60 | if(res.status=="0"){ 61 | this.$store.commit("updateCartCount",res.result); 62 | } 63 | }); 64 | } 65 | }, 66 | template: '', 67 | components: { App } 68 | }) 69 | -------------------------------------------------------------------------------- /server/bin/www: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | var app = require('../app'); 8 | var debug = require('debug')('server:server'); 9 | var http = require('http'); 10 | 11 | /** 12 | * Get port from environment and store in Express. 13 | */ 14 | 15 | var port = normalizePort(process.env.PORT || '3000'); 16 | app.set('port', port); 17 | 18 | /** 19 | * Create HTTP server. 20 | */ 21 | 22 | var server = http.createServer(app); 23 | 24 | /** 25 | * Listen on provided port, on all network interfaces. 26 | */ 27 | 28 | server.listen(port); 29 | server.on('error', onError); 30 | server.on('listening', onListening); 31 | 32 | /** 33 | * Normalize a port into a number, string, or false. 34 | */ 35 | 36 | function normalizePort(val) { 37 | var port = parseInt(val, 10); 38 | 39 | if (isNaN(port)) { 40 | // named pipe 41 | return val; 42 | } 43 | 44 | if (port >= 0) { 45 | // port number 46 | return port; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | /** 53 | * Event listener for HTTP server "error" event. 54 | */ 55 | 56 | function onError(error) { 57 | if (error.syscall !== 'listen') { 58 | throw error; 59 | } 60 | 61 | var bind = typeof port === 'string' 62 | ? 'Pipe ' + port 63 | : 'Port ' + port; 64 | 65 | // handle specific listen errors with friendly messages 66 | switch (error.code) { 67 | case 'EACCES': 68 | console.error(bind + ' requires elevated privileges'); 69 | process.exit(1); 70 | break; 71 | case 'EADDRINUSE': 72 | console.error(bind + ' is already in use'); 73 | process.exit(1); 74 | break; 75 | default: 76 | throw error; 77 | } 78 | } 79 | 80 | /** 81 | * Event listener for HTTP server "listening" event. 82 | */ 83 | 84 | function onListening() { 85 | var addr = server.address(); 86 | var bind = typeof addr === 'string' 87 | ? 'pipe ' + addr 88 | : 'port ' + addr.port; 89 | debug('Listening on ' + bind); 90 | } 91 | -------------------------------------------------------------------------------- /resource/css/login.css: -------------------------------------------------------------------------------- 1 | .regi_form_input{ 2 | position: relative; 3 | height: 42px; 4 | line-height: 42px; 5 | background: none; 6 | margin-bottom: 15px; 7 | font-size: 14px; 8 | overflow: hidden; 9 | border:1px solid #ccc; 10 | padding-bottom: 0; 11 | } 12 | .regi_form_input .icon { 13 | display: inline-block; 14 | float: left; 15 | width: 25px; 16 | height: 29px; 17 | margin: 6px 0 0 14px; 18 | background-position: 4px 5px; 19 | background-image: url("/static/icon.png"); 20 | background-repeat: no-repeat; 21 | } 22 | .regi_form_input .IconPwd { 23 | background-position: -198px 3px; 24 | } 25 | .regi_form_input .regi_login_input{ 26 | position: absolute; 27 | left:45px; 28 | top:0; 29 | padding: 9px 0 10px; 30 | width: 270px; 31 | font-size: 14px; 32 | zoom: 1; 33 | border: none; 34 | color: #333; 35 | /*height: 23px;*/ 36 | line-height: 23px; 37 | background: 0 0!important; 38 | } 39 | .md-title{ 40 | position: absolute; 41 | top: 14px; 42 | line-height: 24px; 43 | padding: 8px 0; 44 | color: #333; 45 | font-size: 18px; 46 | font-weight: 400; 47 | font-style: normal; 48 | } 49 | .login-wrap{ 50 | margin-top:30px; 51 | } 52 | .md-content .btn-login{ 53 | display: block; 54 | height: 38px; 55 | line-height: 38px; 56 | border: 2px solid #009de6; 57 | background: #009de6; 58 | color: #fff; 59 | font-size: 18px; 60 | text-align: center; 61 | } 62 | .btn-login:hover { 63 | background: #61b1ef; 64 | border: 2px solid #61b1ef; 65 | } 66 | .error-wrap .error{ 67 | font-size: 12px; 68 | color: #d31723; 69 | visibility: hidden; 70 | display: block; 71 | padding: 0 0 7px 17px; 72 | line-height: 16px; 73 | height: 16px; 74 | text-align: left; 75 | background: url("/static/icon.png") 0 -100px no-repeat; 76 | } 77 | .md-content .error-wrap .error-show{ 78 | visibility: visible; 79 | height: auto; 80 | } 81 | -------------------------------------------------------------------------------- /src/assets/css/login.css: -------------------------------------------------------------------------------- 1 | .regi_form_input{ 2 | position: relative; 3 | height: 42px; 4 | line-height: 42px; 5 | background: none; 6 | margin-bottom: 15px; 7 | font-size: 14px; 8 | overflow: hidden; 9 | border:1px solid #ccc; 10 | padding-bottom: 0; 11 | } 12 | .regi_form_input .icon { 13 | display: inline-block; 14 | float: left; 15 | width: 25px; 16 | height: 29px; 17 | margin: 6px 0 0 14px; 18 | background-position: 4px 5px; 19 | background-image: url("/static/icon.png"); 20 | background-repeat: no-repeat; 21 | } 22 | .regi_form_input .IconPwd { 23 | background-position: -198px 3px; 24 | } 25 | .regi_form_input .regi_login_input{ 26 | position: absolute; 27 | left:45px; 28 | top:0; 29 | padding: 9px 0 10px; 30 | width: 270px; 31 | font-size: 14px; 32 | zoom: 1; 33 | border: none; 34 | color: #333; 35 | /*height: 23px;*/ 36 | line-height: 23px; 37 | background: 0 0!important; 38 | } 39 | .md-title{ 40 | position: absolute; 41 | top: 14px; 42 | line-height: 24px; 43 | padding: 8px 0; 44 | color: #333; 45 | font-size: 18px; 46 | font-weight: 400; 47 | font-style: normal; 48 | } 49 | .login-wrap{ 50 | margin-top:30px; 51 | } 52 | .md-content .btn-login{ 53 | display: block; 54 | height: 38px; 55 | line-height: 38px; 56 | border: 2px solid #009de6; 57 | background: #009de6; 58 | color: #fff; 59 | font-size: 18px; 60 | text-align: center; 61 | } 62 | .btn-login:hover { 63 | background: #61b1ef; 64 | border: 2px solid #61b1ef; 65 | } 66 | .error-wrap .error{ 67 | font-size: 12px; 68 | color: #d31723; 69 | visibility: hidden; 70 | display: block; 71 | padding: 0 0 7px 17px; 72 | line-height: 16px; 73 | height: 16px; 74 | text-align: left; 75 | background: url("/static/icon.png") 0 -100px no-repeat; 76 | } 77 | .md-content .error-wrap .error-show{ 78 | visibility: visible; 79 | height: auto; 80 | } 81 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue2-shop-lesson", 3 | "version": "1.0.0", 4 | "description": "A Vue.js project", 5 | "author": "worldsong <2060884089@qq.com>", 6 | "private": true, 7 | "scripts": { 8 | "dev": "node build/dev-server.js", 9 | "start": "npm run dev", 10 | "build": "node build/build.js" 11 | }, 12 | "dependencies": { 13 | "axios": "^0.17.0", 14 | "vue": "^2.5.2", 15 | "vue-infinite-scroll": "^2.0.2", 16 | "vue-lazyload": "^1.1.4", 17 | "vue-router": "^3.0.1", 18 | "vuex": "^3.0.1" 19 | }, 20 | "devDependencies": { 21 | "autoprefixer": "^7.1.2", 22 | "babel-core": "^6.22.1", 23 | "babel-loader": "^7.1.1", 24 | "babel-plugin-transform-runtime": "^6.22.0", 25 | "babel-preset-env": "^1.3.2", 26 | "babel-preset-stage-2": "^6.22.0", 27 | "babel-register": "^6.22.0", 28 | "chalk": "^2.0.1", 29 | "connect-history-api-fallback": "^1.3.0", 30 | "copy-webpack-plugin": "^4.0.1", 31 | "css-loader": "^0.28.0", 32 | "eventsource-polyfill": "^0.9.6", 33 | "express": "^4.14.1", 34 | "extract-text-webpack-plugin": "^3.0.0", 35 | "file-loader": "^1.1.4", 36 | "friendly-errors-webpack-plugin": "^1.6.1", 37 | "html-webpack-plugin": "^2.30.1", 38 | "http-proxy-middleware": "^0.17.3", 39 | "webpack-bundle-analyzer": "^2.9.0", 40 | "semver": "^5.3.0", 41 | "shelljs": "^0.7.6", 42 | "opn": "^5.1.0", 43 | "optimize-css-assets-webpack-plugin": "^3.2.0", 44 | "ora": "^1.2.0", 45 | "rimraf": "^2.6.0", 46 | "url-loader": "^0.5.8", 47 | "vue-loader": "^13.3.0", 48 | "vue-style-loader": "^3.0.1", 49 | "vue-template-compiler": "^2.5.2", 50 | "portfinder": "^1.0.13", 51 | "webpack": "^3.6.0", 52 | "webpack-dev-middleware": "^1.12.0", 53 | "webpack-hot-middleware": "^2.18.2", 54 | "webpack-merge": "^4.1.0" 55 | }, 56 | "engines": { 57 | "node": ">= 4.0.0", 58 | "npm": ">= 3.0.0" 59 | }, 60 | "browserslist": [ 61 | "> 1%", 62 | "last 2 versions", 63 | "not ie <= 8" 64 | ] 65 | } 66 | -------------------------------------------------------------------------------- /src/components/NavFooter.vue: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Song on 2017/11/1. 3 | */ 4 | 28 | 29 | 38 | 39 | 40 | 86 | -------------------------------------------------------------------------------- /static/loading-svg/loading-spinning-bubbles.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /server/app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var path = require('path'); 3 | var favicon = require('serve-favicon'); 4 | var logger = require('morgan'); 5 | var cookieParser = require('cookie-parser'); 6 | var bodyParser = require('body-parser'); 7 | var ejs = require('ejs'); 8 | 9 | var index = require('./routes/index'); 10 | var goods = require('./routes/goods'); 11 | var users = require('./routes/users'); 12 | 13 | var app = express(); 14 | 15 | // view engine setup 16 | app.set('views', path.join(__dirname, 'views')); 17 | app.engine('.html', ejs.__express) 18 | app.set('view engine', 'html'); 19 | 20 | // uncomment after placing your favicon in /public 21 | //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); 22 | app.use(logger('dev')); 23 | app.use(bodyParser.json()); 24 | app.use(bodyParser.urlencoded({ extended: false })); 25 | app.use(cookieParser()); 26 | app.use(express.static(path.join(__dirname, 'public'))); 27 | 28 | app.all('*', function(req, res, next) { 29 | // CORS配置 30 | res.header("Access-Control-Allow-Origin", "http://localhost:4000"); 31 | res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); 32 | res.header("Access-Control-Allow-Credentials", true); 33 | res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS"); 34 | res.header("X-Powered-By",' 3.2.1') 35 | res.header("Content-Type", "application/json;charset=utf-8"); 36 | next(); 37 | }); 38 | 39 | app.use(function (req,res,next) { 40 | if(req.cookies.userId){ 41 | next(); 42 | }else{ 43 | console.log("url:"+req.originalUrl); 44 | if(req.originalUrl=='/users/login' || req.originalUrl=='/users/logout' || req.originalUrl.indexOf('/goods/list')>-1){ 45 | next(); 46 | }else{ 47 | res.json({ 48 | status:'10001', 49 | msg:'当前未登录', 50 | result:'' 51 | }); 52 | } 53 | } 54 | }); 55 | 56 | app.use('/', index); 57 | app.use('/goods', goods); 58 | app.use('/users', users); 59 | 60 | // catch 404 and forward to error handler 61 | app.use(function(req, res, next) { 62 | var err = new Error('Not Found'); 63 | err.status = 404; 64 | next(err); 65 | }); 66 | 67 | // error handler 68 | app.use(function(err, req, res, next) { 69 | // set locals, only providing error in development 70 | res.locals.message = err.message; 71 | res.locals.error = req.app.get('env') === 'development' ? err : {}; 72 | 73 | // render the error page 74 | res.status(err.status || 500); 75 | res.render('error'); 76 | }); 77 | 78 | module.exports = app; 79 | -------------------------------------------------------------------------------- /src/views/OrderSuccess.vue: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Song on 2017/11/21. 3 | */ 4 | 5 | 44 | 86 | -------------------------------------------------------------------------------- /server/routes/goods.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | var mongoose = require('mongoose'); 4 | var Goods = require('./../models/goods'); 5 | 6 | 7 | //连接MongoDB数据库 8 | mongoose.connect('mongodb://127.0.0.1:27017/vue_shop'); 9 | 10 | mongoose.connection.on("connected", function () { 11 | console.log("MongoDB connected success.") 12 | }); 13 | 14 | mongoose.connection.on("error", function () { 15 | console.log("MongoDB connected fail.") 16 | }); 17 | 18 | mongoose.connection.on("disconnected", function () { 19 | console.log("MongoDB connected disconnected.") 20 | }); 21 | 22 | /* 查询商品列表数据*/ 23 | router.get('/list', function(req, res, next) { 24 | let page = parseInt(req.param("page")); 25 | let pageSize = parseInt(req.param("pageSize")); 26 | let priceLevel = req.param("priceLevel"); 27 | let sort = req.param("sort"); 28 | let skip = (page-1)*pageSize; 29 | let priceGt = ''; 30 | let priceLte = ''; 31 | let params = {}; 32 | if(priceLevel!='all'){ 33 | switch (priceLevel){ 34 | case '0':priceGt = 0;priceLte=100;break; 35 | case '1':priceGt = 100;priceLte=500;break; 36 | case '2':priceGt = 500;priceLte=1000;break; 37 | case '3':priceGt = 1000;priceLte=2000;break; 38 | case '4':priceGt = 2000;priceLte=3000;break; 39 | case '5':priceGt = 3000;priceLte=6000;break; 40 | } 41 | params = { 42 | salePrice:{ 43 | $gt:priceGt, 44 | $lte:priceLte 45 | } 46 | } 47 | } 48 | let goodsModel = Goods.find(params).skip(skip).limit(pageSize); 49 | goodsModel.sort({'salePrice':sort}); 50 | goodsModel.exec(function (err, doc) { 51 | if(err){ 52 | res.json({ 53 | status: '1', 54 | msg: err.message 55 | }) 56 | }else { 57 | res.json({ 58 | status:'0', 59 | msg:'', 60 | result:{ 61 | count: doc.length, 62 | list: doc 63 | } 64 | }) 65 | } 66 | }) 67 | }); 68 | 69 | //加入到购物车 70 | router.post("/addCart", function (req,res,next) { 71 | var userId = '100000077',productId = req.body.productId; 72 | var User = require('../models/user'); 73 | User.findOne({userId:userId}, function (err,userDoc) { 74 | if(err){ 75 | res.json({ 76 | status:"1", 77 | msg:err.message 78 | }) 79 | }else{ 80 | // console.log("userDoc:"+userDoc); 81 | if(userDoc){ 82 | var goodsItem = ''; 83 | userDoc.cartList.forEach(function (item) { 84 | if(item.productId == productId){ 85 | //购物车商品已经存在,只做数量+1 86 | goodsItem = item; 87 | item.productNum ++; 88 | } 89 | }); 90 | if(goodsItem){ 91 | userDoc.save(function (err2,doc2) { 92 | if(err2){ 93 | res.json({ 94 | status:"1", 95 | msg:err2.message 96 | }) 97 | }else{ 98 | res.json({ 99 | status:'0', 100 | msg:'', 101 | result:'suc' 102 | }) 103 | } 104 | }) 105 | }else{ 106 | //新增购物车商品 107 | Goods.findOne({productId:productId}, function (err1,doc) { 108 | if(err1){ 109 | res.json({ 110 | status:"1", 111 | msg:err1.message 112 | }) 113 | }else{ 114 | if(doc){ 115 | doc.productNum = 1; 116 | doc.checked = 1; 117 | userDoc.cartList.push(doc); 118 | userDoc.save(function (err2,doc2) { 119 | if(err2){ 120 | res.json({ 121 | status:"1", 122 | msg:err2.message 123 | }) 124 | }else{ 125 | res.json({ 126 | status:'0', 127 | msg:'', 128 | result:'suc' 129 | }) 130 | } 131 | }) 132 | } 133 | } 134 | }); 135 | } 136 | } 137 | } 138 | }) 139 | }); 140 | 141 | module.exports = router; 142 | -------------------------------------------------------------------------------- /resource/views/orderSuccess.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 下单成功 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 | 16 | 17 | 18 | arrow-short 19 | 20 | 21 | 22 | status-ok 23 | 24 | 25 | 26 | 27 | cart 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 59 |
60 | 68 |
69 |
70 |

订单提交成功,请尽快付款!

71 |
72 | 73 |
74 |
    75 |
  • 确认 收货地址
  • 76 |
  • 核对 订单信息
  • 77 |
  • 支付 方式
  • 78 |
  • 成功提交 订单
  • 79 |
80 |
81 | 82 |
83 |
84 |
85 |

恭喜!
订单提交成功,请尽快付款!

86 |

87 | 订单号:100000001 88 | 应付金额:¥40390 89 |

90 |
91 |
92 | 购物车列表 93 |
94 |
95 | 商品列表 96 |
97 |
98 |
99 |
100 |
101 | 121 |
122 | 123 | 124 | -------------------------------------------------------------------------------- /resource/views/goodsList.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 商品列表 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | arrow-short 19 | 20 | 21 | 22 | status-ok 23 | 24 | 25 | 26 | 27 | cart 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 59 |
60 | 68 |
69 |
70 |
71 | 排序: 72 | 默认 73 | 价格 74 | 筛选 75 |
76 |
77 | 78 |
79 |
80 |
价格区间:
81 |
选择价格
82 |
83 | ¥ 0 - 100 元 84 |
85 |
86 |
87 | 88 | 89 |
90 |
91 |
    92 |
  • 93 |
    94 | 95 |
    96 |
    97 |
    小米电视4 55英寸
    98 |
    3999
    99 |
    100 | 加入购物车 101 |
    102 |
    103 |
  • 104 |
105 |
106 |
107 |
108 |
109 |
110 | 130 | 131 | -------------------------------------------------------------------------------- /src/views/OrderConfirm.vue: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Song on 2017/11/21. 3 | */ 4 | 133 | 194 | -------------------------------------------------------------------------------- /src/views/GoodsList.vue: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Song on 2017/10/30. 3 | */ 4 | 84 | 85 | 237 | 238 | -------------------------------------------------------------------------------- /src/components/NavHeader.vue: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Song on 2017/11/1. 3 | */ 4 | 87 | 88 | 170 | 171 | 172 | 252 | -------------------------------------------------------------------------------- /src/views/Address.vue: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Song on 2017/10/23. 3 | */ 4 | 139 | 141 | 226 | -------------------------------------------------------------------------------- /server/routes/users.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | var User = require('./../models/user'); 4 | require('./../util/util'); 5 | 6 | //登录接口 7 | router.post("/login", function (req, res, next) { 8 | var param = { 9 | userName: req.body.userName, 10 | userPwd: req.body.userPwd 11 | } 12 | User.findOne(param, function (err,doc) { 13 | if(err){ 14 | res.json({ 15 | status:"1", 16 | msg:err.message 17 | }); 18 | }else{ 19 | if(doc){ 20 | res.cookie("userId", doc.userId,{ 21 | path:'/', 22 | maxAge:1000*60*60 23 | }); 24 | res.cookie("userName", doc.userName,{ 25 | path:'/', 26 | maxAge:1000*60*60 27 | }); 28 | res.json({ 29 | status:'0', 30 | msg:'', 31 | result:{ 32 | userName:doc.userName 33 | } 34 | }); 35 | } 36 | } 37 | }); 38 | }); 39 | 40 | //登出接口 41 | router.post("/logout", function (req,res,next) { 42 | res.cookie("userId","",{ 43 | path:"/", 44 | maxAge:-1 45 | }); 46 | res.json({ 47 | status:"0", 48 | msg:'', 49 | result:'' 50 | }) 51 | }); 52 | 53 | // 检查登录状态cookies 54 | router.get("/checkLogin", function (req,res,next) { 55 | if(req.cookies.userId){ 56 | res.json({ 57 | status:'0', 58 | msg:'', 59 | result:req.cookies.userName || '' 60 | }); 61 | }else{ 62 | res.json({ 63 | status:'1', 64 | msg:'未登录', 65 | result:'' 66 | }); 67 | } 68 | }); 69 | 70 | //查询当前用户的购物车数据 71 | router.get("/cartList", function (req,res,next) { 72 | var userId = req.cookies.userId; 73 | User.findOne({userId:userId}, function (err,doc) { 74 | if(err){ 75 | res.json({ 76 | status:'1', 77 | msg:err.message, 78 | result:'' 79 | }); 80 | }else{ 81 | if(doc){ 82 | res.json({ 83 | status:'0', 84 | msg:'', 85 | result:doc.cartList 86 | }); 87 | } 88 | } 89 | }); 90 | }); 91 | 92 | //购物车删除 93 | router.post("/cartDel", function (req,res,next) { 94 | var userId = req.cookies.userId,productId = req.body.productId; 95 | User.update({ 96 | userId:userId 97 | },{ 98 | $pull:{ 99 | 'cartList':{ 100 | 'productId':productId 101 | } 102 | } 103 | }, function (err,doc) { 104 | if(err){ 105 | res.json({ 106 | status:'1', 107 | msg:err.message, 108 | result:'' 109 | }); 110 | }else{ 111 | res.json({ 112 | status:'0', 113 | msg:'', 114 | result:'suc' 115 | }); 116 | } 117 | }); 118 | }); 119 | //修改商品数量 120 | router.post("/cartEdit", function (req,res,next) { 121 | var userId = req.cookies.userId, 122 | productId = req.body.productId, 123 | productNum = req.body.productNum, 124 | checked = req.body.checked; 125 | User.update({"userId":userId,"cartList.productId":productId},{ 126 | "cartList.$.productNum":productNum, 127 | "cartList.$.checked":checked, 128 | }, function (err,doc) { 129 | if(err){ 130 | res.json({ 131 | status:'1', 132 | msg:err.message, 133 | result:'' 134 | }); 135 | }else{ 136 | res.json({ 137 | status:'0', 138 | msg:'', 139 | result:'suc' 140 | }); 141 | } 142 | }) 143 | }); 144 | 145 | //全部选中接口 146 | router.post("/editCheckAll", function (req,res,next) { 147 | var userId = req.cookies.userId, 148 | checkAll = req.body.checkAll?'1':'0'; 149 | User.findOne({userId:userId}, function (err,user) { 150 | if(err){ 151 | res.json({ 152 | status:'1', 153 | msg:err.message, 154 | result:'' 155 | }); 156 | }else{ 157 | if(user){ 158 | user.cartList.forEach((item)=>{ 159 | item.checked = checkAll; 160 | }) 161 | user.save(function (err1,doc) { 162 | if(err1){ 163 | res.json({ 164 | status:'1', 165 | msg:err1,message, 166 | result:'' 167 | }); 168 | }else{ 169 | res.json({ 170 | status:'0', 171 | msg:'', 172 | result:'suc' 173 | }); 174 | } 175 | }) 176 | } 177 | } 178 | }); 179 | }); 180 | 181 | //查询用户地址接口 182 | router.get("/addressList", function (req,res,next) { 183 | var userId = req.cookies.userId; 184 | User.findOne({userId:userId}, function (err,doc) { 185 | if(err){ 186 | res.json({ 187 | status:'1', 188 | msg:err.message, 189 | result:'' 190 | }); 191 | }else{ 192 | res.json({ 193 | status:'0', 194 | msg:'', 195 | result:doc.addressList 196 | }); 197 | } 198 | }) 199 | }); 200 | 201 | //设置默认地址接口 202 | router.post("/setDefault", function (req,res,next) { 203 | var userId = req.cookies.userId, 204 | addressId = req.body.addressId; 205 | if(!addressId){ 206 | res.json({ 207 | status:'1003', 208 | msg:'addressId is null', 209 | result:'' 210 | }); 211 | }else{ 212 | User.findOne({userId:userId}, function (err,doc) { 213 | if(err){ 214 | res.json({ 215 | status:'1', 216 | msg:err.message, 217 | result:'' 218 | }); 219 | }else{ 220 | var addressList = doc.addressList; 221 | addressList.forEach((item)=>{ 222 | if(item.addressId ==addressId){ 223 | item.isDefault = true; 224 | }else{ 225 | item.isDefault = false; 226 | } 227 | }); 228 | 229 | doc.save(function (err1,doc1) { 230 | if(err){ 231 | res.json({ 232 | status:'1', 233 | msg:err.message, 234 | result:'' 235 | }); 236 | }else{ 237 | res.json({ 238 | status:'0', 239 | msg:'', 240 | result:'' 241 | }); 242 | } 243 | }) 244 | } 245 | }); 246 | } 247 | }); 248 | 249 | //删除地址接口 250 | router.post("/delAddress", function (req,res,next) { 251 | var userId = req.cookies.userId,addressId = req.body.addressId; 252 | User.findOne({userId:userId}, function (err,doc) { 253 | if(err){ 254 | res.json({ 255 | status:'1', 256 | msg:err.message, 257 | result:'' 258 | }); 259 | }else{ 260 | if(doc.addressList.length > 1){ 261 | User.update({ 262 | userId:userId 263 | },{ 264 | $pull:{ 265 | 'addressList':{ 266 | 'addressId':addressId 267 | } 268 | } 269 | }, function (err,doc) { 270 | if(err){ 271 | res.json({ 272 | status:'1', 273 | msg:err.message, 274 | result:'' 275 | }); 276 | }else{ 277 | res.json({ 278 | status:'0', 279 | msg:'', 280 | result:'' 281 | }); 282 | } 283 | }); 284 | } else { 285 | res.json({ 286 | status:'1', 287 | msg:'至少保留一条收货地址!', 288 | result:'' 289 | }); 290 | } 291 | } 292 | }) 293 | 294 | }); 295 | 296 | // 创建订单接口 297 | router.post("/payMent", function (req,res,next) { 298 | var userId = req.cookies.userId, 299 | addressId = req.body.addressId, 300 | orderTotal = req.body.orderTotal; 301 | User.findOne({userId:userId}, function (err,doc) { 302 | if(err){ 303 | res.json({ 304 | status:"1", 305 | msg:err.message, 306 | result:'' 307 | }); 308 | }else{ 309 | var address = '',goodsList = []; 310 | //获取当前用户的地址信息 311 | doc.addressList.forEach((item)=>{ 312 | if(addressId==item.addressId){ 313 | address = item; 314 | } 315 | }) 316 | //获取用户购物车的购买商品 317 | doc.cartList.filter((item)=>{ 318 | if(item.checked=='1'){ 319 | goodsList.push(item); 320 | } 321 | }); 322 | 323 | var platform = '622'; 324 | var r1 = Math.floor(Math.random()*10); 325 | var r2 = Math.floor(Math.random()*10); 326 | 327 | var sysDate = new Date().Format('yyyyMMddhhmmss'); 328 | var createDate = new Date().Format('yyyy-MM-dd hh:mm:ss'); 329 | var orderId = platform+r1+sysDate+r2; 330 | var order = { 331 | orderId:orderId, 332 | orderTotal:orderTotal, 333 | addressInfo:address, 334 | goodsList:goodsList, 335 | orderStatus:'1', 336 | createDate:createDate 337 | }; 338 | 339 | doc.orderList.push(order); 340 | 341 | doc.save(function (err1,doc1) { 342 | if(err1){ 343 | res.json({ 344 | status:"1", 345 | msg:err.message, 346 | result:'' 347 | }); 348 | }else{ 349 | res.json({ 350 | status:"0", 351 | msg:'', 352 | result:{ 353 | orderId:order.orderId, 354 | orderTotal:order.orderTotal 355 | } 356 | }); 357 | } 358 | }); 359 | } 360 | }) 361 | }); 362 | //根据订单Id查询订单信息 363 | router.get("/orderDetail", function (req,res,next) { 364 | var userId = req.cookies.userId,orderId = req.param("orderId"); 365 | User.findOne({userId:userId}, function (err,userInfo) { 366 | if(err){ 367 | res.json({ 368 | status:'1', 369 | msg:err.message, 370 | result:'' 371 | }); 372 | }else{ 373 | var orderList = userInfo.orderList; 374 | if(orderList.length>0){ 375 | var orderTotal = 0; 376 | orderList.forEach((item)=>{ 377 | if(item.orderId == orderId){ 378 | orderTotal = item.orderTotal; 379 | } 380 | }); 381 | if(orderTotal>0){ 382 | res.json({ 383 | status:'0', 384 | msg:'', 385 | result:{ 386 | orderId:orderId, 387 | orderTotal:orderTotal 388 | } 389 | }) 390 | }else{ 391 | res.json({ 392 | status:'120002', 393 | msg:'无此订单', 394 | result:'' 395 | }); 396 | } 397 | }else{ 398 | res.json({ 399 | status:'120001', 400 | msg:'当前用户未创建订单', 401 | result:'' 402 | }); 403 | } 404 | } 405 | }) 406 | }); 407 | 408 | // 获取购车商品数量 409 | router.get("/getCartCount", function (req,res,next) { 410 | if(req.cookies && req.cookies.userId){ 411 | console.log("userId:"+req.cookies.userId); 412 | var userId = req.cookies.userId; 413 | User.findOne({"userId":userId}, function (err,doc) { 414 | if(err){ 415 | res.json({ 416 | status:"0", 417 | msg:err.message 418 | }); 419 | }else{ 420 | let cartList = doc.cartList; 421 | let cartCount = 0; 422 | cartList.map(function(item){ 423 | cartCount += parseFloat(item.productNum); 424 | }); 425 | res.json({ 426 | status:"0", 427 | msg:"", 428 | result:cartCount 429 | }); 430 | } 431 | }); 432 | }else{ 433 | res.json({ 434 | status:"0", 435 | msg:"当前用户不存在" 436 | }); 437 | } 438 | }); 439 | module.exports = router; 440 | -------------------------------------------------------------------------------- /src/views/Cart.vue: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Song on 2017/10/23. 3 | */ 4 | 145 | 146 | 272 | 273 | 297 | -------------------------------------------------------------------------------- /resource/views/orderConfirm.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 订单确认 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 | 16 | 17 | 18 | arrow-short 19 | 20 | 21 | 22 | status-ok 23 | 24 | 25 | 26 | 27 | cart 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 59 |
60 | 68 | 69 | 70 | 71 | add2 72 | 73 | 74 | 75 | ok 76 | 77 | 78 | 79 | edit 80 | 81 | 82 | 83 | delete 84 | 85 | 86 | 87 | clock 88 | 89 | 90 | 91 | 92 |
93 |
94 | 95 |
96 |
    97 |
  • 确认 收货地址
  • 98 |
  • 核对 订单信息
  • 99 |
  • 支付 方式
  • 100 |
  • 成功提交 订单
  • 101 |
102 |
103 | 104 | 105 |
106 |

填写并核对订单信息

107 |
108 |
109 |
110 |
111 |
    112 |
  • 商品
  • 113 |
  • 单价
  • 114 |
  • 数量
  • 115 |
  • 小计
  • 116 |
117 |
118 |
    119 |
  • 120 |
    121 |
    122 | 123 |
    124 |
    125 |
    小米电视4 55英寸
    126 | 127 |
    128 |
    129 |
    130 |
    3999
    131 |
    132 |
    133 |
    134 |
    135 |
    136 | ×10 137 |
    138 |
    139 |
    有货
    140 |
    141 |
    142 |
    143 |
    ¥39990
    144 |
    145 |
  • 146 |
147 |
148 |
149 | 150 | 151 |
152 |
153 |
    154 |
  • 155 | 商品总额: 156 | ¥39990 157 |
  • 158 |
  • 159 | 运费: 160 | ¥100 161 |
  • 162 |
  • 163 | 优惠: 164 | ¥100 165 |
  • 166 |
  • 167 | 纳税: 168 | ¥400 169 |
  • 170 |
  • 171 | 应付总额: 172 | ¥40390 173 |
  • 174 |
175 |
176 |
177 | 178 |
179 |
180 | 181 |
182 |
183 | 184 |
185 |
186 |
187 |
188 | 208 |
209 | 210 | 211 | -------------------------------------------------------------------------------- /resource/css/goods-list.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | .accessory-list > ul:after { 4 | visibility: hidden; 5 | display: block; 6 | content: " "; 7 | clear: both; 8 | } 9 | 10 | .accessory-list > ul > li { 11 | float: left; 12 | width: 23.80952%; 13 | margin-right: 1.5873%; 14 | margin-bottom: 1.5873%; 15 | background: #fff; 16 | border: 2px solid #e9e9e9; 17 | -webkit-transition: all .5s ease-out; 18 | transition: all .5s ease-out; 19 | } 20 | 21 | .accessory-list > ul > li:hover { 22 | border-color: #ee7a23; 23 | -webkit-transform: translateY(-5px); 24 | -ms-transform: translateY(-5px); 25 | transform: translateY(-5px); 26 | -webkit-box-shadow: 0 0 10px #999; 27 | box-shadow: 0 0 10px #999; 28 | -webkit-transition: all .5s ease-out; 29 | transition: all .5s ease-out; 30 | } 31 | 32 | .accessory-list.col-4 > ul > li { 33 | width: 23.80952%; 34 | margin-right: 1.5873%; 35 | margin-bottom: 1.5873%; 36 | } 37 | 38 | .accessory-list.col-4 > ul > li:nth-child(4n) { 39 | margin-right: 0; 40 | } 41 | 42 | .accessory-list.col-5 > ul > li { 43 | width: 18.73016%; 44 | margin-right: 1.5873%; 45 | margin-bottom: 1.5873%; 46 | } 47 | 48 | .accessory-list.col-5 > ul > li:nth-child(5n) { 49 | margin-right: 0; 50 | } 51 | 52 | .accessory-list .pic { 53 | overflow: hidden; 54 | } 55 | 56 | .accessory-list .pic a { 57 | display: block; 58 | width: 100%; 59 | height: 100%; 60 | } 61 | 62 | .accessory-list .pic img { 63 | width: 100%; 64 | } 65 | 66 | .accessory-list .main { 67 | padding: 10px 10px 10px 10px; 68 | } 69 | 70 | .accessory-list .main .name { 71 | height: 2em; 72 | line-height: 1.25em; 73 | padding-bottom: 10px; 74 | font-family: "moderat", sans-serif; 75 | font-weight: bold; 76 | overflow: hidden; 77 | } 78 | 79 | .accessory-list .main .price { 80 | float: left; 81 | line-height: 30px; 82 | color: #d1434a; 83 | font-size: 1.25em; 84 | } 85 | 86 | .accessory-list .main .quantity { 87 | float: right; 88 | } 89 | 90 | .accessory-list .main .btn-area { 91 | clear: both; 92 | padding-top: 10px; 93 | } 94 | 95 | .accessory-list .main .btn-area .btn { 96 | width: 100%; 97 | } 98 | 99 | @media only screen and (max-width: 991px) { 100 | .accessory-list.col-4 > ul > li { 101 | width: 32.27513%; 102 | margin-right: 1.5873%; 103 | margin-bottom: 1.5873%; 104 | } 105 | 106 | .accessory-list.col-4 > ul > li:nth-child(4n) { 107 | margin-right: 1.5873%; 108 | } 109 | 110 | .accessory-list.col-4 > ul > li:nth-child(3n) { 111 | margin-right: 0; 112 | } 113 | 114 | .accessory-list.col-5 > ul > li { 115 | width: 23.80952%; 116 | margin-right: 1.5873%; 117 | margin-bottom: 1.5873%; 118 | } 119 | 120 | .accessory-list.col-5 > ul > li:nth-child(5n) { 121 | margin-right: 20px; 122 | } 123 | 124 | .accessory-list.col-5 > ul > li:nth-child(4n) { 125 | margin-right: 0; 126 | } 127 | 128 | .accessory-list .main .name { 129 | font-size: 1.3rem; 130 | } 131 | 132 | .accessory-list .main .btn-area .btn { 133 | font-size: 1.2rem; 134 | } 135 | } 136 | 137 | @media only screen and (max-width: 767px) { 138 | .accessory-list { 139 | font-size: 1.2rem; 140 | } 141 | 142 | .accessory-list.col-4 > ul > li, .accessory-list.col-5 > ul > li { 143 | width: 100%; 144 | margin-bottom: 10px; 145 | padding: 10px; 146 | border: none; 147 | border-top: 1px solid #e9e9e9; 148 | border-bottom: 1px solid #e9e9e9; 149 | } 150 | 151 | .accessory-list.col-4 > ul > li:hover, .accessory-list.col-5 > ul > li:hover { 152 | border-color: none; 153 | -webkit-transform: none; 154 | -ms-transform: none; 155 | transform: none; 156 | -webkit-box-shadow: none; 157 | box-shadow: none; 158 | -webkit-transition: none .5s ease-out; 159 | transition: none .5s ease-out; 160 | } 161 | 162 | .accessory-list .pic { 163 | float: left; 164 | width: 110px; 165 | height: 72px; 166 | border: 1px solid #e9e9e9; 167 | } 168 | 169 | .accessory-list .pic a { 170 | display: block; 171 | width: 100%; 172 | height: 100%; 173 | padding-bottom: 0; 174 | } 175 | 176 | .accessory-list .main { 177 | padding: 0 0 0 90px; 178 | } 179 | 180 | .accessory-list .main:after { 181 | visibility: hidden; 182 | display: block; 183 | content: " "; 184 | clear: both; 185 | } 186 | 187 | .accessory-list .main .price { 188 | float: none; 189 | } 190 | 191 | .accessory-list .main .quantity { 192 | float: left; 193 | } 194 | 195 | .accessory-list .main .name { 196 | height: auto; 197 | min-height: 30px; 198 | } 199 | 200 | .accessory-list .main .btn-area { 201 | padding: 0; 202 | clear: none; 203 | float: right; 204 | } 205 | 206 | .accessory-list .main .btn-area .btn { 207 | height: 30px; 208 | line-height: 30px; 209 | padding-left: .8em; 210 | padding-right: .8em; 211 | font-size: 1rem; 212 | letter-spacing: .1em; 213 | } 214 | } 215 | 216 | .filter { 217 | width: 230px; 218 | padding: 0 20px 0 20px; 219 | color: #605F5F; 220 | -webkit-transition: right .5s ease-out; 221 | transition: right .5s ease-out; 222 | } 223 | 224 | .filter dl { 225 | min-height: 180px; 226 | margin-bottom: 50px; 227 | } 228 | 229 | .filter dt { 230 | margin-bottom: 30px; 231 | font-family: "moderat", sans-serif; 232 | letter-spacing: .25em; 233 | text-transform: uppercase; 234 | font-weight: bold; 235 | } 236 | 237 | .filter dd { 238 | line-height: 1.2em; 239 | margin: 20px 0; 240 | } 241 | 242 | .filter dd a { 243 | display: block; 244 | padding: 5px 0; 245 | -webkit-transition: padding-left .3s ease-out; 246 | transition: padding-left .3s ease-out; 247 | } 248 | 249 | .filter dd a:hover, .filter dd .cur { 250 | color: #ee7a23; 251 | } 252 | 253 | .filter .filter-category ul { 254 | display: none; 255 | padding-left: 20px; 256 | } 257 | 258 | .filter .filter-category li { 259 | line-height: 1.2em; 260 | margin: 10px 0; 261 | } 262 | 263 | .filter .filter-category ul > li > ul { 264 | margin-bottom: 20px; 265 | } 266 | 267 | .filter .filter-category ul > li > ul .icon-arrow-down { 268 | display: none; 269 | } 270 | 271 | .filter .filter-category a:hover .icon-arrow-down { 272 | fill: #ee7a23; 273 | -webkit-transition: -webkit-transform .3s ease-out; 274 | transition: -webkit-transform .3s ease-out; 275 | transition: transform .3s ease-out; 276 | transition: transform .3s ease-out, -webkit-transform .3s ease-out; 277 | } 278 | 279 | .filter .filter-category .icon-arrow-down { 280 | width: 11px; 281 | height: 11px; 282 | fill: #605F5F; 283 | vertical-align: middle; 284 | margin-left: 3px; 285 | -webkit-transition: -webkit-transform .3s ease-out; 286 | transition: -webkit-transform .3s ease-out; 287 | transition: transform .3s ease-out; 288 | transition: transform .3s ease-out, -webkit-transform .3s ease-out; 289 | } 290 | 291 | .filter .filter-category .open ~ ul { 292 | display: block; 293 | } 294 | 295 | .filter .filter-category .open .icon-arrow-down { 296 | -webkit-transform: rotate(180deg); 297 | -ms-transform: rotate(180deg); 298 | transform: rotate(180deg); 299 | } 300 | 301 | .filter .filter-price dd a:hover, .filter .filter-price dd .cur { 302 | -webkit-transition: padding-left .3s ease-out; 303 | transition: padding-left .3s ease-out; 304 | border-left: 2px solid #ee7a23; 305 | padding-left: 15px; 306 | } 307 | 308 | .filter .filter-price dd .cur { 309 | font-weight: bold; 310 | } 311 | 312 | .filter.filterby-show { 313 | right: 0; 314 | -webkit-transition: right .5s ease-out; 315 | transition: right .5s ease-out; 316 | } 317 | 318 | @media only screen and (max-width: 767px) { 319 | .filter { 320 | position: fixed; 321 | right: -230px; 322 | top: 0; 323 | z-index: 201; 324 | height: 100%; 325 | background: #fff; 326 | padding: 0; 327 | margin: 0; 328 | overflow: auto; 329 | } 330 | 331 | .filter dl { 332 | min-height: 0; 333 | margin: 0; 334 | } 335 | 336 | .filter dt { 337 | background: #f0f0f0; 338 | height: 55px; 339 | line-height: 55px; 340 | margin: 0; 341 | padding-left: 20px; 342 | } 343 | 344 | .filter dd { 345 | margin: 0; 346 | } 347 | 348 | .filter dd a { 349 | padding: 12px 10px 12px 15px; 350 | border-bottom: 1px solid #e9e9e9; 351 | } 352 | 353 | .filter dd li { 354 | margin: 0; 355 | } 356 | 357 | .filter .filter-category ul { 358 | padding-left: 0; 359 | } 360 | 361 | .filter .filter-category ul li > a { 362 | padding-left: 30px; 363 | } 364 | 365 | .filter .filter-category ul li > ul a { 366 | padding-left: 45px; 367 | } 368 | 369 | .filter .filter-category .icon-arrow-down { 370 | float: right; 371 | } 372 | } 373 | 374 | /** search resule **/ 375 | /** 搜索结果页 **/ 376 | .search-result-wrap { 377 | background: #f0f0f0; 378 | } 379 | 380 | .search-result-wrap .search-result-num { 381 | padding: 10px 0; 382 | line-height: 25px; 383 | } 384 | 385 | .search-result-wrap .search-result-num strong { 386 | color: #d1434a; 387 | } 388 | 389 | .accessory-result { 390 | display: -webkit-box; 391 | display: -webkit-flex; 392 | display: -ms-flexbox; 393 | display: flex; 394 | } 395 | 396 | .accessory-result .filter { 397 | margin-right: 25px; 398 | } 399 | 400 | .accessory-result .accessory-list-wrap { 401 | -webkit-box-flex: 1; 402 | -webkit-flex: 1; 403 | -ms-flex: 1; 404 | flex: 1; 405 | } 406 | 407 | .filter-nav { 408 | height: 55px; 409 | line-height: 55px; 410 | margin: 60px 0 30px 0; 411 | padding: 0 20px; 412 | background: #fff; 413 | text-align: right; 414 | overflow: hidden; 415 | } 416 | 417 | .filter-nav a { 418 | margin: 0 10px; 419 | } 420 | 421 | .filter-nav a.cur, .filter-nav a:hover { 422 | color: #ee7a23; 423 | } 424 | 425 | .filter-nav .sort-up .icon-arrow-short { 426 | -webkit-transform: rotate(180deg); 427 | -ms-transform: rotate(180deg); 428 | transform: rotate(180deg); 429 | } 430 | 431 | .filter-nav .filterby { 432 | display: none; 433 | letter-spacing: .25em; 434 | text-transform: uppercase; 435 | font-size: 12px; 436 | } 437 | 438 | @media only screen and (max-width: 767px) { 439 | .search-result-wrap { 440 | background: none; 441 | padding: 0 10px; 442 | } 443 | 444 | .filter-nav { 445 | margin: 0; 446 | padding: 0 10px; 447 | background: #f0f0f0; 448 | border-top: 1px solid #e9e9e9; 449 | text-align: left; 450 | } 451 | 452 | .filter-nav:after { 453 | visibility: hidden; 454 | display: block; 455 | content: " "; 456 | clear: both; 457 | } 458 | 459 | .filter-nav a { 460 | float: left; 461 | } 462 | 463 | .filter-nav .filterby { 464 | display: block; 465 | float: right; 466 | } 467 | 468 | .filter-nav .sortby { 469 | display: none; 470 | } 471 | 472 | .accessory-result .filter { 473 | margin: 0; 474 | } 475 | } 476 | 477 | .icon-arrow-short { 478 | width: 11px; 479 | height: 11px; 480 | } 481 | 482 | .page-title-accessory { 483 | display: none; 484 | } 485 | 486 | .accessory-title:after { 487 | visibility: hidden; 488 | display: block; 489 | content: " "; 490 | clear: both; 491 | } 492 | 493 | .accessory-title h2 { 494 | float: left; 495 | } 496 | 497 | .accessory-title .accessory-more-link { 498 | float: right; 499 | line-height: 30px; 500 | } 501 | 502 | .accessory-title .accessory-more-link .icon-arrow-short { 503 | margin-left: 15px; 504 | -webkit-transform: rotate(-90deg); 505 | -ms-transform: rotate(-90deg); 506 | transform: rotate(-90deg); 507 | } 508 | 509 | .accessory-title .accessory-more-link:hover { 510 | color: #ee7a23; 511 | } 512 | 513 | .accessory-title .accessory-more-link:hover .icon-arrow-short { 514 | fill: #ee7a23; 515 | } 516 | 517 | .accessory-classify { 518 | position: relative; 519 | } 520 | 521 | .accessory-result-page .view-more-normal { 522 | height: 120px; 523 | margin-top: 40px; 524 | } 525 | 526 | .accessory-result-page .view-more-normal .view-more-btn { 527 | top: 0; 528 | padding-top: 40px; 529 | } 530 | 531 | @media only screen and (max-width: 767px) { 532 | .page-title-accessory { 533 | display: block; 534 | } 535 | 536 | .accessory-classify { 537 | padding-bottom: 55px; 538 | } 539 | 540 | .accessory-title { 541 | padding-left: 10px; 542 | padding-right: 10px; 543 | border: none; 544 | } 545 | 546 | .accessory-title .accessory-more-link { 547 | position: absolute; 548 | bottom: 10px; 549 | left: 0; 550 | width: 100%; 551 | height: 45px; 552 | line-height: 45px; 553 | background: #fff; 554 | border-top: 1px solid #e9e9e9; 555 | border-bottom: 1px solid #e9e9e9; 556 | } 557 | 558 | .accessory-result-page { 559 | font-size: 1.2rem; 560 | } 561 | 562 | .accessory-result-page .btn-wrap { 563 | margin: 0; 564 | } 565 | 566 | .accessory-result-page .btn-wrap .btn { 567 | /*line-height: 1.2em;*/ 568 | white-space: normal; 569 | } 570 | 571 | .accessory-result-page .view-more-normal { 572 | height: 60px; 573 | margin-top: 10px; 574 | } 575 | 576 | .accessory-result-page .view-more-normal .view-more-btn { 577 | top: 0; 578 | padding-top: 20px; 579 | } 580 | } 581 | -------------------------------------------------------------------------------- /src/assets/css/goods-list.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | .accessory-list > ul:after { 4 | visibility: hidden; 5 | display: block; 6 | content: " "; 7 | clear: both; 8 | } 9 | 10 | .accessory-list > ul > li { 11 | float: left; 12 | width: 23.80952%; 13 | margin-right: 1.5873%; 14 | margin-bottom: 1.5873%; 15 | background: #fff; 16 | border: 2px solid #e9e9e9; 17 | -webkit-transition: all .5s ease-out; 18 | transition: all .5s ease-out; 19 | } 20 | 21 | .accessory-list > ul > li:hover { 22 | border-color: #ee7a23; 23 | -webkit-transform: translateY(-5px); 24 | -ms-transform: translateY(-5px); 25 | transform: translateY(-5px); 26 | -webkit-box-shadow: 0 0 10px #999; 27 | box-shadow: 0 0 10px #999; 28 | -webkit-transition: all .5s ease-out; 29 | transition: all .5s ease-out; 30 | } 31 | 32 | .accessory-list.col-4 > ul > li { 33 | width: 23.80952%; 34 | margin-right: 1.5873%; 35 | margin-bottom: 1.5873%; 36 | } 37 | 38 | .accessory-list.col-4 > ul > li:nth-child(4n) { 39 | margin-right: 0; 40 | } 41 | 42 | .accessory-list.col-5 > ul > li { 43 | width: 18.73016%; 44 | margin-right: 1.5873%; 45 | margin-bottom: 1.5873%; 46 | } 47 | 48 | .accessory-list.col-5 > ul > li:nth-child(5n) { 49 | margin-right: 0; 50 | } 51 | 52 | .accessory-list .pic { 53 | overflow: hidden; 54 | } 55 | 56 | .accessory-list .pic a { 57 | display: block; 58 | width: 100%; 59 | height: 100%; 60 | } 61 | 62 | .accessory-list .pic img { 63 | width: 100%; 64 | } 65 | 66 | .accessory-list .main { 67 | padding: 10px 10px 10px 10px; 68 | } 69 | 70 | .accessory-list .main .name { 71 | height: 2em; 72 | line-height: 1.25em; 73 | padding-bottom: 10px; 74 | font-family: "moderat", sans-serif; 75 | font-weight: bold; 76 | overflow: hidden; 77 | } 78 | 79 | .accessory-list .main .price { 80 | float: left; 81 | line-height: 30px; 82 | color: #d1434a; 83 | font-size: 1.25em; 84 | } 85 | 86 | .accessory-list .main .quantity { 87 | float: right; 88 | } 89 | 90 | .accessory-list .main .btn-area { 91 | clear: both; 92 | padding-top: 10px; 93 | } 94 | 95 | .accessory-list .main .btn-area .btn { 96 | width: 100%; 97 | } 98 | 99 | @media only screen and (max-width: 991px) { 100 | .accessory-list.col-4 > ul > li { 101 | width: 32.27513%; 102 | margin-right: 1.5873%; 103 | margin-bottom: 1.5873%; 104 | } 105 | 106 | .accessory-list.col-4 > ul > li:nth-child(4n) { 107 | margin-right: 1.5873%; 108 | } 109 | 110 | .accessory-list.col-4 > ul > li:nth-child(3n) { 111 | margin-right: 0; 112 | } 113 | 114 | .accessory-list.col-5 > ul > li { 115 | width: 23.80952%; 116 | margin-right: 1.5873%; 117 | margin-bottom: 1.5873%; 118 | } 119 | 120 | .accessory-list.col-5 > ul > li:nth-child(5n) { 121 | margin-right: 20px; 122 | } 123 | 124 | .accessory-list.col-5 > ul > li:nth-child(4n) { 125 | margin-right: 0; 126 | } 127 | 128 | .accessory-list .main .name { 129 | font-size: 1.3rem; 130 | } 131 | 132 | .accessory-list .main .btn-area .btn { 133 | font-size: 1.2rem; 134 | } 135 | } 136 | 137 | @media only screen and (max-width: 767px) { 138 | .accessory-list { 139 | font-size: 1.2rem; 140 | } 141 | 142 | .accessory-list.col-4 > ul > li, .accessory-list.col-5 > ul > li { 143 | width: 100%; 144 | margin-bottom: 10px; 145 | padding: 10px; 146 | border: none; 147 | border-top: 1px solid #e9e9e9; 148 | border-bottom: 1px solid #e9e9e9; 149 | } 150 | 151 | .accessory-list.col-4 > ul > li:hover, .accessory-list.col-5 > ul > li:hover { 152 | border-color: none; 153 | -webkit-transform: none; 154 | -ms-transform: none; 155 | transform: none; 156 | -webkit-box-shadow: none; 157 | box-shadow: none; 158 | -webkit-transition: none .5s ease-out; 159 | transition: none .5s ease-out; 160 | } 161 | 162 | .accessory-list .pic { 163 | float: left; 164 | width: 110px; 165 | height: 72px; 166 | border: 1px solid #e9e9e9; 167 | } 168 | 169 | .accessory-list .pic a { 170 | display: block; 171 | width: 100%; 172 | height: 100%; 173 | padding-bottom: 0; 174 | } 175 | 176 | .accessory-list .main { 177 | padding: 0 0 0 90px; 178 | } 179 | 180 | .accessory-list .main:after { 181 | visibility: hidden; 182 | display: block; 183 | content: " "; 184 | clear: both; 185 | } 186 | 187 | .accessory-list .main .price { 188 | float: none; 189 | } 190 | 191 | .accessory-list .main .quantity { 192 | float: left; 193 | } 194 | 195 | .accessory-list .main .name { 196 | height: auto; 197 | min-height: 30px; 198 | } 199 | 200 | .accessory-list .main .btn-area { 201 | padding: 0; 202 | clear: none; 203 | float: right; 204 | } 205 | 206 | .accessory-list .main .btn-area .btn { 207 | height: 30px; 208 | line-height: 30px; 209 | padding-left: .8em; 210 | padding-right: .8em; 211 | font-size: 1rem; 212 | letter-spacing: .1em; 213 | } 214 | } 215 | 216 | .filter { 217 | width: 230px; 218 | padding: 0 20px 0 20px; 219 | color: #605F5F; 220 | -webkit-transition: right .5s ease-out; 221 | transition: right .5s ease-out; 222 | } 223 | 224 | .filter dl { 225 | min-height: 180px; 226 | margin-bottom: 50px; 227 | } 228 | 229 | .filter dt { 230 | margin-bottom: 30px; 231 | font-family: "moderat", sans-serif; 232 | letter-spacing: .25em; 233 | text-transform: uppercase; 234 | font-weight: bold; 235 | } 236 | 237 | .filter dd { 238 | line-height: 1.2em; 239 | margin: 20px 0; 240 | } 241 | 242 | .filter dd a { 243 | display: block; 244 | padding: 5px 0; 245 | -webkit-transition: padding-left .3s ease-out; 246 | transition: padding-left .3s ease-out; 247 | } 248 | 249 | .filter dd a:hover, .filter dd .cur { 250 | color: #ee7a23; 251 | } 252 | 253 | .filter .filter-category ul { 254 | display: none; 255 | padding-left: 20px; 256 | } 257 | 258 | .filter .filter-category li { 259 | line-height: 1.2em; 260 | margin: 10px 0; 261 | } 262 | 263 | .filter .filter-category ul > li > ul { 264 | margin-bottom: 20px; 265 | } 266 | 267 | .filter .filter-category ul > li > ul .icon-arrow-down { 268 | display: none; 269 | } 270 | 271 | .filter .filter-category a:hover .icon-arrow-down { 272 | fill: #ee7a23; 273 | -webkit-transition: -webkit-transform .3s ease-out; 274 | transition: -webkit-transform .3s ease-out; 275 | transition: transform .3s ease-out; 276 | transition: transform .3s ease-out, -webkit-transform .3s ease-out; 277 | } 278 | 279 | .filter .filter-category .icon-arrow-down { 280 | width: 11px; 281 | height: 11px; 282 | fill: #605F5F; 283 | vertical-align: middle; 284 | margin-left: 3px; 285 | -webkit-transition: -webkit-transform .3s ease-out; 286 | transition: -webkit-transform .3s ease-out; 287 | transition: transform .3s ease-out; 288 | transition: transform .3s ease-out, -webkit-transform .3s ease-out; 289 | } 290 | 291 | .filter .filter-category .open ~ ul { 292 | display: block; 293 | } 294 | 295 | .filter .filter-category .open .icon-arrow-down { 296 | -webkit-transform: rotate(180deg); 297 | -ms-transform: rotate(180deg); 298 | transform: rotate(180deg); 299 | } 300 | 301 | .filter .filter-price dd a:hover, .filter .filter-price dd .cur { 302 | -webkit-transition: padding-left .3s ease-out; 303 | transition: padding-left .3s ease-out; 304 | border-left: 2px solid #ee7a23; 305 | padding-left: 15px; 306 | } 307 | 308 | .filter .filter-price dd .cur { 309 | font-weight: bold; 310 | } 311 | 312 | .filter.filterby-show { 313 | right: 0; 314 | -webkit-transition: right .5s ease-out; 315 | transition: right .5s ease-out; 316 | } 317 | 318 | @media only screen and (max-width: 767px) { 319 | .filter { 320 | position: fixed; 321 | right: -230px; 322 | top: 0; 323 | z-index: 201; 324 | height: 100%; 325 | background: #fff; 326 | padding: 0; 327 | margin: 0; 328 | overflow: auto; 329 | } 330 | 331 | .filter dl { 332 | min-height: 0; 333 | margin: 0; 334 | } 335 | 336 | .filter dt { 337 | background: #f0f0f0; 338 | height: 55px; 339 | line-height: 55px; 340 | margin: 0; 341 | padding-left: 20px; 342 | } 343 | 344 | .filter dd { 345 | margin: 0; 346 | } 347 | 348 | .filter dd a { 349 | padding: 12px 10px 12px 15px; 350 | border-bottom: 1px solid #e9e9e9; 351 | } 352 | 353 | .filter dd li { 354 | margin: 0; 355 | } 356 | 357 | .filter .filter-category ul { 358 | padding-left: 0; 359 | } 360 | 361 | .filter .filter-category ul li > a { 362 | padding-left: 30px; 363 | } 364 | 365 | .filter .filter-category ul li > ul a { 366 | padding-left: 45px; 367 | } 368 | 369 | .filter .filter-category .icon-arrow-down { 370 | float: right; 371 | } 372 | } 373 | 374 | /** search resule **/ 375 | /** 搜索结果页 **/ 376 | .search-result-wrap { 377 | background: #f0f0f0; 378 | } 379 | 380 | .search-result-wrap .search-result-num { 381 | padding: 10px 0; 382 | line-height: 25px; 383 | } 384 | 385 | .search-result-wrap .search-result-num strong { 386 | color: #d1434a; 387 | } 388 | 389 | .accessory-result { 390 | display: -webkit-box; 391 | display: -webkit-flex; 392 | display: -ms-flexbox; 393 | display: flex; 394 | } 395 | 396 | .accessory-result .filter { 397 | margin-right: 25px; 398 | } 399 | 400 | .accessory-result .accessory-list-wrap { 401 | -webkit-box-flex: 1; 402 | -webkit-flex: 1; 403 | -ms-flex: 1; 404 | flex: 1; 405 | } 406 | 407 | .filter-nav { 408 | height: 55px; 409 | line-height: 55px; 410 | margin: 60px 0 30px 0; 411 | padding: 0 20px; 412 | background: #fff; 413 | text-align: right; 414 | overflow: hidden; 415 | } 416 | 417 | .filter-nav a { 418 | margin: 0 10px; 419 | } 420 | 421 | .filter-nav a.cur, .filter-nav a:hover { 422 | color: #ee7a23; 423 | } 424 | 425 | .filter-nav .sort-up .icon-arrow-short { 426 | -webkit-transform: rotate(180deg); 427 | -ms-transform: rotate(180deg); 428 | transform: rotate(180deg); 429 | } 430 | 431 | .filter-nav .filterby { 432 | display: none; 433 | letter-spacing: .25em; 434 | text-transform: uppercase; 435 | font-size: 12px; 436 | } 437 | 438 | @media only screen and (max-width: 767px) { 439 | .search-result-wrap { 440 | background: none; 441 | padding: 0 10px; 442 | } 443 | 444 | .filter-nav { 445 | margin: 0; 446 | padding: 0 10px; 447 | background: #f0f0f0; 448 | border-top: 1px solid #e9e9e9; 449 | text-align: left; 450 | } 451 | 452 | .filter-nav:after { 453 | visibility: hidden; 454 | display: block; 455 | content: " "; 456 | clear: both; 457 | } 458 | 459 | .filter-nav a { 460 | float: left; 461 | } 462 | 463 | .filter-nav .filterby { 464 | display: block; 465 | float: right; 466 | } 467 | 468 | .filter-nav .sortby { 469 | display: none; 470 | } 471 | 472 | .accessory-result .filter { 473 | margin: 0; 474 | } 475 | } 476 | 477 | .icon-arrow-short { 478 | width: 11px; 479 | height: 11px; 480 | } 481 | 482 | .page-title-accessory { 483 | display: none; 484 | } 485 | 486 | .accessory-title:after { 487 | visibility: hidden; 488 | display: block; 489 | content: " "; 490 | clear: both; 491 | } 492 | 493 | .accessory-title h2 { 494 | float: left; 495 | } 496 | 497 | .accessory-title .accessory-more-link { 498 | float: right; 499 | line-height: 30px; 500 | } 501 | 502 | .accessory-title .accessory-more-link .icon-arrow-short { 503 | margin-left: 15px; 504 | -webkit-transform: rotate(-90deg); 505 | -ms-transform: rotate(-90deg); 506 | transform: rotate(-90deg); 507 | } 508 | 509 | .accessory-title .accessory-more-link:hover { 510 | color: #ee7a23; 511 | } 512 | 513 | .accessory-title .accessory-more-link:hover .icon-arrow-short { 514 | fill: #ee7a23; 515 | } 516 | 517 | .accessory-classify { 518 | position: relative; 519 | } 520 | 521 | .accessory-result-page .view-more-normal { 522 | height: 120px; 523 | margin-top: 40px; 524 | } 525 | 526 | .accessory-result-page .view-more-normal .view-more-btn { 527 | top: 0; 528 | padding-top: 40px; 529 | } 530 | 531 | @media only screen and (max-width: 767px) { 532 | .page-title-accessory { 533 | display: block; 534 | } 535 | 536 | .accessory-classify { 537 | padding-bottom: 55px; 538 | } 539 | 540 | .accessory-title { 541 | padding-left: 10px; 542 | padding-right: 10px; 543 | border: none; 544 | } 545 | 546 | .accessory-title .accessory-more-link { 547 | position: absolute; 548 | bottom: 10px; 549 | left: 0; 550 | width: 100%; 551 | height: 45px; 552 | line-height: 45px; 553 | background: #fff; 554 | border-top: 1px solid #e9e9e9; 555 | border-bottom: 1px solid #e9e9e9; 556 | } 557 | 558 | .accessory-result-page { 559 | font-size: 1.2rem; 560 | } 561 | 562 | .accessory-result-page .btn-wrap { 563 | margin: 0; 564 | } 565 | 566 | .accessory-result-page .btn-wrap .btn { 567 | /*line-height: 1.2em;*/ 568 | white-space: normal; 569 | } 570 | 571 | .accessory-result-page .view-more-normal { 572 | height: 60px; 573 | margin-top: 10px; 574 | } 575 | 576 | .accessory-result-page .view-more-normal .view-more-btn { 577 | top: 0; 578 | padding-top: 20px; 579 | } 580 | } 581 | -------------------------------------------------------------------------------- /resource/views/address.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 收货地址 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | arrow-short 18 | 19 | 20 | 21 | status-ok 22 | 23 | 24 | 25 | 26 | cart 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 58 |
59 | 67 |
68 | 69 | 70 | 71 | add 72 | 73 | 74 | 75 | ok 76 | 77 | 78 | 79 | edit 80 | 81 | 82 | 83 | delete 84 | 85 | 86 | 87 | 88 | 89 | 90 | clock 91 | 92 | 93 | 94 | question 95 | 96 | 97 | 98 | 99 | 100 | 101 |
102 |
103 |
104 |

check out

105 |
106 | 107 |
108 |
    109 |
  • 确认 收货地址
  • 110 |
  • 核对 订单信息
  • 111 |
  • 支付 方式
  • 112 |
  • 成功提交 订单
  • 113 |
114 |
115 | 116 | 117 |
118 |

收货人信息

119 |
120 |
121 |
122 |
    123 |
  • 124 |
    125 |
    XXX(用户名)
    126 |
    湖南省长沙市麓谷企业广场
    127 |
    1017735262@qq.com
    128 |
    129 |
    130 | 131 | 132 | 133 |
    134 |
    135 | Set default 136 |
    137 |
    默认地址
    138 |
  • 139 |
  • 140 |
    141 | 142 | 143 | 144 |

    新增收货地址

    145 |
    146 |
  • 147 |
148 |
149 | 150 | 159 |
160 | 161 | 162 |
163 |

货运方式

164 |
165 | 168 |
169 |
170 |
    171 |
  • 172 |
    京东快递
    173 |
    包邮
    174 |
    175 |

    自签收后7天内退货,15天内换货,可享1次上门取件服务

    176 |
    177 |
  • 178 |
179 |
180 |
181 |
182 | 去结算 183 |
184 |
185 |
186 |
187 | 207 | 208 | 209 | -------------------------------------------------------------------------------- /resource/views/cart.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 购物车 9 | 10 | 11 | 12 | 13 | 14 | 15 | 39 | 40 | 41 |
42 | 43 | 44 | 45 | arrow-short 46 | 47 | 48 | 49 | status-ok 50 | 51 | 52 | 53 | 54 | cart 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 86 |
87 | 95 | 97 | 98 | 99 | add2 100 | 102 | 103 | 104 | ok 105 | 107 | 108 | 109 | edit 110 | 112 | 113 | 114 | delete 115 | 117 | 119 | 121 | 123 | 124 | 125 | clock 126 | 128 | 130 | 131 | 132 | 133 |
134 |
135 |
136 |

我的购物车

137 |
138 |
139 |
140 |
141 |
    142 |
  • 商品
  • 143 |
  • 单价
  • 144 |
  • 数量
  • 145 |
  • 小计
  • 146 |
  • 操作
  • 147 |
148 |
149 |
    150 |
  • 151 |
    152 | 159 |
    160 | 161 |
    162 |
    163 |
    小米电视4 55英寸
    164 |
    165 |
    166 |
    167 |
    3999
    168 |
    169 |
    170 |
    171 |
    172 |
    173 | - 174 | 10 175 | + 176 |
    177 |
    178 |
    179 |
    180 |
    181 |
    39990
    182 |
    183 |
    184 | 191 |
    192 |
  • 193 |
194 |
195 |
196 |
197 |
198 | 208 |
209 |
210 | 总价: 39990 211 |
212 |
213 | 去结算 214 |
215 |
216 |
217 |
218 |
219 |
220 | 240 | 241 | 242 | -------------------------------------------------------------------------------- /server/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "0.0.0", 4 | "lockfileVersion": 1, 5 | "dependencies": { 6 | "accepts": { 7 | "version": "1.3.4", 8 | "resolved": "http://registry.npm.taobao.org/accepts/download/accepts-1.3.4.tgz", 9 | "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=" 10 | }, 11 | "array-flatten": { 12 | "version": "1.1.1", 13 | "resolved": "http://registry.npm.taobao.org/array-flatten/download/array-flatten-1.1.1.tgz", 14 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 15 | }, 16 | "async": { 17 | "version": "2.1.4", 18 | "resolved": "http://registry.npm.taobao.org/async/download/async-2.1.4.tgz", 19 | "integrity": "sha1-LSFgx3iAMuTdbL4lAvH5osj2zeQ=" 20 | }, 21 | "basic-auth": { 22 | "version": "2.0.0", 23 | "resolved": "http://registry.npm.taobao.org/basic-auth/download/basic-auth-2.0.0.tgz", 24 | "integrity": "sha1-AV2z81PgLlY3d1X5YnQuiYHnu7o=" 25 | }, 26 | "bluebird": { 27 | "version": "3.5.1", 28 | "resolved": "http://registry.npm.taobao.org/bluebird/download/bluebird-3.5.1.tgz", 29 | "integrity": "sha1-2VUfnemPH82h5oPRfukaBgLuLrk=" 30 | }, 31 | "body-parser": { 32 | "version": "1.18.2", 33 | "resolved": "http://registry.npm.taobao.org/body-parser/download/body-parser-1.18.2.tgz", 34 | "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=" 35 | }, 36 | "bson": { 37 | "version": "1.0.4", 38 | "resolved": "http://registry.npm.taobao.org/bson/download/bson-1.0.4.tgz", 39 | "integrity": "sha1-k8ENOeqltYQVy8QFLz5T5WKwtyw=" 40 | }, 41 | "buffer-shims": { 42 | "version": "1.0.0", 43 | "resolved": "http://registry.npm.taobao.org/buffer-shims/download/buffer-shims-1.0.0.tgz", 44 | "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" 45 | }, 46 | "bytes": { 47 | "version": "3.0.0", 48 | "resolved": "http://registry.npm.taobao.org/bytes/download/bytes-3.0.0.tgz", 49 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" 50 | }, 51 | "content-disposition": { 52 | "version": "0.5.2", 53 | "resolved": "http://registry.npm.taobao.org/content-disposition/download/content-disposition-0.5.2.tgz", 54 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" 55 | }, 56 | "content-type": { 57 | "version": "1.0.4", 58 | "resolved": "http://registry.npm.taobao.org/content-type/download/content-type-1.0.4.tgz", 59 | "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=" 60 | }, 61 | "cookie": { 62 | "version": "0.3.1", 63 | "resolved": "http://registry.npm.taobao.org/cookie/download/cookie-0.3.1.tgz", 64 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" 65 | }, 66 | "cookie-parser": { 67 | "version": "1.4.3", 68 | "resolved": "http://registry.npm.taobao.org/cookie-parser/download/cookie-parser-1.4.3.tgz", 69 | "integrity": "sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU=" 70 | }, 71 | "cookie-signature": { 72 | "version": "1.0.6", 73 | "resolved": "http://registry.npm.taobao.org/cookie-signature/download/cookie-signature-1.0.6.tgz", 74 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 75 | }, 76 | "core-util-is": { 77 | "version": "1.0.2", 78 | "resolved": "http://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz", 79 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 80 | }, 81 | "debug": { 82 | "version": "2.6.9", 83 | "resolved": "http://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz", 84 | "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=" 85 | }, 86 | "depd": { 87 | "version": "1.1.1", 88 | "resolved": "http://registry.npm.taobao.org/depd/download/depd-1.1.1.tgz", 89 | "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" 90 | }, 91 | "destroy": { 92 | "version": "1.0.4", 93 | "resolved": "http://registry.npm.taobao.org/destroy/download/destroy-1.0.4.tgz", 94 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 95 | }, 96 | "ee-first": { 97 | "version": "1.1.1", 98 | "resolved": "http://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz", 99 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 100 | }, 101 | "ejs": { 102 | "version": "2.5.7", 103 | "resolved": "http://registry.npm.taobao.org/ejs/download/ejs-2.5.7.tgz", 104 | "integrity": "sha1-zIcsFoiArjxxiXYv1f/ACJbJUYo=" 105 | }, 106 | "encodeurl": { 107 | "version": "1.0.1", 108 | "resolved": "http://registry.npm.taobao.org/encodeurl/download/encodeurl-1.0.1.tgz", 109 | "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=" 110 | }, 111 | "es6-promise": { 112 | "version": "3.2.1", 113 | "resolved": "http://registry.npm.taobao.org/es6-promise/download/es6-promise-3.2.1.tgz", 114 | "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" 115 | }, 116 | "escape-html": { 117 | "version": "1.0.3", 118 | "resolved": "http://registry.npm.taobao.org/escape-html/download/escape-html-1.0.3.tgz", 119 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 120 | }, 121 | "etag": { 122 | "version": "1.8.1", 123 | "resolved": "http://registry.npm.taobao.org/etag/download/etag-1.8.1.tgz", 124 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 125 | }, 126 | "express": { 127 | "version": "4.15.5", 128 | "resolved": "http://registry.npm.taobao.org/express/download/express-4.15.5.tgz", 129 | "integrity": "sha1-ZwI1ypWYiQpa6BcLg9tyK4Qu2Sc=", 130 | "dependencies": { 131 | "qs": { 132 | "version": "6.5.0", 133 | "resolved": "http://registry.npm.taobao.org/qs/download/qs-6.5.0.tgz", 134 | "integrity": "sha1-jQSVTTZN7z78VbWgeT4eLIsebkk=" 135 | }, 136 | "statuses": { 137 | "version": "1.3.1", 138 | "resolved": "http://registry.npm.taobao.org/statuses/download/statuses-1.3.1.tgz", 139 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" 140 | } 141 | } 142 | }, 143 | "finalhandler": { 144 | "version": "1.0.6", 145 | "resolved": "http://registry.npm.taobao.org/finalhandler/download/finalhandler-1.0.6.tgz", 146 | "integrity": "sha1-AHrqM9Gk0+QgF/YkhIrVjSEvgU8=", 147 | "dependencies": { 148 | "statuses": { 149 | "version": "1.3.1", 150 | "resolved": "http://registry.npm.taobao.org/statuses/download/statuses-1.3.1.tgz", 151 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" 152 | } 153 | } 154 | }, 155 | "forwarded": { 156 | "version": "0.1.2", 157 | "resolved": "http://registry.npm.taobao.org/forwarded/download/forwarded-0.1.2.tgz", 158 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 159 | }, 160 | "fresh": { 161 | "version": "0.5.2", 162 | "resolved": "http://registry.npm.taobao.org/fresh/download/fresh-0.5.2.tgz", 163 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 164 | }, 165 | "hooks-fixed": { 166 | "version": "2.0.2", 167 | "resolved": "http://registry.npm.taobao.org/hooks-fixed/download/hooks-fixed-2.0.2.tgz", 168 | "integrity": "sha1-IAdtqgfnfYphBog84/FyLgURQLA=" 169 | }, 170 | "http-errors": { 171 | "version": "1.6.2", 172 | "resolved": "http://registry.npm.taobao.org/http-errors/download/http-errors-1.6.2.tgz", 173 | "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=" 174 | }, 175 | "iconv-lite": { 176 | "version": "0.4.19", 177 | "resolved": "http://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.19.tgz", 178 | "integrity": "sha1-90aPYBNfXl2tM5nAqBvpoWA6CCs=" 179 | }, 180 | "inherits": { 181 | "version": "2.0.3", 182 | "resolved": "http://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz", 183 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 184 | }, 185 | "ipaddr.js": { 186 | "version": "1.4.0", 187 | "resolved": "http://registry.npm.taobao.org/ipaddr.js/download/ipaddr.js-1.4.0.tgz", 188 | "integrity": "sha1-KWrKh4qCGBbluF0KKFqZvP9FgvA=" 189 | }, 190 | "isarray": { 191 | "version": "1.0.0", 192 | "resolved": "http://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz", 193 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 194 | }, 195 | "kareem": { 196 | "version": "1.5.0", 197 | "resolved": "http://registry.npm.taobao.org/kareem/download/kareem-1.5.0.tgz", 198 | "integrity": "sha1-4+QQHZ3P3imXadr0tNtk2JXRdEg=" 199 | }, 200 | "lodash": { 201 | "version": "4.17.4", 202 | "resolved": "http://registry.npm.taobao.org/lodash/download/lodash-4.17.4.tgz", 203 | "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" 204 | }, 205 | "lodash.get": { 206 | "version": "4.4.2", 207 | "resolved": "http://registry.npm.taobao.org/lodash.get/download/lodash.get-4.4.2.tgz", 208 | "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" 209 | }, 210 | "media-typer": { 211 | "version": "0.3.0", 212 | "resolved": "http://registry.npm.taobao.org/media-typer/download/media-typer-0.3.0.tgz", 213 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 214 | }, 215 | "merge-descriptors": { 216 | "version": "1.0.1", 217 | "resolved": "http://registry.npm.taobao.org/merge-descriptors/download/merge-descriptors-1.0.1.tgz", 218 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 219 | }, 220 | "methods": { 221 | "version": "1.1.2", 222 | "resolved": "http://registry.npm.taobao.org/methods/download/methods-1.1.2.tgz", 223 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 224 | }, 225 | "mime": { 226 | "version": "1.3.4", 227 | "resolved": "http://registry.npm.taobao.org/mime/download/mime-1.3.4.tgz", 228 | "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=" 229 | }, 230 | "mime-db": { 231 | "version": "1.30.0", 232 | "resolved": "http://registry.npm.taobao.org/mime-db/download/mime-db-1.30.0.tgz", 233 | "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" 234 | }, 235 | "mime-types": { 236 | "version": "2.1.17", 237 | "resolved": "http://registry.npm.taobao.org/mime-types/download/mime-types-2.1.17.tgz", 238 | "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=" 239 | }, 240 | "mongodb": { 241 | "version": "2.2.33", 242 | "resolved": "http://registry.npm.taobao.org/mongodb/download/mongodb-2.2.33.tgz", 243 | "integrity": "sha1-tTfEcdNKZlG0jzb9vyl1A0Dgi1A=" 244 | }, 245 | "mongodb-core": { 246 | "version": "2.1.17", 247 | "resolved": "http://registry.npm.taobao.org/mongodb-core/download/mongodb-core-2.1.17.tgz", 248 | "integrity": "sha1-pBizN6FKFJkPtRC5I97mqBMXPfg=" 249 | }, 250 | "mongoose": { 251 | "version": "4.13.0", 252 | "resolved": "http://registry.npm.taobao.org/mongoose/download/mongoose-4.13.0.tgz", 253 | "integrity": "sha1-gbsmbgRdZqyN/dhPxnSchz16asQ=" 254 | }, 255 | "morgan": { 256 | "version": "1.9.0", 257 | "resolved": "http://registry.npm.taobao.org/morgan/download/morgan-1.9.0.tgz", 258 | "integrity": "sha1-0B+mxlhZt2/PMbPLU6OCGjEdgFE=" 259 | }, 260 | "mpath": { 261 | "version": "0.3.0", 262 | "resolved": "http://registry.npm.taobao.org/mpath/download/mpath-0.3.0.tgz", 263 | "integrity": "sha1-elj3iem1/TyUUgY0FXlg8mvV70Q=" 264 | }, 265 | "mpromise": { 266 | "version": "0.5.5", 267 | "resolved": "http://registry.npm.taobao.org/mpromise/download/mpromise-0.5.5.tgz", 268 | "integrity": "sha1-9bJCWddjrMIlewoMjG2Gb9UXMuY=" 269 | }, 270 | "mquery": { 271 | "version": "2.3.2", 272 | "resolved": "http://registry.npm.taobao.org/mquery/download/mquery-2.3.2.tgz", 273 | "integrity": "sha1-4sYK0RfPCA8u+x7N0UTnu/+/yhE=", 274 | "dependencies": { 275 | "sliced": { 276 | "version": "0.0.5", 277 | "resolved": "http://registry.npm.taobao.org/sliced/download/sliced-0.0.5.tgz", 278 | "integrity": "sha1-XtwETKTrb3gW1Qui/GPiXY/kcH8=" 279 | } 280 | } 281 | }, 282 | "ms": { 283 | "version": "2.0.0", 284 | "resolved": "http://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz", 285 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 286 | }, 287 | "muri": { 288 | "version": "1.3.0", 289 | "resolved": "http://registry.npm.taobao.org/muri/download/muri-1.3.0.tgz", 290 | "integrity": "sha1-rszz22TFaqfFs04A+Vt4eFJ6RyE=" 291 | }, 292 | "negotiator": { 293 | "version": "0.6.1", 294 | "resolved": "http://registry.npm.taobao.org/negotiator/download/negotiator-0.6.1.tgz", 295 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" 296 | }, 297 | "on-finished": { 298 | "version": "2.3.0", 299 | "resolved": "http://registry.npm.taobao.org/on-finished/download/on-finished-2.3.0.tgz", 300 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=" 301 | }, 302 | "on-headers": { 303 | "version": "1.0.1", 304 | "resolved": "http://registry.npm.taobao.org/on-headers/download/on-headers-1.0.1.tgz", 305 | "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=" 306 | }, 307 | "parseurl": { 308 | "version": "1.3.2", 309 | "resolved": "http://registry.npm.taobao.org/parseurl/download/parseurl-1.3.2.tgz", 310 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" 311 | }, 312 | "path-to-regexp": { 313 | "version": "0.1.7", 314 | "resolved": "http://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-0.1.7.tgz", 315 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 316 | }, 317 | "process-nextick-args": { 318 | "version": "1.0.7", 319 | "resolved": "http://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-1.0.7.tgz", 320 | "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" 321 | }, 322 | "proxy-addr": { 323 | "version": "1.1.5", 324 | "resolved": "http://registry.npm.taobao.org/proxy-addr/download/proxy-addr-1.1.5.tgz", 325 | "integrity": "sha1-ccDuOxAt4/IC87ZPYI0XP8uhqRg=" 326 | }, 327 | "qs": { 328 | "version": "6.5.1", 329 | "resolved": "http://registry.npm.taobao.org/qs/download/qs-6.5.1.tgz", 330 | "integrity": "sha1-NJzfbu+J7EXBLX1es/wMhwNDptg=" 331 | }, 332 | "range-parser": { 333 | "version": "1.2.0", 334 | "resolved": "http://registry.npm.taobao.org/range-parser/download/range-parser-1.2.0.tgz", 335 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" 336 | }, 337 | "raw-body": { 338 | "version": "2.3.2", 339 | "resolved": "http://registry.npm.taobao.org/raw-body/download/raw-body-2.3.2.tgz", 340 | "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=" 341 | }, 342 | "readable-stream": { 343 | "version": "2.2.7", 344 | "resolved": "http://registry.npm.taobao.org/readable-stream/download/readable-stream-2.2.7.tgz", 345 | "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=" 346 | }, 347 | "regexp-clone": { 348 | "version": "0.0.1", 349 | "resolved": "http://registry.npm.taobao.org/regexp-clone/download/regexp-clone-0.0.1.tgz", 350 | "integrity": "sha1-p8LgmJH9vzj7sQ03b7cwA+aKxYk=" 351 | }, 352 | "require_optional": { 353 | "version": "1.0.1", 354 | "resolved": "http://registry.npm.taobao.org/require_optional/download/require_optional-1.0.1.tgz", 355 | "integrity": "sha1-TPNaQkf2TKPfjC7yCMxJSxyo/C4=" 356 | }, 357 | "resolve-from": { 358 | "version": "2.0.0", 359 | "resolved": "http://registry.npm.taobao.org/resolve-from/download/resolve-from-2.0.0.tgz", 360 | "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" 361 | }, 362 | "safe-buffer": { 363 | "version": "5.1.1", 364 | "resolved": "http://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.1.tgz", 365 | "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=" 366 | }, 367 | "semver": { 368 | "version": "5.4.1", 369 | "resolved": "http://registry.npm.taobao.org/semver/download/semver-5.4.1.tgz", 370 | "integrity": "sha1-4FnAnYVx8FQII3M0M1BdOi8AsY4=" 371 | }, 372 | "send": { 373 | "version": "0.15.6", 374 | "resolved": "http://registry.npm.taobao.org/send/download/send-0.15.6.tgz", 375 | "integrity": "sha1-IPI6nJJbdiq4JwX+L52yUqzkfjQ=", 376 | "dependencies": { 377 | "statuses": { 378 | "version": "1.3.1", 379 | "resolved": "http://registry.npm.taobao.org/statuses/download/statuses-1.3.1.tgz", 380 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" 381 | } 382 | } 383 | }, 384 | "serve-favicon": { 385 | "version": "2.4.5", 386 | "resolved": "http://registry.npm.taobao.org/serve-favicon/download/serve-favicon-2.4.5.tgz", 387 | "integrity": "sha1-SdmkaGMVOpJAaRyJPSsOfYXW1DY=" 388 | }, 389 | "serve-static": { 390 | "version": "1.12.6", 391 | "resolved": "http://registry.npm.taobao.org/serve-static/download/serve-static-1.12.6.tgz", 392 | "integrity": "sha1-uXN3P2NEmTTaVOW+ul4x2fQhFXc=" 393 | }, 394 | "setprototypeof": { 395 | "version": "1.0.3", 396 | "resolved": "http://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.0.3.tgz", 397 | "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" 398 | }, 399 | "sliced": { 400 | "version": "1.0.1", 401 | "resolved": "http://registry.npm.taobao.org/sliced/download/sliced-1.0.1.tgz", 402 | "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" 403 | }, 404 | "statuses": { 405 | "version": "1.4.0", 406 | "resolved": "http://registry.npm.taobao.org/statuses/download/statuses-1.4.0.tgz", 407 | "integrity": "sha1-u3PURtonlhBu/MG2AaJT1sRr0Ic=" 408 | }, 409 | "string_decoder": { 410 | "version": "1.0.3", 411 | "resolved": "http://registry.npm.taobao.org/string_decoder/download/string_decoder-1.0.3.tgz", 412 | "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=" 413 | }, 414 | "type-is": { 415 | "version": "1.6.15", 416 | "resolved": "http://registry.npm.taobao.org/type-is/download/type-is-1.6.15.tgz", 417 | "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=" 418 | }, 419 | "unpipe": { 420 | "version": "1.0.0", 421 | "resolved": "http://registry.npm.taobao.org/unpipe/download/unpipe-1.0.0.tgz", 422 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 423 | }, 424 | "util-deprecate": { 425 | "version": "1.0.2", 426 | "resolved": "http://registry.npm.taobao.org/util-deprecate/download/util-deprecate-1.0.2.tgz", 427 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 428 | }, 429 | "utils-merge": { 430 | "version": "1.0.0", 431 | "resolved": "http://registry.npm.taobao.org/utils-merge/download/utils-merge-1.0.0.tgz", 432 | "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" 433 | }, 434 | "vary": { 435 | "version": "1.1.2", 436 | "resolved": "http://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz", 437 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 438 | } 439 | } 440 | } 441 | --------------------------------------------------------------------------------