feat: 更新SproutGate前后端代码
This commit is contained in:
61
sproutgate-frontend/src/avatar.js
Normal file
61
sproutgate-frontend/src/avatar.js
Normal file
@@ -0,0 +1,61 @@
|
||||
/** 纯数字 @qq.com(大小写不敏感)→ QQ 号码,用于与后端一致的展示逻辑 */
|
||||
|
||||
export function qqUinFromEmail(email) {
|
||||
if (!email || typeof email !== "string") return "";
|
||||
const e = email.trim().toLowerCase();
|
||||
const at = e.lastIndexOf("@");
|
||||
if (at <= 0 || at >= e.length - 1) return "";
|
||||
const local = e.slice(0, at);
|
||||
const domain = e.slice(at + 1);
|
||||
if (domain !== "qq.com" || !local) return "";
|
||||
if (!/^\d+$/.test(local)) return "";
|
||||
return local;
|
||||
}
|
||||
|
||||
export function qqUinFromUser(user) {
|
||||
if (!user || typeof user !== "object") return "";
|
||||
const primary = qqUinFromEmail(user.email);
|
||||
if (primary) return primary;
|
||||
for (const em of user.secondaryEmails || []) {
|
||||
const u = qqUinFromEmail(em);
|
||||
if (u) return u;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/** 与后端 ResolvedAvatarURL 一致的三档 QQ CDN(依次作为 img onError 回退) */
|
||||
export function qqAvatarUrlCandidates(uin) {
|
||||
if (!uin) return [];
|
||||
return [
|
||||
`https://q.qlogo.cn/headimg_dl?dst_uin=${encodeURIComponent(uin)}&spec=640&img_type=jpg`,
|
||||
`https://q1.qlogo.cn/g?b=qq&nk=${encodeURIComponent(uin)}&s=100`,
|
||||
`https://q2.qlogo.cn/headimg_dl?dst_uin=${encodeURIComponent(uin)}&spec=100`
|
||||
];
|
||||
}
|
||||
|
||||
export function placeholderAvatarUrl(size) {
|
||||
return `https://dummyimage.com/${size}x${size}/ddd/fff&text=Avatar`;
|
||||
}
|
||||
|
||||
/** 用于 <img src>:自选链接优先,否则 QQ 邮箱推断的多 CDN,否则 API 下发的 avatarUrl,最后占位图 */
|
||||
export function avatarImageCandidates(user, placeholderSize = 120) {
|
||||
const custom = (user?.customAvatarUrl != null && String(user.customAvatarUrl).trim()) || "";
|
||||
if (custom) return [custom];
|
||||
const uin = qqUinFromUser(user);
|
||||
if (uin) return qqAvatarUrlCandidates(uin);
|
||||
const resolved = (user?.avatarUrl != null && String(user.avatarUrl).trim()) || "";
|
||||
if (resolved) return [resolved];
|
||||
return [placeholderAvatarUrl(placeholderSize)];
|
||||
}
|
||||
|
||||
export function resolveDisplayAvatarUrl(user, placeholderSize = 120) {
|
||||
const c = avatarImageCandidates(user, placeholderSize);
|
||||
return c[0] || placeholderAvatarUrl(placeholderSize);
|
||||
}
|
||||
|
||||
export function avatarStatusLabel(user) {
|
||||
const custom = (user?.customAvatarUrl != null && String(user.customAvatarUrl).trim()) || "";
|
||||
if (custom) return "已设置";
|
||||
if (qqUinFromUser(user)) return "QQ 邮箱头像";
|
||||
return "未填写";
|
||||
}
|
||||
Reference in New Issue
Block a user