wms-antdvue/.svn/pristine/19/19631113e1f36994ea990ddd09939d1f604b197a.svn-base
2024-11-07 16:33:03 +08:00

232 lines
6.0 KiB
Plaintext

<template>
<div class="password-box" :class="{ 'block-box': block }">
<a-popover
ref="popoverRef"
:trigger="['focus']"
:visibleChange="popoverChange"
destroyTooltipOnHide
:class="{ 'block-box': block }"
:visible="isShowIntensity"
>
<template #content v-if="isShowIntensity">
<Intensity v-bind="intensityValue" />
</template>
<a-form :model="formValue" :rules="rules" ref="formRef">
<a-form-item name="password">
<a-input-password
:id="`${getId}-1`"
ref="passwordRef"
v-model:value="formValue.password"
@change="passwordChange"
placeholder="请输入密码"
:maxlength="maxLength"
@focus="onFocus"
@blur="onBlur"
>
<template #prefix>
<LockOutlined style="color: #808695; font-size: 18px" />
</template>
</a-input-password>
</a-form-item>
<a-form-item name="repeat" v-if="repeat">
<a-input-password
:id="`${getId}-2`"
type="password"
v-model:value="formValue.repeat"
placeholder="请再次输入密码"
:maxlength="maxLength"
@focus="onFocus"
@blur="onBlur"
>
<template #prefix>
<LockOutlined style="color: #808695; font-size: 18px" />
</template>
</a-input-password>
</a-form-item>
</a-form>
</a-popover>
</div>
</template>
<script lang="ts" setup>
import { ref, unref, computed, nextTick, reactive } from 'vue';
import { LockOutlined } from '@ant-design/icons-vue';
import Intensity from './components/Intensity.vue';
import { basicProps } from './props';
import { bindUUid } from '@/utils';
const props = defineProps({ ...basicProps });
defineEmits(['change', 'focus']);
const isSuccess = ref(false);
const isShowIntensity = ref(false);
const getId = bindUUid();
const formValue = reactive({
password: props.value,
repeat: '',
});
const password = ref({
strength: 0,
tips: null,
length: false,
format: false,
complexity: false,
});
const rules = {
password: [{ required: true, validator: checkPasswordVal, trigger: 'change' }],
repeat: [{ required: props.repeat, validator: checkRepeat, trigger: 'change' }],
};
const popoverRef = ref();
const passwordRef = ref();
const intensityValue: any = computed(() => {
return {
value: formValue.password,
complexity: props.complexity,
minLength: props.minLength,
maxLength: props.maxLength,
password: password.value,
complexityTip: props.complexityTip,
};
});
function onFocus() {
isShowIntensity.value = true;
}
function onBlur() {
isShowIntensity.value = false;
}
function passwordChange() {
const value: string = formValue.password as string;
password.value.strength = getStrength(value);
}
async function checkPasswordVal(_, value) {
if (!props.required && !value) {
isSuccess.value = true;
return Promise.resolve();
}
if (!value) {
password.value = {
strength: 0,
tips: null,
length: false,
format: false,
complexity: false,
};
isSuccess.value = false;
return Promise.reject('请设置密码');
} else {
password.value.format = true;
if (value.length < props.minLength) {
password.value.length = false;
password.value.strength = 0;
password.value.tips = null;
return Promise.reject(`密码长度至少为${props.minLength}个字符`);
}
if (props.complexity) {
if (checkPassword(value)) {
password.value.length = true;
const strength = getStrength(value);
password.value.strength = strength;
password.value.tips = props.level[strength];
if (strength <= 1) {
password.value.complexity = false;
return Promise.reject(props.complexityTip);
} else {
password.value.complexity = true;
isSuccess.value = true;
return Promise.resolve();
}
}
} else {
password.value.length = true;
const strength = getStrength(value);
password.value.strength = strength;
password.value.tips = props.level[strength];
password.value.complexity = true;
isSuccess.value = true;
return Promise.resolve();
}
}
isSuccess.value = true;
return Promise.resolve();
}
function checkRepeat(_, value) {
if (!props.required && !value) {
isSuccess.value = true;
return Promise.resolve();
}
if (!value) {
return Promise.reject('请再次输入密码');
} else {
if (formValue.password !== value) {
return Promise.reject('两次密码输入不一致');
}
return Promise.resolve();
}
}
function checkPassword(password: string): boolean {
const regExp = /^[A-Za-z0-9~!@#$%^&*()_+=\-.,]{6,32}$/;
return regExp.test(password);
}
function getStrength(password: string): number {
const reg = {
lower: /[a-z]/,
upper: /[A-Z]/,
number: /[\d]/,
character: /[~!@#$%^&*()_+=\-.,]/,
};
let strength = 0;
if (reg.lower.test(password)) strength++;
if (reg.upper.test(password)) strength++;
if (reg.number.test(password)) strength++;
if (reg.character.test(password)) strength++;
return strength;
}
function showValidator() {
passwordRef.value.focus();
passwordRef.value.blur();
nextTick(() => {
passwordRef.value.focus();
});
}
function isValidator() {
return unref(isSuccess);
}
function popoverChange(visible) {
console.log(visible);
}
defineExpose({
isValidator,
showValidator,
});
</script>
<style lang="less" scoped>
.password-box {
display: inline-block;
}
.block-box {
display: block;
width: 100%;
}
</style>