feat: 修改密码
This commit is contained in:
@ -122,7 +122,7 @@ export const sendUpdateMobileCaptcha = (data: any) => {
|
|||||||
|
|
||||||
// 修改绑定的手机号
|
// 修改绑定的手机号
|
||||||
export const updateMobile = (data: any) => {
|
export const updateMobile = (data: any) => {
|
||||||
return Http.post(`/v1/me/mobile`, data);
|
return Http.patch(`/v1/me/mobile`, data);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 修改我的信息
|
// 修改我的信息
|
||||||
|
|||||||
@ -92,3 +92,19 @@ export const getMyPrimaryEnterprise = () => {
|
|||||||
export const postUpdateMobileCaptcha = (params = {}) => {
|
export const postUpdateMobileCaptcha = (params = {}) => {
|
||||||
return Http.post('/v1/sms/update-mobile-captcha', params);
|
return Http.post('/v1/sms/update-mobile-captcha', params);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 发送修改密码验证码
|
||||||
|
export const postUpdatePasswordCaptcha = (params = {}) => {
|
||||||
|
return Http.post('/v1/sms/update-password-captcha', params);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 验证修改密码验证码
|
||||||
|
export const postCheckUpdatePasswordCaptcha = (params = {}) => {
|
||||||
|
return Http.post('/v1/sms/check-update-password-captcha', params);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 修改密码
|
||||||
|
export const postUpdatePassword = (params = {}) => {
|
||||||
|
return Http.patch('/v1/me/password', params);
|
||||||
|
};
|
||||||
|
|||||||
@ -39,13 +39,13 @@
|
|||||||
</Form>
|
</Form>
|
||||||
<div class="flex justify-end mt-20px">
|
<div class="flex justify-end mt-20px">
|
||||||
<Button class="mr-16px" size="large" @click="onClose">取消</Button>
|
<Button class="mr-16px" size="large" @click="onClose">取消</Button>
|
||||||
<Button type="primary" size="large" @click="handleConfirm">确定</Button>
|
<Button type="primary" size="large" :loading="submitLoading" @click="handleConfirm">确定</Button>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, onUnmounted, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { Button, Form, FormItem, Input, message, Modal } from 'ant-design-vue';
|
import { Button, Form, FormItem, Input, message, Modal } from 'ant-design-vue';
|
||||||
import { postUpdateMobileCaptcha } from '@/api/all/login';
|
import { postUpdateMobileCaptcha } from '@/api/all/login';
|
||||||
import { updateMobile } from '@/api/all';
|
import { updateMobile } from '@/api/all';
|
||||||
@ -58,6 +58,7 @@ const visible = ref(false);
|
|||||||
const timer = ref();
|
const timer = ref();
|
||||||
const isLegalMobile = ref(false);
|
const isLegalMobile = ref(false);
|
||||||
const hasGetCode = ref(false);
|
const hasGetCode = ref(false);
|
||||||
|
const submitLoading = ref(false);
|
||||||
|
|
||||||
const countdown = ref(0);
|
const countdown = ref(0);
|
||||||
|
|
||||||
@ -141,8 +142,7 @@ const startCountdown = () => {
|
|||||||
timer.value = setInterval(() => {
|
timer.value = setInterval(() => {
|
||||||
countdown.value--;
|
countdown.value--;
|
||||||
if (countdown.value <= 0) {
|
if (countdown.value <= 0) {
|
||||||
clearInterval(timer.value);
|
clearTimer();
|
||||||
timer.value = null;
|
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
};
|
};
|
||||||
@ -150,15 +150,27 @@ const startCountdown = () => {
|
|||||||
// 确定按钮点击
|
// 确定按钮点击
|
||||||
const handleConfirm = () => {
|
const handleConfirm = () => {
|
||||||
formRef.value.validate().then(async () => {
|
formRef.value.validate().then(async () => {
|
||||||
|
try {
|
||||||
|
submitLoading.value = true;
|
||||||
const { code } = await updateMobile(form.value);
|
const { code } = await updateMobile(form.value);
|
||||||
if (code === 200) {
|
if (code === 200) {
|
||||||
|
await store.getUserInfo();
|
||||||
message.success('修改成功!');
|
message.success('修改成功!');
|
||||||
store.getUserInfo();
|
onClose();
|
||||||
visible.value = false;
|
}
|
||||||
|
} finally {
|
||||||
|
submitLoading.value = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const clearTimer = () => {
|
||||||
|
if (timer.value) {
|
||||||
|
clearInterval(timer.value);
|
||||||
|
timer.value = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 取消按钮点击
|
// 取消按钮点击
|
||||||
const onClose = () => {
|
const onClose = () => {
|
||||||
form.value = {
|
form.value = {
|
||||||
@ -167,16 +179,15 @@ const onClose = () => {
|
|||||||
};
|
};
|
||||||
countdown.value = 0;
|
countdown.value = 0;
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
|
hasGetCode.value = false;
|
||||||
|
isLegalMobile.value = false;
|
||||||
|
submitLoading.value = false;
|
||||||
|
|
||||||
formRef.value.resetFields();
|
formRef.value.resetFields();
|
||||||
formRef.value.clearValidate();
|
formRef.value.clearValidate();
|
||||||
};
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
clearTimer();
|
||||||
if (timer.value) {
|
};
|
||||||
clearInterval(timer.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 暴露方法供外部调用
|
// 暴露方法供外部调用
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
</Form>
|
</Form>
|
||||||
<div class="flex justify-end mt-20px">
|
<div class="flex justify-end mt-20px">
|
||||||
<Button class="mr-16px" size="large" @click="onClose">取消</Button>
|
<Button class="mr-16px" size="large" @click="onClose">取消</Button>
|
||||||
<Button type="primary" size="large" :loading="loading" @click="handleNicknameConfirm">确定</Button>
|
<Button type="primary" size="large" :loading="submitLoading" @click="handleNicknameConfirm">确定</Button>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
@ -30,7 +30,7 @@ import { useUserStore } from '@/stores';
|
|||||||
const store = useUserStore();
|
const store = useUserStore();
|
||||||
const formRef = ref();
|
const formRef = ref();
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
const loading = ref(false);
|
const submitLoading = ref(false);
|
||||||
const form = ref({
|
const form = ref({
|
||||||
name: '',
|
name: '',
|
||||||
});
|
});
|
||||||
@ -43,11 +43,16 @@ const open = (userName) => {
|
|||||||
|
|
||||||
// 确定按钮点击
|
// 确定按钮点击
|
||||||
const handleNicknameConfirm = async () => {
|
const handleNicknameConfirm = async () => {
|
||||||
|
try {
|
||||||
|
submitLoading.value = true;
|
||||||
const { code } = await updateMyInfo(form.value);
|
const { code } = await updateMyInfo(form.value);
|
||||||
if (code === 200) {
|
if (code === 200) {
|
||||||
|
await store.getUserInfo();
|
||||||
message.success('修改成功!');
|
message.success('修改成功!');
|
||||||
store.getUserInfo();
|
onClose();
|
||||||
visible.value = false;
|
}
|
||||||
|
} finally {
|
||||||
|
submitLoading.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -55,6 +60,7 @@ const handleNicknameConfirm = async () => {
|
|||||||
const onClose = () => {
|
const onClose = () => {
|
||||||
form.value.name = '';
|
form.value.name = '';
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
|
submitLoading.valeu = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 暴露方法供外部调用
|
// 暴露方法供外部调用
|
||||||
|
|||||||
@ -0,0 +1,212 @@
|
|||||||
|
<template>
|
||||||
|
<Modal
|
||||||
|
v-model:open="visible"
|
||||||
|
:title="title"
|
||||||
|
:width="412"
|
||||||
|
centered
|
||||||
|
:footer="null"
|
||||||
|
class="change-password-modal"
|
||||||
|
@cancel="onClose"
|
||||||
|
>
|
||||||
|
<div class="modal-content">
|
||||||
|
<p class="title-text">安全验证</p>
|
||||||
|
<template v-if="isCheckPass">
|
||||||
|
<p class="cts mt-36px !color-#211F24 mb-24px">验证成功,请更改密码</p>
|
||||||
|
<Form ref="formRef" :model="formData" :rules="formRules" auto-label-width class="w-348 form-wrap">
|
||||||
|
<FormItem name="password" class="password-form-item">
|
||||||
|
<Input.Password v-model:value="formData.password" placeholder="新密码" size="large" class="!h-48px">
|
||||||
|
<template #iconRender="visible">
|
||||||
|
<img :src="visible ? icon2 : icon1" width="20" height="20" class="cursor-pointer" />
|
||||||
|
</template>
|
||||||
|
</Input.Password>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem name="confirm_password" class="password-form-item">
|
||||||
|
<Input.Password
|
||||||
|
v-model:value="formData.confirm_password"
|
||||||
|
placeholder="密码确认"
|
||||||
|
size="large"
|
||||||
|
class="!h-48px"
|
||||||
|
>
|
||||||
|
<template #iconRender="visible">
|
||||||
|
<img :src="visible ? icon2 : icon1" width="20" height="20" class="cursor-pointer" />
|
||||||
|
</template>
|
||||||
|
</Input.Password>
|
||||||
|
</FormItem>
|
||||||
|
</Form>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
:disabled="disabledSubmitBtn"
|
||||||
|
:loading="submitLoading"
|
||||||
|
class="w-full !h-48px mt-36px !rounded-8px"
|
||||||
|
@click="handleSubmit"
|
||||||
|
>完成更改
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<p class="cts text-center mt-16px">为进一步保证您的账号安全,确保为您本人操作,</p>
|
||||||
|
<p class="cts mb-36px text-center">请先完成安全验证</p>
|
||||||
|
|
||||||
|
<p class="cts !color-#211F24 mb-24px">请输入发送至{{ showMobile }} 的短信验证码</p>
|
||||||
|
<div class="verify-code-wrap mb-24px">
|
||||||
|
<VerificationCode ref="verificationCodeRef" @success="onCheckPass" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="cts !text-12px !lh-20px !color-#939499" v-if="countdown > 0">
|
||||||
|
{{ countdown }} 秒后您可以再次发送验证码
|
||||||
|
</p>
|
||||||
|
<Button type="text" class="pl-0" v-if="hasGetCode && countdown === 0" @click="getCaptcha">重新发送</Button>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
import { Button, Form, FormItem, Input, message, Modal } from 'ant-design-vue';
|
||||||
|
import VerificationCode from '../verification-code/index.vue';
|
||||||
|
|
||||||
|
import { postUpdatePasswordCaptcha, postUpdatePassword } from '@/api/all/login';
|
||||||
|
import icon1 from '@/assets/img/login/icon-close.png';
|
||||||
|
import icon2 from '@/assets/img/login/icon-open.png';
|
||||||
|
|
||||||
|
const emit = defineEmits(['success', 'cancel']);
|
||||||
|
|
||||||
|
const visible = ref(false);
|
||||||
|
const phone = ref('');
|
||||||
|
const isCheckPass = ref(false);
|
||||||
|
const formRef = ref(null);
|
||||||
|
|
||||||
|
// 验证码输入相关
|
||||||
|
const countdown = ref(0);
|
||||||
|
const timer = ref<number | null>(null);
|
||||||
|
const hasGetCode = ref(false);
|
||||||
|
const submitLoading = ref(false);
|
||||||
|
const verificationCodeRef = ref(null);
|
||||||
|
const formData = ref({
|
||||||
|
captcha: '',
|
||||||
|
password: '',
|
||||||
|
confirm_password: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const formRules = {
|
||||||
|
password: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
validator: (_rule, value) => {
|
||||||
|
if (formData.value.confirm_password) {
|
||||||
|
formRef.value.validateFields('confirm_password');
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
},
|
||||||
|
trigger: ['blur'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
confirm_password: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
validator: (_rule, value) => {
|
||||||
|
if (value !== formData.value.password) {
|
||||||
|
return Promise.reject('确认密码与设置的密码不同');
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
},
|
||||||
|
trigger: ['blur'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const title = computed(() => (isCheckPass.value ? '更改密码' : '安全验证'));
|
||||||
|
const showMobile = computed(() => {
|
||||||
|
return phone.value?.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
|
||||||
|
});
|
||||||
|
const isPassPassword = computed(() => {
|
||||||
|
return (
|
||||||
|
formData.value.confirm_password &&
|
||||||
|
formData.value.password &&
|
||||||
|
formData.value.confirm_password === formData.value.password
|
||||||
|
);
|
||||||
|
});
|
||||||
|
const disabledSubmitBtn = computed(() => {
|
||||||
|
return !isPassPassword.value || !formData.value.password.trim();
|
||||||
|
});
|
||||||
|
|
||||||
|
const onCheckPass = (captcha) => {
|
||||||
|
isCheckPass.value = true;
|
||||||
|
formData.value.captcha = captcha;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCaptcha = async () => {
|
||||||
|
try {
|
||||||
|
const { code, message: msg } = await postUpdatePasswordCaptcha();
|
||||||
|
if (code === 200) {
|
||||||
|
startCountdown();
|
||||||
|
message.success(msg);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// 重置倒计时
|
||||||
|
countdown.value = 0;
|
||||||
|
clearInterval(timer.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 开始倒计时
|
||||||
|
const startCountdown = () => {
|
||||||
|
countdown.value = 60;
|
||||||
|
hasGetCode.value = true;
|
||||||
|
timer.value = window.setInterval(() => {
|
||||||
|
countdown.value--;
|
||||||
|
if (countdown.value <= 0) {
|
||||||
|
clearTimer();
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
const clearTimer = () => {
|
||||||
|
if (timer.value) {
|
||||||
|
clearInterval(timer.value);
|
||||||
|
timer.value = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 提交验证
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
try {
|
||||||
|
submitLoading.value = true;
|
||||||
|
const { code } = await postUpdatePassword(formData.value);
|
||||||
|
if (code === 200) {
|
||||||
|
message.success('更改成功');
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
submitLoading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const open = (mobile) => {
|
||||||
|
getCaptcha();
|
||||||
|
phone.value = mobile;
|
||||||
|
visible.value = true;
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
verificationCodeRef.value?.init();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onClose = () => {
|
||||||
|
visible.value = false;
|
||||||
|
phone.value = '';
|
||||||
|
countdown.value = 0;
|
||||||
|
hasGetCode.value = false;
|
||||||
|
submitLoading.value = false;
|
||||||
|
formRef.value?.resetFields();
|
||||||
|
formRef.value?.clearValidate();
|
||||||
|
clearTimer();
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import './style.scss';
|
||||||
|
</style>
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
.change-password-modal {
|
||||||
|
.ant-modal-content {
|
||||||
|
border-radius: 16px;
|
||||||
|
|
||||||
|
.ant-modal-header {
|
||||||
|
border-radius: 16px 16px 0 0;
|
||||||
|
border-bottom: none !important;
|
||||||
|
|
||||||
|
.ant-modal-title {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-modal-body {
|
||||||
|
padding: 0 32px 8px !important;
|
||||||
|
position: relative;
|
||||||
|
top: -24px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.cts {
|
||||||
|
color: var(--Text-3, #737478);
|
||||||
|
font-family: $font-family-regular;
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 22px; /* 157.143% */
|
||||||
|
}
|
||||||
|
.title-text {
|
||||||
|
color: var(--Text-1, #211F24);
|
||||||
|
text-align: center;
|
||||||
|
font-family: $font-family-medium;
|
||||||
|
font-size: 24px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-form {
|
||||||
|
.ant-form-item {
|
||||||
|
&:not(:last-child) {
|
||||||
|
margin-bottom: 24px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-input-affix-wrapper {
|
||||||
|
border-radius: 8px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-modal-footer {
|
||||||
|
height: 56px !important;
|
||||||
|
border-top: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,154 @@
|
|||||||
|
<template>
|
||||||
|
<div class="verify-code-container">
|
||||||
|
<!-- 验证码输入区域 -->
|
||||||
|
<div class="code-inputs">
|
||||||
|
<Input
|
||||||
|
v-for="(item, index) in codeArray"
|
||||||
|
ref="inputRef"
|
||||||
|
:key="index"
|
||||||
|
:value="item.value"
|
||||||
|
:class="{ error: item.error, fill: item.value }"
|
||||||
|
@input="handleInput(index, $event.target.value)"
|
||||||
|
@focus="handleFocus(index)"
|
||||||
|
@blur="handleBlur(index)"
|
||||||
|
:maxlength="1"
|
||||||
|
placeholder=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 错误提示 -->
|
||||||
|
<p v-if="errorMessage" class="error-message">
|
||||||
|
{{ errorMessage }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { Input } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { ref, watch } from 'vue';
|
||||||
|
import { postCheckUpdatePasswordCaptcha } from '@/api/all/login';
|
||||||
|
|
||||||
|
const emits = defineEmits(['success']);
|
||||||
|
|
||||||
|
const codeArray = ref([]);
|
||||||
|
const activeIndex = ref(0); // 当前激活的输入框索引
|
||||||
|
const errorMessage = ref('');
|
||||||
|
const inputRef = ref(null);
|
||||||
|
|
||||||
|
// 处理输入事件
|
||||||
|
const handleInput = (index, value) => {
|
||||||
|
if (!value || !/^\d$/.test(value)) return;
|
||||||
|
|
||||||
|
codeArray.value[index].value = value;
|
||||||
|
|
||||||
|
if (index < 5) {
|
||||||
|
activeIndex.value = index + 1;
|
||||||
|
inputRef.value?.[activeIndex.value]?.focus?.();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFocus = (index) => {
|
||||||
|
activeIndex.value = index;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBlur = (index) => {
|
||||||
|
const _value = codeArray.value[index].value;
|
||||||
|
if (!_value || !/^\d$/.test(_value)) {
|
||||||
|
codeArray.value[index].error = true;
|
||||||
|
} else {
|
||||||
|
if (errorMessage.value) {
|
||||||
|
codeArray.value.forEach((item) => {
|
||||||
|
item.error = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
errorMessage.value = '';
|
||||||
|
codeArray.value[index].error = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 验证验证码逻辑
|
||||||
|
const validateCode = async () => {
|
||||||
|
const captcha = codeArray.value.map((item) => item.value).join('');
|
||||||
|
const { code } = await postCheckUpdatePasswordCaptcha({ captcha });
|
||||||
|
if (code === 200) {
|
||||||
|
emits('success', captcha);
|
||||||
|
} else {
|
||||||
|
activeIndex.value = 0;
|
||||||
|
inputRef.value?.[activeIndex.value]?.focus?.();
|
||||||
|
errorMessage.value = '验证码错误,请检查后重试';
|
||||||
|
codeArray.value.forEach((item) => {
|
||||||
|
item.error = true;
|
||||||
|
item.value = '';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const init = () => {
|
||||||
|
activeIndex.value = 0;
|
||||||
|
errorMessage.value = '';
|
||||||
|
inputRef.value = null;
|
||||||
|
codeArray.value = new Array(6).fill().map(() => ({ value: '', error: false }));
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
inputRef.value?.[activeIndex.value]?.focus?.();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 监听输入变化
|
||||||
|
watch(
|
||||||
|
() => codeArray.value,
|
||||||
|
(newVal) => {
|
||||||
|
if (newVal.every((item) => item.value)) {
|
||||||
|
validateCode();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true },
|
||||||
|
);
|
||||||
|
defineExpose({ init });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.verify-code-container {
|
||||||
|
.code-inputs {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
|
||||||
|
.ant-input {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
border-radius: 8px !important;
|
||||||
|
text-align: center;
|
||||||
|
font-family: $font-family-medium;
|
||||||
|
font-size: 24px !important;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 32px;
|
||||||
|
border: 1px solid #d7d7d9;
|
||||||
|
outline: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: #6d4cfe !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.fill {
|
||||||
|
color: #6d4cfe;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.error {
|
||||||
|
border-color: #f64b31 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message {
|
||||||
|
color: var(--Functional-Red-6, #f64b31);
|
||||||
|
font-family: $font-family-regular;
|
||||||
|
font-size: 12px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 20px;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -25,7 +25,7 @@
|
|||||||
v-for="(item, index) in new Array(10).fill(0)"
|
v-for="(item, index) in new Array(10).fill(0)"
|
||||||
:key="index"
|
:key="index"
|
||||||
></span>
|
></span>
|
||||||
<Button type="text" size="small" class="!p-0 !h-22px ml-10px">更改</Button>
|
<Button type="text" size="small" class="!p-0 !h-22px ml-10px" @click="openChangePasswordModal">更改</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -110,11 +110,7 @@
|
|||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<SafetyVerificationModal
|
<ChangePasswordModal ref="changePasswordModalRef" />
|
||||||
ref="safetyVerificationModalRef"
|
|
||||||
@success="handleVerifySuccess"
|
|
||||||
@cancel="handleVerifyCancel"
|
|
||||||
/>
|
|
||||||
<ChangeNameModal ref="changeNameModalRef" />
|
<ChangeNameModal ref="changeNameModalRef" />
|
||||||
<ChangeMobileModal ref="changeMobileModalRef" />
|
<ChangeMobileModal ref="changeMobileModalRef" />
|
||||||
</div>
|
</div>
|
||||||
@ -123,7 +119,7 @@
|
|||||||
import { Avatar, Button, Form, FormItem, Input, message } from 'ant-design-vue';
|
import { Avatar, Button, Form, FormItem, Input, message } from 'ant-design-vue';
|
||||||
import Modal from '@/components/modal.vue';
|
import Modal from '@/components/modal.vue';
|
||||||
import PuzzleVerification from '@/views/login/components/PuzzleVerification.vue';
|
import PuzzleVerification from '@/views/login/components/PuzzleVerification.vue';
|
||||||
import SafetyVerificationModal from './components/safety-verification-modal/index.vue';
|
import ChangePasswordModal from './components/change-password-modal/index.vue';
|
||||||
import ChangeNameModal from './components/change-name-modal/index.vue';
|
import ChangeNameModal from './components/change-name-modal/index.vue';
|
||||||
import ChangeMobileModal from './components/change-mobile-modal/index.vue';
|
import ChangeMobileModal from './components/change-mobile-modal/index.vue';
|
||||||
|
|
||||||
@ -137,7 +133,7 @@ import { useUserStore } from '@/stores';
|
|||||||
import icon1 from './img/icon1.png';
|
import icon1 from './img/icon1.png';
|
||||||
|
|
||||||
const store = useUserStore();
|
const store = useUserStore();
|
||||||
const safetyVerificationModalRef = ref(null);
|
const changePasswordModalRef = ref(null);
|
||||||
const changeNameModalRef = ref(null);
|
const changeNameModalRef = ref(null);
|
||||||
const changeMobileModalRef = ref(null);
|
const changeMobileModalRef = ref(null);
|
||||||
|
|
||||||
@ -175,8 +171,6 @@ const mobile = computed(() => {
|
|||||||
return _mobile.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
|
return _mobile.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(store.userInfo);
|
|
||||||
|
|
||||||
// 表单校验规则
|
// 表单校验规则
|
||||||
const formRules = {
|
const formRules = {
|
||||||
mobile: [
|
mobile: [
|
||||||
@ -256,6 +250,9 @@ const openChangeNameModal = () => {
|
|||||||
const openChangeMobileModal = () => {
|
const openChangeMobileModal = () => {
|
||||||
changeMobileModalRef.value.open();
|
changeMobileModalRef.value.open();
|
||||||
};
|
};
|
||||||
|
const openChangePasswordModal = () => {
|
||||||
|
changePasswordModalRef.value.open(dataSource.value.mobile);
|
||||||
|
};
|
||||||
|
|
||||||
async function handleSubmitUserInfo() {
|
async function handleSubmitUserInfo() {
|
||||||
await updateMyInfo(userInfoForm);
|
await updateMyInfo(userInfoForm);
|
||||||
|
|||||||
Reference in New Issue
Block a user