feat: 添加独立其他设置菜单及有效端参数保存
This commit is contained in:
+1
-1
@@ -11,4 +11,4 @@ import (
|
||||
)
|
||||
|
||||
// ProviderSet is biz providers.
|
||||
var ProviderSet = wire.NewSet(system.ProviderSet, payment.ProviderSet, integration.ProviderSet, task.ProviderSet, business.NewUserPreferenceUsecase, business.NewAccountUsecase, business.NewBindingUsecase, business.NewPasswordResetUsecase, business.NewBusinessPromoteUsecase, business.NewAlertRuleUsecase, business.NewAlertRecordUsecase, business.NewActivationUsecase, business.NewChannelUsecase, business.NewBusinessPortraitUsecase, business.NewChannelPortraitUsecase, business.NewLedgerUsecase, business.NewAnalyticsUsecase, business.NewServerAnalysisUsecase, business.NewWorkbenchUsecase, business.NewRankingUsecase, business.NewReportBuildUsecase, business.NewAlertTriggerUsecase)
|
||||
var ProviderSet = wire.NewSet(system.ProviderSet, payment.ProviderSet, integration.ProviderSet, task.ProviderSet, business.NewUserPreferenceUsecase, business.NewOtherSettingsUsecase, business.NewAccountUsecase, business.NewBindingUsecase, business.NewPasswordResetUsecase, business.NewBusinessPromoteUsecase, business.NewAlertRuleUsecase, business.NewAlertRecordUsecase, business.NewActivationUsecase, business.NewChannelUsecase, business.NewBusinessPortraitUsecase, business.NewChannelPortraitUsecase, business.NewLedgerUsecase, business.NewAnalyticsUsecase, business.NewServerAnalysisUsecase, business.NewWorkbenchUsecase, business.NewRankingUsecase, business.NewReportBuildUsecase, business.NewAlertTriggerUsecase)
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package business
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/go-kratos/kratos/v3/errors"
|
||||
"kra/internal/biz/system"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrOtherSettingsScope = errors.Forbidden("SW_OTHER_SETTINGS_SCOPE", "仅超级管理员可以查看和修改其他设置")
|
||||
ErrOtherSettingsInput = errors.BadRequest("SW_OTHER_SETTINGS_INPUT", "达标金额须为不小于0的整数,判定窗口须为不小于1的整数,且不能超过安全整数范围")
|
||||
ErrOtherSettingsStored = errors.BadRequest("SW_OTHER_SETTINGS_STORED", "已保存的设置格式不正确,请恢复默认后重新保存")
|
||||
)
|
||||
|
||||
const MaxSettingsInteger int64 = 9007199254740991
|
||||
|
||||
type OtherSettings struct {
|
||||
Amount, Days int64
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
func DefaultOtherSettings() OtherSettings { return OtherSettings{Amount: 3000, Days: 30} }
|
||||
|
||||
func ValidateOtherSettings(value OtherSettings) error {
|
||||
if value.Amount < 0 || value.Amount > MaxSettingsInteger || value.Days < 1 || value.Days > MaxSettingsInteger {
|
||||
return ErrOtherSettingsInput
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type OtherSettingsRepo interface {
|
||||
Find(context.Context) (*OtherSettings, error)
|
||||
Save(context.Context, OtherSettings) (*OtherSettings, error)
|
||||
}
|
||||
|
||||
type OtherSettingsUsecase struct{ repo OtherSettingsRepo }
|
||||
|
||||
func NewOtherSettingsUsecase(repo OtherSettingsRepo) *OtherSettingsUsecase {
|
||||
return &OtherSettingsUsecase{repo: repo}
|
||||
}
|
||||
|
||||
func requireSettingsAdmin(ctx context.Context) error {
|
||||
actor, ok := system.ActorFromContext(ctx)
|
||||
if !ok || actor.UserID == 0 {
|
||||
return ErrUnauthenticated
|
||||
}
|
||||
if actor.AuthorityID != system.SuperAdminAuthorityID {
|
||||
return ErrOtherSettingsScope
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (uc *OtherSettingsUsecase) Get(ctx context.Context) (*OtherSettings, error) {
|
||||
if err := requireSettingsAdmin(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
value, err := uc.repo.Find(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if value == nil {
|
||||
defaults := DefaultOtherSettings()
|
||||
return &defaults, nil
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func (uc *OtherSettingsUsecase) Save(ctx context.Context, value OtherSettings) (*OtherSettings, error) {
|
||||
if err := requireSettingsAdmin(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := ValidateOtherSettings(value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uc.repo.Save(ctx, value)
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package business
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type otherSettingsFake struct {
|
||||
value *OtherSettings
|
||||
calls int
|
||||
}
|
||||
|
||||
func (r *otherSettingsFake) Find(context.Context) (*OtherSettings, error) {
|
||||
r.calls++
|
||||
return r.value, nil
|
||||
}
|
||||
func (r *otherSettingsFake) Save(_ context.Context, value OtherSettings) (*OtherSettings, error) {
|
||||
r.calls++
|
||||
r.value = &value
|
||||
return r.value, nil
|
||||
}
|
||||
|
||||
func TestOtherSettingsOnlySuperAdminAndDefaults(t *testing.T) {
|
||||
r := &otherSettingsFake{}
|
||||
uc := NewOtherSettingsUsecase(r)
|
||||
for _, ctx := range []context.Context{context.Background(), accountContext(7, 901), accountContext(8, 902), accountContext(9, 903)} {
|
||||
if _, err := uc.Get(ctx); err == nil {
|
||||
t.Fatal("非超管不能读取设置")
|
||||
}
|
||||
if _, err := uc.Save(ctx, DefaultOtherSettings()); err == nil {
|
||||
t.Fatal("非超管不能保存设置")
|
||||
}
|
||||
}
|
||||
if r.calls != 0 {
|
||||
t.Fatal("无权限请求不得访问存储")
|
||||
}
|
||||
value, err := uc.Get(accountContext(1, 888))
|
||||
if err != nil || *value != DefaultOtherSettings() {
|
||||
t.Fatalf("首次读取应返回默认值: %+v %v", value, err)
|
||||
}
|
||||
if _, err := uc.Save(accountContext(1, 888), OtherSettings{Amount: 0, Days: 1}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
value, err = uc.Get(accountContext(2, 888))
|
||||
if err != nil || value.Amount != 0 || value.Days != 1 {
|
||||
t.Fatal("参数应为全站共享,不能按用户各存一份")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOtherSettingsRejectInvalidRange(t *testing.T) {
|
||||
uc := NewOtherSettingsUsecase(&otherSettingsFake{})
|
||||
for _, value := range []OtherSettings{{Amount: -1, Days: 30}, {Amount: 3000, Days: 0}, {Amount: MaxSettingsInteger + 1, Days: 30}, {Amount: 3000, Days: MaxSettingsInteger + 1}} {
|
||||
if _, err := uc.Save(accountContext(1, 888), value); err != ErrOtherSettingsInput {
|
||||
t.Fatalf("不应保存非法值: %+v %v", value, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user