From 960be02e5df56cb3f6d180fa5e75084fb0b50e65 Mon Sep 17 00:00:00 2001 From: atangccc <2199287121@qq.com> Date: Fri, 26 Jun 2026 10:38:25 +0800 Subject: [PATCH] =?UTF-8?q?=E9=83=A8=E5=88=86=E7=AB=99=E7=82=B9=E5=B8=8C?= =?UTF-8?q?=E6=9C=9B=E5=8C=BF=E5=90=8D=E8=AF=84=E8=AE=BA=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E5=A4=B4=E5=83=8F=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=EF=BC=8C=E4=BE=8B=E5=A6=82=E9=9A=8F=E6=9C=BA=E5=A4=B4=E5=83=8F?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=88=96=E7=AB=99=E7=82=B9=E8=87=AA=E5=BB=BA?= =?UTF-8?q?=E5=A4=B4=E5=83=8F=E6=9C=8D=E5=8A=A1=EF=BC=8C=E5=90=8C=E6=97=B6?= =?UTF-8?q?=E4=BF=9D=E7=95=99=E5=B7=B2=E7=99=BB=E5=BD=95=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=9A=84=E7=9C=9F=E5=AE=9E=E5=A4=B4=E5=83=8F=E3=80=82=E5=BD=93?= =?UTF-8?q?=E5=89=8D=E6=8F=92=E4=BB=B6=E5=8F=AA=E6=9C=89=20Gravatar=20prov?= =?UTF-8?q?ider=EF=BC=8C=E4=B8=94Dicebear=E5=A4=B4=E5=83=8F=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E5=AF=B9=E4=BA=8E=E5=A4=A7=E9=83=A8=E5=88=86=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E7=BD=91=E7=BB=9C=E4=B8=8D=E6=98=AF=E5=BE=88=E5=8F=8B?= =?UTF-8?q?=E5=A5=BD=EF=BC=8C=E4=B8=8D=E5=A4=AA=E7=A8=B3=E5=AE=9A=EF=BC=8C?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E7=81=B5=E6=B4=BB=E9=85=8D=E7=BD=AE=E8=BF=99?= =?UTF-8?q?=E7=B1=BB=E5=8C=BF=E5=90=8D=E5=A4=B4=E5=83=8F=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E3=80=82=E6=96=B0=E5=A2=9E=E8=87=AA=E5=AE=9A=E4=B9=89=E5=8C=BF?= =?UTF-8?q?=E5=90=8D=E5=A4=B4=E5=83=8F=E6=9C=8D=E5=8A=A1=E6=8F=90=E4=BE=9B?= =?UTF-8?q?=E8=80=85=EF=BC=8C=E7=94=A8=E4=BA=8E=E8=A7=A3=E5=86=B3=E5=BD=93?= =?UTF-8?q?=E5=89=8D=E8=AF=84=E8=AE=BA=E7=BB=84=E4=BB=B6=E4=BB=85=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20Gravatar=20=E7=9A=84=E9=99=90=E5=88=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/avatar/providers/custom.ts | 22 +++++++++++++++++++ .../src/avatar/providers/index.ts | 6 +++++ packages/comment-widget/src/types/index.ts | 2 +- src/main/resources/extensions/settings.yaml | 4 +++- 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 packages/comment-widget/src/avatar/providers/custom.ts diff --git a/packages/comment-widget/src/avatar/providers/custom.ts b/packages/comment-widget/src/avatar/providers/custom.ts new file mode 100644 index 0000000..611ff8e --- /dev/null +++ b/packages/comment-widget/src/avatar/providers/custom.ts @@ -0,0 +1,22 @@ +import AvatarProvider from './avatar-provider'; + +const seedPlaceholderPattern = /\{(?:hash|seed)\}/; + +class CustomAvatar extends AvatarProvider { + override getAvatarSrc(emailHash: string | undefined): string { + const source = this.url.trim(); + const seed = encodeURIComponent(emailHash || 'anonymous'); + + if (!source) { + return ''; + } + + if (seedPlaceholderPattern.test(source)) { + return source.replace(/\{hash\}/g, seed).replace(/\{seed\}/g, seed); + } + + return `${source}${source.includes('?') ? '&' : '?'}_avatar=${seed}`; + } +} + +export default new CustomAvatar('Custom', ''); diff --git a/packages/comment-widget/src/avatar/providers/index.ts b/packages/comment-widget/src/avatar/providers/index.ts index c2151de..851e6ae 100644 --- a/packages/comment-widget/src/avatar/providers/index.ts +++ b/packages/comment-widget/src/avatar/providers/index.ts @@ -1,14 +1,20 @@ import type AvatarProvider from './avatar-provider'; +import Custom from './custom'; import Gravatar from './gravatar'; let avatarProvider: AvatarProvider | undefined; enum AvatarProviderEnum { + CUSTOM = 'custom', GRAVATAR = 'gravatar', } export function setAvatarProvider(provider: string, mirrorUrl?: string) { switch (provider) { + case AvatarProviderEnum.CUSTOM: + Custom.url = mirrorUrl || ''; + avatarProvider = Custom; + break; case AvatarProviderEnum.GRAVATAR: if (mirrorUrl) { Gravatar.url = mirrorUrl; diff --git a/packages/comment-widget/src/types/index.ts b/packages/comment-widget/src/types/index.ts index 6854bef..aebd8f1 100644 --- a/packages/comment-widget/src/types/index.ts +++ b/packages/comment-widget/src/types/index.ts @@ -25,7 +25,7 @@ interface SecurityConfig { } interface AvatarConfig { - provider: 'gravatar'; + provider: 'custom' | 'gravatar'; enable: boolean; providerMirror: string; policy: 'anonymousUser' | 'allUser' | 'noAvatarUser'; diff --git a/src/main/resources/extensions/settings.yaml b/src/main/resources/extensions/settings.yaml index 9fbfe42..b2f0a10 100644 --- a/src/main/resources/extensions/settings.yaml +++ b/src/main/resources/extensions/settings.yaml @@ -120,6 +120,8 @@ spec: if: "$get(enable).value === true" name: provider options: + - label: "自定义头像服务" + value: "custom" - label: "Gravatar" value: "gravatar" value: "gravatar" @@ -128,7 +130,7 @@ spec: if: "$get(enable).value === true" name: providerMirror value: "" - help: 使用官方源则留空, 示例:https://gravatar.com + help: 自定义头像服务支持 {hash} 或 {seed} 占位符;不填写占位符时会自动追加 _avatar 参数。Gravatar 示例:https://gravatar.com - $formkit: select label: 头像策略 if: "$get(enable).value === true"