210 lines
7.0 KiB
TypeScript
210 lines
7.0 KiB
TypeScript
import { useState, useEffect } from 'react';
|
|
import { useNavigate, Form, useLoaderData } from '@remix-run/react';
|
|
import { type MetaFunction, type ActionFunctionArgs, LoaderFunctionArgs, redirect } from "@remix-run/node";
|
|
import styles from "~/styles/pages/home.css?url";
|
|
import dayjs from 'dayjs';
|
|
import { getUserSession, logout } from "~/api/login/auth.server";
|
|
|
|
export const links = () => [
|
|
{ rel: "stylesheet", href: styles }
|
|
];
|
|
|
|
export const meta: MetaFunction = () => {
|
|
return [
|
|
{ title: "中国烟草AI合同及卷宗审核系统 - 首页" },
|
|
{ name: "description", content: "中国烟草AI合同及卷宗审核系统首页" },
|
|
];
|
|
};
|
|
|
|
// 处理登出请求
|
|
export async function action({ request }: ActionFunctionArgs) {
|
|
const formData = await request.formData();
|
|
const intent = formData.get("intent");
|
|
|
|
if (intent === "logout") {
|
|
return logout(request);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
// 验证用户登录状态
|
|
export async function loader({ request }: LoaderFunctionArgs) {
|
|
const { isAuthenticated, userRole, userInfo } = await getUserSession(request);
|
|
|
|
if (!isAuthenticated) {
|
|
return redirect("/login");
|
|
}
|
|
return Response.json({ userRole, userInfo });
|
|
}
|
|
|
|
export default function Index() {
|
|
const navigate = useNavigate();
|
|
const { userRole, userInfo } = useLoaderData<typeof loader>();
|
|
const [currentDateTime, setCurrentDateTime] = useState({
|
|
date: '',
|
|
time: ''
|
|
});
|
|
|
|
// 检查是否通过51707端口访问
|
|
const [isPort51707, setIsPort51707] = useState(false);
|
|
|
|
useEffect(() => {
|
|
if (typeof window !== 'undefined') {
|
|
setIsPort51707(window.location.port === '51707');
|
|
// setIsPort51707(window.location.port === '5178');
|
|
}
|
|
}, []);
|
|
|
|
// 打印服务器端传递的用户角色
|
|
useEffect(() => {
|
|
console.log('_index 服务器返回的用户角色:', userRole);
|
|
}, [userRole]);
|
|
|
|
// 更新日期时间
|
|
useEffect(() => {
|
|
const updateDateTime = () => {
|
|
const now = dayjs();
|
|
// 格式化日期: YYYY/MM/DD
|
|
setCurrentDateTime({
|
|
date: now.format('YYYY/MM/DD'),
|
|
time: now.format('HH:mm:ss')
|
|
});
|
|
};
|
|
|
|
// 初始化时间
|
|
updateDateTime();
|
|
|
|
// 每秒更新一次
|
|
const timerID = setInterval(updateDateTime, 1000);
|
|
|
|
return () => clearInterval(timerID);
|
|
}, []);
|
|
|
|
// 处理模块点击
|
|
const handleModuleClick = (path: string, reviewType: string) => {
|
|
// 将reviewType存入sessionStorage
|
|
if (typeof window !== 'undefined') {
|
|
sessionStorage.setItem('reviewType', reviewType);
|
|
}
|
|
navigate(path);
|
|
};
|
|
|
|
// 处理键盘事件
|
|
const handleKeyDown = (path: string, reviewType: string, e: React.KeyboardEvent<HTMLDivElement>) => {
|
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
handleModuleClick(path, reviewType);
|
|
}
|
|
};
|
|
|
|
// 处理登出
|
|
const handleLogout = () => {
|
|
// 清除sessionStorage中的所有数据
|
|
if (typeof window !== 'undefined') {
|
|
sessionStorage.clear();
|
|
}
|
|
|
|
// 使用Form组件提交登出请求
|
|
const form = document.getElementById('logout-form') as HTMLFormElement;
|
|
if (form) {
|
|
form.submit();
|
|
} else {
|
|
// 如果找不到表单,直接导航到登录页
|
|
navigate('/login');
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="home-page">
|
|
{/* 登出表单 - 隐藏 */}
|
|
<Form method="post" id="logout-form" className="hidden">
|
|
<input type="hidden" name="intent" value="logout" />
|
|
</Form>
|
|
|
|
{/* 头部 */}
|
|
<header className="header">
|
|
<div className="logo-container">
|
|
<img src="/logo.svg" alt="中国烟草" className="logo" />
|
|
<div className="flex flex-col">
|
|
<span className="logo-text ">中国烟草</span>
|
|
<span className="logo-text-en">CHINA TOBACCO</span>
|
|
</div>
|
|
</div>
|
|
<div className="user-info">
|
|
<span className="datetime">{currentDateTime.date} {currentDateTime.time}</span>
|
|
<div className="user">
|
|
{(() => {
|
|
const displayName = (userInfo?.nick_name || (userInfo as { nickname?: string })?.nickname || (userInfo as { name?: string })?.name || '') as string;
|
|
const lastChar = displayName ? displayName.charAt(displayName.length - 1) : '用';
|
|
return (
|
|
<>
|
|
<div className="avatar w-10 h-10 rounded-full bg-primary text-white flex items-center justify-center">
|
|
<span>{lastChar}</span>
|
|
</div>
|
|
<span className="username ml-2">{displayName || '未知用户'}</span>
|
|
</>
|
|
);
|
|
})()}
|
|
<button
|
|
onClick={handleLogout}
|
|
className="logout-button"
|
|
aria-label="登出"
|
|
>
|
|
<i className="ri-logout-box-line"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
{/* 主要内容 */}
|
|
<main className="index-main-content">
|
|
<div className="index-main-content-container">
|
|
<h1 className="welcome-text">- 欢迎来到智慧法务平台 -</h1>
|
|
|
|
<div className="modules-container">
|
|
{/* 合同管理模块 - 51708端口时隐藏 */}
|
|
{!isPort51707 && (
|
|
<div
|
|
className="module-card"
|
|
onClick={() => handleModuleClick('/contract-template/search', 'contract')}
|
|
onKeyDown={(e) => handleKeyDown('/contract-template/search', 'contract', e)}
|
|
role="button"
|
|
tabIndex={0}
|
|
aria-label="合同管理"
|
|
>
|
|
<img src="/images/icon_hetong.png" alt="合同管理" className="w-12 h-12 mx-1" />
|
|
<span className="module-name">合同管理</span>
|
|
</div>
|
|
)}
|
|
|
|
{/* 案卷智能评查模块 */}
|
|
<div
|
|
className="module-card"
|
|
onClick={() => handleModuleClick('/home', 'record')}
|
|
onKeyDown={(e) => handleKeyDown('/home', 'record', e)}
|
|
role="button"
|
|
tabIndex={0}
|
|
aria-label="案卷智能评查"
|
|
>
|
|
<img src="/images/icon_anjuan.png" alt="案卷智能评查" className="w-12 h-12" />
|
|
<span className="module-name">案卷智能评查</span>
|
|
</div>
|
|
|
|
{/* 智慧法务大模型模块 */}
|
|
<div
|
|
className="module-card"
|
|
onClick={() => handleModuleClick('/chat-with-llm', 'model')}
|
|
onKeyDown={(e) => handleKeyDown('/chat-with-llm', 'model', e)}
|
|
role="button"
|
|
tabIndex={0}
|
|
aria-label="智慧法务大模型"
|
|
>
|
|
<img src="/images/icon_assistant.png" alt="智慧法务大模型" className="w-12 h-12" />
|
|
<span className="module-name">智慧法务大模型</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
);
|
|
} |