Files
ttstd-infinite-canvas/backend/internal/canvas/user_data_page.go

115 lines
3.6 KiB
Go

package canvas
import (
"encoding/json"
"infinite-canvas/backend/internal/kernel"
"strings"
"time"
)
func (s *Service) UserAssetsByIDs(userID string, ids []string) ([]json.RawMessage, error) {
if len(ids) > 100 {
return nil, kernel.BadAuthRequest("每次最多读取 100 个素材")
}
unique := make([]string, 0, len(ids))
seen := make(map[string]bool, len(ids))
for _, id := range ids {
id = strings.TrimSpace(id)
if id == "" || len(id) > 80 {
return nil, kernel.BadAuthRequest("素材 ID 无效")
}
if !seen[id] {
seen[id] = true
unique = append(unique, id)
}
}
assets, err := s.repo.AssetsForUserIDs(userID, unique)
if err != nil {
return nil, err
}
result := make([]json.RawMessage, 0, len(assets))
for _, asset := range assets {
if payload := ClientAssetPayload(asset); len(payload) > 0 {
result = append(result, payload)
}
}
return result, nil
}
type CanvasLibrarySummary struct {
ID string `json:"id"`
ProjectID string `json:"projectId,omitempty"`
Title string `json:"title"`
Revision int64 `json:"revision"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
NodeCount int `json:"nodeCount"`
PreviewNodes []map[string]any `json:"previewNodes"`
}
type CanvasLibraryPage struct {
Projects []CanvasLibrarySummary `json:"projects"`
Page int `json:"page"`
PageSize int `json:"pageSize"`
Total int64 `json:"total"`
HasMore bool `json:"hasMore"`
}
func (s *Service) UserCanvasProjectsPage(userID string, page int, pageSize int, projectID string, search string, sort string) (CanvasLibraryPage, error) {
if page < 1 {
page = 1
}
if page > 1000000 {
return CanvasLibraryPage{}, kernel.BadAuthRequest("页码超出范围")
}
if pageSize < 1 {
pageSize = 40
}
if pageSize > 50 {
pageSize = 50
}
projects, total, err := s.repo.UserCanvasProjectsPage(userID, page, pageSize, projectID, search, sort)
if err != nil {
return CanvasLibraryPage{}, err
}
result := CanvasLibraryPage{Projects: make([]CanvasLibrarySummary, 0, len(projects)), Page: page, PageSize: pageSize, Total: total, HasMore: int64(page)*int64(pageSize) < total}
for _, project := range projects {
var document struct {
Nodes []map[string]any `json:"nodes"`
}
if err := json.Unmarshal([]byte(project.PayloadJSON), &document); err != nil {
return CanvasLibraryPage{}, err
}
preview := make([]map[string]any, 0, 4)
for _, node := range document.Nodes {
if len(preview) == 4 {
break
}
if node["type"] != "image" && node["type"] != "video" {
continue
}
item := map[string]any{"position": map[string]int{"x": 0, "y": 0}}
for _, key := range []string{"id", "type", "title"} {
if value, ok := node[key].(string); ok {
item[key] = string([]rune(value)[:min(len([]rune(value)), 256)])
}
}
for _, key := range []string{"width", "height"} {
if value, ok := node[key].(float64); ok {
item[key] = value
}
}
metadata := map[string]any{}
if original, ok := node["metadata"].(map[string]any); ok {
if key, ok := original["storageKey"].(string); ok && len(key) <= 512 {
metadata["storageKey"] = key
}
}
item["metadata"] = metadata
preview = append(preview, item)
}
result.Projects = append(result.Projects, CanvasLibrarySummary{ID: project.ID, ProjectID: project.ProjectID, Title: project.Title, Revision: project.Revision, CreatedAt: project.CreatedAt, UpdatedAt: project.UpdatedAt, NodeCount: len(document.Nodes), PreviewNodes: preview})
}
return result, nil
}