├── README.md ├── app.js ├── app.json ├── app.wxss ├── images ├── icon │ ├── add.png │ ├── cart.png │ ├── cart_n.png │ ├── del.png │ ├── index.png │ ├── index_c.png │ ├── jian.png │ ├── list.png │ ├── list_c.png │ ├── my.png │ ├── my_c.png │ ├── pay.png │ └── pay_c.png └── index │ ├── ad.png │ ├── b_1.jpg │ ├── b_2.jpg │ ├── b_3.jpg │ ├── b_4.jpg │ ├── lb1.jpg │ ├── lb2.jpg │ └── lb3.jpg ├── pages ├── index │ ├── index.js │ ├── index.json │ ├── index.wxml │ └── index.wxss ├── list │ ├── list.js │ ├── list.json │ ├── list.wxml │ └── list.wxss ├── order │ ├── checkout │ │ ├── checkout.js │ │ ├── checkout.json │ │ ├── checkout.wxml │ │ └── checkout.wxss │ ├── detail │ │ ├── detail.js │ │ ├── detail.json │ │ ├── detail.wxml │ │ └── detail.wxss │ └── list │ │ ├── list.js │ │ ├── list.json │ │ ├── list.wxml │ │ └── list.wxss └── record │ ├── record.js │ ├── record.json │ ├── record.wxml │ └── record.wxss ├── project.config.json ├── sitemap.json └── utils ├── config.js └── fetch.js /README.md: -------------------------------------------------------------------------------- 1 | # mini-program_Order-system 2 | 微信小程序-点餐系统 3 | 4 | ## 小程序简介 5 | 这是一个由 `微信小程序` 开发的一个点餐小程序,用户可通过小程序完成加购食物、结算、支付订单完成点单流程并通过订单号取餐;用户可查看订单记录、订单状态及订单详情,还可看到所有的消费记录。 6 | 7 | ## 项目目录说明 8 | ``` 9 | "pages": [ 10 | "pages/index/index", // 首页,通过开始点餐按钮进入加购页面及展示商品 11 | "pages/list/list", // 加购页面,可添加、减少、删除商品及清空购物车,加购购物车图标变亮,角标显示数量,可参与满减 12 | "pages/order/checkout/checkout", // 确认订单页(支付订单),显示所有加购商品,可备注并支付订单(仅显示支付成功) 13 | "pages/order/detail/detail", // 订单详情页面,显示所有加购商品,未取餐显示取餐号,取餐后显示已取餐 14 | "pages/order/list/list", // 订单页,展示所有订单记录及订单状态(已取餐、未取餐),可查看订单详情 15 | "pages/record/record" // 我的页面,展示授权登录后的个人信息及消费记录 16 | ] 17 | 18 | /utils 小程序客户端与服务器端交互的接口文件 19 | 20 | ``` 21 | 22 | ## 项目展示 23 | 1. 首页 24 | [![index.png](https://z4a.net/images/2020/06/12/index.png)](https://z4a.net/image/Tws3Uj) 25 | 26 | 2. 加购 27 | [![cart.png](https://z4a.net/images/2020/06/12/cart.png)](https://z4a.net/image/Twso30) 28 | 29 | 3. 确认订单 30 | [![chechout.png](https://z4a.net/images/2020/06/12/chechout.png)](https://z4a.net/image/TwsSjO) 31 | 32 | 4. 订单详情 33 | - 未取餐 34 | [![detail1.png](https://z4a.net/images/2020/06/12/detail1.png)](https://z4a.net/image/Tws8FJ) 35 | 36 | - 已取餐 37 | [![detail2.png](https://z4a.net/images/2020/06/12/detail2.png)](https://z4a.net/image/TwsfPK) 38 | 39 | 5. 订单 40 | [![list.png](https://z4a.net/images/2020/06/12/list.png)](https://z4a.net/image/TwsZ8P) 41 | 42 | 6. 我的 43 | [![recode.png](https://z4a.net/images/2020/06/12/recode.png)](https://z4a.net/image/TwsGEa) 44 | 45 | 46 | ## 开发注意 47 | 48 | - 导入项目填写**测试号**即可 49 | 50 | - 除了小程序客户端外还需要服务端,服务端由**Wampserver**集成包及**ThinkPHP**框架搭建,源码见[点餐小程序服务端](https://github.com/nichan-13/mini-program_order-system-server.git) 51 | 52 | 53 | ## 参考文档 54 | 55 | - [微信小程序官方文档](https://developers.weixin.qq.com/miniprogram/dev/framework/) 56 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | //app.js 2 | App({ 3 | fetch: require('utils/fetch.js'), 4 | onLaunch: function () { 5 | wx.showLoading({ 6 | title: '登录中...', 7 | mask: true 8 | }) 9 | this.fetch('user/setting').then( data => { 10 | if (data.isLogin) { 11 | // 已登录 12 | this.onUserInfoReady(); 13 | // console.log('通过保存的cookie登陆成功') 14 | } else { 15 | // 未登录 16 | this.login({ 17 | success: () => { 18 | // 登陆成功 19 | this.onUserInfoReady(); 20 | // wx.hideLoading() 21 | // console.log('登陆成功') 22 | }, 23 | fail: () => { 24 | // 登录失败,说明服务器异常,已经弹出模态框,这里用来重试 25 | this.onLaunch() 26 | } 27 | }) 28 | } 29 | },() => { 30 | this.onLaunch() 31 | }) 32 | 33 | // 登录 34 | wx.login({ 35 | success: res => { 36 | // 发送 res.code 到后台换取 openId, sessionKey, unionId 37 | } 38 | }) 39 | // 获取用户信息 40 | wx.getSetting({ 41 | success: res => { 42 | if (res.authSetting['scope.userInfo']) { 43 | // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 44 | wx.getUserInfo({ 45 | success: res => { 46 | // 可以将 res 发送给后台解码出 unionId 47 | this.globalData.userInfo = res.userInfo 48 | 49 | // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 50 | // 所以此处加入 callback 以防止这种情况 51 | if (this.userInfoReadyCallback) { 52 | this.userInfoReadyCallback(res) 53 | } 54 | } 55 | }) 56 | } 57 | } 58 | }) 59 | this.globalData = {} 60 | }, 61 | 62 | login: function(options) { 63 | wx.login({ 64 | success: res => { 65 | // 获得 res.data 66 | this.fetch('user/login', { 67 | js_code: res.code 68 | }).then(data => { 69 | // 判断是否成功 70 | if (data && data.isLogin) { 71 | // 登录成功 72 | options.success() 73 | } else { 74 | // 登录失败 75 | options.fail() 76 | } 77 | }, () => { 78 | // 登录失败,服务器异常 79 | options.fail() 80 | }) 81 | } 82 | }) 83 | }, 84 | 85 | userInfoReady: false, 86 | onUserInfoReady: function() { 87 | wx.hideLoading(); 88 | if (this.userInfoReadyCallback) { 89 | this.userInfoReadyCallback(); 90 | } 91 | this.userInfoReady = true 92 | } 93 | }) 94 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ 3 | "pages/index/index", 4 | "pages/list/list", 5 | "pages/order/checkout/checkout", 6 | "pages/order/detail/detail", 7 | "pages/order/list/list", 8 | "pages/record/record" 9 | ], 10 | "window": { 11 | "backgroundColor": "#fff", 12 | "backgroundTextStyle": "light", 13 | "navigationBarBackgroundColor": "#F24", 14 | "navigationBarTitleText": "My shop", 15 | "navigationBarTextStyle": "white" 16 | }, 17 | "tabBar": { 18 | "color": "#999", 19 | "selectedColor": "#f24", 20 | "borderStyle": "white", 21 | "list": [{ 22 | "pagePath": "pages/index/index", 23 | "text": "首页", 24 | "iconPath": "images/icon/index.png", 25 | "selectedIconPath": "images/icon/index_c.png" 26 | },{ 27 | "pagePath": "pages/order/list/list", 28 | "text": "订单", 29 | "iconPath": "images/icon/list.png", 30 | "selectedIconPath": "images/icon/list_c.png" 31 | },{ 32 | "pagePath": "pages/record/record", 33 | "text": "我的", 34 | "iconPath": "images/icon/my.png", 35 | "selectedIconPath": "images/icon/my_c.png" 36 | }] 37 | }, 38 | "sitemapLocation": "sitemap.json", 39 | "style": "v2" 40 | } -------------------------------------------------------------------------------- /app.wxss: -------------------------------------------------------------------------------- 1 | page { 2 | box-sizing: border-box; 3 | } -------------------------------------------------------------------------------- /images/icon/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/icon/add.png -------------------------------------------------------------------------------- /images/icon/cart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/icon/cart.png -------------------------------------------------------------------------------- /images/icon/cart_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/icon/cart_n.png -------------------------------------------------------------------------------- /images/icon/del.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/icon/del.png -------------------------------------------------------------------------------- /images/icon/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/icon/index.png -------------------------------------------------------------------------------- /images/icon/index_c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/icon/index_c.png -------------------------------------------------------------------------------- /images/icon/jian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/icon/jian.png -------------------------------------------------------------------------------- /images/icon/list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/icon/list.png -------------------------------------------------------------------------------- /images/icon/list_c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/icon/list_c.png -------------------------------------------------------------------------------- /images/icon/my.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/icon/my.png -------------------------------------------------------------------------------- /images/icon/my_c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/icon/my_c.png -------------------------------------------------------------------------------- /images/icon/pay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/icon/pay.png -------------------------------------------------------------------------------- /images/icon/pay_c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/icon/pay_c.png -------------------------------------------------------------------------------- /images/index/ad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/index/ad.png -------------------------------------------------------------------------------- /images/index/b_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/index/b_1.jpg -------------------------------------------------------------------------------- /images/index/b_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/index/b_2.jpg -------------------------------------------------------------------------------- /images/index/b_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/index/b_3.jpg -------------------------------------------------------------------------------- /images/index/b_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/index/b_4.jpg -------------------------------------------------------------------------------- /images/index/lb1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/index/lb1.jpg -------------------------------------------------------------------------------- /images/index/lb2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/index/lb2.jpg -------------------------------------------------------------------------------- /images/index/lb3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nichan-13/mini-program_Order-system/c792ab0896d21112301a7f408f5baaa31cd0ffb4/images/index/lb3.jpg -------------------------------------------------------------------------------- /pages/index/index.js: -------------------------------------------------------------------------------- 1 | //index.js 2 | const app = getApp() 3 | const fetch = app.fetch 4 | 5 | Page({ 6 | data: { 7 | ad:'/images/index/ad.png', 8 | category: ['/images/index/b_3.jpg','/images/index/b_4.jpg','/images/index/b_1.jpg','/images/index/b_2.jpg'], 9 | swiper: ['/images/index/lb1.jpg','/images/index/lb2.jpg','/images/index/lb3.jpg'] 10 | }, 11 | onLoad: function(options) { 12 | var callback = () => { 13 | wx.showLoading({ 14 | title: '努力加载中...', 15 | mask: true 16 | }) 17 | fetch('food/index').then(data => { 18 | wx.hideLoading() 19 | // this.setData({ 20 | // ad: data.img_ad, 21 | // category: data.img_category, 22 | // swiper: data.img_swiper 23 | // }) 24 | }, () => { 25 | callback() 26 | }) 27 | } 28 | if (app.userInfoReady) { 29 | callback() 30 | } else { 31 | app.userInfoReadyCallback = callback 32 | } 33 | }, 34 | 35 | start: function() { 36 | wx.navigateTo({ 37 | url: '/pages/list/list' 38 | }) 39 | } 40 | }) 41 | -------------------------------------------------------------------------------- /pages/index/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {} 3 | } -------------------------------------------------------------------------------- /pages/index/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /pages/index/index.wxss: -------------------------------------------------------------------------------- 1 | 2 | .swiper { 3 | height: 360rpx; 4 | } 5 | 6 | .swiper image { 7 | width: 100%; 8 | height: 100%; 9 | border-bottom-left-radius: 30%; 10 | border-bottom-right-radius: 30%; 11 | } 12 | 13 | .menu-start { 14 | margin: 30rpx; 15 | border-radius: 80rpx; 16 | background-color: #f24; 17 | color: #fff; 18 | } 19 | 20 | .ad-box { 21 | margin-top: 20rpx; 22 | width: 100%; 23 | text-align: center; 24 | } 25 | 26 | .ad-image { 27 | width: 710rpx; 28 | height: 330rpx; 29 | border-radius: 20rpx; 30 | box-sizing: border-box; 31 | } 32 | 33 | /* 底部图片展示 */ 34 | 35 | .bottom-box { 36 | margin: 10rpx 0; 37 | display: flex; 38 | width: 100%; 39 | padding: 0 20rpx; 40 | flex-direction: row; 41 | flex-wrap: wrap; 42 | justify-content: space-between; 43 | box-sizing: border-box; 44 | } 45 | 46 | .bottom-pic { 47 | width: 49%; 48 | display: inline-block; 49 | } 50 | 51 | .bottom-image { 52 | width: 100%; 53 | height: 220rpx; 54 | border-radius: 10rpx; 55 | } -------------------------------------------------------------------------------- /pages/list/list.js: -------------------------------------------------------------------------------- 1 | const app = getApp() 2 | const fetch = app.fetch 3 | var categoryHeight = [] // 右列表各分类高度数组 4 | 5 | Page({ 6 | data: { 7 | activeIndex: 0, 8 | tapIndex: 0, 9 | foodList: '', 10 | cartList: {}, 11 | cartPrice: 0, 12 | cartNumber: 0, 13 | cartBall: { 14 | show: false, 15 | x: 0, 16 | y: 0 17 | }, 18 | showCart: false, 19 | promotion: {} 20 | }, 21 | changingCategory: false, // 是否正在切换左侧激活的分类(防止滚动过快时切换迟缓) 22 | shopcartAnimate: null, 23 | onLoad: function(options) { 24 | wx.showLoading({ 25 | title: '努力加载中...' 26 | }) 27 | fetch('food/list').then(data => { 28 | wx.hideLoading() 29 | for (var i in data.list) { 30 | this.setData({ 31 | activeIndex: i 32 | }) 33 | break 34 | } 35 | this.setData({ 36 | foodList: data.list, 37 | promotion: data.promotion[0] 38 | }, () => { 39 | var query = wx.createSelectorQuery() 40 | var top = 0 41 | query.select('.food').boundingClientRect(rect => { 42 | top = rect.top 43 | }) 44 | query.selectAll('.food-category').boundingClientRect(res => { 45 | res.forEach(rect => { 46 | categoryHeight[rect.id.substring(rect.id.indexOf('_') + 1)] = rect.top - top 47 | }) 48 | }) 49 | query.exec() 50 | }) 51 | }, () => { 52 | this.onLoad() 53 | }) 54 | this.shopcartAnimate = shopcartAnimate('.cart-icon', this) 55 | }, 56 | tapCategory: function(e) { 57 | var index = e.currentTarget.dataset.index 58 | this.changingCategory = true 59 | this.setData({ 60 | activeIndex: index, 61 | tapIndex: index 62 | }, () => { 63 | this.changingCategory = false 64 | }) 65 | }, 66 | onFoodScroll: function(e) { 67 | var scrollTop = e.detail.scrollTop 68 | var activeIndex = 0 69 | categoryHeight.forEach((item, i) => { 70 | if (scrollTop >= item) { 71 | activeIndex = i 72 | } 73 | }) 74 | if (!this.changingCategory) { 75 | this.changingCategory = true 76 | this.setData({ 77 | activeIndex: activeIndex, 78 | }, () => { 79 | this.changingCategory = false 80 | }) 81 | } 82 | }, 83 | scrolltolower: function() { 84 | this.setData({ 85 | activeIndex: categoryHeight.length - 1 86 | }) 87 | }, 88 | addToCart: function(e) { 89 | var id = e.currentTarget.dataset.id 90 | var category_id = e.currentTarget.dataset.category_id 91 | var food = this.data.foodList[category_id].food[id] 92 | var cartList = this.data.cartList 93 | if (cartList[id]) { 94 | ++cartList[id].number 95 | } else { 96 | cartList[id] = { 97 | id: food.id, 98 | name: food.name, 99 | price: parseFloat(food.price), 100 | number: 1 101 | } 102 | } 103 | this.shopcartAnimate.show(e) 104 | this.setData({ 105 | cartList, 106 | cartPrice: this.data.cartPrice + cartList[id].price, 107 | cartNumber: this.data.cartNumber + 1 108 | }) 109 | }, 110 | showCartList: function() { 111 | if (this.data.cartNumber > 0) { 112 | this.setData({ 113 | showCart: !this.data.showCart 114 | }) 115 | } 116 | }, 117 | // 减少商品,最小数量为1 118 | cartNumberDec: function(e) { 119 | var id = e.currentTarget.dataset.id 120 | var cartList = this.data.cartList 121 | if (cartList[id]) { 122 | var price = cartList[id].price 123 | if (cartList[id].number > 1) { 124 | --cartList[id].number 125 | this.setData({ 126 | cartList, 127 | cartNumber: --this.data.cartNumber, 128 | cartPrice: this.data.cartPrice - price 129 | }) 130 | } else { 131 | wx.showToast({ 132 | icon: "none", 133 | title: '商品不可再减少~', 134 | }) 135 | this.setData({ 136 | cartList, 137 | cartNumber: this.data.cartNumber, 138 | cartPrice: this.data.cartPrice 139 | }) 140 | } 141 | } 142 | }, 143 | // 增加商品 144 | cartNumberAdd: function(e) { 145 | var id = e.currentTarget.dataset.id 146 | var cartList = this.data.cartList 147 | ++cartList[id].number 148 | this.setData({ 149 | cartList, 150 | cartNumber: ++this.data.cartNumber, 151 | cartPrice: this.data.cartPrice + cartList[id].price 152 | }) 153 | }, 154 | // 删除商品 155 | cartNumberDel: function(e) { 156 | var id = e.currentTarget.dataset.id 157 | var cartList = this.data.cartList 158 | var price = cartList[id].price 159 | var num = cartList[id].number 160 | delete cartList[id] 161 | this.setData({ 162 | cartList, 163 | cartNumber: this.data.cartNumber - num, 164 | cartPrice: this.data.cartPrice - num*price 165 | }) 166 | if (this.data.cartNumber <= 0) { 167 | this.setData({ 168 | showCart: false 169 | }) 170 | } 171 | }, 172 | // 清空购物车 173 | cartClear: function() { 174 | this.setData({ 175 | cartList: {}, 176 | cartNumber: 0, 177 | cartPrice: 0, 178 | showCart: false 179 | }) 180 | }, 181 | order: function() { 182 | if (this.data.cartNumber === 0) { 183 | return 184 | } 185 | wx.showLoading({ 186 | title: '正在生成订单...' 187 | }) 188 | fetch('food/order', { 189 | order: this.data.cartList 190 | }, 'POST').then(data => { 191 | wx.navigateTo({ 192 | url: '/pages/order/checkout/checkout?order_id=' + data.order_id 193 | }) 194 | // console.log(data.order_id) 195 | }, () => { 196 | this.order() 197 | }) 198 | } 199 | }) 200 | 201 | function shopcartAnimate(iconClass, page) { 202 | var busPos = {} 203 | wx.createSelectorQuery().select(iconClass).boundingClientRect(rect => { 204 | busPos.x = rect.left + 15 205 | busPos.y = rect.top 206 | }).exec() 207 | return { 208 | show: function(e) { 209 | var finger = { 210 | x: e.touches[0].clientX - 10, 211 | y: e.touches[0].clientY - 10 212 | } 213 | var topPoint = {} 214 | if (finger.y < busPos.y) { 215 | topPoint.y = finger.y - 150 216 | } else { 217 | topPoint.y = busPos.y - 150 218 | } 219 | topPoint.x = Math.abs(finger.x - busPos.x) / 2 220 | if (finger.x > busPos.x) { 221 | topPoint.x = (finger.x - busPos.x) / 2 + busPos.x 222 | } else { 223 | topPoint.x = (busPos.x - finger.x) / 2 + finger.x 224 | } 225 | var linePos = bezier([busPos, topPoint, finger], 30) 226 | var bezier_points = linePos.bezier_points 227 | page.setData({ 228 | 'cartBall.show': true, 229 | 'cartBall.x': finger.x, 230 | 'cartBall.y': finger.y 231 | }) 232 | var len = bezier_points.length 233 | var index = len 234 | let i = index - 1 235 | var timer = setInterval(function() { 236 | i = i - 5 237 | if (i < 1) { 238 | clearInterval(timer) 239 | page.setData({ 240 | 'cartBall.show': false 241 | }) 242 | return 243 | } 244 | page.setData({ 245 | 'cartBall.show': true, 246 | 'cartBall.x': bezier_points[i].x, 247 | 'cartBall.y': bezier_points[i].y 248 | }) 249 | }, 50) 250 | } 251 | } 252 | 253 | function bezier(pots, amount) { 254 | var pot 255 | var lines 256 | var ret = [] 257 | var points 258 | for (var i = 0; i <= amount; ++i) { 259 | points = pots.slice(0) 260 | lines = [] 261 | while (pot = points.shift()) { 262 | if (points.length) { 263 | lines.push(pointLine([pot, points[0]], i / amount)) 264 | } else if (lines.length > 1) { 265 | points = lines 266 | lines = [] 267 | } else { 268 | break 269 | } 270 | } 271 | ret.push(lines[0]) 272 | } 273 | 274 | function pointLine(points, rate) { 275 | var pointA, pointB, pointDistance, xDistance, yDistance, tan, radian, tmpPointDistance 276 | var ret = [] 277 | pointA = points[0] 278 | pointB = points[1] 279 | xDistance = pointB.x - pointA.x 280 | yDistance = pointB.y - pointA.y 281 | pointDistance = Math.pow(Math.pow(xDistance, 2) + Math.pow(yDistance, 2), 1 / 2) 282 | tan = yDistance / xDistance 283 | radian = Math.atan(tan) 284 | tmpPointDistance = pointDistance * rate 285 | ret = { 286 | x: pointA.x + tmpPointDistance * Math.cos(radian), 287 | y: pointA.y + tmpPointDistance * Math.sin(radian) 288 | } 289 | return ret 290 | } 291 | return { 292 | bezier_points: ret 293 | } 294 | } 295 | } -------------------------------------------------------------------------------- /pages/list/list.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {} 3 | } -------------------------------------------------------------------------------- /pages/list/list.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 满{{promotion.k}}元减{{promotion.v}}元(在线支付专享) 5 | 6 | 7 | 8 | 9 | 10 | 11 | {{item.name}} 12 | 13 | 14 | 15 | 16 | 17 | {{category.name}} 18 | 19 | 20 | 21 | 22 | 23 | {{food.name}} 24 | {{priceFormat(food.price)}} 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | {{cartNumber}} 47 | 48 | 购物车内还没有商品~ 49 | 50 | 51 | {{priceFormat(cartPrice - promotion.v)}} 52 | {{priceFormat(cartPrice)}} 53 | 54 | {{priceFormat(cartPrice)}} 55 | 56 | 57 | 结算 58 | 59 | 60 | 61 | 62 | 63 | 64 | 已选商品 65 | 清空购物车 66 | 67 | 68 | 69 | {{item.name}} 70 | 71 | {{priceFormat(item.price * item.number)}} 72 | 73 | 74 | 75 | {{item.number}} 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | module.exports = function(price) { 85 | return '¥ ' + parseFloat(price) 86 | } 87 | -------------------------------------------------------------------------------- /pages/list/list.wxss: -------------------------------------------------------------------------------- 1 | /* pages/list/list.wxss */ 2 | page { 3 | display: flex; 4 | flex-direction: column; 5 | height: 100%; 6 | } 7 | 8 | /* 折扣信息区 */ 9 | 10 | .discount { 11 | width: 100%; 12 | height: 70rpx; 13 | line-height: 70rpx; 14 | background: #f2f8f7; 15 | font-size: 28rpx; 16 | text-align: center; 17 | color: rgb(131, 131, 131); 18 | } 19 | 20 | .discount-txt { 21 | color: #fff; 22 | padding: 5rpx 10rpx; 23 | background: rgb(255, 136, 0); 24 | margin-right: 15rpx; 25 | } 26 | 27 | .content { 28 | flex: 1; 29 | display: flex; 30 | } 31 | 32 | /* 左侧菜单 */ 33 | 34 | .category { 35 | width: 202rpx; 36 | height: 100%; 37 | background: #fcfcfc; 38 | font-size: 28rpx; 39 | } 40 | 41 | /* 隐藏滚动条 */ 42 | 43 | ::-webkit-scrollbar { 44 | width: 0; 45 | height: 0; 46 | color: transparent; 47 | } 48 | 49 | .category-item { 50 | height: 106rpx; 51 | line-height: 106rpx; 52 | text-align: center; 53 | } 54 | 55 | .category-unselect { 56 | color: #6c6c6c; 57 | background: #f9f9f9; 58 | border-bottom: 1rpx solid #e3e3e3; 59 | } 60 | 61 | .category-selected { 62 | color: #f24; 63 | border-left: 6rpx solid #f24; 64 | background-color: white; 65 | } 66 | 67 | /* 右侧菜单 */ 68 | 69 | .food-category { 70 | font-size: 24rpx; 71 | background-color: #fbf8ff; 72 | padding: 10rpx; 73 | color: #f24; 74 | } 75 | 76 | .food-item { 77 | display: flex; 78 | margin: 40rpx 20rpx; 79 | } 80 | 81 | .food-item-pic { 82 | margin-right: 20rpx; 83 | width: 94rpx; 84 | height: 94rpx; 85 | } 86 | 87 | .food-item-pic > image { 88 | width: 100%; 89 | height: 100%; 90 | } 91 | 92 | .food-item-info { 93 | flex: 1; 94 | font-size: 30rpx; 95 | margin-top: 4rpx; 96 | } 97 | 98 | .food-item-price { 99 | margin-top: 14rpx; 100 | color: #f05a86; 101 | } 102 | 103 | .food-item-opt { 104 | margin-top: 40rpx; 105 | } 106 | 107 | 108 | /* 满减区域 */ 109 | 110 | .promotion { 111 | height: 48rpx; 112 | line-height: 48rpx; 113 | background-color: #f3c6ba; 114 | color: #fff7ec; 115 | font-size: 26rpx; 116 | text-align: center; 117 | } 118 | 119 | /* 底部菜单操作 */ 120 | 121 | .operate { 122 | height: 110rpx; 123 | display: flex; 124 | } 125 | 126 | .operate-shopcart { 127 | width: 74%; 128 | padding: 10rpx; 129 | background-color: #464646; 130 | } 131 | 132 | .operate-submit { 133 | width: 26%; 134 | font-size: 30rpx; 135 | background: #eee; 136 | color: #aaa; 137 | text-align: center; 138 | line-height: 110rpx; 139 | } 140 | 141 | .operate-submit-activity { 142 | background: #f24; 143 | color: #fff; 144 | } 145 | 146 | .operate-shopcart { 147 | display: flex; 148 | } 149 | 150 | .cart-num { 151 | height: 38rpx; 152 | padding: 2rpx 14rpx; 153 | border-radius: 50%; 154 | background: red; 155 | color: white; 156 | font-size: 28rpx; 157 | text-align: center; 158 | top: 0px; 159 | right: -10rpx; 160 | } 161 | 162 | .operate-shopcart-ball { 163 | width: 36rpx; 164 | height: 36rpx; 165 | position: fixed; 166 | border-radius: 50%; 167 | left: 50%; 168 | top: 50%; 169 | background: #f24; 170 | } 171 | 172 | .operate-shopcart-empty { 173 | color: #a9a9a9; 174 | line-height: 88rpx; 175 | font-size: 30rpx; 176 | margin-left: 20rpx; 177 | } 178 | 179 | .operate-shopcart-price { 180 | display: flex; 181 | } 182 | 183 | .operate-shopcart-price > view { 184 | font-size: 40rpx; 185 | line-height: 88rpx; 186 | margin-left: 25rpx; 187 | color: #fff; 188 | } 189 | 190 | .operate-shopcart-price > text { 191 | font-size: 24rpx; 192 | line-height: 92rpx; 193 | margin-left: 15rpx; 194 | color: #aaa; 195 | text-decoration: line-through; 196 | } 197 | 198 | .shopcart { 199 | position: fixed; 200 | top: 0; 201 | left: 0; 202 | bottom: 149rpx; 203 | right: 0; 204 | font-size: 28rpx; 205 | } 206 | 207 | .shopcart-mask { 208 | position: absolute; 209 | top: 0; 210 | right: 0; 211 | bottom: 0; 212 | left: 0; 213 | background: #000; 214 | opacity: 0.5; 215 | } 216 | 217 | .shopcart-wrap { 218 | position: absolute; 219 | width: 100%; 220 | max-height: 90%; 221 | bottom: 0; 222 | background: #fff; 223 | overflow: scroll; 224 | } 225 | 226 | .shopcart-head { 227 | position: fixed; 228 | width: 100%; 229 | background: #f0f0f0; 230 | color: #878787; 231 | line-height: 100rpx; 232 | font-size: 26rpx; 233 | overflow: hidden; 234 | } 235 | 236 | .shopcart-head-title { 237 | float: left; 238 | margin-left: 40rpx; 239 | } 240 | 241 | .shopcart-head-title:before { 242 | background: #f24; 243 | width: 8rpx; 244 | height: 32rpx; 245 | content: ""; 246 | display: inline-block; 247 | margin-right: 10rpx; 248 | position: relative; 249 | top: 6rpx; 250 | } 251 | 252 | .shopcart-head-clean { 253 | float: right; 254 | margin-right: 20rpx; 255 | } 256 | 257 | .shopcart-head-clean > i:before { 258 | content: "\e61b"; 259 | position: relative; 260 | top: 2rpx; 261 | } 262 | 263 | .shopcart-list { 264 | margin-top: 101rpx; 265 | } 266 | 267 | .shopcart-item { 268 | display: flex; 269 | padding: 30rpx 20rpx; 270 | line-height: 58rpx; 271 | } 272 | 273 | .shopcart-item > view { 274 | margin-left: 20rpx; 275 | } 276 | 277 | .shopcart-item:not(:last-child) { 278 | border-bottom: 1rpx solid #e3e3e3; 279 | } 280 | 281 | .shopcart-item-name { 282 | flex: 1; 283 | } 284 | 285 | .shopcart-item-price { 286 | color: #f24; 287 | } 288 | 289 | .shopcart-item-number { 290 | display: flex; 291 | } 292 | 293 | .shopcart-item-number > view { 294 | margin: 0 10rpx; 295 | } 296 | 297 | .shopcart-icon-dec:before { 298 | content: "\e61a"; 299 | font-size: 44rpx; 300 | color: #888; 301 | } 302 | 303 | .shopcart-icon-add:before { 304 | content: "\e728"; 305 | font-size: 44rpx; 306 | color: #f24; 307 | } 308 | 309 | .iconfont { 310 | width: 60rpx; 311 | height: 60rpx; 312 | } 313 | 314 | .cart-icon { 315 | margin-top: 15rpx; 316 | } 317 | 318 | .add-icon { 319 | width: 56rpx; 320 | height: 56rpx; 321 | } 322 | 323 | .dec-icon { 324 | width:38rpx; 325 | height: 38rpx; 326 | padding: 10rpx; 327 | } 328 | 329 | .del-icon { 330 | margin-left: 14rpx; 331 | width:48rpx; 332 | height: 48rpx; 333 | padding: 6rpx; 334 | } -------------------------------------------------------------------------------- /pages/order/checkout/checkout.js: -------------------------------------------------------------------------------- 1 | const app = getApp() 2 | const fetch = app.fetch 3 | 4 | Page({ 5 | data: { 6 | comment: '' 7 | }, 8 | 9 | onLoad: function (options) { 10 | var id = options.order_id 11 | wx.showLoading({ 12 | title: '努力加载中...', 13 | }) 14 | fetch('food/order', { 15 | id, 16 | }).then(data => { 17 | this.setData(data) 18 | wx.hideLoading() 19 | }, () => { 20 | this.onLoad(options) 21 | }) 22 | }, 23 | 24 | pay: function () { 25 | var id = this.data.id; 26 | wx.showLoading({ 27 | title: '正在支付...', 28 | }) 29 | fetch('food/order', { 30 | id, 31 | comment: this.data.comment 32 | }, 'POST').then(data => { 33 | return fetch('food/pay', { 34 | id 35 | }, 'POST') 36 | }).then(data => { 37 | wx.hideLoading() 38 | wx.showToast({ 39 | title: '支付成功', 40 | icon: 'success', 41 | duration: 2000, 42 | success: () => { 43 | wx.navigateTo({ 44 | url: '/pages/order/detail/detail?order_id=' + id, 45 | }) 46 | } 47 | }) 48 | }).catch(() => { 49 | // 支付失败 50 | this.pay() 51 | }) 52 | }, 53 | 54 | comment: function (e) { 55 | this.data.comment = e.detail.value; 56 | } 57 | }) -------------------------------------------------------------------------------- /pages/order/checkout/checkout.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": "确认订单", 3 | "usingComponents": {} 4 | } -------------------------------------------------------------------------------- /pages/order/checkout/checkout.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 请确认您的订单 4 | 5 | 订单详情 6 | 7 | 8 | 9 | 10 | 11 | 12 | {{item.name}} 13 | x {{item.number}} 14 | 15 | 16 | {{priceFormat(item.price)}} 17 | 18 | 19 | 20 | 21 | 满减优惠 22 | 23 | - {{priceFormat(promotion)}} 24 | 25 | 26 | 27 | 小计 28 | {{priceFormat(price)}} 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 合计: {{priceFormat(price)}} 40 | 支付订单 41 | 42 | 43 | 44 | module.exports = function(price) { 45 | return '¥ ' + parseFloat(price) 46 | } 47 | 48 | 49 | 50 | module.exports = function(promotion) { 51 | return parseFloat(promotion) > 0 52 | } 53 | -------------------------------------------------------------------------------- /pages/order/checkout/checkout.wxss: -------------------------------------------------------------------------------- 1 | /* pages/order/checkout/checkout.wxss */ 2 | page { 3 | display: flex; 4 | flex-direction: column; 5 | height: 100%; 6 | background-color: #f8f8f8; 7 | } 8 | 9 | .content { 10 | flex: 1; 11 | overflow: scroll; 12 | margin-bottom: 40rpx; 13 | } 14 | 15 | .content-title { 16 | height: 80rpx; 17 | line-height: 80rpx; 18 | font-size: 26rpx; 19 | background-color: #fff; 20 | padding: 0 20rpx; 21 | } 22 | 23 | .order { 24 | background-color: #fff; 25 | margin-top: 20rpx; 26 | } 27 | 28 | .order-title { 29 | font-size: 24rpx; 30 | color: #a2a1a0; 31 | padding: 24rpx; 32 | } 33 | 34 | .order-list { 35 | padding: 0 30rpx; 36 | } 37 | 38 | .order-item { 39 | background-color: #fff; 40 | display: flex; 41 | font-size: 32rpx; 42 | padding: 25rpx 0; 43 | border-top: 1px solid #e3e3e3; 44 | } 45 | 46 | .order-item-l { 47 | flex: 1; 48 | display: flex; 49 | } 50 | 51 | .order-item-image { 52 | width: 94rpx; 53 | height: 94rpx; 54 | margin-right: 25rpx; 55 | } 56 | 57 | .order-item-number { 58 | color: #8f8f8f; 59 | margin-top: 4rpx; 60 | font-size: 30rpx; 61 | } 62 | 63 | .order-promotion-icon { 64 | display: inline-block; 65 | background-color: rgb(255, 145, 0); 66 | color: #fff; 67 | padding: 2rpx 6rpx 6rpx; 68 | font-size: 28rpx; 69 | margin-right: 8rpx; 70 | } 71 | 72 | .order-promotion-price { 73 | color: #f24; 74 | } 75 | 76 | .order-total-price { 77 | font-size: 40rpx; 78 | color: #f24; 79 | } 80 | 81 | .operate { 82 | height: 110rpx; 83 | display: flex; 84 | } 85 | 86 | .operate-info { 87 | width: 74%; 88 | background-color: #353535; 89 | color: #fff; 90 | line-height: 110rpx; 91 | padding-left: 40rpx; 92 | } 93 | 94 | .operate-btn { 95 | width: 26%; 96 | font-size: 30rpx; 97 | text-align: center; 98 | line-height: 110rpx; 99 | background-color: #f24; 100 | color: #fff; 101 | } 102 | 103 | .content-comment { 104 | padding: 10rpx 30rpx 20rpx; 105 | background-color: #fff; 106 | margin-top: 20rpx; 107 | } 108 | 109 | .content-comment>label { 110 | font-size: 32rpx; 111 | color: #a3a3a3; 112 | } 113 | 114 | .content-comment textarea { 115 | width: 95%; 116 | font-size: 24rpx; 117 | background-color: #f2f2f2; 118 | padding: 20rpx; 119 | height: 160rpx; 120 | margin-top: 10rpx; 121 | border-radius: 10rpx; 122 | } -------------------------------------------------------------------------------- /pages/order/detail/detail.js: -------------------------------------------------------------------------------- 1 | // pages/order/detail/detail.js 2 | const app = getApp() 3 | const fetch = app.fetch 4 | 5 | Page({ 6 | data: { 7 | 8 | }, 9 | 10 | onLoad: function (options) { 11 | var id = options.order_id; 12 | wx.showLoading({ 13 | title: '努力加载中...', 14 | }) 15 | fetch('food/order', { 16 | id, 17 | }).then(data => { 18 | this.setData(data) 19 | wx.hideLoading() 20 | }, () => { 21 | // 失败 22 | this.onLoad(options) 23 | }) 24 | }, 25 | 26 | onUnload: function () { 27 | wx.switchTab({ 28 | url: '/pages/order/list/list', 29 | }) 30 | }, 31 | 32 | }) -------------------------------------------------------------------------------- /pages/order/detail/detail.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {} 3 | } -------------------------------------------------------------------------------- /pages/order/detail/detail.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 取餐号 5 | 6 | 7 | {{code}} 8 | 美食正在制作中... 9 | 10 | 备注: {{comment}} 11 | 稍等片刻,美味马上就好 (。・ω・。)ノ♡ 12 | 13 | 14 | 15 | 16 | 17 | 订单详情 18 | 19 | 20 | 21 | 22 | 23 | 24 | {{item.name}} 25 | x {{item.number}} 26 | 27 | 28 | {{priceFormat(item.price)}} 29 | 30 | 31 | 32 | 33 | 满减优惠 34 | 35 | - {{priceFormat(promotion)}} 36 | 37 | 38 | 39 | 小计 40 | {{priceFormat(price)}} 41 | 42 | 43 | 44 | 45 | 46 | 47 | 订单号码 48 | {{sn}} 49 | 50 | 51 | 下单时间 52 | {{create_time}} 53 | 54 | 55 | 付款时间 56 | {{sn}} 57 | 58 | 59 | 取餐时间 60 | {{taken_time}} 61 | 62 | 63 | 64 | 取餐号为 {{code}} 的顾客,您已取餐 65 | 请凭此页面至取餐台取餐~ 66 | 67 | 68 | module.exports = function(price) { 69 | return '¥ ' + parseFloat(price) 70 | } 71 | 72 | 73 | 74 | module.exports = function(promotion) { 75 | return parseFloat(promotion) > 0 76 | } 77 | -------------------------------------------------------------------------------- /pages/order/detail/detail.wxss: -------------------------------------------------------------------------------- 1 | /* pages/order/detail/detail.wxss */ 2 | page { 3 | background-color: #f8f8f8; 4 | } 5 | 6 | .card { 7 | margin: 20rpx auto; 8 | width: 96%; 9 | background-color: #fef9f4; 10 | display: flex; 11 | font-size: 30rpx; 12 | } 13 | 14 | .card-title { 15 | width: 28rpx; 16 | padding: 0 30rpx; 17 | background-color: rgb(255, 115, 0); 18 | color: #fff; 19 | border-left: 1rpx solid #de5f4b; 20 | font-size: 28rpx; 21 | display: flex; 22 | align-items: center; 23 | } 24 | 25 | .card-content { 26 | flex: 1; 27 | margin-left: 50rpx; 28 | } 29 | 30 | .card-info { 31 | margin-left: 10rpx; 32 | } 33 | 34 | .card-code { 35 | font-size: 60rpx; 36 | margin-right: 40rpx; 37 | } 38 | 39 | .card-info-r { 40 | font-size: 24rpx; 41 | color: rgb(255, 133, 34); 42 | } 43 | 44 | .card-comment { 45 | color: #de5f4b; 46 | font-weight: 600; 47 | margin-top: 8rpx; 48 | } 49 | 50 | .card-tips { 51 | color: #a2a1a0; 52 | margin: 10rpx 0 20rpx; 53 | font-size: 24rpx; 54 | } 55 | 56 | .order { 57 | background-color: #fff; 58 | margin-top: 20rpx; 59 | } 60 | 61 | .order-title { 62 | font-size: 24rpx; 63 | color: #a2a1a0; 64 | padding: 24rpx; 65 | } 66 | 67 | .order-list { 68 | padding: 0 30rpx; 69 | } 70 | 71 | .order-item { 72 | background-color: #fff; 73 | display: flex; 74 | font-size: 32rpx; 75 | padding: 25rpx 0; 76 | border-top: 1px solid #e3e3e3; 77 | } 78 | 79 | .order-item-l { 80 | flex: 1; 81 | display: flex; 82 | } 83 | 84 | .order-item-image { 85 | width: 94rpx; 86 | height: 94rpx; 87 | margin-right: 25rpx; 88 | } 89 | 90 | .order-item-number { 91 | color: #8f8f8f; 92 | margin-top: 4rpx; 93 | font-size: 30rpx; 94 | } 95 | 96 | .order-promotion-icon { 97 | display: inline-block; 98 | background-color: rgb(255, 145, 0); 99 | color: #fff; 100 | padding: 2rpx 6rpx 6rpx; 101 | font-size: 28rpx; 102 | margin-right: 8rpx; 103 | } 104 | 105 | .order-promotion-price { 106 | color: #f24; 107 | } 108 | 109 | .order-total-price { 110 | font-size: 40rpx; 111 | color: #f24; 112 | } 113 | 114 | .list { 115 | background-color: #fff; 116 | margin-top: 20rpx; 117 | } 118 | 119 | .list-title { 120 | font-size: 30rpx; 121 | color: #818181; 122 | padding: 20rpx; 123 | border-bottom: 1rpx solid #e3e3e3; 124 | display: flex; 125 | } 126 | 127 | .list-title:last-child { 128 | border-bottom: none; 129 | } 130 | 131 | .list-info { 132 | color: #000; 133 | margin-left: 20rpx; 134 | } 135 | 136 | .tips { 137 | width: 90%; 138 | text-align: center; 139 | margin: 20rpx auto; 140 | padding: 12rpx 20rpx; 141 | background-color: #f24; 142 | color: #fff; 143 | font-size: 32rpx; 144 | border-radius: 10rpx; 145 | } -------------------------------------------------------------------------------- /pages/order/list/list.js: -------------------------------------------------------------------------------- 1 | const app = getApp() 2 | const fetch = app.fetch 3 | 4 | Page({ 5 | data: { 6 | order: {}, 7 | is_last: true 8 | }, 9 | row: 10, 10 | 11 | onLoad: function (options) { 12 | wx.showLoading({ 13 | title: '加载中...', 14 | }) 15 | this.loadData({ 16 | last_id: 0, 17 | success: data => { 18 | this.setData({ 19 | order: data.list 20 | }, () => { 21 | wx.hideLoading() 22 | }) 23 | }, 24 | fail: () => { 25 | this.onLoad() 26 | } 27 | }) 28 | }, 29 | 30 | onShow: function () { 31 | if (this.enableRefresh) { 32 | this.onLoad() 33 | // 刷新订单后页面滚动至顶部 34 | wx.pageScrollTo({ 35 | scrollTop: 0 36 | }) 37 | } else { 38 | this.enableRefresh = true 39 | } 40 | }, 41 | // 是否启用自动刷新 42 | enableRefresh: false, 43 | 44 | // 上拉刷新 45 | onPullDownRefresh: function() { 46 | wx.showLoading({ 47 | title: '加载中...' 48 | }) 49 | this.loadData({ 50 | last_id: 0, 51 | success: data => { 52 | this.setData({ 53 | order: data.list 54 | }, () => { 55 | wx.hideLoading() 56 | wx.stopPullDownRefresh() 57 | }) 58 | } 59 | }) 60 | }, 61 | 62 | // 下拉触底 63 | onReachBottom: function() { 64 | // 下拉到底不再加载数据 65 | if(this.data.is_las){ 66 | return 67 | } 68 | this.loadData({ 69 | last_id: this.last_id, 70 | success: data => { 71 | var order = this.data.order 72 | data.list.forEach(item => { 73 | order.push(item) 74 | }) 75 | this.setData({ 76 | order, 77 | }) 78 | }, 79 | fail: () => { 80 | this.onReachBottom() 81 | } 82 | }) 83 | }, 84 | 85 | loadData: function (options) { 86 | wx.showNavigationBarLoading() 87 | fetch('food/orderlist', { 88 | last_id: options.last_id, 89 | row: this.row 90 | }).then(data => { 91 | this.last_id = data.last_id 92 | // 判断是否到底 93 | this.setData({ 94 | is_last: data.list.length < this.row 95 | }) 96 | wx.hideNavigationBarLoading() 97 | options.success(data) 98 | }, () => { 99 | options.fail() 100 | }) 101 | }, 102 | 103 | detail: function (e) { 104 | var id = e.currentTarget.dataset.id 105 | wx.navigateTo({ 106 | url: '/pages/order/detail/detail?order_id=' + id, 107 | }) 108 | }, 109 | 110 | start: function () { 111 | wx.navigateTo({ 112 | url: '/pages/list/list' 113 | }) 114 | } 115 | }) -------------------------------------------------------------------------------- /pages/order/list/list.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": "我的订单", 3 | "enablePullDownRefresh": true, 4 | "usingComponents": {} 5 | } -------------------------------------------------------------------------------- /pages/order/list/list.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 您还没有下过订单~\n快开启您的点餐之旅吧! 5 | 6 | 7 | 8 | 9 | 下单时间: {{formatData(item.create_time)}} 10 | 11 | {{item.first_food_name}} 12 | 13 | 14 | 等{{item.number}}件商品 15 | {{priceFormat(item.price)}} 16 | 17 | 18 | 19 | 20 | 订单详情 21 | 已取餐 22 | 未取餐 23 | 24 | 25 | 26 | 我也是有底线的! 27 | 加载中... 28 | 29 | 30 | 31 | module.exports = function(price) { 32 | return '¥ ' + parseFloat(price) 33 | } 34 | 35 | 36 | 37 | module.exports = function(time) { 38 | var date = getDate(time) 39 | var y = date.getFullYear() 40 | var m = date.getMonth() + 1 41 | var d = date.getDate() 42 | var h = date.getHours() 43 | var i = date.getMinutes() 44 | var s = date.getSeconds() 45 | return [y, m, d].map(formatNumber).join('-') + ' ' + [h, i, s].map(formatNumber).join(':') 46 | } 47 | 48 | function formatNumber(n) { 49 | n = n.toString() 50 | return n[1] ? n : '0' + n 51 | } 52 | -------------------------------------------------------------------------------- /pages/order/list/list.wxss: -------------------------------------------------------------------------------- 1 | /* pages/order/list/list.wxss */ 2 | 3 | page { 4 | background-color: #f8f8f8; 5 | } 6 | 7 | .list-empty { 8 | margin-top: 80rpx; 9 | text-align: center; 10 | color: #666; 11 | font-size: 40rpx; 12 | } 13 | 14 | .menu-start { 15 | margin: 30rpx; 16 | border-radius: 80rpx; 17 | background-color: #f24; 18 | color: #fff; 19 | } 20 | 21 | 22 | .list-item { 23 | display: flex; 24 | padding: 20rpx; 25 | color: #999; 26 | font-size: 26rpx; 27 | border-bottom: 1rpx solid #ececec; 28 | } 29 | 30 | .list-item:last-child { 31 | border-bottom: none; 32 | } 33 | 34 | .list-item-l { 35 | flex: 1; 36 | } 37 | 38 | .list-item-name { 39 | font-size: 30rpx; 40 | color: #666; 41 | margin-right: 20rpx; 42 | margin-bottom: 10rpx; 43 | } 44 | 45 | .list-item-price { 46 | color: #f24; 47 | margin-left: 20rpx; 48 | font-weight: 600; 49 | } 50 | 51 | .list-item-t { 52 | margin-bottom: 10rpx; 53 | } 54 | 55 | .list-item-r >view { 56 | display: flex; 57 | margin-top: 30rpx; 58 | } 59 | 60 | .list-item-detail { 61 | text-align: center; 62 | color: #f24; 63 | font-size: 24rpx; 64 | padding: 17rpx 10rpx; 65 | background-color: #fff; 66 | border: 1rpx solid #f24; 67 | } 68 | 69 | .list-item-taken { 70 | text-align: center; 71 | color: #fff; 72 | font-size: 24rpx; 73 | padding: 17rpx 10rpx; 74 | margin-left: 20rpx; 75 | background-color: #f24; 76 | } 77 | 78 | .taken-yes { 79 | background-color: #e7e6e4; 80 | color: rgb(95, 92, 92); 81 | } 82 | 83 | .list-item-last { 84 | display: block; 85 | text-align: center; 86 | } -------------------------------------------------------------------------------- /pages/record/record.js: -------------------------------------------------------------------------------- 1 | // pages/record/record.js 2 | const app = getApp() 3 | const fetch = app.fetch 4 | 5 | Page({ 6 | data: { 7 | userInfo: {}, 8 | hasUserInfo: false, 9 | canIUse: wx.canIUse('button.open-type.getUserInfo') 10 | }, 11 | 12 | onLoad: function (options) { 13 | wx.showLoading({ 14 | title: '努力加载中...', 15 | }) 16 | fetch('food/record').then(data => { 17 | wx.hideLoading() 18 | this.setData(data) 19 | }) 20 | 21 | // 登录 22 | if (app.globalData.userInfo) { 23 | this.setData({ 24 | userInfo: app.globalData.userInfo, 25 | hasUserInfo: true 26 | }) 27 | } else if (this.data.canIUse) { 28 | // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 29 | // 所以此处加入 callback 以防止这种情况 30 | app.userInfoReadyCallback = res => { 31 | this.setData({ 32 | userInfo: res.userInfo, 33 | hasUserInfo: true 34 | }) 35 | } 36 | } else { 37 | // 在没有 open-type=getUserInfo 版本的兼容处理 38 | wx.getUserInfo({ 39 | success: res => { 40 | app.globalData.userInfo = res.userInfo 41 | this.setData({ 42 | userInfo: res.userInfo, 43 | hasUserInfo: true 44 | }) 45 | } 46 | }) 47 | } 48 | }, 49 | 50 | getUserInfo: function (e) { 51 | console.log(e) 52 | app.globalData.userInfo = e.detail.userInfo 53 | this.setData({ 54 | userInfo: e.detail.userInfo, 55 | hasUserInfo: true 56 | }) 57 | }, 58 | 59 | enableRefresh: false, 60 | onShow: function () { 61 | if (this.enableRefresh) { 62 | this.onLoad() 63 | } else { 64 | this.enableRefresh = true 65 | } 66 | } 67 | }) -------------------------------------------------------------------------------- /pages/record/record.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": "个人中心", 3 | "usingComponents": {} 4 | } -------------------------------------------------------------------------------- /pages/record/record.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 欢迎你,{{userInfo.nickName}}! 10 | 11 | 12 | 13 | 16 | 17 | 18 | 消费记录 19 | 20 | 21 | 消费 22 | {{item.pay_time}} 23 | 24 | 25 | {{priceFormat(item.price)}} 26 | 27 | 28 | 29 | 30 | 31 | module.exports = function(price) { 32 | return '¥ ' + parseFloat(price) 33 | } 34 | -------------------------------------------------------------------------------- /pages/record/record.wxss: -------------------------------------------------------------------------------- 1 | /* pages/record/record.wxss */ 2 | page { 3 | background-color: #f8f8f8; 4 | font-size: 32rpx; 5 | } 6 | 7 | /* .head { 8 | width: 100%; 9 | background-color: #f24; 10 | height: 400rpx; 11 | display: flex; 12 | justify-content: center; 13 | align-items: center; 14 | } 15 | 16 | .head > .avatar { 17 | width: 200rpx; 18 | height: 200rpx; 19 | border-radius: 50%; 20 | background-color: #fff; 21 | border: 10rpx solid rgba(0, 0, 0, 0.1); 22 | overflow: hidden; 23 | } */ 24 | 25 | .list-title { 26 | background-color: #fff; 27 | padding: 16rpx 0; 28 | text-align: center; 29 | } 30 | 31 | .list-item { 32 | display: flex; 33 | padding: 42rpx 20rpx; 34 | border-bottom: 1rpx solid #ececec; 35 | } 36 | 37 | .list-item-l { 38 | flex: 1; 39 | } 40 | 41 | .list-item-r { 42 | line-height: 76rpx; 43 | } 44 | 45 | .list-item-r > text { 46 | color: #f24; 47 | font-weight: 600; 48 | font-size: 32rpx; 49 | } 50 | 51 | .list-item-time { 52 | margin-top: 10rpx; 53 | font-size: 26rpx; 54 | color: #999; 55 | } 56 | 57 | /* 授权 */ 58 | .show-user-box { 59 | width: 100%; 60 | background-image: linear-gradient(to top, #fad5ad 0%, #f24 100%); 61 | height: 400rpx; 62 | display: flex; 63 | justify-content: center; 64 | align-items: center; 65 | } 66 | 67 | .userinfo>.userinfo-btn { 68 | width: 300rpx; 69 | height: 80rpx; 70 | margin-top: 50rpx; 71 | border-radius: 80rpx; 72 | background-color: #fff; 73 | } 74 | 75 | .userinfo { 76 | display: flex; 77 | flex-direction: column; 78 | align-items: center; 79 | } 80 | 81 | .userinfo-avatar { 82 | width: 200rpx; 83 | height: 200rpx; 84 | margin-bottom: 40rpx; 85 | border-radius: 50%; 86 | background-color: #fff; 87 | border: 10rpx solid rgba(0, 0, 0, 0.1); 88 | } 89 | 90 | .userinfo-nickname { 91 | color: rgb(75, 75, 75); 92 | font-size: 36rpx; 93 | border: 1rpx solid rgb(219, 219, 219); 94 | padding: 8rpx 30rpx; 95 | border-radius: 40rpx; 96 | background-color: rgba(255, 255, 255, 0.664); 97 | } -------------------------------------------------------------------------------- /project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "setting": { 3 | "urlCheck": false, 4 | "es6": true, 5 | "enhance": true, 6 | "postcss": true, 7 | "preloadBackgroundData": false, 8 | "minified": true, 9 | "newFeature": true, 10 | "coverView": true, 11 | "autoAudits": false, 12 | "showShadowRootInWxmlPanel": true, 13 | "scopeDataCheck": false, 14 | "checkInvalidKey": true, 15 | "checkSiteMap": true, 16 | "uploadWithSourceMap": true, 17 | "babelSetting": { 18 | "ignore": [], 19 | "disablePlugins": [], 20 | "outputPath": "" 21 | }, 22 | "useCompilerModule": true, 23 | "userConfirmedUseCompilerModuleSwitch": false 24 | }, 25 | "appid": "", 26 | "projectname": "Order%20system", 27 | "libVersion": "2.8.1", 28 | "simulatorType": "wechat", 29 | "simulatorPluginLibVersion": {}, 30 | "condition": { 31 | "search": { 32 | "current": -1, 33 | "list": [] 34 | }, 35 | "conversation": { 36 | "current": -1, 37 | "list": [] 38 | }, 39 | "plugin": { 40 | "current": -1, 41 | "list": [] 42 | }, 43 | "game": { 44 | "list": [] 45 | }, 46 | "gamePlugin": { 47 | "current": -1, 48 | "list": [] 49 | }, 50 | "miniprogram": { 51 | "current": 0, 52 | "list": [ 53 | { 54 | "id": -1, 55 | "name": "db guide", 56 | "pathName": "pages/databaseGuide/databaseGuide", 57 | "query": "" 58 | }, 59 | { 60 | "id": -1, 61 | "name": "pages/list/list", 62 | "pathName": "pages/list/list", 63 | "query": "", 64 | "scene": null 65 | }, 66 | { 67 | "id": 2, 68 | "name": "pages/order/list/list", 69 | "pathName": "pages/order/list/list", 70 | "query": "order_id=3", 71 | "scene": null 72 | }, 73 | { 74 | "id": 3, 75 | "name": "pages/order/checkout/checkout", 76 | "pathName": "pages/order/checkout/checkout", 77 | "query": "order_id=1", 78 | "scene": null 79 | }, 80 | { 81 | "id": 4, 82 | "name": "pages/order/checkout/checkout", 83 | "pathName": "pages/order/checkout/checkout", 84 | "query": "order_id=4", 85 | "scene": null 86 | }, 87 | { 88 | "id": 5, 89 | "name": "pages/order/detail/detail", 90 | "pathName": "pages/order/detail/detail", 91 | "query": "order_id=5", 92 | "scene": null 93 | }, 94 | { 95 | "id": 6, 96 | "name": "pages/record/record", 97 | "pathName": "pages/record/record", 98 | "query": "", 99 | "scene": null 100 | } 101 | ] 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /sitemap.json: -------------------------------------------------------------------------------- 1 | { 2 | "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html", 3 | "rules": [{ 4 | "action": "allow", 5 | "page": "*" 6 | }] 7 | } -------------------------------------------------------------------------------- /utils/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | url: 'http://localhost/api/' 3 | } -------------------------------------------------------------------------------- /utils/fetch.js: -------------------------------------------------------------------------------- 1 | const config = require('./config'); 2 | module.exports = function (path, data, method) { 3 | var sess = wx.getStorageSync('PHPSESSID') 4 | return new Promise ((resolve, reject) => { 5 | wx.request({ 6 | url: config.url + path, 7 | method, 8 | data, 9 | header: { 10 | 'Content-Type': 'json', 11 | 'X-Requested-With': 'XMLHttpRequest', 12 | 'Cookie': sess ? 'PHPSESSID=' + sess : '' 13 | }, 14 | success: res => { 15 | if (res.header['Set-Cookie'] !== undefined) { 16 | sess = decodeCookie(res.header['Set-Cookie'])['PHPSESSID'] 17 | wx.setStorageSync('PHPSESSID', sess) 18 | } 19 | // 请求成功 20 | if (res.statusCode !== 200) { 21 | fail('服务器异常!', reject) 22 | return 23 | } 24 | if (res.data.code === 0) { 25 | fail(res.data.msg, reject) 26 | return 27 | } 28 | resolve(res.data); 29 | }, 30 | fail: (e) => { 31 | console.log(e) 32 | // 请求失败 33 | fail('加载数据失败', reject) 34 | } 35 | }) 36 | }) 37 | } 38 | 39 | function fail(title, callback) { 40 | wx.hideLoading() 41 | wx.showModal({ 42 | title, 43 | confirmText: '重试', 44 | success: res => { 45 | if (res.confirm) { 46 | callback() 47 | } 48 | } 49 | }) 50 | } 51 | 52 | function decodeCookie(cookie) { 53 | var obj = {} 54 | cookie.split(',').forEach((item) => { 55 | item.split(';').forEach((item) => { 56 | var arr = item.split('=') 57 | obj[arr[0]] = arr[1] !== undefined ? decodeURIComponent(arr[1]) : true 58 | }) 59 | }) 60 | return obj 61 | } --------------------------------------------------------------------------------