feat: 接入商务用户资料和全局统计偏好

This commit is contained in:
Yvan
2026-11-03 17:44:25 +08:00
parent 89cc7761b5
commit ce4b54a2e2
39 changed files with 2562 additions and 17 deletions
+33
View File
@@ -0,0 +1,33 @@
package business
import (
"context"
"kra/internal/biz/business"
"kra/internal/service/dto"
)
type PreferenceUsecase interface {
Current(context.Context) (*business.UserPreference, error)
UpdateCurrent(context.Context, business.UserPreference) error
}
type UserPreferenceService struct{ uc PreferenceUsecase }
func NewUserPreferenceService(uc *business.UserPreferenceUsecase) *UserPreferenceService {
return &UserPreferenceService{uc: uc}
}
func (s *UserPreferenceService) Current(ctx context.Context) (*dto.UserPreferenceResponse, error) {
pref, err := s.uc.Current(ctx)
if err != nil {
return nil, err
}
return &dto.UserPreferenceResponse{IncludeSubPromote: pref.IncludeSubPromote, IDCardDedup: pref.IDCardDedup}, nil
}
func (s *UserPreferenceService) UpdateCurrent(ctx context.Context, req *dto.UserPreferenceRequest) error {
if req == nil || req.IncludeSubPromote == nil || req.IDCardDedup == nil {
return business.ErrPreferenceRequired
}
return s.uc.UpdateCurrent(ctx, business.UserPreference{IncludeSubPromote: *req.IncludeSubPromote, IDCardDedup: *req.IDCardDedup})
}
@@ -0,0 +1,42 @@
package business
import (
"context"
"kra/internal/biz/business"
"kra/internal/service/dto"
"testing"
)
type preferenceFake struct {
calls int
value business.UserPreference
}
func (f *preferenceFake) Current(context.Context) (*business.UserPreference, error) {
return &f.value, nil
}
func (f *preferenceFake) UpdateCurrent(_ context.Context, p business.UserPreference) error {
f.calls++
f.value = p
return nil
}
func TestPreferenceRequiresBothFieldsButAcceptsFalse(t *testing.T) {
f := &preferenceFake{}
s := &UserPreferenceService{uc: f}
off := false
for _, req := range []*dto.UserPreferenceRequest{nil, {}, {IncludeSubPromote: &off}, {IDCardDedup: &off}} {
if err := s.UpdateCurrent(context.Background(), req); err != business.ErrPreferenceRequired {
t.Fatalf("缺字段应被拒绝: %v", err)
}
}
if f.calls != 0 {
t.Fatal("校验失败后不应调用用例")
}
if err := s.UpdateCurrent(context.Background(), &dto.UserPreferenceRequest{IncludeSubPromote: &off, IDCardDedup: &off}); err != nil {
t.Fatal(err)
}
if f.calls != 1 || f.value.IncludeSubPromote || f.value.IDCardDedup {
t.Fatalf("false 值未完整传递: %+v", f)
}
}
+11
View File
@@ -0,0 +1,11 @@
package dto
type UserPreferenceRequest struct {
IncludeSubPromote *bool `json:"includeSubPromote"`
IDCardDedup *bool `json:"idcardDedup"`
}
type UserPreferenceResponse struct {
IncludeSubPromote bool `json:"includeSubPromote"`
IDCardDedup bool `json:"idcardDedup"`
}
+7
View File
@@ -73,6 +73,13 @@ type SwitchAuthorityRequest struct {
}
type UserResponse struct {
Level int `json:"level"`
ParentID uint `json:"parentId"`
IDPath string `json:"idPath"`
RealName string `json:"realName"`
QQNumber string `json:"qqNumber"`
BusinessStatus int `json:"businessStatus"`
RejectReason string `json:"rejectReason"`
ID uint `json:"ID"`
CreatedAt time.Time `json:"CreatedAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
+2
View File
@@ -1,6 +1,7 @@
package service
import (
businessservice "kra/internal/service/business"
integrationservice "kra/internal/service/integration"
paymentservice "kra/internal/service/payment"
systemservice "kra/internal/service/system"
@@ -11,6 +12,7 @@ import (
// ProviderSet aggregates all service modules for Wire.
var ProviderSet = wire.NewSet(
businessservice.NewUserPreferenceService,
systemservice.ProviderSet,
paymentservice.ProviderSet,
integrationservice.ProviderSet,
+1 -1
View File
@@ -40,5 +40,5 @@ func convertUser(user *system.User) *dto.UserResponse {
if user.Department != nil {
department = departmentResponse(user.Department)
}
return &dto.UserResponse{ID: user.ID, CreatedAt: user.CreatedAt, UpdatedAt: user.UpdatedAt, UUID: user.UUID, Username: user.Username, NickName: user.NickName, HeaderImg: user.HeaderImg, AuthorityID: user.AuthorityID, Authority: convertAuthority(user.Authority), Authorities: authorities, DeptID: user.DeptID, Department: department, Departments: departments, Positions: positions, Phone: user.Phone, Email: user.Email, Enable: user.Enable, OriginSetting: user.OriginSetting, PasswordUpdatedAt: user.PasswordUpdatedAt}
return &dto.UserResponse{ID: user.ID, CreatedAt: user.CreatedAt, UpdatedAt: user.UpdatedAt, UUID: user.UUID, Username: user.Username, NickName: user.NickName, HeaderImg: user.HeaderImg, AuthorityID: user.AuthorityID, Authority: convertAuthority(user.Authority), Authorities: authorities, DeptID: user.DeptID, Department: department, Departments: departments, Positions: positions, Phone: user.Phone, Email: user.Email, Enable: user.Enable, OriginSetting: user.OriginSetting, PasswordUpdatedAt: user.PasswordUpdatedAt, Level: user.Level, ParentID: user.ParentID, IDPath: user.IDPath, RealName: user.RealName, QQNumber: user.QQNumber, BusinessStatus: user.BusinessStatus, RejectReason: user.RejectReason}
}