470 lines
16 KiB
Go
470 lines
16 KiB
Go
package handlers
|
|
|
|
import (
|
|
"tyapi-server/internal/application/product"
|
|
"tyapi-server/internal/application/product/dto/commands"
|
|
"tyapi-server/internal/application/product/dto/queries"
|
|
"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
|
|
if err := h.validator.ValidateParam(c, &cmd); err != nil {
|
|
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 status query string false "产品状态"
|
|
// @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 [get]
|
|
func (h *ProductAdminHandler) ListProducts(c *gin.Context) {
|
|
var query queries.ListProductsQuery
|
|
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.productAppService.ListProducts(c.Request.Context(), &query)
|
|
if err != nil {
|
|
h.logger.Error("获取产品列表失败", zap.Error(err))
|
|
h.responseBuilder.InternalError(c, "获取产品列表失败")
|
|
return
|
|
}
|
|
|
|
h.responseBuilder.Success(c, result, "获取产品列表成功")
|
|
}
|
|
|
|
// GetProductDetail 获取产品详情(管理员)
|
|
// @Summary 获取产品详情
|
|
// @Description 管理员获取产品详细信息
|
|
// @Tags 产品管理
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security Bearer
|
|
// @Param id path string true "产品ID"
|
|
// @Success 200 {object} responses.ProductInfoResponse "获取产品详情成功"
|
|
// @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.GetProductByID(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, "获取产品详情成功")
|
|
}
|
|
|
|
// 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, "获取订阅统计成功")
|
|
}
|