61 lines
1.6 KiB
Go
61 lines
1.6 KiB
Go
package kb
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
// LookupCite 根据标准号/条文引用粗查法规库;命中则返回可写入参考文献的完整说明条目
|
||
// 若未命中或无法连接返回 ok=false
|
||
func (r *Retriever) LookupCite(ctx context.Context, citeKey string) (string, bool) {
|
||
if r == nil || r.Store == nil || r.Store.Pool == nil {
|
||
return "", false
|
||
}
|
||
|
||
std := strings.TrimSpace(citeKey)
|
||
std = strings.TrimPrefix(std, "〔")
|
||
std = strings.TrimSuffix(std, "〕")
|
||
std = strings.TrimPrefix(std, "[")
|
||
std = strings.TrimSuffix(std, "]")
|
||
|
||
clause := ""
|
||
if idx := strings.IndexAny(std, " §"); idx >= 0 {
|
||
clause = strings.TrimSpace(std[idx:])
|
||
std = strings.TrimSpace(std[:idx])
|
||
}
|
||
if std == "" {
|
||
return "", false
|
||
}
|
||
|
||
cctx, cancel := context.WithTimeout(ctx, 3*time.Second)
|
||
defer cancel()
|
||
|
||
// 1. 尝试精确查找文档
|
||
var title, docNo, status string
|
||
err := r.Store.Pool.QueryRow(cctx, `
|
||
SELECT COALESCE(doc_no,''), COALESCE(title,''), COALESCE(status,'')
|
||
FROM reg_documents
|
||
WHERE doc_no ILIKE $1 OR title ILIKE $1
|
||
ORDER BY id ASC LIMIT 1`, "%"+std+"%").Scan(&docNo, &title, &status)
|
||
|
||
if err == nil && docNo != "" {
|
||
line := fmt.Sprintf("〔%s%s〕%s", docNo, clause, title)
|
||
if status == "repealed" || status == "superseded" {
|
||
line = "〔已废止〕" + line
|
||
}
|
||
return line, true
|
||
}
|
||
|
||
// 2. 备选:按 Search 检索 Top 1
|
||
hits, err := r.Search(cctx, std, SearchOptions{Limit: 1, IncludeRepealed: true})
|
||
if err == nil && len(hits) > 0 {
|
||
h := hits[0]
|
||
line := fmt.Sprintf("%s %s", h.CiteKey, h.Title)
|
||
return line, true
|
||
}
|
||
|
||
return "", false
|
||
}
|