33b4c734aa
后端: - 新增认证(auth)、任务(tasks)、映射(mappings)、对账(reconciliation)、异常(exceptions)、导出(exports) API - 新增核心模块: database, security, permissions, tenant, exceptions, error_handlers - 新增数据模型: user, company, reconciliation_task, field_mapping, uploaded_file 等 - 新增服务层: ai_recognizer, file_parser, file_storage, mapping, reconciliation 等 - 添加数据库迁移脚本 前端: - 新增登录页面和仪表盘页面 - 新增任务列表、任务详情、字段映射页面 - 新增异常处理页面和规则设置页面 - 新增 API 代理路由 /api/[...path] - 新增 UI 组件库 (button, card, dialog, input, table 等) - 新增 auth 组件 (ProtectedRoute, PermissionGate) - 新增 layout 组件 (Header, Sidebar) - 新增 mapping 组件 (FieldMappingTable, AISuggestionPanel) - 新增 API 客户端和 hooks (useAsync, useToast, usePermission 等) - 新增状态管理 (auth-store, company-store, ui-store) - 集成 Tailwind CSS 和 shadcn/ui 组件库 其他: - 添加 Alembic 数据库迁移配置 - 添加初始化示例数据脚本 - 更新项目文档
82 lines
2.8 KiB
TypeScript
82 lines
2.8 KiB
TypeScript
"use client";
|
|
|
|
import { useRouter } from "next/navigation";
|
|
import { LogOut, User } from "lucide-react";
|
|
import { useAuthStore } from "@/lib/stores/auth-store";
|
|
import { Button } from "@/components/ui/button";
|
|
import { api } from "@/lib/api/client";
|
|
import ENDPOINTS from "@/lib/api/endpoints";
|
|
|
|
export function Header() {
|
|
const router = useRouter();
|
|
const { user, logout } = useAuthStore();
|
|
|
|
const handleLogout = async () => {
|
|
try {
|
|
// 调用后端登出接口
|
|
await api.post(ENDPOINTS.AUTH.LOGOUT);
|
|
} catch {
|
|
// 即使后端失败也清除本地状态
|
|
}
|
|
|
|
// 清除本地状态
|
|
logout();
|
|
|
|
// 跳转到登录页
|
|
router.push("/login");
|
|
};
|
|
|
|
if (!user) return null;
|
|
|
|
return (
|
|
<header className="sticky top-0 z-50 w-full border-b border-border bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
|
<div className="flex h-14 items-center justify-between px-6">
|
|
{/* 左侧 - Logo 和系统名称 */}
|
|
<div className="flex items-center gap-3">
|
|
<div className="w-8 h-8 rounded-lg bg-primary/10 flex items-center justify-center shrink-0">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width="24"
|
|
height="24"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth="2"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
className="lucide lucide-shield w-4 h-4 text-primary"
|
|
aria-hidden="true"
|
|
>
|
|
<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"></path>
|
|
</svg>
|
|
</div>
|
|
<span className="font-semibold text-foreground">财务AI助手</span>
|
|
</div>
|
|
|
|
{/* 右侧 - 用户信息和登出 */}
|
|
<div className="flex items-center gap-4">
|
|
{/* 用户信息 */}
|
|
<div className="flex items-center gap-3 text-sm">
|
|
<div className="flex items-center gap-2 px-3 py-1.5 rounded-lg bg-muted/50">
|
|
<User className="w-4 h-4 text-muted-foreground" />
|
|
<span className="font-medium text-foreground">{user.full_name}</span>
|
|
<span className="text-muted-foreground">·</span>
|
|
<span className="text-muted-foreground">{user.role}</span>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 登出按钮 */}
|
|
<Button
|
|
variant="ghost"
|
|
size="sm"
|
|
onClick={handleLogout}
|
|
className="gap-2 text-muted-foreground hover:text-foreground"
|
|
>
|
|
<LogOut className="w-4 h-4" />
|
|
<span>登出</span>
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
);
|
|
} |