流程解说
1、点击立即领取,如果没有领取资格,弹窗去邀请海报
2、有邀请资格,点击立即邀请,商品列表会显示复选框
3、点击某个商品选框时,弹出该商品的规格弹窗,选择规格,然后确定
4、选好多件商品后,立即领取
<config>
{
"usingComponents": {
"van-popup": "@vant/weapp/popup/index",
"wxml-to-canvas": "wxml-to-canvas"
},
"navigationBarTitleText":"领取奖品",
"enablePullDownRefresh": true
}
</config>
<template lang="wxml">
<view class="active">
<view class="top_bg relative">
<image
class="w100"
style="height:300rpx;"
src="https://file.lojangcc.com/weapp/common/ac-goods-bg.png"
mode="aspectFit"
>
</image>
<view class="top_number absolute white">当前可领取{{alldata.gift_num || 0}}件商品</view>
</view>
<!-- 商品 -->
<view class="second-con bg-white" style="{{showPoster>0?'':'position: relative; z-index: 6666;'}}">
<view class="item2 flex_l" wx:for="{{giftList}}">
<image
class="goods-img mr-24"
src="{{item.size.size_image||item.cover_Image}}"
mode="aspectFill"
>
</image>
<view class="pro ptb-48 flex-1 clipped border-bottom flex flex-column flex-top">
<view class="ellipsis-l2">{{item.name}}</view>
<view class="flex1 w100 mtb-8">
<view class="size bg gray-1 size-24">
{{item.size.size_name}}{{item.num}}件
</view>
<van-checkbox
wx:if="{{onceget}}"
name="{{item.goods_id}}"
value="{{item.checked}}"
bind:change="onCheck"
data-index="{{index}}"
></van-checkbox>
</view>
<view class="flex flex-bottom flex-between w100">
<view class="">
<view class="flex_l">
<view class="red size-32 flex_l mr-16"
><text class="size-24">¥</text>{{item.size.price}}</view
>
<view class="gray-2 size-24 old_price">¥{{item.size.market_price}}</view>
</view>
<view class="size-24 gray-1">{{item.usernum}}人已领取</view>
</view>
</view>
</view>
</view>
</view>
<view class="fixed plr-32 fixed-bottom bg-white" style="z-index:999;">
<view class="sub center white size-30" bind:tap="onceGet">{{onceget?'确定':'立即领取'}}</view>
</view>
<!-- 规格弹窗 -->
<van-popup round show="{{ show }}" style="{{showPoster>0?'':'position: relative; z-index: 8888;'}}" position="bottom" bind:close="onClose">
<view class="size ptb-24 bg-white">
<view class="plr-32">
<view class="flex">
<van-image
width="6rem"
height="6rem"
radius="16rpx"
fit="cover"
class="relative goods_img"
src="{{giftList[index].size.size_image||giftList[index].cover_Image}}"
/>
<view class="ml-24 flex-1 clipped">
<view class="ellipsis-l1">{{giftList[index].name}}</view>
<view class="gray-1 mtb-8">库存{{giftList[index].size.goods_stock}}件</view>
<view class="red">¥{{giftList[index].size.price}}</view>
</view>
</view>
<view style="margin-top: -50rpx;">规格分类</view>
<view
class="flex flex-top flex-wrap"
style="min-height: 200rpx; max-height: 300rpx; align-content: flex-start; overflow: auto;"
>
<view
class=" item mt-16 mr-16 size-24 {{giftList[index].active==indexs?'bg-red white':'bg'}}"
wx:for="{{giftList[index].goods_size}}"
wx:key="{{item.goods_size_id}}"
wx:for-index="indexs"
data-index="{{indexs}}"
bindtap="getSize"
>{{item.size_name}}</view
>
</view>
<view class="flex1 mtb-32">
<view> 数量 </view>
<van-stepper
input-width="80rpx"
button-size="45rpx"
bind:change="onChange"
value="{{giftList[index].num}}"
integer
max="{{alldata.gift_num<giftList[index].size.goods_stock?alldata.gift_num:giftList[index].size.goods_stock}}"
/>
</view>
</view>
<van-divider />
<view class="plr-24 pb-24">
<van-button class="w100" type="danger" bind:tap="submit" block round>
确定
</van-button>
</view>
</view>
</van-popup>
<!-- 立即邀请 -->
<van-popup class="rules" show="{{ showRule }}" bind:close="onRuleClose" style="{{showPoster>0?'':'position: relative; z-index: 9999;'}}" >
<view class="rule_content">
<image src="https://file.lojangcc.com/weapp/common/ac3_tip.png" class="rule_title"/>
<view class="flex-1 rule_con center">啊哦~您当前没有领取资格</view>
<view class="flex-1 rule_con center">快去邀请好友,领取精美奖品吧~</view>
<view class="know center" bind:tap="drawPoster">立即邀请</view>
</view>
</van-popup>
<!-- 海报 -->
<van-popup
class="posterPop {{showPoster>0?'':'opacity'}}"
show="{{ true }}"
z-index="{{showPoster}}"
custom-class="{{showPoster>0?'':'opacity'}}"
close-icon="https://file.lojangcc.com/weapp/common/ac3-close.png"
closeable
bind:close="onPosterClose"
>
<wxml-to-canvas class="widget" width="{{310}}" height="{{435}}"></wxml-to-canvas>
<view class="flex flex-around pd-32 mt-24 bg-white radius-16">
<button class="text-center unbutton" open-type="share">
<image class="actionimg" src="https://file.lojangcc.com/weapp/common/wechat.png" />
<view>微信好友</view>
</button>
<view wx:if="{{drawOver}}" class="text-center" bind:tap="posterToFile">
<image class="actionimg" src="https://file.lojangcc.com/weapp/common/save.png" />
<view>发送至朋友圈</view>
</view>
</view>
</van-popup>
</view>
</template>
<script>
// pages/active/index.js
import computedBehavior from 'miniprogram-computed'
import { storeBindingsBehavior } from 'mobx-miniprogram-bindings'
import { store } from '../../store/index'
import { loginRedirect, http } from '../../utils/index'
let widget = null
Component({
behaviors: [storeBindingsBehavior, computedBehavior],
properties: {
id: Number,
ud: Number,
scene: String,
},
storeBindings: {
store,
fields: ['isvip', 'userInfo'],
actions: {
setUserInfo: 'setUserInfo',
},
},
computed: {
//是否有领取资格
canget(data) {
return data.state != 1 && data.alldata.gift_num > 0
},
// 再邀请几人
neednum(data) {
return data.invite_limit - (data.alldata.invite_num % data.invite_limit)
},
// 选中的总数量
allnum(data) {
let num = 0
data.giftList.forEach(item => {
if (item.checked) {
num += item.num
}
})
return num
},
// 礼包价格
price(data) {
let price = 0
data.giftList.forEach(item => {
price += item.size.price
})
return price
},
},
data: {
invite_limit: null, //邀请几人一次
state: null, //活动状态 1 未开始 2 进行中 3 已结束
receive_state: null, //奖品领取时间 1 未开始 2 进行中 3 已结束
receive_status: 0,
onceget: false, //是否点击一键领取
alldata: {
// invite_num: 5, //邀请成功人数
// gift_num: 1, //可领奖次数
// receive_num: 1, //已领奖次数
},
bg_img: '',
giftList: [], // 可领取商品列表
// 领取记录轮播
swiper: [],
record: [], // 邀请人数列表
show: false, //规格弹窗
index: null, //当前操作商品
showRule: false,
qrcode: '',
showPoster: -1000,
drawOver: false,
},
methods: {
/**
* 生命周期函数--监听页面加载
*/
onLoad() {},
// init
async init() {
const { data } = await http.get('/activity/invite/index', {
params: {
activity_id: this.data.id,
},
})
data.giftList.forEach(item => {
item.checked = false //每个商品的选中状态
item.size = item.goods_size[0] || {} //每个商品选中的规格
item.active = 0 //每个商品选中的规格的索引
item.num = 1 //每个商品选中的数量
let num = 0
item.goods_size.forEach(item => {
num += item.receive_num
})
item.usernum = num //每个商品的使用人数
})
this.setData({
giftList: data.giftList,
state: data.state,
receive_state: data.receive_state,
receive_status: data.receive_status,
alldata: data.join_info,
bg_img: data.bg_img,
})
},
// 点击每一个复选框
onCheck(e) {
this.setData({
show: e.detail,
[`giftList[${e.currentTarget.dataset.index}].checked`]: e.detail,
index: e.currentTarget.dataset.index, //当前商品的索引
})
},
// 选择规格
getSize(e) {
this.setData({
[`giftList[${this.data.index}].size`]: this.data.giftList[
this.data.index
].goods_size[e.currentTarget.dataset.index],
[`giftList[${this.data.index}].active`]: e.currentTarget.dataset.index,
})
},
// 规格数量
onChange(event) {
this.setData({
[`giftList[${this.data.index}].num`]: event.detail,
})
},
onClose() {
this.setData({
show: false,
})
},
// 规格弹窗确定
async submit() {
this.setData({
show: false,
})
},
onRuleClose() {
this.setData({
showRule: false,
})
},
// 一键领取
onceGet() {
if (!this.data.canget) {
this.setData({
showRule: true,
})
} else if (this.data.receive_state != 2) {
wx.showToast({
title:
this.data.receive_state == 1
? '奖品领取暂未开始'
: '奖品领取时间已截止',
icon: 'none',
})
} else {
if (!this.data.onceget) {
this.setData({
onceget: true,
})
} else {
if (this.data.allnum == 0) {
wx.showToast({
title: '请选择领取商品',
icon: 'none',
})
} else if (this.data.allnum > this.data.alldata.gift_num) {
wx.showToast({
title: `最多可领取${this.data.alldata.gift_num}件哦`,
icon: 'none',
})
} else {
let ids = ''
this.data.giftList.forEach(item => {
if (item.checked) {
ids += `,${item.goods_id}|${item.size.goods_size_id}|${item.num}`
}
})
wx.navigateTo({
url: `./confirmorder/index?cart_ids=${ids.substr(
1
)}&activity_id=${this.data.id}&user_id=${this.data.ud}&count=${
this.data.alldata.gift_num
}`,
})
}
}
}
},
async drawPoster() {
this.setData({
showRule: false,
})
if (!store.userInfo.token) {
loginRedirect()
return
}
wx.showLoading({
title: '绘制海报中',
})
this.setData({
showPoster: 1000,
})
if (this.data.drawOver) {
return wx.hideLoading()
}
try {
const {
data: { qrcode },
} = await http.get('/activity/invite/getInviteCode', {
params: {
activity_id: this.data.id,
},
})
const wxml = `<view class="poster">
<image src="https://file.lojangcc.com/weapp/common/ac-poster.png" class="bg" />
<image class="qrcode" src="${qrcode}"></image>
</view>`
const style = {
poster: {
position: 'relative',
width: 310,
height: 435,
backgroundColor: '#fff',
borderRadius: 16,
overflow: 'hidden',
},
bg: {
width: 310,
height: 435,
},
qrcode: {
position: 'absolute',
left: 95,
bottom: 30,
width: 120,
height: 120,
borderRadius: 60,
},
}
wx.nextTick(async () => {
widget = this.selectComponent('.widget')
await this.renderToCanvas(wxml, style)
this.setData({
drawOver: true,
})
wx.hideLoading()
})
} catch (error) {
wx.showToast({
title: '绘制错误,请稍后重试',
icon: 'none',
})
this.setData({
showPoster: -1000,
})
}
},
renderToCanvas(wxml, style) {
widget.renderToCanvas({ wxml, style }).then(res => {
this.container = res
})
},
posterToFile() {
widget.canvasToTempFilePath().then(res => {
this.setData({
src: res.tempFilePath,
width: this.container.layoutBox.width * 2,
height: this.container.layoutBox.height * 2,
})
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success() {
wx.showToast({
title: '保存成功',
})
},
})
})
},
onPosterClose() {
this.setData({
showPoster: -1000,
})
},
onShareAppMessage: function () {
//menu右上角转发
return {
title: '邀请好友即可领取精美礼品',
path: `/pages/active/index?id=${this.data.id}&ud=${
store.userInfo.user_id || ''
}`, // 点击分享打开首页,在首页判断分享路径,再跳转到详情页
imageUrl: this.data.bg_img, //分享的图片路径
}
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {},
/**
* 生命周期函数--监听页面显示
*/
async onShow() {
await this.init()
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
async onPullDownRefresh() {
await this.init()
wx.stopPullDownRefresh()
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {},
},
})
</script>
<style>
/* pages/active/index.wxss */
page {
background-color: #fff9f9;
padding-bottom: 120rpx;
--popup-background-color: transparent;
}
.top_bg {
height: 300rpx;
}
.top_number {
left: 30rpx;
top: 143rpx;
font-size: 26rpx;
border: 1rpx solid rgba(255, 255, 255, 1);
border-radius: 6rpx;
padding: 2rpx 10rpx 4rpx;
}
.price {
top: 500rpx;
left: 50%;
transform: translateX(-50%);
line-height: 1;
}
.second-con {
padding: 0rpx 20rpx 0rpx;
border-radius: 24rpx;
}
.goods-img {
width: 220rpx;
height: 220rpx;
border-radius: 8rpx;
}
.item2 {
padding: 0 10rpx;
}
.size {
padding: 0 15rpx;
border-radius: 4rpx;
}
.old_price {
text-decoration: line-through;
}
.btn {
width: 140rpx;
height: 56rpx;
border: 1rpx solid rgba(242, 36, 36, 1);
border-radius: 28rpx;
}
.sub {
margin: 15rpx auto;
height: 80rpx;
background: #f22424;
border-radius: 40rpx;
}
.items1 {
width: 20%;
}
.items3 {
width: 20%;
text-align: center;
}
.items2 {
width: 60%;
}
.rank-img {
width: 40rpx;
height: 60rpx;
}
/* .van-popup {
overflow-y: visible !important;
} */
.goods_img {
top: -60rpx;
}
.item {
padding: 10rpx 20rpx;
border-radius: 8rpx;
}
.btn-solo {
height: 80rpx;
border-radius: 40rpx;
}
.detail_img {
width: 38rpx;
height: 16rpx;
}
.rule_content {
width: 550rpx;
border: 15rpx solid #ff3a57;
border-radius: 10rpx;
overflow: hidden;
background-color: #fff;
}
.rules .van-popup {
background-color: transparent;
}
.rules .van-popup--center {
top: 30%;
}
.rule_title {
width: 272rpx;
height: 53rpx;
margin: 27rpx auto 50rpx;
display: block;
}
.rule_con {
overflow-y: auto;
padding: 0 20rpx;
color: #333;
font-size: 28rpx;
}
.know {
width: 240rpx;
height: 60rpx;
background: linear-gradient(0deg, rgba(255, 150, 0, 1), rgba(255, 207, 0, 1));
border-radius: 30rpx;
margin: 80rpx auto 27rpx;
font-size: 32rpx;
color: rgba(154, 92, 0, 1);
}
.posterPop .van-popup {
overflow-y: visible !important;
background-color: transparent !important;
}
.poster .qrcode {
left: 209rpx;
top: 390rpx;
}
.actionimg {
width: 90rpx;
height: 90rpx;
}
.unbutton {
margin: 0;
padding: 0;
background-color: transparent;
color: inherit;
font-size: inherit;
line-height: inherit;
}
.unbutton:after {
border: none;
}
</style>