├── .gitignore ├── README.md ├── app.js ├── config.js ├── controllers ├── address │ └── index.js ├── brand │ └── index.js ├── cart │ └── index.js ├── category │ └── index.js ├── collect │ └── index.js ├── comment │ └── index.js ├── feedback │ └── index.js ├── goods │ └── index.js ├── home │ └── index.js ├── index.js ├── order │ └── index.js ├── search │ └── index.js └── topic │ └── index.js ├── middlewares └── response.js ├── mysql.js ├── nideshop_ad ├── nodemon.json ├── nodemysql.sql ├── package.json ├── process.prod.json ├── routes └── index.js └── tools.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | *.suo 11 | *.ntvs* 12 | *.njsproj 13 | *.sln 14 | package-lock.json 15 | study.code-workspace 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # 为了快速让学习者搭建本地的服务,现在对程序进行了修改 3 | 4 | 1. **删除了对wafer2的依赖,删除了小程序登陆等相关的** 5 | 2. **数据库中存了一个用户数据,供接口使用,无需掉登陆** 6 | 7 | 8 | ## 下载源码 9 | git clone https://github.com/heyushuo/mpvue-shop-node.git 10 | 11 | ## 开始使用 12 | 13 | ### 1.项目开始前本机安装mysql5.7版本,然后创建数据库nodemysql并导入项目根目录下的nodemysql.sql 14 | 15 | ### 2.项目根目录有一个config.js文件,在这里可以配置数据库相关信息账号密码等 16 | ```javascript 17 | mysql: { 18 | host: 'localhost', 19 | port: 3306, 20 | user: '', 21 | db: 'nodemysql', //数据库名字 22 | pass: '', //数据库密码 23 | char: 'utf8mb4' 24 | }; 25 | ``` 26 | #### 安装依赖 27 | npm install 28 | 29 | #### 启动项目 30 | npm run dev 31 | 32 | # 项目目录结构 # 33 | 1.mysql.js存放对knex的引用(用来操作数据库使用) 34 | 35 | 2.本项目所有的业务逻辑都在**controllers**文件夹中 36 | 37 | 3.本项目所有的接口都写在**router文件夹下的index.js**里边 38 | ```javascript 39 | //首页数据 40 | //1.首页 41 | router.get('/index/index', controllers.home.index) 42 | //2.首页品牌制造商直供的详情内的列表数据 43 | router.get('/brand/listaction', controllers.brand.index.listAction) 44 | //3.首页品牌制造商直供的详情数据 45 | router.get('/brand/detailaction', controllers.brand.index.detailAction) 46 | 47 | 48 | /** 49 | * 分类 50 | */ 51 | //1.分类和子类 52 | router.get('/category/indexaction', controllers.category.index.indexAction) 53 | //2.通过分类的id来查询子类接口 54 | router.get('/category/currentaction', controllers.category.index.currentAction) 55 | //3.获取导航数据 56 | router.get('/category/categoryNav', controllers.category.index.categoryNav) 57 | 58 | 59 | /** 60 | * 商品相关接口 61 | */ 62 | //1.商品详情接口 63 | router.get('/goods/detailaction', controllers.goods.index.detailAction) 64 | //2.获取商品列表 65 | router.get('/goods/goodsList', controllers.goods.index.goodsList) 66 | 67 | 68 | /** 69 | * 专题接口 70 | */ 71 | //1.列表 72 | router.get('/topic/listaction', controllers.topic.index.listAction) 73 | //2.详情加下方四个专题推荐 74 | router.get('/topic/detailaction', controllers.topic.index.detailAction) 75 | 76 | 77 | /** 78 | * 搜索相关接口 79 | */ 80 | //1.关键词和搜索历史接口 81 | router.get('/search/indexaction', controllers.search.index.indexAction) 82 | //2.搜索提示接口 83 | router.get('/search/helperaction', controllers.search.index.helperAction) 84 | //3.搜索的关键词添加到数据库 85 | router.post('/search/addhistoryaction', controllers.search.index.addHistoryAction) 86 | //4.清空搜索历史 87 | router.post('/search/clearhistoryAction', controllers.search.index.clearhistoryAction) 88 | 89 | 90 | /** 91 | * 收藏相关接口 92 | */ 93 | //1.添加收藏 94 | router.post('/collect/addcollect', controllers.collect.index.addCollect) 95 | //2.获取收藏列表 96 | router.get('/collect/listAction', controllers.collect.index.listAction) 97 | //2.获取收藏列表 98 | router.get('/collect/deleteCollect', controllers.collect.index.deleteCollect) 99 | 100 | /** 101 | * 购物车相关接口 102 | */ 103 | //1.添加购物车 104 | router.post('/cart/addCart', controllers.cart.index.addCart) 105 | //2.购物车列表 106 | router.get('/cart/cartList', controllers.cart.index.cartList) 107 | //3.删除商品 108 | router.get('/cart/deleteAction', controllers.cart.index.deleteAction) 109 | 110 | 111 | /** 112 | * 订单相关 113 | */ 114 | router.post('/order/submitAction', controllers.order.index.submitAction) 115 | 116 | router.get('/order/detailAction', controllers.order.index.detailAction) 117 | /** 118 | * 收货地址相关接口 119 | */ 120 | //1.保存和跟新收货地址 121 | router.post('/address/saveAction', controllers.address.index.saveAction) 122 | //2.获取收货地址列表 123 | router.get('/address/getListAction', controllers.address.index.getListAction) 124 | //3.获取收货地址详情 125 | router.get('/address/detailAction', controllers.address.index.detailAction) 126 | //4.删除收货地址 127 | router.get('/address/deleteAction', controllers.address.index.deleteAction) 128 | 129 | 130 | /** 131 | * 意见反馈 132 | */ 133 | router.post('/feedback/submitAction', controllers.feedback.index.submitAction) 134 | ``` 135 | 136 | # 如果需要小程序登陆的可以看,腾讯提供的小程序node解决方案 # 137 | ## [ Wafer2 Node.js Demo](https://github.com/tencentyun/wafer2-quickstart-nodejs) ## 138 | 139 | # 下方为微信小程序效果展示 # 140 | ### 1.首页展示和专题页效果 141 | ![](https://user-gold-cdn.xitu.io/2018/8/27/165793588dd8808f?w=323&h=571&f=gif&s=3649872) 142 | ![](https://user-gold-cdn.xitu.io/2018/8/25/165717735a9e3c60?w=327&h=573&f=gif&s=3983502) 143 | ### 2、分类页面,分类子页面以及搜索功能、搜索列表、历史记录、模糊搜索提示 144 | ![](https://user-gold-cdn.xitu.io/2018/8/25/1657185090f5d3cd?w=327&h=573&f=gif&s=884918) 145 | ![](https://user-gold-cdn.xitu.io/2018/8/25/1657188bf2746d85?w=327&h=573&f=gif&s=585295) 146 | ### 3、购物车功能添加购物车,单选多选,删除和商品收藏功能 147 | ![](https://user-gold-cdn.xitu.io/2018/8/25/165719656d9bdb5b?w=327&h=573&f=gif&s=1979300) 148 | ![](https://user-gold-cdn.xitu.io/2018/8/25/165719e76bd00f05?w=327&h=573&f=gif&s=1770550) 149 | ### 4、地址管理 150 | ![](https://user-gold-cdn.xitu.io/2018/8/25/165719e2d9b28ee1?w=327&h=573&f=gif&s=611343) 151 | 152 | # 小程序端传送门 [点击进入小程序地址](https://github.com/heyushuo/mpvue-shop) 153 | # 最后 # 154 | - 喜欢的记得点个start,鼓励一下谢谢哈!! 155 | - 微信号 hys838723 156 | - qq群号 647099996 -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa') 2 | const app = new Koa() 3 | const debug = require('debug')('koa-weapp-demo') 4 | const response = require('./middlewares/response') 5 | const bodyParser = require('koa-bodyparser') 6 | const config = require('./config') 7 | // 使用响应处理中间件 8 | app.use(response) 9 | // 解析请求体 10 | app.use(bodyParser()) 11 | // 引入路由分发 12 | const router = require('./routes') 13 | app.use(router.routes()) // 添加路由中间件 14 | // 启动程序,监听端口 15 | app.listen(config.port, () => debug(`listening on port ${config.port}`)) -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | const CONF = { 2 | //开启服务的端口 3 | port: '5757', 4 | /** 5 | * MySQL 配置 6 | */ 7 | mysql: { 8 | host: 'localhost', 9 | port: 3306, 10 | user: '', 11 | db: 'nodemysql', 12 | pass: '', 13 | char: 'utf8mb4' 14 | } 15 | } 16 | 17 | module.exports = CONF -------------------------------------------------------------------------------- /controllers/address/index.js: -------------------------------------------------------------------------------- 1 | const { 2 | mysql 3 | } = require("../../mysql"); 4 | 5 | /** 6 | * 添加或者跟新收货地址 7 | * @param {*} ctx 8 | */ 9 | async function saveAction(ctx) { 10 | var addressId = ctx.request.body.addressId; 11 | const { 12 | userName, 13 | telNumber, 14 | address, 15 | detailadress, 16 | checked, 17 | openId 18 | } = ctx.request.body; 19 | 20 | //如果是默认选中 21 | //先在数据库查询是否默认的地址 22 | if (checked) { 23 | const isDefault = await mysql("nideshop_address").where({ 24 | user_id: openId, 25 | is_default: 1 26 | }); 27 | if (isDefault.length > 0) { 28 | await mysql("nideshop_address") 29 | .where({ 30 | user_id: openId, 31 | is_default: 1 32 | }) 33 | .update({ 34 | is_default: 0 35 | }); 36 | } 37 | } 38 | 39 | 40 | if (!addressId) { 41 | //添加地址 42 | const data = await mysql("nideshop_address").insert({ 43 | name: userName, 44 | mobile: telNumber, 45 | address: address, 46 | address_detail: detailadress, 47 | user_id: openId, 48 | is_default: checked == "true" || checked ? 1 : 0 49 | }); 50 | if (data) { 51 | ctx.body = { 52 | data: true 53 | }; 54 | } else { 55 | ctx.body = { 56 | data: false 57 | }; 58 | } 59 | } else { 60 | // console.log(checked == "true" || checked ? 1 : 0); 61 | // console.log(addressId); 62 | 63 | //跟新地址 64 | const data = await mysql("nideshop_address") 65 | .where({ 66 | id: addressId 67 | }) 68 | .update({ 69 | name: userName, 70 | mobile: telNumber, 71 | address: address, 72 | address_detail: detailadress, 73 | user_id: openId, 74 | is_default: checked == "true" || checked ? 1 : 0 75 | }); 76 | if (data) { 77 | ctx.body = { 78 | data: true 79 | }; 80 | } else { 81 | ctx.body = { 82 | data: false 83 | }; 84 | } 85 | } 86 | } 87 | 88 | /** 89 | * 收货地址列表 90 | * @param {*} ctx 91 | */ 92 | async function getListAction(ctx) { 93 | var openId = ctx.query.openId; 94 | const addressList = await mysql("nideshop_address") 95 | .where({ 96 | user_id: openId 97 | }).orderBy('is_default', 'desc') 98 | .select(); 99 | 100 | ctx.body = { 101 | data: addressList 102 | }; 103 | } 104 | 105 | /** 106 | * 获取收货地址详情 107 | * @param {*} ctx 108 | */ 109 | async function detailAction(ctx) { 110 | var id = ctx.query.id; 111 | const detailData = await mysql("nideshop_address") 112 | .where({ 113 | id: id 114 | }) 115 | .select(); 116 | 117 | ctx.body = { 118 | data: detailData[0] 119 | }; 120 | } 121 | 122 | /** 123 | * 删除收货地址 124 | * @param {*} ctx 125 | */ 126 | async function deleteAction(ctx) { 127 | var id = ctx.query.id; 128 | const delData = await mysql("nideshop_address") 129 | .where({ 130 | id: id 131 | }) 132 | .del(); 133 | if (delData) { 134 | ctx.body = { 135 | data: true 136 | }; 137 | } else { 138 | ctx.body = { 139 | data: false 140 | }; 141 | } 142 | 143 | } 144 | 145 | module.exports = { 146 | saveAction, 147 | getListAction, 148 | detailAction, 149 | deleteAction 150 | }; -------------------------------------------------------------------------------- /controllers/brand/index.js: -------------------------------------------------------------------------------- 1 | const { 2 | mysql 3 | } = require('../../mysql'); 4 | 5 | async function listAction(ctx) { 6 | var page = ctx.query.page || 1; 7 | var size = 5; 8 | const data = await mysql('nideshop_brand').column('id', 'name', 'floor_price', 'app_list_pic_url').limit(size).offset((page - 1) * size).select(); 9 | const data1 = await mysql('nideshop_brand').column('id', 'name', 'floor_price', 'app_list_pic_url').select(); 10 | const total = parseInt(data1.length / size); 11 | ctx.body = { 12 | "total": total, 13 | data 14 | } 15 | } 16 | 17 | async function detailAction(ctx) { 18 | const id = ctx.query.id; 19 | let data = [{}]; 20 | let goodsList = []; 21 | if (id) { 22 | data = await mysql("nideshop_brand").where({ 23 | id: id 24 | }).select(); 25 | 26 | goodsList = await mysql("nideshop_goods").where({ 27 | brand_id: id 28 | }).select(); 29 | } 30 | 31 | 32 | 33 | ctx.body = { 34 | "data": data[0] || {}, 35 | goodsList 36 | } 37 | } 38 | 39 | module.exports = { 40 | listAction, 41 | detailAction 42 | } -------------------------------------------------------------------------------- /controllers/cart/index.js: -------------------------------------------------------------------------------- 1 | const { 2 | mysql 3 | } = require('../../mysql'); 4 | async function addCart(ctx) { 5 | const { 6 | number, 7 | goodsId, 8 | openId 9 | } = ctx.request.body 10 | 11 | 12 | //判断购物车是否包含此数据 13 | const haveGoods = await mysql("nideshop_cart").where({ 14 | "user_id": openId, 15 | "goods_id": goodsId 16 | }).select() 17 | 18 | 19 | if (haveGoods.length == 0) { 20 | // const { 21 | // retail_price, 22 | // name, 23 | // list_pic_url 24 | // } = await mysql("nideshop_goods").where({ 25 | // "id": goodsId 26 | // }).select()[0]; 27 | const goods = await mysql("nideshop_goods").where({ 28 | "id": goodsId 29 | }).select(); 30 | const { 31 | retail_price, 32 | name, 33 | list_pic_url 34 | } = goods[0]; 35 | //如果不存在 36 | await mysql('nideshop_cart').insert({ 37 | "user_id": openId, 38 | "goods_id": goodsId, 39 | number, 40 | "goods_name": name, 41 | list_pic_url, 42 | retail_price 43 | }) 44 | } else { 45 | //如果存在 46 | const oldNumber = await mysql("nideshop_cart").where({ 47 | "user_id": openId, 48 | "goods_id": goodsId 49 | }).column('number').select(); 50 | console.log(oldNumber) 51 | //跟新数据 52 | await mysql("nideshop_cart").where({ 53 | "user_id": openId, 54 | "goods_id": goodsId 55 | }).update({ 56 | "number": oldNumber[0].number + number 57 | }); 58 | } 59 | ctx.body = { 60 | data: "success" 61 | } 62 | } 63 | async function cartList(ctx) { 64 | 65 | const { 66 | openId 67 | } = ctx.query; 68 | 69 | const cartList = await mysql("nideshop_cart").where({ 70 | "user_id": openId, 71 | }).select(); 72 | 73 | ctx.body = { 74 | data: cartList 75 | } 76 | 77 | } 78 | 79 | 80 | async function deleteAction(ctx) { 81 | 82 | const id = ctx.query.id; 83 | 84 | const data = await mysql("nideshop_cart").where({ 85 | "id": id, 86 | }).del(); 87 | 88 | if (data) { 89 | ctx.body = { 90 | data: true 91 | } 92 | } else { 93 | ctx.body = { 94 | data: false 95 | } 96 | } 97 | } 98 | 99 | module.exports = { 100 | addCart, 101 | cartList, 102 | deleteAction 103 | } -------------------------------------------------------------------------------- /controllers/category/index.js: -------------------------------------------------------------------------------- 1 | const { 2 | mysql 3 | } = require('../../mysql'); 4 | 5 | async function indexAction(ctx) { 6 | //ctx.query 获取get请求的参数对象的形式 7 | const { 8 | id: categoryId 9 | } = ctx.query; 10 | //获取所有的分类 11 | const data = await mysql("nideshop_category").where({ 12 | "parent_id": 0 13 | }).select(); 14 | const currentCategory = []; 15 | if (categoryId) { 16 | //获取分类里的子类 17 | currentCategory = await mysql("nideshop_category").where({ 18 | "parent_id": categoryId 19 | }).select(); 20 | } 21 | 22 | 23 | ctx.body = { 24 | "categoryList": data, 25 | } 26 | } 27 | //点击右侧分类时获取左侧对应的分类 28 | async function currentAction(ctx) { 29 | const { 30 | id: categoryId 31 | } = ctx.query; 32 | const data = {}; 33 | //获取分类里的子类 34 | const currentOne = await mysql("nideshop_category").where({ 35 | "id": categoryId 36 | }).select(); 37 | const subList = await mysql("nideshop_category").where({ 38 | "parent_id": currentOne[0].id 39 | }).select(); 40 | data.currentOne = currentOne[0]; 41 | data.currentOne.subList = subList; 42 | ctx.body = { 43 | "data": data 44 | } 45 | } 46 | 47 | 48 | //获取分类列表 49 | //1.需要头部导航包含的分类 50 | //2.查找导航上分类对应的商品 51 | async function categoryNav(ctx) { 52 | const categoryId = ctx.query.id; 53 | //获得当前分类 54 | const currentNav = await mysql("nideshop_category").where({ 55 | "id": categoryId 56 | }).select(); 57 | //获得他的同类 58 | const navData = await mysql("nideshop_category").where({ 59 | "parent_id": currentNav[0].parent_id 60 | }); 61 | 62 | ctx.body = { 63 | navData, 64 | currentNav: currentNav[0] 65 | } 66 | 67 | } 68 | 69 | 70 | 71 | module.exports = { 72 | indexAction, 73 | currentAction, 74 | categoryNav 75 | } -------------------------------------------------------------------------------- /controllers/collect/index.js: -------------------------------------------------------------------------------- 1 | const { 2 | mysql 3 | } = require('../../mysql'); 4 | 5 | /** 6 | * 添加收藏 7 | * @param {*} ctx 8 | */ 9 | async function addCollect(ctx) { 10 | const { 11 | openId, 12 | goodsId 13 | } = ctx.request.body 14 | //判断是否收藏过 15 | const iscollect = await mysql("nideshop_collect").where({ 16 | "user_id": openId, 17 | "value_id": goodsId 18 | }).select() 19 | if (iscollect.length == 0) { 20 | await mysql('nideshop_collect').insert({ 21 | "user_id": openId, 22 | "value_id": goodsId 23 | }) 24 | } else { 25 | await mysql("nideshop_collect").where({ 26 | "user_id": openId, 27 | "value_id": goodsId 28 | }).del() 29 | } 30 | ctx.body = { 31 | data: "success" 32 | } 33 | } 34 | async function listAction(ctx) { 35 | const openId = ctx.query.openId; 36 | const data = await mysql("nideshop_collect").where({ 37 | "user_id": openId, 38 | }).select() 39 | var goodsIds = []; 40 | for (let i = 0; i < data.length; i++) { 41 | const element = data[i]; 42 | goodsIds.push(element.value_id) 43 | } 44 | const listData = await mysql("nideshop_goods").whereIn('id', goodsIds).column('id', 'name', 'list_pic_url', 'retail_price', 'goods_brief').select(); 45 | ctx.body = { 46 | collectGoodsList: listData 47 | } 48 | } 49 | 50 | async function deleteCollect(ctx) { 51 | const id = ctx.query.id; 52 | console.log(id); 53 | 54 | const data = await mysql("nideshop_collect").where({ 55 | "id": id 56 | }).del(); 57 | console.log(data) 58 | if (data) { 59 | ctx.body = { 60 | 'data': "删除成功" 61 | } 62 | } else { 63 | ctx.body = { 64 | 'data': "删除失败" 65 | } 66 | } 67 | 68 | } 69 | module.exports = { 70 | addCollect, 71 | deleteCollect, 72 | listAction 73 | } -------------------------------------------------------------------------------- /controllers/comment/index.js: -------------------------------------------------------------------------------- 1 | const { 2 | mysql 3 | } = require('../../mysql'); 4 | async function postAction(ctx) { 5 | const { 6 | openId, 7 | goodsId, 8 | content 9 | } = ctx.request.body 10 | const buffer = Buffer.from(content); 11 | const typeId = 0; 12 | const insertId = await mysql('nideshop_comment').insert({ 13 | type_id: typeId, 14 | value_id: goodsId, 15 | content: buffer.toString('base64'), 16 | add_time: new Date().getTime(), 17 | user_id: openId 18 | }); 19 | 20 | if (insertId) { 21 | ctx.body = { 22 | data: "success", 23 | message: "添加成功" 24 | } 25 | } else { 26 | ctx.body = { 27 | data: "success", 28 | message: "添加失败" 29 | } 30 | } 31 | 32 | 33 | 34 | } 35 | async function deleteCollect() { 36 | 37 | } 38 | 39 | module.exports = { 40 | postAction 41 | } -------------------------------------------------------------------------------- /controllers/feedback/index.js: -------------------------------------------------------------------------------- 1 | const { 2 | mysql 3 | } = require('../../mysql'); 4 | 5 | async function submitAction(ctx) { 6 | const { 7 | openId, 8 | name, 9 | content, 10 | phone 11 | } = ctx.request.body; 12 | 13 | const data = await mysql("nideshop_feedback").insert({ 14 | 'user_id': openId, 15 | "user_name": name, 16 | "msg_content": content, 17 | "connect": phone, 18 | "msg_time": new Date().getTime() / 100 19 | }) 20 | console.log(data) 21 | if (data) { 22 | ctx.body = { 23 | data: true 24 | } 25 | } else { 26 | ctx.body = { 27 | data: false 28 | } 29 | } 30 | 31 | } 32 | 33 | module.exports = { 34 | submitAction 35 | } 36 | -------------------------------------------------------------------------------- /controllers/goods/index.js: -------------------------------------------------------------------------------- 1 | const { 2 | mysql 3 | } = require('../../mysql'); 4 | 5 | /** 6 | * 商品详情页数据 7 | * 8 | */ 9 | async function detailAction(ctx) { 10 | //ctx.query 获取get请求的参数对象的形式 11 | const goodsId = ctx.query.id; 12 | const openId = ctx.query.openId; 13 | //商品信息 14 | const info = await mysql('nideshop_goods').where({ 15 | 'id': goodsId 16 | }).select(); 17 | //商品相关图片 18 | const gallery = await mysql('nideshop_goods_gallery').where({ 19 | goods_id: goodsId 20 | }).limit(4).select(); 21 | //相关属性 22 | //关联查询两个表 leftJoin 23 | const attribute = await mysql('nideshop_goods_attribute').column("nideshop_goods_attribute.value", "nideshop_attribute.name").leftJoin('nideshop_attribute', 'nideshop_goods_attribute.attribute_id', 'nideshop_attribute.id').where({ 24 | 'nideshop_goods_attribute.goods_id': goodsId 25 | }).select(); 26 | //常见问题 27 | const issue = await mysql('nideshop_goods_issue').select(); 28 | //品牌 29 | let brand = []; 30 | if (info[0].brand_id) { 31 | brand = await mysql('nideshop_brand').where({ 32 | id: info[0].brand_id 33 | }).select(); 34 | } 35 | 36 | //评论条数 37 | const commentCount = await mysql('nideshop_comment').where({ 38 | value_id: goodsId, 39 | type_id: 0 40 | }).count('id as number '); 41 | //热门评论 42 | const hotComment = await mysql('nideshop_comment').where({ 43 | value_id: goodsId, 44 | type_id: 0 45 | }).select(); 46 | let commentInfo = {}; 47 | if (hotComment.length != 0) { 48 | const commentUser = await mysql('nideshop_user').column('nickname', 'username', 'avatar').where({ 49 | id: hotComment[0].user_id 50 | }).select(); 51 | commentInfo = { 52 | content: Buffer.from(hotComment[0].content, 'base64').toString(), 53 | add_time: hotComment.add_time, 54 | nickname: commentUser[0].nickname, 55 | avatar: commentUser[0].avatar, 56 | pic_list: await mysql('nideshop_comment_picture').where({ 57 | comment_id: hotComment[0].id 58 | }).select() 59 | }; 60 | } 61 | 62 | const comment = { 63 | count: commentCount[0].number, 64 | data: commentInfo 65 | }; 66 | //大家都在看 67 | const productList = await mysql('nideshop_goods').where({ 68 | 'category_id': info[0].category_id 69 | }).select(); 70 | 71 | //判断是否收藏过 72 | const iscollect = await mysql("nideshop_collect").where({ 73 | "user_id": openId, 74 | "value_id": goodsId 75 | }).select(); 76 | let collected = false; 77 | if (iscollect.length > 0) { 78 | collected = true 79 | } 80 | //判断该用户是否在购物车有此商品 81 | const oldNumber = await mysql("nideshop_cart").where({ 82 | "user_id": openId, 83 | }).column('number').select(); 84 | let allnumber = 0; 85 | 86 | if (oldNumber.length > 0) { 87 | for (let i = 0; i < oldNumber.length; i++) { 88 | const element = oldNumber[i]; 89 | allnumber += element.number 90 | } 91 | } 92 | 93 | ctx.body = { 94 | "info": info[0] || [], 95 | "gallery": gallery, 96 | "attribute": attribute, 97 | "issue": issue, 98 | "comment": comment, 99 | "brand": brand[0] || [], 100 | "productList": productList, 101 | "collected": collected, 102 | "allnumber": allnumber, 103 | } 104 | } 105 | 106 | 107 | async function goodsList(ctx) { 108 | const categoryId = ctx.query.categoryId; 109 | const isNew = ctx.query.isNew; 110 | const isHot = ctx.query.isHot; 111 | // const page = this.get('page'); 112 | // const size = this.get('size'); 113 | // const sort = this.get('sort'); 114 | let order = ctx.query.order; 115 | let goodsList = []; 116 | //---------------------------------------------------------------------- 117 | if (categoryId) { 118 | //获得商品列表 119 | goodsList = await mysql("nideshop_goods").where({ 120 | "category_id": categoryId 121 | }).select(); 122 | //获得当前分类 123 | const currentNav = await mysql("nideshop_category").where({ 124 | "id": categoryId 125 | }).select(); 126 | 127 | //如果goodsList没有可能这个分类是主分类例如:居家,厨具 128 | if (goodsList.length == 0) { 129 | //找到与之相关的子类,再找到与子类相关的商品列表 130 | let subIds = await mysql("nideshop_category").where({ 131 | "parent_id": categoryId 132 | }).column('id').select(); 133 | //需要变成数组形式childCategoryIds [1020000,1036002] 134 | if (subIds.lenght != 0) { 135 | subIds = subIds.map((item) => { 136 | return item.id; 137 | }) 138 | } 139 | goodsList = await mysql("nideshop_goods").whereIn('category_id', subIds).limit(50).select(); 140 | } 141 | ctx.body = { 142 | data: goodsList, 143 | currentNav: currentNav[0] 144 | } 145 | } 146 | 147 | 148 | if (!order) { 149 | order = ''; 150 | orderBy = "id" 151 | } else { 152 | orderBy = "retail_price" 153 | } 154 | 155 | 156 | 157 | 158 | //---------------------------------------------------------------------- 159 | //新品列表 160 | if (isNew) { 161 | goodsList = await mysql("nideshop_goods").where('is_new', isNew).orderBy(orderBy, order).select(); 162 | ctx.body = { 163 | data: goodsList, 164 | } 165 | } 166 | //---------------------------------------------------------------------- 167 | //---------------------------------------------------------------------- 168 | //热门商品 169 | if (isHot) { //desc //asc 170 | goodsList = await mysql("nideshop_goods").where('is_hot', isHot).orderBy(orderBy, order).select(); 171 | ctx.body = { 172 | data: goodsList, 173 | } 174 | } 175 | //---------------------------------------------------------------------- 176 | 177 | } 178 | 179 | module.exports = { 180 | detailAction, 181 | goodsList 182 | } -------------------------------------------------------------------------------- /controllers/home/index.js: -------------------------------------------------------------------------------- 1 | const { 2 | mysql 3 | } = require('../../mysql'); 4 | 5 | module.exports = async (ctx) => { 6 | //轮播数据 7 | const banner = await mysql('nideshop_ad').where({ 8 | ad_position_id: 1 9 | }).select(); 10 | //类型 11 | const channel = await mysql('nideshop_channel').select(); 12 | //类型 13 | //这几个id有商品详情 14 | const newGoods = await mysql('nideshop_goods').whereIn('id', [1181000, 1135002, 1134030, 1134032]).andWhere("is_new", 1).select(); 15 | 16 | // const newGoods = await mysql('nideshop_goods').where("is_new", 1).limit(7).select(); 17 | /** 18 | * 热门商品 19 | * 选择对象的列字段 20 | * retail_price 零售价 21 | * goods_brief 简明描述 22 | */ 23 | const hotGoods = await mysql('nideshop_goods').column('id', 'name', 'list_pic_url', 'retail_price', 'goods_brief').where({ 24 | is_hot: 1 25 | }).limit(5).select(); 26 | /** 27 | * 品牌列表 28 | */ 29 | const brandList = await mysql('nideshop_brand').where({ 30 | is_new: 1 31 | }).orderBy("new_sort_order", 'asc').limit(4).select(); 32 | /** 33 | * 主题列表 34 | */ 35 | const topicList = await mysql('nideshop_topic').limit(3).select(); 36 | /** 37 | * 类别列表 38 | */ 39 | //1.查询到所有的主类别 40 | const categoryList = await mysql('nideshop_category').where({ 41 | parent_id: 0 42 | }).select(); 43 | //2.查询住类别对应的子类别 44 | const newCategoryList = []; 45 | 46 | 47 | for (let i = 0; i < categoryList.length; i++) { 48 | var item = categoryList[i]; 49 | let childCategoryIds = await mysql('nideshop_category').where({ 50 | parent_id: item.id 51 | }).column('id').select(); 52 | //需要变成数组形式childCategoryIds [1020000,1036002] 53 | childCategoryIds = childCategoryIds.map((item) => { 54 | return item.id; 55 | }) 56 | //在商品中找到 在childCategoryIds里的七条数据 57 | const categoryGoods = await mysql('nideshop_goods').column('id', 'name', 'list_pic_url', 'retail_price').whereIn('category_id', childCategoryIds).limit(7).select(); 58 | newCategoryList.push({ 59 | "id": item.id, 60 | "name": item.name, 61 | "goodsList": categoryGoods 62 | }) 63 | } 64 | //这里如果使用map就无法使用await了 65 | // categoryList.map((item) => { 66 | 67 | // }) 68 | 69 | ctx.body = { 70 | "banner": banner, 71 | "channel": channel, 72 | "newGoods": newGoods, 73 | "hotGoods": hotGoods, 74 | "brandList": brandList, 75 | "topicList": topicList, 76 | "newCategoryList": newCategoryList, 77 | "message": null, 78 | "success": true 79 | } 80 | 81 | } -------------------------------------------------------------------------------- /controllers/index.js: -------------------------------------------------------------------------------- 1 | const _ = require('lodash') 2 | const fs = require('fs') 3 | const path = require('path') 4 | /** 5 | * 映射 d 文件夹下的文件为模块 6 | */ 7 | const mapDir = d => { 8 | const tree = {} 9 | // console.log(fs.readdirSync(d)); //[ 'address','brand', 'cart', 'category', 'collect', 'comment', 'feedback', 'goods', 'home', 'index.js', 'login.js', 'message.js', 'order', 'search', 'topic', 'tunnel.js', 'upload.js', 'user.js'] 10 | // 获得当前文件夹下的所有的文件夹和文件 分成两组,文件夹一组,文件一组 [['address','brand', 'cart'],[index.js,login.js]] 11 | const [dirs, files] = _(fs.readdirSync(d)).partition(p => fs.statSync(path.join(d, p)).isDirectory()) 12 | // 映射文件夹 13 | dirs.forEach(dir => { 14 | tree[dir] = mapDir(path.join(d, dir)) 15 | }) 16 | // 映射文件 17 | files.forEach(file => { 18 | //获取后缀名字 19 | if (path.extname(file) === '.js') { 20 | tree[path.basename(file, '.js')] = require(path.join(d, file)) 21 | } 22 | }) 23 | return tree 24 | } 25 | // { 26 | // address:{ 27 | // index:{ 28 | // } 29 | // }, 30 | // login:{ 31 | // } 32 | // } 33 | // 默认导出当前文件夹下的映射 34 | module.exports = mapDir(path.join(__dirname)) -------------------------------------------------------------------------------- /controllers/order/index.js: -------------------------------------------------------------------------------- 1 | const { 2 | mysql 3 | } = require('../../mysql'); 4 | 5 | async function submitAction(ctx) { 6 | const { 7 | openId, 8 | } = ctx.request.body; 9 | let goodsId = ctx.request.body.goodsId; 10 | let allPrise = ctx.request.body.allPrise 11 | //是否存在在订单 12 | const isOrder = await mysql('nideshop_order').where({ 13 | user_id: openId, 14 | }).select(); 15 | // 存在 16 | // var nowgoodsid = ""; 17 | if (isOrder.length > 0) { 18 | //现在的goodsId加上以前的 19 | // goodsId = isOrder[0].goods_id + ',' + goodsId; 20 | // allPrise = isOrder[0].allprise + allPrise 21 | const data = await mysql('nideshop_order').where({ 22 | user_id: openId, 23 | }).update({ 24 | user_id: openId, 25 | goods_id: goodsId, 26 | allprice: allPrise 27 | }) 28 | if (data) { 29 | ctx.body = { 30 | data: true 31 | } 32 | } else { 33 | ctx.body = { 34 | data: false 35 | } 36 | } 37 | } else { 38 | const data = await mysql('nideshop_order').insert({ 39 | user_id: openId, 40 | goods_id: goodsId, 41 | allprice: allPrise 42 | }) 43 | if (data) { 44 | ctx.body = { 45 | data: true 46 | } 47 | } else { 48 | ctx.body = { 49 | data: false 50 | } 51 | } 52 | } 53 | 54 | 55 | } 56 | async function detailAction(ctx) { 57 | const openId = ctx.query.openId; 58 | const addressId = ctx.query.addressId || ''; 59 | const orderDetail = await mysql('nideshop_order').where({ 60 | user_id: openId, 61 | }).select(); 62 | 63 | var goodsIds = orderDetail[0].goods_id.split(","); 64 | console.log(goodsIds); 65 | 66 | const list = await mysql('nideshop_cart').andWhere({ 67 | user_id: openId 68 | }).whereIn('goods_id', goodsIds).select(); 69 | 70 | //收货地址 71 | var addressList; 72 | if (addressId) { 73 | addressList = await mysql("nideshop_address") 74 | .where({ 75 | user_id: openId, 76 | id: addressId 77 | }).orderBy('is_default', 'desc') 78 | .select(); 79 | } else { 80 | addressList = await mysql("nideshop_address") 81 | .where({ 82 | user_id: openId, 83 | }).orderBy('is_default', 'desc') 84 | .select(); 85 | } 86 | 87 | 88 | ctx.body = { 89 | allPrise: orderDetail[0].allprice, 90 | goodsList: list, 91 | address: addressList[0] || {} 92 | } 93 | 94 | } 95 | async function listAction(ctx) { 96 | 97 | } 98 | module.exports = { 99 | submitAction, 100 | detailAction, 101 | listAction 102 | } -------------------------------------------------------------------------------- /controllers/search/index.js: -------------------------------------------------------------------------------- 1 | const { 2 | mysql 3 | } = require('../../mysql'); 4 | async function indexAction(ctx) { 5 | const openId = ctx.query.openId; 6 | // 默认关键词 7 | const defaultKeyword = await mysql('nideshop_keywords').where({ 8 | is_default: 1 9 | }).limit(1).select(); 10 | // 取出热闹关键词 11 | const hotKeywordList = await mysql('nideshop_keywords').distinct('keyword').column('keyword', 'is_hot').limit(10).select(); 12 | // const historyKeywordList = await mysql('nideshop_search_history').distinct('keyword').where({ 13 | // user_id: think.userId 14 | // }).limit(10).column('keyword'); 15 | const historyData = await mysql('nideshop_search_history').where({ 16 | "user_id": openId 17 | }).limit(10).select(); 18 | ctx.body = { 19 | "defaultKeyword": defaultKeyword[0], 20 | "hotKeywordList": hotKeywordList, 21 | "historyData": historyData 22 | } 23 | } 24 | //搜索的时候匹配搜索相关的 25 | async function helperAction(ctx) { 26 | const keyword = ctx.query.keyword; 27 | var order = ctx.query.order; 28 | if (!order) { 29 | order = ''; 30 | orderBy = "id" 31 | } else { 32 | orderBy = "retail_price" 33 | } 34 | const keywords = await mysql("nideshop_goods").orderBy(orderBy, order).column('id', 'name', 'list_pic_url', 'retail_price').where("name", 'like', '%' + keyword + '%').limit(10).select(); 35 | if (keyword) { 36 | ctx.body = { 37 | keywords 38 | } 39 | } else { 40 | ctx.body = { 41 | keywords: [] 42 | } 43 | } 44 | 45 | } 46 | // async function () { 47 | 48 | // } 49 | // await this.model('search_history').add({ 50 | // keyword: keyword, 51 | // user_id: think.userId, 52 | // add_time: parseInt(new Date().getTime() / 1000) 53 | // }); 54 | 55 | //添加搜索历史,add 56 | 57 | async function addHistoryAction(ctx) { 58 | 59 | const { 60 | openId, 61 | keyword 62 | } = ctx.request.body 63 | 64 | const oldData = await mysql('nideshop_search_history').where({ 65 | "user_id": openId, 66 | "keyword": keyword 67 | }) 68 | if (oldData.length == 0) { 69 | const data = await mysql('nideshop_search_history').insert({ 70 | "user_id": openId, 71 | "keyword": keyword, 72 | "add_time": parseInt(new Date().getTime() / 1000) 73 | }) 74 | if (data) { 75 | ctx.body = { 76 | data: "success" 77 | } 78 | } else { 79 | ctx.body = { 80 | data: "fail" 81 | } 82 | } 83 | } else { 84 | ctx.body = { 85 | data: "已经有记录了" 86 | } 87 | } 88 | 89 | } 90 | //清除历史记录 91 | async function clearhistoryAction(ctx) { 92 | 93 | const openId = ctx.request.body.openId; 94 | console.log(openId); 95 | 96 | const data = await mysql('nideshop_search_history').where({ 97 | "user_id": openId 98 | }).del(); 99 | if (data) { 100 | ctx.body = { 101 | "data": "清除成功" 102 | } 103 | } else { 104 | ctx.body = { 105 | "data": null 106 | } 107 | } 108 | 109 | } 110 | 111 | module.exports = { 112 | indexAction, 113 | helperAction, 114 | addHistoryAction, 115 | clearhistoryAction 116 | } -------------------------------------------------------------------------------- /controllers/topic/index.js: -------------------------------------------------------------------------------- 1 | const { 2 | mysql 3 | } = require('../../mysql'); 4 | 5 | //专题列表 6 | async function listAction(ctx) { 7 | var page = ctx.query.page || 1; 8 | const size = 5; 9 | //这里做分页处理 10 | const data = await mysql("nideshop_topic").column('id', 'title', 'price_info', 'scene_pic_url', 'subtitle').limit(size).offset((page - 1) * size); 11 | const data1 = await mysql("nideshop_topic").column('id', 'title', 'price_info', 'scene_pic_url', 'subtitle').select(); 12 | const total = parseInt(data1.length / 5); 13 | ctx.body = { 14 | "page": page, 15 | "total": total, 16 | "data": data 17 | } 18 | } 19 | //列表详情,下方还有四个专题推荐 20 | async function detailAction(ctx) { 21 | const id = ctx.query.id; 22 | let data = []; 23 | if (id) { 24 | data = await mysql('nideshop_topic').where({ 25 | "id": id 26 | }).select(); 27 | } 28 | const recommendList = await mysql("nideshop_topic").column('id', 'title', 'price_info', 'scene_pic_url', 'subtitle').limit(4).select(); 29 | ctx.body = { 30 | "data": data[0], 31 | "recommendList": recommendList 32 | } 33 | } 34 | module.exports = { 35 | listAction, 36 | detailAction 37 | } -------------------------------------------------------------------------------- /middlewares/response.js: -------------------------------------------------------------------------------- 1 | const debug = require('debug')('koa-weapp-demo') 2 | 3 | /** 4 | * 响应处理模块 5 | */ 6 | module.exports = async function (ctx, next) { 7 | try { 8 | // 调用下一个 middleware 9 | await next() 10 | 11 | // 处理响应结果 12 | // 如果直接写入在 body 中,则不作处理 13 | // 如果写在 ctx.body 为空,则使用 state 作为响应 14 | ctx.body = ctx.body ? ctx.body : { 15 | code: ctx.state.code !== undefined ? ctx.state.code : 0, 16 | data: ctx.state.data !== undefined ? ctx.state.data : {} 17 | } 18 | } catch (e) { 19 | // catch 住全局的错误信息 20 | debug('Catch Error: %o', e) 21 | 22 | // 设置状态码为 200 - 服务端错误 23 | ctx.status = 200 24 | 25 | // 输出详细的错误信息 26 | ctx.body = { 27 | code: -1, 28 | error: e && e.message ? e.message : e.toString() 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /mysql.js: -------------------------------------------------------------------------------- 1 | // 获取基础配置 2 | const configs = require('./config') 3 | 4 | var knex = require('knex')({ 5 | client: 'mysql', 6 | connection: { 7 | host: configs.mysql.host, 8 | port: configs.mysql.port, 9 | user: configs.mysql.user, 10 | password: configs.mysql.pass, 11 | database: configs.mysql.db 12 | } 13 | }); 14 | // 初始化 SDK 15 | // 将基础配置和 sdk.config 合并传入 SDK 并导出初始化完成的 SDK 16 | module.exports = { mysql: knex } -------------------------------------------------------------------------------- /nideshop_ad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heyushuo/mpvue-shop-node/7a23d0cc795d3dc7a7cb638412fe70066fac64ad/nideshop_ad -------------------------------------------------------------------------------- /nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "restartable": "rs", 3 | "ignore": [ 4 | ".git", 5 | "node_modules/**/node_modules" 6 | ], 7 | "verbose": true, 8 | "execMap": { 9 | "js": "node --harmony" 10 | }, 11 | "env": { 12 | "NODE_ENV": "development", 13 | "DEBUG": "*,-nodemon:*,-nodemon,-knex:pool" 14 | }, 15 | "ext": "js json" 16 | } 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "koa-weapp-demo", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "scripts": { 7 | "start": "pm2 start process.prod.json --no-daemon", 8 | "dev": "nodemon --config nodemon.json app.js", 9 | "initdb": "npm install && node tools/initdb.js" 10 | }, 11 | "author": "Jason", 12 | "license": "MIT", 13 | "dependencies": { 14 | "axios": "^0.15.3", 15 | "knex": "^0.13.0", 16 | "koa": "^2.0.0", 17 | "koa-bodyparser": "^3.2.0", 18 | "koa-log4": "^2.1.0", 19 | "koa-router": "^7.0.1", 20 | "lodash": "^4.17.4", 21 | "mkdir-p": "0.0.7", 22 | "mysql": "^2.14.1", 23 | "pify": "^2.3.0", 24 | "wafer-node-sdk": "^1.4.0" 25 | }, 26 | "devDependencies": { 27 | "babel-eslint": "^7.1.0", 28 | "debug": "^2.6.8", 29 | "eslint-config-standard": "^6.2.1", 30 | "eslint-plugin-promise": "^3.3.1", 31 | "eslint-plugin-standard": "^2.0.1", 32 | "nodemon": "^1.18.4" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /process.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "session", 3 | "script": "app.js", 4 | "cwd": "./", 5 | "exec_mode": "fork", 6 | "watch": true, 7 | "ignore_watch": ["tmp"], 8 | "env": { 9 | "NODE_ENV": "production" 10 | }, 11 | "engines": { 12 | "node": ">=7.6" 13 | } 14 | } -------------------------------------------------------------------------------- /routes/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ajax 服务路由集合 3 | */ 4 | const router = require('koa-router')({ 5 | prefix: '/heyushuo' 6 | }) 7 | const controllers = require('../controllers') 8 | 9 | //================================================================自己的接口 10 | 11 | //首页数据 12 | //1.首页 13 | router.get('/index/index', controllers.home.index) 14 | //2.首页品牌制造商直供的详情内的列表数据 15 | router.get('/brand/listaction', controllers.brand.index.listAction) 16 | //3.首页品牌制造商直供的详情数据 17 | router.get('/brand/detailaction', controllers.brand.index.detailAction) 18 | 19 | 20 | /** 21 | * 分类 22 | */ 23 | //1.分类和子类 24 | router.get('/category/indexaction', controllers.category.index.indexAction) 25 | //2.通过分类的id来查询子类接口 26 | router.get('/category/currentaction', controllers.category.index.currentAction) 27 | //3.获取导航数据 28 | router.get('/category/categoryNav', controllers.category.index.categoryNav) 29 | 30 | 31 | /** 32 | * 商品相关接口 33 | */ 34 | //1.商品详情接口 35 | router.get('/goods/detailaction', controllers.goods.index.detailAction) 36 | //2.获取商品列表 37 | router.get('/goods/goodsList', controllers.goods.index.goodsList) 38 | 39 | 40 | /** 41 | * 专题接口 42 | */ 43 | //1.列表 44 | router.get('/topic/listaction', controllers.topic.index.listAction) 45 | //2.详情加下方四个专题推荐 46 | router.get('/topic/detailaction', controllers.topic.index.detailAction) 47 | 48 | 49 | /** 50 | * 搜索相关接口 51 | */ 52 | //1.关键词和搜索历史接口 53 | router.get('/search/indexaction', controllers.search.index.indexAction) 54 | //2.搜索提示接口 55 | router.get('/search/helperaction', controllers.search.index.helperAction) 56 | //3.搜索的关键词添加到数据库 57 | router.post('/search/addhistoryaction', controllers.search.index.addHistoryAction) 58 | //4.清空搜索历史 59 | router.post('/search/clearhistoryAction', controllers.search.index.clearhistoryAction) 60 | 61 | 62 | /** 63 | * 收藏相关接口 64 | */ 65 | //1.添加收藏 66 | router.post('/collect/addcollect', controllers.collect.index.addCollect) 67 | //2.获取收藏列表 68 | router.get('/collect/listAction', controllers.collect.index.listAction) 69 | //2.获取收藏列表 70 | router.get('/collect/deleteCollect', controllers.collect.index.deleteCollect) 71 | 72 | /** 73 | * 购物车相关接口 74 | */ 75 | //1.添加购物车 76 | router.post('/cart/addCart', controllers.cart.index.addCart) 77 | //2.购物车列表 78 | router.get('/cart/cartList', controllers.cart.index.cartList) 79 | //3.删除商品 80 | router.get('/cart/deleteAction', controllers.cart.index.deleteAction) 81 | 82 | 83 | /** 84 | * 订单相关 85 | */ 86 | router.post('/order/submitAction', controllers.order.index.submitAction) 87 | 88 | router.get('/order/detailAction', controllers.order.index.detailAction) 89 | /** 90 | * 收货地址相关接口 91 | */ 92 | //1.保存和跟新收货地址 93 | router.post('/address/saveAction', controllers.address.index.saveAction) 94 | //2.获取收货地址列表 95 | router.get('/address/getListAction', controllers.address.index.getListAction) 96 | //3.获取收货地址详情 97 | router.get('/address/detailAction', controllers.address.index.detailAction) 98 | //4.删除收货地址 99 | router.get('/address/deleteAction', controllers.address.index.deleteAction) 100 | 101 | 102 | /** 103 | * 意见反馈 104 | */ 105 | router.post('/feedback/submitAction', controllers.feedback.index.submitAction) 106 | 107 | module.exports = router -------------------------------------------------------------------------------- /tools.md: -------------------------------------------------------------------------------- 1 | # 腾讯云小程序解决方案 Demo 工具使用文档 2 | 3 | 本文件夹下的脚本为腾讯云小程序解决方案 Demo 配套的工具,旨在让用户方便快捷的使用并创建小程序的开发环境。 4 | 5 | 工具包括: 6 | 7 | - [数据库初始化工具](#数据库初始化工具) 8 | 9 | ## 数据库初始化工具 10 | 11 | 本工具是为了让用户快速的按照腾讯云制定的数据库 schema 创建符合 SDK 标准的数据库结构。 12 | 13 | _**注意**:本工具支持的 MySQL 版本为 **5.7**,并且需提前在数据库中创建名为 `cAuth` 的数据库。`charset` 设置为 `utf8mb4`。_ 14 | 15 | 快速使用: 16 | 17 | ```bash 18 | npm run initdb 19 | ``` 20 | 21 | 或直接执行 `tools` 目录下的 `initdb.js` 文件: 22 | 23 | ```bash 24 | # 请保证已经执行了 npm install 安装了所需要的依赖 25 | node tools/initdb.js 26 | ``` 27 | 28 | 我们提供了初始化的 SQL 文件,你也可以用其他数据库工具(如 Navicat)直接导入 SQL 文件。 29 | --------------------------------------------------------------------------------