Files
cwd/cwd-api/src/utils/getAvatar.ts
anghunk 55af0ed516 fix(头像生成): 当邮箱为空时使用昵称生成头像哈希
修复 getCravatar 函数在邮箱为空时无法生成有效头像的问题。现在当邮箱为空或不存在时,函数会尝试使用昵称作为替代标识符生成 MD5 哈希。如果两者都不可用,则返回默认占位符头像,确保始终返回有效的头像 URL。
2026-01-28 13:35:32 +08:00

42 lines
1.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 默认 gravatar.com 前缀
*/
const DEFAULT_AVATAR_PREFIX = 'https://gravatar.com/avatar';
/**
* 当缺少邮箱或邮箱为空时使用的占位 hash
* 32 个 0符合 MD5 长度要求Gravatar 会回退到默认头像样式
*/
const DEFAULT_AVATAR_HASH = '00000000000000000000000000000000';
/**
* 辅助函数:生成 gravatar.com 头像地址 (MD5 算法)
* 优先使用邮箱;当邮箱不存在或为空时,使用昵称计算 MD5。
*/
export const getCravatar = async (
email: string | null | undefined,
name?: string | null | undefined,
prefix?: string
): Promise<string> => {
const avatarPrefix = prefix || DEFAULT_AVATAR_PREFIX;
const pickIdentifier = (value: string | null | undefined) => {
if (!value || typeof value !== 'string') return null;
const trimmed = value.trim().toLowerCase();
return trimmed || null;
};
const identifier = pickIdentifier(email) || pickIdentifier(name);
if (!identifier) {
return `${avatarPrefix}/${DEFAULT_AVATAR_HASH}?s=200&d=retro`;
}
const msgUint8 = new TextEncoder().encode(identifier);
const hashBuffer = await crypto.subtle.digest('MD5', msgUint8);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
return `${avatarPrefix}/${hashHex}?s=200&d=retro`;
};