LOGO logo

需求 开发 交付;每一步修改到满意后在付款。

下载到桌面 免费获取解决方案
当前位置: 网站建设/ 微信小程序制作/ 微信小程序制作中如何制作打卡倒计时功能-附代码

微信小程序制作中如何制作打卡倒计时功能-附代码

日期:2021-04-21 10:30 浏览量:1077

微信小程序制作中如何制作倒计时的功能,效果样式图如下,下面直接贴代码



1、css代码

.container {background-color:#F3F3F3;}

/*合作商家*/
.brand-info .name{ width: 100%;height: 350rpx;position: relative;}
.brand-info .img1{ position: absolute; top:0;left:0; width: 100%; height: 350rpx;}
.imgbg{width: 100%; height: 350rpx; top: 0; left: 0; position: absolute; background: #000; filter:alpha(Opacity=80);-moz-opacity:0.8;opacity: 0.8}
.brand-info .info-box{position: absolute;top:0;left:0;width: 100%;height: 350rpx;text-align: center; display: flex;justify-content: center; align-items: center;
}
.brand-info .info{ display: block;}
.brand-info .txt{display: block;  letter-spacing: 2px;color:#ffffff; font-weight:bold;}
.brand-info .line{ margin: 0 auto;margin-top: 16rpx;display:flex; flex-direction:row; }
.brand-info .line .num-people {padding-right:10px;color:#ffffff; font-weight:bold;}
.brand-info .line .sline {height:20px;width:3rpx;background-color: #ffffff;display: block;}
.brand-info .line .txt-dk {padding-left:10px;color:#ffffff; font-weight:bold;}

/* 在线打卡 */
.am-dakai {background-color:#ffffff;display: block;padding-bottom:10px;}
.am-dakai .am-dk {border-bottom:#efefef 1px solid;font-size:.7rem;padding-left:10px;padding-bottom:10px;padding-top:10px;}
.am-dakai .am-dk .am-ico{width:20px;height:20px; vertical-align: bottom;padding-right:10rpx;}
.am-dakai .am-startdk {border-bottom:#efefef 1px solid; font-size:.7rem;color:#ff5600;padding-left:8px; height:40px; line-height:40px;}
.am-dakai .am-d1 {margin-top:10px; text-align: center}
.am-dakai .am-kq {padding-top:10px; width:100%; }
.am-dakai .am-kq .am-name {width:60%;height:270rpx; position: relative;}
.am-dakai .am-kq .am-name .img {position: absolute;width:270rpx;height:270rpx;}
.am-dakai .am-kq .am-name .info-box{
    position: absolute; top:15px; left:68px; width: 100%;  height: 200rpx;text-align: center;display: flex; justify-content: center; align-items: center;
}
.am-dakai .am-kq .am-name .info{ display: block; text-align: center;}
.am-dakai .am-kq .am-name .txt{ display: block; height: 37.5rpx;font-size: 37.5rpx;color: #fff;margin-left:10px;}

.am-line {width:100%;background:#F3F3F3;height:10px;}

.dk-1 {padding-right:10rpx; font-size:.8rem;}
.dk-2 {color:#ff0000;font-size:.8rem;}

/* 评价 */
.am-pingjia {background-color:#ffffff;}
.am-pingjia .am-left {display: flex;padding: 20rpx 0;   align-items: center;width:100%;}
.userinfo-avatar {width: 100rpx;height: 100rpx;margin: 20rpx; border-radius: 50%;}
.userinfo-nickname {color: #333;}
.am-description{display:flex; flex-direction:row; padding-bottom:10px;}
.am-fuwu {padding-left:15px; vertical-align: bototm;}
.stars{
    background:url("http://login.pink333.com/uploads/20180911/c52b67b195b552bc1a14ed74dc9d4448.png");width: 50rpx;height: 50rpx;background-size: 50rpx 50rpx; margin-left: 30rpx;transition: 600ms;
}
.on{
    background:url("http://login.pink333.com/uploads/20180911/50a17380c22133d165a2c1f04ee09aba.png");
    width: 50rpx; height: 50rpx;background-size: 50rpx 50rpx; transition: 1s; transform: scale(1,1)
}
.weui-textarea {padding:5px;}
.weui-cells_after-title{ width: 92%; margin:0 auto; border:1px solid #ddd;}
.weui-textarea-counter {float:right;padding-right:10px;padding-bottom:5px;}
.weui-cell__bd {height:7em;}
.btnSf{ width: 80%;margin:30rpx auto; }
.btnSf button{ background: #F43272;color: #fff;}
.btnSf button:active{ background: #5BC2C6; color: #fff;}


/* 日历 */
.box1 .dateBox{
width: 100%;
height: 50px;
line-height: 50px;
text-align: center;
margin-top: 20px;
font-size: 40rpx;
}

.box1{
display: flex;
flex-wrap: wrap;
margin: 0 auto;
}

.box1>view{
height: 30px;
line-height: 30px;
text-align: center;
font-size: 34rpx;
}

.dateOn{
border-radius: 50%;
background-color: hotpink;
color: #fff;
}
.ball {
box-shadow:2px 2px 10px #AAA;
border-radius: 20px;
position: absolute;
}
.font-color{
color:#a9a9a9;
}


2、js代码

const api = require('../../config/api.js');
const util = require('../../utils/util.js');
const user = require('../../services/user.js');
const app = getApp();

/**
 * 打卡计时
 */
function countdown(that) {
  var enddate = that.data.end_time;
  var newTimeStr = enddate.replace(/-/g, "/");
  var EndTime = new Date(newTimeStr).getTime();

  var startdate = new Date();
  var start_value = startdate.getFullYear() + '-' + (startdate.getMonth() + 1) + '-' + startdate.getDate() + ' ' + startdate.getHours() + ':' + startdate.getMinutes() + ':' + startdate.getSeconds(); 
  var startformat = start_value.replace(/-/g, "/");
  var NowTime = new Date(startformat).getTime() || [];
  var total_micro_second = EndTime - NowTime;
  if (total_micro_second < 0) {
    total_micro_second = 1;  
  }
  console.log('开始时间:' + new Date() + ',结束时间:' + EndTime + ',总秒数:' + total_micro_second);
  that.setData({
    clock: dateformat(total_micro_second)   //若已结束,此处输出'0天0小时0分钟0秒'
  });
  if (total_micro_second <= 0) {
    that.setData({
      clock: "已经截止"
    });
    return;
  }
  setTimeout(function () {
    total_micro_second -= 1000;
    countdown(that);
  }, 1000)

} 

/**
 * 日期格式化
 */
function dateformat(micro_second) {   
  // 总秒数   
  var second = Math.floor(micro_second / 1000); 
  // 天数  
  //var day = Math.floor(second / 3600 / 24); 
   // 小时   
  //var hr = Math.floor(second / 3600 % 24); 
  var hr = Math.floor(second / 3600);
  // 分钟   
  var min = Math.floor((second - hr * 3600) / 60); 
  // 秒   
  var sec = Math.floor(second - hr * 3600 - min * 60); 
  return  min + ":" + sec; 
 } 

var time = 0;
var touchDot = 0;//触摸时的原点
var interval = "";
var flag_hd = true;

Page({

  /**
   * 页面的初始数据
   */
  data: {
    id: 0,
    sellerInfo: {},
    seller: [],
    image_url: app.globalData.image_url,
    image_url2: app.globalData.image_url2,
    imageHeight: wx.getSystemInfoSync().windowHeight,
    clock: '打卡计时',
    end_time:'',
    dkdate: 0,
    userInfo: {},
    flag: 0,
    noteMaxLen: 200, // 最多放多少字
    info: "",
    noteNowLen: 0,//备注当前字数
    total:0,
    punchId:0,
    userTotal: 0,
    overTotal: 0,
    p_id: 0,

    font: "",
    arr: [],
    sysW: null,
    lastDay: null,
    firstDay: null,
    weekArr: ['日', '一', '二', '三', '四', '五', '六'],
    year: null,
    day: null,
    ballTop: 0,
    ballLeft: 0,
    screenHeight: 0,
    screenWidth: 0,
    text: "没有滑动",
  },

  /**
   * 图片自适应高度
   */
  imgHeight: function (e) {
    var winWid = wx.getSystemInfoSync().windowWidth; //获取当前屏幕的宽度  
    var imgh = e.detail.height;//图片高度   
    var imgw = e.detail.width;//图片宽度   
    var swiperH = winWid * imgh / imgw + "px" //等比设置swiper的高度。 即 屏幕宽度 / swiper高度 = 图片宽度 / 图片高度  ==》swiper高度 = 屏幕宽度 * 图片高度 / 图片宽度   
    this.setData({
      imageHeight: swiperH//设置高度  
    })
  }, 

 
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options,year, month, day, state) {
    let that = this;
    that.setData({
      id: options.id
    })
    this.getSellerInfo();
    // 页面初始化 options为页面跳转所带来的参数
    this.setData({
      userInfo: app.globalData.userInfo,
    });

    wx.getSystemInfo({
      success: function (res) {
        that.setData({
          screenHeight: res.windowHeight,
          screenWidth: res.windowWidth,
          font: ""
        });
      }
    });

    this.dataTime(year, month, day, state);
    var two;
    var res = wx.getSystemInfoSync();
    var date = ""
    if (this.data.getWeek == 0) {
      date = this.data.getDate
    }
    else if (this.data.getDate <= this.data.getWeek) {
      two = 1
      date = 1
    }
    else {
      date = this.data.getDate - Number(this.data.getWeek)
    }
    var num = Number(this.data.getDate + (6 - this.data.getWeek));
    if (num > this.data.lastDay) {
      num = this.data.lastDay
    }
    var cha = Number(this.data.lastDay - date)
    var endDay;
    this.data.arr = []
    var startDay = date;
    if (two == 1) {
      this.setData({
        font: 1
      })
      var last = new Date(this.data.year, this.data.month - 1, 1).getDay()
      var start = new Date(this.data.year, this.data.month - 1, 0).getDate()
      var now = start - last + 1
      var newdate = new Date(this.data.year, this.data.month - 1, now)
      startDay = newdate.getDate()
      for (var i = startDay; i <= start; i++) {
        this.data.arr.push(i);
      }
    }
    for (var i = date; i <= num; i++) {
      this.data.arr.push(i);
      endDay = i;
    }
    if (cha < 6) {
      this.setData({
        font: 2
      })
      for (var i = 1; i <= (6 - cha); i++) {
        this.data.arr.push(i);
        endDay = i;
      }
    }
    that.setData({
      sysW: res.windowHeight / 12,//更具屏幕宽度变化自动设置宽度
      marLet: that.data.firstDay,
      arr: that.data.arr,
      year: that.data.year,
      getDate: that.data.getDate,
      month: that.data.month,
      endDay: endDay,
      startDay: startDay
    });
  },

  /**
     * 基本信息
     */
  getSellerInfo: function () {
    var that = this;
    let user = wx.getStorageSync('userInfo');
    util.request(api.sellerDetail, { id: that.data.id, m_id: user.m_id}, 'POST').then(res => {
      console.log(res);
      if (res.errCode == 200) {
        wx.setNavigationBarTitle({
          title: res.errMsg.sellerDetail['s_name']
        })
        that.setData({
          seller: res.errMsg.sellerDetail,
          total:res.errMsg.total,
          userTotal: res.errMsg.userTotal,
          overTotal: res.errMsg.overTotal
        });
      } else {
        if (res.errCode == 4003) {
          wx.showModal({
            title: '友情提醒',
            content: res.errMsg,
            showCancel: false,
            success: function(rs) {
              if (rs.confirm) {
                wx.navigateTo({
                  url: '/pages/ucenter/edituser/edituser',
                })
              }
            }
          })
        } else {
          wx.showModal({
            title: '友情提醒',
            content: res.errMsg,
            showCancel: false
          })
        }
      }
    });
  },

  /**
   * 开始打卡
   */
  startDaKai: function () {
    let that = this;
    let user = wx.getStorageSync('userInfo');
    util.request(api.addPunch, { s_id: that.data.id, m_id: user.m_id, m_username: user.nickName }, 'POST').then(res => {
     console.log(res);
      if (res.errCode != 200) { 
       // util.showErrorToast(res.errMsg);
       wx.showModal({
         title: '友情提醒',
         content: res.errMsg,
         showCancel:false
       })
      } else {
        that.setData({
          end_time: res.data.date,
          dkdate: res.data.startdate,
       /*   total: res.data.total, */
          punchId: res.errMsg
        });
        countdown(that);
      }
    });
  },

  // 提交清空当前值
  bindSubmit: function () {
    var that = this;
    let user = wx.getStorageSync('userInfo');
    util.request(api.addCommentary, {p_id: that.data.punchId, s_id: that.data.id, m_id: user.m_id, m_username: user.nickName, t_flag: that.data.flag, t_mark: that.data.info}, 'POST').then(res => {
      if (res.errCode == 200) {
        wx.showToast({
          title: res.errMsg,
          icon: 'success'
        })
      } else {
        wx.showToast({
          title: res.errMsg,
          icon: 'success',
          image: '/images/icon_error.png'
        })
      }
    });
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
    
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    let userInfo = wx.getStorageSync('userInfo');
    let token = wx.getStorageSync('token');

    // 页面显示
    if (userInfo && token) {
      app.globalData.userInfo = userInfo;
      app.globalData.token = token;
    }
    this.setData({
      userInfo: app.globalData.userInfo,
    });

    //日历显示
    flag_hd = true; //重新进入页面之后,可以再次执行滑动切换页面代码
    clearInterval(interval); // 清除setInterval
    time = 0;
  },

  test: function (event) {
    let pageX = event.touches[0].pageX;
    let pageY = event.touches[0].pageY;
    if (pageX < 30 || pageY < 30)
      return;
    if (pageX > this.data.screenWidth - 30)
      return;
    if (pageY > this.data.screenHeight - 30)
      return;
    this.setData({
      ballTop: event.touches[0].pageY - 30,
      ballLeft: event.touches[0].pageX - 30,
    });
  },
  next: function (res) {
    if (this.data.endDay < this.data.getDate) {
      this.onLoad(res, this.data.year, this.data.month, this.data.endDay, 2)
    }
    else if (this.data.lastDay == this.data.getDate && this.data.endDay != null) {
      this.onLoad(res, this.data.year, Number(this.data.month), 1, 2)
    }
    else if (this.data.lastDay != this.data.endDay) {
      this.onLoad(res, this.data.year, Number(this.data.month - 1), Number(this.data.endDay + 1), 2)
    }
    else {
      this.data.endDay = 0
      this.onLoad(res, this.data.year, Number(this.data.month), 1, 2)
    }
  },
  last: function (res) {
    if (this.data.startDay < 7) {
      this.onLoad(res, this.data.year, this.data.month - 1, this.data.startDay - 1)
    }
    else if (this.data.startDay > this.data.endDay && this.data.font == 1) {
      this.onLoad(res, this.data.year, this.data.month - 2, this.data.startDay)
    }
    else {
      this.onLoad(res, this.data.year, this.data.month - 1, this.data.startDay - 7)
    }
  },

  //获取日历相关参数
  dataTime: function (year, month, day, state) {

    var last = this.data.lastDay
    var date = new Date(year, month, day);
    if (year == null) {
      date = new Date();
    }
    var year = date.getFullYear();
    var month = date.getMonth();
    var day = date.getDate();
    var months = date.getMonth() + 1;

    //获取现今年份
    this.data.year = year;

    //获取现今月份
    this.data.month = months;
    //获取今日日期
    this.data.getDate = date.getDate();
    //最后一天是几号
    var d = new Date(year, months, 0);

    this.data.lastDay = d.getDate();
    //第一天星期几

    let firstDay
    if (state == 1) {
      if (d.getDate() == date.getDate()) {
        if (this.data.startDay == 1) {
          firstDay = new Date(year, Number(month), Number(new Date(year, month - 1, 0).getDate() - 6));
        }
        else if (this.data.startDay <= 7) {
          firstDay = new Date(year, Number(month), Number(new Date(year, month - 1, 0).getDate() - 8));
        }
        else {
          firstDay = new Date(year, Number(month), Number(new Date(year, month - 1, 0).getDate() - 7));
        }
      }
      else if (this.data.startDay >= 6) {
        if (month == 11 && this.data.endDay > this.data.startDay && this.data.startDay != 16 && this.data.startDay != 9) {
          if (this.data.endDay <= 23) {
            firstDay = new Date(year, Number(month + 1), day);
          }
          else {
            firstDay = new Date(year, Number(month), day);
          }
        }
        else if (this.data.startDay == 8) {
          firstDay = new Date(year, Number(month), day - 4);
        }
        else {
          if (this.data.startDay == 6 && this.data.year != 2018 && this.data.month != 4) {
            this.data.month = Number(this.data.month + 1)
            firstDay = new Date(year, Number(month + 1), day);
          }
          else if (this.data.year == 2018 && this.data.month == 4) {
            firstDay = new Date(year, Number(month), day);
          }
          else {
            firstDay = new Date(year, Number(month - 1), day);
          }
        }
      }
      else {
        if (this.data.startDay == 4 && month == 2) {
          firstDay = new Date(year, Number(month - 1), Number(new Date(year, month - 1, 0).getDate() - day + 1));
        }
        else if (month == 1) {

          firstDay = new Date(year, Number(month), Number(new Date(year, month - 1, 0).getDate() - day + 2));
        }
      }
    }
    else if (state == 2) {
      if (this.data.endDay == last && last != null) {
        firstDay = new Date(year, month, 1);
      }
      else {
        firstDay = new Date(year, Number(month), Number(1 + this.data.endDay));
      }
    }
    else {
      firstDay = new Date(year, month, day);
    }
    this.data.firstDay = firstDay.getDay();
    this.setData({
      getWeek: date.getDay()
    })
  },
  touchStart: function (e) {
    touchDot = e.touches[0].pageX; // 获取触摸时的原点
    // 使用js计时器记录时间
    interval = setInterval(function () {
      time++;
    }, 100);
  },
  // 触摸结束事件
  touchEnd: function (e) {
    var touchMove = e.changedTouches[0].pageX;
    // 向左滑动
    if (touchMove - touchDot <= -20 && time < 10) {
      //执行切换页面的方法
      this.next()
    }
    // 向右滑动
    if (touchMove - touchDot >= 20 && time < 10) {
      //执行切换页面的方法
      this.last()
    }
    clearInterval(interval); // 清除setInterval
    time = 0;
  },
  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    let that = this;
    if (!(getCurrentPages().length == '-1')) {
      util.request(api.updateEndDate, { p_id: that.data.punchId }, 'POST').then(res => {
        console.log(res);
        if (res.errCode == 200) {
          wx.navigateTo({
            url: '/pages/punch/punch', //返回商家页面
          })
        }
      });
    }
    
   /* wx.showModal({
      title: '提示',
      content: '确定要关闭当前页面吗?关闭后系统将计算您的体验时间',
      success: function(res) {
        console.log(res);
        if (res.confirm) {
          util.request(api.updateEndDate, { p_id: that.data.punchId }, 'POST').then(res => {
            console.log(res);
            if (res.errCode == 200) {
              wx.navigateTo({
                url: '/pages/punch/punch', //返回商家页面
              })
            }
          });
        }
      }
    }) */
   
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
    
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
    
  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () { 
  },
  // 监听字数
  bindTextAreaChange: function (e) {
    var that = this
    var value = e.detail.value,
      len = parseInt(value.length);
    if (len > that.data.noteMaxLen)
      return;
    that.setData({ info: value, noteNowLen: len })
  },
  changeColor1: function () {
    var that = this;
    that.setData({
      flag: 1
    });
  },
  changeColor2: function () {
    var that = this;
    that.setData({
      flag: 2
    });
  },
  changeColor3: function () {
    var that = this;
    that.setData({
      flag: 3
    });
  },
  changeColor4: function () {
    var that = this;
    that.setData({
      flag: 4
    });
  },
  changeColor5: function () {
    var that = this;
    that.setData({
      flag: 5
    });
  }

})


3、wxml代码

<view class='container'>
<!-- 合作商家开始 
      <view class="brand-info">
        <view class="name">
            <image class="img1" src="{{image_url}}{{seller.s_img}}"   background-size="cover"></image>
            <view class="imgbg"></view>
            <view class="info-box">
                <view class="info">
                    <text class="txt">{{seller.s_name}}</text>
                     <view class="line">
                    
                     </view>
                </view>
            </view>
        </view>
    </view>
  <view class='clear'></view>
   <!-- 合作商家结束  -->

   <!--在线打卡开始 -->
   <view class='am-dakai'>
     <view class='am-dk'>
     <image class='am-ico' src='{{image_url2}}20180913/584d02e58f45445061a582e4520e9c23.png'></image>
     <text class='dk-1'>已打卡{{total}}次 还剩<text class='dk-2'>{{overTotal}}</text>次</text>
     </view>
     <view class='am-dk' style='color:#FE527B;font-weight:bold;font-size:.8rem;'>温馨提示:一旦点击打卡计时按钮,请不要离开此页面</view>
     <!-- 日历开始 -->

<view bindtouchstart="touchStart" bindtouchend="touchEnd">

  <view class='box1' style='width: {{ sysW * 7 }}px'>
    <block wx:for='{{ weekArr }}' wx:key=''>
     <view style='width: {{ sysW }}px; height: {{ sysW }}px; line-height: {{ sysW }}px;'>{{ item }}</view>
     </block>
     <block wx:for='{{ arr }}'  wx:key=''>
     <view style='width: {{ sysW }}px; height: {{ sysW }}px; line-height: {{ sysW }}px;' class='{{ item == getDate ? "dateOn" : ""}} {{font==1?item>7?"font-color":"":font==2?item<7?"font-color":"":"" }}'>{{ item }}</view>
     </block>
  </view>
</view>


     <!-- 日历结束 -->

     <view class='am-startdk' wx:if="{{dkdate != 0}}">开始打卡时间:{{dkdate}}</view>
     <view class='am-d1'>
       <view class='am-kq' bindtap='startDaKai'>
         <view class='am-name'>
          <image class="img" src="{{image_url2}}20180911/0b6ed9cb264f1ac3a773820e6c6385c4.png" background-size="cover"></image>
           <view class="info-box">
             <view class="info">
              <text class='txt'>{{clock}}</text>
             </view>
           </view>
         </view>
       </view>
     </view>
   </view>
   <!--在线打卡结束 -->
   <view class='am-line'></view>

   <!-- 评价 -->
   <view class='am-pingjia'>
     <view class='am-left'  >
         <image wx:if="{{userInfo && userInfo.avatarUrl}}" class="userinfo-avatar" src="{{ userInfo.avatarUrl }}" background-size="cover"></image>
             <text class="userinfo-nickname" wx:if="{{userInfo.nickName != '点击登录'}}" >{{ userInfo.nickName }}</text>
     </view>
     <!--星星-->
     <view class='am-description'>
        <view class="star-pos" style="display:flex;flex-direction:row;">
            <view class='am-fuwu'>服务:</view>
            <view class="stars  {{flag>=1? 'on': ''}}" bindtap="changeColor1"></view>
            <view class="stars  {{flag>=2? 'on': ''}}" bindtap="changeColor2"></view>
            <view class="stars  {{flag>=3? 'on': ''}}" bindtap="changeColor3"></view>
            <view class="stars  {{flag>=4? 'on': ''}}" bindtap="changeColor4"></view>
            <view class="stars  {{flag>=5? 'on': ''}}" bindtap="changeColor5"></view>
        </view>
     </view>

     <!--文本域  -->
 <!--  <view class="weui-cells_after-title">
    <view class="weui-cell">
      <view class="weui-cell__bd">
        <textarea class="weui-textarea" bindinput="bindTextAreaChange" placeholder="我要提出建议..." style="height: 5em" 
        value="{{info}}" maxlength="{{noteMaxLen}}" focus />
        <view class="weui-textarea-counter">{{noteNowLen}}/{{noteMaxLen}}</view>
      </view>
    </view>
  </view> -->
<!--发布按钮  -->
  <view class="btnSf">
    <button bindtap="bindSubmit">提交</button>
  </view>

   </view>
</view>


热门文章
友情链接