feat(auth): 注册服务协议 - 名称与条款改为后台可配置并同步注册页展示

后端:
- RegistrationSettingRequest 协议字段改为可选指针,注册开关单独保存不再覆盖协议正文
- 新增 RegistrationAgreement / AgreementTitleForMessage:标题未配置时跟随品牌名生成,读取失败返回空标题而非猜一个不存在的协议名
- PublicAuthSettings 下发 agreementTitle / agreementContent,首用户分支同样携带
- 新增 registration_agreement_test.go 覆盖品牌名兜底、存储合并与失败降级

前端:
- 注册页协议标题与条款改为消费后台配置;读取失败时隐藏协议入口并支持重新读取
- 验证码获取按钮内联到输入框右侧,联系方式为空即禁用;sms_email 双通道合并为单输入框
- 协议弹窗重排:条目标题独立成行加重、空态虚线提示、底部补充同意说明;深浅主题适配
- 协议勾选行改为状态化区域,复选框适配 AntD 6 结构(方框在 .ant-checkbox 本体,修正深色主题白底白勾)
- 后台「服务协议名称与条款」区块补齐表单内边距并对齐区块头/页脚,协议名称限宽

文档:http-api.mdx 更新协议字段语义与失败降级说明;pending-test.mdx 增加手工验证清单
This commit is contained in:
✨await committed 2026-09-24 16:56:44 +08:00
1 parent abf593c6c9
commit 672bb0be73
16 files changed
+977 -74

No files matched your search

+26 -10
View File
@@ -47,13 +47,15 @@ type LoginRequest struct {
type PublicAuthSettings struct {
VerificationPolicy
SMSBindingAvailable bool `json:"smsBindingAvailable"`
EmailBindingAvailable bool `json:"emailBindingAvailable"`
FirstUser bool `json:"firstUser"`
RegistrationEnabled bool `json:"registrationEnabled"`
LinuxDOEnabled bool `json:"linuxdoEnabled"`
EmailEnabled bool `json:"emailEnabled"`
EmailCodeRequired bool `json:"emailCodeRequired"`
SMSBindingAvailable bool `json:"smsBindingAvailable"`
EmailBindingAvailable bool `json:"emailBindingAvailable"`
FirstUser bool `json:"firstUser"`
RegistrationEnabled bool `json:"registrationEnabled"`
LinuxDOEnabled bool `json:"linuxdoEnabled"`
EmailEnabled bool `json:"emailEnabled"`
EmailCodeRequired bool `json:"emailCodeRequired"`
AgreementTitle string `json:"agreementTitle,omitempty"`
AgreementContent string `json:"agreementContent,omitempty"`
}
type AuthSessionResult struct {
@@ -76,7 +78,9 @@ func (s *Service) PublicAuthSettings() (*PublicAuthSettings, error) {
return nil, err
}
if count == 0 {
return &PublicAuthSettings{FirstUser: true, RegistrationEnabled: true, LinuxDOEnabled: false}, nil
// 首个管理员同样要看到服务协议,不能因为跳过注册校验就丢失协议字段。
agreementTitle, agreementContent := s.RegistrationAgreement()
return &PublicAuthSettings{FirstUser: true, RegistrationEnabled: true, LinuxDOEnabled: false, AgreementTitle: agreementTitle, AgreementContent: agreementContent}, nil
}
registrationEnabled, err := s.RegistrationEnabled()
if err != nil {
@@ -107,12 +111,24 @@ func (s *Service) PublicAuthSettings() (*PublicAuthSettings, error) {
p.SMSRegistration = p.SMSRegistration && smsRegister
p.EmailRegistration = p.EmailRegistration && emailEnabled
p.SMSAndEmailRegistration = p.SMSAndEmailRegistration && smsRegister && emailEnabled
return &PublicAuthSettings{VerificationPolicy: p, SMSBindingAvailable: smsBind, EmailBindingAvailable: emailEnabled, FirstUser: false, RegistrationEnabled: registrationEnabled, LinuxDOEnabled: s.LinuxDOEnabled(), EmailEnabled: emailEnabled, EmailCodeRequired: p.EmailRegistration || p.SMSAndEmailRegistration}, nil
agreementTitle, agreementContent := s.RegistrationAgreement()
return &PublicAuthSettings{
VerificationPolicy: p,
SMSBindingAvailable: smsBind,
EmailBindingAvailable: emailEnabled,
FirstUser: false,
RegistrationEnabled: registrationEnabled,
LinuxDOEnabled: s.LinuxDOEnabled(),
EmailEnabled: emailEnabled,
EmailCodeRequired: p.EmailRegistration || p.SMSAndEmailRegistration,
AgreementTitle: agreementTitle,
AgreementContent: agreementContent,
}, nil
}
func (s *Service) Register(req RegisterRequest) (*AuthSessionResult, error) {
if !req.AcceptedTerms {
return nil, kernel.BadAuthRequest("请先同意影策服务协议")
return nil, kernel.BadAuthRequest("请先同意" + s.AgreementTitleForMessage())
}
username := NormalizeUsername(req.Username)
email := NormalizeEmail(req.Email)