132 lines
3.8 KiB
Go
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
|
|
}
|