Files
tyapi-server/internal/infrastructure/http/handlers/product_admin_handler.go
2025-07-30 00:51:22 +08:00

922 lines
33 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package handlers
import (
"strconv"
"tyapi-server/internal/application/product"
"tyapi-server/internal/application/product/dto/commands"
"tyapi-server/internal/application/product/dto/queries"
"tyapi-server/internal/application/product/dto/responses"
"tyapi-server/internal/shared/interfaces"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
// ProductAdminHandler 产品管理员HTTP处理器
type ProductAdminHandler struct {
productAppService product.ProductApplicationService
categoryAppService product.CategoryApplicationService
subscriptionAppService product.SubscriptionApplicationService
responseBuilder interfaces.ResponseBuilder
validator interfaces.RequestValidator
logger *zap.Logger
}
// NewProductAdminHandler 创建产品管理员HTTP处理器
func NewProductAdminHandler(
productAppService product.ProductApplicationService,
categoryAppService product.CategoryApplicationService,
subscriptionAppService product.SubscriptionApplicationService,
responseBuilder interfaces.ResponseBuilder,
validator interfaces.RequestValidator,
logger *zap.Logger,
) *ProductAdminHandler {
return &ProductAdminHandler{
productAppService: productAppService,
categoryAppService: categoryAppService,
subscriptionAppService: subscriptionAppService,
responseBuilder: responseBuilder,
validator: validator,
logger: logger,
}
}
// CreateProduct 创建产品
// @Summary 创建产品
// @Description 管理员创建新产品
// @Tags 产品管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param request body commands.CreateProductCommand true "创建产品请求"
// @Success 201 {object} map[string]interface{} "产品创建成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/products [post]
func (h *ProductAdminHandler) CreateProduct(c *gin.Context) {
var cmd commands.CreateProductCommand
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
return
}
if err := h.productAppService.CreateProduct(c.Request.Context(), &cmd); err != nil {
h.logger.Error("创建产品失败", zap.Error(err))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Created(c, nil, "产品创建成功")
}
// UpdateProduct 更新产品
// @Summary 更新产品
// @Description 管理员更新产品信息
// @Tags 产品管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "产品ID"
// @Param request body commands.UpdateProductCommand true "更新产品请求"
// @Success 200 {object} map[string]interface{} "产品更新成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 404 {object} map[string]interface{} "产品不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/products/{id} [put]
func (h *ProductAdminHandler) UpdateProduct(c *gin.Context) {
var cmd commands.UpdateProductCommand
cmd.ID = c.Param("id")
if cmd.ID == "" {
h.responseBuilder.BadRequest(c, "产品ID不能为空")
return
}
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
return
}
if err := h.productAppService.UpdateProduct(c.Request.Context(), &cmd); err != nil {
h.logger.Error("更新产品失败", zap.Error(err))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, nil, "产品更新成功")
}
// DeleteProduct 删除产品
// @Summary 删除产品
// @Description 管理员删除产品
// @Tags 产品管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "产品ID"
// @Success 200 {object} map[string]interface{} "产品删除成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 404 {object} map[string]interface{} "产品不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/products/{id} [delete]
func (h *ProductAdminHandler) DeleteProduct(c *gin.Context) {
var cmd commands.DeleteProductCommand
if err := h.validator.ValidateParam(c, &cmd); err != nil {
return
}
if err := h.productAppService.DeleteProduct(c.Request.Context(), &cmd); err != nil {
h.logger.Error("删除产品失败", zap.Error(err))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, nil, "产品删除成功")
}
// CreateCategory 创建分类
// @Summary 创建分类
// @Description 管理员创建新产品分类
// @Tags 分类管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param request body commands.CreateCategoryCommand true "创建分类请求"
// @Success 201 {object} map[string]interface{} "分类创建成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/product-categories [post]
func (h *ProductAdminHandler) CreateCategory(c *gin.Context) {
var cmd commands.CreateCategoryCommand
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
return
}
if err := h.categoryAppService.CreateCategory(c.Request.Context(), &cmd); err != nil {
h.logger.Error("创建分类失败", zap.Error(err))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Created(c, nil, "分类创建成功")
}
// UpdateCategory 更新分类
// @Summary 更新分类
// @Description 管理员更新产品分类信息
// @Tags 分类管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "分类ID"
// @Param request body commands.UpdateCategoryCommand true "更新分类请求"
// @Success 200 {object} map[string]interface{} "分类更新成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 404 {object} map[string]interface{} "分类不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/product-categories/{id} [put]
func (h *ProductAdminHandler) UpdateCategory(c *gin.Context) {
var cmd commands.UpdateCategoryCommand
if err := h.validator.ValidateParam(c, &cmd); err != nil {
return
}
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
return
}
if err := h.categoryAppService.UpdateCategory(c.Request.Context(), &cmd); err != nil {
h.logger.Error("更新分类失败", zap.Error(err))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, nil, "分类更新成功")
}
// DeleteCategory 删除分类
// @Summary 删除分类
// @Description 管理员删除产品分类
// @Tags 分类管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "分类ID"
// @Success 200 {object} map[string]interface{} "分类删除成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 404 {object} map[string]interface{} "分类不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/product-categories/{id} [delete]
func (h *ProductAdminHandler) DeleteCategory(c *gin.Context) {
var cmd commands.DeleteCategoryCommand
if err := h.validator.ValidateParam(c, &cmd); err != nil {
return
}
if err := h.categoryAppService.DeleteCategory(c.Request.Context(), &cmd); err != nil {
h.logger.Error("删除分类失败", zap.Error(err))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, nil, "分类删除成功")
}
// UpdateSubscriptionPrice 更新订阅价格
// @Summary 更新订阅价格
// @Description 管理员修改用户订阅价格
// @Tags 订阅管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "订阅ID"
// @Param request body commands.UpdateSubscriptionPriceCommand true "更新订阅价格请求"
// @Success 200 {object} map[string]interface{} "订阅价格更新成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 404 {object} map[string]interface{} "订阅不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/subscriptions/{id}/price [put]
func (h *ProductAdminHandler) UpdateSubscriptionPrice(c *gin.Context) {
var cmd commands.UpdateSubscriptionPriceCommand
if err := h.validator.ValidateParam(c, &cmd); err != nil {
return
}
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
return
}
if err := h.subscriptionAppService.UpdateSubscriptionPrice(c.Request.Context(), &cmd); err != nil {
h.logger.Error("更新订阅价格失败", zap.Error(err))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, nil, "订阅价格更新成功")
}
// ListProducts 获取产品列表(管理员)
// @Summary 获取产品列表
// @Description 管理员获取产品列表,支持筛选和分页,包含所有产品(包括隐藏的)
// @Tags 产品管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(10)
// @Param keyword query string false "搜索关键词"
// @Param category_id query string false "分类ID"
// @Param is_enabled query bool false "是否启用"
// @Param is_visible query bool false "是否可见"
// @Param is_package query bool false "是否组合包"
// @Param sort_by query string false "排序字段"
// @Param sort_order query string false "排序方向" Enums(asc, desc)
// @Success 200 {object} responses.ProductAdminListResponse "获取产品列表成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/products [get]
func (h *ProductAdminHandler) ListProducts(c *gin.Context) {
// 解析查询参数
page := h.getIntQuery(c, "page", 1)
pageSize := h.getIntQuery(c, "page_size", 10)
// 构建筛选条件
filters := make(map[string]interface{})
// 搜索关键词筛选
if keyword := c.Query("keyword"); keyword != "" {
filters["keyword"] = keyword
}
// 分类ID筛选
if categoryID := c.Query("category_id"); categoryID != "" {
filters["category_id"] = categoryID
}
// 启用状态筛选
if isEnabled := c.Query("is_enabled"); isEnabled != "" {
if enabled, err := strconv.ParseBool(isEnabled); err == nil {
filters["is_enabled"] = enabled
}
}
// 可见状态筛选
if isVisible := c.Query("is_visible"); isVisible != "" {
if visible, err := strconv.ParseBool(isVisible); err == nil {
filters["is_visible"] = visible
}
}
// 产品类型筛选
if isPackage := c.Query("is_package"); isPackage != "" {
if pkg, err := strconv.ParseBool(isPackage); err == nil {
filters["is_package"] = pkg
}
}
// 排序字段
sortBy := c.Query("sort_by")
if sortBy == "" {
sortBy = "created_at"
}
// 排序方向
sortOrder := c.Query("sort_order")
if sortOrder == "" {
sortOrder = "desc"
}
// 构建分页选项
options := interfaces.ListOptions{
Page: page,
PageSize: pageSize,
Sort: sortBy,
Order: sortOrder,
}
// 使用管理员专用的产品列表方法
result, err := h.productAppService.ListProductsForAdmin(c.Request.Context(), filters, options)
if err != nil {
h.logger.Error("获取产品列表失败", zap.Error(err))
h.responseBuilder.InternalError(c, "获取产品列表失败")
return
}
h.responseBuilder.Success(c, result, "获取产品列表成功")
}
// getIntQuery 获取整数查询参数
func (h *ProductAdminHandler) getIntQuery(c *gin.Context, key string, defaultValue int) int {
if value := c.Query(key); value != "" {
if intValue, err := strconv.Atoi(value); err == nil && intValue > 0 {
return intValue
}
}
return defaultValue
}
// GetProductDetail 获取产品详情(管理员)
// @Summary 获取产品详情
// @Description 管理员获取产品详细信息,包含可见状态
// @Tags 产品管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "产品ID"
// @Success 200 {object} responses.ProductAdminInfoResponse "获取产品详情成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 404 {object} map[string]interface{} "产品不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/products/{id} [get]
func (h *ProductAdminHandler) GetProductDetail(c *gin.Context) {
var query queries.GetProductQuery
query.ID = c.Param("id")
if query.ID == "" {
h.responseBuilder.BadRequest(c, "产品ID不能为空")
return
}
// 使用管理员专用的产品详情获取方法
result, err := h.productAppService.GetProductByIDForAdmin(c.Request.Context(), &query)
if err != nil {
h.logger.Error("获取产品详情失败", zap.Error(err), zap.String("product_id", query.ID))
h.responseBuilder.NotFound(c, "产品不存在")
return
}
h.responseBuilder.Success(c, result, "获取产品详情成功")
}
// GetAvailableProducts 获取可选子产品列表
// @Summary 获取可选子产品列表
// @Description 管理员获取可选作组合包子产品的产品列表
// @Tags 产品管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param exclude_package_id query string false "排除的组合包ID"
// @Param keyword query string false "搜索关键词"
// @Param category_id query string false "分类ID"
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(20)
// @Success 200 {object} responses.ProductListResponse "获取可选产品列表成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/products/available [get]
func (h *ProductAdminHandler) GetAvailableProducts(c *gin.Context) {
var query queries.GetAvailableProductsQuery
if err := h.validator.ValidateQuery(c, &query); err != nil {
return
}
// 设置默认值
if query.Page <= 0 {
query.Page = 1
}
if query.PageSize <= 0 {
query.PageSize = 20
}
if query.PageSize > 100 {
query.PageSize = 100
}
result, err := h.productAppService.GetAvailableProducts(c.Request.Context(), &query)
if err != nil {
h.logger.Error("获取可选产品列表失败", zap.Error(err))
h.responseBuilder.InternalError(c, "获取可选产品列表失败")
return
}
h.responseBuilder.Success(c, result, "获取可选产品列表成功")
}
// AddPackageItem 添加组合包子产品
// @Summary 添加组合包子产品
// @Description 管理员向组合包添加子产品
// @Tags 产品管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "组合包ID"
// @Param command body commands.AddPackageItemCommand true "添加子产品命令"
// @Success 200 {object} map[string]interface{} "添加成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 404 {object} map[string]interface{} "产品不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/products/{id}/package-items [post]
func (h *ProductAdminHandler) AddPackageItem(c *gin.Context) {
packageID := c.Param("id")
if packageID == "" {
h.responseBuilder.BadRequest(c, "组合包ID不能为空")
return
}
var cmd commands.AddPackageItemCommand
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
return
}
err := h.productAppService.AddPackageItem(c.Request.Context(), packageID, &cmd)
if err != nil {
h.logger.Error("添加组合包子产品失败", zap.Error(err), zap.String("package_id", packageID))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, nil, "添加组合包子产品成功")
}
// UpdatePackageItem 更新组合包子产品
// @Summary 更新组合包子产品
// @Description 管理员更新组合包子产品信息
// @Tags 产品管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "组合包ID"
// @Param item_id path string true "子产品项目ID"
// @Param command body commands.UpdatePackageItemCommand true "更新子产品命令"
// @Success 200 {object} map[string]interface{} "更新成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 404 {object} map[string]interface{} "产品不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/products/{id}/package-items/{item_id} [put]
func (h *ProductAdminHandler) UpdatePackageItem(c *gin.Context) {
packageID := c.Param("id")
itemID := c.Param("item_id")
if packageID == "" || itemID == "" {
h.responseBuilder.BadRequest(c, "参数不能为空")
return
}
var cmd commands.UpdatePackageItemCommand
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
return
}
err := h.productAppService.UpdatePackageItem(c.Request.Context(), packageID, itemID, &cmd)
if err != nil {
h.logger.Error("更新组合包子产品失败", zap.Error(err), zap.String("package_id", packageID), zap.String("item_id", itemID))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, nil, "更新组合包子产品成功")
}
// RemovePackageItem 移除组合包子产品
// @Summary 移除组合包子产品
// @Description 管理员从组合包移除子产品
// @Tags 产品管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "组合包ID"
// @Param item_id path string true "子产品项目ID"
// @Success 200 {object} map[string]interface{} "移除成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 404 {object} map[string]interface{} "产品不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/products/{id}/package-items/{item_id} [delete]
func (h *ProductAdminHandler) RemovePackageItem(c *gin.Context) {
packageID := c.Param("id")
itemID := c.Param("item_id")
if packageID == "" || itemID == "" {
h.responseBuilder.BadRequest(c, "参数不能为空")
return
}
err := h.productAppService.RemovePackageItem(c.Request.Context(), packageID, itemID)
if err != nil {
h.logger.Error("移除组合包子产品失败", zap.Error(err), zap.String("package_id", packageID), zap.String("item_id", itemID))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, nil, "移除组合包子产品成功")
}
// ReorderPackageItems 重新排序组合包子产品
// @Summary 重新排序组合包子产品
// @Description 管理员重新排序组合包子产品
// @Tags 产品管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "组合包ID"
// @Param command body commands.ReorderPackageItemsCommand true "重新排序命令"
// @Success 200 {object} map[string]interface{} "排序成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 404 {object} map[string]interface{} "产品不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/products/{id}/package-items/reorder [put]
func (h *ProductAdminHandler) ReorderPackageItems(c *gin.Context) {
packageID := c.Param("id")
if packageID == "" {
h.responseBuilder.BadRequest(c, "组合包ID不能为空")
return
}
var cmd commands.ReorderPackageItemsCommand
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
return
}
err := h.productAppService.ReorderPackageItems(c.Request.Context(), packageID, &cmd)
if err != nil {
h.logger.Error("重新排序组合包子产品失败", zap.Error(err), zap.String("package_id", packageID))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, nil, "重新排序组合包子产品成功")
}
// UpdatePackageItems 批量更新组合包子产品
// @Summary 批量更新组合包子产品
// @Description 管理员批量更新组合包子产品配置
// @Tags 产品管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "组合包ID"
// @Param command body commands.UpdatePackageItemsCommand true "批量更新命令"
// @Success 200 {object} map[string]interface{} "更新成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 404 {object} map[string]interface{} "产品不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/products/{id}/package-items/batch [put]
func (h *ProductAdminHandler) UpdatePackageItems(c *gin.Context) {
packageID := c.Param("id")
if packageID == "" {
h.responseBuilder.BadRequest(c, "组合包ID不能为空")
return
}
var cmd commands.UpdatePackageItemsCommand
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
return
}
err := h.productAppService.UpdatePackageItems(c.Request.Context(), packageID, &cmd)
if err != nil {
h.logger.Error("批量更新组合包子产品失败", zap.Error(err), zap.String("package_id", packageID))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, nil, "批量更新组合包子产品成功")
}
// ListCategories 获取分类列表(管理员)
// @Summary 获取分类列表
// @Description 管理员获取产品分类列表
// @Tags 分类管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(10)
// @Success 200 {object} responses.CategoryListResponse "获取分类列表成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/product-categories [get]
func (h *ProductAdminHandler) ListCategories(c *gin.Context) {
var query queries.ListCategoriesQuery
if err := h.validator.ValidateQuery(c, &query); err != nil {
return
}
// 设置默认值
if query.Page <= 0 {
query.Page = 1
}
if query.PageSize <= 0 {
query.PageSize = 10
}
if query.PageSize > 100 {
query.PageSize = 100
}
result, err := h.categoryAppService.ListCategories(c.Request.Context(), &query)
if err != nil {
h.logger.Error("获取分类列表失败", zap.Error(err))
h.responseBuilder.InternalError(c, "获取分类列表失败")
return
}
h.responseBuilder.Success(c, result, "获取分类列表成功")
}
// GetCategoryDetail 获取分类详情(管理员)
// @Summary 获取分类详情
// @Description 管理员获取分类详细信息
// @Tags 分类管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "分类ID"
// @Success 200 {object} responses.CategoryInfoResponse "获取分类详情成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 404 {object} map[string]interface{} "分类不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/product-categories/{id} [get]
func (h *ProductAdminHandler) GetCategoryDetail(c *gin.Context) {
var query queries.GetCategoryQuery
query.ID = c.Param("id")
if query.ID == "" {
h.responseBuilder.BadRequest(c, "分类ID不能为空")
return
}
result, err := h.categoryAppService.GetCategoryByID(c.Request.Context(), &query)
if err != nil {
h.logger.Error("获取分类详情失败", zap.Error(err), zap.String("category_id", query.ID))
h.responseBuilder.NotFound(c, "分类不存在")
return
}
h.responseBuilder.Success(c, result, "获取分类详情成功")
}
// ListSubscriptions 获取订阅列表(管理员)
// @Summary 获取订阅列表
// @Description 管理员获取订阅列表
// @Tags 订阅管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(10)
// @Param status query string false "订阅状态"
// @Success 200 {object} responses.SubscriptionListResponse "获取订阅列表成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/subscriptions [get]
func (h *ProductAdminHandler) ListSubscriptions(c *gin.Context) {
var query queries.ListSubscriptionsQuery
if err := c.ShouldBindQuery(&query); err != nil {
h.responseBuilder.BadRequest(c, "请求参数错误")
return
}
// 设置默认值
if query.Page <= 0 {
query.Page = 1
}
if query.PageSize <= 0 {
query.PageSize = 10
}
if query.PageSize > 100 {
query.PageSize = 100
}
result, err := h.subscriptionAppService.ListSubscriptions(c.Request.Context(), &query)
if err != nil {
h.logger.Error("获取订阅列表失败", zap.Error(err))
h.responseBuilder.InternalError(c, "获取订阅列表失败")
return
}
h.responseBuilder.Success(c, result, "获取订阅列表成功")
}
// GetSubscriptionStats 获取订阅统计(管理员)
// @Summary 获取订阅统计
// @Description 管理员获取订阅统计信息
// @Tags 订阅管理
// @Accept json
// @Produce json
// @Security Bearer
// @Success 200 {object} responses.SubscriptionStatsResponse "获取订阅统计成功"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/subscriptions/stats [get]
func (h *ProductAdminHandler) GetSubscriptionStats(c *gin.Context) {
result, err := h.subscriptionAppService.GetSubscriptionStats(c.Request.Context())
if err != nil {
h.logger.Error("获取订阅统计失败", zap.Error(err))
h.responseBuilder.InternalError(c, "获取订阅统计失败")
return
}
h.responseBuilder.Success(c, result, "获取订阅统计成功")
}
// GetProductApiConfig 获取产品API配置
// @Summary 获取产品API配置
// @Description 管理员获取产品的API配置信息如果不存在则返回空配置
// @Tags 产品管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "产品ID"
// @Success 200 {object} responses.ProductApiConfigResponse "获取API配置成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 404 {object} map[string]interface{} "产品不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/products/{id}/api-config [get]
func (h *ProductAdminHandler) GetProductApiConfig(c *gin.Context) {
productID := c.Param("id")
if productID == "" {
h.responseBuilder.BadRequest(c, "产品ID不能为空")
return
}
result, err := h.productAppService.GetProductApiConfig(c.Request.Context(), productID)
if err != nil {
// 如果是配置不存在的错误,返回空配置而不是错误
if err.Error() == "record not found" || err.Error() == "产品API配置不存在" {
// 返回空的配置结构,让前端可以创建新配置
emptyConfig := &responses.ProductApiConfigResponse{
ID: "",
ProductID: productID,
RequestParams: []responses.RequestParamResponse{},
ResponseFields: []responses.ResponseFieldResponse{},
ResponseExample: map[string]interface{}{},
}
h.responseBuilder.Success(c, emptyConfig, "获取API配置成功")
return
}
h.logger.Error("获取产品API配置失败", zap.Error(err), zap.String("product_id", productID))
h.responseBuilder.NotFound(c, "产品不存在")
return
}
h.responseBuilder.Success(c, result, "获取API配置成功")
}
// CreateProductApiConfig 创建产品API配置
// @Summary 创建产品API配置
// @Description 管理员为产品创建API配置
// @Tags 产品管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "产品ID"
// @Param request body responses.ProductApiConfigResponse true "API配置信息"
// @Success 201 {object} map[string]interface{} "API配置创建成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 409 {object} map[string]interface{} "API配置已存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/products/{id}/api-config [post]
func (h *ProductAdminHandler) CreateProductApiConfig(c *gin.Context) {
productID := c.Param("id")
if productID == "" {
h.responseBuilder.BadRequest(c, "产品ID不能为空")
return
}
var configResponse responses.ProductApiConfigResponse
if err := h.validator.BindAndValidate(c, &configResponse); err != nil {
return
}
if err := h.productAppService.CreateProductApiConfig(c.Request.Context(), productID, &configResponse); err != nil {
h.logger.Error("创建产品API配置失败", zap.Error(err), zap.String("product_id", productID))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Created(c, nil, "API配置创建成功")
}
// UpdateProductApiConfig 更新产品API配置
// @Summary 更新产品API配置
// @Description 管理员更新产品的API配置
// @Tags 产品管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "产品ID"
// @Param request body responses.ProductApiConfigResponse true "API配置信息"
// @Success 200 {object} map[string]interface{} "API配置更新成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 404 {object} map[string]interface{} "产品或配置不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/products/{id}/api-config [put]
func (h *ProductAdminHandler) UpdateProductApiConfig(c *gin.Context) {
productID := c.Param("id")
if productID == "" {
h.responseBuilder.BadRequest(c, "产品ID不能为空")
return
}
var configResponse responses.ProductApiConfigResponse
if err := h.validator.BindAndValidate(c, &configResponse); err != nil {
return
}
// 先获取现有配置以获取配置ID
existingConfig, err := h.productAppService.GetProductApiConfig(c.Request.Context(), productID)
if err != nil {
h.logger.Error("获取现有API配置失败", zap.Error(err), zap.String("product_id", productID))
h.responseBuilder.NotFound(c, "产品API配置不存在")
return
}
if err := h.productAppService.UpdateProductApiConfig(c.Request.Context(), existingConfig.ID, &configResponse); err != nil {
h.logger.Error("更新产品API配置失败", zap.Error(err), zap.String("product_id", productID))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, nil, "API配置更新成功")
}
// DeleteProductApiConfig 删除产品API配置
// @Summary 删除产品API配置
// @Description 管理员删除产品的API配置
// @Tags 产品管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "产品ID"
// @Success 200 {object} map[string]interface{} "API配置删除成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 404 {object} map[string]interface{} "产品或配置不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/products/{id}/api-config [delete]
func (h *ProductAdminHandler) DeleteProductApiConfig(c *gin.Context) {
productID := c.Param("id")
if productID == "" {
h.responseBuilder.BadRequest(c, "产品ID不能为空")
return
}
// 先获取现有配置以获取配置ID
existingConfig, err := h.productAppService.GetProductApiConfig(c.Request.Context(), productID)
if err != nil {
h.logger.Error("获取现有API配置失败", zap.Error(err), zap.String("product_id", productID))
h.responseBuilder.NotFound(c, "产品API配置不存在")
return
}
if err := h.productAppService.DeleteProductApiConfig(c.Request.Context(), existingConfig.ID); err != nil {
h.logger.Error("删除产品API配置失败", zap.Error(err), zap.String("product_id", productID))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, nil, "API配置删除成功")
}