115 lines
3.6 KiB
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
|
|
}
|