美文网首页
移动端打卡器雷达效果及时间同步方案

移动端打卡器雷达效果及时间同步方案

作者: 小仙有毒_1991 | 来源:发表于2020-06-01 09:41 被阅读0次
<template>
  <div class="punch">
    <section class="goTip" :class="{'radar': punched || syncTimeLoading}" @click="confirmPunch">
      <div class="circle">
        <p v-text="text"></p>
        <p>{{currentTimeText}}</p>
      </div>
    </section>
    <section class="position">
      <van-icon size=".48rem" color="#c4c7cc" name="location"/>
      <p v-text="gps.address?gps.address:$t('lang.noGps')"></p>
      <div v-show="!gps.address" @click="getAndLocation">{{$t('lang.getGps')}}</div>
    </section>
  </div>
</template>

<script>
  export default {
    name: 'Punch',
    data() {
      return {
        gps: {
          address: '',
          longitude: '',
          latitude: ''
        },
        syncTimeLoading:true,//同步时间中
        gpsLoading: false,//获取GPS中
        currentTimeText: ''
      }
    },
    props: {
      text: {// 上班 下班
        type: String,
        default: '出乘'
      },
      punched: { //是否打过卡
        type: Boolean,
        default: false
      },
      currentTime: {//当前时间
        type: String,
        default: () => {
          return '00:00:00'
        }
      }
    },
    watch: {
      'currentTime': function (value) {
        if (!this.punched) {
          this.currentTimeText = value;
        }
      }
    },
    methods: {
      getPosition() {
         //TODO
      },
      getAndLocation() { //从android 获取 地理位置
        if (!this.gpsLoading) {
          this.gpsLoading = true;
        }
        //TODO
      },
      openGPSSetting() { //打开GPS
        //TODO
      },
      confirmPunch() {
        if(this.punched || this.syncTimeLoading ){//已打卡,时间获取中 均不能打卡
          return;
        }
        if(this.gpsLoading){//gps定位中
          this.$toast('定位中,请稍后重试');
          return;
        }
        if(!this.gps.address){ //定位失败
          this.$toast('定位失败,请先获取定位');
          return;
        }
        let message = this.text === '出乘' ? `是否确定出乘?` : '退乘打卡后不可继续编辑报告\n是否确定?';
        this.$dialog.confirm({
          title: '提示',
          className: 'punch-dialog',
          message: message,
          confirmButtonText: '确定'
        })
          .then(() => {
            if (this.text === '出乘') {
              this.$emit('handleClick', '出乘');
            } else {
              this.$emit('handleClick', '退乘');
            }
            // on confirm
          })
          .catch(() => {
            // on cancel
          });
      }
    },
    mounted() {
    }
  }
</script>

<style scoped lang="less">
  .punch {
    display: inline-block;
    padding: .2rem 0 .1rem;
  }
  
  .goTip {
    width: 3.9rem;
    height: 3.9rem;
    background-color: #CFE1F7;
    border: 1px solid #529AEF;
    border-radius: 50%;
    position: relative;
    margin: 0 auto .53rem;
  }
  
  .circle {
    width: 3.54rem;
    height: 3.54rem;
    background-color: #4A96F4;
    border-radius: 50%;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    p {
      color: #FFFEFB;
      text-align: center;
      position: absolute;
      width: 100%;
      &:first-of-type {
        top: 1rem;
        font-size: .46rem;
      }
      &:last-of-type {
        font-size: .46rem;
        bottom: 1rem;
      }
    }
  }
  
  .position {
    display: flex;
    align-items: center;
    color: #525252;
    font-size: .42rem;
    p {
      margin: 0 .25rem 0 .17rem;
      max-width: 5rem;
      word-break: break-all;
    }
    div {
      color: #4696F5;
    }
  }
  
  .radar::before {
    content: '';
    position: absolute;
    width:50%;
    height:50%;
    background: linear-gradient(45deg, rgba(0, 0, 0, 0) 50%, #8abff6 100%);
    border-radius: 100% 0 0 0;
    top: 0;
    left: 0;
    animation: scanning 5s linear infinite;
    transform-origin: 100% 100%;
    z-index: 1;
  }
  
  @keyframes scanning {
    to {
      transform: rotate(360deg);
    }
  }

</style>

父组件同步时间

// methods

getServerTime() {
    if(this.$refs.punch){
          this.$refs.punch.syncTimeLoading = true;
        }
        
        setTimeout(()=>{
          //this.serveTime
          let localTime = this.$moment().valueOf();
          let diffTime = localTime - this.formatNow;
          if (this.timer) {
            clearInterval(this.timer);
          }
          this.timer = setInterval(() => {
            this.getTime(diffTime);
          }, 1000)
        },3000);
      },
      getTime(diffTime) {
        let localTime = this.$moment().valueOf();
        let serveTime = localTime - diffTime;
        if (this.lastTime && serveTime - this.lastTime > 5000) {
          //服务端获取时间重新init,停止计时器,并禁止打卡
          this.getServerTime();
        } else {
          this.lastTime = serveTime;
          this.dateText = this.$moment(serveTime).format('YYYY-MM-DD');
          this.weekText = this.$moment(serveTime).format('dddd');
          this.currentTime = this.$moment(serveTime).format('HH:mm:ss');
          if(this.$refs.punch){
            this.$refs.punch.syncTimeLoading = false;
          }
        }
      }

//computed
formatNow() {
  return this.$moment(this.serveTime).valueOf() + 1000
},

相关文章

网友评论

      本文标题:移动端打卡器雷达效果及时间同步方案

      本文链接:https://www.haomeiwen.com/subject/zukjzhtx.html