<!--
 * @Author: xiejiang
 * @Date: 2023-03-08 16:51:55
 * @LastEditors: zengzhe
 * @LastEditTime: 2024-12-27 15:38:09
 * @Description: 密码风险等级
 * Copyright（c）2023 by 好老师教育科技有限公司 All right Reserved.
-->
<template>
  <main class="line-container flex items-center">
    <div class="line text-12">密码强度</div>
    <div class="line-main flex items-center">
      <span
        v-for="index in 3"
        :key="index"
        :class="index <= state.risk && showProgress ? state.bgColor : 'grey'"
      ></span>
    </div>
    <div v-show="showProgress && isPawTxt" :class="state.bgColor + ' line text-12'">
      {{ state.pwdList[state.risk - 1] }}
    </div>
  </main>
</template>

<script lang="ts" setup name="pwdRisk">
import { reactive, watch, computed } from 'vue'
type propsType = {
  passwordVal: string
  isPawTxt?: boolean
  passwordLength?: number
}
const props = withDefaults(defineProps<propsType>(), {
  passwordVal: '',
  isPawTxt: true, //是否显示密码强度
  passwordLength: 6 //密码安全长度
})
const state = reactive({
  bgColor: 'risk',
  risk: 0,
  pwdList: ['风险', '中等', '安全']
})

function checkStrong(sValue: string) {
  let modes = 0
  if (/\d/.test(sValue)) modes++ // 数字
  if (modes < 3 && /[a-z]/.test(sValue)) modes++ // 小写
  if (modes < 3 && /[A-Z]/.test(sValue)) modes++ // 大写
  if (modes < 3 && /\W/.test(sValue)) modes++ // 特殊字符
  modes = Math.min(modes, 3)

  const colorMap = ['risk', 'medium', 'safe']
  state.risk = modes
  state.bgColor = colorMap[modes - 1] || 'risk'
}
watch(
  () => props.passwordVal,
  value => {
    checkStrong(value)
  },
  { immediate: true }
)
const showProgress = computed(() => {
  return props.passwordVal.length >= props.passwordLength
})
</script>

<style lang="less" scoped>
.line-container {
  color: var(--gray-300);
  font-size: 12px;

  .line-main {
    margin: 0 8px;

    span {
      display: inline-block;
      width: 24px;
      height: 8px;
      border-radius: 4px;
      margin-right: 8px;
    }
  }

  .risk {
    background: #ff7c99;
    color: #ff7c99;
  }

  .medium {
    background: #ffd200;
    color: #ffd200;
  }

  .safe {
    background: #4bd1a7;
    color: #4bd1a7;
  }

  .grey {
    background: #e4e5e6;
  }

  .line {
    background: none;
  }
}
</style>
