Files
backend/internal/dto/segment.go

144 lines
3.8 KiB
Go
Raw Normal View History

package dto
import (
"encoding/json"
"fmt"
"slices"
"with_you/internal/model"
)
// NewTextSegment 创建文本Segment
func NewTextSegment(content string) model.MessageSegment {
return model.MessageSegment{
Type: string(SegmentTypeText),
Data: map[string]any{"text": content},
}
}
// ExtractVoteSegmentData 从消息链中提取投票Segment数据
func ExtractVoteSegmentData(segments model.MessageSegments) *VoteSegmentData {
for _, segment := range segments {
if segment.Type == string(SegmentTypeVote) {
dataBytes, err := json.Marshal(segment.Data)
if err != nil {
continue
}
var voteData VoteSegmentData
if err := json.Unmarshal(dataBytes, &voteData); err != nil {
continue
}
return &voteData
}
}
return nil
}
// HasVoteSegment 检查消息链中是否包含投票Segment
func HasVoteSegment(segments model.MessageSegments) bool {
return HasSegmentType(segments, SegmentTypeVote)
}
// ExtractTextContentFromModel 从 model.MessageSegments 中提取纯文本内容
func ExtractTextContentFromModel(segments model.MessageSegments) string {
var result string
for _, segment := range segments {
switch segment.Type {
case "text":
if text, ok := segment.Data["text"].(string); ok {
result += text
}
case "at":
userID, _ := segment.Data["user_id"].(string)
if userID == "all" {
result += "@所有人 "
} else if userID != "" {
// 昵称由前端实时解析,后端文本提取仅用于推送通知兜底
result += "@某人 "
}
case "image":
result += "[图片]"
case "voice":
result += "[语音]"
case "video":
result += "[视频]"
case "file":
if name, ok := segment.Data["name"].(string); ok && name != "" {
result += fmt.Sprintf("[文件:%s]", name)
} else {
result += "[文件]"
}
case "face":
if name, ok := segment.Data["name"].(string); ok && name != "" {
result += fmt.Sprintf("[%s]", name)
} else {
result += "[表情]"
}
case "link":
if title, ok := segment.Data["title"].(string); ok && title != "" {
result += fmt.Sprintf("[链接:%s]", title)
} else {
result += "[链接]"
}
case "vote":
result += "[投票]"
case "post_ref":
if title, ok := segment.Data["title"].(string); ok && title != "" {
result += fmt.Sprintf("[帖子:%s]", title)
} else {
result += "[帖子引用]"
}
}
}
return result
}
// ExtractTextContent 从消息链中提取纯文本内容
// 用于搜索、通知展示等场景
func ExtractTextContent(segments model.MessageSegments) string {
return ExtractTextContentFromModel(segments)
}
// ExtractMentionedUsers 从消息链中提取被@的用户ID列表
// 不包括 "all"@所有人)
func ExtractMentionedUsers(segments model.MessageSegments) []string {
var userIDs []string
seen := make(map[string]bool)
for _, segment := range segments {
if segment.Type == string(SegmentTypeAt) {
userID, _ := segment.Data["user_id"].(string)
if userID != "all" && userID != "" && !seen[userID] {
userIDs = append(userIDs, userID)
seen[userID] = true
}
}
}
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
}
// HasSegmentType 检查消息链中是否包含指定类型的segment
func HasSegmentType(segments model.MessageSegments, segmentType SegmentType) bool {
return slices.ContainsFunc(segments, func(segment model.MessageSegment) bool {
return segment.Type == string(segmentType)
})
}