From cef65deb23a95c0b674883e4af963fd4230b0173 Mon Sep 17 00:00:00 2001 From: cialloo Date: Wed, 29 Oct 2025 08:13:08 +0800 Subject: [PATCH] Refactor file key extraction in CreatePost and EditPost logic to handle multiple file types; enhance error logging and simplify utility functions --- app/internal/logic/createpostlogic.go | 18 +---- app/internal/logic/editpostlogic.go | 18 +---- app/internal/utils/content.go | 102 ++++++++++---------------- 3 files changed, 48 insertions(+), 90 deletions(-) diff --git a/app/internal/logic/createpostlogic.go b/app/internal/logic/createpostlogic.go index 00b5b79..06f508d 100644 --- a/app/internal/logic/createpostlogic.go +++ b/app/internal/logic/createpostlogic.go @@ -36,23 +36,13 @@ func (l *CreatePostLogic) CreatePost(req *types.CreatePostReq) (resp *types.Crea } defer tx.Rollback() - // Extract all image file keys from content - imageKeys, err := utils.ExtractImageKeysFromContent(req.Content) + // Extract all file keys (images, archives, audio, video) from content + allFileKeys, err := utils.ExtractAllFileKeysFromContent(req.Content) if err != nil { - l.Errorf("Failed to parse content: %v", err) + l.Errorf("Failed to parse file references from content: %v", err) return nil, fmt.Errorf("invalid content format") } - // Extract all archive file keys from content - archiveKeys, err := utils.ExtractArchiveKeysFromContent(req.Content) - if err != nil { - l.Errorf("Failed to parse archive files from content: %v", err) - return nil, fmt.Errorf("invalid content format") - } - - // Combine all file keys - allFileKeys := append(imageKeys, archiveKeys...) - // Extract all hashtags from content hashtags, err := utils.ExtractHashtagsFromContent(req.Content) if err != nil { @@ -71,7 +61,7 @@ func (l *CreatePostLogic) CreatePost(req *types.CreatePostReq) (resp *types.Crea coverID.Valid = true } - // Migrate all content files (images and archives) from tmpfiles to files + // Migrate all referenced content files (images, archives, audio, video) from tmpfiles to files for _, fileKey := range allFileKeys { _, err := l.migrateFileFromTmpToFiles(tx, fileKey) if err != nil { diff --git a/app/internal/logic/editpostlogic.go b/app/internal/logic/editpostlogic.go index f543f84..62e57bf 100644 --- a/app/internal/logic/editpostlogic.go +++ b/app/internal/logic/editpostlogic.go @@ -49,23 +49,13 @@ func (l *EditPostLogic) EditPost(req *types.EditPostReq) (resp *types.EditPostRe return nil, err } - // Extract all image file keys from content - imageKeys, err := utils.ExtractImageKeysFromContent(req.Content) + // Extract all file keys (images, archives, audio, video) from content + allFileKeys, err := utils.ExtractAllFileKeysFromContent(req.Content) if err != nil { - l.Errorf("Failed to parse content: %v", err) + l.Errorf("Failed to parse file references from content: %v", err) return nil, fmt.Errorf("invalid content format") } - // Extract all archive file keys from content - archiveKeys, err := utils.ExtractArchiveKeysFromContent(req.Content) - if err != nil { - l.Errorf("Failed to parse archive files from content: %v", err) - return nil, fmt.Errorf("invalid content format") - } - - // Combine all file keys - allFileKeys := append(imageKeys, archiveKeys...) - // Extract all hashtags from content hashtags, err := utils.ExtractHashtagsFromContent(req.Content) if err != nil { @@ -110,7 +100,7 @@ func (l *EditPostLogic) EditPost(req *types.EditPostReq) (resp *types.EditPostRe } } - // Migrate all content files (images and archives) from tmpfiles to files + // Migrate all referenced content files (images, archives, audio, video) from tmpfiles to files for _, fileKey := range allFileKeys { _, err := l.migrateFileFromTmpToFiles(tx, fileKey) if err != nil { diff --git a/app/internal/utils/content.go b/app/internal/utils/content.go index d5d415f..aa4c2af 100644 --- a/app/internal/utils/content.go +++ b/app/internal/utils/content.go @@ -5,91 +5,69 @@ import ( "strings" ) -// ExtractImageKeysFromContent parses the rich text JSON and extracts all image fileKey values +// ExtractImageKeysFromContent parses content and returns all image file keys. func ExtractImageKeysFromContent(content string) ([]string, error) { - var contentData map[string]interface{} - if err := json.Unmarshal([]byte(content), &contentData); err != nil { - return nil, err - } - - var imageKeys []string - extractImageKeys(contentData, &imageKeys) - return imageKeys, nil + return extractFileKeysByTypes(content, "image") } -// extractImageKeys recursively searches for image nodes and collects their fileKey values -func extractImageKeys(data interface{}, keys *[]string) { - switch v := data.(type) { - case map[string]interface{}: - // Check if this is an image node - if nodeType, ok := v["type"].(string); ok && nodeType == "image" { - if fileKey, ok := v["fileKey"].(string); ok && fileKey != "" { - *keys = append(*keys, fileKey) - } - } - // Recurse into all map values - for _, value := range v { - extractImageKeys(value, keys) - } - case []interface{}: - // Recurse into all array elements - for _, item := range v { - extractImageKeys(item, keys) - } - } -} - -// ExtractArchiveKeysFromContent parses the rich text JSON and extracts all archive fileKey values +// ExtractArchiveKeysFromContent parses content and returns all archive file keys. func ExtractArchiveKeysFromContent(content string) ([]string, error) { + return extractFileKeysByTypes(content, "archive") +} + +// ExtractAudioKeysFromContent parses content and returns all audio file keys. +func ExtractAudioKeysFromContent(content string) ([]string, error) { + return extractFileKeysByTypes(content, "audio") +} + +// ExtractVideoKeysFromContent parses content and returns all video file keys. +func ExtractVideoKeysFromContent(content string) ([]string, error) { + return extractFileKeysByTypes(content, "video") +} + +// ExtractAllFileKeysFromContent returns every supported file key (image, archive, audio, video). +func ExtractAllFileKeysFromContent(content string) ([]string, error) { + return extractFileKeysByTypes(content, "image", "archive", "audio", "video") +} + +// extractFileKeysByTypes walks the rich text JSON and collects file keys that match allowed node types. +func extractFileKeysByTypes(content string, nodeTypes ...string) ([]string, error) { var contentData map[string]interface{} if err := json.Unmarshal([]byte(content), &contentData); err != nil { return nil, err } - var archiveKeys []string - extractArchiveKeys(contentData, &archiveKeys) - return archiveKeys, nil + typeSet := make(map[string]struct{}, len(nodeTypes)) + for _, nodeType := range nodeTypes { + typeSet[nodeType] = struct{}{} + } + + var keys []string + extractFileKeys(contentData, typeSet, &keys) + return keys, nil } -// extractArchiveKeys recursively searches for archive nodes and collects their fileKey values -func extractArchiveKeys(data interface{}, keys *[]string) { +// extractFileKeys recursively searches for nodes whose type appears in typeSet and collects fileKey values. +func extractFileKeys(data interface{}, typeSet map[string]struct{}, keys *[]string) { switch v := data.(type) { case map[string]interface{}: - // Check if this is an archive node - if nodeType, ok := v["type"].(string); ok && nodeType == "archive" { - if fileKey, ok := v["fileKey"].(string); ok && fileKey != "" { - *keys = append(*keys, fileKey) + if nodeType, ok := v["type"].(string); ok { + if _, allowed := typeSet[nodeType]; allowed { + if fileKey, ok := v["fileKey"].(string); ok && fileKey != "" { + *keys = append(*keys, fileKey) + } } } - // Recurse into all map values for _, value := range v { - extractArchiveKeys(value, keys) + extractFileKeys(value, typeSet, keys) } case []interface{}: - // Recurse into all array elements for _, item := range v { - extractArchiveKeys(item, keys) + extractFileKeys(item, typeSet, keys) } } } -// ExtractAllFileKeysFromContent extracts both image and archive file keys from content -func ExtractAllFileKeysFromContent(content string) ([]string, error) { - imageKeys, err := ExtractImageKeysFromContent(content) - if err != nil { - return nil, err - } - - archiveKeys, err := ExtractArchiveKeysFromContent(content) - if err != nil { - return nil, err - } - - // Combine both slices - allKeys := append(imageKeys, archiveKeys...) - return allKeys, nil -} - // ExtractHashtagsFromContent parses the rich text JSON and extracts all hashtag text values func ExtractHashtagsFromContent(content string) ([]string, error) { var contentData map[string]interface{}