thread-master/apps/backend/internal/module/radar/usecase/priority.go

66 lines
1.8 KiB
Go
Raw Permalink Normal View History

2026-08-13 02:22:24 +00:00
package usecase
import (
"strings"
"unicode/utf8"
"apps/backend/internal/module/radar/domain"
)
type priorityResult struct {
Priority, PainFit, DemandIntent, EvidenceQuality, Freshness int
Band string
Evidence []string
}
func scoreOpportunityPriority(cand *domain.CandidatePost, result *JudgeResult) priorityResult {
if cand == nil || result == nil {
return priorityResult{}
}
intent, freshness, fit := 0, 0, 0
for _, reason := range result.Reasons {
switch reason.Dimension {
case domain.DimIntent:
intent = reason.Score
case domain.DimFreshness:
freshness = reason.Score
case domain.DimFit:
fit = reason.Score
}
}
if result.ProductMatch != nil {
fit = result.ProductMatch.ProductFitScore
}
intent100 := intent * 100 / domain.WeightIntent
fresh100 := freshness * 100 / domain.WeightFreshness
evidence := make([]string, 0, 4)
if strings.TrimSpace(cand.MatchedTerm) != "" {
evidence = append(evidence, "命中詞:"+strings.TrimSpace(cand.MatchedTerm))
}
for _, reason := range result.Reasons {
if strings.TrimSpace(reason.Reason) == "" {
continue
}
text := strings.TrimSpace(reason.Reason)
if utf8.RuneCountInString(text) > 60 {
text = string([]rune(text)[:60])
}
evidence = append(evidence, text)
if len(evidence) >= 4 {
break
}
}
evidenceQuality := len(evidence) * 20
if evidenceQuality > 100 {
evidenceQuality = 100
}
priority := (intent100*35 + fit*35 + evidenceQuality*20 + fresh100*10) / 100
band := "low"
if priority >= 75 {
band = "high"
} else if priority >= 50 {
band = "review"
}
return priorityResult{Priority: priority, Band: band, PainFit: fit, DemandIntent: intent100, EvidenceQuality: evidenceQuality, Freshness: fresh100, Evidence: evidence}
}