Files
leaudit-platform-frontend/app/routes/login.tsx
T

189 lines
6.5 KiB
TypeScript

import { useState } from "react";
import { useActionData, Form } from "@remix-run/react";
import { type MetaFunction, type ActionFunctionArgs, redirect, type LoaderFunctionArgs } from "@remix-run/node";
import styles from "~/styles/pages/login.css?url";
import { getUserSession, getSession, type UserRole, sessionStorage } from "~/root";
export const links = () => [
{ rel: "stylesheet", href: styles }
];
export const meta: MetaFunction = () => {
return [
{ title: "中国烟草AI合同及卷宗审核系统 - 登录" },
{ name: "description", content: "中国烟草AI合同及卷宗审核系统登录页面" },
];
};
// 处理表单提交的action
export async function action({ request }: ActionFunctionArgs) {
const formData = await request.formData();
const username = formData.get("username") as string;
const password = formData.get("password") as string;
const userRole = formData.get("userRole") as UserRole || 'common';
// console.log("userRole-----", userRole);
// 简单的登录验证,实际应用中应该进行真正的身份验证
if (!username || !password) {
return Response.json({ error: "用户名和密码不能为空" });
}
if(userRole === 'common') {
// console.log("username-----", username);
// console.log("password-----", password);
const validUsers = [
{ username: 'gdycuser', password: 'gdyc06111' },
{ username: 'gdycuser2', password: 'gdyc06112' },
{ username: 'gdycuser3', password: 'gdyc06113' }
];
const validUser = validUsers.find(user => user.username === username && user.password === password);
if (!validUser) {
return Response.json({ error: "普通用户用户名或密码错误" });
}
}
// console.log("login success", userRole);
// 管理员登录
if (userRole === 'developer') {
const validAdminUsers = [
{ username: 'admin', password: 'admin0611' },
// { username: 'admin2', password: 'admin06112' },
// { username: 'admin3', password: 'admin06113' }
];
const validAdminUser = validAdminUsers.find(user => user.username === username && user.password === password);
if (!validAdminUser) {
return Response.json({ error: "管理员用户名或密码错误" });
}
}
// 获取session中存储的重定向URL,如果没有则默认到/
const session = await getSession(request);
// 查看session中存储的redirectTo值
const redirectTo = session.get("redirectTo") || "/";
// console.log("登录后重定向到:", redirectTo);
// 创建会话cookie
const newSession = await sessionStorage.getSession();
newSession.set("isAuthenticated", true);
newSession.set("userRole", userRole);
const cookie = await sessionStorage.commitSession(newSession);
// console.log("设置cookie:", !!cookie);
// 使用新方法进行重定向
return redirect(redirectTo, {
headers: {
"Set-Cookie": cookie
}
});
}
// 加载器,获取当前会话状态
export async function loader({ request }: LoaderFunctionArgs) {
const { isAuthenticated } = await getUserSession(request);
// 如果已登录,重定向到首页
if (isAuthenticated) {
return redirect("/");
}
return Response.json({ isAuthenticated });
}
export default function Login() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [userRole, setUserRole] = useState<UserRole>("common");
const [showPassword, setShowPassword] = useState(false);
const actionData = useActionData<typeof action>();
return (
<div className="login-page">
<div className="login-container">
<div className="login-header">
{/* <img src="/logo.png" alt="中国烟草" className="login-logo" /> */}
<h1 className="login-title">AI合同及卷宗审核系统</h1>
</div>
<div className="login-form-container">
<h2 className="login-subtitle"></h2>
<Form
method="post"
className="login-form"
>
{actionData?.error && (
<div className="error-message-container">
<div className="error-icon"><i className="ri-error-warning-line"></i></div>
<div className="error-text">{actionData.error}</div>
</div>
)}
<div className="form-group">
<label htmlFor="username"></label>
<input
type="text"
id="username"
name="username"
value={username}
onChange={(e) => setUsername(e.target.value)}
className="form-input"
placeholder="请输入用户名"
/>
</div>
<div className="form-group">
<label htmlFor="password"></label>
<div className="password-input-container">
<input
type={showPassword ? "text" : "password"}
id="password"
name="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="form-input password-input"
placeholder="请输入密码"
/>
<button
type="button"
className="password-toggle-btn"
onClick={() => setShowPassword(!showPassword)}
aria-label={showPassword ? "隐藏密码" : "显示密码"}
>
<i className={showPassword ? "ri-eye-off-line" : "ri-eye-line"}></i>
</button>
</div>
</div>
<div className="form-group">
<label htmlFor="userRole"></label>
<select
id="userRole"
name="userRole"
value={userRole}
onChange={(e) => setUserRole(e.target.value as UserRole)}
className="form-input"
required
>
<option value="common"></option>
{/* <option value="developer">管理员</option> */}
</select>
</div>
<button
type="submit"
className="login-button"
>
</button>
</Form>
</div>
<div className="login-footer">
<p>© 2024 </p>
</div>
</div>
</div>
);
}