Files
zn-ai/src/renderer/views/login/index.vue
2025-12-01 22:16:34 +08:00

149 lines
5.9 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 box-border p-[8px] login-bg flex items-center justify-center"
>
<div class="w-[836px] h-full 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">注册</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>
<div class="w-[392px] ml-auto mr-auto">
<div class="font-[14px] text-gray-700 mb-2">账号</div>
<div class="border rounded-[10px] flex items-center gap-2 box-border px-[12px] py-[10px]">
<RiUser3Fill size="20px" color="#99A0AE" />
<input
class="flex-1 focus-visible:outline-none"
type="text"
v-model.trim="form.account"
placeholder="请输入账号"
@keyup.enter="onSubmit"
/>
</div>
<p v-if="errors.account" class="mt-1 text-xs text-red-500">{{ errors.account }}</p>
<div class="font-[14px] text-gray-700 mb-[8px] mt-[12px]">密码</div>
<div class="flex items-center gap-2 border rounded-[10px] box-border px-[12px] py-[10px]">
<RiKey2Fill size="20px" color="#99A0AE" />
<input
class="flex-1 focus-visible:outline-none"
:type="showPwd ? 'text' : 'password'"
v-model.trim="form.password"
placeholder="请输入密码"
@keyup.enter="onSubmit"
/>
</div>
<p v-if="errors.password" class="mt-1 text-xs text-red-500">{{ errors.password }}</p>
<!-- 验证码 -->
<div class="font-[14px] text-gray-700 mb-[8px] mt-[12px]">验证码</div>
<div class="flex items-center gap-2 border rounded-[10px] box-border px-[12px] py-[10px]">
<input
class="flex-1 focus-visible:outline-none"
type="text"
v-model.trim="form.code"
placeholder="请输入验证码"
@keyup.enter="onSubmit"
/>
<img class="w-[80px] h-[40px]" src="" />
</div>
<p v-if="errors.code" class="mt-1 text-xs text-red-500">{{ errors.code }}</p>
<!-- 记住密码|忘记密码 -->
<div class="flex items-center justify-between mb-[24px] mt-[24px]">
<div class="flex items-center gap-2">
<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">忘记密码</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="form.agreement"
class="w-[14px] h-[14px] rounded-[4px]"
/>
<span class="text-[14px] text-gray-600">我已同意</span>
<span class="text-[14px] text-sky-600">使用协议</span>
<span class="text-[14px] text-gray-600"></span>
<span class="text-[14px] text-sky-600">隐私协议</span>
</div>
</div>
<!-- Copy Right -->
<div class="text-[14px] text-gray-500 text-center mt-[24px] mt-auto">
© 2025 贵州智念科技服务有限公司 版权所有
</div>
</div>
<img class="w-[570px]" src="@assets/images/login/logo.png" />
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from "vue";
import { useRouter } from "vue-router";
import { login as apiLogin } from "@/renderer/api/login";
import { RiUser3Fill , RiKey2Fill} from '@remixicon/vue'
const router = useRouter();
const form = reactive({ account: "", password: "", agreement: "", code: "" });
const errors = reactive<{ account?: string; password?: string; code?: string }>({});
const loading = ref(false);
const showPwd = ref(false);
const validate = () => {
errors.account = undefined;
errors.password = undefined;
if (!form.account) errors.account = "请输入账号";
else if (form.account.length < 4 || form.account.length > 32) errors.account = "账号长度需在 4-32 之间";
if (!form.password) errors.password = "请输入密码";
else if (form.password.length < 6) errors.password = "密码长度不少于 6 位";
return !errors.account && !errors.password;
};
const onSubmit = async () => {
// if (!validate() || loading.value) return;
// loading.value = true;
try {
localStorage.setItem("token", "dev-token");
// const res: any = await apiLogin({ account: form.account, password: form.password });
// const token = res && (res.token || res.data?.token || res.access_token);
// if (!token) throw new Error("登录失败");
// localStorage.setItem("token", token);
await (window as any).ipcAPI.app.setFrameless('/home')
} finally {
// 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;
}
</style>