|
|
<script lang="ts" setup>
|
|
|
import { reactive, ref } from "vue";
|
|
|
import { useMessage } from "naive-ui";
|
|
|
import { forgetPassword, getCode, updateSUser } from "@/api/login/login";
|
|
|
|
|
|
const emit = defineEmits(["close", "forget"]);
|
|
|
interface FormState {
|
|
|
enterprisecode?: string;
|
|
|
username: string;
|
|
|
password: string;
|
|
|
captcha: string;
|
|
|
}
|
|
|
|
|
|
interface FormForget {
|
|
|
agentcode: string;
|
|
|
loginname: string;
|
|
|
phone: string;
|
|
|
phonecode: string;
|
|
|
}
|
|
|
|
|
|
interface FormSure {
|
|
|
newPassword: string;
|
|
|
rePasswrod: string;
|
|
|
loginname: string;
|
|
|
}
|
|
|
|
|
|
const formRef = ref();
|
|
|
const formRefSure = ref();
|
|
|
|
|
|
const message = useMessage();
|
|
|
const loading = ref(false);
|
|
|
const flag = ref(true);
|
|
|
const formForget: FormForget = reactive({
|
|
|
agentcode: "",
|
|
|
loginname: "",
|
|
|
phone: "",
|
|
|
phonecode: "",
|
|
|
});
|
|
|
|
|
|
const formInline: FormState = reactive({
|
|
|
enterprisecode: "",
|
|
|
username: "",
|
|
|
password: "",
|
|
|
captcha: "",
|
|
|
});
|
|
|
|
|
|
const formSure: FormSure = reactive({
|
|
|
newPassword: "",
|
|
|
rePasswrod: "",
|
|
|
loginname: "13311111111",
|
|
|
});
|
|
|
const tab = ref(0);
|
|
|
const loginSuccess = ref(true);
|
|
|
const loginRejectMessge = ref("");
|
|
|
const countTime = ref("获取验证码");
|
|
|
const rules = {
|
|
|
enterprisecode: [
|
|
|
{ required: true, message: "请输入企业编码", trigger: "blur" },
|
|
|
{
|
|
|
trigger: ["blur", "input", "change"],
|
|
|
level: "error",
|
|
|
validator(_rule, value) {
|
|
|
if (loginSuccess.value || !value) {
|
|
|
return true;
|
|
|
}
|
|
|
if (loginRejectMessge.value.indexOf("企业") > -1) {
|
|
|
return new Error(loginRejectMessge.value);
|
|
|
}
|
|
|
},
|
|
|
},
|
|
|
],
|
|
|
agentcode: [
|
|
|
{ required: true, message: "请输入企业编码", trigger: "blur" },
|
|
|
{
|
|
|
trigger: ["blur", "input", "change"],
|
|
|
level: "error",
|
|
|
validator(_rule, value) {
|
|
|
if (loginSuccess.value || !value) {
|
|
|
return true;
|
|
|
}
|
|
|
if (loginRejectMessge.value.indexOf("企业") > -1) {
|
|
|
return new Error(loginRejectMessge.value);
|
|
|
}
|
|
|
},
|
|
|
},
|
|
|
],
|
|
|
loginname: [
|
|
|
{ required: true, message: "请输入用户名", trigger: "blur" },
|
|
|
{
|
|
|
trigger: ["blur", "input", "change"],
|
|
|
level: "error",
|
|
|
validator(_rule, value) {
|
|
|
if (loginSuccess.value || !value) {
|
|
|
return true;
|
|
|
}
|
|
|
if (loginRejectMessge.value.indexOf("用户名") > -1) {
|
|
|
return new Error(loginRejectMessge.value);
|
|
|
}
|
|
|
},
|
|
|
},
|
|
|
],
|
|
|
phone: [
|
|
|
{ required: true, message: "请输入手机号", trigger: "blur" },
|
|
|
{
|
|
|
trigger: ["blur", "input", "change"],
|
|
|
level: "error",
|
|
|
validator(_rule, value) {
|
|
|
if (loginSuccess.value || !value) {
|
|
|
return true;
|
|
|
}
|
|
|
if (loginRejectMessge.value.indexOf("手机号") > -1) {
|
|
|
return new Error(loginRejectMessge.value);
|
|
|
}
|
|
|
},
|
|
|
},
|
|
|
],
|
|
|
password: { required: true, message: "请输入密码", trigger: "blur" },
|
|
|
phonecode: [
|
|
|
{ required: true, message: "请输入验证码", trigger: "blur" },
|
|
|
{
|
|
|
trigger: ["blur", "input", "change"],
|
|
|
level: "error",
|
|
|
validator(_rule, value) {
|
|
|
if (loginSuccess.value || !value) {
|
|
|
return true;
|
|
|
}
|
|
|
if (loginRejectMessge.value.indexOf("验证码") > -1) {
|
|
|
return new Error(loginRejectMessge.value);
|
|
|
}
|
|
|
},
|
|
|
},
|
|
|
],
|
|
|
newPassword: { required: true, message: "请输入新密码", trigger: "blur" },
|
|
|
rePasswrod: [
|
|
|
{
|
|
|
required: true,
|
|
|
message: "请再次输入密码",
|
|
|
trigger: ["input", "blur"],
|
|
|
},
|
|
|
{
|
|
|
validator: validatePasswordSame,
|
|
|
message: "两次密码输入不一致",
|
|
|
trigger: ["blur", "password-input"],
|
|
|
},
|
|
|
],
|
|
|
};
|
|
|
|
|
|
function validatePasswordSame(rule: any, value: string): boolean {
|
|
|
if (Boolean(formSure.rePasswrod)) {
|
|
|
if (value == formSure.newPassword) {
|
|
|
return true;
|
|
|
} else {
|
|
|
return false;
|
|
|
}
|
|
|
} else {
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function handleSubmit(e) {
|
|
|
e.preventDefault();
|
|
|
loginSuccess.value = true;
|
|
|
formRef.value.validate(async (errors) => {
|
|
|
if (!errors) {
|
|
|
const { loginname, phone, phonecode, agentcode } = formForget;
|
|
|
loading.value = true;
|
|
|
const params = {
|
|
|
loginname,
|
|
|
phone,
|
|
|
phonecode,
|
|
|
agentcode,
|
|
|
};
|
|
|
try {
|
|
|
const res = await forgetPassword(params);
|
|
|
if (res.code === "OK") {
|
|
|
loginSuccess.value = true;
|
|
|
formSure.loginname = res.data?.loginname;
|
|
|
tab.value = 1;
|
|
|
} else {
|
|
|
loginSuccess.value = false;
|
|
|
message.error(res.message);
|
|
|
loginRejectMessge.value = res.message;
|
|
|
formRef.value.validate();
|
|
|
}
|
|
|
} finally {
|
|
|
loading.value = false;
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
function handleSure(e) {
|
|
|
e.preventDefault();
|
|
|
formRefSure.value.validate(async (errors) => {
|
|
|
if (!errors) {
|
|
|
const { newPassword, rePasswrod, loginname } = formSure;
|
|
|
loading.value = true;
|
|
|
|
|
|
const params = {
|
|
|
newPassword,
|
|
|
rePasswrod,
|
|
|
loginname,
|
|
|
};
|
|
|
|
|
|
try {
|
|
|
const res = await updateSUser(params);
|
|
|
if (res.code === "OK") {
|
|
|
message.success("修改成功");
|
|
|
tab.value = 0;
|
|
|
forget();
|
|
|
} else {
|
|
|
message.error(res.message);
|
|
|
}
|
|
|
} finally {
|
|
|
loading.value = false;
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
function close() {
|
|
|
loading.value = false;
|
|
|
emit("close");
|
|
|
}
|
|
|
|
|
|
function switchTab(type: number) {
|
|
|
tab.value = type;
|
|
|
}
|
|
|
|
|
|
function computedForm() {
|
|
|
return !formInline.enterprisecode || !formInline.username || !formInline.password;
|
|
|
}
|
|
|
|
|
|
function computedFormSure() {
|
|
|
return !formSure.newPassword || !formSure.rePasswrod;
|
|
|
}
|
|
|
async function sendCode(value) {
|
|
|
if (!flag.value) return;
|
|
|
flag.value = false;
|
|
|
const res = await getCode({
|
|
|
phone: formForget.phone,
|
|
|
agentcode: formForget.agentcode,
|
|
|
});
|
|
|
if (!res.data) {
|
|
|
message.error(res.message);
|
|
|
return;
|
|
|
}
|
|
|
startCount();
|
|
|
}
|
|
|
|
|
|
function startCount() {
|
|
|
let time = 60;
|
|
|
countTime.value = "60s";
|
|
|
const timer = setInterval(() => {
|
|
|
countTime.value = `${--time}s`;
|
|
|
if (time === 0) {
|
|
|
clearInterval(timer);
|
|
|
countTime.value = "获取验证码";
|
|
|
flag.value = true;
|
|
|
}
|
|
|
}, 1000);
|
|
|
}
|
|
|
|
|
|
function forget() {
|
|
|
loading.value = false;
|
|
|
emit("forget");
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
<div class="form-login">
|
|
|
<img class="img-close" src="@/assets/images/login/close.png" alt="" @click="close" />
|
|
|
<div class="flex justify-between header">
|
|
|
<div class="tab">忘记密码</div>
|
|
|
<div class="back" @click="forget">< 返回登录</div>
|
|
|
</div>
|
|
|
<div v-if="tab === 0" class="form-1">
|
|
|
<n-form
|
|
|
ref="formRef"
|
|
|
label-placement="left"
|
|
|
size="large"
|
|
|
:model="formForget"
|
|
|
:rules="rules"
|
|
|
>
|
|
|
<n-form-item class="form-item" path="agentcode">
|
|
|
<n-input
|
|
|
v-model:value="formForget.agentcode"
|
|
|
class="item-input"
|
|
|
placeholder="请输入企业编码"
|
|
|
maxlength="20"
|
|
|
>
|
|
|
<template #prefix>
|
|
|
<svg-icon size="20" name="enterprise" />
|
|
|
</template>
|
|
|
</n-input>
|
|
|
</n-form-item>
|
|
|
<n-form-item class="form-item" path="loginname">
|
|
|
<n-input
|
|
|
v-model:value="formForget.loginname"
|
|
|
class="item-input"
|
|
|
placeholder="请输入用户名"
|
|
|
maxlength="16"
|
|
|
>
|
|
|
<template #prefix>
|
|
|
<svg-icon size="20" name="account" />
|
|
|
</template>
|
|
|
</n-input>
|
|
|
</n-form-item>
|
|
|
<n-form-item class="form-item" path="phone">
|
|
|
<n-input
|
|
|
v-model:value="formForget.phone"
|
|
|
class="item-input"
|
|
|
placeholder="请输入手机号"
|
|
|
maxlength="11"
|
|
|
>
|
|
|
<template #prefix>
|
|
|
<img
|
|
|
class="img-phone"
|
|
|
src="@/assets/images/login/phone.png"
|
|
|
alt=""
|
|
|
@click="close"
|
|
|
/>
|
|
|
</template>
|
|
|
</n-input>
|
|
|
</n-form-item>
|
|
|
<n-form-item class="form-item" path="phonecode">
|
|
|
<n-input
|
|
|
v-model:value="formForget.phonecode"
|
|
|
maxlength="4"
|
|
|
class="item-input"
|
|
|
placeholder="请输入验证码"
|
|
|
clearable
|
|
|
>
|
|
|
<template #prefix>
|
|
|
<img
|
|
|
class="img-phone"
|
|
|
src="@/assets/images/login/auth.png"
|
|
|
alt=""
|
|
|
@click="close"
|
|
|
/>
|
|
|
</template>
|
|
|
<template #suffix>
|
|
|
<div
|
|
|
:class="{
|
|
|
'code-count':
|
|
|
countTime !== '获取验证码' || !(formForget.phone.length == 11),
|
|
|
}"
|
|
|
class="code"
|
|
|
@click="sendCode"
|
|
|
>
|
|
|
{{ countTime }}
|
|
|
</div>
|
|
|
</template>
|
|
|
</n-input>
|
|
|
</n-form-item>
|
|
|
<!-- <n-form-item class="form-item"> -->
|
|
|
<n-button
|
|
|
:class="{ 'btn-disabled': computedForm() }"
|
|
|
class="btn"
|
|
|
type="primary"
|
|
|
size="large"
|
|
|
:loading="loading"
|
|
|
block
|
|
|
@click="handleSubmit"
|
|
|
>
|
|
|
下一步
|
|
|
</n-button>
|
|
|
<!-- </n-form-item> -->
|
|
|
</n-form>
|
|
|
</div>
|
|
|
<div v-if="tab === 1" class="form-1">
|
|
|
<n-form
|
|
|
ref="formRefSure"
|
|
|
label-placement="left"
|
|
|
size="large"
|
|
|
:model="formSure"
|
|
|
:rules="rules"
|
|
|
>
|
|
|
<n-form-item class="form-item" path="newPassword">
|
|
|
<n-input
|
|
|
v-model:value="formSure.newPassword"
|
|
|
class="item-input"
|
|
|
type="password"
|
|
|
show-password-on="click"
|
|
|
placeholder="请输入8-16位密码,必须包含英文及数字"
|
|
|
maxlength="16"
|
|
|
>
|
|
|
<template #prefix>
|
|
|
<svg-icon size="20" name="password" />
|
|
|
</template>
|
|
|
</n-input>
|
|
|
</n-form-item>
|
|
|
<n-form-item class="form-item" path="rePasswrod">
|
|
|
<n-input
|
|
|
v-model:value="formSure.rePasswrod"
|
|
|
class="item-input"
|
|
|
type="password"
|
|
|
show-password-on="click"
|
|
|
placeholder="请再次确认输入新密码"
|
|
|
maxlength="16"
|
|
|
>
|
|
|
<template #prefix>
|
|
|
<svg-icon size="20" name="password" />
|
|
|
</template>
|
|
|
</n-input>
|
|
|
</n-form-item>
|
|
|
<n-form-item class="form-item">
|
|
|
<n-button
|
|
|
:class="{ 'btn-disabled': computedFormSure() }"
|
|
|
class="btn"
|
|
|
type="primary"
|
|
|
size="large"
|
|
|
:loading="loading"
|
|
|
block
|
|
|
@click="handleSure"
|
|
|
>
|
|
|
确定
|
|
|
</n-button>
|
|
|
</n-form-item>
|
|
|
</n-form>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<style lang="less" scoped>
|
|
|
.form-login {
|
|
|
width: 26.25rem;
|
|
|
box-sizing: border-box;
|
|
|
background: linear-gradient(
|
|
|
136deg,
|
|
|
rgba(226, 236, 255, 0.8) 3%,
|
|
|
rgba(251, 251, 251, 0.8) 97%
|
|
|
);
|
|
|
border: 1px solid #ffffff;
|
|
|
border-radius: 6px;
|
|
|
box-shadow: 0px 6px 12px 0px rgba(0, 0, 0, 0.04);
|
|
|
backdrop-filter: blur(12px);
|
|
|
position: relative;
|
|
|
padding: 3rem 1.6875rem 2rem;
|
|
|
.img-close {
|
|
|
position: absolute;
|
|
|
right: 0;
|
|
|
top: -44px;
|
|
|
width: 1.75rem;
|
|
|
height: 1.75rem;
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
.tab {
|
|
|
font-size: 1.5rem;
|
|
|
font-family: PingFang SC, PingFang SC-Medium;
|
|
|
font-weight: Medium;
|
|
|
text-align: left;
|
|
|
color: #507afd;
|
|
|
}
|
|
|
|
|
|
.header {
|
|
|
align-items: center;
|
|
|
}
|
|
|
|
|
|
.form-1 {
|
|
|
margin-top: 1.8125rem;
|
|
|
|
|
|
.form-item {
|
|
|
height: 3.75rem;
|
|
|
}
|
|
|
|
|
|
.item-input {
|
|
|
width: 22.875rem;
|
|
|
// height: 44px;
|
|
|
background: rgba(255, 255, 255, 0.5);
|
|
|
border-radius: 4px;
|
|
|
}
|
|
|
|
|
|
.btn {
|
|
|
width: 22.875rem;
|
|
|
height: 2.75rem;
|
|
|
background: linear-gradient(234deg, #96aaff 0%, #1c43ff 100%);
|
|
|
border-radius: 3px;
|
|
|
margin-top: 1rem;
|
|
|
// margin-bottom: .875rem;
|
|
|
font-size: 1rem;
|
|
|
&-disabled {
|
|
|
opacity: 0.5;
|
|
|
background: linear-gradient(234deg, #96aaff 0%, #1c43ff 100%);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.img-phone {
|
|
|
width: 1.25rem;
|
|
|
height: 1.25rem;
|
|
|
}
|
|
|
|
|
|
.order-last {
|
|
|
font-size: 0.875rem;
|
|
|
font-family: PingFang SC, PingFang SC-Regular;
|
|
|
font-weight: Regular;
|
|
|
color: #507afd;
|
|
|
}
|
|
|
|
|
|
.code {
|
|
|
font-size: 0.9375rem;
|
|
|
font-family: PingFang SC, PingFang SC-Regular;
|
|
|
font-weight: Regular;
|
|
|
color: #507afd;
|
|
|
margin-left: 0.75rem;
|
|
|
cursor: pointer;
|
|
|
&-count {
|
|
|
font-size: 0.875rem;
|
|
|
color: #999999;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
::v-deep(.n-form-item-feedback--error) {
|
|
|
// color: #FF4E4F !important;
|
|
|
}
|
|
|
.back {
|
|
|
font-size: 0.9375rem;
|
|
|
font-family: PingFang SC, PingFang SC-Medium;
|
|
|
font-weight: Medium;
|
|
|
text-align: center;
|
|
|
color: #666666;
|
|
|
line-height: 1.3125rem;
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
|
|
|
// 样式适配
|
|
|
::v-deep(.n-base-clear > .n-base-clear__clear > .n-base-icon > svg) {
|
|
|
color: #c9c9c9;
|
|
|
}
|
|
|
::v-deep(.n-input .n-input__input-el) {
|
|
|
height: 2.75rem !important;
|
|
|
font-size: 1rem !important;
|
|
|
}
|
|
|
::v-deep(.n-input .n-input-wrapper) {
|
|
|
height: 2.75rem !important;
|
|
|
}
|
|
|
.save-btn {
|
|
|
font-size: 0.9375rem;
|
|
|
}
|
|
|
::v-deep(.n-form-item .n-form-item-feedback-wrapper) {
|
|
|
height: 1rem;
|
|
|
padding: 0 !important;
|
|
|
margin: 0 !important;
|
|
|
line-height: normal !important;
|
|
|
min-height: 0 !important;
|
|
|
// margin-bottom: .5rem;
|
|
|
}
|
|
|
</style>
|