package integration import ( "bytes" "context" "encoding/json" "strings" biz "kra/internal/biz/integration" "kra/internal/service/dto" ) type smsUsecase interface { Send(context.Context, *biz.SMSMessage) (*biz.SMSResult, error) } type SMSService struct{ uc smsUsecase } func NewSMSService(uc *biz.SMSUsecase) *SMSService { return &SMSService{uc: uc} } func (s *SMSService) Send(ctx context.Context, provider string, req *dto.SMSSendRequest) (*dto.SMSSendResponse, error) { if req == nil || len(req.Params) > 12000 { return nil, biz.ErrSMSInvalid } m := &biz.SMSMessage{Provider: provider, Phone: strings.TrimSpace(req.Phone)} params := bytes.TrimSpace(req.Params) var values any if json.Unmarshal(params, &values) != nil { return nil, biz.ErrSMSInvalid } switch provider { case "aliyun": object, ok := values.(map[string]any) if !ok { return nil, biz.ErrSMSInvalid } m.NamedParams = make(map[string]string, len(object)) for key, value := range object { text, ok := value.(string) if !ok { return nil, biz.ErrSMSInvalid } m.NamedParams[key] = text } case "tencent": array, ok := values.([]any) if !ok { return nil, biz.ErrSMSInvalid } m.Params = make([]string, 0, len(array)) for _, value := range array { text, ok := value.(string) if !ok { return nil, biz.ErrSMSInvalid } m.Params = append(m.Params, text) } default: return nil, biz.ErrSMSInvalid } if err := biz.ValidateSMSMessage(m); err != nil { return nil, err } result, err := s.uc.Send(ctx, m) if err != nil { return nil, err } return &dto.SMSSendResponse{RequestID: result.RequestID, MessageID: result.MessageID}, nil }