03-06 首页生成礼包
______egon新书python全套来袭请看:https://egonlin.com/book.html
首页生成礼包
需求:用户选择好要送的礼品过后,可以选择开奖方式,有直接开奖,满人开奖,以及定时开奖三种开奖方式,当订单创建完成后,请求支付,支付成功后,跳转到支付结果页,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