haixunMaster/haixun-backend/internal/logic/copy_mission/mapper.go

238 lines
7.9 KiB
Go
Raw Permalink Normal View History

2026-06-25 08:20:03 +00:00
package copy_mission
import (
copydraftdomain "haixun-backend/internal/model/copy_draft/domain/usecase"
missionentity "haixun-backend/internal/model/copy_mission/domain/entity"
missiondomain "haixun-backend/internal/model/copy_mission/domain/usecase"
personadomain "haixun-backend/internal/model/persona/domain/usecase"
scanpostdomain "haixun-backend/internal/model/scan_post/domain/usecase"
"haixun-backend/internal/types"
)
func seedMissionResearchFromPersona(persona personadomain.PersonaSummary) (*missionentity.ResearchMap, []string) {
src := persona.CopyResearchMap
if src.AudienceSummary == "" && src.ContentGoal == "" && len(src.SuggestedTags) == 0 {
return nil, nil
}
tags := make([]missionentity.SuggestedTag, 0, len(src.SuggestedTags))
for _, tag := range src.SuggestedTags {
if tag == "" {
continue
}
tags = append(tags, missionentity.SuggestedTag{Tag: tag})
}
selected := append([]string(nil), src.SuggestedTags...)
if len(selected) > 6 {
selected = selected[:6]
}
rm := &missionentity.ResearchMap{
AudienceSummary: src.AudienceSummary,
ContentGoal: src.ContentGoal,
Questions: append([]string(nil), src.Questions...),
Pillars: append([]string(nil), src.Pillars...),
Exclusions: append([]string(nil), src.Exclusions...),
SuggestedTags: tags,
BenchmarkNotes: src.BenchmarkNotes,
}
return rm, selected
}
func toMissionPatch(req *types.UpdateCopyMissionReq) missiondomain.MissionPatch {
if req == nil {
return missiondomain.MissionPatch{}
}
patch := missiondomain.MissionPatch{
Label: req.Label,
SeedQuery: req.SeedQuery,
Brief: req.Brief,
}
if req.AudienceSummary != nil {
patch.AudienceSummary = req.AudienceSummary
}
if req.ContentGoal != nil {
patch.ContentGoal = req.ContentGoal
}
if req.Questions != nil {
patch.QuestionsSet = true
patch.Questions = append([]string(nil), req.Questions...)
}
if req.Pillars != nil {
patch.PillarsSet = true
patch.Pillars = append([]string(nil), req.Pillars...)
}
if req.Exclusions != nil {
patch.ExclusionsSet = true
patch.Exclusions = append([]string(nil), req.Exclusions...)
}
if req.BenchmarkNotes != nil {
patch.BenchmarkNotes = req.BenchmarkNotes
}
if req.SelectedTags != nil {
patch.SelectedTagsSet = true
patch.SelectedTags = append([]string(nil), req.SelectedTags...)
}
return patch
}
func toCopyMissionData(item missiondomain.MissionSummary) types.CopyMissionData {
tags := make([]types.CopySuggestedTagData, 0, len(item.ResearchMap.SuggestedTags))
for _, tag := range item.ResearchMap.SuggestedTags {
tags = append(tags, types.CopySuggestedTagData{
Tag: tag.Tag,
Reason: tag.Reason,
SearchIntent: tag.SearchIntent,
SearchType: tag.SearchType,
})
}
accounts := make([]types.CopySimilarAccountData, 0, len(item.ResearchMap.SimilarAccounts))
for _, acc := range item.ResearchMap.SimilarAccounts {
accounts = append(accounts, types.CopySimilarAccountData{
Username: acc.Username,
Reason: acc.Reason,
Source: acc.Source,
Confidence: acc.Confidence,
ProfileUrl: acc.ProfileURL,
AuthorVerified: acc.AuthorVerified,
FollowerCount: acc.FollowerCount,
EngagementScore: acc.EngagementScore,
LikeCount: acc.LikeCount,
ReplyCount: acc.ReplyCount,
PostCount: acc.PostCount,
})
}
return types.CopyMissionData{
ID: item.ID,
PersonaID: item.PersonaID,
Label: item.Label,
SeedQuery: item.SeedQuery,
Brief: item.Brief,
ResearchMap: types.CopyMissionResearchMapData{
AudienceSummary: item.ResearchMap.AudienceSummary,
ContentGoal: item.ResearchMap.ContentGoal,
Questions: append([]string(nil), item.ResearchMap.Questions...),
Pillars: append([]string(nil), item.ResearchMap.Pillars...),
Exclusions: append([]string(nil), item.ResearchMap.Exclusions...),
SuggestedTags: tags,
SimilarAccounts: accounts,
BenchmarkNotes: item.ResearchMap.BenchmarkNotes,
},
SelectedTags: append([]string(nil), item.SelectedTags...),
LastScanJobID: item.LastScanJobID,
Status: item.Status,
CreateAt: item.CreateAt,
UpdateAt: item.UpdateAt,
}
}
func toListData(result *missiondomain.ListResult) *types.ListCopyMissionsData {
if result == nil {
return &types.ListCopyMissionsData{List: []types.CopyMissionData{}}
}
list := make([]types.CopyMissionData, 0, len(result.List))
for _, item := range result.List {
list = append(list, toCopyMissionData(item))
}
return &types.ListCopyMissionsData{List: list}
}
func toEntityResearchMap(data types.CopyMissionResearchMapData) missionentity.ResearchMap {
tags := make([]missionentity.SuggestedTag, 0, len(data.SuggestedTags))
for _, tag := range data.SuggestedTags {
tags = append(tags, missionentity.SuggestedTag{
Tag: tag.Tag,
Reason: tag.Reason,
SearchIntent: tag.SearchIntent,
SearchType: tag.SearchType,
})
}
accounts := make([]missionentity.SimilarAccount, 0, len(data.SimilarAccounts))
for _, acc := range data.SimilarAccounts {
accounts = append(accounts, missionentity.SimilarAccount{
Username: acc.Username,
Reason: acc.Reason,
Source: acc.Source,
Confidence: acc.Confidence,
ProfileURL: acc.ProfileUrl,
AuthorVerified: acc.AuthorVerified,
FollowerCount: acc.FollowerCount,
EngagementScore: acc.EngagementScore,
LikeCount: acc.LikeCount,
ReplyCount: acc.ReplyCount,
PostCount: acc.PostCount,
})
}
return missionentity.ResearchMap{
AudienceSummary: data.AudienceSummary,
ContentGoal: data.ContentGoal,
Questions: append([]string(nil), data.Questions...),
Pillars: append([]string(nil), data.Pillars...),
Exclusions: append([]string(nil), data.Exclusions...),
SuggestedTags: tags,
SimilarAccounts: accounts,
BenchmarkNotes: data.BenchmarkNotes,
}
}
func toViralScanPostsData(posts []scanpostdomain.ScanPostSummary) *types.ListPersonaViralScanPostsData {
list := make([]types.ViralScanPostData, 0, len(posts))
for _, post := range posts {
list = append(list, types.ViralScanPostData{
ID: post.ID,
SearchTag: post.SearchTag,
Permalink: post.Permalink,
Author: post.Author,
AuthorVerified: post.AuthorVerified,
FollowerCount: post.FollowerCount,
Text: post.Text,
LikeCount: post.LikeCount,
ReplyCount: post.ReplyCount,
EngagementScore: post.EngagementScore,
Source: post.Source,
ScanJobID: post.ScanJobID,
Replies: toScanReplyData(post.Replies),
CreateAt: post.CreateAt,
})
}
return &types.ListPersonaViralScanPostsData{List: list, Total: len(list)}
}
func toScanReplyData(replies []scanpostdomain.ScanReplySummary) []types.ScanReplyData {
if len(replies) == 0 {
return nil
}
out := make([]types.ScanReplyData, 0, len(replies))
for _, reply := range replies {
out = append(out, types.ScanReplyData{
ExternalID: reply.ExternalID,
Author: reply.Author,
Text: reply.Text,
Permalink: reply.Permalink,
LikeCount: reply.LikeCount,
PostedAt: reply.PostedAt,
})
}
return out
}
func toCopyDraftData(item copydraftdomain.CopyDraftSummary) types.CopyDraftData {
return types.CopyDraftData{
ID: item.ID,
PersonaID: item.PersonaID,
CopyMissionID: item.CopyMissionID,
ScanPostID: item.ScanPostID,
DraftType: item.DraftType,
SortOrder: item.SortOrder,
Text: item.Text,
Angle: item.Angle,
Hook: item.Hook,
Rationale: item.Rationale,
ReferenceNotes: item.ReferenceNotes,
Sources: item.Sources,
Status: item.Status,
PublishedMediaID: item.PublishedMediaID,
PublishedPermalink: item.PublishedPermalink,
PublishedAt: item.PublishedAt,
CreateAt: item.CreateAt,
}
}