diff --git a/server/api/resource.go b/server/api/resource.go index 8dbde5e..83888c0 100644 --- a/server/api/resource.go +++ b/server/api/resource.go @@ -312,7 +312,7 @@ func handleUpdateCharacterImage(c fiber.Ctx) error { if err != nil { return model.NewRequestError("Invalid character ID") } - + var params struct { ImageID uint `json:"image_id"` } @@ -321,17 +321,17 @@ func handleUpdateCharacterImage(c fiber.Ctx) error { if err != nil { return model.NewRequestError("Invalid request body") } - + uid, ok := c.Locals("uid").(uint) if !ok { return model.NewUnAuthorizedError("You must be logged in to update a character") } - + err = service.UpdateCharacterImage(uid, uint(resourceId), uint(characterId), params.ImageID) if err != nil { return err } - + return c.Status(fiber.StatusOK).JSON(model.Response[any]{ Success: true, Data: nil, @@ -339,6 +339,51 @@ func handleUpdateCharacterImage(c fiber.Ctx) error { }) } +func handleGetLowResolutionCharacters(c fiber.Ctx) error { + pageStr := c.Query("page") + if pageStr == "" { + pageStr = "1" + } + page, err := strconv.Atoi(pageStr) + if err != nil { + return model.NewRequestError("Invalid page number") + } + + maxWidthStr := c.Query("max_width") + if maxWidthStr == "" { + maxWidthStr = "800" // 默认最大宽度800px + } + maxWidth, err := strconv.Atoi(maxWidthStr) + if err != nil { + return model.NewRequestError("Invalid max_width parameter") + } + + maxHeightStr := c.Query("max_height") + if maxHeightStr == "" { + maxHeightStr = "800" // 默认最大高度800px + } + maxHeight, err := strconv.Atoi(maxHeightStr) + if err != nil { + return model.NewRequestError("Invalid max_height parameter") + } + + characters, totalPages, err := service.GetLowResolutionCharacters(page, maxWidth, maxHeight) + if err != nil { + return err + } + + if characters == nil { + characters = []model.LowResCharacterView{} + } + + return c.Status(fiber.StatusOK).JSON(model.PageResponse[model.LowResCharacterView]{ + Success: true, + Data: characters, + TotalPages: totalPages, + Message: "Low resolution characters retrieved successfully", + }) +} + func AddResourceRoutes(api fiber.Router) { resource := api.Group("/resource") { @@ -348,6 +393,7 @@ func AddResourceRoutes(api fiber.Router) { resource.Get("/random", handleGetRandomResource) resource.Get("/pinned", handleGetPinnedResources) resource.Get("/vndb/characters", handleGetCharactersFromVndb) + resource.Get("/characters/low-resolution", handleGetLowResolutionCharacters) resource.Get("/:id", handleGetResource) resource.Delete("/:id", handleDeleteResource) resource.Get("/tag/:tag", handleListResourcesWithTag) diff --git a/server/dao/resource.go b/server/dao/resource.go index 1bb4ca4..01e8059 100644 --- a/server/dao/resource.go +++ b/server/dao/resource.go @@ -544,3 +544,52 @@ func UpdateCharacterImage(characterID, imageID uint) error { } return nil } + +// GetLowResolutionCharacters 获取低清晰度的角色图片 +// maxWidth和maxHeight定义了低清晰度的阈值 +func GetLowResolutionCharacters(maxWidth, maxHeight int, limit int, offset int) ([]model.LowResCharacterView, error) { + var results []model.LowResCharacterView + + query := ` + SELECT + c.id as character_id, + c.resource_id as resource_id, + c.name as name, + i.id as image_id, + i.width as image_width, + i.height as image_height + FROM characters c + INNER JOIN images i ON c.image_id = i.id + WHERE (i.width <= ? OR i.height <= ?) + AND c.image_id IS NOT NULL + ORDER BY c.id + LIMIT ? OFFSET ? + ` + + err := db.Raw(query, maxWidth, maxHeight, limit, offset).Scan(&results).Error + if err != nil { + return nil, err + } + + return results, nil +} + +// GetLowResolutionCharactersCount 获取低清晰度角色的总数 +func GetLowResolutionCharactersCount(maxWidth, maxHeight int) (int64, error) { + var count int64 + + query := ` + SELECT COUNT(*) + FROM characters c + INNER JOIN images i ON c.image_id = i.id + WHERE (i.width <= ? OR i.height <= ?) + AND c.image_id IS NOT NULL + ` + + err := db.Raw(query, maxWidth, maxHeight).Scan(&count).Error + if err != nil { + return 0, err + } + + return count, nil +} diff --git a/server/model/character.go b/server/model/character.go index 91cbca4..0e294d6 100644 --- a/server/model/character.go +++ b/server/model/character.go @@ -20,6 +20,15 @@ type CharacterView struct { Image uint `json:"image"` } +type LowResCharacterView struct { + CharacterID uint `json:"character_id"` + ResourceID uint `json:"resource_id"` + Name string `json:"name"` + ImageID uint `json:"image_id"` + ImageWidth int `json:"image_width"` + ImageHeight int `json:"image_height"` +} + func (c *Character) ToView() *CharacterView { var imageID uint if c.ImageID != nil { diff --git a/server/service/resource.go b/server/service/resource.go index 6a5358d..f55a21c 100644 --- a/server/service/resource.go +++ b/server/service/resource.go @@ -801,3 +801,30 @@ func UpdateCharacterImage(uid, resourceID, characterID, imageID uint) error { return nil } + +// GetLowResolutionCharacters 获取低清晰度的角色图片 +func GetLowResolutionCharacters(page int, maxWidth, maxHeight int) ([]model.LowResCharacterView, int, error) { + const pageSize = 50 // 每页50个角色 + + if page <= 0 { + page = 1 + } + + offset := (page - 1) * pageSize + + // 获取角色列表 + characters, err := dao.GetLowResolutionCharacters(maxWidth, maxHeight, pageSize, offset) + if err != nil { + return nil, 0, err + } + + // 获取总数 + totalCount, err := dao.GetLowResolutionCharactersCount(maxWidth, maxHeight) + if err != nil { + return nil, 0, err + } + + totalPages := int((totalCount + int64(pageSize) - 1) / int64(pageSize)) + + return characters, totalPages, nil +}