feat(posts): add post reference/internal linking functionality
All checks were successful
Build Backend / build (push) Successful in 2m19s
Build Backend / build-docker (push) Successful in 1m18s

Add support for referencing other posts within messages through a new post_ref segment type. Includes new PostReference model to track relationships, PostRefService for processing references, and new endpoints for post suggestions, related posts, and reference click tracking.
This commit is contained in:
lafay
2026-04-26 00:37:20 +08:00
parent 898c0e6d9c
commit 23d7f1151e
11 changed files with 592 additions and 5 deletions

View File

@@ -145,6 +145,17 @@ func NewLinkSegment(url, title, description, image string) model.MessageSegment
}
}
// NewPostRefSegment 创建帖子内链Segment
func NewPostRefSegment(postID, title string) model.MessageSegment {
return model.MessageSegment{
Type: string(SegmentTypePostRef),
Data: map[string]any{
"post_id": postID,
"title": title,
},
}
}
// ExtractVoteSegmentData 从消息链中提取投票Segment数据
func ExtractVoteSegmentData(segments model.MessageSegments) *VoteSegmentData {
for _, segment := range segments {
@@ -227,6 +238,12 @@ func ExtractTextContentFromModel(segments model.MessageSegments) string {
}
case "vote":
result += "[投票]"
case "post_ref":
if title, ok := segment.Data["title"].(string); ok && title != "" {
result += fmt.Sprintf("[帖子:%s]", title)
} else {
result += "[帖子引用]"
}
}
}
return result
@@ -256,6 +273,28 @@ func ExtractMentionedUsers(segments model.MessageSegments) []string {
return userIDs
}
// ExtractReferencedPosts 从消息链中提取所有被引用的帖子ID
func ExtractReferencedPosts(segments model.MessageSegments) []string {
var postIDs []string
seen := make(map[string]bool)
for _, segment := range segments {
if segment.Type == string(SegmentTypePostRef) {
postID, _ := segment.Data["post_id"].(string)
if postID != "" && !seen[postID] {
postIDs = append(postIDs, postID)
seen[postID] = true
}
}
}
return postIDs
}
// HasPostRefSegment 检查消息链中是否包含帖子引用
func HasPostRefSegment(segments model.MessageSegments) bool {
return HasSegmentType(segments, SegmentTypePostRef)
}
// IsAtAll 检查消息是否@了所有人
func IsAtAll(segments model.MessageSegments) bool {
return slices.ContainsFunc(segments, func(segment model.MessageSegment) bool {