feat: Web端401队列拦截器 + 消息/任务/个人中心重写 + TabBar红点 + Admin页面完善

This commit is contained in:
2026-08-07 11:44:12 +08:00
parent b71c5a2d07
commit 721cfe1504
25 changed files with 1730 additions and 435 deletions

View File

@ -1,35 +1,71 @@
/** 我的 — 个人中心 */
/** 我的 — 1:1 复刻 uni-app pages/profile/index.vue + 真实用户数据绑定 */
import { useNavigate } from "react-router-dom";
import { useAuth } from "../contexts/AuthContext";
import { LogOut } from "lucide-react";
export default function ProfilePage() {
const { user, logout } = useAuth();
const navigate = useNavigate();
// ---- 从 AuthContext 派生真实数据 ----
const displayName = user?.display_name || user?.username || "未知用户";
const avatarChar = displayName.charAt(0);
const roleLabel =
user?.role === "SUPER_ADMIN"
? "超级管理员"
: user?.role || "操作员";
function handleLogout() {
logout();
navigate("/admin/login", { replace: true });
}
return (
<div className="flex min-h-full flex-col px-4 pt-safe">
{/* 用户信息卡片 */}
<div className="mt-4 flex items-center gap-4 rounded-xl bg-white p-4 shadow-sm">
<div className="flex h-14 w-14 items-center justify-center rounded-full bg-blue-100 text-xl font-bold text-blue-600">
张
<div className="flex min-h-full flex-col px-4 pt-safe pb-20">
{/* 用户卡片 — 与 uni-app user-card 完全一致 */}
<div className="mt-4 flex items-center gap-3 rounded-xl bg-white p-4 shadow-[0_1px_3px_rgba(0,0,0,0.06)]">
{/* 头像 — 取真实用户名的第一个字 */}
<div className="flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-blue-100 text-xl font-bold text-blue-600">
{avatarChar}
</div>
<div className="flex-1">
<h3 className="font-semibold text-gray-800">张三</h3>
<p className="text-sm text-gray-500">操作员</p>
<span className="block text-base font-bold text-gray-800">
{displayName}
</span>
<span className="text-xs text-gray-400">{roleLabel}</span>
</div>
<svg className="h-5 w-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
<span className="text-xl text-gray-300">›</span>
</div>
{/* 菜单列表占位 */}
<div className="mt-6 space-y-1 rounded-xl bg-white shadow-sm">
{["工作统计", "设置", "帮助与反馈", "关于"].map((item) => (
{/* 菜单列表 — 与 uni-app menu-card 完全一致 */}
<div className="mt-4 overflow-hidden rounded-xl bg-white shadow-[0_1px_3px_rgba(0,0,0,0.06)]">
{["工作统计", "设置", "帮助与反馈", "关于"].map((item, i) => (
<div
key={item}
className="flex items-center justify-between border-b border-gray-50 px-4 py-3 last:border-b-0"
className={`flex items-center justify-between px-4 py-3.5 ${
i < 3 ? "border-b border-gray-50" : ""
}`}
>
<span className="text-sm text-gray-700">{item}</span>
<svg className="h-4 w-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
<span className="text-xl text-gray-300">›</span>
</div>
))}
{/* 退出登录 — 红色高亮 */}
<button
onClick={handleLogout}
className="flex w-full items-center justify-between border-t border-gray-50 px-4 py-3.5 transition-colors hover:bg-red-50"
>
<span className="flex items-center gap-2 text-sm text-red-500">
<LogOut size={16} strokeWidth={2} />
退出登录
</span>
<span className="text-xl text-red-300">›</span>
</button>
</div>
{/* 版本号 — 与 uni-app .version 一致 */}
<p className="mt-8 text-center text-xs text-gray-300">生产流转 v1.0.0</p>
</div>
);
}