feat: 媒体库 blob 去重存储与品牌/注册等前端调整

新增:
- blob_store 二进制去重存储 + blob_dedup 测试

其它:
- 后端 settings/auth/media_library/upload/operations 服务与 handler 调整
- 前端品牌(BrandLockup/BrandCropModal/BrandSeoPanel)、注册、媒体库、分析详情页、Header/SiteChrome 等更新
This commit is contained in:
2026-10-03 02:38:11 +08:00
parent 8cfdfcbbf0
commit 46e0cdc0b3
32 changed files with 1242 additions and 228 deletions

View File

@@ -24,6 +24,9 @@ import (
type mailPayload struct{ To, Subject, Body string }
// ErrEmailRegistered 注册发码时邮箱已被占用,handler 据此返回 400 业务提示
var ErrEmailRegistered = errors.New("该邮箱已被注册,请直接登录")
func (o *Operations) smtp(ctx context.Context, c MailConfig, p *mailPayload, id string) error {
password, e := o.open(c.Password, "mail:password")
if e != nil {
@@ -392,6 +395,16 @@ func (o *Operations) SendCode(email, purpose, ip string) (int, error) {
return 0, nil
}
}
if purpose == "register" {
// 入口拦截:邮箱已被占用则不发码,省一次邮件资源,也给用户明确提示
var n int64
if e = o.db.Model(&model.User{}).Where("LOWER(email) = ?", email).Count(&n).Error; e != nil {
return 0, e
}
if n > 0 {
return 0, ErrEmailRegistered
}
}
code := randomCode()
hash := counterKey(email + ":" + purpose + ":" + code)
e = o.db.Transaction(func(tx *gorm.DB) error {