58 lines
1.5 KiB
TypeScript
58 lines
1.5 KiB
TypeScript
import React, { useMemo } from "react";
|
||
import { Avatar } from "antd";
|
||
import { AvatarProps } from "antd/lib/avatar";
|
||
import multiavatar from "@multiavatar/multiavatar";
|
||
|
||
interface CustomAvatarProps extends Omit<AvatarProps, "children"> {
|
||
src?: string;
|
||
name?: string;
|
||
ip?: string;
|
||
}
|
||
|
||
export function CustomAvatar({
|
||
src,
|
||
name,
|
||
className = "",
|
||
ip,
|
||
...props
|
||
}: CustomAvatarProps) {
|
||
// 获取名字的第一个字符,如果没有名字则显示"匿"
|
||
const firstChar = name ? name.charAt(0) : "匿";
|
||
|
||
// 如果没有 src,且 name 不存在或为 "匿名用户",则使用 ip 生成随机头像
|
||
const generateAvatarFromIp = (ip: string) => {
|
||
// 使用 multiavatar 生成 SVG 字符串
|
||
const svgString = multiavatar(ip);
|
||
return `data:image/svg+xml;utf8,${encodeURIComponent(svgString)}`;
|
||
};
|
||
// 判断头像模式
|
||
const avatarMode = useMemo(() => {
|
||
if (src) {
|
||
return "avatar"; // 使用 src 提供的头像
|
||
}
|
||
if (name && name !== "匿名用户") {
|
||
return "name"; // 使用名称的首字母
|
||
}
|
||
return "random"; // 使用随机头像(基于 ip)
|
||
}, [src, name]);
|
||
// 判断是否需要使用 ip 生成头像
|
||
const avatarSrc =
|
||
src || (name && name !== "匿名用户")
|
||
? src
|
||
: generateAvatarFromIp(ip || "default");
|
||
|
||
return (
|
||
<Avatar
|
||
className={`
|
||
${avatarMode ? "bg-primary-300text-white" : ""}
|
||
|
||
transition-all duration-200 ease-in-out shadow-md
|
||
hover:shadow-lg
|
||
${className}`}
|
||
src={avatarSrc}
|
||
{...props}>
|
||
{!avatarSrc && firstChar}
|
||
</Avatar>
|
||
);
|
||
}
|