This commit is contained in:
2025-07-31 15:41:00 +08:00
parent f3a3bc84c7
commit 934dce2776
36 changed files with 1614 additions and 264 deletions

View File

@@ -14,12 +14,13 @@ import (
// ProductAdminHandler 产品管理员HTTP处理器
type ProductAdminHandler struct {
productAppService product.ProductApplicationService
categoryAppService product.CategoryApplicationService
subscriptionAppService product.SubscriptionApplicationService
responseBuilder interfaces.ResponseBuilder
validator interfaces.RequestValidator
logger *zap.Logger
productAppService product.ProductApplicationService
categoryAppService product.CategoryApplicationService
subscriptionAppService product.SubscriptionApplicationService
documentationAppService product.DocumentationApplicationServiceInterface
responseBuilder interfaces.ResponseBuilder
validator interfaces.RequestValidator
logger *zap.Logger
}
// NewProductAdminHandler 创建产品管理员HTTP处理器
@@ -27,17 +28,19 @@ func NewProductAdminHandler(
productAppService product.ProductApplicationService,
categoryAppService product.CategoryApplicationService,
subscriptionAppService product.SubscriptionApplicationService,
documentationAppService product.DocumentationApplicationServiceInterface,
responseBuilder interfaces.ResponseBuilder,
validator interfaces.RequestValidator,
logger *zap.Logger,
) *ProductAdminHandler {
return &ProductAdminHandler{
productAppService: productAppService,
categoryAppService: categoryAppService,
subscriptionAppService: subscriptionAppService,
responseBuilder: responseBuilder,
validator: validator,
logger: logger,
productAppService: productAppService,
categoryAppService: categoryAppService,
subscriptionAppService: subscriptionAppService,
documentationAppService: documentationAppService,
responseBuilder: responseBuilder,
validator: validator,
logger: logger,
}
}
@@ -357,14 +360,15 @@ func (h *ProductAdminHandler) getIntQuery(c *gin.Context, key string, defaultVal
return defaultValue
}
// GetProductDetail 获取产品详情(管理员)
// GetProductDetail 获取产品详情
// @Summary 获取产品详情
// @Description 管理员获取产品详细信息,包含可见状态
// @Description 管理员获取产品详细信息
// @Tags 产品管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "产品ID"
// @Param with_document query bool false "是否包含文档信息"
// @Success 200 {object} responses.ProductAdminInfoResponse "获取产品详情成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
@@ -372,18 +376,23 @@ func (h *ProductAdminHandler) getIntQuery(c *gin.Context, key string, defaultVal
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/products/{id} [get]
func (h *ProductAdminHandler) GetProductDetail(c *gin.Context) {
var query queries.GetProductQuery
var query queries.GetProductDetailQuery
query.ID = c.Param("id")
if query.ID == "" {
h.responseBuilder.BadRequest(c, "产品ID不能为空")
return
}
// 使用管理员专用的产品详情获取方法
// 解析可选参数
if withDocument := c.Query("with_document"); withDocument != "" {
if withDoc, err := strconv.ParseBool(withDocument); err == nil {
query.WithDocument = &withDoc
}
}
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.logger.Error("获取产品详情失败", zap.Error(err))
h.responseBuilder.NotFound(c, "产品不存在")
return
}
@@ -793,7 +802,7 @@ func (h *ProductAdminHandler) GetProductApiConfig(c *gin.Context) {
h.responseBuilder.Success(c, emptyConfig, "获取API配置成功")
return
}
h.logger.Error("获取产品API配置失败", zap.Error(err), zap.String("product_id", productID))
h.responseBuilder.NotFound(c, "产品不存在")
return
@@ -893,7 +902,7 @@ func (h *ProductAdminHandler) UpdateProductApiConfig(c *gin.Context) {
// @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 404 {object} map[string]interface{} "产品或API配置不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/admin/products/{id}/api-config [delete]
func (h *ProductAdminHandler) DeleteProductApiConfig(c *gin.Context) {
@@ -903,19 +912,144 @@ func (h *ProductAdminHandler) DeleteProductApiConfig(c *gin.Context) {
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))
if err := h.productAppService.DeleteProductApiConfig(c.Request.Context(), productID); err != nil {
h.logger.Error("删除产品API配置失败", zap.Error(err))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, nil, "API配置删除成功")
}
// GetProductDocumentation 获取产品文档
// @Summary 获取产品文档
// @Description 管理员获取产品的文档信息
// @Tags 产品管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "产品ID"
// @Success 200 {object} responses.DocumentationResponse "获取文档成功"
// @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}/documentation [get]
func (h *ProductAdminHandler) GetProductDocumentation(c *gin.Context) {
productID := c.Param("id")
if productID == "" {
h.responseBuilder.BadRequest(c, "产品ID不能为空")
return
}
doc, err := h.documentationAppService.GetDocumentationByProductID(c.Request.Context(), productID)
if err != nil {
// 文档不存在时,返回空数据而不是错误
h.logger.Info("产品文档不存在,返回空数据", zap.String("product_id", productID))
h.responseBuilder.Success(c, nil, "文档不存在")
return
}
h.responseBuilder.Success(c, doc, "获取文档成功")
}
// CreateOrUpdateProductDocumentation 创建或更新产品文档
// @Summary 创建或更新产品文档
// @Description 管理员创建或更新产品的文档信息,如果文档不存在则创建,存在则更新
// @Tags 产品管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "产品ID"
// @Param request body commands.CreateDocumentationCommand true "文档信息"
// @Success 200 {object} responses.DocumentationResponse "文档操作成功"
// @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}/documentation [post]
func (h *ProductAdminHandler) CreateOrUpdateProductDocumentation(c *gin.Context) {
productID := c.Param("id")
if productID == "" {
h.responseBuilder.BadRequest(c, "产品ID不能为空")
return
}
var cmd commands.CreateDocumentationCommand
cmd.ProductID = productID
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
return
}
// 先尝试获取现有文档
existingDoc, err := h.documentationAppService.GetDocumentationByProductID(c.Request.Context(), productID)
if err != nil {
// 文档不存在,创建新文档
doc, err := h.documentationAppService.CreateDocumentation(c.Request.Context(), &cmd)
if err != nil {
h.logger.Error("创建产品文档失败", zap.Error(err))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Created(c, doc, "文档创建成功")
return
}
// 文档存在,更新文档
updateCmd := commands.UpdateDocumentationCommand{
RequestURL: cmd.RequestURL,
RequestMethod: cmd.RequestMethod,
BasicInfo: cmd.BasicInfo,
RequestParams: cmd.RequestParams,
ResponseFields: cmd.ResponseFields,
ResponseExample: cmd.ResponseExample,
ErrorCodes: cmd.ErrorCodes,
}
doc, err := h.documentationAppService.UpdateDocumentation(c.Request.Context(), existingDoc.ID, &updateCmd)
if err != nil {
h.logger.Error("更新产品文档失败", zap.Error(err))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, doc, "文档更新成功")
}
// DeleteProductDocumentation 删除产品文档
// @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}/documentation [delete]
func (h *ProductAdminHandler) DeleteProductDocumentation(c *gin.Context) {
productID := c.Param("id")
if productID == "" {
h.responseBuilder.BadRequest(c, "产品ID不能为空")
return
}
// 先获取文档
doc, err := h.documentationAppService.GetDocumentationByProductID(c.Request.Context(), productID)
if err != nil {
h.responseBuilder.NotFound(c, "文档不存在")
return
}
// 删除文档
if err := h.documentationAppService.DeleteDocumentation(c.Request.Context(), doc.ID); err != nil {
h.logger.Error("删除产品文档失败", zap.Error(err))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, nil, "文档删除成功")
}