首页生成礼包
需求:用户选择好要送的礼品过后,可以选择开奖方式,有直接开奖,满人开奖,以及定时开奖三种开奖方式,当订单创建完成后,请求支付,支付成功后,跳转到支付结果页,ps:这里支付需要商户号,所以创建订单后,直接支付成功。
小程序端
1 当用户点击生成礼包的时候,必须保证用户是登入状态,将订单信息发送给后端,创建订单后,跳转到支付结果页。
app.json
{ "pages": [ "pages/index/index", "pages/list/list", "pages/item/item", "pages/login/login" ], "window": { "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#e50e38", "navigationBarTitleText": "百步生活", "navigationBarTextStyle": "#fff", "enablePullDownRefresh": false, "backgroundColor": "#e50e38" }, }
index.json
{ "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#e50e38", "navigationBarTitleText": "百步Gift", "navigationBarTextStyle": "white", "enablePullDownRefresh": false }
index.wxml
<!--index.wxml--> <view class="container"> <view class="top"> <text class="text1">微信送礼新方式</text> <text class="text2">微信上送礼·对方填地址·免邮送上门</text> <navigator url="/pages/guide/guide" class="guide">操作指南</navigator> </view> <block wx:if="{{gifts.length>0}}"> <view class="gift-lists"> <block wx:for="{{gifts}}" wx:for-index="index" wx:key="key"> <view class="item"> <image class="item-img" src="{{item.img}}"></image> <view class="caption"> <view class="name">{{item.name}}</view> <view class="brief">{{item.brief}}</view> <view class="price">¥{{item.price}}</view> </view> <view class="btn-group"> <view class="minus" bindtap='minusAction' data-id="{{item.product_id}}">-</view> <input type="number" disabled class="ipt" value="{{item.num}}"></input> <view class="plus" bindtap='plusAction' data-id="{{item.product_id}}">+</view> </view> </view> </block> <view class="gift-total"> <text class="num">共{{totalgiftsNum}}件礼物</text> <text bindtap='bindViewTap' class="add">继续添加></text> </view> </view> </block> <block wx:else> <view class="no-product" bindtap='bindViewTap'> <image class="gift-icon1" src='../../images/purplebox.png'></image> <view class="none-tip"> <text class="tip1">开始挑选礼物</text> <text class="tip2">点击这里,挑选喜欢的礼物</text> </view> </view> </block> <view class="selectType"> <view class="typeName">{{gifttype}}</view> <view class="selectBtn" bindtap='selectType'>更改玩法></view> </view> <block wx:if="{{gifttype=='定时开奖'}}"> <picker mode="multiSelector" bindchange="bindMultiPickerChange" bindcolumnchange="bindMultiPickerColumnChange" value="{{multiIndex}}" range="{{multiArray}}" class="typeIpt"> <image src="../../images/ipt-icon1.png" class="icon"></image> <view class="tip">定时开奖</view> <view class="timer"> {{multiArray[0][multiIndex[0]]}} {{multiArray[1][multiIndex[1]]}}:{{multiArray[2][multiIndex[2]]}}</view> </picker> </block> <block wx:elif="{{gifttype=='满人开奖'}}"> <view class="typeIpt"> <image src="../../images/ipt-icon1.png" class="icon"></image> <view class="tip">开奖人数</view> <view class="ipt-wrap"><input bindinput="personChange" class="num" value="{{personNum}}" maxlength="3" placeholder='人数' type="number"></input>人</view> </view> </block> <block wx:else> <view bindtap='selectType' class="typeIpt"> <image src="../../images/ipt-icon1.png" class="icon"></image> <view class="tip">每人最多可领一份礼物</view> </view> </block> <view class="selectType"> <view class="typeName">传达心意,写祝福语</view> </view> <textarea show-confirm-bar="false" class="wish" auto-height placeholder="大吉大利,送你好礼" placeholder-style="color:#ccc;" value="{{wish}}" bindinput="bindwish"/> <view class="total-price">¥<text class="price">{{totalPrice}}</text></view> <button class="btn-finish" bindtap='getRedPackage'>生成礼物红包</button> <view class="bottom"> <navigator class="guide" url="/pages/guide/guide" hover-class="navigator-hover">使用说明</navigator> </view> </view>
index.wxss
/**index.wxss**/ page{ background: #f2f2f2; } .container{ padding: 0; background: #f2f2f2; } .top{ height: 360rpx; width: 100%; background: linear-gradient(#e50e38, #f0743e); } .top .text1{ font-size: 40rpx; color: #fff; padding-left:80rpx; position: relative; top: 80rpx; display: block; } .top .text2{ font-size: 30rpx; color: #fff; padding-left:80rpx; position: relative; top: 90rpx; display: block; } .top .guide{ display: inline-block; width: 60rpx; height: 60rpx; border-radius: 50%; background: #f34043; position: absolute; right: 40rpx; top: 40rpx; text-align: center; color: #fff; padding: 20rpx; line-height: 30rpx; font-size: 24rpx; } .userinfo { display: flex; flex-direction: column; align-items: center; } .userinfo-avatar { width: 128rpx; height: 128rpx; margin: 20rpx; border-radius: 50%; } .userinfo-nickname { color: #aaa; } .usermotto { margin-top: 200px; } .swiper { height: 312.5rpx; width: 100%; } .swiper image { height: 100%; width: 100%; } .no-product{ background: #faf1ea; width: 680rpx; height: 160rpx; border-radius:16rpx; position: relative; top:-80rpx; vertical-align: middle; } .no-product .gift-icon1{ width:80rpx; height:80rpx; display:inline-block; vertical-align:middle; padding-top:40rpx; padding-left:40rpx; padding-right:40rpx; } .no-product .none-tip{ display: inline-block; width: 450rpx; position:relative; top:40rpx; } .no-product .none-tip .tip1{ color: #bea272; font-size: 34rpx; display: block; } .no-product .none-tip .tip2{ color: #000; font-size: 30rpx; display: block; position: relative; top: 10rpx; } .gift-lists{ background: #fff; width: 620rpx; border-radius:16rpx; position: relative; top:-80rpx; padding:30rpx; } .gift-lists .item{ margin-bottom: 20rpx; border-bottom: 1px solid #eee; position: relative; padding-bottom:10rpx; } .gift-lists .item .item-img{ width: 140rpx; height: 140rpx; padding-right: 20rpx; } .gift-lists .item .caption{ width: 400rpx; display: inline-block; } .gift-lists .item .name{ width: 400rpx; overflow: hidden; font-size: 28rpx; height: 40rpx; line-height: 40rpx; } .gift-lists .item .brief{ width: 400rpx; overflow: hidden; font-size: 28rpx; height: 40rpx; line-height: 40rpx; color: #ccc; } .gift-lists .item .price{ width: 400rpx; overflow: hidden; font-size: 28rpx; height: 40rpx; line-height: 40rpx; color: #e50e38; } .gift-lists .item .btn-group{ position: absolute; right:0; bottom:10rpx; width:180rpx; } .gift-lists .item .btn-group .minus{ width: 36rpx; height: 36rpx; border-radius: 50%; border: 2rpx solid #ccc; display: inline-block; text-align: center; vertical-align: middle; line-height: 36rpx; color: #ccc; font-size: 28rpx; } .gift-lists .item .btn-group .plus{ width: 36rpx; height: 36rpx; border-radius: 50%; border: 2rpx solid #ccc; display: inline-block; text-align: center; vertical-align: middle; line-height: 36rpx; color: #ccc; font-size: 28rpx; } .gift-lists .item .btn-group .ipt{ width:80rpx; display:inline-block; text-align: center; height: 36rpx; font-size: 28rpx; vertical-align:middle; background: #f9f9f9; margin: 0 6rpx; } .gift-lists .gift-total{ height: 48rpx; } .gift-lists .gift-total .num{ color: #ccc; font-size:28rpx; line-height: 48rpx; vertical-align: middle; } .gift-lists .gift-total .add{ color: #9786ed; font-size:28rpx; float: right; line-height: 48rpx; vertical-align: middle; } .selectType{ width: 620rpx; height: 60rpx; position: relative; top: -80rpx; padding: 10rpx 65rpx; } .selectType .typeName{ font-size: 28rpx; display: inline; vertical-align: middle; line-height:60rpx; } .selectType .selectBtn{ font-size: 28rpx; float: right; vertical-align: middle; line-height: 60rpx; color: #9786ed; } .typeIpt{ background: #fff; width: 620rpx; border-radius:16rpx; position: relative; top:-80rpx; padding:0rpx 30rpx; height: 80rpx; vertical-align: middle; } .typeIpt .ipt-wrap{ font-size: 28rpx; display: inline-block; top: 0; right: 0; z-index: 99; position: absolute; height: 80rpx; vertical-align: middle; line-height: 80rpx; width: 120rpx; color: #000; padding-right:10rpx; } .timer{ font-size: 28rpx; position: absolute; height: 80rpx; vertical-align: middle; line-height: 80rpx; width: 420rpx; color: #000; top: 0; right: 30rpx; text-align: right; } .typeIpt .ipt-wrap .num{ width: 60rpx; display: inline-block; height:80rpx; vertical-align:middle; padding-right: 8rpx; text-align: right; } .typeIpt .icon{ width: 40rpx; height: 40rpx; display: inline-block; padding-right: 10rpx; padding-top: 20rpx; line-height: 80rpx; } .typeIpt .tip{ font-size: 28rpx; color: #ccc; display: inline-block; top: 0; position: absolute; height: 80rpx; vertical-align: middle; line-height: 80rpx; } .wish{ background: #fff; width: 620rpx; border-radius:16rpx; position: relative; padding:10rpx 30rpx; vertical-align: middle; top:-80rpx; color: #ccc; font-size: 32rpx; padding-bottom: 60rpx; } .total-price{ position: relative; top: -66rpx; } .total-price .price{ font-size: 64rpx; padding-left: 10rpx; } .btn-finish{ background: #e50e38; border:none; color: #fff; width: 580rpx; font-size: 32rpx; padding: 8rpx 0; position: relative; top: -60rpx; } .bottom{ padding-bottom: 10rpx; position: relative; top: -40rpx } .bottom .guide{ display: inline-block; font-size: 28rpx; color: #ccc; vertical-align: middle; padding: 0 10rpx; height: 32rpx; } .bottom .agree{ display: inline-block; font-size: 28rpx; color: #ccc; vertical-align: middle; padding: 0 10rpx; height: 32rpx; }
index.js
//index.js //获取应用实例 const app = getApp() Page({ data: { motto: 'Hello World', userInfo: {}, gifttype:'直接送礼', hasUserInfo: false, canIUse: wx.canIUse('button.open-type.getUserInfo'), totalPrice:"0.00", multiArray: ['', '', ''], gifts:[], personNum:3, objectMultiArray: [ [], [], [] ], multiIndex: [0, 0, 0], weekArr:['周日','周一','周二','周三','周四','周五','周六'], wish:'' }, bindwish:function(e){//祝福语保存到本地 var _this = this; _this.data.wish = e.detail.value; wx.setStorageSync('wish', e.detail.value); }, personChange:function(e){//开奖人数修改 var _this = this; var p_num = e.detail.value; _this.data.personNum = p_num; wx.setStorageSync('p_num', e.detail.value); }, getDate:function(){ var _this = this; var _now = new Date();//当前时间 var multi0 ='multiArray['+0+']'; var multi1 = 'multiArray[' + 1 + ']'; var multi2 = 'multiArray[' + 2 + ']'; var nowDayArr = [_this.getMd(0), _this.getMd(1), _this.getMd(2), _this.getMd(3), _this.getMd(4), _this.getMd(5), _this.getMd(6)]; var nowhoursArr = _this.getHour(0); var nowminutesArr = _this.getMin(0); _this.setData({ [multi0]: nowDayArr, [multi1]: nowhoursArr, [multi2]: nowminutesArr }); }, getMd:function(dayNum){//参数1当前时间后第几天int类型 获取月份日期和星期 多列选择第一列 var _this = this; var _now = new Date(); var targetday_milliseconds = _now.getTime() + 1000 * 60 * 60 * 24 * dayNum;//目标日期的时间戳 _now.setTime(targetday_milliseconds);//时间设置 var _str = (_now.getFullYear()) + '年' +((_now.getMonth() + 1) < 10 ? '0' + (_now.getMonth() + 1) : (_now.getMonth() + 1)) + '月' + (_now.getDate() < 10 ? '0' + _now.getDate() : _now.getDate()) + '日 ' + _this.data.weekArr[_now.getDay()]; return _str; }, getHour: function (dayNum) {//时间选择多列第二列小时 var _this = this; var _now = new Date(); var _hour = _now.getHours(); var _minute = _now.getMinutes(); if(dayNum<=0){ var hoursArr = []; var idx = parseInt(_hour); if(_minute>55){//如果已经过了55分钟则从下一个整点开始 for (var i = idx+1; i <= 23; i++) { var _stri = i < 10 ? ('0' + i) : i; hoursArr.push(_stri); } }else{ for (var i = idx; i <= 23; i++) { var _stri = i < 10 ? ('0' + i) : i; hoursArr.push(_stri); } } return hoursArr; }else{ var hoursArr = []; var idx = parseInt(_hour); for (var i = 0; i <= 23; i++) { var _stri = i < 10 ? ('0' + i) : i; hoursArr.push(_stri); } return hoursArr; } }, getMin:function(key){ var _this = this; var _now = new Date(); var _minute = _now.getMinutes(); if(key==0){ var MinutsArr=[]; var idx = Math.ceil(parseInt(_minute)/5); if(idx==12){ for (var i = 0; i < 12; i++) { var _strM = 5 * i < 10 ? ('0' + 5 * i) : 5 * i; MinutsArr.push(_strM); } return MinutsArr; }else{ for (var i = idx; i < 12; i++) { var _strM = 5 * i < 10 ? ('0' + 5 * i) : 5 * i; MinutsArr.push(_strM); }; } return MinutsArr; }else{ var MinutsArr = []; var idx = Math.ceil(parseInt(_minute) / 5); for (var i = 0; i < 12; i++) { var _strM = 5 * i < 10 ? ('0' + 5 * i) : 5 * i; MinutsArr.push(_strM); } return MinutsArr; } }, bindMultiPickerChange: function (e) { //console.log('picker发送选择改变,携带值为', e.detail.value) this.setData({ multiIndex: e.detail.value }) }, bindMultiPickerColumnChange: function (e) { //console.log('修改的列为', e.detail.column, ',值为', e.detail.value); var _this = this; var data = { multiArray: this.data.multiArray, multiIndex: this.data.multiIndex }; data.multiIndex[e.detail.column] = e.detail.value; switch (e.detail.column) {//修改的列 case 0://如果修改的是第一列 switch (data.multiIndex[0]) { case 0://如果第一列的值是第一个 data.multiArray[1] = _this.getHour(0); data.multiArray[2] = _this.getMin(0); break; default://第一列选择的值不是第一个的话后续值都是相同的 data.multiArray[1] = _this.getHour(1); data.multiArray[2] = _this.getMin(1); break; } data.multiIndex[1] = 0; data.multiIndex[2] = 0; break; case 1://如果修改的是第二列 switch (data.multiIndex[0]) { case 0://如果第一列的值是第一个 switch (data.multiIndex[1]) { case 0: data.multiArray[2] = _this.getMin(0); break; default: data.multiArray[2] = _this.getMin(1); break; } break; case 1://如果第一列的值是第二个 data.multiArray[2] = _this.getMin(1); break; } data.multiIndex[2] = 0; break; } this.setData(data); }, //事件处理函数 bindViewTap: function () {//选择商品跳转列表页 wx.navigateTo({ url: '../list/list' }) }, selectType:function(){//选择开奖方式 var _this = this; wx.showActionSheet({ itemList: ['直接送礼', '定时开奖', '满人开奖'], success: function (res) { if(res.tapIndex=="0"){ _this.setData({ gifttype:"直接送礼" }); wx.setStorageSync('gifttype', "直接送礼"); }else if (res.tapIndex == "1") { _this.setData({ gifttype: "定时开奖" }); wx.setStorageSync('gifttype', "定时开奖"); }else if (res.tapIndex == "2") { _this.setData({ gifttype: "满人开奖" }); wx.setStorageSync('gifttype', "满人开奖"); } }, fail: function (res) { console.log(res.errMsg) } }) }, onLoad: function () { var _this = this; _this.getDate(); if (app.globalData.userInfo) { this.setData({ userInfo: app.globalData.userInfo, hasUserInfo: true }) } else if (this.data.canIUse) { // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 app.userInfoReadyCallback = res => { this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } } else { // 在没有 open-type=getUserInfo 版本的兼容处理 wx.getUserInfo({ success: res => { app.globalData.userInfo = res.userInfo this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } }) }; this.setData({ gifts: wx.getStorageSync('gifts') || [], wish: wx.getStorageSync('wish') || '', gifttype: wx.getStorageSync('gifttype') || '直接送礼', personNum: wx.getStorageSync('p_num') || this.data.personNum, },() => {//获取商品总数并且赋值 var _total = 0; var _price = 0; for (var i = 0; i < _this.data.gifts.length;i++){ _total += parseInt(_this.data.gifts[i].num); _price += parseFloat(_this.data.gifts[i].price) * _this.data.gifts[i].num; }; _this.setData({ totalgiftsNum:_total, totalPrice: _price.toFixed(2) }) }); }, minusAction:function(e){//商品减操作 var _this = this; var pid = e.currentTarget.dataset.id; for (var i = 0; i < _this.data.gifts.length; i++) { if (_this.data.gifts[i].product_id == pid) { var num = 'gifts[' + i + '].num'; var numData = parseInt(_this.data.gifts[i].num); numData--; if(numData<=0){ //从数组中删除 var arr = _this.data.gifts; arr.splice(i,1); this.setData({ gifts: arr }, () => {//获取商品总数并且赋值 var _total = 0; var _price = 0; for (var i = 0; i < _this.data.gifts.length; i++) { _total += parseInt(_this.data.gifts[i].num); _price += parseFloat(_this.data.gifts[i].price) * _this.data.gifts[i].num; }; _this.setData({ totalgiftsNum: _total, totalPrice: _price.toFixed(2) }) }) }else{ _this.setData({ [num]: numData }, () => {//获取商品总数并且赋值 var _total = 0; var _price = 0; for (var i = 0; i < _this.data.gifts.length; i++) { _total += parseInt(_this.data.gifts[i].num); _price += parseFloat(_this.data.gifts[i].price) * _this.data.gifts[i].num; }; _this.setData({ totalgiftsNum: _total, totalPrice: _price.toFixed(2) }) }) }; wx.setStorageSync('gifts', _this.data.gifts); return; } } }, plusAction: function (e) {//商品加操作 var _this = this; var pid = e.currentTarget.dataset.id; for (var i = 0; i < _this.data.gifts.length; i++) { if (_this.data.gifts[i].product_id == pid) { var num = 'gifts[' + i + '].num'; var numData = parseInt(_this.data.gifts[i].num); numData++; _this.setData({ [num]: numData }, () => {//获取商品总数并且赋值 var _total = 0; var _price = 0; for (var i = 0; i < _this.data.gifts.length; i++) { _total += parseInt(_this.data.gifts[i].num); _price += parseFloat(_this.data.gifts[i].price) * _this.data.gifts[i].num; }; _this.setData({ totalgiftsNum: _total, totalPrice: _price.toFixed(2) }) }); wx.setStorageSync('gifts', _this.data.gifts); } } }, onShareAppMessage: function () { return { title: '来一场意外的邂逅', path: '/page/user?id=123' } }, // opencamera: function () { // wx.scanCode({ // success: (res) => { // if (res.result) { // wx.navigateTo({ url: res.result }); // } // } // }) // }, checkForm: function () {//提交表单数据验证 var _this = this; var _error_tip = ''; if (_this.data.gifts.length < 1) {//礼物列表是否为空 _error_tip = '请先选择礼物'; wx.showToast({ title: _error_tip, icon: 'none', duration: 2000 }); return false; }; switch (_this.data.gifttype) { case "直接送礼": break; case "定时开奖": var tp = _this.getGiftsTimestamp(); var now = Date.parse(new Date()) / 1000; if (now >= tp) { _error_tip = '开奖时间已过,请重选'; wx.showToast({ title: _error_tip, icon: 'none', duration: 2000 }); return false; } break; case "满人开奖": if (parseInt(_this.data.personNum) < _this.data.gifts.length) { _error_tip = '开奖人数少于礼物数'; wx.showToast({ title: _error_tip, icon: 'none', duration: 2000 }); return false; } break; } return true; }, errorBox:function(tip){//错误提示 wx.hideLoading(); wx.showToast({ title: tip, icon: 'none', duration: 2000 }); }, relogin:function(auth){//重新登录,auth为布尔值,true为需要验证授权,false时只更新login_key var _this = this; wx.login({ success: res => { wx.request({ url: app.globalData.apiDomain+'/api/member/code/login', data: { code: res.code }, method: "POST", header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { wx.setStorageSync('login_key', res.data.data.login_key); if(auth){ wx.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 wx.getUserInfo({ success: res => { // 可以将 res 发送给后台解码出 unionId _this.globalData.userInfo = res.userInfo; wx.request({ url: app.globalData.apiDomain+'/api/member/code/getUserInfo', data: { 'iv': res.iv, 'encryptedData': res.encryptedData, 'login_key': wx.getStorageSync('login_key') }, method: "POST", header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { } }); // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 if (_this.userInfoReadyCallback) { _this.userInfoReadyCallback(res) } } }) } else { //未授权跳到授权登录页 wx.hideLoading(); wx.navigateTo({ url: '../login/login?redirect=index', }) } } }) } _this.getRedPackage(); } }); } }) }, getGiftsTimestamp: function () {//定时开奖获取时间戳判断 var _this = this; var ymd = _this.data.multiArray[0][_this.data.multiIndex[0]]; var result = ymd.match(/\d+/g); var hour = _this.data.multiArray[1][_this.data.multiIndex[1]]; var minutes = _this.data.multiArray[2][_this.data.multiIndex[2]]; var _tspStr = result[0] + '/' + result[1] + '/' + result[2] + ' ' + hour + ':' + minutes; var date = new Date(_tspStr); var tsp = Date.parse(date); var utimeStamp = tsp / 1000; return String(utimeStamp); }, getRedPackage:function(){//生成礼物红包操作 //表单数据验证 var _this = this; var result = _this.checkForm(); if(!result){ return; } //表单通过之后检测登录状态和授权状态 wx.showLoading({ title: '验证登录', }); wx.checkSession({ success:function(){//sessionKey未过期 //判断授权状态 wx.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 wx.getUserInfo({ success: res => { // 可以将 res 发送给后台解码出 unionId app.globalData.userInfo = res.userInfo; wx.request({ url: app.globalData.apiDomain+'/api/member/code/getUserInfo', data: { 'iv': res.iv, 'encryptedData': res.encryptedData, 'login_key': wx.getStorageSync('login_key') }, method: "POST", header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { wx.hideLoading(); wx.showLoading({ title: '创建订单', }); wx.request({ url: app.globalData.apiDomain+'/api/order/creatOrder',//生成礼物红包接口 data:{ 'productList': _this.data.gifts, 'login_key':wx.getStorageSync('login_key'), 'play': { 'method': _this.data.gifttype, 'openTime': _this.getGiftsTimestamp(), 'openPeople': _this.data.personNum}, 'wish': _this.data.wish ? _this.data.wish:'大吉大利,送你好礼' }, method: "POST", header: { 'content-type': 'application/json' // 默认值 }, success:function(res){ if (res.data.code == 'error' && res.data.message) { wx.showToast({ title: res.data.message, icon:'none' }) }else{ var _orderId = res.data.data.order_id; //直接到结果页 wx.removeStorageSync('gifts'); wx.removeStorageSync('wish'); wx.removeStorageSync('gifttype'); wx.removeStorageSync('p_num'); _this.setData({ gifts: [], wish: '', gifttype: '直接送礼', personNum: _this.data.personNum, }) wx.hideLoading(); wx.navigateTo({ url: '../payment/payresult/payresult?orderId=' + _orderId, }) //去除支付 // wx.request({ // url: app.globalData.apiDomain + '/api/payment?act=requestPayment',//订单创建成功后请求微信支付的参数 // data: { // 'login_key': wx.getStorageSync('login_key'), // 'order_id': _orderId // }, // method: "POST", // header: { // 'content-type': 'application/json' // 默认值 // }, // success: function (res) { // wx.hideLoading(); // wx.showLoading({ // title: '等待支付', // }); // //吊起微信支付 // if (res.data.data.nonceStr && res.data.data.package && res.data.data.timeStamp && res.data.data.paySign) { // wx.requestPayment({ // 'timeStamp': String(res.data.data.timeStamp), // 'nonceStr': res.data.data.nonceStr, // 'package': res.data.data.package, // 'signType': 'MD5', // 'paySign': res.data.data.paySign, // 'success': function (res) {//微信支付成功之后 // //TODO清除数据 // try { // wx.removeStorageSync('gifts'); // wx.removeStorageSync('wish'); // wx.removeStorageSync('gifttype'); // wx.removeStorageSync('p_num'); // } catch (e) { // // Do something when catch error // } // _this.setData({ // gifts: [], // wish: '', // gifttype: '直接送礼', // personNum: _this.data.personNum, // }) // wx.hideLoading(); // wx.navigateTo({ // url: '../payment/payresult/payresult?orderId=' + _orderId, // }) // }, // 'fail': function (res) { // wx.hideLoading(); // _this.errorBox('支付失败'); // } // }) // } // }, // fail: function (res) { // wx.hideLoading(); // if (res.data.message) { // wx.showToast({ // title: res.data.message // }) // } // } //}) } }, fail:function(){ //订单创建失败 _this.errorBox('网络异常,请稍后再试'); } }) }, fail:function(){ //后台解密用户信息失败 _this.errorBox('网络异常,请稍后再试'); } }); //由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回所以此处加入 callback 以防止这种情况 if (_this.userInfoReadyCallback) { _this.userInfoReadyCallback(res) } } }) }else{ //未授权跳到授权登录页 wx.hideLoading(); wx.navigateTo({ url: '../login/login?redirect=index', }) } } }) }, fail:function(){//登录过期 _this.relogin(true); } }) } })
服务端
1 添加创建订单接口,接收数据后,需要创建订单数据,对每一个礼物都要生成一个order_item,和一个订单的方法记录,这里直接将创建好的,订单置为支付状态。并返回订单号。
url.py
from django.contrib import admin from django.urls import path from django.conf.urls import url from api.views import product,user urlpatterns = [ path('admin/', admin.site.urls), url(r'^api/indexlist/categoryList$', product.caetgoryList.as_view()), url(r'^api/indexlist/IndexProductList$', product.ProductList.as_view()), url(r'^api/indexlist/categoryProductsList$', product.categoryProductsList.as_view()), url(r'^api/indexlist/detailProduct$', product.detailProduct.as_view()), url(r'^api/member/code/login$', user.login.as_view()), url(r'^api/member/code/getUserInfo$', user.getUserInfo.as_view()), url(r'^api/order/creatOrder$', order.creatOrder.as_view()), ]
order.py
from django.shortcuts import render,HttpResponse from rest_framework.views import APIView from api.wx import wxlogin,UserInfo,setting from api import baseResponse import time import datetime import random from django.core.cache import cache #引入缓存模块 from api import models from django.http import JsonResponse import hashlib #创建订单接口 class creatOrder(APIView): def post(self,request): params = request.data #判断参数是否传对,productList需要生成订单的商品列表,play订单开奖方式 if params.get("login_key") and params.get("productList") and params.get("play"): #在redis中获取用户数据 login_key = params['login_key'] data = cache.get(login_key) if not data: re_data = baseResponse.resdic("error", "login_key已过期") return JsonResponse(re_data) data_list = data.split('&') #通过用户的openid查找用户 member_info=models.Wxuser.objects.filter(openid=data_list[1]).values().first() #调用创建订单方法 order_data=self.createOrder_def(params,member_info) re_data = baseResponse.resdic("success", "获取成功",order_data) return JsonResponse(re_data) else: re_data = baseResponse.resdic("error", "创建订单失败") return JsonResponse(re_data) def createOrder_def(self,params,member_info): #创建订单item order_data=self.creatOrderItem(params['productList'],member_info) #创建订单方法数据ordermethon self.creatOrderMethon(params['play'], order_data) order_data['createtime'] = datetime.datetime.now() order_data['pay_app'] = 'wxpay' order_data['member_id'] =member_info['id'] order_data['get_method'] =params['play']['method'] order_data['memo'] =params['wish'] order_data['pay_status']=1 order_data['payed'] =order_data['order_total'] #将数据保存到order表中 models.Order.objects.create(**order_data) return order_data def creatOrderItem(self,data,member_infor): order_data={} #生成订单号 order_data['order_id'] = str(int(time.time() * 1000)) + str(int(time.clock() * 1000000)) order_data['order_total']=0 order_data['quantity']=0 for key,vale in enumerate(data): #查出传过来的商品列表中单个商品的数据 product=models.Products.objects.filter(product_id=vale['product_id']).values().first() params={} params['order_id_id'] =order_data['order_id'] params['product_id'] =vale['product_id'] params['name'] =vale['name'] params['buy_member_id_id'] =member_infor['id'] params['image_id'] =vale['image_id'] params['price'] = round(float(vale['price']), 3) params['brief'] =product['brief'] for i in range(0,vale['num']): params['nums']=1 params['amount']=product['price'] #每个商品每个数量都生成一个订单item models.Order_items.objects.create(**params) #models.Order_items.create(order_id_id=params['order_id_id'],product_id=params['product_id'],name=params['name'],buy_member_id_id=params['buy_member_id_id'],image_id= params['image_id'],price=params['price'],brief=params['brief'],nums=params['nums'],amount=params['amount']) order_data['quantity'] +=vale['num']; order_data['order_total'] = order_data['order_total'] + (round(float(vale['price']), 3) * int(vale['num'])) return order_data def creatOrderMethon(self,data,order_data): methon_data={} methon_data['get_method']=data['method'] methon_data['order_id'] =order_data['order_id'] #将数据存入到ordermethon中 if data['method'] == "定时开奖": timeArray = time.localtime(int(data['openTime'])) datatime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray) methon_data['opentime']=datatime elif data['method'] == "满人开奖": methon_data['open_number']=data['openPeople'] models.Order_methons.objects.create(**methon_data) return True