thread-master/apps/backend/internal/module/radar/domain/suggest.go

64 lines
1.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package domain
import "strings"
const (
SuggestUsageInclude = "include"
SuggestUsageExclude = "exclude"
// 建議數量上限:清單要能一眼看完並逐條決定,不是丟一大串讓人放棄。
MaxSuggestions = 20
DefaultSuggestions = 8
)
/*
WatchTermSuggestion 是一則關鍵字建議。
Reason 是必填的:使用者要逐條決定採不採用,看不到「為什麼建議這個詞」就只能全採或全不採,
那這個功能就退化成一個猜測產生器。
*/
type WatchTermSuggestion struct {
Term string `json:"term"`
Reason string `json:"reason"`
Usage string `json:"usage"`
}
func NormalizeSuggestUsage(s string) string {
if strings.EqualFold(strings.TrimSpace(s), SuggestUsageExclude) {
return SuggestUsageExclude
}
return SuggestUsageInclude
}
/*
CleanSuggestions 收掉空白與重複,丟掉沒有理由的項目,並套用數量上限。
沒有理由的項目直接丟補一句「AI 建議」等於假裝有理由,比少一則更糟。
*/
func CleanSuggestions(in []WatchTermSuggestion, limit int) []WatchTermSuggestion {
if limit <= 0 || limit > MaxSuggestions {
limit = MaxSuggestions
}
out := make([]WatchTermSuggestion, 0, len(in))
seen := map[string]bool{}
for _, s := range in {
term := strings.ToLower(strings.Join(strings.Fields(strings.ReplaceAll(s.Term, "\u3000", " ")), " "))
reason := strings.TrimSpace(s.Reason)
if term == "" || reason == "" {
continue
}
if len([]rune(term)) < MinTermLen || len([]rune(term)) > MaxTermLen {
continue
}
if seen[term] {
continue
}
seen[term] = true
out = append(out, WatchTermSuggestion{Term: term, Reason: reason, Usage: NormalizeSuggestUsage(s.Usage)})
if len(out) >= limit {
break
}
}
return out
}