mirror of
https://github.com/wgh136/nysoure.git
synced 2025-09-27 12:17:24 +00:00
Add tag alias management functionality
This commit is contained in:
@@ -180,12 +180,44 @@ func getOrCreateTags(c fiber.Ctx) error {
|
||||
})
|
||||
}
|
||||
|
||||
func editTagAlias(c fiber.Ctx) error {
|
||||
uid, ok := c.Locals("uid").(uint)
|
||||
if !ok {
|
||||
return model.NewUnAuthorizedError("You must be logged in to edit tag aliases")
|
||||
}
|
||||
|
||||
idStr := c.Params("id")
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
return model.NewRequestError("Invalid tag ID")
|
||||
}
|
||||
|
||||
var req struct {
|
||||
Aliases []string `json:"aliases"`
|
||||
}
|
||||
if err := c.Bind().JSON(&req); err != nil {
|
||||
return model.NewRequestError("Invalid request format")
|
||||
}
|
||||
|
||||
tag, err := service.EditTagAlias(uid, uint(id), req.Aliases)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(model.Response[model.TagView]{
|
||||
Success: true,
|
||||
Data: *tag,
|
||||
Message: "Tag aliases updated successfully",
|
||||
})
|
||||
}
|
||||
|
||||
func AddTagRoutes(api fiber.Router) {
|
||||
tag := api.Group("/tag")
|
||||
{
|
||||
tag.Post("/", handleCreateTag)
|
||||
tag.Get("/search", handleSearchTag)
|
||||
tag.Delete("/:id", handleDeleteTag)
|
||||
tag.Put("/:id/alias", editTagAlias)
|
||||
tag.Put("/:id/info", handleSetTagInfo)
|
||||
tag.Get("/:name", handleGetTagByName)
|
||||
tag.Get("/", getAllTags)
|
||||
|
@@ -3,12 +3,16 @@ package dao
|
||||
import (
|
||||
"errors"
|
||||
"nysoure/server/model"
|
||||
"strings"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func CreateTag(tag string) (model.Tag, error) {
|
||||
// Create a new tag in the database
|
||||
if strings.Contains(tag, "%") {
|
||||
return model.Tag{}, model.NewRequestError("Tag name cannot contain '%' character")
|
||||
}
|
||||
t := model.Tag{Name: tag}
|
||||
if err := db.Create(&t).Error; err != nil {
|
||||
return model.Tag{}, err
|
||||
@@ -18,6 +22,9 @@ func CreateTag(tag string) (model.Tag, error) {
|
||||
|
||||
func CreateTagWithType(tag string, tagType string) (model.Tag, error) {
|
||||
// Create a new tag with a specific type in the database
|
||||
if strings.Contains(tag, "%") {
|
||||
return model.Tag{}, model.NewRequestError("Tag name cannot contain '%' character")
|
||||
}
|
||||
t := model.Tag{Name: tag, Type: tagType}
|
||||
if err := db.Create(&t).Error; err != nil {
|
||||
return model.Tag{}, err
|
||||
@@ -101,3 +108,35 @@ func ListTags() ([]model.Tag, error) {
|
||||
}
|
||||
return tags, nil
|
||||
}
|
||||
|
||||
// SetTagAlias sets a tag with the given ID having the given alias.
|
||||
func SetTagAlias(tagID uint, alias string) error {
|
||||
// Set a tag as an alias of another tag
|
||||
var t model.Tag
|
||||
if err := db.Where("name = ?", alias).First(&t).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
// create
|
||||
newTag, err := CreateTag(alias)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t = newTag
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if t.ID == tagID {
|
||||
return model.NewRequestError("Tag cannot be an alias of itself")
|
||||
}
|
||||
return db.Model(&t).Update("alias_of", tagID).Error
|
||||
}
|
||||
|
||||
// RemoveTagAliasOf sets a tag is an independent tag, removing its alias relationship.
|
||||
func RemoveTagAliasOf(tagID uint) error {
|
||||
// Remove the alias of a tag
|
||||
return db.Model(&model.Tag{
|
||||
Model: gorm.Model{
|
||||
ID: tagID,
|
||||
},
|
||||
}).Update("alias_of", nil).Error
|
||||
}
|
||||
|
@@ -4,6 +4,8 @@ import (
|
||||
"github.com/gofiber/fiber/v3/log"
|
||||
"nysoure/server/dao"
|
||||
"nysoure/server/model"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func CreateTag(uid uint, name string) (*model.TagView, error) {
|
||||
@@ -161,3 +163,68 @@ func GetOrCreateTags(uid uint, names []string, tagType string) ([]model.TagView,
|
||||
}
|
||||
return tags, updateCachedTagList()
|
||||
}
|
||||
|
||||
func EditTagAlias(uid uint, tagID uint, aliases []string) (*model.TagView, error) {
|
||||
canUpload, err := checkUserCanUpload(uid)
|
||||
if err != nil {
|
||||
log.Error("Error checking user permissions:", err)
|
||||
return nil, model.NewInternalServerError("Error checking user permissions")
|
||||
}
|
||||
if !canUpload {
|
||||
return nil, model.NewUnAuthorizedError("User cannot create tags")
|
||||
}
|
||||
|
||||
tag, err := dao.GetTagByID(tagID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if tag.AliasOf != nil {
|
||||
return nil, model.NewRequestError("Cannot edit aliases of a tag that is an alias of another tag")
|
||||
}
|
||||
|
||||
// trim params
|
||||
for i, alias := range aliases {
|
||||
aliases[i] = strings.TrimSpace(alias)
|
||||
if aliases[i] == "" {
|
||||
return nil, model.NewRequestError("Alias cannot be empty")
|
||||
}
|
||||
}
|
||||
|
||||
// new aliases
|
||||
for _, name := range aliases {
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
exists := false
|
||||
for _, alias := range tag.Aliases {
|
||||
if alias.Name == name {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !exists {
|
||||
err := dao.SetTagAlias(tagID, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove old aliases
|
||||
for _, alias := range tag.Aliases {
|
||||
if !slices.Contains(aliases, alias.Name) {
|
||||
err := dao.RemoveTagAliasOf(alias.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t, err := dao.GetTagByID(tagID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return t.ToView(), updateCachedTagList()
|
||||
}
|
||||
|
Reference in New Issue
Block a user