主頁 > 區塊鏈 > 小程式中關于紅包雨的實作

小程式中關于紅包雨的實作

2020-09-17 14:26:35 區塊鏈

一、原型依據

在我這個專案中小程式端所需要實作的只有紅包雨的下落影片和通屏背景圖的兼容,關于紅包點擊金額的計算是由后端實作的,首先來看下需要實作的效果圖,
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

二、實作代碼

首先是第一次進入的頁面,在這個頁面的時候會進行靜默登錄,靜默登錄成功的話會顯示當前剩余次數,否則在點擊開始的時候回跳轉登錄頁面,不論是否登錄成功都會去呼叫活動資訊監測的介面,判斷當前是否有可以參加的活動,在點擊開始后進行三秒鐘的倒計時,倒計時結束則轉入下一個界面實作紅包雨的下落,

<!--RedEnvelopes/pages/RedEnvelopes/index/index.wxml-->
<nav-bar navbar-data='{{nvabarData}}'></nav-bar>
<view style='padding-top: {{height}}px;' wx:if="{{ready}}">
  <block wx:if="{{!showTime}}">
    <view class="start" bindtap="participateIn" wx:if="{{readyTime != 0}}">
      <view class="start-aperture">
        <view class="start-aperture-bg">
          <text class="start-aperture-txt" wx:if="{{!showTime}}">開始</text>
          <text class="start-aperture-txt" wx:else>{{readyTime}}</text>
        </view>
      </view>
    </view>
  </block>
  <block wx:else>
    <view class="start" wx:if="{{readyTime != 0}}">
      <view class="start-aperture">
        <view class="start-aperture-bg">
          <text class="start-aperture-txt" wx:if="{{!showTime}}">開始</text>
          <text class="start-aperture-txt" wx:else>{{readyTime}}</text>
        </view>
      </view>
    </view>
  </block>
  <view class="remaTimes" wx:if="{{showLogin && !showTime}}">今日剩余次數: {{RemainingTimes}}/{{MaxSharingAwardTimes}}</view>
  <view class="rule" wx:if="{{!showTime}}">
    <view class="rule-top">
      <text class="iconfont iconxiangxia2"></text>
    </view>
    <view class="rule-body">
      <view class="rule-body-one">
        <view class="rule-body-title">規則:</view>
        <view class="rule-body-html">{{ActivityRules}}</view>
      </view>
    </view>
  </view>
</view>
<!-- 紅包雨組件 -->
<block wx:if="{{readyTime == 0}}">
  <sol-packet-rain visible="{{visible}}" createSpeed="{{createSpeed}}" time="{{time}}" min="{{min}}" max="{{max}}" bind:finish="success"></sol-packet-rain>
</block>
// RedEnvelopes/pages/RedEnvelopes/index/index.js
const api = require('../../../../server/api.js');
const http = require('../../../../server/request.js');
const appJs = require('../../../../utils/uselogn.js');
const app = getApp()
let readyTimer = null
Page({

  /**
   * 頁面的初始資料
   */
  data: {
    // 導航頭組件所需的引數
    nvabarData: {
      showCapsule: 1, //是否顯示左上角圖示   1表示顯示    0表示不顯示
      title: '搶紅包', //導航欄 中間的標題
      white: true, // 是就顯示白的,不是就顯示黑的,
      address: api.pictureServer + '/res/shopImg/RedEnvelopes.png' // 加個背景 不加就是沒有
    },
    // 導航頭的高度
    height: app.globalData.height * 2 + 20,
    readyTime: 3,
    showTime: false,
    btnText: '獲取驗證碼',
    phone: '',
    VerificationCode: '',
    unbind: false,
    showLogin: true,
    ready: false,
    tell: '',
    redId: '', //搶紅包活動標識
    BackgroundMap: '', //活動背景圖
    ThemeMap: '', //活動主題圖
    ActivityRules: '', //活動規則
    ShareDescription: '', //分享描述
    ShareIcon: '', //分享圖示
    MaxSharingAwardTimes: '0',
    RemainingTimes: '0'
  },
  onLogin: appJs.userLogin,
  /**
   * 生命周期函式--監聽頁面加載
   */
  onl oad: function(options) {
    if (options.refer && options.ShareMemberId) {
      let SharedMemberId = wx.getStorageSync('CustomerService').MemberId;
      let parm = {
        Id: options.refer,
        ShareMemberId: options.ShareMemberId,
        SharedMemberId: SharedMemberId
      }
      this.getRedEnvelopeLotteryShare(parm)
      let white = 'nvabarData.white'
      this.setData({
        [white]: false
      })
    }
  },

  /**
   * 生命周期函式--監聽頁面初次渲染完成
   */
  onReady: function() {

  },

  /**
   * 生命周期函式--監聽頁面顯示
   */
  onShow: function() {
    this.setData({
      ready: true,
      showTime: false,
      readyTime: 3
    })
    this.onLogin(this.authCallback, this.authCallback1);
  },
  authCallback() {
    let that = this
    // 獲取當前時間搶紅包資訊
    that.getGrabRed();
    that.setData({
      showLogin: true
    })
  },
  authCallback1() {
    let that = this
    // 獲取當前時間搶紅包資訊
    that.getGrabRed();
    that.setData({
      showLogin: false
    })
  },
  /**
   * 生命周期函式--監聽頁面隱藏
   */
  onHide: function() {},

  /**
   * 生命周期函式--監聽頁面卸載
   */
  onUnload: function() {

  },

  /**
   * 頁面相關事件處理函式--監聽用戶下拉動作
   */
  onPullDownRefresh: function() {

  },

  /**
   * 頁面上拉觸底事件的處理函式
   */
  onReachBottom: function() {

  },

  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function() {

  },
  // 開始準備倒計時
  cultdown: function() {
    let _this = this
    let {
      readyTime
    } = this.data
    readyTimer = setInterval(function() {
      if (--readyTime <= 0) {
        clearInterval(readyTimer)
        // 顯示紅包雨
        _this.run();
      }
      _this.setData({
        readyTime: readyTime
      })
    }, 1000)
  },
  start: function() {
    if (!this.data.showLogin) {
      setTimeout(() => {
        wx.navigateTo({
          url: '/pages/member/loginAndRegister/loginAndRegister',
        })
      }, 500)
      return
    }
    if (this.data.RemainingTimes == 0){
      return
    }
    if (!this.data.showTime) {
      this.cultdown();
      this.setData({
        showTime: true
      })
    }
  },
  run: function() {
    let address = 'nvabarData.address'
    this.setData({
      visible: true,
      createSpeed: 5, // 速度
      time: 10, // 游戲時間
      min: 1, // 金幣最小是0
      max: 1, // 金幣最大是10
      [address]: this.data.ThemeMap || api.pictureServer + '/res/shopImg/RedEnvelopes1.png'
    })
    clearInterval(this.readyTimer);
  },
  // 結束
  success(e) {
    let that = this;
    let redId = this.data.redId;
    console.log('bind:finish', e.detail)
    let RedEnvelopeNum = e.detail;
    // 中獎
    let parm = {
      Id: redId,
      RedEnvelopeNum: RedEnvelopeNum
    }
    http.requestLoading('/api/services/app/RedEnvelope/ExcuteGrabRedEnvelope', parm, '', 'POST').then(res => {
      if (res.data.Result.Code === 0) {
        console.log(res)
        that.setData({
          visible: false //  隱藏界面
        })
        wx.navigateTo({
          url: '/RedEnvelopes/pages/RedEnvelopes/WinningRedEnvelope/WinningRedEnvelope?Id=' + res.data.Result.Data.Id + '&PartId=' + res.data.Result.Data.PartId + '&ShareDescription=' + that.data.ShareDescription + '&ShareIcon=' + that.data.ShareIcon
        })
      }
    })
  },
  // 立即參與
  participateIn() {
    let that = this;
    let redId = this.data.redId;
    let parm = {
      Id: redId
    }
    http.requestLoading('/api/services/app/RedEnvelope/GetGrabRedEnvelopeAppSingle', parm, '', 'GET').then(res => {
      if (res.data.Result.Code === 0) {
        console.log(res)
        if (redId != res.data.Result.Data.Id) {
          wx.showToast({
            title: '當前活動資訊不符',
            icon: 'none'
          })
        } else {
          that.setData({
            redId: res.data.Result.Data.Id
          })
          // 驗證會員是否可以參加該活動
          let parms = {
            Id: res.data.Result.Data.Id,
            RedEnvelopeNum: 0
          }
          if (!this.data.showLogin) {
            setTimeout(() => {
              wx.navigateTo({
                url: '/pages/member/loginAndRegister/loginAndRegister',
              })
            }, 500)
            return
          }
          http.requestLoading('/api/services/app/RedEnvelope/DrawGrabRedEnvelope', parms, '', 'POST').then(res => {
            if (res.data.Result.Code === 0) {
              that.setData({
                ready: true
              })
              that.start();
            }
          })
        }
      }
    })
  },
  // 獲取當前時間搶紅包資訊
  getGrabRed: function(redId) {
    let that = this;
    let address = 'nvabarData.address'
    http.requestLoading('/api/services/app/RedEnvelope/GetGrabRedEnvelopeAppSingle', {}, '', 'GET').then(res => {
      if (res.data.Result.Code === 0) {
        console.log(res)
        that.setData({
          redId: res.data.Result.Data.Id,
          BackgroundMap: res.data.Result.Data.BackgroundMap,
          ThemeMap: res.data.Result.Data.ThemeMap, //活動主題圖
          ActivityRules: res.data.Result.Data.ActivityRules, //活動規則
          ShareDescription: res.data.Result.Data.ShareDescription, //分享描述
          ShareIcon: res.data.Result.Data.ShareIcon, //分享圖示
          [address]: res.data.Result.Data.BackgroundMap
        })
        if (that.data.showLogin) {
          that.getRemainingTimes();
        }
      }
    })
  },
  // 分享得額外抽獎次數
  getRedEnvelopeLotteryShare(parm) {
    http.requestLoading('/api/services/app/RedEnvelope/RedEnvelopeLotteryShare', parm, '', 'POST').then(res => {
      if (res.data.Result.Code === 0) {
        console.log(res)
      }
    })
  },
  // 獲取總次數
  getRemainingTimes() {
    let that = this;
    let parm = {
      Id: this.data.redId
    }
    http.requestLoading('/api/services/app/RedEnvelope/GetRemainingTimes', parm, '', 'GET').then(res => {
      if (res.data.Result.Code === 0) {
        console.log(res)
        that.setData({
          MaxSharingAwardTimes: res.data.Result.Data.MaxSharingAwardTimes,
          RemainingTimes: res.data.Result.Data.RemainingTimes
        })
      }
    })
  }
})
/* RedEnvelopes/pages/RedEnvelopes/index/index.wxss */
page {
  position: relative;
}

.login {
  width: 626rpx;
  height: 554rpx;
  background: #fff;
  border-radius: 10rpx;
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  margin: auto;
}

.login-center {
  width: 501rpx;
  height: 138rpx;
  border-bottom: 1rpx solid #e2e2e2;
  margin: auto;
  display: flex;
  align-items: center;
}

.userIpt {
  font-size: 28rpx;
  font-family: Source Han Sans CN Regular, Source Han Sans CN Regular-Regular;
  font-weight: 400;
  color: #999;
}

.posion {
  position: relative;
}

.zc_view {
  position: absolute;
  right: 0;
  top: 40rpx;
  width: 170rpx;
  height: 52rpx;
  line-height: 52rpx;
  margin-left: 12rpx;
  border: 1rpx solid #e2e2e2;
  text-align: center;
  font-size: 24rpx;
  border-radius: 10rpx;
}

.login-state {
  font-size: 40rpx;
  font-family: Microsoft YaHei Regular, Microsoft YaHei Regular-Regular;
  font-weight: 400;
  color: #333;
  text-align: center;
  margin-top: 146rpx;
}

.login-ready {
  font-size: 30rpx;
  font-family: Microsoft YaHei Regular, Microsoft YaHei Regular-Regular;
  font-weight: 400;
  color: #333;
  text-align: center;
  margin-top: 89rpx;
}

.login-btn {
  width: 299rpx;
  height: 74rpx;
  background: #fc7297;
  border-radius: 37rpx;
  box-shadow: 0rpx 2rpx 6rpx 0rpx rgba(3, 0, 6, 0.1);
  margin: auto;
  margin-top: 65rpx;
  display: flex;
  align-items: center;
  justify-content: center;
}

.btn-txt {
  font-size: 30rpx;
  font-family: Microsoft YaHei Regular, Microsoft YaHei Regular-Regular;
  font-weight: 500;
  color: #fff;
}

/* 開始按鈕 */

.start {
  position: absolute;
  top: 45%;
  padding: 0 250rpx;
}

.start-aperture {
  width: 250rpx;
  height: 250rpx;
  background: rgb(247, 136, 44, 0.29);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.start-aperture-bg {
  width: 210rpx;
  height: 210rpx;
  background: linear-gradient(0deg, #f0510b 0%, #ffc350 100%);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.start-aperture-txt {
  font-size: 60rpx;
  font-family: Source Han Sans CN Medium, Source Han Sans CN Medium-Medium;
  font-weight: 500;
  color: #fff;
}

/* 規則 */

.rule {
  position: absolute;
  left: 0;
  right: 0;
  top: 73%;
}

.rule-top {
  width: 160rpx;
  height: 36rpx;
  background: rgb(237, 216, 255, 0.4);
  border-top-left-radius: 20rpx;
  border-top-right-radius: 20rpx;
  margin: auto;
  text-align: center;
}

.iconxiangxia2 {
  font-size: 28rpx;
  color: #fff;
}

.rule-body {
  width: 660rpx;
  /* height: 208rpx; */
  background: rgb(237, 216, 255, 0.4);
  border-radius: 20rpx;
  margin: auto;
  padding: 38rpx 0 38rpx 38rpx;
}
.rule-body-one{
  display: flex;
}
.rule-body-title {
  display: inline-block;
  width: 81rpx;
  font-size: 26rpx;
  font-family: Source Han Sans CN Normal, Source Han Sans CN Normal-Normal;
  color: #fff;
}

.rule-body-html {
  display: inline-block;
  width: 417rpx;
  font-size: 26rpx;
  font-family: Source Han Sans CN Normal, Source Han Sans CN Normal-Normal;
  color: #fff;
}
/* 新 */
.remaTimes{
  position: absolute;
  left: 0;
  right: 0;
  top: 65%;
  font-size: 30rpx;
  font-family: Microsoft YaHei Regular, Microsoft YaHei Regular-Regular;
  font-weight: 400;
  color: #fff;
  text-align: center;
  margin-top: 20rpx;
}

在當前的頁面中引入了兩個組件,第一個是實作自定義導航欄的,因為在當前的界面中背景圖的要求是全屏的,第二個組件就是紅包雨的下落是參考網上一大佬的紅包雨實作的,

//app.js
// 引入請求檔案
App({
  onLaunch: function(e) {
    //獲取設備頂部視窗的高度(不同設備視窗高度不一樣,根據這個來設定自定義導航欄的高度)
    wx.getSystemInfo({
      success: res => {
        this.globalData.height = res.statusBarHeight
      }
    })
    this.getSystemInfo();
  },
  globalData: {
    share: false, // 分享默認為false
    height: 0, // 頂部高度
    systemInfo: {} //設備資訊
  },
  getSystemInfo: function() {
    var info = util.getSystemInfoSync();
    var iphoneX = "";
    if (info) {
      var statusBarHeight = info.statusBarHeight;
      var model = info.model;
      var windowHeight = info.windowHeight;
      var totalTopHeight = 68;
      model.indexOf("iPhone X") !== -1 ?
        ((totalTopHeight = 94), (iphoneX = "iphone-x")) :
        -1 !== model.indexOf("iPhone") ? (totalTopHeight = 64) : -1 !== model.indexOf("MI 8") && (totalTopHeight = 88);
      var titleBarHeight = totalTopHeight - statusBarHeight;
      this.globalData.systemInfo = Object.assign({}, info, {
        statusBarHeight,
        titleBarHeight,
        totalTopHeight,
        iphoneX,
        windowHeight
      })
    }
  }
})

app.js中針對不同的設備的導航條的高度進行了處理,使之能夠實作適配,

<!--componets/shoppingMall-components/navbar/navbar.wxml-->
<view class='nav-wrap' style='height: {{height*2 + 20}}px;'>
  <!-- 導航欄背景圖片 -->
  <image class="backgroundimg" src="{{navbarData.address}}" bindload="imgLoaded" style="width:{{imageWidth}}px;height:{{imageHeight}}px" />
  <!-- // 導航欄 中間的標題 -->
  <view class='nav-title' wx:if='{{!navbarData.white}}' style='line-height: {{height*2 + 44}}px;'>
    {{navbarData.title}}
  </view>
  <view class='nav-title' wx:else='{{!navbarData.white}}' style='line-height: {{height*2 + 44}}px; color:#ffffff'>
    {{navbarData.title}}
  </view>
  <view style='display: flex; justify-content: space-around;flex-direction: column'>
    <!-- // 導航欄  左上角的回傳按鈕 -->
    <!-- //  其中wx:if='{{navbarData.showCapsule}}' 是控制左上角按鈕的顯示隱藏,首頁不顯示 -->
    <view class='nav-capsule' style='height: {{height*2 + 44}}px;' wx:if='{{navbarData.showCapsule}}'>
      <!-- //左上角的回傳按鈕,wx:if='{{!share}}'空制回傳按鈕顯示 -->
      <!-- //從分享進入小程式時 回傳上一級按鈕不應該存在 -->
      <!-- navbarData.white是控制按鈕顏色的,因為背景有深淺色,回傳按鈕自己找圖片 -->
      <view bindtap='_navback' wx:if='{{showBack}}'>
        <text class="iconfont iconxiangzuo"></text>
      </view>
      <view bindtap='_navbackTo' wx:else>
        <text class="iconfont iconxiaochengxushouye"></text>
      </view>
    </view>
  </view>
</view>
<!-- 導航欄下面的背景圖片 -->
<image class="backgroundimg" src="{{navbarData.address}}" bindload="imgLoaded" style="width:{{imageWidth}}px;height:{{imageHeight}}px" />
// componets/shoppingMall-components/navbar/navbar.js
const app = getApp()
const util = require('../../../utils/indexPage.js');
Component({
  /**
   * 組件的屬性串列
   */
  properties: {
    navbarData: {
      //navbarData   由父頁面傳遞的資料,變數名字自命名
      type: Object,
      value: {},
      observer: function(newVal, oldVal) {}
    }
  },
  options: {
    styleIsolation: 'apply-shared'
  },
  /**
   * 組件的初始資料
   */
  data: {
    height: '',
    //默認值  默認顯示左上角
    navbarData: {
      showCapsule: 1
    },
    imageWidth: wx.getSystemInfoSync().windowWidth, // 背景圖片的高度
    imageHeight: '', // 背景圖片的長度,通過計算獲取
    showBack:false
  },
  attached: function() {
    // 獲取是否是通過分享進入的小程式
    this.setData({
      share: app.globalData.share
    })
    let pages = getCurrentPages();
    if (pages.length > 1){
      this.setData({
        showBack: true
      })
    }
    // 定義導航欄的高度   方便對齊
    this.setData({
      height: app.globalData.height
    })
  },
  /**
   * 組件的方法串列
   */
  methods: {
    // 回傳上一頁面
    _navback() {
      wx.navigateBack()
    },
    _navbackTo(){
      util.indexPage();
    },
    // 計算圖片高度
    imgLoaded(e) {
      // console.log(e, wx.getSystemInfoSync())
      this.setData({
        imageHeight: e.detail.height *
          (wx.getSystemInfoSync().windowHeight / e.detail.height)
      })
    }
    //回傳到首頁
    // _backhome() {
    //   wx.switchTab({
    //     url: '/pages/index/index'
    //   })
    // }
  }
})
/* componets/shoppingMall-components/navbar/navbar.wxss */

/* 頂部要固定定位   標題要居中   自定義按鈕和標題要和右邊微信原生的膠囊上下對齊 */

.nav-wrap {
  /* display: none; */
  position: fixed;
  width: 100%;
  top: 0;
  background: #fff;
  color: #000;
  z-index: 9999999;
  background: #000;
  overflow: hidden;
}

/* 背景圖 */

.backgroundimg {
  position: absolute;
  z-index: -1;
}

/* 標題要居中 */

.nav-title {
  position: absolute;
  text-align: center;
  max-width: 400rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  font-size: 36rpx;
  color: #2c2b2b;
  font-weight: 450;
}

.nav-capsule {
  display: flex;
  align-items: center;
  margin-left: 30rpx;
  width: 140rpx;
  justify-content: space-between;
  height: 100%;
}

.back-pre {
  width: 36rpx;
  height: 40rpx;
  margin-top: 4rpx;
  padding: 10rpx;
}

.nav-capsule {
  width: 36rpx;
  height: 40rpx;
  margin-top: 3rpx;
}

.iconxiangzuo{
  font-size: 41rpx;
  color: #fff;
}

.iconxiaochengxushouye {
  font-size: 41rpx;
  color: #fff;
}

在自定義導航欄中針對不同的進入情況對左上角的按鈕做不同的處理,當是通過掃碼或分享進入的時候左上角是回傳首頁的小房子,通過其他頁面跳轉過來時則是回傳上一級的箭頭,

<view wx:if="{{visible}}" class="red-envelope-popup">
  <view class="container flex-center">
    <view bind:tap="handleClose" catch:touchmove="handleScrollTouch" class="close-bg"></view>
    <block>
      <block wx:if="{{showStatus===2}}">
        <view class="rain-wrapper flex-column">

          <view class="canvas-wrapper">
            <view class='score-change' animation="{{scoreAni}}">
              +{{showChangeScore}}
            </view>
            <canvas disableScroll binderror="canvasIdErrorCallback" bindtouchstart="handleClickRain" canvasId="rain-canvas" style="width: 100vw; height: 100vh;z-index: 9999999;"></canvas>
          </view>
        </view>
      </block>
      <block wx:if="{{showStatus===3}}">
        <view class="result-wrapper flex-column-center">
          <block>
            <view class="group-content flex-column-center" bindtap="handleClose">
              
            </view>
          </block>
        </view>
      </block>
    </block>
  </view>
</view>
const innerAudioContext = wx.createInnerAudioContext()
const api = require('../../../server/api.js');
const APP = getApp()
let readyTimer = null
let rainTimer = null
let redEnvelopes = []
let animation = null
const minWidth = 30 // 紅包圖片最小寬度
const maxWidth = 40 // 紅包圖片最大寬度
Component({
  properties: {
    // 是否開始展示游戲
    visible: {
      type: Boolean,
      value: false
    },
    // 游戲時間
    time: {
      type: Number,
      value: 10
    },
    //  速度
    createSpeed: {
      type: Number,
      value: 5
    },
    // 單個最小金額
    min: {
      type: Number,
      value: 0
    },
    // 單個最大金額
    max: {
      type: Number,
      value: 3
    }
  },
  data: {
    showRainTotalTime: 10, // 紅包雨時間
    showStatus: 1, // 紅包雨狀態:1:準備倒計時,2:正在紅包雨,3:紅包雨結束
    windowWidth: 375,
    windowHeight: 555,
    rainResult: {},
    loading: false,
    showScore: 0,
    showChangeScore: 0,
    scoreStyle: ''
  },
  ready: function() {
    // 重置
    redEnvelopes = []
    // clearTimeout(readyTimer) 
    clearTimeout(rainTimer)
    this.cancelCustomAnimationFrame(animation)
    // 開始準備倒計時
    this.showRain()
    const {
      windowWidth,
      windowHeight
    } = APP.globalData.systemInfo
    this.data.windowWidth = windowWidth
    this.data.windowWidth = windowHeight
  },
  detached: function() {
    // readyTimer && clearInterval(readyTimer)
    rainTimer && clearInterval(rainTimer)
    animation && this.cancelCustomAnimationFrame(animation)
  },
  methods: {
    // 展示紅包雨界面
    showRain: function() {
      let _this = this
      // 顯示紅包雨
      this.setData({
        showStatus: 2
      })
      // 初始化紅包雨
      this.initRain()

      // 倒計時進度條
      this.ininProgress()
      // 紅包雨倒計時
      let showRainTotalTime = this.data.time
      rainTimer = setInterval(function() {
        if (--showRainTotalTime <= 0) {
          clearInterval(rainTimer)
          if (animation) {
            // 結束
            _this.showRainResult()
            _this.cancelCustomAnimationFrame(animation)
          }
        }
        _this.setData({
          showRainTotalTime
        });
      }, 1000);
    },
    // 倒計時進度條
    ininProgress() {
      const {
        time
      } = this.data
      const animation = wx.createAnimation({
        duration: time * 1000
      })
      animation.translateX(-120).step()
      this.setData({
        progressAni: animation.export()
      })
    },
    //分數影片
    animationOfScore(x, y) {
      const position = wx.createAnimation({
        duration: 0
      })
      position.left(x).top(y).step()
      this.setData({
        scoreAni: position.export()
      })
      const animation = wx.createAnimation({
        duration: 300,
        timingFunction: 'ease'
      })
      animation.opacity(1).step()
      setTimeout(function() {
        animation.opacity(0).step()
        this.setData({
          scoreAni: animation.export()
        })
      }.bind(this), 10)
    },
    // 關閉
    handleClose: function() {
      this.triggerEvent("finish", this.data.showScore)
    },
    // 顯示結果
    showRainResult: function() {
      // 結束影片
      this.cancelCustomAnimationFrame(animation)
      this.setData({
        showStatus: 3,
        rainResult: {
          amount: 100
        }
      });
    },
    // 紅包下落函式
    customRequestAnimationFrame: function(e) {
      let _this = this
      let timer = setTimeout(function() {
        e.call(_this), clearTimeout(timer);
      }, 1000 / 60)
      return timer
    },
    // 清除紅包下落函式
    cancelCustomAnimationFrame: function(e) {
      e && (clearTimeout(e), animation = null)
    },
    // 開始下落
    doDrawRain: function() {
      const context = this.context
      const {
        windowWidth,
        windowHeight
      } = this.data
      context.clearRect(0, 0, windowWidth, windowHeight)
      for (let n = 0; n < redEnvelopes.length; n += 1) {
        const i = redEnvelopes[n] // 紅包
        const {
          x,
          y,
          vx,
          vy,
          width,
          height,
          open
        } = i
        const img = open ? this.openEnvelopeImg : this.redEnvelopeImg
        const imgWidth = open ? width + 20 : width
        const imgHeight = open ? height + 25 : height
        if (x < 0) {
          x += 50;
        } else if (x > 750) {
          x -= 50;
        }
        context.drawImage(img, x, y, imgWidth, imgHeight)
        i.x += vx
        i.y += vy
        i.y >= windowHeight && (i.y = 0, i.open = false)
        i.x + width <= 0 && (i.x = windowWidth - width, i.open = false)
      }
      context.draw()
      // 下落函式
      animation = this.customRequestAnimationFrame(this.doDrawRain);
    },
    // 亂數
    randNum: function(min, max) {
      return Math.floor(min + Math.random() * (max - min));
    },
    // 準備紅包雨下落
    initRainDrops: function() {
      const {
        windowWidth,
        windowHeight,
        createSpeed,
        max,
        min
      } = this.data
      for (let n = 0; n < 10; n += 1) {
        const startX = Math.floor(Math.random() * windowWidth)
        // 優化位置,防止紅包越界現象,保證每個紅包都在螢屏之內
        if (startX < 0) {
          startX += 50;
        } else if (startX > windowWidth) {
          startX -= 50;
        }
        const startY = Math.floor(Math.random() * windowHeight)
        // 紅包圖片寬度大小30~40
        const width = this.randNum(minWidth, maxWidth)
        // 寬度為紅包高度的百分之八十
        const height = Math.floor(width / .8)
        // 速度
        const vy = 1 * Math.random() + createSpeed
        // 紅包金額
        const score = this.randNum(min, max + 1)
        redEnvelopes.push({
          x: startX,
          y: startY,
          vx: -1, // x軸速度
          vy: vy, // y軸速度
          score: score,
          width: width,
          height: height,
          open: false
        });
      }
      this.doDrawRain();
    },
    // 點擊紅包事件
    handleClickRain: function(e) {
      let touch = e.touches[0]
      let touchX = touch.x
      let touchY = touch.y
      let _this = this
      for (let o = 0; o < redEnvelopes.length; o += 1) {
        let i = redEnvelopes[o],
          rainX = i.x,
          rainY = i.y,
          width = i.width,
          height = i.height,
          gapX = touchX - rainX,
          gapY = touchY - rainY;
        if (gapX >= -20 && gapX <= width + 20 && gapY >= -20 && gapY <= height + 20) {
          _this.animationOfScore(touchX, touchY)
          innerAudioContext.play()
          i.open = true;
          let score = _this.data.showScore + i.score
          _this.setData({
            showScore: score,
            showChangeScore: i.score
          })
          break;
        }
      }
    },
    // 初始化 canvas
    initRain: function() {
      this.context = wx.createCanvasContext("rain-canvas", this)
      this.redEnvelopeImg = "./images/red-packet-rain.png",
        this.openEnvelopeImg = "./images/red-packet-rain-open.png"
      // 初始化紅包雨
      this.initRainDrops()
      // 音效
      this.audioOfClick()
    },
    handleScrollTouch: function() {},
    audioOfClick() {
      innerAudioContext.autoplay = false
      innerAudioContext.src = 'https://imgs.solui.cn/weapp/dianji.mp3'
      innerAudioContext.onPlay(() => {})
      innerAudioContext.onError(res => {})
    },
  }
});
.flex {
  display: -ms-flexbox;
  display: flex
}
.flex-center {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-direction: column;
  flex-direction: column;
  -ms-flex-align: center;
  align-items: center;
  -ms-flex-pack: center;
  justify-content: center;
  width: 100%;
  height: 100%
}
.flex-column {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-direction: column;
  flex-direction: column
}
.flex-column-center {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-direction: column;
  flex-direction: column;
  -ms-flex-align: center;
  align-items: center
}
.flex-column-sb {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-direction: column;
  flex-direction: column;
  -ms-flex-align: center;
  align-items: center;
  -ms-flex-pack: justify;
  justify-content: space-between
}
.flex-column-c {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-direction: column;
  flex-direction: column;
  -ms-flex-align: center;
  align-items: center;
  -ms-flex-pack: center;
  justify-content: center
}
.flex-row {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: center;
  align-items: center
}
.flex-row-center {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: center;
  align-items: center;
  width: 100%
}
.flex-content-center {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-pack: center;
  justify-content: center;
  width: 100%
}
.flex-column-right {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-direction: column;
  flex-direction: column;
  -ms-flex-align: end;
  align-items: flex-end
}
.flex-column-left {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-direction: column;
  flex-direction: column;
  -ms-flex-align: start;
  align-items: flex-start
}
.flex-sb {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: center;
  align-items: center;
  -ms-flex-pack: justify;
  justify-content: space-between
}
.flex-sa {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: center;
  align-items: center;
  -ms-flex-pack: distribute;
  justify-content: space-around
}
.flex-c {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: center;
  align-items: center;
  -ms-flex-pack: center;
  justify-content: center
}
.flex-sb-start {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-pack: justify;
  justify-content: space-between
}
.flex-start {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-pack: start;
  justify-content: flex-start
}
.flex-end {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-pack: end;
  justify-content: flex-end
}
.flex-center-end {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: center;
  align-items: center;
  -ms-flex-pack: end;
  justify-content: flex-end
}
.flex-end-center {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: end;
  align-items: flex-end;
  -ms-flex-pack: center;
  justify-content: center
}
.flex-end-sb {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: end;
  align-items: flex-end;
  -ms-flex-pack: justify;
  justify-content: space-between
}
.flex-end-start {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: end;
  align-items: flex-end
}
.red-envelope-popup {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 999;
  /* background: rgba(0,0,0,.8) */
}
.red-envelope-popup .close-bg {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0
}
.red-envelope-popup .reminder-wrapper {
  position: relative;
  width: 750rpx;
  height: 716rpx;
  color: #fff;
  box-sizing: border-box
}
.red-envelope-popup .reminder-wrapper .title {
  font-size: 60rpx;
  color: #fffdc5
}
.red-envelope-popup .reminder-wrapper .time {
  margin-top: 100rpx;
  font-size: 240rpx;
  color: #fffdc5
}
.red-envelope-popup .rain-wrapper {
  /* width: 100%; */
  /* height: 100%; */
  /* background-image: url(https://imgs.solui.cn/weapp/redBacketBG.jpg); */
  /* background-size: 100% 100%; */
  /* background-repeat: no-repeat */
}
.red-envelope-popup .rain-wrapper .time-info {
  position: absolute;
  top: 80rpx;
  left: 45rpx;
  font-size: 24rpx;
  color: #fff
}
.red-envelope-popup .rain-wrapper .time-info .progress-wrapper {
  position: relative;
  height: 16rpx;
  width: 240rpx;
  margin-left: 20rpx;
  margin-right: 20rpx;
  border-radius: 16rpx;
  background: #fff;
  overflow: hidden
}
.red-envelope-popup .rain-wrapper .time-info .progress-wrapper .progress {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 240rpx;
  border-radius: 16rpx;
  background: #fe2e00;
  z-index: 1
}
.red-envelope-popup .rain-wrapper .time-info .total-score {
  font-size: 40rpx
}
.red-envelope-popup .rain-wrapper .canvas-wrapper {
  position: relative
}
.red-envelope-popup .rain-wrapper .canvas-wrapper .score-change {
  position: absolute;
  width: 50rpx;
  height: 50rpx;
  font-size: 40rpx;
  color: #fffdc5;
  opacity: 0
}
.red-envelope-popup .result-wrapper {
  width: 100%;
  height: 100%;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-pack: center;
  justify-content: center
}
.red-envelope-popup .result-wrapper .group-content {
  position: relative;
  width: 550rpx;
  height: 700rpx;
  /* background-image: url(https://imgs.solui.cn/weapp/l-rain-gold@2x.png); */
  background-image: url(http://hmspimg.afarsoft.com/static/crmmicroapp/res/shopImg/Demolition.png);
  background-size: 100% 100%;
  background-repeat: no-repeat
}
.red-envelope-popup .result-wrapper .group-content .result-title {
  margin-top: 50rpx;
  font-size: 40rpx;
  color: #fff
}
.red-envelope-popup .result-wrapper .group-content .money-wrapper {
  margin-top: 56rpx;
  color: #fff
}
.red-envelope-popup .result-wrapper .group-content .money-wrapper .money {
  font-size: 120rpx
}
.red-envelope-popup .result-wrapper .group-content .money-wrapper .unit {
  position: relative;
  top: 34rpx;
  font-size: 32rpx
}
.red-envelope-popup .result-wrapper .group-content .result-btn {
  margin-top: 158rpx;
  width: 300rpx;
  height: 70rpx;
  background-color: #fff9e8;
  text-align: center;
  line-height: 70rpx;
  border-radius: 40rpx;
  font-size: 30rpx;
  color: #b10000
}

在這個組件中,在attached這個生命周期的時候進是紅包下落的方法開始執行,在創建紅包橫向坐標的時候需要對坐標進行優化防止紅包出現在螢屏外,

<!--RedEnvelopes/pages/RedEnvelopes/WinningRedEnvelope/WinningRedEnvelope.wxml-->
<view wx:if="{{showMode}}">
  <image src="{{url}}" class="winning"></image>
  <view class="congratulations" wx:if="{{NotWinning}}">很遺憾!</view>
  <view class="congratulations" wx:else>恭喜您!</view>
  <view class="prize" wx:if="{{NotWinning}}">您本次沒有中獎,</view>
  <view class="prize" wx:else>您一共獲得<block wx:if="{{RedEnvelope.AmountCount}}">{{RedEnvelope.AmountCount}}個紅包</block><block wx:if="{{RedEnvelope.AmountCount && RedEnvelope.CouponCount}}">,</block><block wx:if="{{RedEnvelope.CouponCount}}">{{RedEnvelope.CouponCount}}張優惠券</block></view>
  <block wx:for="{{RedEnvelope.CouponWinInfoList}}" wx:key="index">
    <view class="prize-details">
      <view class="prize-quan">
        <image src="{{quan}}" class="quan"></image>
        <text class="quan-txt" wx:if="{{item.UseType == 0}}">{{item.DiscountAmount}}元</text>
        <text class="quan-txt" wx:else>{{item.DiscountRate}}折</text>
        <text class="quan-type coupon">優惠券</text>
      </view>
      <view class="prize-name">{{item.CouponName}}</view>
      <view class="prize-num">數量:{{item.Num}}</view>
    </view>
  </block>
  <block wx:for="{{RedEnvelope.AmountWinInfoList}}" wx:key="index">
    <view class="prize-details">
      <view class="prize-quan">
        <image src="{{quan}}" class="quan"></image>
        <text class="quan-txt">{{item.RedEnvelopeAmount}}元</text>
        <text class="quan-type cash">現金</text>
      </view>
      <view class="prize-name">{{item.RedEnvelopeAmount}}元現金紅包</view>
      <view class="prize-num">數量:{{item.Num}}</view>
    </view>
  </block>
  <view class="share">
    <view class="share-left">邀請好友參加活動</view>
    <view class="share-left lower">每天可獲得
      <text class="share-num" wx:if="{{NotWinning}}">{{MaxSharingAwardTimes}}次</text>
      <text class="share-num" wx:else>{{RedEnvelope.MaxSharingAwardTimes}}次</text>分享獎勵</view>
    <button class="share-btn" open-type="share">
      <text class="share-txt">去分享</text>
    </button>
  </view>
</view>
// RedEnvelopes/pages/RedEnvelopes/WinningRedEnvelope/WinningRedEnvelope.js
const api = require('../../../../server/api.js');
const http = require('../../../../server/request.js');
Page({

  /**
   * 頁面的初始資料
   */
  data: {
    url: api.pictureServer + '/res/shopImg/winning.png',
    quan: api.pictureServer + '/res/shopImg/redCoupon.png',
    Id: '', //搶紅包活動標識
    PartId: '', //搶紅包參與資訊標識
    RedEnvelope: {},
    ShareDescription: '', //分享描述
    ShareIcon: '', //分享圖示
    NotWinning: true, //未中獎
    showMode: false
  },

  /**
   * 生命周期函式--監聽頁面加載
   */
  onl oad: function(options) {
    console.log(options)
    this.setData({
      Id: options.Id,
      PartId: options.PartId,
      ShareDescription: options.ShareDescription,
      ShareIcon: options.ShareIcon,
    })
    let parm = {
      Id: options.Id,
      PartId: options.PartId
    }
    this.getGrabRedEnvelopeWinInfo(parm);
  },

  /**
   * 生命周期函式--監聽頁面初次渲染完成
   */
  onReady: function() {

  },

  /**
   * 生命周期函式--監聽頁面顯示
   */
  onShow: function() {

  },

  /**
   * 生命周期函式--監聽頁面隱藏
   */
  onHide: function() {

  },

  /**
   * 生命周期函式--監聽頁面卸載
   */
  onUnload: function() {

  },

  /**
   * 頁面相關事件處理函式--監聽用戶下拉動作
   */
  onPullDownRefresh: function() {

  },

  /**
   * 頁面上拉觸底事件的處理函式
   */
  onReachBottom: function() {

  },

  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function() {
    let ShareMemberId = wx.getStorageSync('CustomerService').MemberId
    return {
      title: this.data.ShareDescription,
      // desc: '快來搶紅包雨',
      imageUrl: this.data.ShareIcon,
      path: '/RedEnvelopes/pages/RedEnvelopes/index/index?refer=' + this.data.Id + '&ShareMemberId=' + ShareMemberId,
      success: function(res) {
        // 轉發成功
        wx.showToast({
          title: '分享成功',
          icon: 'none'
        })
      },
      fail: function(res) {
        // 轉發失敗
      }
    }
  },
  // 拆開紅包得到中獎資訊
  getGrabRedEnvelopeWinInfo: function(parm) {
    let that = this;
    http.requestLoading('/api/services/app/RedEnvelope/GetGrabRedEnvelopeWinInfo', parm, '', 'GET').then(res => {
      if (res.data.Result.Code === 0) {
        console.log(res)
        that.setData({
          NotWinning: false,
          RedEnvelope: res.data.Result.Data,
          showMode: true
        })
      } else if (res.data.Result.Code === 1) {
        //未中獎
        that.setData({
          NotWinning: true,
          MaxSharingAwardTimes: res.data.Result.Data.MaxSharingAwardTimes,
          showMode: true
        })
      }
    })
  }
})
/* RedEnvelopes/pages/RedEnvelopes/WinningRedEnvelope/WinningRedEnvelope.wxss */
page {
  width: 100%;
  background: rgb(254, 177, 198, 0.2);
}
/* 禮品 */
.winning {
  width: 286rpx;
  height: 294rpx;
  display: block;
  margin: 20rpx auto;
}

.congratulations {
  font-size: 46rpx;
  font-family: Adobe Heiti Std R, Adobe Heiti Std R-R;
  color: #ff3005;
  text-align: center;
}

.prize {
  font-size: 28rpx;
  font-family: Adobe Heiti Std R, Adobe Heiti Std R-R;
  color: #fc7297;
  text-align: center;
  margin: 38rpx auto;
}
/* 獎勵內容 */
.prize-details {
  width: 668rpx;
  height: 150rpx;
  background: #fff;
  border-radius: 10rpx;
  display: block;
  margin: auto;
  padding: 38rpx 0 38rpx 38rpx;
  margin-bottom: 20rpx;
  position: relative;
}

.prize-quan {
  width: 177rpx;
  position: relative;
}

.quan {
  width: 177rpx;
  height: 74rpx;
}

.quan-txt {
  position: absolute;
  top: 20rpx;
  left: 30rpx;
  font-size: 28rpx;
  font-family: Source Han Sans CN Regular, Source Han Sans CN Regular-Regular;
  font-weight: 400;
  color: #fff;
}

.quan-type {
  width: 19rpx;
  font-size: 20rpx;
  font-family: Source Han Sans CN Regular, Source Han Sans CN Regular-Regular;
  font-weight: 400;
  text-align: left;
  color: #fff;
  line-height: 22rpx;
}

.coupon {
  position: absolute;
  top: 7rpx;
  right: 16rpx;
  height: 63rpx;
}

.cash {
  position: absolute;
  top: 15rpx;
  right: 16rpx;
  height: 39rpx;
}

.prize-name {
  font-size: 30rpx;
  font-family: Source Han Sans CN Regular, Source Han Sans CN Regular-Regular;
  font-weight: 400;
  color: #333;
  position: absolute;
  top: 37rpx;
  left: 244rpx;
}

.prize-num {
  font-size: 24rpx;
  font-family: Source Han Sans CN Regular, Source Han Sans CN Regular-Regular;
  font-weight: 400;
  color: #333;
  position: absolute;
  top: 86rpx;
  left: 244rpx;
}
/* 分享 */
.share {
  width: 668rpx;
  height: 150rpx;
  background: #f77b7b;
  border-radius: 10rpx;
  margin: 40rpx auto;
  position: relative;
}

.share-left {
  font-size: 30rpx;
  font-family: Source Han Sans CN Normal, Source Han Sans CN Normal-Normal;
  color: #fff;
  position: absolute;
  top: 32rpx;
  left: 47rpx;
}

.lower {
  position: absolute;
  top: 73rpx;
  left: 47rpx;
}

.share-num {
  font-size: 38rpx;
}

.share-btn {
  width: 170rpx;
  height: 49rpx;
  background: linear-gradient(0deg, #fa8d35 0%, #ffc341 100%);
  border-radius: 25rpx;
  display: flex;
  justify-content: center;
  align-items: center;
  position: absolute;
  top: 55rpx;
  right: 35rpx;
}

.share-txt {
  font-size: 30rpx;
  font-family: Source Han Sans CN Normal, Source Han Sans CN Normal-Normal;
  font-weight: 500;
  color: #fff;
}

在查看紅包界面中沒有太多需要主要的東西,主要實作分享即可,

<!--RedEnvelopes/pages/RedEnvelopes/WinningRecord/WinningRecord.wxml-->
<wxs module="func">
  module.exports = {
    strSplit: function(str, con) {
      return str.split(con);
    }
  }
</wxs>
<view>
  <view class="calendar_container container">
    <view class="select" bindtap="dateClick">
      <view>{{showStartDate||showEndDate?showStartDate+'-'+showEndDate:'全部'}}</view>
    </view>
    <i class="iconfont iconrili" bindtap="dateClick"></i>
  </view>
  <view class="container">
    <block wx:for="{{DrawRecordlist}}" wx:key="{{index}}">
      <view class="DrawRecordItem">
        <view class="item0">
          <view class="item_txt">{{item.CreateTime}}</view>
        </view>
        <view class="item1">
          <block wx:for="{{item.HongBaoWinningRecordList}}" wx:key="{{index}}">
            <view class="item_txt dib mr-5">{{item.RedEnvelopeAmount}}元紅包
              <text class="lookCode lookCodes">X{{item.HongBaoNum}}</text>
            </view>
          </block>
          <block wx:for="{{item.CouponWinningRecordList}}" wx:key="{{index}}">
            <view class="item_txt dib mr-5">{{item.CouponName}}
              <text class="lookCode">X{{item.CouponNum}}</text>
            </view>
          </block>
        </view>
      </view>
    </block>
  </view>
  <CalendarComponent id="calendar-component" startDate="{{startDate}}" endDate="{{endDate}}" bind:myevent="getDate"></CalendarComponent>
</view>
// RedEnvelopes/pages/RedEnvelopes/WinningRecord/WinningRecord.js
// 引入URL
const http = require('../../../../server/request.js');
//呼叫公共js物件以便呼叫其方法
var app = require('../../../../utils/uselogn.js'); //獲取應用實體
var util = require('../../../../utils/util.js') //公用方法
const api = require('../../../../server/api.js');
var pageNum = 1;
Page({

  /**
   * 頁面的初始資料
   */
  data: {
    //組件資料
    componentData: null,
    // 僅支持 年-月-1
    startDate: "1960/1/1",
    endDate: new Date().getFullYear() + "/" + (new Date().getMonth() + 1) + "/" + new Date().getDate(),
    pictureServer: api.pictureServer,
    tabIndex: 0,
    skinStyle: "",
    userDaysAward: [], //用戶簽到獎勵
    signInReward: [], //連續簽到獎勵
    showStartDate: "", //顯示用的
    showEndDate: "", //顯示用的
    time1: "",
    time2: "",
    DrawRecordlist: [],
    ActivityId: ""
  },
  onLogin: app.userLogin,
  /**
   * 生命周期函式--監聽頁面加載
   */
  onl oad: function(options) {
    pageNum = 1;
    //創建自定義組件實體
    this.setData({
      componentData: this.selectComponent('#calendar-component')
    })
    this.setData({
      skinStyle: wx.getStorageSync("skin")
    })
    if (options.ActivityId) {
      this.setData({
        ActivityId: options.ActivityId
      })
    }
    this.onLogin(this.callback)

  },

  /**
   * 生命周期函式--監聽頁面初次渲染完成
   */
  onReady: function() {

  },

  /**
   * 生命周期函式--監聽頁面顯示
   */
  onShow: function() {},

  /**
   * 生命周期函式--監聽頁面隱藏
   */
  onHide: function() {

  },

  /**
   * 生命周期函式--監聽頁面卸載
   */
  onUnload: function() {

  },

  /**
   * 頁面相關事件處理函式--監聽用戶下拉動作
   */
  onPullDownRefresh: function() {

  },

  /**
   * 頁面上拉觸底事件的處理函式
   */
  onReachBottom: function() {
    pageNum++;
    this.getLotteryRecord();
  },

  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function() {

  },
  callback() {
    this.getLotteryRecord(this.data.time1,
      this.data.time2)
  },
  /**
   * tab切換
   */
  //獲取會員的中獎紀錄資訊
  getLotteryRecord(s, e) {
    http.requestLoading("/api/services/app/RedEnvelope/MemberWinningRecord", {
      "StartDate": s ? s + " 00:00:00" : '',
      "EndDate": e ? e + " 23:59:59" : '',
      "page": pageNum,
      "rows": 10
    }, "", "POST").then(res => {
      if (res.data.Result.Code === 0) {
        if (!res.data.Result.Rows) {
          wx.showToast({
            title: '無更多資料了',
            icon: "none"
          })
          return
        }
        this.setData({
          DrawRecordlist: this.data.DrawRecordlist.concat(res.data.Result.Rows)
        })
      }
    })
  },
  showClick(e) {
    const {
      index
    } = e.currentTarget.dataset
    const data = this.data.signInReward
    data[index].show = !data[index].show
    this.setData({
      signInReward: data
    })
  },
  //顯示組件
  dateClick() {
    this.data.componentData.createAni()
  },
  //獲取開始結束
  getDate(e) {
    const startDate = e.detail[0]
    const endDate = e.detail[1]
    this.setData({
      showStartDate: startDate.replace(/-/g, '/'),
      showEndDate: endDate ? endDate.replace(/-/g, '/') : "",
      time1: startDate,
      time2: endDate ? endDate : "",
      DrawRecordlist: []
    })
    this.getLotteryRecord(startDate, endDate)
  }
})
/* RedEnvelopes/pages/RedEnvelopes/WinningRecord/WinningRecord.wxss */

page {
  background-color: #f5f6f7;
}

.container {
  padding: 0 40rpx;
  box-sizing: border-box;
}

/* 選擇日歷 */

.calendar_container {
  width: 100%;
  height: 86rpx;
  display: flex;
  align-items: center;
}

.select {
  width: 320rpx;
  height: 58rpx;
  background: #fff;
  border-radius: 10rpx;
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: #999;
  font-size: 24rpx;
  padding-left: 20rpx;
  padding-right: 10rpx;
}

.iconrili {
  margin-left: 22rpx;
  font-size: 32rpx;
  color: rgba(205, 205, 205, 0.97);
}

.DrawRecordItem {
  margin-top: 16rpx;
  background: #fff;
  border-radius: 10rpx;
}

.item1 {
  padding: 0 22rpx 22rpx 22rpx;
  width: 100%;
  background: #fff;
  border-radius: 10rpx;
}

.lookCode {
  font-size: 24rpx;
  font-family: Source Han Sans CN Normal, Source Han Sans CN Normal-Normal;
  font-weight: 400;
  color: #4ace8c;
}

.lookCodes {
  color: #fc7297;
}

.item0 {
  padding: 0 16rpx 0 26rpx;
  width: 100%;
  height: 66rpx;
  background: #fff;
  border-radius: 10rpx;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.item_txt {
  font-size: 24rpx;
  font-family: Source Han Sans CN Normal, Source Han Sans CN Normal-Normal;
  font-weight: 400;
  color: #666;
}

.mr-5 {
  margin-right: 20rpx;
}

在中獎紀錄查看的頁面中使用的自己封裝的日歷組件,僅是為了復合專案的要求,在此就不做展示了,
紅包雨整個流程到此就結束了,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/66259.html

標籤:區塊鏈

上一篇:[題解]the moon

下一篇:js 防抖和節流的區別和使用 函式去抖(debounce)函式節流(throttle)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • JAVA使用 web3j 進行token轉賬

    最近新學習了下區塊鏈這方面的知識,所學不多,給大家分享下。 # 1. 關于web3j web3j是一個高度模塊化,反應性,型別安全的Java和Android庫,用于與智能合約配合并與以太坊網路上的客戶端(節點)集成。 # 2. 準備作業 jdk版本1.8 引入maven <dependency> < ......

    uj5u.com 2020-09-10 03:03:06 more
  • 以太坊智能合約開發框架Truffle

    前言 部署智能合約有多種方式,命令列的瀏覽器的渠道都有,但往往跟我們程式員的風格不太相符,因為我們習慣了在IDE里寫了代碼然后打包運行看效果。 雖然現在IDE中已經存在了Solidity插件,可以撰寫智能合約,但是部署智能合約卻要另走他路,沒辦法進行一個快捷的部署與測驗。 如果團隊管理的區塊節點多、 ......

    uj5u.com 2020-09-10 03:03:12 more
  • 谷歌二次驗證碼成為區塊鏈專用安全碼,你怎么看?

    前言 谷歌身份驗證器,前些年大家都比較陌生,但隨著國內互聯網安全的加強,它越來越多地出現在大家的視野中。 比較廣泛接觸的人群是國際3A游戲愛好者,游戲盜號現象嚴重+國外賬號安全應用廣泛,這類游戲一般都會要求用戶系結名為“兩步驗證”、“雙重驗證”等,平臺一般都推薦用谷歌身份驗證器。 后來區塊鏈業務風靡 ......

    uj5u.com 2020-09-10 03:03:17 more
  • 密碼學DAY1

    目錄 ##1.1 密碼學基本概念 密碼在我們的生活中有著重要的作用,那么密碼究竟來自何方,為何會產生呢? 密碼學是網路安全、資訊安全、區塊鏈等產品的基礎,常見的非對稱加密、對稱加密、散列函式等,都屬于密碼學范疇。 密碼學有數千年的歷史,從最開始的替換法到如今的非對稱加密演算法,經歷了古典密碼學,近代密 ......

    uj5u.com 2020-09-10 03:03:50 more
  • 密碼學DAY1_02

    目錄 ##1.1 ASCII編碼 ASCII(American Standard Code for Information Interchange,美國資訊交換標準代碼)是基于拉丁字母的一套電腦編碼系統,主要用于顯示現代英語和其他西歐語言。它是現今最通用的單位元組編碼系統,并等同于國際標準ISO/IE ......

    uj5u.com 2020-09-10 03:04:50 more
  • 密碼學DAY2

    ##1.1 加密模式 加密模式:https://docs.oracle.com/javase/8/docs/api/javax/crypto/Cipher.html ECB ECB : Electronic codebook, 電子密碼本. 需要加密的訊息按照塊密碼的塊大小被分為數個塊,并對每個塊進 ......

    uj5u.com 2020-09-10 03:05:42 more
  • NTP時鐘服務器的特點(京準電子)

    NTP時鐘服務器的特點(京準電子) NTP時鐘服務器的特點(京準電子) 京準電子官V——ahjzsz 首先對時間同步進行了背景介紹,然后討論了不同的時間同步網路技術,最后指出了建立全球或區域時間同步網存在的問題。 一、概 述 在通信領域,“同步”概念是指頻率的同步,即網路各個節點的時鐘頻率和相位同步 ......

    uj5u.com 2020-09-10 03:05:47 more
  • 標準化考場時鐘同步系統推進智能化校園建設

    標準化考場時鐘同步系統推進智能化校園建設 標準化考場時鐘同步系統推進智能化校園建設 安徽京準電子科技官微——ahjzsz 一、背景概述隨著教育事業的快速發展,學校建設如雨后春筍,隨之而來的學校教育、管理、安全方面的問題成了學校管理人員面臨的最大的挑戰,這些問題同時也是學生家長所擔心的。為了讓學生有更 ......

    uj5u.com 2020-09-10 03:05:51 more
  • 位元幣入門

    引言 位元幣基本結構 位元幣基礎知識 1)哈希演算法 2)非對稱加密技術 3)數字簽名 4)MerkleTree 5)哪有位元幣,有的是UTXO 6)位元幣挖礦與共識 7)區塊驗證(共識) 總結 引言 上一篇我們已經知道了什么是區塊鏈,此篇說一下區塊鏈的第一個應用——位元幣。其實先有位元幣,后有的區塊 ......

    uj5u.com 2020-09-10 03:06:15 more
  • 北斗對時服務器(北斗對時設備)電力系統應用

    北斗對時服務器(北斗對時設備)電力系統應用 北斗對時服務器(北斗對時設備)電力系統應用 京準電子科技官微(ahjzsz) 中國北斗衛星導航系統(英文名稱:BeiDou Navigation Satellite System,簡稱BDS),因為是目前世界范圍內唯一可以大面積提供免費定位服務的系統,所以 ......

    uj5u.com 2020-09-10 03:06:20 more
最新发布
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:46:47 more
  • Hyperledger Fabric 使用 CouchDB 和復雜智能合約開發

    在上個實驗中,我們已經實作了簡單智能合約實作及客戶端開發,但該實驗中智能合約只有基礎的增刪改查功能,且其中的資料管理功能與傳統 MySQL 比相差甚遠。本文將在前面實驗的基礎上,將 Hyperledger Fabric 的默認資料庫支持 LevelDB 改為 CouchDB 模式,以實作更復雜的資料... ......

    uj5u.com 2023-04-16 07:28:31 more
  • .NET Core 波場鏈離線簽名、廣播交易(發送 TRX和USDT)筆記

    Get Started NuGet You can run the following command to install the Tron.Wallet.Net in your project. PM> Install-Package Tron.Wallet.Net 配置 public reco ......

    uj5u.com 2023-04-14 08:08:00 more
  • DKP 黑客分析——不正確的代幣對比率計算

    概述: 2023 年 2 月 8 日,針對 DKP 協議的閃電貸攻擊導致該協議的用戶損失了 8 萬美元,因為 execute() 函式取決于 USDT-DKP 對中兩種代幣的余額比率。 智能合約黑客概述: 攻擊者的交易:0x0c850f,0x2d31 攻擊者地址:0xF38 利用合同:0xf34ad ......

    uj5u.com 2023-04-07 07:46:09 more
  • Defi開發簡介

    Defi開發簡介 介紹 Defi是去中心化金融的縮寫, 是一項旨在利用區塊鏈技術和智能合約創建更加開放,可訪問和透明的金融體系的運動. 這與傳統金融形成鮮明對比,傳統金融通常由少數大型銀行和金融機構控制 在Defi的世界里,用戶可以直接從他們的電腦或移動設備上訪問廣泛的金融服務,而不需要像銀行或者信 ......

    uj5u.com 2023-04-05 08:01:34 more
  • solidity簡單的ERC20代幣實作

    // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; import "hardhat/console.sol"; //ERC20 同質化代幣,每個代幣的本質或性質都是相同 //ETH 是原生代幣,它不是ERC20代幣, ......

    uj5u.com 2023-03-21 07:56:29 more
  • solidity 參考型別修飾符memory、calldata與storage 常量修飾符C

    在solidity語言中 參考型別修飾符(參考型別為存盤空間不固定的數值型別) memory、calldata與storage,它們只能修飾參考型別變數,比如字串、陣列、位元組等... memory 適用于方法傳參、返參或在方法體內使用,使用完就會清除掉,釋放記憶體 calldata 僅適用于方法傳參 ......

    uj5u.com 2023-03-08 07:57:54 more
  • solidity注解標簽

    在solidity語言中 注釋符為// 注解符為/* 內容*/ 或者 是 ///內容 注解中含有這幾個標簽給予我們使用 @title 一個應該描述合約/介面的標題 contract, library, interface @author 作者的名字 contract, library, interf ......

    uj5u.com 2023-03-08 07:57:49 more
  • 評價指標:相似度、GAS消耗

    【代碼注釋自動生成方法綜述】 這些評測指標主要來自機器翻譯和文本總結等研究領域,可以評估候選文本(即基于代碼注釋自動方法而生成)和參考文本(即基于手工方式而生成)的相似度. BLEU指標^[^?88^^?^]^:其全稱是bilingual evaluation understudy.該指標是最早用于 ......

    uj5u.com 2023-02-23 07:27:39 more
  • 基于NOSTR協議的“公有制”版本的Twitter,去中心化社交軟體Damus

    最近,一個幽靈,Web3的幽靈,在網路游蕩,它叫Damus,這玩意詮釋了什么叫做病毒式營銷,滑稽的是,一個Web3產品卻在Web2的產品鏈上瘋狂傳銷,各方大佬紛紛為其背書,到底發生了什么?Damus的葫蘆里,賣的是什么藥? 注冊和簡單實用 很少有什么產品在用戶注冊環節會有什么噱頭,但Damus確實出 ......

    uj5u.com 2023-02-05 06:48:39 more