haixunMaster/haixun-backend/internal/library/placement/query_build.go

63 lines
1.6 KiB
Go
Raw Permalink Normal View History

2026-06-24 10:02:42 +00:00
package placement
import (
2026-06-25 08:20:03 +00:00
"fmt"
2026-06-24 10:02:42 +00:00
"strings"
"time"
2026-06-25 08:20:03 +00:00
"haixun-backend/internal/library/websearch"
2026-06-24 10:02:42 +00:00
)
type QueryDimension string
const (
QueryRelevance QueryDimension = "relevance"
QueryRecency QueryDimension = "recency"
)
type TagQuery struct {
Tag string
Query string
Dimension QueryDimension
GraphNodeID string
ProductFitScore int
RecencyDays int // 0 = no after filter; 7 or 30 for recency track
}
2026-06-25 08:20:03 +00:00
func BuildRelevanceQuery(provider websearch.Provider, tag string) string {
2026-06-24 10:02:42 +00:00
tag = strings.TrimSpace(tag)
if tag == "" {
return ""
}
2026-06-25 08:20:03 +00:00
if websearch.ParseProvider(string(provider)) == websearch.ProviderExa {
return fmt.Sprintf("Threads 貼文 繁體中文 %s", tag)
}
2026-06-24 10:02:42 +00:00
return `site:threads.net "` + tag + `"`
}
2026-06-25 08:20:03 +00:00
func BuildRecencyQuery(provider websearch.Provider, tag string, maxAgeDays int) string {
2026-06-24 10:02:42 +00:00
tag = strings.TrimSpace(tag)
if tag == "" {
return ""
}
2026-06-25 08:20:03 +00:00
if websearch.ParseProvider(string(provider)) == websearch.ProviderExa {
return fmt.Sprintf("Threads 近期貼文 繁體中文 %s", tag)
}
2026-06-24 10:02:42 +00:00
after := FormatAfterDate(maxAgeDays, timeNow())
return `site:threads.net "` + tag + `" 請問 after:` + after
}
2026-06-25 08:20:03 +00:00
func PublishedAfterForRecency(provider websearch.Provider, maxAgeDays int) string {
if maxAgeDays <= 0 || websearch.ParseProvider(string(provider)) != websearch.ProviderExa {
return ""
}
return FormatPublishedAfterISO(maxAgeDays, timeNow())
}
2026-06-24 10:02:42 +00:00
var timeNow = func() time.Time { return time.Now() }
// SetTimeNowForTest overrides time source in tests.
func SetTimeNowForTest(fn func() time.Time) {
timeNow = fn
}