package scale import ( "context" "encoding/json" "errors" "github.com/google/uuid" "github.com/yuxingu/digital-psychology/apps/api/internal/repository" ) // Service serves 探索测试. type Service struct { Repo *repository.ScaleRepo Profiles *repository.ProfileRepo } // List returns published scales. func (s *Service) List(ctx context.Context) ([]repository.ScaleListItem, error) { return s.Repo.ListPublished(ctx) } // Get returns scale detail. func (s *Service) Get(ctx context.Context, slug string) (*repository.ScaleDetail, error) { d, err := s.Repo.GetBySlug(ctx, slug) if err != nil { return nil, errors.New("scale not found") } return d, nil } // SubmitInput answers map question_id -> option key. type SubmitInput struct { ProfileID uuid.UUID Answers map[string]string } // SubmitResult is exploration result. type SubmitResult struct { ID uuid.UUID `json:"id"` Result map[string]interface{} `json:"result"` } // Submit scores a simple majority style. func (s *Service) Submit(ctx context.Context, userID uuid.UUID, slug string, in SubmitInput) (*SubmitResult, error) { if _, err := s.Profiles.GetForUser(ctx, userID, in.ProfileID); err != nil { return nil, errors.New("profile not found") } scaleID, err := s.Repo.ScaleIDBySlug(ctx, slug) if err != nil { return nil, errors.New("scale not found") } counts := map[string]int{} for _, v := range in.Answers { counts[v]++ } best, bestN := "A", -1 for k, n := range counts { if n > bestN { best, bestN = k, n } } label := map[string]string{ "A": "理性澄清型", "B": "感受连接型", "C": "节奏尊重型", }[best] if label == "" { label = "平衡探索型" } result := map[string]interface{}{ "title": "探索结果", "style_key": best, "label": label, "summary": "这是你当前沟通偏好的探索结果,可用于自我了解与关系理解,不是固定标签。", "share_line": "我的沟通方式:" + label, } ansJSON, _ := json.Marshal(in.Answers) resJSON, _ := json.Marshal(result) id, err := s.Repo.SaveResult(ctx, userID, scaleID, in.ProfileID, ansJSON, resJSON) if err != nil { return nil, err } return &SubmitResult{ID: id, Result: result}, nil }