参与抽奖
**需求:**但用户点击购买者分享的礼物,点击进入抽奖,在抽奖之前判断1.未开奖未参与2.已经开奖跳转到结果页3.已参与未开奖开奖等待页面
小程序端
1在页面加载之前先判断是否已经参与抽奖,如果是未参与未开奖,则可以显示当前常与抽奖页面,不然就跳转到开奖结果页。
2 点击抽奖以后。跳转到等待开奖的页面
app.json
{
"pages": [
"pages/index/index",
"pages/list/list",
"pages/item/item",
"pages/login/login",
"pages/payment/payresult/payresult",
"pages/gift/join/join",
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#e50e38",
"navigationBarTitleText": "百步生活",
"navigationBarTextStyle": "#fff",
"enablePullDownRefresh": false,
"backgroundColor": "#e50e38"
},
}
join.wxml
<block wx:if="{{inited}}">
<view class="main">
<view class="join-info">
<view class="package-info">
</view>
<image class="avatar" src="{{avatar}}"></image>
<view class="uname">{{uname}}</view>
<view class="openInfo">发起一个抽奖,
<block wx:if="{{openType.get_method=='直接送礼'}}">直接送礼</block>
<block wx:elif="{{openType.get_method=='满人开奖'}}">满{{openType.open_number}}人开奖</block>
<block wx:elif="{{openType.get_method=='定时开奖'}}">{{openType.opentime}}开奖</block>
</view>
<view class="wish">{{wish}}</view>
<view class="btn-join" bindtap='join' hidden='true'>抽</view>
<form bindsubmit="join" report-submit='true'>
<button form-type="submit" type="default" size="mini" class="btn-join">抽</button>
</form>
</view>
</view>
</block>
join.wxss
page{
width: 100%;
height: 100%;
}
.main{
background: rgba(0, 0, 0, 0.7);
width: 100%;
height: 100%;
position: relative;
}
.main .join-info{
width: 84%;
height: 70%;
background: #ca463a;
border-radius: 16rpx;
vertical-align: middle;
text-align: center;
position: absolute;
top: 15%;
left: 8%;
overflow:hidden;
}
.main .join-info .package-info{
height:70%;
width:140%;
background:#e4544b;
border-bottom-left-radius:50%;
border-bottom-right-radius:50%;
margin:0 -20%;
}
.main .join-info .avatar{
position:absolute;
width:120rpx;
height:120rpx;
top:60rpx;
left:50%;
margin-left:-60rpx;
border-radius: 50%;
border: 2rpx solid #eccc99;
}
.main .join-info .uname{
color: #eccc99;
font-size: 32rpx;
position: absolute;
top: 200rpx;
text-align: center;
width: 100%;
}
.main .join-info .openInfo{
color: #eccc99;
font-size: 28rpx;
position: absolute;
text-align: center;
width: 100%;
top: 250rpx;
}
.main .join-info .wish{
color: #eccc99;
font-size: 40rpx;
position: absolute;
text-align: center;
width: 100%;
top: 320rpx;
}
.main .join-info .btn-join{
background:#eccc99;
font-size:60rpx;
width:140rpx;
height:140rpx;
position:absolute;
text-align:center;
top:70%;
border-radius:50%;
color:#4c330a;
left:50%;
margin-left:-70rpx;
margin-top:-70rpx;
line-height: 134rpx;
padding: 0;
}
join.js
// pages/gift/join/join.js
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
inited:false
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
wx.showLoading({
title: '加载中',
});
wx.hideShareMenu();
//这里先用固定order——id
var orderId = options.token;//获取订单token
var _from = '';
var _this = this;
if (options.from){
_from = options.from;
_this.setData({
_from:_from
});
}
_this.setData({
orderId: orderId //这里先用固定的orderid
},function(){
console.log(orderId)
wx.request({
url: app.globalData.apiDomain + '/api/sharagift/checkHasJoin',
data: {
'login_key': wx.getStorageSync('login_key'),
'order_id': orderId,
},
method: "POST",
header: {
'content-type': 'application/json' // 默认值
},
success: function (res) {//1.未开奖未参与2.已经开奖跳转到结果页3.已参与未开奖开奖等待页面
if (res.data.code == 'error' || res.data.code == 'suc') {
wx.redirectTo({
url: '/pages/gift/openresult/openresult?orderId=' + orderId,
})
} else if (res.data.code == 'success') {
wx.hideLoading();
_this.setData({
avatar: res.data.data.member_data.avatar,
uname: res.data.data.member_data.name,
openType: res.data.data.methons_data,
wish: res.data.data.order_data.memo,
inited:true
})
};
},
fail: function () {
wx.hideLoading();
wx.showToast({
title: '网络不给力,请稍后再试',
})
}
})
});
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
join:function(e){
var _this = this;
var formId = e.detail.formId;
wx.showLoading({
title: '登录验证',
});
wx.checkSession({
success:function(res){//session_key未过期
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/sharagift/JoinGift',//参与抽奖接口
data: {
'order_id': _this.data.orderId,
'login_key': wx.getStorageSync('login_key'),
'form_id': formId
},
method: "POST",
header: {
'content-type': 'application/json' // 默认值
},
success: function (res) {
if(res.data.code=='error'){
wx.hideLoading();
wx.showToast({
title: res.data.message
});
wx.reLaunch({
url: '/pages/index/index'
})
}else if (res.data.code == 'suc'){
wx.hideLoading();
wx.showToast({
title: '参与成功',
icon: 'none',
duration: 2000
});
wx.redirectTo({
url: '/pages/gift/openresult/openresult?orderId=' + _this.data.orderId
})
}else{
wx.hideLoading();
wx.showToast({
title: '参与成功',
icon:'none',
duration:2000
});
//如果是每日抽奖,去更新页面栈的数据
var pages = getCurrentPages();
if (pages.length > 1) {
//上一个页面实例对象
var prePage = pages[pages.length - 2];
//关键在这里,这里面是触发上个界面
prePage.changeStatus(_this.data.orderId);
}
wx.redirectTo({
url: '/pages/gift/openresult/openresult?orderId=' + _this.data.orderId
})
}
},
fail: function () {
//订单创建失败
wx.hideLoading();
wx.showToast({
title: '网络异常,请稍后再试',
icon: 'none',
duration: 2000
})
}
})
},
fail: function () {
//后台解密用户信息失败
wx.hideLoading();
wx.showToast({
title: '获取用户信息失败',
icon:'none',
duration: 2000
})
}
});
//由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回所以此处加入 callback 以防止这种情况
if (_this.userInfoReadyCallback) {
_this.userInfoReadyCallback(res)
}
}
})
} else {
//未授权跳到授权登录页
wx.hideLoading();
wx.navigateTo({
url: '/pages/login/login?redirect=join',
})
}
}
})
},
fail: function () {//session_key已过期,登录更新login_key之后回调
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);
_this.join();
}
});
}
})
}
})
}
})
服务端
1 在checkoutHasJoin接口中,如果是不满足参与条件,则返回不能参与,如果能参与则返回可以参与,并返回相关订单信息。
2 在joinGift接口中,接收用户的的login_key,form_id(作为消息通知的依据),order_id,记入到order_join表中,判断订单是否开奖,如果是定时开奖,则判断当前时间是否小于开奖时间,如果是满人开奖,判断参与人数是否小于开奖人数,当到达开奖人数的时候,将订单的order_methon记录修改成read,如果是直接开奖,这需要将直接将礼物发送给该用户,并发送模板消息给改用户。并返回成功。
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()),
url(r'^api/payment/returnOrderData$', payment.returnOrderData.as_view()),
url(r'^api/sharagift/checkHasJoin$', sharagift.checkHasJoin.as_view()),
url(r'^api/sharagift/JoinGift$', sharagift.JoinGift.as_view()),
]
sharagift.py
from rest_framework.views import APIView
from api.wx import order,SendMessage
from api import baseResponse
import time
from api.MySer.MySer import OrdermethonsSerializer,OrderSerializer,OrderitemsSerializer,WxuserSerializer,MemberJoinSerializer
from django.core.cache import cache #引入缓存模块
from api import models
from django.db.models import Count
from django.http import JsonResponse
#判断是否是否参加抽奖
class checkHasJoin(APIView):
def post(self,request):
params=request.data
#判断请求参数
if params.get('login_key') and params.get("order_id"):
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('&')
#获取用户信息
member_info = models.Wxuser.objects.filter(openid=data_list[1]).values().first()
#判断该奖是否已经开奖
if self.checkGiftHasOpen(params['order_id']):
re_data = baseResponse.resdic("suc", "已经开奖")
return JsonResponse(re_data)
#判断是否参与该抽奖
elif self.checkHasJoin_def(params['order_id'],member_info['id']):
re_data = baseResponse.resdic("error", "你已经参与过了")
return JsonResponse(re_data)
#判断是否参与人数已满
elif self.checkMemberFull(params['order_id']):
re_data = baseResponse.resdic("error", "参与人数已满")
return JsonResponse(re_data)
#如果以上条件都没有满足,则可以参与抽奖
else:
#返回订单,订单详细,订单方法,以及购买者信息
order_data=models.Order.objects.filter(order_id=params['order_id']).values().first()
methon_data=models.Order_methons.objects.filter(order_id=params['order_id'])
send_member_data=models.Wxuser.objects.filter(id=order_data['member_id']).values().first()
print(send_member_data, "sqldata")
return_data={}
order_data =OrderSerializer(instance=order_data, many=False)
methon_data = OrdermethonsSerializer(instance=methon_data, many=False)
send_member_data = WxuserSerializer(instance=send_member_data, many=False)
return_data['order_data']=order_data.data
return_data['methons_data']=methon_data.data
return_data['member_data']=send_member_data.data
re_data=baseResponse.resdic("success","可以参与",return_data)
return JsonResponse(re_data)
else:
re_data = baseResponse.resdic("error", "缺少参数")
return JsonResponse(re_data)
#判断是否以及开奖
def checkGiftHasOpen(self,order_id):
return models.Order_methons.objects.filter(order_id=order_id,status="finish").first()
#判断是否参与过该订单
def checkHasJoin_def(self,order_id,member_id):
return models.Member_joins.objects.filter(order_id=order_id,member_id=member_id).first()
#判断该订单参与人数是否已满
def checkMemberFull(self,order_id):
data=models.Order_methons.objects.filter(order_id=order_id,get_method="满人开奖").values().first()
join_num=models.Member_joins.objects.filter(order_id=order_id).all().count()
if data and join_num>int(data['open_number']):
return True
else:
return False
#参与抽奖接口
class JoinGift(APIView):
def post(self,request):
params=request.data
#判断请求参数
if params.get('login_key') and params.get("order_id") and params.get("form_id"):
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('&')
#获取该用户的信息
member_info = models.Wxuser.objects.filter(openid=data_list[1]).values().first()
#获取订单数据
order_data = models.Order.objects.filter(order_id=params['order_id']).values().first()
#判断订单是否正常
if not order_data or not order_data['pay_status'] == 1:
re_data = baseResponse.resdic("error", "订单错误,参与失败")
return JsonResponse(re_data)
else:
return_data={}
#获取订单相关数据
methons_data=models.Order_methons.objects.filter(order_id=params['order_id']).values().first()
send_member_data=models.Wxuser.objects.filter(id=order_data["member_id"]).values().first()
order_data_ser = OrderSerializer(instance=order_data, many=False)
methon_data_ser = OrdermethonsSerializer(instance=methons_data, many=False)
send_member_data_ser = WxuserSerializer(instance=send_member_data, many=False)
return_data['order_data'] = order_data_ser.data
return_data['methons_data'] = methon_data_ser.data
return_data['member_data'] = send_member_data_ser.data
#判断订单是否未定时开奖
if methons_data['get_method']=="定时开奖":
timeArray = time.strptime(str(methons_data['opentime']), "%Y-%m-%d %H:%M:%S")
timeStamp = int(time.mktime(timeArray))
#当前时间大于开奖时间
if timeStamp < time.time():
re_data = baseResponse.resdic("error", "参与时间已过")
return JsonResponse(re_data)
#参与抽奖
if not self.joinOrder(params['order_id'],member_info['id'],params['form_id']):
re_data = baseResponse.resdic("error", "参与失败")
return JsonResponse(re_data)
else:
re_data = baseResponse.resdic("success", "参与成功,等待抽奖",return_data)
return JsonResponse(re_data)
#如果是满人开奖
elif methons_data['get_method']=="满人开奖":
#获取当前已经参与所有人数
join_mun=self.getJoinMemberByOrderId(params['order_id'])
#获取加上当前用户和join_mun的人数
new_join_mun=join_mun+1
#如果new_join_mun小于等于开奖人数
if new_join_mun <= methons_data['open_number']:
#参与抽奖
if self.joinOrder(params['order_id'],member_info['id'],params['form_id']):
#如果new_join_mun等于开奖人数
if new_join_mun == methons_data['open_number']:
#改变订单状态,等待开奖
self.changeOpenstatusByOrderId(params['order_id'],status="read")
re_data = baseResponse.resdic("success", "参与成功,等待抽奖", return_data)
return JsonResponse(re_data)
else:
re_data = baseResponse.resdic("error", "参与失败")
return JsonResponse(re_data)
else:
re_data = baseResponse.resdic("error", "人数已满,参与失败")
return JsonResponse(re_data)
#如果是直接送礼
elif methons_data['get_method'] == "直接送礼":
#判断礼物数量
gift_num=self.hasGift(params['order_id'])
print(gift_num,"gift_num")
#如果没有礼物
if not gift_num:
re_data = baseResponse.resdic("error", "没有礼品可以领取")
return JsonResponse(re_data)
#参与抽奖
if not self.joinOrder(params['order_id'],member_info['id'],params['form_id']):
re_data = baseResponse.resdic("error", "参与失败2")
return JsonResponse(re_data)
#获奖人id
get_win_peple=[member_info['id']]
#如果奖品是1个
if gift_num==1:
peple_itemId=order.giveWindToPeple(get_win_peple,params['order_id'])
else:
peple_itemId = order.giveOneWindToPeple(get_win_peple, params['order_id'])
print(peple_itemId,"peple_itemId")
#判断是否发奖成功
if not peple_itemId:
re_data = baseResponse.resdic("error", "参与失败1")
return JsonResponse(re_data)
#模板消息通知该用户获的奖品消息
join_peple=[{"member_id":member_info['id'],"form_id":params['form_id']}]
SendMessage.sendMessageToPeple(join_peple,params['order_id'])
re_data = baseResponse.resdic("suc", "直接开奖",return_data)
return JsonResponse(re_data)
else:
re_data = baseResponse.resdic("error", "缺少参数")
return JsonResponse(re_data)
#参与抽奖
def joinOrder(self,order_id,member_id,form_id):
data={"order_id":order_id,"member_id":member_id,"form_id":form_id}
return models.Member_joins.objects.create(**data)
#获取有多少人抽奖
def getJoinMemberByOrderId(self,order_id):
join_num = models.Member_joins.objects.filter(order_id=order_id).all().count()
return join_num
#改变订单的订单状态
def changeOpenstatusByOrderId(self,order_id,status):
return models.Order_methons.objects.filter(order_id=order_id).update(status=status)
#判断有多少个礼物
def hasGift(self,order_id):
return models.Order_items.objects.filter(order_id=order_id,get_mermber_id_id=None).count()
api.wx.order.py
from api import models
#如果只有一个礼物,送完以后将订单状态变成结束态
def giveWindToPeple(win_peple,order_id):
num=len(win_peple)
item_data=models.Order_items.objects.filter(order_id_id=order_id,get_mermber_id_id=None).values()[0:num]
for k,v in enumerate(item_data):
if not models.Order_items.objects.filter(item_id=v['item_id']).update(get_mermber_id_id=win_peple[k]):
return False
if not models.Order_methons.objects.filter(order_id=order_id).update(status="finish"):
return False
return item_data
#如果不止有一个礼物,则选择一个发给用户
def giveOneWindToPeple(win_peple,order_id):
num = len(win_peple)
item_data = models.Order_items.objects.filter(order_id_id=order_id, get_mermber_id_id=None).values()[0:num]
print(item_data, "peple_itemId2222222")
for k,v in enumerate(item_data):
if not models.Order_items.objects.filter(item_id=v['item_id']).update(get_mermber_id_id=win_peple[k]):
return False
return item_data
api.wx.SendMessage.py
from api.wx import setting
import requests
import json
from django.core.cache import cache #引入缓存模块
from api import models
#获取微信的access_token,这个最好是全局唯一获取方法
def getAccssToken():
access_token = cache.get("access_token")
url = setting.acces_url.format(setting.AppId,setting.AppSecret)
if not access_token:
re_data = requests.get(url)
json_response = re_data.content.decode() # 获取r的文本 就是一个json字符串
# 将json字符串转换成dic字典对象
access_token = json.loads(json_response)
if access_token.get('access_token'):
print()
return False
print(access_token,"access_token")
cache.set("access_token",access_token['access_token'],7200)
return access_token['access_token']
#将模板消息发用给用户
def senMsgto(access_token,member_open_id,form_id,order_id):
url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=%s"%(access_token)
data={
"touser":member_open_id,
"template_id":"DeFlgmAbVI2EaPoQC4BVB0_gQ2hPWCxCpkgbKuc_kdw",
"page":"pages/gift/openresult/openresult?orderId=%s"%(order_id),
"form_id":form_id,
"data":{
"keyword1":{"value":"叮咚——!礼物已降临,点击看看你有没有被奖品砸中"},
"keyword2":{"value":"如果你中奖,记得填写奖品领取信息进行签收哦"}
}
}
requests.post(url, data)
#组织要发的人,和数据
def sendMessageToPeple(join_peple,order_id):
for k,v in enumerate(join_peple):
access_token=getAccssToken()
member_info=models.Wxuser.objects.filter(id=v['member_id']).values().first()
senMsgto(access_token,member_info['openid'],v['form_id'],order_id)