66 lines
1.8 KiB
Go
66 lines
1.8 KiB
Go
|
|
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}
|
||
|
|
}
|