Files
zn-ai/src/renderer/views/login/index.vue
2025-12-20 00:02:47 +08:00

162 lines
6.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="h-screen login-bg flex flex-col">
<header-bar>
<drag-region class="w-full" />
</header-bar>
<main class="box-border p-[8px] flex-auto flex ">
<div class="w-[836px] box-border bg-white rounded-2xl p-[32px] flex flex-col">
<div class="flex items-center">
<img class="w-[48px] h-[48px]" src="@assets/images/login/blue_logo.png" />
<span class="ml-auto text-[14px] text-gray-600">没有账号</span>
<button
class="bg-sky-50 rounded-[8px] text-[14px] text-sky-600 px-[12px] py-[6px] focus-visible:outline-none cursor-pointer">注册</button>
</div>
<div class="flex flex-col items-center justify-center mb-[24px] box-border pt-[108px]">
<img class="w-[80px] h-[80px] mb-[12px]" src="@assets/images/login/user_icon.png" />
<div class="text-[24px] font-500 text-gray-800 line-height-[32px] mb-[4px]">登录</div>
<div class="text-[16px] text-gray-500 line-height-[24px]">24小时在岗从不打烊的数字员工</div>
</div>
<el-form class="w-[392px] ml-auto mr-auto" ref="formRef" :rules="rules" :model="form" label-position="top"
@keyup.enter="onSubmit">
<el-form-item prop="username">
<div class="text-[14px] text-gray-600">账号</div>
<el-input class="h-[40px]" v-model.trim="form.username" placeholder="请输入账号" clearable autocomplete="off">
<template #prefix>
<RiUser3Fill size="20px" color="#99A0AE" />
</template>
</el-input>
</el-form-item>
<el-form-item prop="password">
<div class="text-[14px] text-gray-600">密码</div>
<el-input class="h-[40px]" v-model.trim="form.password" placeholder="请输入密码" clearable autocomplete="off">
<template #prefix>
<RiKey2Fill size="20px" color="#99A0AE" />
</template>
</el-input>
</el-form-item>
<el-form-item prop="code">
<span class="text-[14px] text-gray-600">验证码</span>
<el-input v-model.trim="form.code" placeholder="请输入验证码" autocomplete="off">
<template #suffix>
<img class="w-[80px] h-[38px] cursor-pointer" :src="imgSrc" @click="getVerifyCode" />
</template>
</el-input>
</el-form-item>
<!-- 记住密码|忘记密码 -->
<div class="flex items-center justify-between mb-[24px] mt-[24px]">
<div class="flex items-center gap-2 cursor-pointer">
<input type="checkbox" v-model="showPwd" class="w-[14px] h-[14px] rounded-[4px]" />
<span class="text-[14px] text-gray-600">记住密码</span>
</div>
<span class="text-[14px] text-sky-600 cursor-pointer">忘记密码</span>
</div>
<!-- 登录按钮 -->
<button class="w-full py-2 bg-blue-600 text-white rounded-[8px] hover:bg-blue-700 disabled:bg-blue-300"
@click="onSubmit">
{{ loading ? '登录中' : '登录' }}
</button>
<!-- 同意协议 -->
<div class="flex items-center justify-center gap-2 mt-[24px]">
<input type="checkbox" v-model="isAgree" class="w-[14px] h-[14px] rounded-[4px]" />
<span class="text-[14px] text-gray-600">我已同意</span>
<span class="text-[14px] text-sky-600 cursor-pointer">使用协议</span>
<span class="text-[14px] text-gray-600"></span>
<span class="text-[14px] text-sky-600 cursor-pointer">隐私协议</span>
</div>
</el-form>
<!-- Copy Right -->
<div class="text-[14px] text-gray-500 text-center mt-auto">
© 2025 贵州智念科技服务有限公司 版权所有
</div>
</div>
<img class="w-[540px]" src="@assets/images/login/logo.png" />
</main>
</div>
</template>
<script setup lang="ts">
import { authOauth2TokenUsingPost } from "@renderer/api";
import { RiUser3Fill, RiKey2Fill } from '@remixicon/vue'
import { generateUUID } from "@utils/generateUUID";
import { rule } from '@utils/validate'
// form 表单数据类型声明
interface LoginForm {
username: string;
password: string;
randomStr: string;
code: string;
}
const router = useRouter();
const form = reactive<LoginForm>({ username: "", password: "", randomStr: '', code: "" });
const loading = ref(false);
const showPwd = ref(false);
const isAgree = ref(false);
const imgSrc = ref('');
const rules = reactive({
username: [{ validator: rule.overLength, trigger: 'blur' }, { required: true, trigger: 'blur', message: '请输入账号' }], // 用户名校验规则
password: [{ validator: rule.overLength, trigger: 'blur' }, { required: true, trigger: 'blur', message: '请输入密码' }], // 密码校验规则
code: [{ validator: rule.overLength, trigger: 'blur' }, { required: true, trigger: 'blur', message: '请输入验证码' }], // 验证码校验规则
})
//获取验证码图片
const { VITE_SERVICE_URL } = (import.meta as any).env
const getVerifyCode = async () => {
form.randomStr = generateUUID()
imgSrc.value = `${VITE_SERVICE_URL}/auth/code/image?randomStr=${form.randomStr}`
}
onMounted(() => getVerifyCode())
const formRef = ref()
const onSubmit = async () => {
const valid = await formRef.value.validate().catch(() => { }); // 表单校验
if (!valid) return false;
loading.value = true;
try {
// localStorage.setItem("token", "dev-token");
// const res: any = await authOauth2TokenUsingPost({ body: form });
// const token = res && (res.token || res.data?.token || res.access_token);
// if (!token) throw new Error("登录失败");
// localStorage.setItem("token", token);
// await (window as any).api.app.setFrameless('/home')
router.push('/home');
} finally {
getVerifyCode()
loading.value = false; // 登录结束
}
};
</script>
<style scoped>
.login-bg {
background: url('@assets/images/login/login_bg.png');
background-size: 100% 100%;
background-position: 0 0;
background-repeat: no-repeat;
}
:deep(.el-input__wrapper) {
border-radius: 10px;
}
:deep(.el-form-item__error) {
padding-top: 8px;
}
</style>