redis实现简单的动态密码

1.实现效果

效果图如下,样式可以自行调整

在这里插入图片描述

2.后端实现逻辑

RandomUtil生成6位随机数,采用AES加密,存储redis并设置60s过期时间

  /**
     * 生成新密码
     */
    public TrendsPasswordResVO handleSavePass(TrendsPasswordResVO resVO, String redisKey) {
        // 随机6位密码
        String password = RandomUtil.randomNumbers(6);
        String decryptPassword = AesUtil.encrypt(password);
        resVO.setPassword(password);
        resVO.setCountdown(60L);
        redisUtil.set(redisKey, decryptPassword, 60, TimeUnit.SECONDS);
        return resVO;
    }

    /**
     * 生成动态密码
     */
    @GetMapping("/password/generate")
    public TrendsPasswordResVO getStoreTrendsPass(@RequestParam("storeId") Integer storeId) {
        TrendsPasswordResVO resVO = new TrendsPasswordResVO();
        String redisKey = "STORE_PASSWORD_KEY_" + storeId;
        Object smsCode = redisUtil.get(redisKey);
        if (ObjectUtil.isNotEmpty(smsCode)) {
            Long expireSecond = redisUtil.getExpire(redisKey);
            //0秒过期的话也重新生成,这个必须要,不然偶尔会返回0秒过期的密码
            if (expireSecond == 0) {
                return this.handleSavePass(resVO, redisKey);
            }
            resVO.setPassword(AesUtil.decrypt(String.valueOf(smsCode)));
            resVO.setCountdown(expireSecond);
            return resVO;
        }
        return this.handleSavePass(resVO, redisKey);
    }

3.前端实现逻辑

画一个大圆,一个右边的圆环,一个左边的圆环,一个遮罩圆,通过定时器动态计算transform的值,实现滚动

<template>
  <div class="circle">
    <div class="pie-right">
      <div class="right" :style="`--progress:${progress}deg`"></div>
    </div>
    <div class="pie-left">
      <div class="left" :style="`--progress:${progress2}deg`"></div>
    </div>
    <div class="mask">
      <span>{{ countdown - 1 }}s</span>
      <p>密码:{{ password }}</p>
    </div>
  </div>
</template>

<script>
  import { getStoreTrendsPass } from '@/api/sys/dept'
  export default {
    beforeRouteLeave(to, from, next) {
      clearInterval(this.timer)
      next()
    },
    data() {
      return {
        progress: 0,
        progress2: 0,
        countdown: 1,
        password: 0,
        timer: null, // 定时器
      }
    },
    created: function () {
      this.pageInit()
      this.timer = setInterval(() => {
        //60s一个圈  360/60
        let temporary = this.countdown * 6
        //小于180转第一个圆
        if (temporary <= 180) {
          this.progress = temporary
        }
        //第一个半圆转到180,开始转第二圆
        if (temporary >= 180) {
          this.progress2 = temporary - 180
        }
        //防止重新调接口后,progress为0
        if (!restFlag && temporary >= 180 && this.progress < 180) {
          this.progress = 180
        }
        //达到60秒,重置进度条,重新获取密码
        let restFlag = false
        if (this.countdown === 60) {
          this.countdown = 0
          this.progress = 0
          this.progress2 = 0
          restFlag = true
        }
        //重置,重新调取接口获取密码和时间
        if (restFlag) {
          this.pageInit()
        }
        //秒数自加1
        this.countdown = this.countdown + 1
        console.log('bbbbbbbbbb', this.progress)
        console.log('cccccccccc', this.progress2)
      }, 1000)

      // 离开当前页面时销毁定时器
      this.$once('hook:beforeDestroy', () => {
        clearInterval(this.timer)
        this.timer = null
      })
    },
    methods: {
      pageInit() {
        const params = new URLSearchParams()
        params.append('storeId', 1)
        getStoreTrendsPass(params).then((res) => {
          this.countdown = 60 - res.data.data.countdown + 1
          this.password = res.data.data.password
        })
      },
    },
  }
</script>
<style lang="scss" scoped>
  //css
  .circle {
    //这个元素可以提供进度条的颜色
    position: absolute;
    height: 200px;
    width: 200px;
    border-radius: 50%;
    background: red; //注意这是表示当前进度的颜色
  }
  .pie-right,
  .pie-left {
    //这俩元素主要是为了分别生成两个半圆的,所以起作用的地方在于clip裁掉另一半
    position: absolute;
    top: 0;
    left: 0;
    height: 200px;
    width: 200px;
    border-radius: 50%;
  }
  .right,
  .left {
    position: absolute;
    top: 0;
    left: 0;
    height: 200px;
    width: 200px;
    border-radius: 50%;
    background: #f0f0f0; //注意这个才不是当前进度的颜色
  }
  .pie-right,
  .right {
    //裁掉左边一半
    clip: rect(0, auto, auto, 100px);
    transform: rotate(var(--progress));
  }
  .pie-left,
  .left {
    //裁掉右边一半
    clip: rect(0, 100px, auto, 0);
    transform: rotate(var(--progress));
  }
  .mask {
    //我是遮罩 mask不用改 好欣慰
    position: absolute;
    top: 25px;
    left: 25px;
    height: 150px;
    width: 150px;
    background: #fff;
    border-radius: 50%;
    text-align: center;
  }
</style>

3.源码地址

https://github.com/yangzp11/yangzp

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值