小程序,多商品多规格同时购买

流程解说

小程序,多商品多规格同时购买_第1张图片
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
            />
          </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 = `
          
          ${qrcode}">
        `
        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>

你可能感兴趣的:(小程序)