2022-12-30 01:56:26 +08:00

175 lines
5.0 KiB
Vue

<template>
<div class="login-form-container">
<div class="title">
<span style="color: #6777ef">Plusone&nbsp;</span>
<span style="font-weight: 300">Admin</span>
</div>
<n-form
ref="formRef"
:model="model"
:rules="rules"
:show-feedback="false"
:show-label="false"
size="large"
>
<n-form-item path="principal">
<n-input
placeholder="邮箱地址 / 手机号"
v-model:value="model.principal"
@keydown.enter.prevent
/>
</n-form-item>
<n-grid y-gap="24" :cols="24">
<n-gi :span="15">
<n-form-item path="password">
<n-input
placeholder="验证码"
v-model:value="model.otp"
@input="handlePasswordInput"
@keydown.enter.prevent
/>
</n-form-item>
</n-gi>
<n-gi :span="9">
<div style="display: flex; justify-content: flex-end">
<n-button
class="txt-btn"
@click="handleBtnGetOTPClick"
size="large"
style="width: 100%"
>
获取验证码
</n-button>
</div>
</n-gi>
</n-grid>
<n-grid y-gap="24" :cols="2">
<n-gi>
<n-form-item path="rememberMe">
<n-checkbox v-model:checked="model.rememberMe" size="large">
<span style="color: #808080">保持登录状态</span>
</n-checkbox>
</n-form-item>
</n-gi>
<n-gi>
<div style="display: flex; justify-content: flex-end">
<n-button class="txt-btn" text @click="$emit('toLoginByPassword')">
密码登录
</n-button>
</div>
</n-gi>
</n-grid>
<n-button
type="primary"
size="large"
style="width: 100%; margin-top: 8px"
@click="handleBtnLoginClick"
>
登录
</n-button>
<div style="display: flex; justify-content: flex-end; margin-top: 8px">
<n-button class="txt-btn" text style="margin-left: 16px"> 忘记密码 </n-button>
<n-button class="txt-btn" text style="margin-left: 16px"> 免费注册 </n-button>
</div>
</n-form>
</div>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import type { FormInst, FormItemInst, FormItemRule, FormRules } from "naive-ui";
import type { LoginByOTPCommand } from "@/type/commands/LoginCommands";
const formRef = ref<FormInst | null>(null);
const rPasswordFormItemRef = ref<FormItemInst | null>(null);
const model = ref<LoginByOTPCommand>({
principal: "",
otp: "",
rememberMe: false,
});
const rules: FormRules = {
principal: [
{
required: true,
validator(rule: FormItemRule, value: string) {
if (!value) {
return new Error("需要年龄");
} else if (!/^\d*$/.test(value)) {
return new Error("年龄应该为整数");
} else if (Number(value) < 18) {
return new Error("年龄应该超过十八岁");
}
return true;
},
trigger: ["input", "blur"],
},
],
otp: [
{
required: true,
message: "请输入密码",
},
],
};
function handlePasswordInput() {
if (model.value.rememberMe) {
rPasswordFormItemRef.value?.validate({ trigger: "password-input" });
}
}
function handleBtnLoginClick(e: MouseEvent) {
e.preventDefault();
formRef.value?.validate((errors) => {
if (!errors) {
window.$message.success("验证成功");
} else {
console.log(errors);
window.$message.error("验证失败");
}
});
}
function handleBtnGetOTPClick() {
console.log("handleBtnGetOTPClick");
}
</script>
<style scoped>
.login-form-container {
width: 320px;
background-color: #f3f3f3;
padding: 32px 40px;
border-radius: 6px;
border: solid 1px #e4e4e4;
box-shadow: 0 4px 24px 0 rgba(0, 0, 0, 0.2);
border-top: solid 4px #6777ef;
}
.title {
font-size: 30px;
text-align: center;
margin-bottom: 16px;
}
.n-form-item {
margin-bottom: 8px;
}
.txt-btn {
line-height: 40px;
font-size: 15px;
color: #6777ef;
}
.txt-btn:hover {
color: rgba(103, 119, 239, 0.8);
}
</style>