├── LICENSE ├── README.md ├── app.js ├── controllers ├── cart-contrl.js ├── collection-contrl.js ├── index-contrl.js ├── order-contrl.js ├── prod-contrl.js └── signin-contrl.js ├── html_template ├── 404.html ├── 500.html ├── address.html ├── cart.html ├── collection.html ├── images │ ├── BuynBtn.png │ ├── bear.jpg │ ├── cart.png │ ├── cart_on.png │ ├── center-icon-dlmm.png │ ├── center-icon-dz.png │ ├── center-icon-order-all.png │ ├── center-icon-order-dfh.png │ ├── center-icon-order-dfk.png │ ├── center-icon-order-dpj.png │ ├── center-icon-order-dsh.png │ ├── center-icon-out.png │ ├── center-icon-sc.png │ ├── footer03.png │ ├── good1.jpg │ ├── good2.jpg │ ├── good3.jpg │ ├── good4.jpg │ ├── good5.jpg │ ├── good6.jpg │ ├── goods.png │ ├── goods_on.png │ ├── head_index.png │ ├── icon-back.png │ ├── icon-collection.png │ ├── icon-dele.png │ ├── icon-edit.png │ ├── icon-kefu.png │ ├── icon_nav_city.png │ ├── index.png │ ├── index_on.png │ ├── location-border.png │ ├── menu1.png │ ├── menu2.png │ ├── menu3.png │ ├── menu4.png │ ├── mid.png │ ├── my.png │ ├── my_on.png │ ├── prod_content1.jpg │ ├── prod_content10.png │ ├── prod_content11.png │ ├── prod_content12.png │ ├── prod_content13.jpg │ ├── prod_content2.jpg │ ├── prod_content3.png │ ├── prod_content4.png │ ├── prod_content5.png │ ├── prod_content6.png │ ├── prod_content7.png │ ├── prod_content8.png │ ├── prod_content9.png │ ├── prod_detail0.jpg │ ├── prod_detail1.jpg │ ├── prod_detail2.jpg │ ├── prod_detail3.jpg │ ├── s1.png │ ├── s2.png │ ├── s3.png │ ├── tophovertree.gif │ ├── vcode.jpg │ └── xuanze.png ├── index.html ├── js │ ├── app │ │ ├── address.js │ │ ├── cart.js │ │ ├── collection.js │ │ ├── index.js │ │ ├── index_main.js │ │ ├── login.js │ │ ├── order-detail.js │ │ ├── prod-detail.js │ │ ├── register.js │ │ ├── settlement.js │ │ └── user.js │ └── lib │ │ ├── city.js │ │ ├── jquery.Spinner.js │ │ ├── jquery.js │ │ ├── require.js │ │ ├── swipe.js │ │ ├── swiper-4.1.6.min.js │ │ ├── vue.js │ │ ├── vue.min.js │ │ ├── weui.min.js │ │ └── zepto.min.js ├── login.html ├── msg.html ├── order-detail.html ├── order-list.html ├── prod-detail.html ├── register.html ├── reset-pass.html ├── screenshot │ ├── 1.jpg │ ├── 2.jpg │ ├── 3.jpg │ ├── 4.jpg │ ├── 5.jpg │ ├── 6.jpg │ ├── 7.png │ ├── 8.jpg │ └── 9.jpg ├── settlement.html ├── style │ ├── style.css │ ├── swipe.css │ ├── swiper-4.1.6.min.css │ └── weui.min.css ├── upt-pass.html └── user.html ├── init-db.js ├── init-sql.sql ├── middleware ├── config-default.js ├── config-test.js ├── config.js ├── controller.js ├── db.js ├── model.js ├── my-log4js.js ├── rest.js ├── static-files.js └── templating.js ├── models ├── advert.js ├── cart.js ├── collection.js ├── group_attri.js ├── group_attri_value.js ├── order.js ├── order_prod.js ├── prod_attri.js ├── product.js ├── user.js └── user_address.js ├── package.json ├── service ├── ad-service.js ├── cart-service.js ├── collection-service.js ├── order-service.js ├── product-service.js └── user-service.js ├── static ├── css │ ├── style.css │ ├── swipe.css │ ├── swiper-4.1.6.min.css │ └── weui.min.css ├── html │ ├── 404.html │ ├── 500.html │ └── prod_detail │ │ └── prod-detial0.html ├── images │ ├── BuynBtn.png │ ├── cart.png │ ├── cart_bak.png │ ├── cart_on.png │ ├── cart_on_bak.png │ ├── center-icon-dlmm.png │ ├── center-icon-dz.png │ ├── center-icon-order-all.png │ ├── center-icon-order-dfh.png │ ├── center-icon-order-dfk.png │ ├── center-icon-order-dpj.png │ ├── center-icon-order-dsh.png │ ├── center-icon-out.png │ ├── center-icon-sc.png │ ├── favicon.ico │ ├── footer03.png │ ├── goods.png │ ├── goods_bak.png │ ├── goods_on.png │ ├── goods_on_bak.png │ ├── head │ │ └── bear.jpg │ ├── icon-back.png │ ├── icon-collection-on.png │ ├── icon-collection.png │ ├── icon-dele.png │ ├── icon-kefu.png │ ├── icon_nav_city.png │ ├── index.png │ ├── index_bak.png │ ├── index_on.png │ ├── index_on_bak.png │ ├── location-border.png │ ├── menu1.png │ ├── menu2.png │ ├── menu3.png │ ├── menu4.png │ ├── my.png │ ├── my_bak.png │ ├── my_on.png │ ├── my_on_bak.png │ ├── product │ │ ├── content │ │ │ ├── prod_content1.jpg │ │ │ ├── prod_content10.png │ │ │ ├── prod_content11.png │ │ │ ├── prod_content12.png │ │ │ ├── prod_content13.jpg │ │ │ ├── prod_content2.jpg │ │ │ ├── prod_content3.png │ │ │ ├── prod_content4.png │ │ │ ├── prod_content5.png │ │ │ ├── prod_content6.png │ │ │ ├── prod_content7.png │ │ │ ├── prod_content8.png │ │ │ └── prod_content9.png │ │ ├── detail │ │ │ ├── prod_detail0.jpg │ │ │ ├── prod_detail1.jpg │ │ │ ├── prod_detail2.jpg │ │ │ └── prod_detail3.jpg │ │ ├── good1.jpg │ │ ├── good2.jpg │ │ ├── good3.jpg │ │ ├── good4.jpg │ │ ├── good5.jpg │ │ └── good6.jpg │ ├── tophovertree.gif │ ├── vcode.jpg │ ├── vt │ │ ├── mid.png │ │ ├── s1.png │ │ ├── s2.png │ │ └── s3.png │ └── xuanze.png └── js │ ├── app │ ├── cart.js │ ├── collection.js │ ├── index-main.js │ ├── index.js │ ├── login.js │ ├── order-detail.js │ ├── order-list.js │ ├── pay-success.js │ ├── prod-detail.js │ ├── public-tip.js │ ├── public.js │ ├── register.js │ ├── settlement.js │ ├── upt-pass.js │ └── user.js │ └── lib │ ├── jquery.Spinner.js │ ├── jquery.js │ ├── require.js │ ├── swipe.js │ ├── swiper-4.1.6.min.js │ ├── vue-resource.js │ ├── vue-resource.min.js │ ├── vue.js │ ├── vue.min.js │ ├── weui.min.js │ └── zepto.min.js ├── utils └── common.js └── views ├── cart.html ├── collection.html ├── index.html ├── login.html ├── msg.html ├── order-detail.html ├── order-list.html ├── pay-success.html ├── prod-detail.html ├── public-tip.html ├── register.html ├── reset-pass.html ├── settlement.html ├── upt-pass.html └── user.html /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 halloffamezwx 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | zshop是一个nodejs写的商城系统,看完廖雪峰的[《javaScript全栈教程》](https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000)后,想练练手,已是开始踩坑之路。目前完成了首页,商品搜索,购物车,我的,登录,商品详情,结算等,后面将继续完善其它功能。完善后会把数据库的er图画出来。 2 | 3 | 在线预览效果地址:(pc浏览器请切换为手机模式)。部署在阿里云上面,`centOS 6.5 64位`,`1核cpu`,`1g内存`,`1m带宽`,`40g普通硬盘`,登录手机:18312345678,密码:123456。 4 | 5 | 一 部署方式:
6 | 7 | 1 安装`node.js`(7.6版本以上,因为要支持`async/await`);
8 | 2 安装`mysql`数据库(utf-8编码的配置),创建数据库`zshop`;
9 | 3 下载本工程文件,可修改数据库的用户名密码等连接配置(middleware目录下的`config-default.js`和`config-test.js`两个配置文件),在根目录下执行`npm install`下载依赖库,然后执行`node init-db.js`(初始化数据库表和表数据);
10 | 4 最后在工程根目录下执行`node app.js`,看到日志`app started at port 3000...`就代表启动成功了,浏览器访问(pc浏览器请切换为手机模式)。 11 | 12 | 二 涉及的技术框架:
13 | 14 | 1 前端:`weui.css`,`jquery`,`jquery.spinner`,`requirejs`,`swiper-4.1.6`,`vue`,`vue-resource`;
15 | 2 后端:`koa2`,`koa-bodyparser`,`koa-router`,`nunjucks`,`mime`,`mz`,`koa-compress`,`sequelize`,`mysql`,`koa-session2`,`log4js`,`moment`。 16 | 17 | 三 工程目录的主要结构:
18 | |-zshop
19 |    |-controllers         //controller
20 |    |-html_template   //如果你只需要本项目的那些静态的html文件等
21 |    |-middleware       //本项目的koa2的一些middleware
22 |    |-models              //数据库实体
23 |    |-service               //service
24 |    |-static                 //静态文件目录,包括图片,js,css等,这部分可以部署在nginx
25 |    |-utils                   //工具函数目录
26 |    |-views                 //模板页面文件
27 |    |-app.js                //程序主入口文件
28 |    |-init-db.js           //执行这个可以初始化数据库表和表数据,谨慎执行
29 |    |-init-sql.sql         //init-db.js执行的sql文件
30 |    |-LICENSE            //MIT协议,拿走不谢
31 |    |-package.json    //依赖的库 32 | 33 | 四 一些截图:
34 | 35 | ![image](https://github.com/halloffamezwx/zshop/raw/master/html_template/screenshot/1.jpg) 36 | ![image](https://github.com/halloffamezwx/zshop/raw/master/html_template/screenshot/2.jpg) 37 | ![image](https://github.com/halloffamezwx/zshop/raw/master/html_template/screenshot/3.jpg) 38 | ![image](https://github.com/halloffamezwx/zshop/raw/master/html_template/screenshot/4.jpg) 39 | ![image](https://github.com/halloffamezwx/zshop/raw/master/html_template/screenshot/5.jpg) 40 | ![image](https://github.com/halloffamezwx/zshop/raw/master/html_template/screenshot/6.jpg) 41 | ![image](https://github.com/halloffamezwx/zshop/raw/master/html_template/screenshot/8.jpg) 42 | ![image](https://github.com/halloffamezwx/zshop/raw/master/html_template/screenshot/9.jpg) 43 | 44 | 五 如果你觉得对你有所启发,star一下或者扫码请我喝杯咖啡,金额任意。
45 | 46 | ![image](https://github.com/halloffamezwx/zshop/raw/master/html_template/screenshot/7.png) 47 | 48 | 六 我的博客:。 -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | const myLog4js = require("./middleware/my-log4js"); 2 | const uuid = require('node-uuid'); 3 | const sysLogger = myLog4js.getLogger('system'); 4 | sysLogger.addContext('logid', uuid.v4().replace(/-/g,"")); 5 | console.log = sysLogger.info.bind(sysLogger); 6 | 7 | const Koa = require('koa'); 8 | const bodyParser = require('koa-bodyparser'); 9 | const koaBody = require('koa-body'); 10 | const controller = require('./middleware/controller'); 11 | const templating = require('./middleware/templating'); 12 | const compress = require('koa-compress'); 13 | const rest = require('./middleware/rest'); 14 | const app = new Koa(); 15 | const session = require("koa-session2"); 16 | 17 | console.log(`process.env.NODE_ENV = [${process.env.NODE_ENV}]`); 18 | const isProduction = process.env.NODE_ENV === 'production'; 19 | console.log(`isProduction = [${isProduction}]`); 20 | 21 | // log request URL: 22 | app.use(async (ctx, next) => { 23 | var logger = myLog4js.getLogger('zshop'); 24 | var logid = uuid.v4().replace(/-/g, ""); 25 | logger.addContext('logid', logid); 26 | console.log = logger.info.bind(logger); 27 | ctx.logger = logger; 28 | 29 | logger.info(`Process ${ctx.request.method} ${ctx.request.url}...`); 30 | var 31 | start = new Date().getTime(), 32 | execTime; 33 | 34 | await next(); 35 | 36 | console.log("ctx.response.status=" + ctx.response.status); 37 | if (ctx.response.status == 404) { 38 | ctx.response.redirect('/static/html/404.html'); 39 | } 40 | 41 | ctx.response.set('logid', logid); 42 | execTime = new Date().getTime() - start; 43 | ctx.response.set('X-Response-Time', `${execTime}ms`); 44 | }); 45 | 46 | app.use(compress({ 47 | //filter: function (content_type) { 48 | // return /text/i.test(content_type) 49 | //}, 50 | threshold: 2048, 51 | flush: require('zlib').Z_SYNC_FLUSH 52 | })); 53 | 54 | app.use(session({ 55 | key: "SESSIONID", //default "koa:sess" 56 | maxAge: 30 * 60 * 1000 57 | })); 58 | 59 | // static file support: 60 | //if (! isProduction) { 61 | let staticFiles = require('./middleware/static-files'); 62 | app.use(staticFiles('/static/', __dirname + '/static')); 63 | //} 64 | 65 | app.use(koaBody({ 66 | multipart: true, 67 | formidable: { 68 | maxFileSize: 200 * 1024 * 1024 //设置上传文件大小最大限制,默认2M 69 | } 70 | })); 71 | // parse request body: 72 | app.use(bodyParser()); 73 | 74 | // add nunjucks as view: 75 | app.use(templating('views', { 76 | noCache: !isProduction, 77 | watch: !isProduction 78 | })); 79 | 80 | // bind .rest() for ctx: 81 | app.use(rest.restify()); 82 | 83 | // add controller: 84 | app.use(controller()); 85 | 86 | app.listen(3000); 87 | console.log('app started at port 3000...'); 88 | -------------------------------------------------------------------------------- /controllers/cart-contrl.js: -------------------------------------------------------------------------------- 1 | //购物车ctrl 2 | const cartService = require('../service/cart-service'); 3 | const APIError = require('../middleware/rest').APIError; 4 | 5 | module.exports = { 6 | 'GET /user/cart': async (ctx, next) => { 7 | var userCartProds = await cartService.getUserCartProd(ctx.session.user); 8 | 9 | ctx.render('cart.html', userCartProds); 10 | }, 11 | 12 | 'POST /userapi/delCartProd': async (ctx, next) => { 13 | //console.log(JSON.stringify(ctx.request.body)); 14 | var cid = ctx.request.body.cid || ''; 15 | await cartService.deleteCardProd(cid); 16 | //ctx.rest(); 17 | ctx.rest({code: 'system:success', message: '成功'}); 18 | }, 19 | 20 | 'POST /userapi/chgCartProdCount': async (ctx, next) => { 21 | var cid = ctx.request.body.cid || ''; 22 | var newValue = ctx.request.body.newValue || ''; 23 | await cartService.updateCardProdCount(cid, newValue); 24 | ctx.rest(); 25 | }, 26 | 27 | 'POST /userapi/addCartProd': async (ctx, next) => { 28 | var pid = ctx.request.body.pid || ''; 29 | var pcount = ctx.request.body.pcount || '1'; 30 | if (!pid || pid.trim() == '') { 31 | throw new APIError('cart:empty_pid', '商品ID不能为空'); 32 | } 33 | let cartSize = await cartService.addCartProd(pid, pcount, ctx.session.user.userId); 34 | ctx.rest({cartSize: cartSize}); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /controllers/collection-contrl.js: -------------------------------------------------------------------------------- 1 | //收藏ctrl 2 | const collectionService = require('../service/collection-service'); 3 | const APIError = require('../middleware/rest').APIError; 4 | 5 | module.exports = { 6 | 'GET /user/collection/index': async (ctx, next) => { 7 | var collections = await collectionService.getCollection(ctx.session.user.userId); 8 | ctx.render('collection.html', {collections: collections}); 9 | }, 10 | 11 | 'POST /userapi/collection/act': async (ctx, next) => { 12 | var id = ctx.request.body.id || ''; 13 | var pid = ctx.request.body.pid || ''; 14 | var userId = ctx.session.user.userId; 15 | var id = await collectionService.collection(id, userId, pid); 16 | ctx.rest({id: id}); 17 | }, 18 | 19 | 'GET /user/collection/del/:id': async (ctx, next) => { 20 | var id = ctx.params.id || ''; 21 | if (!id || id.trim() == '') { 22 | throw new APIError('collection:empty_id', 'id不能为空'); 23 | } 24 | await collectionService.collection(id); 25 | ctx.response.redirect('/zshop/user/collection/index'); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /controllers/prod-contrl.js: -------------------------------------------------------------------------------- 1 | //产品ctrl 2 | const productService = require('../service/product-service'); 3 | const cartService = require('../service/cart-service'); 4 | const collectionService = require('../service/collection-service'); 5 | 6 | module.exports = { 7 | //商品详情 8 | 'GET /prodDetail/:pid': async (ctx, next) => { 9 | var product = await productService.prodDetail(ctx.params.pid); 10 | var cardProdNum = 0; 11 | var collection; 12 | if (ctx.session.user) { 13 | cardProdNum = await cartService.getCardProdNum(ctx.session.user.userId); 14 | collection = await collectionService.getOneCollection(ctx.session.user.userId, product.id); 15 | } 16 | 17 | ctx.render('prod-detail.html', {product: product, cardProdNum: cardProdNum, collection: collection}); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /controllers/signin-contrl.js: -------------------------------------------------------------------------------- 1 | //登录ctrl 2 | const userService = require('../service/user-service'); 3 | const orderService = require('../service/order-service'); 4 | const APIError = require('../middleware/rest').APIError; 5 | const indexContrl = require('../controllers/index-contrl'); 6 | let captchapng = null; 7 | const fs = require('fs'); 8 | const openCaptcha = process.env.OPEN_CAPTCHA === 'true'; 9 | console.log(`openCaptcha = [${openCaptcha}]`); 10 | if (openCaptcha) { 11 | captchapng = require('captchapng'); 12 | } 13 | 14 | module.exports = { 15 | 'POST /api/signin': async (ctx, next) => { 16 | //console.log(JSON.stringify(ctx.request.body)); 17 | let 18 | mobile = ctx.request.body.mobile || '', 19 | password = ctx.request.body.password || '', 20 | captcha = ctx.request.body.captcha || '', 21 | sessionCaptcha = ctx.session.sessionCaptcha, 22 | userIn = new Object(); 23 | userIn.mobile = mobile; 24 | userIn.passwd = password; 25 | console.log("sessionCaptcha=" + sessionCaptcha); 26 | 27 | if ( openCaptcha && (!sessionCaptcha || sessionCaptcha != captcha) ) { 28 | throw new APIError('login:error_captcha', '验证码错误'); 29 | } 30 | 31 | ctx.session.sessionCaptcha = null; 32 | var user = await userService.getOneUser(userIn); 33 | if (user) { 34 | var userTemp = new Object(); 35 | userTemp.id = user.id; 36 | userTemp.name = user.name; 37 | userTemp.userId = user.userId; 38 | userTemp.headImage = user.headImage; 39 | ctx.session.user = userTemp; 40 | 41 | ctx.rest({user: userTemp}); 42 | } else { 43 | throw new APIError('login:error_mobile_passwd', '手机号或密码错误'); 44 | } 45 | }, 46 | 47 | 'GET /signout': async (ctx, next) => { 48 | ctx.session.user = null; 49 | //return await indexContrl['GET /'](ctx, next); 50 | ctx.response.redirect('/zshop/'); 51 | }, 52 | 53 | 'GET /login': async (ctx, next) => { 54 | ctx.render('login.html', {loginSuccUrl: ctx.query.loginSuccUrl, openCaptcha: openCaptcha}); 55 | }, 56 | 57 | 'GET /resetPass': async (ctx, next) => { 58 | ctx.render('reset-pass.html', {mobile: ctx.query.mobile}); 59 | }, 60 | 61 | 'GET /registPage': async (ctx, next) => { 62 | ctx.render('register.html'); 63 | }, 64 | 65 | 'POST /api/regist': async (ctx, next) => { 66 | /* let file = ctx.request.body.files.file1; // 获取上传文件 67 | let reader = fs.createReadStream(file.path); // 创建可读流 68 | let ext = file.name.split('.').pop(); // 获取上传文件扩展名 69 | let upStream = fs.createWriteStream(`static/images/head/${Math.random().toString()}.${ext}`); // 创建可写流 70 | reader.pipe(upStream); // 可读流通过管道写入可写流 */ 71 | 72 | let mobile = ctx.request.body.mobile || ''; 73 | let password = ctx.request.body.password || ''; 74 | let passwordConfirm = ctx.request.body.passwordConfirm || ''; 75 | 76 | if (mobile.trim() == '' || password.trim() == '' || passwordConfirm.trim() == '') { 77 | throw new APIError('regist:error_input', '手机号,密码和确认密码必传'); 78 | } 79 | if (password != passwordConfirm) { 80 | throw new APIError('regist:error_input', '密码和确认密码不一致'); 81 | } 82 | 83 | let cuser = await userService.regist(mobile, password); 84 | ctx.session.user = cuser; 85 | ctx.rest({}); 86 | }, 87 | 88 | 'POST /api/countUserMobile': async (ctx, next) => { 89 | let mobile = ctx.request.body.mobile || ''; 90 | if (mobile.trim() == '') { 91 | throw new APIError('regist:error_input', '手机号必传'); 92 | } 93 | let countInt = await userService.countUser({mobile: mobile}); 94 | ctx.rest({countInt: countInt}); 95 | }, 96 | 97 | 'POST /userapi/getLoginUserInfo': async (ctx, next) => { 98 | let orderCount = await orderService.countOrder("1111", ctx.session.user.userId); 99 | let user = await userService.getOneUser({userId: ctx.session.user.userId}); 100 | 101 | var userTemp = new Object(); 102 | userTemp.name = user.name; 103 | userTemp.userId = user.userId; 104 | userTemp.headImage = user.headImage; 105 | 106 | ctx.rest({user: userTemp, orderCount: orderCount}); 107 | }, 108 | 109 | 'POST /api/checkCaptcha': async (ctx, next) => { 110 | let captcha = ctx.request.body.captcha || '', 111 | sessionCaptcha = ctx.session.sessionCaptcha; 112 | console.log("checkCaptcha-sessionCaptcha=" + sessionCaptcha); 113 | 114 | if ( openCaptcha && (!sessionCaptcha || sessionCaptcha != captcha) ) { 115 | throw new APIError('login:error_captcha', '验证码错误'); 116 | } 117 | 118 | ctx.rest({}); 119 | }, 120 | 121 | 'GET /captcha': async (ctx, next) => { 122 | //const captchapng = require('captchapng'); 123 | 124 | var numeric = parseInt(Math.random()*9000+1000); 125 | console.log("captcha=" + numeric); 126 | ctx.session.sessionCaptcha = numeric; 127 | 128 | var p = new captchapng(110,45,numeric); // width,height,numeric captcha 129 | p.color(248, 248, 248, 255); // First color: background (red, green, blue, alpha) 130 | p.color(80, 80, 80, 255); // Second color: paint (red, green, blue, alpha) 131 | 132 | var img = p.getBase64(); 133 | var imgbase64 = new Buffer(img,'base64'); 134 | ctx.response.type = "image/png"; 135 | ctx.response.body = imgbase64; 136 | } 137 | }; 138 | -------------------------------------------------------------------------------- /html_template/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 404 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
商城
15 |
16 |
17 | 18 |
19 |
20 |
21 |

404

22 |

这个页面被我吃掉了,点击返回

23 |
24 |
25 | 31 |
32 |
33 | 34 | 35 | -------------------------------------------------------------------------------- /html_template/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 500 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
商城
15 |
16 |
17 | 18 |
19 |
20 |
21 |

未知错误

22 |

抱歉!系统出现错误了,点击返回

23 |
24 |
25 | 31 |
32 |
33 | 34 | 35 | -------------------------------------------------------------------------------- /html_template/collection.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 我的收藏 7 | 8 | 9 | 10 | 18 | 19 | 20 | 21 |
22 |
23 |
我的收藏
24 |
25 |
26 | 27 |
28 |
29 |
30 |
31 | 32 | 33 | 34 |
35 |

魅蓝 Note6

36 |

疾速双摄 1100万前置美拍

37 |

¥1099

38 |
39 |
40 |
41 | 42 |
43 |
44 |
45 |
46 | 47 | 48 | 49 |
50 |

魅蓝 Note6

51 |

疾速双摄 1100万前置美拍

52 |

¥1099

53 |
54 |
55 |
56 | 57 |
58 |
59 |
60 |
61 | 62 | 63 | 64 |
65 |

魅蓝 Note6

66 |

疾速双摄 1100万前置美拍

67 |

¥1099

68 |
69 |
70 |
71 | 72 |
73 |
74 |
75 |
76 | 77 | 78 | 79 |
80 |

魅蓝 Note6

81 |

疾速双摄 1100万前置美拍

82 |

¥1099

83 |
84 |
85 |
86 | 87 |
88 |
89 |
90 | 91 |
92 | 93 |
94 |
95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /html_template/images/BuynBtn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/BuynBtn.png -------------------------------------------------------------------------------- /html_template/images/bear.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/bear.jpg -------------------------------------------------------------------------------- /html_template/images/cart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/cart.png -------------------------------------------------------------------------------- /html_template/images/cart_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/cart_on.png -------------------------------------------------------------------------------- /html_template/images/center-icon-dlmm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/center-icon-dlmm.png -------------------------------------------------------------------------------- /html_template/images/center-icon-dz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/center-icon-dz.png -------------------------------------------------------------------------------- /html_template/images/center-icon-order-all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/center-icon-order-all.png -------------------------------------------------------------------------------- /html_template/images/center-icon-order-dfh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/center-icon-order-dfh.png -------------------------------------------------------------------------------- /html_template/images/center-icon-order-dfk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/center-icon-order-dfk.png -------------------------------------------------------------------------------- /html_template/images/center-icon-order-dpj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/center-icon-order-dpj.png -------------------------------------------------------------------------------- /html_template/images/center-icon-order-dsh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/center-icon-order-dsh.png -------------------------------------------------------------------------------- /html_template/images/center-icon-out.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/center-icon-out.png -------------------------------------------------------------------------------- /html_template/images/center-icon-sc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/center-icon-sc.png -------------------------------------------------------------------------------- /html_template/images/footer03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/footer03.png -------------------------------------------------------------------------------- /html_template/images/good1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/good1.jpg -------------------------------------------------------------------------------- /html_template/images/good2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/good2.jpg -------------------------------------------------------------------------------- /html_template/images/good3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/good3.jpg -------------------------------------------------------------------------------- /html_template/images/good4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/good4.jpg -------------------------------------------------------------------------------- /html_template/images/good5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/good5.jpg -------------------------------------------------------------------------------- /html_template/images/good6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/good6.jpg -------------------------------------------------------------------------------- /html_template/images/goods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/goods.png -------------------------------------------------------------------------------- /html_template/images/goods_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/goods_on.png -------------------------------------------------------------------------------- /html_template/images/head_index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/head_index.png -------------------------------------------------------------------------------- /html_template/images/icon-back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/icon-back.png -------------------------------------------------------------------------------- /html_template/images/icon-collection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/icon-collection.png -------------------------------------------------------------------------------- /html_template/images/icon-dele.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/icon-dele.png -------------------------------------------------------------------------------- /html_template/images/icon-edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/icon-edit.png -------------------------------------------------------------------------------- /html_template/images/icon-kefu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/icon-kefu.png -------------------------------------------------------------------------------- /html_template/images/icon_nav_city.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/icon_nav_city.png -------------------------------------------------------------------------------- /html_template/images/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/index.png -------------------------------------------------------------------------------- /html_template/images/index_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/index_on.png -------------------------------------------------------------------------------- /html_template/images/location-border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/location-border.png -------------------------------------------------------------------------------- /html_template/images/menu1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/menu1.png -------------------------------------------------------------------------------- /html_template/images/menu2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/menu2.png -------------------------------------------------------------------------------- /html_template/images/menu3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/menu3.png -------------------------------------------------------------------------------- /html_template/images/menu4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/menu4.png -------------------------------------------------------------------------------- /html_template/images/mid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/mid.png -------------------------------------------------------------------------------- /html_template/images/my.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/my.png -------------------------------------------------------------------------------- /html_template/images/my_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/my_on.png -------------------------------------------------------------------------------- /html_template/images/prod_content1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/prod_content1.jpg -------------------------------------------------------------------------------- /html_template/images/prod_content10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/prod_content10.png -------------------------------------------------------------------------------- /html_template/images/prod_content11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/prod_content11.png -------------------------------------------------------------------------------- /html_template/images/prod_content12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/prod_content12.png -------------------------------------------------------------------------------- /html_template/images/prod_content13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/prod_content13.jpg -------------------------------------------------------------------------------- /html_template/images/prod_content2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/prod_content2.jpg -------------------------------------------------------------------------------- /html_template/images/prod_content3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/prod_content3.png -------------------------------------------------------------------------------- /html_template/images/prod_content4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/prod_content4.png -------------------------------------------------------------------------------- /html_template/images/prod_content5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/prod_content5.png -------------------------------------------------------------------------------- /html_template/images/prod_content6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/prod_content6.png -------------------------------------------------------------------------------- /html_template/images/prod_content7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/prod_content7.png -------------------------------------------------------------------------------- /html_template/images/prod_content8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/prod_content8.png -------------------------------------------------------------------------------- /html_template/images/prod_content9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/prod_content9.png -------------------------------------------------------------------------------- /html_template/images/prod_detail0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/prod_detail0.jpg -------------------------------------------------------------------------------- /html_template/images/prod_detail1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/prod_detail1.jpg -------------------------------------------------------------------------------- /html_template/images/prod_detail2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/prod_detail2.jpg -------------------------------------------------------------------------------- /html_template/images/prod_detail3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/prod_detail3.jpg -------------------------------------------------------------------------------- /html_template/images/s1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/s1.png -------------------------------------------------------------------------------- /html_template/images/s2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/s2.png -------------------------------------------------------------------------------- /html_template/images/s3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/s3.png -------------------------------------------------------------------------------- /html_template/images/tophovertree.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/tophovertree.gif -------------------------------------------------------------------------------- /html_template/images/vcode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/vcode.jpg -------------------------------------------------------------------------------- /html_template/images/xuanze.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/images/xuanze.png -------------------------------------------------------------------------------- /html_template/js/app/address.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "js/lib", 3 | "shim": { 4 | "jquery.Spinner": ["jquery"] 5 | } 6 | }); 7 | 8 | requirejs(["jquery", "weui.min", "city"], function($, weui, city){ 9 | $(function() { 10 | $("#area").click(function () { 11 | weui.picker(city.cityData, { 12 | className: 'addressPicClass', 13 | container: '#addressPicContainer', 14 | defaultValue: ['440000', '440100', '440106'], 15 | onChange: function (result) { 16 | console.log(result) 17 | }, 18 | onConfirm: function (result) { 19 | console.log(result) 20 | }, 21 | id: 'addressPic' 22 | }); 23 | }); 24 | 25 | $("#addBtn").click(function () { 26 | $("#listDiv").hide(); 27 | $("#editForm").show(); 28 | }); 29 | 30 | $("#backBtn").click(function () { 31 | $("#editForm").hide(); 32 | $("#listDiv").show(); 33 | }); 34 | }); 35 | 36 | }) -------------------------------------------------------------------------------- /html_template/js/app/cart.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "js/lib", 3 | "shim": { 4 | "jquery.Spinner": ["jquery"] 5 | } 6 | }); 7 | 8 | requirejs(["jquery", "jquery.Spinner"], function($){ 9 | $(function() { 10 | $("#cart-all").click(function () { 11 | if ( $(this).prop('checked') ) { 12 | $("input[name=cartpro]").each(function () { 13 | $(this).prop("checked", true); 14 | }); 15 | } else { 16 | $("input[name=cartpro]").each(function () { 17 | $(this).prop("checked", false); 18 | }); 19 | } 20 | }); 21 | 22 | $("input[type=checkbox]").click(function () { 23 | var cartCheckedSize = $("input[name='cartpro']:checked").size(); 24 | var cartSize = $("input[name='cartpro']").size(); 25 | 26 | if ( cartCheckedSize >= 1 ) { 27 | $("#settlement").css("background-color", "green"); 28 | } else { 29 | $("#settlement").css("background-color", "gray"); 30 | } 31 | 32 | if (cartCheckedSize == cartSize) { 33 | $("#cart-all").prop("checked", true); 34 | } else { 35 | $("#cart-all").prop("checked", false); 36 | } 37 | }); 38 | 39 | $("#cart-all").click(); 40 | $(".Spinner").Spinner({value:1, len:3, max:15}); 41 | }); 42 | 43 | }) -------------------------------------------------------------------------------- /html_template/js/app/collection.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "js/lib", 3 | "shim": { 4 | "jquery.Spinner": ["jquery"] 5 | } 6 | }); 7 | 8 | requirejs(["jquery"], function($){ 9 | $(function() { 10 | 11 | }); 12 | 13 | }) -------------------------------------------------------------------------------- /html_template/js/app/index.js: -------------------------------------------------------------------------------- 1 | //define(["jquery", "swipe"], function($){ 2 | define(["jquery", "swiper-4.1.6.min"], function($, Swiper){ 3 | //alert("load finished"); 4 | 5 | $(function() { 6 | function swipeFun() { 7 | var mySwipeElem = document.getElementById('mySwipe'); 8 | window.mySwipe = Swipe(mySwipeElem, { 9 | //startSlide: 4, 10 | auto: 2000, 11 | //continuous: true, 12 | //disableScroll: true, 13 | //stopPropagation: true, 14 | callback: function(index, element) { 15 | //var preIndex = index - 1; 16 | //if (preIndex == -1) { 17 | // preIndex = mySwipe.getNumSlides() - 1; 18 | //} 19 | //$("#disc_" + preIndex).css("list-style-type", "circle"); 20 | //$("#disc_" + index).css("list-style-type", "disc"); 21 | //$("#disc_" + preIndex).css("color", "#c8c9cb"); 22 | $(".swipe-wrap-circle li").css("color", "#c8c9cb"); 23 | $("#disc_" + index).css("color", "green"); 24 | }, 25 | //transitionEnd: function(index, element) { 26 | // 27 | //} 28 | }); 29 | } 30 | //swipeFun(); 31 | 32 | var mySwiper = new Swiper ('.swiper-container', { 33 | loop: true, 34 | autoplay : { 35 | delay:2000 36 | }, 37 | // 分页器 38 | pagination: { 39 | el: '.swiper-pagination', 40 | clickable: true 41 | } 42 | }); 43 | 44 | $(".weui-tabbar__item").click(function () { 45 | var currentId = $(this).attr("id"); 46 | var preId = $(".weui-bar__item_on").attr("id"); 47 | 48 | $(".weui-bar__item_on img").attr("src", "./images/" + preId + ".png"); 49 | $(".weui-bar__item_on").removeClass("weui-bar__item_on"); 50 | $(this).addClass("weui-bar__item_on"); 51 | 52 | //$("div.weui-tab__panel[style='display: block;']").hide(); 53 | $(".weui-tab__panel").hide(); 54 | $("#" + currentId + "_content").show(); 55 | $("#" + currentId + "_img").attr("src", "./images/" + currentId + "_on.png"); 56 | 57 | //mySwipe.next(); 58 | }); 59 | 60 | $("#loadmore-button").click(function () { 61 | $("#loadmore-button").hide(); 62 | $("#loadmore-loading").show(); 63 | setTimeout(function () { 64 | $("#loadmore-loading").hide(); 65 | $("#noData").show(); 66 | }, 1000); 67 | }); 68 | 69 | var $searchBar = $('#searchBar'), 70 | $searchResult = $('#searchResult'), 71 | $searchText = $('#searchText'), 72 | $searchInput = $('#searchInput'), 73 | $searchClear = $('#searchClear'), 74 | $searchCancel = $('#searchCancel'); 75 | 76 | function hideSearchResult(){ 77 | $searchResult.hide(); 78 | $searchInput.val(''); 79 | } 80 | function cancelSearch(){ 81 | hideSearchResult(); 82 | $searchBar.removeClass('weui-search-bar_focusing'); 83 | $searchText.show(); 84 | } 85 | 86 | $searchText.on('click', function(){ 87 | $searchBar.addClass('weui-search-bar_focusing'); 88 | $searchInput.focus(); 89 | }); 90 | $searchInput 91 | .on('blur', function () { 92 | if(!this.value.length) cancelSearch(); 93 | }) 94 | .on('input', function(){ 95 | if(this.value.length) { 96 | $searchResult.show(); 97 | } else { 98 | $searchResult.hide(); 99 | } 100 | }) 101 | ; 102 | $searchClear.on('click', function(){ 103 | hideSearchResult(); 104 | $searchInput.focus(); 105 | }); 106 | $searchCancel.on('click', function(){ 107 | cancelSearch(); 108 | $searchInput.blur(); 109 | }); 110 | }); 111 | 112 | }) 113 | -------------------------------------------------------------------------------- /html_template/js/app/index_main.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "js/lib", 3 | "paths": { 4 | "index": "../app/index" 5 | } 6 | }); 7 | 8 | requirejs(["index"]); -------------------------------------------------------------------------------- /html_template/js/app/login.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "js/lib" 3 | }); 4 | 5 | requirejs(["jquery"], function($){ 6 | $(function() { 7 | var tipTimeOutId; 8 | 9 | $("#loginBtn").click(function () { 10 | clearTimeout(tipTimeOutId); 11 | $("#errorTip").show(800); 12 | 13 | tipTimeOutId = setTimeout(function(){ 14 | $("#errorTip").hide(800); 15 | }, 2000); 16 | }); 17 | 18 | }); 19 | 20 | }) -------------------------------------------------------------------------------- /html_template/js/app/order-detail.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "js/lib", 3 | "shim": { 4 | "jquery.Spinner": ["jquery"] 5 | } 6 | }); 7 | 8 | requirejs(["jquery"], function($){ 9 | $(function() { 10 | 11 | }); 12 | 13 | }) -------------------------------------------------------------------------------- /html_template/js/app/prod-detail.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "js/lib", 3 | "shim": { 4 | "jquery.Spinner": ["jquery"] 5 | } 6 | }); 7 | 8 | requirejs(["jquery", "swiper-4.1.6.min", "jquery.Spinner"], function($, Swiper){ 9 | $(function() { 10 | var mySwiper = new Swiper ('.swiper-container', { 11 | loop: true, 12 | // 分页器 13 | pagination: { 14 | el: '.swiper-pagination', 15 | clickable: true 16 | } 17 | }); 18 | 19 | $(".wy-header-titlebut").click(function () { 20 | var currentId = $(this).attr("id"); 21 | $(".wy-product-content").hide(); 22 | $("#" + currentId + "Div").show(); 23 | 24 | $(".wy-header-titlebut").removeClass("wy-header-titlebut-active"); 25 | $(this).addClass('wy-header-titlebut-active'); 26 | }); 27 | 28 | $(".Spinner").Spinner({value:1, len:3, max:15}); 29 | }); 30 | 31 | }) -------------------------------------------------------------------------------- /html_template/js/app/register.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "js/lib" 3 | }); 4 | 5 | requirejs(["jquery", "weui.min"], function($, weui){ 6 | 7 | $(function(){ 8 | /* var tmpl = '
  • ', 9 | $gallery = $("#gallery"), $galleryImg = $("#galleryImg"), 10 | $uploaderInput = $("#uploaderInput"), 11 | $uploaderFiles = $("#uploaderFiles") 12 | ; 13 | 14 | $uploaderInput.on("change", function(e){ 15 | var src, url = window.URL || window.webkitURL || window.mozURL, files = e.target.files; 16 | for (var i = 0, len = files.length; i < len; ++i) { 17 | var file = files[i]; 18 | console.log(file); 19 | 20 | if (url) { 21 | src = url.createObjectURL(file); 22 | } else { 23 | src = e.target.result; 24 | } 25 | 26 | $uploaderFiles.append($(tmpl.replace('#url#', src))); 27 | } 28 | }); 29 | $uploaderFiles.on("click", "li", function(){ 30 | $galleryImg.attr("style", this.getAttribute("style")); 31 | $gallery.fadeIn(100); 32 | }); 33 | $gallery.on("click", function(){ 34 | $gallery.fadeOut(100); 35 | }); */ 36 | 37 | $("#headDiv").on("click", function(){ 38 | $("#headFile").click(); 39 | }); 40 | 41 | var uploadCount = 0, 42 | uploadList = []; 43 | var uploadCountDom = document.getElementById("uploadCount"); 44 | weui.uploader('#uploader', { 45 | url: 'http://localhost:8081', 46 | auto: false, 47 | type: 'file', 48 | fileVal: 'fileVal', 49 | compress: { 50 | width: 1600, 51 | height: 1600, 52 | quality: .8 53 | }, 54 | onBeforeQueued: function(files) { 55 | // `this` 是轮询到的文件, `files` 是所有文件 56 | 57 | if(["image/jpg", "image/jpeg", "image/png", "image/gif"].indexOf(this.type) < 0){ 58 | weui.alert('请上传图片'); 59 | return false; // 阻止文件添加 60 | } 61 | if(this.size > 10 * 1024 * 1024){ 62 | weui.alert('请上传不超过10M的图片'); 63 | return false; 64 | } 65 | if (files.length > 5) { // 防止一下子选择过多文件 66 | weui.alert('最多只能上传5张图片,请重新选择'); 67 | return false; 68 | } 69 | if (uploadCount + 1 > 5) { 70 | weui.alert('最多只能上传5张图片'); 71 | return false; 72 | } 73 | 74 | ++uploadCount; 75 | 76 | // return true; // 阻止默认行为,不插入预览图的框架 77 | }, 78 | onQueued: function(){ 79 | console.log(this); 80 | 81 | // console.log(this.status); // 文件的状态:'ready', 'progress', 'success', 'fail' 82 | // console.log(this.base64); // 如果是base64上传,file.base64可以获得文件的base64 83 | 84 | // this.upload(); // 如果是手动上传,这里可以通过调用upload来实现;也可以用它来实现重传。 85 | // this.stop(); // 中断上传 86 | 87 | // return true; // 阻止默认行为,不显示预览图的图像 88 | }, 89 | onBeforeSend: function(data, headers){ 90 | console.log(this, data, headers); 91 | // $.extend(data, { test: 1 }); // 可以扩展此对象来控制上传参数 92 | // $.extend(headers, { Origin: 'http://127.0.0.1' }); // 可以扩展此对象来控制上传头部 93 | 94 | // return false; // 阻止文件上传 95 | }, 96 | onProgress: function(procent){ 97 | console.log(this, procent); 98 | // return true; // 阻止默认行为,不使用默认的进度显示 99 | }, 100 | onSuccess: function (ret) { 101 | console.log(this, ret); 102 | // return true; // 阻止默认行为,不使用默认的成功态 103 | }, 104 | onError: function(err){ 105 | console.log(this, err); 106 | // return true; // 阻止默认行为,不使用默认的失败态 107 | } 108 | }); 109 | 110 | // 缩略图预览 111 | document.querySelector('#uploaderFiles').addEventListener('click', function (e) { 112 | var target = e.target; 113 | 114 | while (!target.classList.contains('weui-uploader__file') && target) { 115 | target = target.parentNode; 116 | } 117 | if (!target) return; 118 | 119 | var url = target.getAttribute('style') || ''; 120 | var id = target.getAttribute('data-id'); 121 | 122 | if (url) { 123 | url = url.match(/url\((.*?)\)/)[1].replace(/"/g, ''); 124 | } 125 | var gallery = weui.gallery(url, { 126 | className: 'zindex-9999', 127 | onDelete: function onDelete() { 128 | weui.confirm('确定删除该图片?', function () { 129 | --uploadCount; 130 | uploadCountDom.innerHTML = uploadCount; 131 | 132 | for (var i = 0, len = uploadList.length; i < len; ++i) { 133 | var file = uploadList[i]; 134 | if (file.id == id) { 135 | file.stop(); 136 | break; 137 | } 138 | } 139 | target.remove(); 140 | gallery.hide(); 141 | }); 142 | } 143 | }); 144 | }); 145 | 146 | }); 147 | 148 | }) -------------------------------------------------------------------------------- /html_template/js/app/settlement.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "js/lib", 3 | "shim": { 4 | "jquery.Spinner": ["jquery"] 5 | } 6 | }); 7 | 8 | requirejs(["jquery", "weui.min", "city"], function($, weui, city){ 9 | $(function() { 10 | $("#addressSelect").click(function () { 11 | weui.picker(city.cityData, { 12 | className: 'addressPicClass', 13 | container: '#addressPicContainer', 14 | defaultValue: ['440000', '440100', '440106'], 15 | onChange: function (result) { 16 | console.log(result) 17 | }, 18 | onConfirm: function (result) { 19 | console.log(result) 20 | }, 21 | id: 'addressPic' 22 | }); 23 | }); 24 | 25 | }); 26 | 27 | }) -------------------------------------------------------------------------------- /html_template/js/app/user.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "js/lib" 3 | }); 4 | 5 | requirejs(["jquery"], function($){ 6 | 7 | $(function(){ 8 | var $gallery = $("#gallery"), $galleryImg = $("#galleryImg"); 9 | 10 | $("#headFile").on("change", function(e){ 11 | var src, url = window.URL || window.webkitURL || window.mozURL, files = e.target.files; 12 | if (files.length > 0) { 13 | var file = files[0]; 14 | console.log(file); 15 | 16 | if (url) { 17 | src = url.createObjectURL(file); 18 | } else { 19 | src = e.target.result; 20 | } 21 | 22 | $("#headImage").attr("src", src); 23 | } 24 | }); 25 | $("#headImage").on("click", function(){ 26 | $galleryImg.attr("style", "background-image:url(" + this.getAttribute("src") + ")"); 27 | $gallery.fadeIn(100); 28 | event.stopPropagation(); 29 | }); 30 | $gallery.on("click", function(){ 31 | $gallery.fadeOut(100); 32 | }); 33 | 34 | $("#headDiv").on("click", function(){ 35 | $("#headFile").click(); 36 | }); 37 | 38 | }); 39 | 40 | }) -------------------------------------------------------------------------------- /html_template/js/lib/jquery.Spinner.js: -------------------------------------------------------------------------------- 1 | /* jQuery.Spinner V1.0 CopyRight (c) 2014 by:Loyaoo Taobao:http://isseven.taobao.com */ 2 | 3 | (function($) { 4 | 5 | $.fn.Spinner = function (opts) { 6 | 7 | var defaults = {value:1, min:1, len:3, max:99} 8 | var options = $.extend(defaults, opts) 9 | var keyCodes = {up:38, down:40} 10 | return this.each(function() { 11 | 12 | var a = $(''); f(a,0,"Decrease","-"); //加 13 | var c = $(''); f(c,0,"Increase","+"); //减 14 | var b = $('');f(b,1,"Amount");cv(0); //值 15 | 16 | $(this).append(a).append(b).append(c); 17 | a.click(function(){cv(-1)}); 18 | b.keyup(function(){cv(0)}); 19 | c.click(function(){cv(+1)}); 20 | b.bind('keyup paste change',function(e){ 21 | e.keyCode==keyCodes.up&&cv(+1); 22 | e.keyCode==keyCodes.down&&cv(-1); 23 | }); 24 | 25 | function cv(n){ 26 | b.val(b.val().replace(/[^\d]/g,'')); 27 | bv=parseInt(b.val()||options.min)+n; 28 | bv>=options.min&&bv<=options.max&&b.val(bv); 29 | if(bv<=options.min){b.val(options.min);f(a,2,"DisDe","Decrease");}else{f(a,2,"Decrease","DisDe");} 30 | if(bv>=options.max){b.val(options.max);f(c,2,"DisIn","Increase");}else{f(c,2,"Increase","DisIn");} 31 | } 32 | 33 | }); 34 | 35 | function f(o,t,c,s){ 36 | t==0&&o.addClass(c).attr("href","javascript:void(0)").append("").find("i").append(s); 37 | t==1&&o.addClass(c).attr({"value":options.value,"autocomplete":"off","maxlength":options.len}); 38 | t==2&&o.addClass(c).removeClass(s); 39 | } 40 | } 41 | 42 | })(jQuery); -------------------------------------------------------------------------------- /html_template/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 登录 7 | 8 | 9 | 10 | 15 | 16 | 17 | 18 |
    错误提示
    19 |
    20 |
    21 |
    登录商城
    22 |
    23 |
    24 | 25 |
    26 |
    27 |
    28 |
    29 | 30 |
    31 |
    32 | 40 |
    41 |
    42 |
    43 | 44 |
    45 |
    46 |
    47 |
    48 |
    49 | 50 |
    51 |
    52 | 53 |
    54 |
    55 |
    56 |
    57 | 58 |
    59 | 登 录 60 | 注 册 61 |
    62 | 63 | 73 | 74 |
    75 | 76 |
    77 | 80 |
    81 | 82 | 83 | -------------------------------------------------------------------------------- /html_template/msg.html: -------------------------------------------------------------------------------- 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 |
    31 | 37 |
    38 |
    39 | 40 | 41 | -------------------------------------------------------------------------------- /html_template/reset-pass.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 密码重置 7 | 8 | 9 | 14 | 15 | 16 | 17 |
    18 |
    19 |
    密码重置
    20 |
    21 |
    22 | 23 |
    24 |
    25 |
    26 |
    27 |
    28 | 29 |
    30 |
    31 | 32 |
    33 |
    34 | 35 |
    36 |
    37 |
    38 | 39 |
    40 |
    41 | 42 |
    43 |
    44 | 45 |
    46 |
    47 | 48 |
    49 |
    50 | 获取验证码 51 |
    52 |
    53 | 54 |
    55 |
    56 | 57 |
    58 | 59 | 60 |
    61 |
    62 |
    63 | 64 |
    65 | 68 |
    69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /html_template/screenshot/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/screenshot/1.jpg -------------------------------------------------------------------------------- /html_template/screenshot/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/screenshot/2.jpg -------------------------------------------------------------------------------- /html_template/screenshot/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/screenshot/3.jpg -------------------------------------------------------------------------------- /html_template/screenshot/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/screenshot/4.jpg -------------------------------------------------------------------------------- /html_template/screenshot/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/screenshot/5.jpg -------------------------------------------------------------------------------- /html_template/screenshot/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/screenshot/6.jpg -------------------------------------------------------------------------------- /html_template/screenshot/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/screenshot/7.png -------------------------------------------------------------------------------- /html_template/screenshot/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/screenshot/8.jpg -------------------------------------------------------------------------------- /html_template/screenshot/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/html_template/screenshot/9.jpg -------------------------------------------------------------------------------- /html_template/settlement.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 结算 7 | 8 | 9 | 10 | 24 | 25 | 26 | 27 |
    28 |
    29 |
    结算
    30 |
    31 |
    32 | 33 |
    34 | 46 | 47 | 96 | 97 |
    98 |
    99 |
    100 |

    配送方式

    101 |
    102 |
    快递
    103 |
    104 |
    105 | 106 |
    107 |
    108 |
    109 |

    商品金额

    110 |
    111 |
    ¥300
    112 |
    113 |
    114 |
    115 |

    物流运费

    116 |
    117 |
    + ¥10
    118 |
    119 |
    120 |
    121 |

    总的金额

    122 |
    123 |
    ¥310
    124 |
    125 | 126 |
    127 | 微信支付 128 |
    129 |
    130 | 131 |
    132 |
    133 | 134 | 135 | -------------------------------------------------------------------------------- /html_template/style/style.css: -------------------------------------------------------------------------------- 1 | body,html { 2 | height: 100%; 3 | background-color: #f8f8f8; 4 | } 5 | .searchbar-result { 6 | display: none; 7 | margin-top: 0; 8 | font-size: 14px; 9 | color: #666; 10 | } 11 | 12 | /*首页图标链接*/ 13 | .wy-iconlist-box{background:#fff; padding:0;} 14 | .wy-links-iconlist{display:block; text-align:center; margin:10px 0;} 15 | .wy-links-iconlist .img{margin:0 23px;} 16 | .wy-links-iconlist img{width:100%;} 17 | .wy-links-iconlist p{font-size:12px; color:#666; margin-top:5px;} 18 | 19 | .wy-iconlist-box-ex{background:#f8f8f8; padding:0;margin-bottom:5px;} 20 | .wy-links-iconlist-ex{display:block; text-align:center; margin:10px 0;} 21 | .wy-links-iconlist-ex .img{margin:0 23px;} 22 | .wy-links-iconlist-ex img{width:100%;} 23 | .wy-links-iconlist-ex p{font-size:12px; color:#666; margin-top:5px;} 24 | 25 | .radius{border-radius:50%; -moz-border-radius:50%; -ms-border-radius:50%; -o-border-radius:50%; -webkit-border-radius:50%;} 26 | 27 | .triangle-up { 28 | width: 0; 29 | height: 0; 30 | border-left: 4px solid transparent; 31 | border-right: 4px solid transparent; 32 | border-bottom: 4px solid gray; 33 | } 34 | .triangle-down { 35 | width: 0; 36 | height: 0; 37 | border-left: 4px solid transparent; 38 | border-right: 4px solid transparent; 39 | border-top: 4px solid green; 40 | } 41 | 42 | .center-list-icon{width:20px; height:auto;} 43 | 44 | .wy-header{ height:41px; border-bottom:1px solid #e1e1e1; position:fixed;z-index:9999; width:100%;background-color:#f7f7fa;} 45 | .wy-header-icon-back{position: absolute; left:0; top:0; width: 40px;height: 44px; } 46 | .wy-header-icon-back a {width:20px;height:20px; margin: 12px 0 0 10px; background:url(../images/icon-back.png) no-repeat; background-size:20px; display:block;} 47 | .wy-header-title{margin: 0 50px;text-align: center;height: 44px;line-height: 44px;font-size: 15px; color:#252525;} 48 | .wy-header-icon-index{position: absolute; right:0; top:0; width: 40px;height: 44px; } 49 | .wy-header-icon-index a {width:25px;height:25px; margin: 9px 0 0 3px; background:url(../images/head_index.png) no-repeat; background-size:25px; display:block;} 50 | 51 | .Spinner{display:block;overflow:hidden;width:88px;margin:0;} 52 | .Spinner .Amount{width:26px;height:14px;padding:4px 5px;line-height:14px;border-top:1px solid #d9d9d9; border-bottom:1px solid #d9d9d9;float:left;text-align:center;color:#333;outline:0; font-size:14px;border-left:0px;border-right:0px;} 53 | .Spinner a{display:inline-block;width:22px;height:22px;border:1px solid #d9d9d9;background-color:#f7f7f7;float:left;cursor:pointer;outline:0;} 54 | .Spinner a i{font-style:normal;background:url(../images/BuynBtn.png) no-repeat;display:block;width:12px;height:12px;margin:5px;text-indent:999999%;overflow:hidden;} 55 | .Spinner .Decrease i{background-position:-12px -12px;} 56 | .Spinner .Increase i{background-position:-12px -0px;} 57 | .Spinner .DisDe i{background-position:-0px -12px;} 58 | .Spinner .DisIn i{background-position:-0px -0px;} 59 | 60 | .wy-dele{width:20px; height:20px; background:url(../images/icon-dele.png) no-repeat; display:block; background-size:20px;} 61 | 62 | .promotion-foot-menu-kefu{background:url(../images/icon-kefu.png) no-repeat; background-size:22px;} 63 | .promotion-foot-menu-collection{background:url(../images/icon-collection.png) no-repeat; background-size:22px;} 64 | .promotion-foot-menu-cart{background:url(../images/footer03.png) no-repeat; background-size:22px;} 65 | .promotion-foot-menu-items{position:relative; padding:5px 10px 0; text-align:center;} 66 | .promotion-foot-menu-label{line-height:38px; color:#fff;font-size: 13px;} 67 | 68 | .wy-media-box2{margin:10px 0; background:#fff; padding:5px 10px; border-top:0px solid #e1e1e1; border-bottom:0px solid #e1e1e1;} 69 | .wy-media-box2 .weui-media-box_appmsg{border-top:0px solid #ededed; padding-top:0px;} 70 | .wy-media-box2 .weui-media-box_appmsg:first-child{border:0; padding-top:0; } 71 | .wy-media-box2.txtpd .weui-media-box_appmsg{padding-top:0; border:0;} 72 | .weui-media-box_appmsg .weui-media-box__hd.proinfo-txt-l{width:38px; height:auto; vertical-align:top;} 73 | .promotion-label-tit{font-size:13px; color:gray; line-height:12px;} 74 | .promotion-label-tit img{width:80%;} 75 | .promotion-sku{padding:8px 0 5px 0;} 76 | .promotion-sku li{float:left; margin:5px 10px 1px 0;list-style:none;} 77 | .promotion-sku li a{display:block;border:1px solid #ddd; border-radius:3px; background-color:#fff;min-width:20px;padding:7px 12px; max-width:100%;text-align: center; font-size:12px; color:gray; position:relative;} 78 | .promotion-sku li.active a:after{content:""; width:12px; height:12px; background:url(../images/xuanze.png) no-repeat; background-size:12px; position:absolute; right:0; bottom:0;} 79 | .promotion-sku li.active a{border:1px solid green; color:green;} 80 | .wy-header-titlebut{color:gray;} 81 | .wy-header-titlebut-active{color:green;border-bottom: 1px solid green;padding-bottom:9px;} 82 | .wy-product-content{padding-top:40px;padding-bottom:45px;} 83 | 84 | .wy-media-box{margin:10px 0; background:#fff; padding:12px 10px; border-top:1px solid #e1e1e1; border-bottom:1px solid #e1e1e1;} 85 | .wy-media-box.address-select{margin-top:0; background:url(../images/location-border.png) repeat-x left bottom #fff; border-bottom:0; background-size:auto 3px;} 86 | .address-name{font-size:14px; color:black;} 87 | .address-name span{margin-right:10px;} 88 | .address-txt{font-size:13px; color:#999; line-height:29px;} 89 | 90 | .weui-navbar__item.proinfo-tab-tit{padding:10px 0;color:#999;} 91 | .weui-navbar__item.proinfo-tab-tit:after{display:none;} 92 | .weui-navbar__item.proinfo-tab-tit.weui-bar__item--on:before{content:""; width:34px; height:1px; background:green; position:absolute; left:50%; margin-left:-17px; bottom:0px; z-index:10;} 93 | .weui-navbar__item.weui-bar__item--on{color:green; background-color:inherit;} 94 | .weui-navbar + .weui-tab__bd.proinfo-tab-con{padding-top:44px;} 95 | 96 | .font-14{font-size:14px; font-weight:normal;} 97 | .font-13{font-size:13px; font-weight:normal;} -------------------------------------------------------------------------------- /html_template/style/swipe.css: -------------------------------------------------------------------------------- 1 | /* Swipe 2 required styles */ 2 | .swipe { 3 | overflow: hidden; 4 | visibility: hidden; 5 | position: relative; 6 | } 7 | .swipe-wrap div{ 8 | overflow: hidden; 9 | position: relative; 10 | /*max-height: 350px;*/ 11 | } 12 | .swipe-wrap > div { 13 | float: left; 14 | width: 100%; 15 | position: relative; 16 | } 17 | /* END required styles */ 18 | 19 | .swipe-wrap img { 20 | width: 100%; 21 | } 22 | 23 | .swipe-wrap-circle {position: absolute; z-index: 9999; bottom: 0; left: 50%; margin-left: -5%;} 24 | .swipe-wrap-circle li{float: left; margin-left: 20px;color: #c8c9cb;list-style-type: disc} 25 | .swipe-wrap-circle li:first-child{color: green;} -------------------------------------------------------------------------------- /html_template/upt-pass.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 密码修改 7 | 8 | 9 | 14 | 15 | 16 | 17 |
    18 |
    19 |
    密码修改
    20 |
    21 |
    22 | 23 |
    24 |
    25 |
    26 |
    27 |
    28 | 29 |
    30 |
    31 | 32 |
    33 |
    34 | 35 |
    36 |
    37 |
    38 | 39 |
    40 |
    41 | 42 |
    43 |
    44 | 45 |
    46 |
    47 |
    48 | 49 |
    50 |
    51 | 52 |
    53 |
    54 | 55 |
    56 |
    57 | 58 |
    59 | 60 | 61 |
    62 |
    63 |
    64 | 65 |
    66 | 69 |
    70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /html_template/user.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 用户 7 | 8 | 9 | 10 | 22 | 23 | 24 | 25 |
    26 |
    27 |
    用户
    28 |
    29 |
    30 | 31 |
    32 |
    33 |
    34 |
    35 |
    36 | 37 |
    38 |
    39 | 40 |
    41 |
    42 |
    43 |
    44 |
    45 | 46 |
    47 |
    48 | 49 |
    50 |
    51 |
    52 | 53 |
    54 |
    55 | 56 | 64 | 65 | 66 |
    67 |
    68 |
    69 | 70 |
    71 |
    72 | 73 |
    74 |
    75 | 76 |
    77 | 78 | 79 |
    80 |
    81 |
    82 | 83 |
    84 | 87 |
    88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /init-db.js: -------------------------------------------------------------------------------- 1 | //初始化数据库 包括表和表数据 谨慎执行 2 | const model = require('./middleware/model.js'); 3 | const fs = require('mz/fs'); 4 | var sequelize = model.sequelize; 5 | 6 | (async () => { 7 | await model.sync(); 8 | 9 | let fp = 'init-sql.sql'; 10 | var sqlBuffer = await fs.readFile(fp); 11 | var sqlString = sqlBuffer.toString('utf-8'); 12 | 13 | var sqlStringArray = sqlString.split("\n"); 14 | for (let i = 0; i < sqlStringArray.length; i++) { 15 | //console.log(sqlStringArray[i]); 16 | if (sqlStringArray[i].trim() == '') { 17 | continue; 18 | } 19 | await sequelize.query(sqlStringArray[i]); 20 | } 21 | 22 | process.exit(0); 23 | })(); 24 | 25 | /* sequelize.query('select * from product').spread((results, metadata) => { 26 | console.log(results); 27 | }); 28 | 29 | sequelize.query('select * from product', { type: sequelize.QueryTypes.SELECT }).then(results => { 30 | console.log(results); 31 | }); */ -------------------------------------------------------------------------------- /middleware/config-default.js: -------------------------------------------------------------------------------- 1 | 2 | var config = { 3 | dialect: 'mysql', 4 | database: 'zshop', 5 | username: 'root', 6 | password: '', 7 | host: 'localhost', 8 | port: 3306, 9 | rootpath: '/zshop' 10 | }; 11 | 12 | module.exports = config; 13 | -------------------------------------------------------------------------------- /middleware/config-test.js: -------------------------------------------------------------------------------- 1 | 2 | var config = { 3 | dialect: 'mysql', 4 | database: 'zshop', 5 | username: 'root', 6 | password: '', 7 | host: 'localhost', 8 | port: 3306, 9 | rootpath: '/zshop' 10 | }; 11 | 12 | module.exports = config; 13 | -------------------------------------------------------------------------------- /middleware/config.js: -------------------------------------------------------------------------------- 1 | // config files: 2 | const defaultConfig = './config-default.js'; 3 | const overrideConfig = './config-override.js'; 4 | const testConfig = './config-test.js'; 5 | 6 | const fs = require('fs'); 7 | 8 | var config = null; 9 | 10 | if (process.env.NODE_ENV === 'test') { 11 | console.log(`Load ${testConfig}...`); 12 | config = require(testConfig); 13 | } else { 14 | console.log(`Load ${defaultConfig}...`); 15 | config = require(defaultConfig); 16 | try { 17 | if (fs.statSync(overrideConfig).isFile()) { 18 | console.log(`Load ${overrideConfig}...`); 19 | config = Object.assign(config, require(overrideConfig)); 20 | } 21 | } catch (err) { 22 | console.log(`Cannot load ${overrideConfig}.`); 23 | } 24 | } 25 | 26 | module.exports = config; 27 | -------------------------------------------------------------------------------- /middleware/controller.js: -------------------------------------------------------------------------------- 1 | 2 | const fs = require('fs'); 3 | const config = require('./config'); 4 | 5 | // add url-route in /controllers: 6 | 7 | function addMapping(router, mapping) { 8 | for (var url in mapping) { 9 | if (url.startsWith('GET ')) { 10 | var path = config.rootpath + url.substring(4); 11 | router.get(path, mapping[url]); 12 | console.log(`register URL mapping: GET ${path}`); 13 | } else if (url.startsWith('POST ')) { 14 | var path = config.rootpath + url.substring(5); 15 | router.post(path, mapping[url]); 16 | console.log(`register URL mapping: POST ${path}`); 17 | } else if (url.startsWith('PUT ')) { 18 | var path = config.rootpath + url.substring(4); 19 | router.put(path, mapping[url]); 20 | console.log(`register URL mapping: PUT ${path}`); 21 | } else if (url.startsWith('DELETE ')) { 22 | var path = config.rootpath + url.substring(7); 23 | router.del(path, mapping[url]); 24 | console.log(`register URL mapping: DELETE ${path}`); 25 | } else { 26 | console.log(`invalid URL: ${url}`); 27 | } 28 | } 29 | } 30 | 31 | function addControllers(router, dir) { 32 | fs.readdirSync(__dirname + '/' + dir).filter((f) => { 33 | return f.endsWith('.js'); 34 | }).forEach((f) => { 35 | console.log(`process controller: ${f}...`); 36 | let mapping = require(__dirname + '/' + dir + '/' + f); 37 | addMapping(router, mapping); 38 | }); 39 | } 40 | 41 | module.exports = function (dir) { 42 | let 43 | controllers_dir = dir || '../controllers', 44 | router = require('koa-router')(); 45 | addControllers(router, controllers_dir); 46 | return router.routes(); 47 | }; 48 | -------------------------------------------------------------------------------- /middleware/db.js: -------------------------------------------------------------------------------- 1 | const Sequelize = require('sequelize'); 2 | const moment = require('moment'); 3 | const uuid = require('node-uuid'); 4 | 5 | const config = require('./config'); 6 | 7 | console.log('init sequelize...'); 8 | 9 | function generateId() { 10 | return uuid.v4(); 11 | } 12 | 13 | var sequelize = new Sequelize(config.database, config.username, config.password, { 14 | host: config.host, 15 | dialect: config.dialect, 16 | pool: { 17 | max: 5, 18 | min: 0, 19 | idle: 10000 20 | }, 21 | timezone: '+08:00' //东八时区 22 | //logging: function(sql) { 23 | // console.log(sql); 24 | //} 25 | }); 26 | 27 | const ID_TYPE = Sequelize.STRING(50); 28 | 29 | function defineModel(name, attributes) { 30 | var attrs = {}; 31 | attrs.id = { 32 | type: ID_TYPE, 33 | primaryKey: true 34 | }; 35 | for (let key in attributes) { 36 | let value = attributes[key]; 37 | if (typeof value === 'object' && value['type']) { 38 | value.allowNull = value.allowNull || false; 39 | attrs[key] = value; 40 | } else { 41 | attrs[key] = { 42 | type: value, 43 | allowNull: false 44 | }; 45 | } 46 | } 47 | 48 | attrs.createdAt = { 49 | type: Sequelize.DATE, 50 | allowNull: false 51 | //get() { 52 | // return moment(this.getDataValue('ServiceTime')).utcOffset(8).format('YYYY-MM-DD HH:mm:ss'); 53 | //} 54 | }; 55 | attrs.updatedAt = { 56 | type: Sequelize.DATE, 57 | allowNull: false 58 | //get() { 59 | // return moment(this.getDataValue('ServiceTime')).utcOffset(8).format('YYYY-MM-DD HH:mm:ss'); 60 | //} 61 | }; 62 | attrs.version = { 63 | type: Sequelize.BIGINT, 64 | allowNull: false, 65 | defaultValue: 0 66 | }; 67 | console.log('model defined for table: ' + name + '\n' + JSON.stringify(attrs, function (k, v) { 68 | if (k === 'type') { 69 | for (let key in Sequelize) { 70 | if (key === 'ABSTRACT' || key === 'NUMBER') { 71 | continue; 72 | } 73 | let dbType = Sequelize[key]; 74 | if (typeof dbType === 'function') { 75 | if (v instanceof dbType) { 76 | if (v._length) { 77 | return `${dbType.key}(${v._length})`; 78 | } 79 | return dbType.key; 80 | } 81 | if (v === dbType) { 82 | return dbType.key; 83 | } 84 | } 85 | } 86 | } 87 | return v; 88 | }, ' ')); 89 | return sequelize.define(name, attrs, { 90 | tableName: name, 91 | timestamps: false, 92 | hooks: { 93 | beforeValidate: function (obj) { 94 | let now = Date.now(); 95 | if (obj.isNewRecord) { 96 | console.log('will create entity...' + JSON.stringify(obj)); 97 | console.log('will create entity idtype...' + attrs.id.type); 98 | if (!obj.id && attrs.id.type == ID_TYPE) { 99 | obj.id = generateId(); 100 | } 101 | obj.createdAt = now; 102 | obj.updatedAt = now; 103 | //obj.version = 0; 104 | } else { 105 | console.log('will update entity...'); 106 | obj.updatedAt = now; 107 | obj.version++; 108 | } 109 | } 110 | } 111 | }); 112 | } 113 | 114 | const TYPES = ['STRING', 'INTEGER', 'BIGINT', 'TEXT', 'DOUBLE', 'DATEONLY', 'BOOLEAN', 'DECIMAL', 'DATE']; 115 | 116 | var exp = { 117 | defineModel: defineModel, 118 | sync: async () => { 119 | console.log('process.env.NODE_ENV=' + process.env.NODE_ENV); 120 | // only allow create ddl in non-production environment: 121 | //if (process.env.NODE_ENV !== 'production') { 122 | await sequelize.sync({ force: true }); 123 | //} else { 124 | // throw new Error('Cannot sync() when NODE_ENV is set to \'production\'.'); 125 | //} 126 | } 127 | }; 128 | 129 | for (let type of TYPES) { 130 | exp[type] = Sequelize[type]; 131 | } 132 | 133 | exp.ID = ID_TYPE; 134 | exp.generateId = generateId; 135 | exp.sequelize = sequelize; 136 | 137 | module.exports = exp; 138 | -------------------------------------------------------------------------------- /middleware/model.js: -------------------------------------------------------------------------------- 1 | // scan all models defined in models: 2 | const fs = require('fs'); 3 | const db = require('./db'); 4 | 5 | //let files = fs.readdirSync(__dirname + '/models'); 6 | let files = fs.readdirSync('./models'); 7 | 8 | let js_files = files.filter((f)=>{ 9 | return f.endsWith('.js'); 10 | }, files); 11 | 12 | module.exports = {}; 13 | 14 | for (let f of js_files) { 15 | console.log(`import model from file ${f}...`); 16 | let name = f.substring(0, f.length - 3); 17 | //module.exports[name] = require(__dirname + '/models/' + f); 18 | module.exports[name] = require('../models/' + f); 19 | } 20 | 21 | module.exports.sync = async () => { 22 | await db.sync(); 23 | }; 24 | 25 | module.exports.sequelize = db.sequelize 26 | -------------------------------------------------------------------------------- /middleware/my-log4js.js: -------------------------------------------------------------------------------- 1 | const log4js = require('log4js'); 2 | //const uuid = require('node-uuid'); 3 | 4 | log4js.configure({ 5 | appenders: { 6 | myFileAppend: { 7 | type: 'dateFile', 8 | filename: 'logs/', 9 | pattern: 'zshop_yyyy-MM-dd.log', 10 | alwaysIncludePattern: true, 11 | layout: { 12 | type: 'pattern', 13 | pattern: '[%d] [%p] [%X{logid}] %c - %m' 14 | } 15 | }, 16 | myConsoleAppend: { 17 | type: 'console', 18 | layout: { 19 | type: 'pattern', 20 | pattern: '%[[%d] [%p] [%X{logid}] %c -%] %m' 21 | //tokens: { 22 | // logid: function(logEvent) { 23 | // return uuid.v4(); 24 | // } 25 | //} 26 | } 27 | } 28 | }, 29 | categories: { 30 | default: { appenders: ['myFileAppend', 'myConsoleAppend'], level: 'debug'} 31 | } 32 | }); 33 | 34 | module.exports = log4js; -------------------------------------------------------------------------------- /middleware/rest.js: -------------------------------------------------------------------------------- 1 | var timeoutFunMap = new Map(); 2 | 3 | module.exports = { 4 | timeoutFunMap: timeoutFunMap, 5 | APIError: function (code, message) { 6 | this.code = code || 'internal:unknown_error'; 7 | this.message = message || ''; 8 | }, 9 | restify: (pathPrefix) => { 10 | var loginPathPrefix = pathPrefix || '/zshop/userapi/'; 11 | pathPrefix = pathPrefix || '/zshop/api/'; 12 | 13 | return async (ctx, next) => { 14 | var isRest = false; 15 | if (ctx.request.path.startsWith(pathPrefix) || ctx.request.path.startsWith(loginPathPrefix)) { 16 | console.log(`Process API ${ctx.request.method} ${ctx.request.url}...`); 17 | isRest = true; 18 | ctx.rest = (data, httpCode) => { 19 | ctx.response.type = 'application/json'; 20 | ctx.response.body = data; 21 | if (httpCode) { 22 | ctx.response.status = httpCode; 23 | } 24 | } 25 | 26 | if (ctx.request.path.startsWith(loginPathPrefix) && !ctx.session.user) { 27 | ctx.rest({code: 'login:must_login', message: '请先登录'}, 400); 28 | return; 29 | } 30 | } else if (ctx.request.path.startsWith('/zshop/user/')) { 31 | if ( !ctx.session.user ) { 32 | let loginSuccUrl = ctx.query.loginSuccUrl || ctx.request.path || '/zshop/'; 33 | ctx.response.redirect('/zshop/login?loginSuccUrl=' + loginSuccUrl); 34 | //ctx.render('login.html'); 35 | return; 36 | } 37 | } 38 | 39 | try { 40 | await next(); 41 | if (ctx.transaction) ctx.transaction.commit(); 42 | if (ctx.timeoutFun) { 43 | let taskTimeOutId = setTimeout(ctx.timeoutFun, ctx.timeoutFunTime); 44 | timeoutFunMap.set(ctx.timeoutFunKey, taskTimeOutId); 45 | } 46 | } catch (e) { 47 | console.log('Process error: ' + JSON.stringify(e)); 48 | if (e.stack) console.log(e.stack); 49 | if (ctx.transaction) ctx.transaction.rollback(); 50 | if (isRest) { 51 | ctx.rest({code: e.code || 'internal:unknown_error', message: e.message || ''}, 400); 52 | } else { 53 | //throw e; 54 | //let msg = "系统出现错误"; 55 | //if (typeof e == "string") msg = e; 56 | //ctx.response.redirect('/static/html/500.html?msg=' + encodeURI(msg)); 57 | ctx.response.redirect('/static/html/500.html'); 58 | } 59 | } 60 | }; 61 | } 62 | }; 63 | -------------------------------------------------------------------------------- /middleware/static-files.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const mime = require('mime'); 3 | const fs = require('mz/fs'); 4 | 5 | function staticFiles(url, dir) { 6 | return async (ctx, next) => { 7 | let rpath = ctx.request.path; 8 | if (rpath.startsWith(url)) { 9 | let fp = path.join(dir, rpath.substring(url.length)); 10 | if (await fs.exists(fp)) { 11 | ctx.response.type = mime.lookup(rpath); 12 | ctx.response.body = await fs.readFile(fp); 13 | } else { 14 | ctx.response.status = 404; 15 | } 16 | } else if (rpath == "/favicon.ico") { 17 | let fp = "static/images/favicon.ico"; 18 | if (await fs.exists(fp)) { 19 | ctx.response.type = mime.lookup(rpath); 20 | ctx.response.body = await fs.readFile(fp); 21 | } else { 22 | ctx.response.status = 404; 23 | } 24 | } else { 25 | await next(); 26 | } 27 | }; 28 | } 29 | 30 | module.exports = staticFiles; 31 | -------------------------------------------------------------------------------- /middleware/templating.js: -------------------------------------------------------------------------------- 1 | const nunjucks = require('nunjucks'); 2 | 3 | function createEnv(path, opts) { 4 | var 5 | autoescape = opts.autoescape === undefined ? true : opts.autoescape, 6 | noCache = opts.noCache || false, 7 | watch = opts.watch || false, 8 | throwOnUndefined = opts.throwOnUndefined || false, 9 | env = new nunjucks.Environment( 10 | new nunjucks.FileSystemLoader(path, { 11 | noCache: noCache, 12 | watch: watch, 13 | }), { 14 | autoescape: autoescape, 15 | throwOnUndefined: throwOnUndefined 16 | }); 17 | if (opts.filters) { 18 | for (var f in opts.filters) { 19 | env.addFilter(f, opts.filters[f]); 20 | } 21 | } 22 | return env; 23 | } 24 | 25 | function templating(path, opts) { 26 | var env = createEnv(path, opts); 27 | return async (ctx, next) => { 28 | ctx.render = function (view, model) { 29 | ctx.response.body = env.render(view, Object.assign({}, ctx.state || {}, model || {})); 30 | ctx.response.type = 'text/html'; 31 | }; 32 | await next(); 33 | }; 34 | } 35 | 36 | module.exports = templating; 37 | -------------------------------------------------------------------------------- /models/advert.js: -------------------------------------------------------------------------------- 1 | const db = require('../middleware/db'); 2 | //广告实体 3 | module.exports = db.defineModel('advert', { 4 | id: { 5 | type: db.INTEGER, 6 | autoIncrement: true, 7 | primaryKey: true 8 | }, 9 | name: db.STRING(100), 10 | description: { 11 | type: db.STRING(200), 12 | allowNull: true 13 | }, 14 | position: db.INTEGER, //位置 1-首页头部 2-首页中部 15 | image: db.STRING(100), 16 | url: { 17 | type: db.STRING(100), 18 | allowNull: true 19 | } 20 | }); 21 | -------------------------------------------------------------------------------- /models/cart.js: -------------------------------------------------------------------------------- 1 | const db = require('../middleware/db'); 2 | //购物车实体 3 | module.exports = db.defineModel('cart', { 4 | id: { 5 | type: db.INTEGER, 6 | autoIncrement: true, 7 | primaryKey: true 8 | }, 9 | userId: db.STRING(30), 10 | prodId: db.INTEGER, 11 | count: db.INTEGER 12 | }); 13 | -------------------------------------------------------------------------------- /models/collection.js: -------------------------------------------------------------------------------- 1 | const db = require('../middleware/db'); 2 | //我的收藏实体 3 | module.exports = db.defineModel('collection', { 4 | userId: db.STRING(30), 5 | prodId: db.INTEGER 6 | }); 7 | -------------------------------------------------------------------------------- /models/group_attri.js: -------------------------------------------------------------------------------- 1 | const db = require('../middleware/db'); 2 | //分组产品属性实体 3 | module.exports = db.defineModel('group_attri', { 4 | id: { 5 | type: db.INTEGER, 6 | autoIncrement: true, 7 | primaryKey: true 8 | }, 9 | prodGroup: db.INTEGER, //product表的groupId 10 | attriId: db.STRING(20), //属性id 11 | attriName: db.STRING(30) //属性name 12 | }); 13 | -------------------------------------------------------------------------------- /models/group_attri_value.js: -------------------------------------------------------------------------------- 1 | const db = require('../middleware/db'); 2 | //分组产品属性值实体 3 | module.exports = db.defineModel('group_attri_value', { 4 | id: { 5 | type: db.INTEGER, 6 | autoIncrement: true, 7 | primaryKey: true 8 | }, 9 | groupAttriId: db.INTEGER, //group_attri表的id 10 | attriValue: db.STRING(200) //属性value 11 | }); 12 | -------------------------------------------------------------------------------- /models/order.js: -------------------------------------------------------------------------------- 1 | const db = require('../middleware/db'); 2 | const moment = require('moment'); 3 | 4 | //订单实体 5 | module.exports = db.defineModel('order', { 6 | userId: db.STRING(30), //用户id 7 | province: db.STRING(20), //配送省 8 | city: db.STRING(20), //配送市 9 | area: db.STRING(20), //配送地区 10 | address: db.STRING(100), //配送详细地址 11 | recipient: db.STRING(20), //收件人 12 | recipientPhone: db.STRING(30), //收件人电话号码 13 | deliveryType: { //配送方式 1-快递 14 | type: db.INTEGER, 15 | defaultValue: 1 16 | }, 17 | expressCompany: db.STRING(50), //快递公司 18 | expressNumber: db.STRING(50), //快递单号 19 | status: { //订单状态 1-初始化 2-待付款 3-待发货 4-待收货 5-待评价 6-已评价 20 | type: db.INTEGER, 21 | defaultValue: 1 22 | }, 23 | deliveryFee: { //配送费用 24 | type: db.DECIMAL(12, 2), 25 | defaultValue: 10.00 26 | }, 27 | prodPrice: db.DECIMAL(12, 2), //商品价格 28 | totalPrice: db.DECIMAL(12, 2), //总价格 = 商品价格 + 配送费用 29 | payStartTime: { //支付有效开始时间 30 | type: db.DATE, 31 | allowNull: true 32 | //get() { 33 | // return moment(this.getDataValue('ServiceTime')).utcOffset(8).format('YYYY-MM-DD HH:mm:ss'); 34 | //} 35 | } 36 | }); -------------------------------------------------------------------------------- /models/order_prod.js: -------------------------------------------------------------------------------- 1 | const db = require('../middleware/db'); 2 | //订单产品实体 3 | module.exports = db.defineModel('order_prod', { 4 | orderId: db.STRING(50), //订单id 5 | prodId: db.INTEGER, //产品id 6 | price: db.DECIMAL(12, 2), //价格 7 | count: db.INTEGER, //数量 8 | cartId: db.INTEGER //购物车id 9 | }); -------------------------------------------------------------------------------- /models/prod_attri.js: -------------------------------------------------------------------------------- 1 | const db = require('../middleware/db'); 2 | //产品属性实体 3 | module.exports = db.defineModel('prod_attri', { 4 | prodId: db.INTEGER, //product表的id 5 | groupAttriValueId: db.INTEGER //group_attri_value的id 6 | }); 7 | -------------------------------------------------------------------------------- /models/product.js: -------------------------------------------------------------------------------- 1 | const db = require('../middleware/db'); 2 | //商品实体 3 | module.exports = db.defineModel('product', { 4 | id: { 5 | type: db.INTEGER, 6 | autoIncrement: true, 7 | primaryKey: true 8 | }, 9 | groupId: db.INTEGER, //比如拥有不同颜色属性的产品属于同一组 10 | name: db.STRING(100), 11 | description: db.STRING(200), 12 | price: db.DECIMAL(12, 2), 13 | image: db.STRING(100), 14 | recommend: { //推荐 1-首页精品推荐 15 | type: db.INTEGER, 16 | allowNull: true 17 | }, 18 | sales: { //销量 19 | type: db.INTEGER, 20 | defaultValue: 0 21 | }, 22 | stock: { //库存 23 | type: db.INTEGER, 24 | defaultValue: 0 25 | }, 26 | detailImages: db.STRING(300), 27 | detailHtml: db.STRING(100) 28 | }); 29 | -------------------------------------------------------------------------------- /models/user.js: -------------------------------------------------------------------------------- 1 | const db = require('../middleware/db'); 2 | //用户实体 3 | module.exports = db.defineModel('user', { 4 | email: { 5 | type: db.STRING(100), 6 | unique: true, 7 | allowNull: true 8 | }, 9 | mobile: { 10 | type: db.STRING(11), 11 | unique: true 12 | }, 13 | userId: { 14 | type: db.STRING(30), 15 | unique: true 16 | }, 17 | passwd: db.STRING(100), 18 | name: db.STRING(100), 19 | gender: { //true:男,false:女 20 | type: db.BOOLEAN, 21 | allowNull: true 22 | }, 23 | headImage: db.STRING(100) //头像 24 | }); 25 | -------------------------------------------------------------------------------- /models/user_address.js: -------------------------------------------------------------------------------- 1 | const db = require('../middleware/db'); 2 | //用户地址实体 3 | module.exports = db.defineModel('user_address', { 4 | userId: db.STRING(30), //用户id 5 | province: db.STRING(20), //配送省 6 | city: db.STRING(20), //配送市 7 | area: db.STRING(20), //配送地区 8 | address: db.STRING(100), //配送详细地址 9 | name: db.STRING(20), //收件人 10 | phone: db.STRING(30), //收件人电话号码 11 | type: db.INTEGER //1-默认地址 12 | }); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zshop", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "scripts": { 7 | "start": "node --use_strict app.js" 8 | }, 9 | "keywords": [ 10 | "koa", 11 | "async", 12 | "zshop" 13 | ], 14 | "author": "halloffamezwx", 15 | "license": "MIT", 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/halloffamezwx/zshop.git" 19 | }, 20 | "dependencies": { 21 | "koa": "2.0.0", 22 | "koa-bodyparser": "3.2.0", 23 | "koa-router": "7.0.0", 24 | "nunjucks": "2.4.2", 25 | "mime": "1.3.4", 26 | "mz": "2.4.0", 27 | "koa-compress": "", 28 | "sequelize": "3.24.1", 29 | "mysql": "2.11.1", 30 | "koa-session2": "", 31 | "log4js": "", 32 | "captchapng": "", 33 | "moment": "", 34 | "koa-body": "" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /service/ad-service.js: -------------------------------------------------------------------------------- 1 | //广告service 2 | const model = require('../middleware/model'); 3 | 4 | let advert = model.advert; 5 | 6 | module.exports = { 7 | //查询所有广告 8 | getAllAds: async () => { 9 | var adverts = await advert.findAll(); 10 | return adverts; 11 | }, 12 | 13 | //根据位置查询广告 14 | getAdByPosition: async (posit) => { 15 | var adverts = await advert.findAll({ 16 | where: { 17 | position: posit 18 | } 19 | }); 20 | return adverts; 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /service/cart-service.js: -------------------------------------------------------------------------------- 1 | //购物车service 2 | const model = require('../middleware/model'); 3 | const productService = require('./product-service'); 4 | var sequelize = model.sequelize; 5 | let prodAttriValue = model.prod_attri_value; 6 | let cart = model.cart; 7 | 8 | module.exports = { 9 | //查询用户购物车 10 | getUserCartProd: async (user) => { 11 | var qcarts = await sequelize.query('SELECT c.id AS cid, p.id AS pid, p.`name`, p.price, p.image, c.count, p.stock ' 12 | + 'FROM cart c ' 13 | + 'LEFT JOIN product p ON c.prodId = p.id ' 14 | + 'WHERE c.userId = :userId', 15 | {replacements: {userId: user.userId}, type: sequelize.QueryTypes.SELECT}); 16 | let totalPrice = 0.00; 17 | for (let i = 0; i < qcarts.length; i++) { 18 | let attriValueStr = await productService.getProdAttriValueStr(qcarts[i].pid); 19 | qcarts[i].attriValuesStr = attriValueStr; 20 | totalPrice += qcarts[i].price * qcarts[i].count; 21 | } 22 | var result = new Object(); 23 | result.totalPrice = totalPrice; 24 | result.totalSize = qcarts.length; 25 | result.cartProds = qcarts; 26 | 27 | //console.log(JSON.stringify(result)); 28 | return result; 29 | }, 30 | 31 | //根据id删除一个购物车商品 32 | deleteCardProd: async (id) => { 33 | await cart.destroy({where: {id: parseInt(id)}}); 34 | }, 35 | 36 | //修改购物车商品数量 37 | updateCardProdCount: async (id, count) => { 38 | //let uptRet = await cart.update({count: parseInt(count), updatedAt: Date.now()}, {where: {id: parseInt(id)}}); 39 | //console.log(uptRet[0]); 40 | await sequelize.query('UPDATE cart SET count = :count, updatedAt = now(), version = version + 1 WHERE id = :id', 41 | { replacements: { count: parseInt(count), id: parseInt(id) } }); 42 | }, 43 | 44 | getCardProdNum: async (userId) => { 45 | return await cart.count({where: {userId: userId}}); 46 | }, 47 | 48 | addCartProd: async (pid, pcount, userId) => { 49 | let pcountInt = parseInt(pcount); 50 | let pidInt = parseInt(pid); 51 | 52 | let uptRet = await sequelize.query('UPDATE cart SET count = :count, updatedAt = now(), version = version + 1 WHERE prodId = :prodId AND userId = :userId', 53 | { replacements: { count: pcountInt, prodId: pidInt, userId: userId } }); 54 | if (uptRet[0].affectedRows != 1) { 55 | await cart.create({userId: userId, prodId: pidInt, count: pcountInt}); 56 | } 57 | let cartSize = await cart.count({where: {userId: userId}}); 58 | //console.log("cartSize=" + cartSize); 59 | return cartSize; 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /service/collection-service.js: -------------------------------------------------------------------------------- 1 | //收藏service 2 | const model = require('../middleware/model'); 3 | var sequelize = model.sequelize; 4 | let collection = model.collection; 5 | 6 | module.exports = { 7 | //查询一个收藏 8 | getOneCollection: async (userId, prodId) => { 9 | return await collection.findOne({ 10 | where: { 11 | userId: userId, 12 | prodId: parseInt(prodId) 13 | } 14 | }); 15 | }, 16 | 17 | getCollection: async (userId) => { 18 | return await sequelize.query("SELECT t.id, t.prodId, t1.`name`, t1.price, t1.image, t1.description " 19 | + "FROM collection t " 20 | + "LEFT JOIN product t1 ON t.prodId = t1.id " 21 | + "WHERE t.userId = :userId", 22 | {replacements: {userId: userId}, type: sequelize.QueryTypes.SELECT}); 23 | }, 24 | 25 | collection: async (id, userId, pid) => { 26 | if (id && id.trim() != "") { 27 | await collection.destroy({where: {id: id}}); 28 | } else { 29 | let coll = await collection.create({ 30 | userId: userId, 31 | prodId: parseInt(pid), 32 | }); 33 | return coll.id; 34 | } 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /service/user-service.js: -------------------------------------------------------------------------------- 1 | //用户service 2 | const model = require('../middleware/model'); 3 | const APIError = require('../middleware/rest').APIError; 4 | 5 | let user = model.user; 6 | 7 | module.exports = { 8 | //查询一个用户 9 | getOneUser: async (userCon) => { 10 | let whereObj = new Object(); 11 | if (userCon.mobile) { 12 | whereObj.mobile = userCon.mobile; 13 | } 14 | if (userCon.passwd) { 15 | whereObj.passwd = userCon.passwd; 16 | } 17 | if (userCon.userId) { 18 | whereObj.userId = userCon.userId; 19 | } 20 | let quser = await user.findOne({where: whereObj}); 21 | //let quser = await user.findById(userCon.id); 22 | //let quser = await user.findByPrimary(userCon.id); 23 | return quser; 24 | }, 25 | 26 | countUser: async (userCon) => { 27 | let whereObj = new Object(); 28 | if (userCon.mobile) { 29 | whereObj.mobile = userCon.mobile; 30 | } 31 | if (userCon.userId) { 32 | whereObj.userId = userCon.userId; 33 | } 34 | if (userCon.email) { 35 | whereObj.email = userCon.email; 36 | } 37 | return await user.count({where: whereObj}); 38 | }, 39 | 40 | regist: async (mobile, password) => { 41 | let countInt = await user.count({where: {mobile: mobile}}); 42 | if (countInt > 0) { 43 | throw new APIError('regist:repeat_mobile', '该手机号码已被占用'); 44 | } 45 | let cuser = await user.create({ 46 | mobile: mobile, 47 | userId: mobile, 48 | passwd: password, 49 | name: '墨菲', 50 | headImage: '/static/images/head/bear.jpg' 51 | }); 52 | return cuser; 53 | }, 54 | 55 | checkUserInfo: async (email, userId, id) => { 56 | let result = new Object(); 57 | let whereObj = new Object(); 58 | 59 | if (email && email.trim() != '') { 60 | whereObj.email = email.trim(); 61 | } 62 | if (userId && userId.trim() != '') { 63 | whereObj.userId = userId.trim(); 64 | } 65 | whereObj.id = {$ne: id}; 66 | 67 | result.countInt = await user.count({where: whereObj}); 68 | return result; 69 | }, 70 | 71 | uptUser: async (userCon, userValue) => { 72 | let uptUserInfo = new Object(); 73 | uptUserInfo.updatedAt = Date.now(); 74 | if (userValue.name && userValue.name.trim() != '') { 75 | uptUserInfo.name = userValue.name; 76 | } 77 | if (userValue.userId && userValue.userId.trim() != '') { 78 | uptUserInfo.userId = userValue.userId; 79 | } 80 | if (userValue.email && userValue.email.trim() != '') { 81 | uptUserInfo.email = userValue.email; 82 | } 83 | if (userValue.headImage && userValue.headImage.trim() != '') { 84 | uptUserInfo.headImage = userValue.headImage; 85 | } 86 | if (userValue.passwd && userValue.passwd.trim() != '') { 87 | uptUserInfo.passwd = userValue.passwd; 88 | } 89 | 90 | let whereObj = new Object(); 91 | if (userCon.id) { 92 | whereObj.id = userCon.id; 93 | } 94 | if (userCon.version >= 0) { 95 | whereObj.version = userCon.version; 96 | uptUserInfo.version = userCon.version + 1; 97 | } 98 | 99 | let uptRet = await user.update(uptUserInfo, {where: whereObj}); 100 | console.log('uptSize:' + uptRet[0]); 101 | if (uptRet[0] < 1) { 102 | throw new APIError('uptUserInfo:update_fail', '请稍后重试'); 103 | } 104 | } 105 | }; 106 | -------------------------------------------------------------------------------- /static/css/swipe.css: -------------------------------------------------------------------------------- 1 | /* Swipe 2 required styles */ 2 | .swipe { 3 | overflow: hidden; 4 | visibility: hidden; 5 | position: relative; 6 | } 7 | .swipe-wrap div{ 8 | overflow: hidden; 9 | position: relative; 10 | /*max-height: 350px;*/ 11 | } 12 | .swipe-wrap > div { 13 | float: left; 14 | width: 100%; 15 | position: relative; 16 | } 17 | /* END required styles */ 18 | 19 | .swipe-wrap img { 20 | width: 100%; 21 | } 22 | 23 | .swipe-wrap-circle {position: absolute; z-index: 9999; bottom: 0; left: 50%; margin-left: -5%;} 24 | .swipe-wrap-circle li{float: left; margin-left: 20px;color: #c8c9cb;list-style-type: disc} 25 | .swipe-wrap-circle li:first-child{color: green;} -------------------------------------------------------------------------------- /static/html/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 404 7 | 8 | 9 | 10 | 11 | 12 |
    13 |
    14 |
    商城
    15 |
    16 |
    17 | 18 |
    19 |
    20 |
    21 |

    404

    22 |

    这个页面被我吃掉了,点击返回

    23 |
    24 |
    25 | 31 |
    32 |
    33 | 34 | 35 | -------------------------------------------------------------------------------- /static/html/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 500 7 | 8 | 9 | 10 | 11 | 12 |
    13 |
    14 |
    商城
    15 |
    16 |
    17 | 18 |
    19 |
    20 |
    21 |

    未知错误

    22 |

    抱歉!系统出现错误了,点击返回

    23 |
    24 |
    25 | 31 |
    32 |
    33 | 34 | 35 | -------------------------------------------------------------------------------- /static/html/prod_detail/prod-detial0.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
    -------------------------------------------------------------------------------- /static/images/BuynBtn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/BuynBtn.png -------------------------------------------------------------------------------- /static/images/cart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/cart.png -------------------------------------------------------------------------------- /static/images/cart_bak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/cart_bak.png -------------------------------------------------------------------------------- /static/images/cart_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/cart_on.png -------------------------------------------------------------------------------- /static/images/cart_on_bak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/cart_on_bak.png -------------------------------------------------------------------------------- /static/images/center-icon-dlmm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/center-icon-dlmm.png -------------------------------------------------------------------------------- /static/images/center-icon-dz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/center-icon-dz.png -------------------------------------------------------------------------------- /static/images/center-icon-order-all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/center-icon-order-all.png -------------------------------------------------------------------------------- /static/images/center-icon-order-dfh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/center-icon-order-dfh.png -------------------------------------------------------------------------------- /static/images/center-icon-order-dfk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/center-icon-order-dfk.png -------------------------------------------------------------------------------- /static/images/center-icon-order-dpj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/center-icon-order-dpj.png -------------------------------------------------------------------------------- /static/images/center-icon-order-dsh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/center-icon-order-dsh.png -------------------------------------------------------------------------------- /static/images/center-icon-out.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/center-icon-out.png -------------------------------------------------------------------------------- /static/images/center-icon-sc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/center-icon-sc.png -------------------------------------------------------------------------------- /static/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/favicon.ico -------------------------------------------------------------------------------- /static/images/footer03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/footer03.png -------------------------------------------------------------------------------- /static/images/goods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/goods.png -------------------------------------------------------------------------------- /static/images/goods_bak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/goods_bak.png -------------------------------------------------------------------------------- /static/images/goods_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/goods_on.png -------------------------------------------------------------------------------- /static/images/goods_on_bak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/goods_on_bak.png -------------------------------------------------------------------------------- /static/images/head/bear.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/head/bear.jpg -------------------------------------------------------------------------------- /static/images/icon-back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/icon-back.png -------------------------------------------------------------------------------- /static/images/icon-collection-on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/icon-collection-on.png -------------------------------------------------------------------------------- /static/images/icon-collection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/icon-collection.png -------------------------------------------------------------------------------- /static/images/icon-dele.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/icon-dele.png -------------------------------------------------------------------------------- /static/images/icon-kefu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/icon-kefu.png -------------------------------------------------------------------------------- /static/images/icon_nav_city.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/icon_nav_city.png -------------------------------------------------------------------------------- /static/images/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/index.png -------------------------------------------------------------------------------- /static/images/index_bak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/index_bak.png -------------------------------------------------------------------------------- /static/images/index_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/index_on.png -------------------------------------------------------------------------------- /static/images/index_on_bak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/index_on_bak.png -------------------------------------------------------------------------------- /static/images/location-border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/location-border.png -------------------------------------------------------------------------------- /static/images/menu1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/menu1.png -------------------------------------------------------------------------------- /static/images/menu2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/menu2.png -------------------------------------------------------------------------------- /static/images/menu3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/menu3.png -------------------------------------------------------------------------------- /static/images/menu4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/menu4.png -------------------------------------------------------------------------------- /static/images/my.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/my.png -------------------------------------------------------------------------------- /static/images/my_bak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/my_bak.png -------------------------------------------------------------------------------- /static/images/my_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/my_on.png -------------------------------------------------------------------------------- /static/images/my_on_bak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/my_on_bak.png -------------------------------------------------------------------------------- /static/images/product/content/prod_content1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/content/prod_content1.jpg -------------------------------------------------------------------------------- /static/images/product/content/prod_content10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/content/prod_content10.png -------------------------------------------------------------------------------- /static/images/product/content/prod_content11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/content/prod_content11.png -------------------------------------------------------------------------------- /static/images/product/content/prod_content12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/content/prod_content12.png -------------------------------------------------------------------------------- /static/images/product/content/prod_content13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/content/prod_content13.jpg -------------------------------------------------------------------------------- /static/images/product/content/prod_content2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/content/prod_content2.jpg -------------------------------------------------------------------------------- /static/images/product/content/prod_content3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/content/prod_content3.png -------------------------------------------------------------------------------- /static/images/product/content/prod_content4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/content/prod_content4.png -------------------------------------------------------------------------------- /static/images/product/content/prod_content5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/content/prod_content5.png -------------------------------------------------------------------------------- /static/images/product/content/prod_content6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/content/prod_content6.png -------------------------------------------------------------------------------- /static/images/product/content/prod_content7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/content/prod_content7.png -------------------------------------------------------------------------------- /static/images/product/content/prod_content8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/content/prod_content8.png -------------------------------------------------------------------------------- /static/images/product/content/prod_content9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/content/prod_content9.png -------------------------------------------------------------------------------- /static/images/product/detail/prod_detail0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/detail/prod_detail0.jpg -------------------------------------------------------------------------------- /static/images/product/detail/prod_detail1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/detail/prod_detail1.jpg -------------------------------------------------------------------------------- /static/images/product/detail/prod_detail2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/detail/prod_detail2.jpg -------------------------------------------------------------------------------- /static/images/product/detail/prod_detail3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/detail/prod_detail3.jpg -------------------------------------------------------------------------------- /static/images/product/good1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/good1.jpg -------------------------------------------------------------------------------- /static/images/product/good2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/good2.jpg -------------------------------------------------------------------------------- /static/images/product/good3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/good3.jpg -------------------------------------------------------------------------------- /static/images/product/good4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/good4.jpg -------------------------------------------------------------------------------- /static/images/product/good5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/good5.jpg -------------------------------------------------------------------------------- /static/images/product/good6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/product/good6.jpg -------------------------------------------------------------------------------- /static/images/tophovertree.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/tophovertree.gif -------------------------------------------------------------------------------- /static/images/vcode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/vcode.jpg -------------------------------------------------------------------------------- /static/images/vt/mid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/vt/mid.png -------------------------------------------------------------------------------- /static/images/vt/s1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/vt/s1.png -------------------------------------------------------------------------------- /static/images/vt/s2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/vt/s2.png -------------------------------------------------------------------------------- /static/images/vt/s3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/vt/s3.png -------------------------------------------------------------------------------- /static/images/xuanze.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/halloffamezwx/zshop/9128a34f1b3db3af98e51085f14081826c1fe285/static/images/xuanze.png -------------------------------------------------------------------------------- /static/js/app/cart.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "/static/js/lib", 3 | "paths": { 4 | "publicTip": "/static/js/app/public-tip", 5 | "zepto": "zepto.min" 6 | }, 7 | "shim": { 8 | "jquery.Spinner": ["jquery"] 9 | } 10 | }); 11 | 12 | requirejs(["jquery", "publicTip", "jquery.Spinner"], function($, publicTip){ 13 | $(function() { 14 | $(".Spinner").each(function(){ 15 | var stock = $(this).attr("stock"); 16 | var count = $(this).attr("count"); 17 | var cid = $(this).attr("cid"); 18 | 19 | var max = 5; 20 | if (stock < max) { 21 | max = stock; 22 | } 23 | if (count > max) { 24 | max = count; 25 | } 26 | $(this).Spinner({ 27 | value:count, 28 | len:3, 29 | max:max, 30 | changeValue:changeValue(cid) 31 | }); 32 | 33 | function changeValue(cid) { 34 | return function (newValue, chgFailFun, chgSuccFun) { 35 | publicTip.showLoadingToast(true, "操作中"); 36 | $.ajax({ 37 | type: 'post', 38 | dataType: 'json', 39 | url: '/zshop/userapi/chgCartProdCount', 40 | data: {cid: cid, newValue: newValue} 41 | }).done(function (r) { 42 | chgSuccFun(); 43 | var tPrice = Math.floor(getTotalPrice() * 100) / 100; 44 | $("#totalPrice").html("¥" + tPrice); 45 | publicTip.showLoadingToast(false); 46 | }).fail(function (jqXHR, textStatus) { // Not 200 47 | chgFailFun(); 48 | publicTip.showLoadingToast(false); 49 | publicTip.showTip(jqXHR.responseJSON); 50 | }); 51 | } 52 | } 53 | }); 54 | 55 | $("#cart-all").click(function () { 56 | if ( $(this).prop('checked') ) { 57 | var isLessStock = false; 58 | 59 | $("input[name=cartpro]").each(function () { 60 | var cid = $(this).attr("id").replace(/cart-pto/g, ""); 61 | var cidSpinner = $("#spinner_" + cid); 62 | var count = cidSpinner.find("input").val(); 63 | var stock = cidSpinner.attr("stock"); 64 | 65 | if (parseInt(count) <= parseInt(stock)) { 66 | $(this).prop("checked", true); 67 | } else { 68 | isLessStock = true; 69 | } 70 | }); 71 | if (isLessStock) { 72 | publicTip.showTipForStr("有商品库存不足"); 73 | } 74 | } else { 75 | $("input[name=cartpro]").each(function () { 76 | $(this).prop("checked", false); 77 | }); 78 | } 79 | }); 80 | 81 | $("input[type=checkbox]").click(function () { 82 | var that = this; 83 | var id = $(that).attr("id"); 84 | 85 | if (id != 'cart-all') { 86 | var cid = id.replace(/cart-pto/g, ""); 87 | var cidSpinner = $("#spinner_" + cid); 88 | var count = cidSpinner.find("input").val(); 89 | var stock = cidSpinner.attr("stock"); 90 | 91 | if (parseInt(count) > parseInt(stock)) { 92 | publicTip.showAlert('该商品库存不足', null, function () { 93 | $(that).prop("checked", false); 94 | }); 95 | return; 96 | } 97 | } 98 | 99 | var cartCheckedSize = $("input[name='cartpro']:checked").size(); 100 | var cartSize = 0; //$("input[name='cartpro']").size(); 101 | $("input[name='cartpro']").each(function () { 102 | var cid = $(this).attr("id").replace(/cart-pto/g, ""); 103 | var cidSpinner = $("#spinner_" + cid); 104 | var count = cidSpinner.find("input").val(); 105 | var stock = cidSpinner.attr("stock"); 106 | if (parseInt(count) <= parseInt(stock)) { 107 | cartSize++; 108 | } 109 | }); 110 | 111 | if ( cartCheckedSize >= 1 ) { 112 | $("#settlement").css("background-color", "green"); 113 | } else { 114 | $("#settlement").css("background-color", "gray"); 115 | } 116 | 117 | if (cartCheckedSize == cartSize) { 118 | $("#cart-all").prop("checked", true); 119 | } else { 120 | $("#cart-all").prop("checked", false); 121 | } 122 | var tPrice = Math.floor(getTotalPrice() * 100) / 100; 123 | $("#totalPrice").html("¥" + tPrice); 124 | }); 125 | 126 | var cartSize = $("input[name='cartpro']").size(); 127 | if ( cartSize > 0 ) { 128 | $("#cart-all").click(); 129 | } 130 | 131 | function getTotalPrice(){ 132 | var totalPrice = 0.00; 133 | $('p[id^=pricep_]').each(function(){ 134 | var pricepId = $(this).attr("id"); 135 | var cid = pricepId.split("_")[1]; 136 | var isCheck = $("#cart-pto" + cid).prop('checked'); 137 | 138 | if (isCheck) { 139 | var price = $(this).html().replace(/¥/g, ""); 140 | var count = $("#spinner_" + cid).find("input").val(); 141 | var onePrice = parseFloat(price) * parseInt(count); 142 | totalPrice += onePrice; 143 | } 144 | }); 145 | console.log('totalPrice=' + totalPrice); 146 | return totalPrice; 147 | } 148 | //getTotalPrice(); 149 | 150 | $(".wy-dele").click(function () { 151 | var that = this; 152 | 153 | publicTip.showConfirm('确认删除此商品?', function(){ 154 | var cid = $(that).attr("cid"); 155 | publicTip.showLoadingToast(true, "操作中"); 156 | $.ajax({ 157 | type: 'post', 158 | dataType: 'json', 159 | url: '/zshop/userapi/delCartProd', 160 | data: {cid: cid} 161 | }).done(function (r) { 162 | console.log(JSON.stringify(r)); 163 | window.location.reload(); 164 | }).fail(function (jqXHR, textStatus) { // Not 200 165 | publicTip.showLoadingToast(false); 166 | publicTip.showTip(jqXHR.responseJSON); 167 | }); 168 | }); 169 | 170 | }); 171 | 172 | $("#settlement").click(function () { 173 | var cartIds = ""; 174 | $("input[name='cartpro']:checked").each(function (index) { 175 | var cid = $(this).attr("id").replace(/cart-pto/g, ""); 176 | if (index == 0) { 177 | cartIds = cid; 178 | } else { 179 | cartIds += "," + cid; 180 | } 181 | }); 182 | 183 | publicTip.showLoadingToast(true, "操作中"); 184 | $.ajax({ 185 | type: 'post', 186 | dataType: 'json', 187 | url: '/zshop/userapi/settlementAct', 188 | data: {cartIds: cartIds} 189 | }).done(function (r) { 190 | window.location.href = "/zshop/user/settlement/" + r.orderId; 191 | }).fail(function (jqXHR, textStatus) { // Not 200 192 | publicTip.showLoadingToast(false); 193 | publicTip.showTip(jqXHR.responseJSON); 194 | }); 195 | }); 196 | }); 197 | 198 | }) -------------------------------------------------------------------------------- /static/js/app/collection.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "/static/js/lib", 3 | "paths": { 4 | "publicTip": "/static/js/app/public-tip", 5 | "zepto": "zepto.min" 6 | }, 7 | "shim": { 8 | "jquery.Spinner": ["jquery"] 9 | } 10 | }); 11 | 12 | requirejs(["jquery", "publicTip"], function($, publicTip){ 13 | $(function() { 14 | 15 | }); 16 | }) -------------------------------------------------------------------------------- /static/js/app/index-main.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "/static/js/lib", 3 | "paths": { 4 | "index": "/static/js/app/index", 5 | "publicTip": "/static/js/app/public-tip", 6 | "public": "/static/js/app/public", 7 | "zepto": "zepto.min", 8 | "vue": "vue.min", 9 | "vue-resource": "vue-resource.min" 10 | } 11 | }); 12 | 13 | requirejs(["index"]); -------------------------------------------------------------------------------- /static/js/app/login.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "/static/js/lib", 3 | "paths": { 4 | "publicTip": "/static/js/app/public-tip", 5 | "zepto": "zepto.min" 6 | } 7 | }); 8 | 9 | requirejs(["jquery", "publicTip"], function($, publicTip){ 10 | $(function() { 11 | var $mobile = $("#mobile"); 12 | var $password = $("#password"); 13 | var $captcha = $("#captcha"); 14 | 15 | var openCaptcha = $("#openCaptcha").val(); 16 | var $captchaImg = $("#captchaImg"); 17 | if (openCaptcha == "true") { 18 | $captchaImg.attr("src", '/zshop/captcha?r=' + Math.random()); 19 | $captchaImg.click(function () { 20 | $(this).attr("src", '/zshop/captcha?r=' + Math.random()); 21 | }); 22 | } 23 | 24 | var exgMobile = /^1\d{10}$/; 25 | $mobile.blur(function () { 26 | var mobile = $(this).val(); 27 | if (mobile.trim() == '') { 28 | publicTip.showTipForStr("手机号必填"); 29 | $("#mobileCell").addClass('weui-cell_warn'); 30 | return; 31 | } 32 | if ( !exgMobile.test(mobile) ) { 33 | publicTip.showTipForStr("手机号格式不正确"); 34 | $("#mobileCell").addClass('weui-cell_warn'); 35 | return; 36 | } 37 | $("#mobileCell").removeClass('weui-cell_warn'); 38 | }); 39 | 40 | $password.blur(function () { 41 | var password = $(this).val(); 42 | if (password.trim() == '') { 43 | publicTip.showTipForStr("密码必填"); 44 | $("#passwordCell").addClass('weui-cell_warn'); 45 | return; 46 | } 47 | $("#passwordCell").removeClass('weui-cell_warn'); 48 | }); 49 | 50 | var exgCaptcha = /^\d{4}$/; 51 | if (openCaptcha == "true") { 52 | $captcha.blur(function () { 53 | var captcha = $(this).val(); 54 | if (captcha.trim() == '') { 55 | publicTip.showTipForStr("验证码必填"); 56 | $("#captchaCell").addClass('weui-cell_warn'); 57 | return; 58 | } 59 | if ( !exgCaptcha.test(captcha) ) { 60 | publicTip.showTipForStr("验证码是4位数字"); 61 | $("#captchaCell").addClass('weui-cell_warn'); 62 | return; 63 | } 64 | 65 | $.ajax({ 66 | type: 'post', 67 | dataType: 'json', 68 | url: '/zshop/api/checkCaptcha', 69 | data: {captcha: captcha} 70 | }).done(function (r) { 71 | $("#captchaCell").removeClass('weui-cell_warn'); 72 | }).fail(function (jqXHR, textStatus) { // Not 200 73 | publicTip.showTip(jqXHR.responseJSON); 74 | $("#captchaCell").addClass('weui-cell_warn'); 75 | }); 76 | }); 77 | } 78 | 79 | $("#loginBtn").click(function () { 80 | if ( $("#loginBtn").hasClass('weui-btn_loading') ) { 81 | return; 82 | } 83 | 84 | var mobile = $mobile.val(); 85 | var password = $password.val(); 86 | var captcha = $captcha.val(); 87 | 88 | if (mobile.trim() == '') { 89 | publicTip.showTipForStr("手机号必填"); 90 | $("#mobileCell").addClass('weui-cell_warn'); 91 | return; 92 | } 93 | if ( !exgMobile.test(mobile) ) { 94 | publicTip.showTipForStr("手机号格式不正确"); 95 | $("#mobileCell").addClass('weui-cell_warn'); 96 | return; 97 | } 98 | if (password.trim() == '') { 99 | publicTip.showTipForStr("密码必填"); 100 | $("#passwordCell").addClass('weui-cell_warn'); 101 | return; 102 | } 103 | if (openCaptcha == "true") { 104 | if (captcha.trim() == '') { 105 | publicTip.showTipForStr("验证码必填"); 106 | $("#captchaCell").addClass('weui-cell_warn'); 107 | return; 108 | } 109 | if (!exgCaptcha.test(captcha)) { 110 | publicTip.showTipForStr("验证码是4位数字"); 111 | $("#captchaCell").addClass('weui-cell_warn'); 112 | return; 113 | } 114 | } 115 | 116 | var userReq = { 117 | mobile: mobile, 118 | password: password, 119 | captcha: captcha 120 | }; 121 | 122 | $("#loginBtn").addClass('weui-btn_loading'); 123 | $("#loginLoading").addClass('weui-loading'); 124 | $.ajax({ 125 | type: 'post', 126 | dataType: 'json', 127 | contentType: 'application/json', 128 | url: '/zshop/api/signin', 129 | data: JSON.stringify(userReq) 130 | }).done(function (r) { 131 | console.log(JSON.stringify(r)); 132 | var loginSuccUrl = $("#loginSuccUrl").val(); 133 | if (loginSuccUrl == '') loginSuccUrl = '/zshop/' 134 | window.location.href = loginSuccUrl; 135 | }).fail(function (jqXHR, textStatus) { // Not 200 136 | //publicTip.showTip(jqXHR.responseJSON.message); 137 | //publicTip.showTip(jqXHR.responseText); 138 | publicTip.showTip(jqXHR.responseJSON); 139 | $("#loginBtn").removeClass('weui-btn_loading'); 140 | $("#loginLoading").removeClass('weui-loading'); 141 | 142 | if (openCaptcha == "true" && jqXHR.responseJSON.code != "login:error_captcha") { 143 | $captchaImg.click(); 144 | } 145 | }); 146 | 147 | }); 148 | 149 | }); 150 | 151 | }) -------------------------------------------------------------------------------- /static/js/app/order-detail.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "/static/js/lib", 3 | "paths": { 4 | "publicTip": "/static/js/app/public-tip" 5 | } 6 | }); 7 | 8 | requirejs(["jquery", "publicTip"], function($, publicTip){ 9 | $(function() { 10 | var orderId = $('#orderId').val(); 11 | 12 | $("#wePayBtn").click(function () { 13 | if ( $("#wePayBtn").hasClass('weui-btn_loading') ) { 14 | return; 15 | } 16 | $("#wePayBtn").addClass('weui-btn_loading'); 17 | $("#payLoading").addClass('weui-loading'); 18 | 19 | $.ajax({ 20 | type: 'post', 21 | dataType: 'json', 22 | url: '/zshop/userapi/confirmOrder', 23 | data: {orderId: orderId} 24 | }).done(function (r) { 25 | $("#wePayBtn").removeClass('weui-btn_loading'); 26 | $("#payLoading").removeClass('weui-loading'); 27 | 28 | var confirmMsg = "确认支付" + r.totalPrice + "元!
    截止时间:" + r.payEndTime + "
    "; 29 | publicTip.showConfirm(confirmMsg, function() { 30 | payOrder(r.totalPrice); 31 | }); 32 | }).fail(function (jqXHR, textStatus) { // Not 200 33 | $("#wePayBtn").removeClass('weui-btn_loading'); 34 | $("#payLoading").removeClass('weui-loading'); 35 | 36 | publicTip.showTip(jqXHR.responseJSON); 37 | }); 38 | }); 39 | 40 | function payOrder(totalPrice) { 41 | publicTip.showLoadingToast(true, "支付中"); 42 | $.ajax({ 43 | type: 'post', 44 | dataType: 'json', 45 | url: '/zshop/userapi/payOrder', 46 | data: { 47 | orderId: orderId, 48 | totalPrice: totalPrice 49 | } 50 | }).done(function (r) { 51 | window.location.href = '/zshop/user/paySuccess/' + orderId; 52 | }).fail(function (jqXHR, textStatus) { // Not 200 53 | publicTip.showLoadingToast(false); 54 | publicTip.showTip(jqXHR.responseJSON); 55 | }); 56 | } 57 | 58 | $("#reminderBtn").click(function () { 59 | if ( $("#reminderBtn").hasClass('weui-btn_loading') ) { 60 | return; 61 | } 62 | $("#reminderBtn").addClass('weui-btn_loading'); 63 | $("#reminderLoading").addClass('weui-loading'); 64 | 65 | publicTip.showToast("已提醒"); 66 | 67 | $("#reminderBtn").removeClass('weui-btn_loading'); 68 | $("#reminderLoading").removeClass('weui-loading'); 69 | }); 70 | 71 | $("#confirmBtn").click(function () { 72 | if ( $("#confirmBtn").hasClass('weui-btn_loading') ) { 73 | return; 74 | } 75 | 76 | publicTip.showConfirm("请确认是否已经收到货", function() { 77 | $("#confirmBtn").addClass('weui-btn_loading'); 78 | $("#confirmLoading").addClass('weui-loading'); 79 | 80 | $.ajax({ 81 | type: 'post', 82 | dataType: 'json', 83 | url: '/zshop/userapi/confirmReceipt', 84 | data: {orderId: orderId} 85 | }).done(function (r) { 86 | window.location.reload(); 87 | }).fail(function (jqXHR, textStatus) { // Not 200 88 | $("#confirmBtn").removeClass('weui-btn_loading'); 89 | $("#confirmLoading").removeClass('weui-loading'); 90 | 91 | publicTip.showTip(jqXHR.responseJSON); 92 | }); 93 | }); 94 | }); 95 | 96 | $("#delBtn").click(function () { 97 | if ( $("#delBtn").hasClass('weui-btn_loading') ) { 98 | return; 99 | } 100 | 101 | publicTip.showConfirm("确认删除订单?", function() { 102 | $("#delBtn").addClass('weui-btn_loading'); 103 | $("#delLoading").addClass('weui-loading'); 104 | 105 | $.ajax({ 106 | type: 'post', 107 | dataType: 'json', 108 | url: '/zshop/userapi/delOrder', 109 | data: {orderId: orderId} 110 | }).done(function (r) { 111 | window.location.href = '/zshop/'; 112 | }).fail(function (jqXHR, textStatus) { // Not 200 113 | $("#delBtn").removeClass('weui-btn_loading'); 114 | $("#delLoading").removeClass('weui-loading'); 115 | 116 | publicTip.showTip(jqXHR.responseJSON); 117 | }); 118 | }); 119 | }); 120 | 121 | $("#cancelBtn").click(function () { 122 | if ( $("#cancelBtn").hasClass('weui-btn_loading') ) { 123 | return; 124 | } 125 | 126 | publicTip.showConfirm("确认取消订单?", function() { 127 | $("#cancelBtn").addClass('weui-btn_loading'); 128 | $("#cancelLoading").addClass('weui-loading'); 129 | 130 | $.ajax({ 131 | type: 'post', 132 | dataType: 'json', 133 | url: '/zshop/userapi/cancelOrder', 134 | data: {orderId: orderId} 135 | }).done(function (r) { 136 | window.location.href = '/zshop/'; 137 | }).fail(function (jqXHR, textStatus) { // Not 200 138 | $("#cancelBtn").removeClass('weui-btn_loading'); 139 | $("#cancelLoading").removeClass('weui-loading'); 140 | 141 | publicTip.showTip(jqXHR.responseJSON); 142 | }); 143 | }); 144 | }); 145 | 146 | }); 147 | 148 | }) -------------------------------------------------------------------------------- /static/js/app/order-list.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "/static/js/lib", 3 | "paths": { 4 | "publicTip": "/static/js/app/public-tip", 5 | "zepto": "zepto.min" 6 | }, 7 | "shim": { 8 | "jquery.Spinner": ["jquery"] 9 | } 10 | }); 11 | 12 | requirejs(["jquery", "vue", "vue-resource", "publicTip"], function($, Vue, vueResource, publicTip){ 13 | Vue.use(vueResource); 14 | 15 | $(function() { 16 | var ocVm = new Vue({ 17 | el: '#orderContent', 18 | http: { 19 | timeout: 5000 20 | }, 21 | data: { 22 | sorders: [], 23 | loading: false, 24 | limit: 3, 25 | offset: 0, 26 | hasdata: false, 27 | loadMoreflag: false, 28 | status: parseInt($('#orderStatus').val()) 29 | }, 30 | created: function () { 31 | this.getOrderList(false, null); 32 | }, 33 | methods: { 34 | wePayV: function (orderId) { 35 | wePay(orderId, this.getOrderList); 36 | }, 37 | reminderV: function (orderId) { 38 | reminder(orderId); 39 | }, 40 | confirmV: function (orderId) { 41 | confirm(orderId, this.getOrderList); 42 | }, 43 | delV: function (orderId) { 44 | del(orderId, this.getOrderList); 45 | }, 46 | cancelV: function (orderId) { 47 | cancel(orderId, this.getOrderList); 48 | }, 49 | getOrderList: function (isLoadMore, statusIn) { 50 | var that = this; 51 | that.loading = true; 52 | that.loadMoreflag = isLoadMore; 53 | if (statusIn != null) { 54 | that.status = statusIn; 55 | } 56 | 57 | if (isLoadMore) { 58 | that.offset = that.offset + that.limit; 59 | } else { 60 | that.limit = 3; 61 | that.offset = 0; 62 | } 63 | 64 | that.$resource('/zshop/userapi/getOrderList').save({limit: that.limit, offset: that.offset, status: that.status}).then(function (resp) { 65 | that.loading = false; 66 | var result = resp.json(); 67 | 68 | if (result.length > 0) { 69 | that.hasdata = true; 70 | } else { 71 | that.hasdata = false; 72 | } 73 | 74 | if (isLoadMore) { 75 | that.sorders = that.sorders.concat(result); 76 | } else { 77 | that.sorders = result; 78 | } 79 | }, function (resp) { 80 | that.loading = false; 81 | var respJson = resp.json(); 82 | publicTip.showTipForStr(respJson.message, respJson.code); 83 | }); 84 | } 85 | } 86 | }); 87 | 88 | function wePay(orderId, getOrderList) { 89 | publicTip.showLoadingToast(true, '操作中'); 90 | $.ajax({ 91 | type: 'post', 92 | dataType: 'json', 93 | url: '/zshop/userapi/confirmOrder', 94 | data: {orderId: orderId} 95 | }).done(function (r) { 96 | publicTip.showLoadingToast(false); 97 | var confirmMsg = "确认支付" + r.totalPrice + "元!
    截止时间:" + r.payEndTime + "
    "; 98 | publicTip.showConfirm(confirmMsg, function() { 99 | payOrder(r.totalPrice, getOrderList, orderId); 100 | }); 101 | }).fail(function (jqXHR, textStatus) { // Not 200 102 | publicTip.showLoadingToast(false); 103 | publicTip.showTip(jqXHR.responseJSON); 104 | }); 105 | } 106 | 107 | function payOrder(totalPrice, getOrderList, orderId) { 108 | publicTip.showLoadingToast(true, "支付中"); 109 | $.ajax({ 110 | type: 'post', 111 | dataType: 'json', 112 | url: '/zshop/userapi/payOrder', 113 | data: { 114 | orderId: orderId, 115 | totalPrice: totalPrice 116 | } 117 | }).done(function (r) { 118 | window.location.href = '/zshop/user/paySuccess/' + orderId; 119 | }).fail(function (jqXHR, textStatus) { // Not 200 120 | publicTip.showLoadingToast(false); 121 | publicTip.showTip(jqXHR.responseJSON); 122 | }); 123 | } 124 | 125 | function reminder(orderId) { 126 | publicTip.showToast("已提醒"); 127 | } 128 | 129 | function confirm(orderId, getOrderList) { 130 | publicTip.showConfirm("请确认是否已经收到货", function() { 131 | publicTip.showLoadingToast(true, '操作中'); 132 | 133 | $.ajax({ 134 | type: 'post', 135 | dataType: 'json', 136 | url: '/zshop/userapi/confirmReceipt', 137 | data: {orderId: orderId} 138 | }).done(function (r) { 139 | publicTip.showLoadingToast(false); 140 | getOrderList(false, null); 141 | }).fail(function (jqXHR, textStatus) { // Not 200 142 | publicTip.showLoadingToast(false); 143 | publicTip.showTip(jqXHR.responseJSON); 144 | }); 145 | }); 146 | } 147 | 148 | function del(orderId, getOrderList) { 149 | publicTip.showConfirm("确认删除订单?", function() { 150 | publicTip.showLoadingToast(true, '操作中'); 151 | 152 | $.ajax({ 153 | type: 'post', 154 | dataType: 'json', 155 | url: '/zshop/userapi/delOrder', 156 | data: {orderId: orderId} 157 | }).done(function (r) { 158 | publicTip.showLoadingToast(false); 159 | getOrderList(false, null); 160 | }).fail(function (jqXHR, textStatus) { // Not 200 161 | publicTip.showLoadingToast(false); 162 | publicTip.showTip(jqXHR.responseJSON); 163 | }); 164 | }); 165 | } 166 | 167 | function cancel(orderId, getOrderList) { 168 | publicTip.showConfirm("确认取消订单?", function() { 169 | publicTip.showLoadingToast(true, '操作中'); 170 | 171 | $.ajax({ 172 | type: 'post', 173 | dataType: 'json', 174 | url: '/zshop/userapi/cancelOrder', 175 | data: {orderId: orderId} 176 | }).done(function (r) { 177 | publicTip.showLoadingToast(false); 178 | getOrderList(false, null); 179 | }).fail(function (jqXHR, textStatus) { // Not 200 180 | publicTip.showLoadingToast(false); 181 | publicTip.showTip(jqXHR.responseJSON); 182 | }); 183 | }); 184 | } 185 | 186 | }); 187 | 188 | }) -------------------------------------------------------------------------------- /static/js/app/pay-success.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "/static/js/lib", 3 | "paths": { 4 | "publicTip": "/static/js/app/public-tip" 5 | } 6 | }); 7 | 8 | requirejs(["jquery", "publicTip"], function($, publicTip){ 9 | $(function() { 10 | var orderId = $('#orderId').val(); 11 | 12 | $("#cancelOrderBtn").click(function () { 13 | if ( $("#cancelOrderBtn").hasClass('weui-btn_loading') ) { 14 | return; 15 | } 16 | 17 | publicTip.showConfirm("确认取消订单?", function() { 18 | $("#cancelOrderBtn").addClass('weui-btn_loading'); 19 | $("#cancelOrderLoading").addClass('weui-loading'); 20 | 21 | $.ajax({ 22 | type: 'post', 23 | dataType: 'json', 24 | url: '/zshop/userapi/paySuccCancelOrder', 25 | data: {orderId: orderId} 26 | }).done(function (r) { 27 | $("#cancelOrderBtn").removeClass('weui-btn_loading'); 28 | $("#cancelOrderLoading").removeClass('weui-loading'); 29 | 30 | publicTip.showAlert('将原路退还金额到您的账户', null, function () { 31 | window.location.href = '/zshop/'; 32 | }); 33 | }).fail(function (jqXHR, textStatus) { // Not 200 34 | $("#cancelOrderBtn").removeClass('weui-btn_loading'); 35 | $("#cancelOrderLoading").removeClass('weui-loading'); 36 | 37 | publicTip.showTip(jqXHR.responseJSON); 38 | }); 39 | }); 40 | }); 41 | 42 | }); 43 | 44 | }) -------------------------------------------------------------------------------- /static/js/app/public-tip.js: -------------------------------------------------------------------------------- 1 | define(["jquery"], function($){ 2 | var showAlert = function (msg, iKnowFun, exFun){ 3 | $('#alertDialogContent').html(msg); 4 | //$('#alertDialogTitle').html(result.code); 5 | if (!iKnowFun) { 6 | iKnowFun = function(){ 7 | $('#alertDialogContent').html(''); 8 | $('#alertDialog').hide(); 9 | if (exFun) exFun(); 10 | } 11 | } 12 | $('#iKnow').one('click', iKnowFun); 13 | $('#alertDialog').show(); 14 | } 15 | 16 | var showConfirm = function (msg, confirmFun, cancelFun) { 17 | $('#confirmDialogContent').html(msg); 18 | $('#confirmMain').unbind(); 19 | $('#confirmMain').on('click', function(){ 20 | $('#confirmDialogContent').html(''); 21 | $('#confirmDialog').hide(); 22 | confirmFun(); 23 | }); 24 | if (!cancelFun) { 25 | cancelFun = function(){ 26 | $('#confirmDialogContent').html(''); 27 | $('#confirmDialog').hide(); 28 | } 29 | } 30 | $('#confirmAssist').unbind(); 31 | $('#confirmAssist').on('click', cancelFun); 32 | $('#confirmDialog').show(); 33 | } 34 | 35 | var showError = function (resp) { 36 | resp.json().then(function (result) { 37 | console.log('Error: ' + JSON.stringify(result)); 38 | if (result.code == 'login:must_login') { 39 | var loginSuccUrl = result.loginSuccUrl || window.location.pathname || "/zshop/"; 40 | window.location.href = '/zshop/login?loginSuccUrl=' + loginSuccUrl; 41 | } else { 42 | showAlert(result.message); 43 | } 44 | }); 45 | } 46 | 47 | var tipTimeOutId; 48 | var showTip = function (resp) { 49 | //var msgObj = JSON.parse(msg); 50 | if (resp.code == 'login:must_login') { 51 | var loginSuccUrl = resp.loginSuccUrl || window.location.pathname || "/zshop/"; 52 | window.location.href = '/zshop/login?loginSuccUrl=' + loginSuccUrl; 53 | } else { 54 | $("#errorTip").html(resp.message); 55 | clearTimeout(tipTimeOutId); 56 | //$("#errorTip").show(800); 57 | $("#errorTip").show(); 58 | 59 | tipTimeOutId = setTimeout(function(){ 60 | $("#errorTip").hide(); 61 | $("#errorTip").html(''); 62 | }, 2000); 63 | } 64 | } 65 | var showTipForStr = function (tipMsg, tipCode) { 66 | var msgObj = new Object(); 67 | msgObj.message = tipMsg; 68 | if (tipCode) { 69 | msgObj.code = tipCode; 70 | } 71 | showTip(msgObj); 72 | } 73 | 74 | var showLoadingToast = function (flag, msg) { 75 | if (!msg) { 76 | msg = "数据加载中"; 77 | } 78 | $("#publicLoadingToastContent").html(msg); 79 | if (flag) { 80 | $("#publicLoadingToast").show(); 81 | } else { 82 | $("#publicLoadingToast").hide(); 83 | } 84 | } 85 | 86 | var toastTimeOutId; 87 | var showToast = function (msg) { 88 | if (!msg) { 89 | msg = "已完成"; 90 | } 91 | $("#publicToastContent").html(msg); 92 | clearTimeout(toastTimeOutId); 93 | $("#publicToast").show(); 94 | 95 | toastTimeOutId = setTimeout(function(){ 96 | $("#publicToast").hide(); 97 | $("#publicToastContent").html(''); 98 | }, 1000); 99 | } 100 | 101 | return { 102 | showAlert: showAlert, 103 | showConfirm: showConfirm, 104 | showError: showError, 105 | showTip: showTip, 106 | showTipForStr: showTipForStr, 107 | showLoadingToast: showLoadingToast, 108 | showToast: showToast 109 |   }; 110 | }) 111 | -------------------------------------------------------------------------------- /static/js/app/public.js: -------------------------------------------------------------------------------- 1 | define(function(){ 2 | //获取url中的参数 3 | var getQueryString = function (name) { 4 | var qs = location.search.substr(1), // 获取url中"?"符后的字串 5 | args = {}, // 保存参数数据的对象 6 | items = qs.length ? qs.split("&") : [], // 取得每一个参数项, 7 | item = null, 8 | len = items.length; 9 | 10 | for(var i = 0; i < len; i++) { 11 | item = items[i].split("="); 12 | var name = decodeURIComponent(item[0]), 13 | value = decodeURIComponent(item[1]); 14 | if (name) { 15 | args[name] = value; 16 | } 17 | } 18 | return args; 19 | } 20 | 21 | return { 22 | getQueryString: getQueryString 23 |   }; 24 | }) 25 | -------------------------------------------------------------------------------- /static/js/app/register.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "/static/js/lib", 3 | "paths": { 4 | "publicTip": "/static/js/app/public-tip", 5 | "zepto": "zepto.min" 6 | } 7 | }); 8 | 9 | requirejs(["jquery", "publicTip"], function($, publicTip){ 10 | $(function() { 11 | var $mobile = $("#mobile"); 12 | var $password = $("#password"); 13 | var $passwordConfirm = $("#passwordConfirm"); 14 | 15 | $password.blur(function () { 16 | var password = $(this).val(); 17 | if (password.trim() == '') { 18 | publicTip.showTipForStr("密码必填"); 19 | $("#passwordCell").addClass('weui-cell_warn'); 20 | return; 21 | } 22 | var passwordConfirm = $passwordConfirm.val(); 23 | if (passwordConfirm != '' && passwordConfirm != password) { 24 | publicTip.showTipForStr("密码和确认密码不一致"); 25 | $("#passwordCell").addClass('weui-cell_warn'); 26 | return; 27 | } 28 | $("#passwordCell").removeClass('weui-cell_warn'); 29 | }); 30 | 31 | $passwordConfirm.blur(function () { 32 | var password = $password.val(); 33 | if (password.trim() == '') { 34 | publicTip.showTipForStr("请先输入密码"); 35 | $("#passwordCell").addClass('weui-cell_warn'); 36 | return; 37 | } 38 | var passwordConfirm = $(this).val(); 39 | if (passwordConfirm.trim() == '') { 40 | publicTip.showTipForStr("确认密码必填"); 41 | $("#passwordConfirmCell").addClass('weui-cell_warn'); 42 | return; 43 | } 44 | if (passwordConfirm != password) { 45 | publicTip.showTipForStr("密码和确认密码不一致"); 46 | $("#passwordConfirmCell").addClass('weui-cell_warn'); 47 | return; 48 | } 49 | $("#passwordConfirmCell").removeClass('weui-cell_warn'); 50 | }); 51 | 52 | $mobile.blur(function () { 53 | var mobile = $(this).val(); 54 | if (mobile.trim() == '') { 55 | publicTip.showTipForStr("手机号必填"); 56 | $("#mobileCell").addClass('weui-cell_warn'); 57 | return; 58 | } 59 | if ( !/^1\d{10}$/.test(mobile) ) { 60 | publicTip.showTipForStr("手机号格式不正确"); 61 | $("#mobileCell").addClass('weui-cell_warn'); 62 | return; 63 | } 64 | 65 | $.ajax({ 66 | type: 'post', 67 | dataType: 'json', 68 | url: '/zshop/api/countUserMobile', 69 | data: {mobile: mobile} 70 | }).done(function (r) { 71 | if (r.countInt > 0) { 72 | publicTip.showTipForStr("该手机号码已被占用"); 73 | $("#mobileCell").addClass('weui-cell_warn'); 74 | } else { 75 | $("#mobileCell").removeClass('weui-cell_warn'); 76 | } 77 | }).fail(function (jqXHR, textStatus) { // Not 200 78 | publicTip.showTip(jqXHR.responseJSON); 79 | $("#mobileCell").addClass('weui-cell_warn'); 80 | }); 81 | }); 82 | 83 | $("#confirmBtn").click(function () { 84 | if ( $("#confirmBtn").hasClass('weui-btn_loading') ) { 85 | return; 86 | } 87 | 88 | var mobile = $mobile.val(); 89 | var password = $password.val(); 90 | var passwordConfirm = $passwordConfirm.val(); 91 | 92 | if (mobile.trim() == '') { 93 | publicTip.showTipForStr("手机号必填"); 94 | $("#mobileCell").addClass('weui-cell_warn'); 95 | return; 96 | } 97 | if ( !/^1\d{10}$/.test(mobile) ) { 98 | publicTip.showTipForStr("手机号格式不正确"); 99 | $("#mobileCell").addClass('weui-cell_warn'); 100 | return; 101 | } 102 | if (password.trim() == '') { 103 | publicTip.showTipForStr("密码必填"); 104 | $("#passwordCell").addClass('weui-cell_warn'); 105 | return; 106 | } 107 | if (passwordConfirm.trim() == '') { 108 | publicTip.showTipForStr("确认密码必填"); 109 | $("#passwordConfirmCell").addClass('weui-cell_warn'); 110 | return; 111 | } 112 | if (password != passwordConfirm) { 113 | publicTip.showTipForStr("密码和确认密码不一致"); 114 | $("#passwordCell").addClass('weui-cell_warn'); 115 | $("#passwordConfirmCell").addClass('weui-cell_warn'); 116 | return; 117 | } 118 | 119 | var userReq = { 120 | mobile: mobile, 121 | password: password, 122 | passwordConfirm: passwordConfirm 123 | }; 124 | 125 | $("#confirmBtn").addClass('weui-btn_loading'); 126 | $("#confirmLoading").addClass('weui-loading'); 127 | $.ajax({ 128 | type: 'post', 129 | dataType: 'json', 130 | contentType: 'application/json', 131 | url: '/zshop/api/regist', 132 | data: JSON.stringify(userReq) 133 | }).done(function (r) { 134 | window.location.href = '/zshop?actTabbar=my'; 135 | }).fail(function (jqXHR, textStatus) { // Not 200 136 | publicTip.showTip(jqXHR.responseJSON); 137 | if (jqXHR.responseJSON.code == 'regist:repeat_mobile') { 138 | $("#mobileCell").addClass('weui-cell_warn'); 139 | } 140 | $("#confirmBtn").removeClass('weui-btn_loading'); 141 | $("#confirmLoading").removeClass('weui-loading'); 142 | }); 143 | 144 | }); 145 | 146 | }); 147 | 148 | }) -------------------------------------------------------------------------------- /static/js/app/settlement.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "/static/js/lib", 3 | "paths": { 4 | "publicTip": "/static/js/app/public-tip" 5 | } 6 | }); 7 | 8 | requirejs(["jquery", "publicTip"], function($, publicTip){ 9 | $(function() { 10 | var orderId = $('#orderId').val(); 11 | 12 | $("#wePayBtn").click(function () { 13 | if ( $("#wePayBtn").hasClass('weui-btn_loading') ) { 14 | return; 15 | } 16 | $("#wePayBtn").addClass('weui-btn_loading'); 17 | $("#payLoading").addClass('weui-loading'); 18 | 19 | $.ajax({ 20 | type: 'post', 21 | dataType: 'json', 22 | url: '/zshop/userapi/confirmOrder', 23 | data: {orderId: orderId} 24 | }).done(function (r) { 25 | $("#wePayBtn").removeClass('weui-btn_loading'); 26 | $("#payLoading").removeClass('weui-loading'); 27 | 28 | var confirmMsg = "确认支付" + r.totalPrice + "元!
    截止时间:" + r.payEndTime + "
    "; 29 | publicTip.showConfirm(confirmMsg, function() { 30 | payOrder(r.totalPrice); 31 | }); 32 | }).fail(function (jqXHR, textStatus) { // Not 200 33 | $("#wePayBtn").removeClass('weui-btn_loading'); 34 | $("#payLoading").removeClass('weui-loading'); 35 | 36 | publicTip.showTip(jqXHR.responseJSON); 37 | }); 38 | }); 39 | 40 | function payOrder(totalPrice) { 41 | publicTip.showLoadingToast(true, "支付中"); 42 | $.ajax({ 43 | type: 'post', 44 | dataType: 'json', 45 | url: '/zshop/userapi/payOrder', 46 | data: { 47 | orderId: orderId, 48 | totalPrice: totalPrice 49 | } 50 | }).done(function (r) { 51 | window.location.href = '/zshop/user/paySuccess/' + orderId; 52 | }).fail(function (jqXHR, textStatus) { // Not 200 53 | publicTip.showLoadingToast(false); 54 | publicTip.showTip(jqXHR.responseJSON); 55 | }); 56 | } 57 | }); 58 | 59 | }) -------------------------------------------------------------------------------- /static/js/app/upt-pass.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | "baseUrl": "/static/js/lib", 3 | "paths": { 4 | "publicTip": "/static/js/app/public-tip" 5 | } 6 | }); 7 | 8 | requirejs(["jquery", "publicTip"], function($, publicTip){ 9 | $(function() { 10 | var $password = $("#password"); 11 | var $passwordConfirm = $("#passwordConfirm"); 12 | var $oldPassword = $("#oldPassword"); 13 | 14 | $password.blur(function () { 15 | var password = $(this).val(); 16 | if (password.trim() == '') { 17 | publicTip.showTipForStr("新的密码必填"); 18 | $("#passwordCell").addClass('weui-cell_warn'); 19 | return; 20 | } 21 | var passwordConfirm = $passwordConfirm.val(); 22 | if (passwordConfirm != '' && passwordConfirm != password) { 23 | publicTip.showTipForStr("新的密码和确认密码不一致"); 24 | $("#passwordCell").addClass('weui-cell_warn'); 25 | return; 26 | } 27 | $("#passwordCell").removeClass('weui-cell_warn'); 28 | }); 29 | 30 | $passwordConfirm.blur(function () { 31 | var password = $password.val(); 32 | if (password.trim() == '') { 33 | publicTip.showTipForStr("请先输入新的密码"); 34 | $("#passwordCell").addClass('weui-cell_warn'); 35 | return; 36 | } 37 | var passwordConfirm = $(this).val(); 38 | if (passwordConfirm.trim() == '') { 39 | publicTip.showTipForStr("确认密码必填"); 40 | $("#passwordConfirmCell").addClass('weui-cell_warn'); 41 | return; 42 | } 43 | if (passwordConfirm != password) { 44 | publicTip.showTipForStr("新的密码和确认密码不一致"); 45 | $("#passwordConfirmCell").addClass('weui-cell_warn'); 46 | return; 47 | } 48 | $("#passwordConfirmCell").removeClass('weui-cell_warn'); 49 | }); 50 | 51 | $oldPassword.blur(function () { 52 | var oldPassword = $(this).val(); 53 | if (oldPassword.trim() == '') { 54 | publicTip.showTipForStr("原的密码必填"); 55 | $("#oldPasswordCell").addClass('weui-cell_warn'); 56 | return; 57 | } 58 | 59 | $.ajax({ 60 | type: 'post', 61 | dataType: 'json', 62 | url: '/zshop/userapi/checkPassword', 63 | data: {oldPassword: oldPassword} 64 | }).done(function (r) { 65 | $("#oldPasswordCell").removeClass('weui-cell_warn'); 66 | }).fail(function (jqXHR, textStatus) { // Not 200 67 | publicTip.showTip(jqXHR.responseJSON); 68 | $("#oldPasswordCell").addClass('weui-cell_warn'); 69 | }); 70 | }); 71 | 72 | $("#confirmBtn").click(function () { 73 | if ( $("#confirmBtn").hasClass('weui-btn_loading') ) { 74 | return; 75 | } 76 | 77 | var oldPassword = $oldPassword.val(); 78 | var password = $password.val(); 79 | var passwordConfirm = $passwordConfirm.val(); 80 | 81 | if (oldPassword.trim() == '') { 82 | publicTip.showTipForStr("原的密码必填"); 83 | $("#oldPasswordCell").addClass('weui-cell_warn'); 84 | return; 85 | } 86 | if (password.trim() == '') { 87 | publicTip.showTipForStr("新的密码必填"); 88 | $("#passwordCell").addClass('weui-cell_warn'); 89 | return; 90 | } 91 | if (passwordConfirm.trim() == '') { 92 | publicTip.showTipForStr("确认密码必填"); 93 | $("#passwordConfirmCell").addClass('weui-cell_warn'); 94 | return; 95 | } 96 | if (password != passwordConfirm) { 97 | publicTip.showTipForStr("新的密码和确认密码不一致"); 98 | $("#passwordCell").addClass('weui-cell_warn'); 99 | $("#passwordConfirmCell").addClass('weui-cell_warn'); 100 | return; 101 | } 102 | 103 | var userReq = { 104 | oldPassword: oldPassword, 105 | password: password, 106 | passwordConfirm: passwordConfirm 107 | }; 108 | 109 | $("#confirmBtn").addClass('weui-btn_loading'); 110 | $("#confirmLoading").addClass('weui-loading'); 111 | $.ajax({ 112 | type: 'post', 113 | dataType: 'json', 114 | contentType: 'application/json', 115 | url: '/zshop/userapi/uptPass', 116 | data: JSON.stringify(userReq) 117 | }).done(function (r) { 118 | publicTip.showConfirm('修改成功!重新登录?', function(){ 119 | window.location.href = "/zshop/login"; 120 | }); 121 | $("#confirmBtn").removeClass('weui-btn_loading'); 122 | $("#confirmLoading").removeClass('weui-loading'); 123 | }).fail(function (jqXHR, textStatus) { // Not 200 124 | publicTip.showTip(jqXHR.responseJSON); 125 | if (jqXHR.responseJSON.code == 'index:error_password') { 126 | $("#oldPasswordCell").addClass('weui-cell_warn'); 127 | } 128 | $("#confirmBtn").removeClass('weui-btn_loading'); 129 | $("#confirmLoading").removeClass('weui-loading'); 130 | }); 131 | 132 | }); 133 | 134 | }); 135 | 136 | }) -------------------------------------------------------------------------------- /static/js/lib/jquery.Spinner.js: -------------------------------------------------------------------------------- 1 | /* jQuery.Spinner V1.0 CopyRight (c) 2014 by:Loyaoo Taobao:http://isseven.taobao.com */ 2 | 3 | (function($) { 4 | 5 | $.fn.Spinner = function (opts) { 6 | 7 | var defaults = {value:1, min:1, len:3, max:99} 8 | var options = $.extend(defaults, opts) 9 | var keyCodes = {up:38, down:40} 10 | return this.each(function() { 11 | 12 | var a = $(''); f(a,0,"Decrease","-"); //减 13 | var c = $(''); f(c,0,"Increase","+"); //加 14 | var b = $('');f(b,1,"Amount");cv(0); //值 15 | var oldValue = b.val(); 16 | 17 | $(this).append(a).append(b).append(c); 18 | a.click(function(){ 19 | var isNotDisabled = a.hasClass('Decrease'); 20 | cv(-1); 21 | if (opts.changeValue && isNotDisabled) { 22 | opts.changeValue(b.val(), function (){cv(+1);}, function (){oldValue = b.val();}); 23 | } 24 | }); 25 | b.keyup(function(){cv(0);}); 26 | c.click(function(){ 27 | var isNotDisabled = c.hasClass('Increase'); 28 | cv(+1); 29 | if (opts.changeValue && isNotDisabled) { 30 | opts.changeValue(b.val(), function (){cv(-1);}, function (){oldValue = b.val();}); 31 | } 32 | }); 33 | b.change(function(){ 34 | if (opts.changeValue) { 35 | opts.changeValue(b.val(), function (){b.val(oldValue);cv(0);}, function (){oldValue = b.val();}); 36 | } 37 | }); 38 | b.bind('keyup paste change',function(e){ 39 | e.keyCode==keyCodes.up&&cv(+1); 40 | e.keyCode==keyCodes.down&&cv(-1); 41 | }); 42 | 43 | function cv(n){ 44 | b.val(b.val().replace(/[^\d]/g,'')); 45 | bv=parseInt(b.val()||options.min)+n; 46 | bv>=options.min&&bv<=options.max&&b.val(bv); 47 | if(bv<=options.min){b.val(options.min);f(a,2,"DisDe","Decrease");}else{f(a,2,"Decrease","DisDe");} 48 | if(bv>=options.max){b.val(options.max);f(c,2,"DisIn","Increase");}else{f(c,2,"Increase","DisIn");} 49 | } 50 | 51 | }); 52 | 53 | function f(o,t,c,s){ 54 | t==0&&o.addClass(c).attr("href","javascript:void(0)").append("").find("i").append(s); 55 | t==1&&o.addClass(c).attr({"value":options.value,"autocomplete":"off","maxlength":options.len}); 56 | t==2&&o.addClass(c).removeClass(s); 57 | } 58 | } 59 | 60 | })(jQuery); -------------------------------------------------------------------------------- /utils/common.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = { 3 | sleep: function (time) { 4 | return new Promise(function (resolve, reject) { 5 | setTimeout(function () { 6 | resolve('ok'); 7 | //reject('error'); //模拟出错了,返回 ‘error’ 8 | }, time); 9 | }) 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /views/cart.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 购物车 7 | 8 | 9 | 10 | 19 | 20 | 21 | 22 |
    23 |
    24 |
    购物车
    25 |
    26 |
    27 | 28 |
    29 |
    30 |
    31 | {% for ucp in cartProds %} 32 |
    33 |
    34 | 37 |
    38 | 39 | 40 | 41 |
    42 |

    {{ucp.name}}

    43 |

    {{ucp.attriValuesStr}}

    44 |
    库存 {{ucp.stock}} 件
    45 |

    ¥{{ucp.price}}

    46 |
    47 |
    48 |
    49 | 50 |
    51 |
    52 |
    53 |
    54 | {% endfor %} 55 |
    56 |
    57 | {% if totalSize == 0 %} 58 | 61 | {% endif %} 62 |
    63 | 64 | {% if totalSize > 0 %} 65 |
    66 |
    67 | 70 |
    71 |
    72 | 总计 : ¥{{totalPrice}} 73 |
    74 | 75 | 结算 76 | 77 |
    78 | {% endif %} 79 | 80 | {% include "public-tip.html" %} 81 | 82 | 83 | -------------------------------------------------------------------------------- /views/collection.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 我的收藏 7 | 8 | 9 | 10 | 19 | 20 | 21 | 22 |
    23 |
    24 |
    我的收藏
    25 |
    26 |
    27 | 28 |
    29 |
    30 |
    31 | {% for c in collections %} 32 |
    33 | 34 | 35 | 36 |
    37 |

    {{c.name}}

    38 |

    {{c.description}}

    39 |

    ¥{{c.price}}

    40 |
    41 |
    42 |
    43 | 44 |
    45 |
    46 |
    47 | {% endfor %} 48 |
    49 |
    50 | {% if collections.length == 0 %} 51 | 54 | {% endif %} 55 |
    56 | 57 | {% include "public-tip.html" %} 58 | 59 | 60 | -------------------------------------------------------------------------------- /views/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 登录 7 | 8 | 9 | 10 | 15 | 16 | 17 | 18 |
    19 |
    20 |
    登录商城
    21 |
    22 |
    23 | 24 |
    25 |
    26 |
    27 |
    28 | 29 |
    30 |
    31 | 32 |
    33 |
    34 | 42 |
    43 |
    44 |
    45 | 46 |
    47 |
    48 | 49 |
    50 |
    51 |
    52 |
    53 |
    54 | 55 |
    56 |
    57 | 58 |
    59 |
    60 | {% if openCaptcha %} 61 | 62 | {% else %} 63 | 64 | {% endif %} 65 |
    66 |
    67 |
    68 |
    69 | 70 |
    71 | 登 录 72 | 注 册 73 |
    74 | 75 | 85 | 86 |
    87 | 88 |
    89 | 92 |
    93 | 94 | 95 | 96 | {% include "public-tip.html" %} 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /views/msg.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 消息提示 7 | 8 | 9 | 10 | 11 | 12 |
    13 |
    14 |
    系统提示
    15 |
    16 |
    17 | 18 |
    19 |
    20 |

    {{msg}},点击刷新

    21 |
    22 |
    23 | 29 |
    30 |
    31 | 32 | 33 | -------------------------------------------------------------------------------- /views/pay-success.html: -------------------------------------------------------------------------------- 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 |
    31 |
    32 | 38 |
    39 |
    40 | 41 | 42 | 43 | {% include "public-tip.html" %} 44 | 45 | 46 | -------------------------------------------------------------------------------- /views/public-tip.html: -------------------------------------------------------------------------------- 1 |
    错误提示
    2 | 3 | 13 | 14 | 25 | 26 | 33 | 34 | -------------------------------------------------------------------------------- /views/register.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 注册 7 | 8 | 9 | 10 | 15 | 16 | 17 | 18 |
    19 |
    20 |
    注册
    21 |
    22 |
    23 | 24 |
    25 |
    26 |
    27 |
    28 |
    29 | 30 |
    31 |
    32 | 33 |
    34 |
    35 | 36 |
    37 |
    38 |
    39 | 40 |
    41 |
    42 | 43 |
    44 |
    45 |
    46 |
    47 |
    48 | 49 |
    50 |
    51 | 52 |
    53 |
    54 | 55 |
    56 |
    57 | 58 |
    59 |
    60 | 获取验证码 61 |
    62 |
    63 | 64 |
    65 |
    66 | 67 |
    68 | 69 | 确 定 70 | 登 录 71 |
    72 |
    73 |
    74 | 75 |
    76 | 79 |
    80 | 81 | {% include "public-tip.html" %} 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /views/reset-pass.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 密码重置 7 | 8 | 9 | 14 | 15 | 16 | 17 |
    18 |
    19 |
    密码重置
    20 |
    21 |
    22 | 23 |
    24 |
    25 |
    26 |
    27 |
    28 | 29 |
    30 |
    31 | 32 |
    33 |
    34 | 35 |
    36 |
    37 |
    38 | 39 |
    40 |
    41 | 42 |
    43 |
    44 | 45 |
    46 |
    47 | 48 |
    49 |
    50 | 获取验证码 51 |
    52 |
    53 | 54 |
    55 |
    56 | 57 |
    58 | 59 | 确 定 60 |
    61 |
    62 |
    63 | 64 |
    65 | 68 |
    69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /views/settlement.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 结算 7 | 8 | 9 | 10 | 18 | 19 | 20 | 21 |
    22 |
    23 |
    结算
    24 |
    25 |
    26 | 27 |
    28 | 40 | 41 | 42 | 43 | 64 | 65 |
    66 |
    67 |
    68 |

    配送方式

    69 |
    70 |
    {{order.deliveryTypeName}}
    71 |
    72 |
    73 | 74 |
    75 |
    76 |
    77 |

    商品金额

    78 |
    79 |
    ¥{{order.prodPrice}}
    80 |
    81 |
    82 |
    83 |

    物流运费

    84 |
    85 |
    + ¥{{order.deliveryFee}}
    86 |
    87 |
    88 |
    89 |

    总的金额

    90 |
    91 |
    ¥{{order.totalPrice}}
    92 |
    93 | 94 |
    95 | 微信支付 96 |
    97 |
    98 | 99 |
    100 | {% include "public-tip.html" %} 101 | 102 | 103 | -------------------------------------------------------------------------------- /views/upt-pass.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 密码修改 7 | 8 | 9 | 10 | 15 | 16 | 17 | 18 |
    19 |
    20 |
    密码修改
    21 |
    22 |
    23 | 24 |
    25 |
    26 |
    27 |
    28 |
    29 | 30 |
    31 |
    32 | 33 |
    34 |
    35 | 36 |
    37 |
    38 |
    39 | 40 |
    41 |
    42 | 43 |
    44 |
    45 | 46 |
    47 |
    48 |
    49 | 50 |
    51 |
    52 | 53 |
    54 |
    55 | 56 |
    57 |
    58 | 59 |
    60 | 61 | 确 定 62 |
    63 |
    64 |
    65 | 66 |
    67 | 70 |
    71 | {% include "public-tip.html" %} 72 | 73 | 74 | -------------------------------------------------------------------------------- /views/user.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 用户 7 | 8 | 9 | 10 | 24 | 25 | 26 | 27 |
    28 |
    29 |
    用户
    30 |
    31 |
    32 | 33 |
    34 |
    35 |
    36 |
    37 |
    38 | 39 |
    40 |
    41 | 42 |
    43 |
    44 |
    45 |
    46 |
    47 | 48 |
    49 |
    50 | 51 |
    52 |
    53 | 54 |
    55 |
    56 |
    57 | 58 |
    59 |
    60 | 61 |
    62 |
    63 | 64 | 72 | 73 |
    74 | 78 |
    79 |
    80 |
    81 |
      82 |
    • 83 |
    84 |
    85 |
    86 |
    87 | 88 |
    89 |
    90 | 91 |
    92 | 93 | 确 定 94 |
    95 |
    96 |
    97 | 98 |
    99 | 102 |
    103 | {% include "public-tip.html" %} 104 | 105 | 106 | --------------------------------------------------------------------------------