Files
user-system/internal/service/custom_field.go

320 lines
8.3 KiB
Go
Raw Normal View History

package service
import (
"context"
"errors"
"fmt"
"strconv"
"time"
"github.com/user-management-system/internal/domain"
"github.com/user-management-system/internal/repository"
)
// CustomFieldService 自定义字段服务
type CustomFieldService struct {
fieldRepo *repository.CustomFieldRepository
valueRepo *repository.UserCustomFieldValueRepository
}
// NewCustomFieldService 创建自定义字段服务
func NewCustomFieldService(
fieldRepo *repository.CustomFieldRepository,
valueRepo *repository.UserCustomFieldValueRepository,
) *CustomFieldService {
return &CustomFieldService{
fieldRepo: fieldRepo,
valueRepo: valueRepo,
}
}
// CreateFieldRequest 创建字段请求
type CreateFieldRequest struct {
Name string `json:"name" binding:"required"`
FieldKey string `json:"field_key" binding:"required"`
Type int `json:"type" binding:"required"`
Required bool `json:"required"`
Default string `json:"default"`
MinLen int `json:"min_len"`
MaxLen int `json:"max_len"`
MinVal float64 `json:"min_val"`
MaxVal float64 `json:"max_val"`
Options string `json:"options"`
Sort int `json:"sort"`
}
// UpdateFieldRequest 更新字段请求
type UpdateFieldRequest struct {
Name string `json:"name"`
Type int `json:"type"`
Required *bool `json:"required"`
Default string `json:"default"`
MinLen int `json:"min_len"`
MaxLen int `json:"max_len"`
MinVal float64 `json:"min_val"`
MaxVal float64 `json:"max_val"`
Options string `json:"options"`
Sort int `json:"sort"`
Status *int `json:"status"`
}
// CreateField 创建自定义字段
func (s *CustomFieldService) CreateField(ctx context.Context, req *CreateFieldRequest) (*domain.CustomField, error) {
// 检查field_key是否已存在
existing, err := s.fieldRepo.GetByFieldKey(ctx, req.FieldKey)
if err == nil && existing != nil {
return nil, errors.New("字段标识符已存在")
}
field := &domain.CustomField{
Name: req.Name,
FieldKey: req.FieldKey,
Type: domain.CustomFieldType(req.Type),
Required: req.Required,
DefaultVal: req.Default,
MinLen: req.MinLen,
MaxLen: req.MaxLen,
MinVal: req.MinVal,
MaxVal: req.MaxVal,
Options: req.Options,
Sort: req.Sort,
Status: 1,
}
if err := s.fieldRepo.Create(ctx, field); err != nil {
return nil, err
}
return field, nil
}
// UpdateField 更新自定义字段
func (s *CustomFieldService) UpdateField(ctx context.Context, id int64, req *UpdateFieldRequest) (*domain.CustomField, error) {
field, err := s.fieldRepo.GetByID(ctx, id)
if err != nil {
return nil, errors.New("字段不存在")
}
if req.Name != "" {
field.Name = req.Name
}
if req.Type > 0 {
field.Type = domain.CustomFieldType(req.Type)
}
if req.Required != nil {
field.Required = *req.Required
}
if req.Default != "" {
field.DefaultVal = req.Default
}
if req.MinLen > 0 {
field.MinLen = req.MinLen
}
if req.MaxLen > 0 {
field.MaxLen = req.MaxLen
}
if req.MinVal > 0 {
field.MinVal = req.MinVal
}
if req.MaxVal > 0 {
field.MaxVal = req.MaxVal
}
if req.Options != "" {
field.Options = req.Options
}
if req.Sort > 0 {
field.Sort = req.Sort
}
if req.Status != nil {
field.Status = *req.Status
}
if err := s.fieldRepo.Update(ctx, field); err != nil {
return nil, err
}
return field, nil
}
// DeleteField 删除自定义字段
func (s *CustomFieldService) DeleteField(ctx context.Context, id int64) error {
field, err := s.fieldRepo.GetByID(ctx, id)
if err != nil {
return errors.New("字段不存在")
}
// 删除字段定义
if err := s.fieldRepo.Delete(ctx, id); err != nil {
return err
}
// 清理用户的该字段值(可选,取决于业务需求)
_ = field
return nil
}
// GetField 获取自定义字段
func (s *CustomFieldService) GetField(ctx context.Context, id int64) (*domain.CustomField, error) {
return s.fieldRepo.GetByID(ctx, id)
}
// ListFields 获取所有启用的自定义字段
func (s *CustomFieldService) ListFields(ctx context.Context) ([]*domain.CustomField, error) {
return s.fieldRepo.List(ctx)
}
// ListAllFields 获取所有自定义字段
func (s *CustomFieldService) ListAllFields(ctx context.Context) ([]*domain.CustomField, error) {
return s.fieldRepo.ListAll(ctx)
}
// SetUserFieldValue 设置用户的自定义字段值
func (s *CustomFieldService) SetUserFieldValue(ctx context.Context, userID int64, fieldKey string, value string) error {
// 获取字段定义
field, err := s.fieldRepo.GetByFieldKey(ctx, fieldKey)
if err != nil {
return errors.New("字段不存在")
}
// 验证值
if err := s.validateFieldValue(field, value); err != nil {
return err
}
return s.valueRepo.Set(ctx, userID, field.ID, fieldKey, value)
}
// BatchSetUserFieldValues 批量设置用户的自定义字段值
func (s *CustomFieldService) BatchSetUserFieldValues(ctx context.Context, userID int64, values map[string]string) error {
// 获取所有启用的字段定义
fields, err := s.fieldRepo.List(ctx)
if err != nil {
return err
}
fieldMap := make(map[string]*domain.CustomField)
for _, f := range fields {
fieldMap[f.FieldKey] = f
}
// 验证每个值
for fieldKey, value := range values {
field, ok := fieldMap[fieldKey]
if !ok {
return fmt.Errorf("字段不存在: %s", fieldKey)
}
if err := s.validateFieldValue(field, value); err != nil {
return err
}
}
// 批量设置值
return s.valueRepo.BatchSet(ctx, userID, values)
}
// GetUserFieldValues 获取用户的所有自定义字段值
func (s *CustomFieldService) GetUserFieldValues(ctx context.Context, userID int64) ([]*domain.CustomFieldValueResponse, error) {
// 获取所有启用的字段定义
fields, err := s.fieldRepo.List(ctx)
if err != nil {
return nil, err
}
// 获取用户的字段值
values, err := s.valueRepo.GetByUserID(ctx, userID)
if err != nil {
return nil, err
}
// 构建字段值映射
valueMap := make(map[int64]*domain.UserCustomFieldValue)
for _, v := range values {
valueMap[v.FieldID] = v
}
// 构建响应
fieldMap := make(map[string]*domain.CustomField)
for _, f := range fields {
fieldMap[f.FieldKey] = f
}
var result []*domain.CustomFieldValueResponse
for _, field := range fields {
resp := &domain.CustomFieldValueResponse{
FieldKey: field.FieldKey,
}
if val, ok := valueMap[field.ID]; ok {
resp.Value = val.GetValueAsInterface(field)
} else if field.DefaultVal != "" {
resp.Value = field.DefaultVal
} else {
resp.Value = nil
}
result = append(result, resp)
}
return result, nil
}
// DeleteUserFieldValue 删除用户的自定义字段值
func (s *CustomFieldService) DeleteUserFieldValue(ctx context.Context, userID int64, fieldKey string) error {
field, err := s.fieldRepo.GetByFieldKey(ctx, fieldKey)
if err != nil {
return errors.New("字段不存在")
}
return s.valueRepo.Delete(ctx, userID, field.ID)
}
// validateFieldValue 验证字段值
func (s *CustomFieldService) validateFieldValue(field *domain.CustomField, value string) error {
// 检查必填
if field.Required && value == "" {
return errors.New("字段值不能为空")
}
// 如果值为空且有默认值,跳过验证
if value == "" && field.DefaultVal != "" {
return nil
}
switch field.Type {
case domain.CustomFieldTypeString:
// 字符串长度验证
if field.MinLen > 0 && len(value) < field.MinLen {
return fmt.Errorf("值长度不能小于%d", field.MinLen)
}
if field.MaxLen > 0 && len(value) > field.MaxLen {
return fmt.Errorf("值长度不能大于%d", field.MaxLen)
}
case domain.CustomFieldTypeNumber:
// 数字验证
numVal, err := strconv.ParseFloat(value, 64)
if err != nil {
return errors.New("值必须是数字")
}
if field.MinVal > 0 && numVal < field.MinVal {
return fmt.Errorf("值不能小于%.2f", field.MinVal)
}
if field.MaxVal > 0 && numVal > field.MaxVal {
return fmt.Errorf("值不能大于%.2f", field.MaxVal)
}
case domain.CustomFieldTypeBoolean:
// 布尔验证
if value != "true" && value != "false" && value != "1" && value != "0" {
return errors.New("值必须是布尔值(true/false/1/0)")
}
case domain.CustomFieldTypeDate:
// 日期验证
_, err := time.Parse("2006-01-02", value)
if err != nil {
return errors.New("值必须是有效的日期格式(YYYY-MM-DD)")
}
}
return nil
}