mirror of
https://github.com/ctwj/urldb.git
synced 2025-11-25 03:15:04 +08:00
312 lines
10 KiB
Go
312 lines
10 KiB
Go
package handlers
|
||
|
||
import (
|
||
"net/http"
|
||
"strconv"
|
||
"github.com/ctwj/urldb/db/converter"
|
||
"github.com/ctwj/urldb/db/dto"
|
||
"github.com/ctwj/urldb/db/entity"
|
||
"github.com/ctwj/urldb/db/repo"
|
||
"github.com/ctwj/urldb/middleware"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
"github.com/go-playground/validator/v10"
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
type CopyrightClaimHandler struct {
|
||
copyrightClaimRepo repo.CopyrightClaimRepository
|
||
resourceRepo repo.ResourceRepository
|
||
validate *validator.Validate
|
||
}
|
||
|
||
func NewCopyrightClaimHandler(copyrightClaimRepo repo.CopyrightClaimRepository, resourceRepo repo.ResourceRepository) *CopyrightClaimHandler {
|
||
return &CopyrightClaimHandler{
|
||
copyrightClaimRepo: copyrightClaimRepo,
|
||
resourceRepo: resourceRepo,
|
||
validate: validator.New(),
|
||
}
|
||
}
|
||
|
||
// CreateCopyrightClaim 创建版权申述
|
||
// @Summary 创建版权申述
|
||
// @Description 提交资源版权申述
|
||
// @Tags CopyrightClaim
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param request body dto.CopyrightClaimCreateRequest true "版权申述信息"
|
||
// @Success 200 {object} Response{data=dto.CopyrightClaimResponse}
|
||
// @Failure 400 {object} Response
|
||
// @Failure 500 {object} Response
|
||
// @Router /copyright-claims [post]
|
||
func (h *CopyrightClaimHandler) CreateCopyrightClaim(c *gin.Context) {
|
||
var req dto.CopyrightClaimCreateRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
ErrorResponse(c, "参数错误: "+err.Error(), http.StatusBadRequest)
|
||
return
|
||
}
|
||
|
||
// 验证参数
|
||
if err := h.validate.Struct(req); err != nil {
|
||
ErrorResponse(c, "参数验证失败: "+err.Error(), http.StatusBadRequest)
|
||
return
|
||
}
|
||
|
||
// 创建版权申述实体
|
||
claim := &entity.CopyrightClaim{
|
||
ResourceKey: req.ResourceKey,
|
||
Identity: req.Identity,
|
||
ProofType: req.ProofType,
|
||
Reason: req.Reason,
|
||
ContactInfo: req.ContactInfo,
|
||
ClaimantName: req.ClaimantName,
|
||
ProofFiles: req.ProofFiles,
|
||
UserAgent: req.UserAgent,
|
||
IPAddress: req.IPAddress,
|
||
Status: "pending", // 默认为待处理
|
||
}
|
||
|
||
// 保存到数据库
|
||
if err := h.copyrightClaimRepo.Create(claim); err != nil {
|
||
ErrorResponse(c, "创建版权申述失败: "+err.Error(), http.StatusInternalServerError)
|
||
return
|
||
}
|
||
|
||
// 返回响应
|
||
response := converter.CopyrightClaimToResponse(claim)
|
||
SuccessResponse(c, response)
|
||
}
|
||
|
||
// GetCopyrightClaim 获取版权申述详情
|
||
// @Summary 获取版权申述详情
|
||
// @Description 根据ID获取版权申述详情
|
||
// @Tags CopyrightClaim
|
||
// @Produce json
|
||
// @Param id path int true "版权申述ID"
|
||
// @Success 200 {object} Response{data=dto.CopyrightClaimResponse}
|
||
// @Failure 400 {object} Response
|
||
// @Failure 404 {object} Response
|
||
// @Failure 500 {object} Response
|
||
// @Router /copyright-claims/{id} [get]
|
||
func (h *CopyrightClaimHandler) GetCopyrightClaim(c *gin.Context) {
|
||
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
||
if err != nil {
|
||
ErrorResponse(c, "无效的ID", http.StatusBadRequest)
|
||
return
|
||
}
|
||
|
||
claim, err := h.copyrightClaimRepo.GetByID(uint(id))
|
||
if err != nil {
|
||
if err == gorm.ErrRecordNotFound {
|
||
ErrorResponse(c, "版权申述不存在", http.StatusNotFound)
|
||
return
|
||
}
|
||
ErrorResponse(c, "获取版权申述失败: "+err.Error(), http.StatusInternalServerError)
|
||
return
|
||
}
|
||
|
||
SuccessResponse(c, converter.CopyrightClaimToResponse(claim))
|
||
}
|
||
|
||
// ListCopyrightClaims 获取版权申述列表
|
||
// @Summary 获取版权申述列表
|
||
// @Description 获取版权申述列表(支持分页和状态筛选)
|
||
// @Tags CopyrightClaim
|
||
// @Produce json
|
||
// @Param page query int false "页码" default(1)
|
||
// @Param page_size query int false "每页数量" default(10)
|
||
// @Param status query string false "处理状态"
|
||
// @Success 200 {object} Response{data=object{items=[]dto.CopyrightClaimResponse,total=int}}
|
||
// @Failure 400 {object} Response
|
||
// @Failure 500 {object} Response
|
||
// @Router /copyright-claims [get]
|
||
func (h *CopyrightClaimHandler) ListCopyrightClaims(c *gin.Context) {
|
||
var req dto.CopyrightClaimListRequest
|
||
if err := c.ShouldBindQuery(&req); err != nil {
|
||
ErrorResponse(c, "参数错误: "+err.Error(), http.StatusBadRequest)
|
||
return
|
||
}
|
||
|
||
// 设置默认值
|
||
if req.Page == 0 {
|
||
req.Page = 1
|
||
}
|
||
if req.PageSize == 0 {
|
||
req.PageSize = 10
|
||
}
|
||
|
||
// 验证参数
|
||
if err := h.validate.Struct(req); err != nil {
|
||
ErrorResponse(c, "参数验证失败: "+err.Error(), http.StatusBadRequest)
|
||
return
|
||
}
|
||
|
||
claims, total, err := h.copyrightClaimRepo.List(req.Status, req.Page, req.PageSize)
|
||
if err != nil {
|
||
ErrorResponse(c, "获取版权申述列表失败: "+err.Error(), http.StatusInternalServerError)
|
||
return
|
||
}
|
||
|
||
// 转换为包含资源信息的响应
|
||
var responses []*dto.CopyrightClaimResponse
|
||
for _, claim := range claims {
|
||
// 查询关联的资源信息
|
||
resources, err := h.getResourcesByResourceKey(claim.ResourceKey)
|
||
if err != nil {
|
||
// 如果查询资源失败,使用空资源列表
|
||
responses = append(responses, converter.CopyrightClaimToResponse(claim))
|
||
} else {
|
||
// 使用包含资源详情的转换函数
|
||
responses = append(responses, converter.CopyrightClaimToResponseWithResources(claim, resources))
|
||
}
|
||
}
|
||
|
||
PageResponse(c, responses, total, req.Page, req.PageSize)
|
||
}
|
||
|
||
// getResourcesByResourceKey 根据资源key获取关联的资源列表
|
||
func (h *CopyrightClaimHandler) getResourcesByResourceKey(resourceKey string) ([]*entity.Resource, error) {
|
||
// 从资源仓库获取与key关联的所有资源
|
||
resources, err := h.resourceRepo.FindByResourceKey(resourceKey)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
// 将 []entity.Resource 转换为 []*entity.Resource
|
||
var resourcePointers []*entity.Resource
|
||
for i := range resources {
|
||
resourcePointers = append(resourcePointers, &resources[i])
|
||
}
|
||
|
||
return resourcePointers, nil
|
||
}
|
||
|
||
// UpdateCopyrightClaim 更新版权申述状态
|
||
// @Summary 更新版权申述状态
|
||
// @Description 更新版权申述处理状态
|
||
// @Tags CopyrightClaim
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param id path int true "版权申述ID"
|
||
// @Param request body dto.CopyrightClaimUpdateRequest true "更新信息"
|
||
// @Success 200 {object} Response{data=dto.CopyrightClaimResponse}
|
||
// @Failure 400 {object} Response
|
||
// @Failure 404 {object} Response
|
||
// @Failure 500 {object} Response
|
||
// @Router /copyright-claims/{id} [put]
|
||
func (h *CopyrightClaimHandler) UpdateCopyrightClaim(c *gin.Context) {
|
||
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
||
if err != nil {
|
||
ErrorResponse(c, "无效的ID", http.StatusBadRequest)
|
||
return
|
||
}
|
||
|
||
var req dto.CopyrightClaimUpdateRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
ErrorResponse(c, "参数错误: "+err.Error(), http.StatusBadRequest)
|
||
return
|
||
}
|
||
|
||
// 验证参数
|
||
if err := h.validate.Struct(req); err != nil {
|
||
ErrorResponse(c, "参数验证失败: "+err.Error(), http.StatusBadRequest)
|
||
return
|
||
}
|
||
|
||
// 获取当前版权申述
|
||
_, err = h.copyrightClaimRepo.GetByID(uint(id))
|
||
if err != nil {
|
||
if err == gorm.ErrRecordNotFound {
|
||
ErrorResponse(c, "版权申述不存在", http.StatusNotFound)
|
||
return
|
||
}
|
||
ErrorResponse(c, "获取版权申述失败: "+err.Error(), http.StatusInternalServerError)
|
||
return
|
||
}
|
||
|
||
// 更新状态
|
||
processedBy := uint(0) // 从上下文获取当前用户ID,如果存在的话
|
||
if currentUser := c.GetUint("user_id"); currentUser > 0 {
|
||
processedBy = currentUser
|
||
}
|
||
|
||
if err := h.copyrightClaimRepo.UpdateStatus(uint(id), req.Status, &processedBy, req.Note); err != nil {
|
||
ErrorResponse(c, "更新版权申述状态失败: "+err.Error(), http.StatusInternalServerError)
|
||
return
|
||
}
|
||
|
||
// 获取更新后的版权申述信息
|
||
updatedClaim, err := h.copyrightClaimRepo.GetByID(uint(id))
|
||
if err != nil {
|
||
ErrorResponse(c, "获取更新后版权申述信息失败: "+err.Error(), http.StatusInternalServerError)
|
||
return
|
||
}
|
||
|
||
SuccessResponse(c, converter.CopyrightClaimToResponse(updatedClaim))
|
||
}
|
||
|
||
// DeleteCopyrightClaim 删除版权申述
|
||
// @Summary 删除版权申述
|
||
// @Description 删除版权申述记录
|
||
// @Tags CopyrightClaim
|
||
// @Produce json
|
||
// @Param id path int true "版权申述ID"
|
||
// @Success 200 {object} Response
|
||
// @Failure 400 {object} Response
|
||
// @Failure 500 {object} Response
|
||
// @Router /copyright-claims/{id} [delete]
|
||
func (h *CopyrightClaimHandler) DeleteCopyrightClaim(c *gin.Context) {
|
||
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
||
if err != nil {
|
||
ErrorResponse(c, "无效的ID", http.StatusBadRequest)
|
||
return
|
||
}
|
||
|
||
if err := h.copyrightClaimRepo.Delete(uint(id)); err != nil {
|
||
ErrorResponse(c, "删除版权申述失败: "+err.Error(), http.StatusInternalServerError)
|
||
return
|
||
}
|
||
|
||
SuccessResponse(c, nil)
|
||
}
|
||
|
||
// GetCopyrightClaimByResource 获取某个资源的版权申述列表
|
||
// @Summary 获取资源版权申述列表
|
||
// @Description 获取某个资源的所有版权申述记录
|
||
// @Tags CopyrightClaim
|
||
// @Produce json
|
||
// @Param resource_key path string true "资源Key"
|
||
// @Success 200 {object} Response{data=[]dto.CopyrightClaimResponse}
|
||
// @Failure 400 {object} Response
|
||
// @Failure 500 {object} Response
|
||
// @Router /copyright-claims/resource/{resource_key} [get]
|
||
func (h *CopyrightClaimHandler) GetCopyrightClaimByResource(c *gin.Context) {
|
||
resourceKey := c.Param("resource_key")
|
||
if resourceKey == "" {
|
||
ErrorResponse(c, "资源Key不能为空", http.StatusBadRequest)
|
||
return
|
||
}
|
||
|
||
claims, err := h.copyrightClaimRepo.GetByResourceKey(resourceKey)
|
||
if err != nil {
|
||
ErrorResponse(c, "获取资源版权申述失败: "+err.Error(), http.StatusInternalServerError)
|
||
return
|
||
}
|
||
|
||
SuccessResponse(c, converter.CopyrightClaimsToResponse(claims))
|
||
}
|
||
|
||
// RegisterCopyrightClaimRoutes 注册版权申述相关路由
|
||
func RegisterCopyrightClaimRoutes(router *gin.RouterGroup, copyrightClaimRepo repo.CopyrightClaimRepository, resourceRepo repo.ResourceRepository) {
|
||
handler := NewCopyrightClaimHandler(copyrightClaimRepo, resourceRepo)
|
||
|
||
claims := router.Group("/copyright-claims")
|
||
{
|
||
claims.POST("", handler.CreateCopyrightClaim) // 创建版权申述
|
||
claims.GET("/:id", handler.GetCopyrightClaim) // 获取版权申述详情
|
||
claims.GET("", middleware.AuthMiddleware(), middleware.AdminMiddleware(), handler.ListCopyrightClaims) // 获取版权申述列表
|
||
claims.PUT("/:id", middleware.AuthMiddleware(), middleware.AdminMiddleware(), handler.UpdateCopyrightClaim) // 更新版权申述状态
|
||
claims.DELETE("/:id", middleware.AuthMiddleware(), middleware.AdminMiddleware(), handler.DeleteCopyrightClaim) // 删除版权申述
|
||
claims.GET("/resource/:resource_key", handler.GetCopyrightClaimByResource) // 获取资源版权申述列表
|
||
}
|
||
} |