fix(header): fix userIcon

This commit is contained in:
zhangheng
2026-04-22 16:18:26 +08:00
parent 4311cd67eb
commit 81c9f1d165
2 changed files with 108 additions and 5 deletions

View File

@@ -17,8 +17,10 @@ import {
useComputedColorScheme,
useMantineColorScheme,
} from "@mantine/core"
import Avvvatars from "avvvatars-react"
import { useDisclosure, useMediaQuery } from "@mantine/hooks"
import { IconLogout, IconMoon, IconSun, IconUser } from "@tabler/icons-react"
import { IconLogout, IconMoon, IconSun } from "@tabler/icons-react"
import cx from "clsx"
import { Suspense, useEffect, useMemo, useState } from "react"
import actionToggleClasses from "./ActionToggle.module.css"
@@ -33,6 +35,103 @@ import { ClientIcon } from "./components/ClientIcon"
import { LinksGroup } from "./components/NavbarLinks"
import { useAppLayoutStore } from "./store"
const COMPOUND_SURNAMES = new Set([
"欧阳",
"太史",
"端木",
"上官",
"司马",
"东方",
"独孤",
"南宫",
"万俟",
"闻人",
"夏侯",
"诸葛",
"尉迟",
"公羊",
"赫连",
"澹台",
"皇甫",
"宗政",
"濮阳",
"公冶",
"太叔",
"申屠",
"公孙",
"慕容",
"仲孙",
"钟离",
"长孙",
"宇文",
"司徒",
"鲜于",
"司空",
"闾丘",
"子车",
"亓官",
"司寇",
"巫马",
"公西",
"颛孙",
"壤驷",
"公良",
"漆雕",
"乐正",
"宰父",
"谷梁",
"拓跋",
"轩辕",
"令狐",
"段干",
"百里",
"呼延",
"东郭",
"南门",
"羊舌",
"微生",
"梁丘",
"左丘",
"东门",
"西门",
"南荣",
"第五",
])
function isChineseName(value: string) {
return /[\u4e00-\u9fff]/.test(value)
}
function getAvatarDisplayValue(rawValue?: string | null) {
const value = rawValue?.trim() ?? ""
if (!value) return "-"
if (isChineseName(value)) {
const normalized = value.replace(/[\s·•・・]/g, "")
if (normalized.length <= 1) return normalized
const surnameLength =
normalized.length >= 3 && COMPOUND_SURNAMES.has(normalized.slice(0, 2))
? 2
: 1
const givenName = normalized.slice(surnameLength)
if (!givenName) return normalized.slice(-1)
if (givenName.length <= 2) return givenName
return givenName.slice(-2)
}
const tokens = value.split(/[\s-_]+/).filter(Boolean)
if (tokens.length >= 2) {
return `${tokens[0][0] ?? ""}${tokens[tokens.length - 1][0] ?? ""}`
.trim()
.toUpperCase()
}
return value.slice(0, 2).toUpperCase()
}
export default function AppLayout({
menu,
children,
@@ -144,6 +243,10 @@ export default function AppLayout({
}
const matches = useMediaQuery("(min-width: 48em)")
const userName = usePermissionStore((s) => s.user_name)
const avatarDisplayValue = useMemo(
() => getAvatarDisplayValue(userName),
[userName]
)
return isClient ? (
withoutLayout ? (
@@ -199,10 +302,9 @@ export default function AppLayout({
<Menu shadow="md" width={220}>
<Menu.Target>
<UnstyledButton>
<IconUser
style={{ display: "block" }}
size={22}
stroke={1.5}
<Avvvatars
value={userName || "-"}
displayValue={avatarDisplayValue}
/>
</UnstyledButton>
</Menu.Target>

View File

@@ -41,6 +41,7 @@
"@tiptap/react": "^3.15.3",
"@tiptap/starter-kit": "^3.15.3",
"@tmcw/togeojson": "^7.1.2",
"avvvatars-react": "^0.4.2",
"classnames": "^2.5.1",
"clsx": "^2.1.1",
"dayjs": "^1.11.18",