diff --git a/frontend-web/src/components/workspace/user-identity-badge.tsx b/frontend-web/src/components/workspace/user-identity-badge.tsx new file mode 100644 index 00000000..5929040e --- /dev/null +++ b/frontend-web/src/components/workspace/user-identity-badge.tsx @@ -0,0 +1,54 @@ +"use client"; + +import { User } from "lucide-react"; +import { useMemo } from "react"; + +import { getStoredAuth } from "@/core/auth"; +import { useMyPosition } from "@/core/positions"; +import { cn } from "@/lib/utils"; +import { readUserInfo } from "@/strategy-components/lib/light-app"; + +/** + * 名称 + 岗位 用户标识。全量模式由 strategy-components/Header.tsx 顶栏右侧展示; + * 紧凑模式(不带全局顶栏)无处承载,故抽成共享组件,复用同一套数据来源 + * (`readUserInfo().userName` 优先、回退 auth 邮箱前缀;岗位取 `useMyPosition`), + * 供页面级顶栏(如 ChatPage)右侧复用,保证两套布局一致。 + * + * 配色按当前内容区前景色(foreground / muted-foreground),适配聊天页浅底顶栏, + * 而非 Header 的白字贴 banner 方案。 + */ +export function UserIdentityBadge({ className }: { className?: string }) { + const auth = getStoredAuth(); + const { data: myPosition } = useMyPosition(); + const positionName = myPosition?.name?.trim() || ""; + + // 与 Header.tsx 一致:外部登录写入的真实用户名优先,缺省回退邮箱前缀。 + const displayName = useMemo(() => { + const info = readUserInfo(); + const name = typeof info.userName === "string" ? info.userName.trim() : ""; + if (name) return name; + const email = auth?.email?.trim(); + return email ? email.split("@")[0] : "用户"; + }, [auth?.email]); + + return ( +
+ {displayName} +
+ {positionName && ( ++ {positionName} +
+ )} +