Files
geo/server/internal/tenant/app/monitoring_article_alias_sync.go
T
root 31c4dd9358
Frontend CI / Frontend (push) Successful in 7m47s
Backend CI / Backend (push) Successful in 19m26s
feat: add monitoring marked articles and retention updates
2026-06-17 12:48:41 +08:00

132 lines
3.8 KiB
Go

package app
import (
"context"
"net/url"
"strings"
)
func (s *DesktopTaskService) syncMonitoringArticleAlias(ctx context.Context, input *monitoringArticleAliasInput) error {
if s == nil || s.monitoringPool == nil || input == nil {
return nil
}
originalURL, confidence := monitoringAliasOriginalURL(input)
if originalURL == "" {
return nil
}
normalizedURL := normalizeCitationURL(originalURL)
if normalizedURL == "" {
return nil
}
host, registrableDomain, _, _ := deriveCitationURLParts(originalURL, normalizedURL)
if registrableDomain == "" {
registrableDomain = host
}
siteKey := host
if siteKey == "" {
siteKey = registrableDomain
}
lastPathSegment := monitoringAliasLastPathSegment(normalizedURL)
_, err := s.monitoringPool.Exec(ctx, `
INSERT INTO monitoring_article_url_aliases (
tenant_id, article_id, publish_record_id, platform_id, publish_platform_name_snapshot,
external_article_id, article_title_snapshot, original_url, normalized_url,
host, registrable_domain, site_key, last_path_segment, confidence
)
VALUES (
$1, $2, $3, $4, $5,
$6, $7, $8, $9,
$10, $11, $12, $13, $14
)
ON CONFLICT (tenant_id, normalized_url)
DO UPDATE SET
article_id = EXCLUDED.article_id,
publish_record_id = EXCLUDED.publish_record_id,
platform_id = EXCLUDED.platform_id,
publish_platform_name_snapshot = EXCLUDED.publish_platform_name_snapshot,
external_article_id = EXCLUDED.external_article_id,
article_title_snapshot = EXCLUDED.article_title_snapshot,
original_url = EXCLUDED.original_url,
host = EXCLUDED.host,
registrable_domain = EXCLUDED.registrable_domain,
site_key = EXCLUDED.site_key,
last_path_segment = EXCLUDED.last_path_segment,
confidence = EXCLUDED.confidence,
updated_at = NOW()
`,
input.TenantID,
input.ArticleID,
input.PublishRecordID,
strings.TrimSpace(input.PlatformID),
strings.TrimSpace(input.PlatformName),
normalizeStringPointer(input.ExternalArticleID),
strings.TrimSpace(input.ArticleTitle),
originalURL,
normalizedURL,
host,
registrableDomain,
siteKey,
nullableString(lastPathSegment),
confidence,
)
if err != nil {
return err
}
if confidence == "high" {
_, err = s.monitoringPool.Exec(ctx, `
UPDATE monitoring_citation_facts
SET content_source_type = 'published_article',
content_source_id = $3,
article_id = COALESCE(article_id, $3),
publish_record_id = COALESCE(publish_record_id, $4)
WHERE tenant_id = $1
AND normalized_url = $2
AND (
content_source_type IS DISTINCT FROM 'published_article'
OR content_source_id IS DISTINCT FROM $3
)
`, input.TenantID, normalizedURL, input.ArticleID, input.PublishRecordID)
}
return err
}
func monitoringAliasOriginalURL(input *monitoringArticleAliasInput) (string, string) {
if input == nil {
return "", ""
}
switch strings.TrimSpace(input.PlatformID) {
case "baijiahao":
if articleID := strings.TrimSpace(monitoringStringValue(input.ExternalArticleID)); articleID != "" {
return baijiahaoPublishedArticleURL(articleID), "high"
}
case "wangyihao":
if articleID := strings.TrimSpace(monitoringStringValue(input.ExternalArticleID)); articleID != "" {
return wangyihaoPublishedArticleURL(articleID), "high"
}
}
if value := strings.TrimSpace(monitoringStringValue(input.ExternalArticleURL)); value != "" {
return value, "high"
}
if value := strings.TrimSpace(monitoringStringValue(input.ExternalManageURL)); value != "" {
return value, "medium"
}
return "", ""
}
func monitoringAliasLastPathSegment(rawURL string) *string {
parsed, err := url.Parse(strings.TrimSpace(rawURL))
if err != nil {
return nil
}
segments := strings.Split(strings.Trim(parsed.Path, "/"), "/")
for index := len(segments) - 1; index >= 0; index-- {
if segment := strings.TrimSpace(segments[index]); segment != "" {
return &segment
}
}
return nil
}