Files
ttstd-infinite-canvas/backend/internal/tools/repository.go

57 lines
1.6 KiB
Go

package tools
import (
"encoding/json"
"regexp"
"strings"
"time"
"yingce/backend/internal/model"
)
// ToolWithFavorite 列表查询结果:工具 + 当前用户收藏状态。
type ToolWithFavorite struct {
Tool model.Tool
Favorited bool
FavoritedAt *time.Time
}
// Repository 定义 tools 域需要的持久化接口,由 repository.Repository 实现。
type Repository interface {
UpsertBuiltinTools(tools []model.Tool) error
ListTools(userID string, req ToolListRequest) ([]ToolWithFavorite, int64, error)
ToolForUser(userID string, toolID int64) (model.Tool, error)
ToolFavorited(userID string, toolID int64) (model.Tool, *time.Time, error)
AddToolFavorite(userID string, toolID int64) error
RemoveToolFavorite(userID string, toolID int64) error
CreateTool(tool *model.Tool) (*model.Tool, error)
DeleteUserTool(userID string, toolID int64) error
}
var labelEnPattern = regexp.MustCompile(`[^a-zA-Z0-9_]+`)
// sanitizeLabelEn 从中文名称生成英文标识:取拼音不可行时用时间戳保证唯一性由数据库自增 ID 兜底。
func sanitizeLabelEn(label string) string {
normalized := labelEnPattern.ReplaceAllString(strings.ToLower(label), "_")
normalized = strings.Trim(normalized, "_")
if normalized == "" {
normalized = "custom_tool"
}
return normalized
}
func marshalExtraInfo(items []string) ([]byte, error) {
return json.Marshal(items)
}
func decodeExtraInfo(raw string) []string {
if strings.TrimSpace(raw) == "" {
return []string{}
}
var items []string
if err := json.Unmarshal([]byte(raw), &items); err != nil {
return []string{}
}
return items
}