mirror of
https://github.com/wgh136/nysoure.git
synced 2025-09-27 04:17:23 +00:00
Add collection api.
This commit is contained in:
145
server/service/collection.go
Normal file
145
server/service/collection.go
Normal file
@@ -0,0 +1,145 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"nysoure/server/dao"
|
||||
"nysoure/server/model"
|
||||
)
|
||||
|
||||
// Create a new collection.
|
||||
func CreateCollection(uid uint, title, article string, host string) (*model.CollectionView, error) {
|
||||
if uid == 0 || title == "" || article == "" {
|
||||
return nil, errors.New("invalid parameters")
|
||||
}
|
||||
c, err := dao.CreateCollection(uid, title, article, findImagesInContent(article, host))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
view := c.ToView()
|
||||
return view, nil
|
||||
}
|
||||
|
||||
// Update an existing collection with user validation.
|
||||
func UpdateCollection(uid, id uint, title, article string, host string) error {
|
||||
if uid == 0 || id == 0 || title == "" || article == "" {
|
||||
return errors.New("invalid parameters")
|
||||
}
|
||||
collection, err := dao.GetCollectionByID(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if collection.UserID != uid {
|
||||
return errors.New("user does not have permission to update this collection")
|
||||
}
|
||||
return dao.UpdateCollection(id, title, article, findImagesInContent(article, host))
|
||||
}
|
||||
|
||||
// Delete a collection by ID.
|
||||
func DeleteCollection(uint, id uint) error {
|
||||
user, err := dao.GetUserByID(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
collection, err := dao.GetCollectionByID(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if user.ID != collection.UserID && !user.IsAdmin {
|
||||
return errors.New("user does not have permission to delete this collection")
|
||||
}
|
||||
|
||||
return dao.DeleteCollection(id)
|
||||
}
|
||||
|
||||
// Add a resource to a collection with user validation.
|
||||
func AddResourceToCollection(uid, collectionID, resourceID uint) error {
|
||||
if uid == 0 || collectionID == 0 || resourceID == 0 {
|
||||
return errors.New("invalid parameters")
|
||||
}
|
||||
collection, err := dao.GetCollectionByID(collectionID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if collection.UserID != uid {
|
||||
return errors.New("user does not have permission to modify this collection")
|
||||
}
|
||||
return dao.AddResourceToCollection(collectionID, resourceID)
|
||||
}
|
||||
|
||||
// Remove a resource from a collection with user validation.
|
||||
func RemoveResourceFromCollection(uid, collectionID, resourceID uint) error {
|
||||
if uid == 0 || collectionID == 0 || resourceID == 0 {
|
||||
return errors.New("invalid parameters")
|
||||
}
|
||||
collection, err := dao.GetCollectionByID(collectionID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if collection.UserID != uid {
|
||||
return errors.New("user does not have permission to modify this collection")
|
||||
}
|
||||
return dao.RemoveResourceFromCollection(collectionID, resourceID)
|
||||
}
|
||||
|
||||
// Get a collection by ID.
|
||||
func GetCollectionByID(id uint) (*model.CollectionView, error) {
|
||||
if id == 0 {
|
||||
return nil, errors.New("invalid collection id")
|
||||
}
|
||||
c, err := dao.GetCollectionByID(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.ToView(), nil
|
||||
}
|
||||
|
||||
// List collections of a user with pagination.
|
||||
func ListUserCollections(uid uint, page int) ([]*model.CollectionView, int64, error) {
|
||||
if uid == 0 || page < 1 {
|
||||
return nil, 0, errors.New("invalid parameters")
|
||||
}
|
||||
collections, total, err := dao.ListUserCollections(uid, page, pageSize)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
var views []*model.CollectionView
|
||||
for _, c := range collections {
|
||||
views = append(views, c.ToView())
|
||||
}
|
||||
return views, total, nil
|
||||
}
|
||||
|
||||
// List resources in a collection with pagination.
|
||||
func ListCollectionResources(collectionID uint, page int) ([]*model.ResourceView, int64, error) {
|
||||
if collectionID == 0 || page < 1 {
|
||||
return nil, 0, errors.New("invalid parameters")
|
||||
}
|
||||
resources, total, err := dao.ListCollectionResources(collectionID, page, pageSize)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
var views []*model.ResourceView
|
||||
for _, r := range resources {
|
||||
v := r.ToView()
|
||||
views = append(views, &v)
|
||||
}
|
||||
return views, total, nil
|
||||
}
|
||||
|
||||
// Search user collections by keyword, limited to 10 results.
|
||||
func SearchUserCollections(uid uint, keyword string) ([]*model.CollectionView, error) {
|
||||
if uid == 0 || keyword == "" {
|
||||
return nil, errors.New("invalid parameters")
|
||||
}
|
||||
collections, err := dao.SearchUserCollections(uid, keyword)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var views []*model.CollectionView
|
||||
for _, c := range collections {
|
||||
views = append(views, c.ToView())
|
||||
}
|
||||
return views, nil
|
||||
}
|
@@ -4,7 +4,6 @@ import (
|
||||
"nysoure/server/dao"
|
||||
"nysoure/server/model"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v3/log"
|
||||
@@ -22,39 +21,6 @@ type CommentRequest struct {
|
||||
// Images []uint `json:"images"` // Unrequired after new design
|
||||
}
|
||||
|
||||
func findImagesInContent(content string, host string) []uint {
|
||||
// Handle both absolute and relative URLs
|
||||
absolutePattern := `!\[.*?\]\((?:https?://` + host + `)?/api/image/(\d+)(?:\s+["'].*?["'])?\)`
|
||||
relativePattern := `!\[.*?\]\(/api/image/(\d+)(?:\s+["'].*?["'])?\)`
|
||||
|
||||
// Combine patterns and compile regex
|
||||
patterns := []string{absolutePattern, relativePattern}
|
||||
|
||||
// Store unique image IDs to avoid duplicates
|
||||
imageIDs := make(map[uint]struct{})
|
||||
|
||||
for _, pattern := range patterns {
|
||||
re := regexp.MustCompile(pattern)
|
||||
matches := re.FindAllStringSubmatch(content, -1)
|
||||
|
||||
for _, match := range matches {
|
||||
if len(match) >= 2 {
|
||||
if id, err := strconv.ParseUint(match[1], 10, 32); err == nil {
|
||||
imageIDs[uint(id)] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert map keys to slice
|
||||
result := make([]uint, 0, len(imageIDs))
|
||||
for id := range imageIDs {
|
||||
result = append(result, id)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func CreateComment(req CommentRequest, userID uint, refID uint, ip string, cType model.CommentType, host string) (*model.CommentView, error) {
|
||||
if len(req.Content) == 0 {
|
||||
return nil, model.NewRequestError("Content cannot be empty")
|
||||
|
@@ -6,6 +6,8 @@ import (
|
||||
"net/http"
|
||||
"nysoure/server/config"
|
||||
"nysoure/server/dao"
|
||||
"regexp"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func checkUserCanUpload(uid uint) (bool, error) {
|
||||
@@ -58,3 +60,36 @@ func verifyCfToken(cfToken string) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
func findImagesInContent(content string, host string) []uint {
|
||||
// Handle both absolute and relative URLs
|
||||
absolutePattern := `!\[.*?\]\((?:https?://` + host + `)?/api/image/(\d+)(?:\s+["'].*?["'])?\)`
|
||||
relativePattern := `!\[.*?\]\(/api/image/(\d+)(?:\s+["'].*?["'])?\)`
|
||||
|
||||
// Combine patterns and compile regex
|
||||
patterns := []string{absolutePattern, relativePattern}
|
||||
|
||||
// Store unique image IDs to avoid duplicates
|
||||
imageIDs := make(map[uint]struct{})
|
||||
|
||||
for _, pattern := range patterns {
|
||||
re := regexp.MustCompile(pattern)
|
||||
matches := re.FindAllStringSubmatch(content, -1)
|
||||
|
||||
for _, match := range matches {
|
||||
if len(match) >= 2 {
|
||||
if id, err := strconv.ParseUint(match[1], 10, 32); err == nil {
|
||||
imageIDs[uint(id)] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert map keys to slice
|
||||
result := make([]uint, 0, len(imageIDs))
|
||||
for id := range imageIDs {
|
||||
result = append(result, id)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
Reference in New Issue
Block a user