fix
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"tyapi-server/internal/domains/product/entities"
|
||||
"tyapi-server/internal/domains/product/repositories"
|
||||
"tyapi-server/internal/shared/database"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const (
|
||||
ProductDocumentationsTable = "product_documentations"
|
||||
)
|
||||
|
||||
type GormProductDocumentationRepository struct {
|
||||
*database.CachedBaseRepositoryImpl
|
||||
}
|
||||
|
||||
func (r *GormProductDocumentationRepository) Delete(ctx context.Context, id string) error {
|
||||
return r.DeleteEntity(ctx, id, &entities.ProductDocumentation{})
|
||||
}
|
||||
|
||||
var _ repositories.ProductDocumentationRepository = (*GormProductDocumentationRepository)(nil)
|
||||
|
||||
func NewGormProductDocumentationRepository(db *gorm.DB, logger *zap.Logger) repositories.ProductDocumentationRepository {
|
||||
return &GormProductDocumentationRepository{
|
||||
CachedBaseRepositoryImpl: database.NewCachedBaseRepositoryImpl(db, logger, ProductDocumentationsTable),
|
||||
}
|
||||
}
|
||||
|
||||
// Create 创建文档
|
||||
func (r *GormProductDocumentationRepository) Create(ctx context.Context, documentation *entities.ProductDocumentation) error {
|
||||
return r.CreateEntity(ctx, documentation)
|
||||
}
|
||||
|
||||
// Update 更新文档
|
||||
func (r *GormProductDocumentationRepository) Update(ctx context.Context, documentation *entities.ProductDocumentation) error {
|
||||
return r.UpdateEntity(ctx, documentation)
|
||||
}
|
||||
|
||||
// FindByID 根据ID查找文档
|
||||
func (r *GormProductDocumentationRepository) FindByID(ctx context.Context, id string) (*entities.ProductDocumentation, error) {
|
||||
var entity entities.ProductDocumentation
|
||||
err := r.SmartGetByID(ctx, id, &entity)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, gorm.ErrRecordNotFound
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &entity, nil
|
||||
}
|
||||
|
||||
// FindByProductID 根据产品ID查找文档
|
||||
func (r *GormProductDocumentationRepository) FindByProductID(ctx context.Context, productID string) (*entities.ProductDocumentation, error) {
|
||||
var entity entities.ProductDocumentation
|
||||
err := r.GetDB(ctx).Where("product_id = ?", productID).First(&entity).Error
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, gorm.ErrRecordNotFound
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &entity, nil
|
||||
}
|
||||
|
||||
// FindByProductIDs 根据产品ID列表批量查找文档
|
||||
func (r *GormProductDocumentationRepository) FindByProductIDs(ctx context.Context, productIDs []string) ([]*entities.ProductDocumentation, error) {
|
||||
var documentations []entities.ProductDocumentation
|
||||
err := r.GetDB(ctx).Where("product_id IN ?", productIDs).Find(&documentations).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 转换为指针切片
|
||||
result := make([]*entities.ProductDocumentation, len(documentations))
|
||||
for i := range documentations {
|
||||
result[i] = &documentations[i]
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// UpdateBatch 批量更新文档
|
||||
func (r *GormProductDocumentationRepository) UpdateBatch(ctx context.Context, documentations []*entities.ProductDocumentation) error {
|
||||
if len(documentations) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 使用事务进行批量更新
|
||||
return r.GetDB(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
for _, doc := range documentations {
|
||||
if err := tx.Save(doc).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// CountByProductID 统计指定产品的文档数量
|
||||
func (r *GormProductDocumentationRepository) CountByProductID(ctx context.Context, productID string) (int64, error) {
|
||||
var count int64
|
||||
err := r.GetDB(ctx).Model(&entities.ProductDocumentation{}).Where("product_id = ?", productID).Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
@@ -289,3 +289,26 @@ func (r *GormSubscriptionRepository) WithTx(tx interface{}) interfaces.Repositor
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// IncrementAPIUsageWithOptimisticLock 使用乐观锁增加API使用次数
|
||||
func (r *GormSubscriptionRepository) IncrementAPIUsageWithOptimisticLock(ctx context.Context, subscriptionID string, increment int64) error {
|
||||
// 使用原生SQL进行乐观锁更新
|
||||
result := r.GetDB(ctx).WithContext(ctx).Exec(`
|
||||
UPDATE subscription
|
||||
SET api_used = api_used + ?, version = version + 1, updated_at = NOW()
|
||||
WHERE id = ? AND version = (
|
||||
SELECT version FROM subscription WHERE id = ?
|
||||
)
|
||||
`, increment, subscriptionID, subscriptionID)
|
||||
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
|
||||
// 检查是否有行被更新
|
||||
if result.RowsAffected == 0 {
|
||||
return gorm.ErrRecordNotFound
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -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, "文档删除成功")
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ type ProductHandler struct {
|
||||
apiConfigService product.ProductApiConfigApplicationService
|
||||
categoryService product.CategoryApplicationService
|
||||
subAppService product.SubscriptionApplicationService
|
||||
documentationAppService product.DocumentationApplicationServiceInterface
|
||||
responseBuilder interfaces.ResponseBuilder
|
||||
validator interfaces.RequestValidator
|
||||
logger *zap.Logger
|
||||
@@ -28,6 +29,7 @@ func NewProductHandler(
|
||||
apiConfigService product.ProductApiConfigApplicationService,
|
||||
categoryService product.CategoryApplicationService,
|
||||
subAppService product.SubscriptionApplicationService,
|
||||
documentationAppService product.DocumentationApplicationServiceInterface,
|
||||
responseBuilder interfaces.ResponseBuilder,
|
||||
validator interfaces.RequestValidator,
|
||||
logger *zap.Logger,
|
||||
@@ -37,6 +39,7 @@ func NewProductHandler(
|
||||
apiConfigService: apiConfigService,
|
||||
categoryService: categoryService,
|
||||
subAppService: subAppService,
|
||||
documentationAppService: documentationAppService,
|
||||
responseBuilder: responseBuilder,
|
||||
validator: validator,
|
||||
logger: logger,
|
||||
@@ -171,30 +174,36 @@ func (h *ProductHandler) getCurrentUserID(c *gin.Context) string {
|
||||
|
||||
// GetProductDetail 获取产品详情
|
||||
// @Summary 获取产品详情
|
||||
// @Description 根据产品ID获取产品详细信息,只能获取可见的产品
|
||||
// @Description 获取产品详细信息,用户端只能查看可见的产品
|
||||
// @Tags 数据大厅
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "产品ID"
|
||||
// @Success 200 {object} responses.ProductInfoResponse "获取产品详情成功"
|
||||
// @Param with_document query bool false "是否包含文档信息"
|
||||
// @Success 200 {object} responses.ProductInfoWithDocumentResponse "获取产品详情成功"
|
||||
// @Failure 400 {object} map[string]interface{} "请求参数错误"
|
||||
// @Failure 404 {object} map[string]interface{} "产品不存在"
|
||||
// @Failure 404 {object} map[string]interface{} "产品不存在或不可见"
|
||||
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
|
||||
// @Router /api/v1/products/{id} [get]
|
||||
func (h *ProductHandler) 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.appService.GetProductByIDForUser(c.Request.Context(), &query)
|
||||
if err != nil {
|
||||
h.logger.Error("获取产品详情失败", zap.Error(err), zap.String("product_id", query.ID))
|
||||
h.responseBuilder.NotFound(c, "产品不存在")
|
||||
h.logger.Error("获取产品详情失败", zap.Error(err))
|
||||
h.responseBuilder.NotFound(c, "产品不存在或不可见")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -523,31 +532,61 @@ func (h *ProductHandler) GetMySubscriptionDetail(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Security Bearer
|
||||
// @Param id path string true "订阅ID"
|
||||
// @Success 200 {object} responses.SubscriptionUsageResponse "获取使用情况成功"
|
||||
// @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/my/subscriptions/{id}/usage [get]
|
||||
func (h *ProductHandler) GetMySubscriptionUsage(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
if userID == "" {
|
||||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||||
return
|
||||
}
|
||||
|
||||
subscriptionID := c.Param("id")
|
||||
if subscriptionID == "" {
|
||||
h.responseBuilder.BadRequest(c, "订阅ID不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
result, err := h.subAppService.GetSubscriptionUsage(c.Request.Context(), subscriptionID)
|
||||
if err != nil {
|
||||
h.logger.Error("获取我的订阅使用情况失败", zap.Error(err), zap.String("user_id", userID), zap.String("subscription_id", subscriptionID))
|
||||
h.responseBuilder.NotFound(c, "订阅不存在")
|
||||
// 获取当前用户ID
|
||||
userID := h.getCurrentUserID(c)
|
||||
if userID == "" {
|
||||
h.responseBuilder.Unauthorized(c, "用户未认证")
|
||||
return
|
||||
}
|
||||
|
||||
h.responseBuilder.Success(c, result, "获取我的订阅使用情况成功")
|
||||
usage, err := h.subAppService.GetSubscriptionUsage(c.Request.Context(), subscriptionID)
|
||||
if err != nil {
|
||||
h.logger.Error("获取订阅使用情况失败", zap.Error(err))
|
||||
h.responseBuilder.BadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.responseBuilder.Success(c, usage, "获取使用情况成功")
|
||||
}
|
||||
|
||||
// GetProductDocumentation 获取产品文档
|
||||
// @Summary 获取产品文档
|
||||
// @Description 获取指定产品的文档信息
|
||||
// @Tags 数据大厅
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "产品ID"
|
||||
// @Success 200 {object} responses.DocumentationResponse "获取文档成功"
|
||||
// @Failure 400 {object} map[string]interface{} "请求参数错误"
|
||||
// @Failure 404 {object} map[string]interface{} "产品或文档不存在"
|
||||
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
|
||||
// @Router /api/v1/products/{id}/documentation [get]
|
||||
func (h *ProductHandler) 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.Error("获取产品文档失败", zap.Error(err))
|
||||
h.responseBuilder.NotFound(c, "文档不存在")
|
||||
return
|
||||
}
|
||||
|
||||
h.responseBuilder.Success(c, doc, "获取文档成功")
|
||||
}
|
||||
|
||||
@@ -55,6 +55,11 @@ func (r *ProductAdminRoutes) Register(router *sharedhttp.GinRouter) {
|
||||
products.POST("/:id/api-config", r.handler.CreateProductApiConfig)
|
||||
products.PUT("/:id/api-config", r.handler.UpdateProductApiConfig)
|
||||
products.DELETE("/:id/api-config", r.handler.DeleteProductApiConfig)
|
||||
|
||||
// 文档管理
|
||||
products.GET("/:id/documentation", r.handler.GetProductDocumentation)
|
||||
products.POST("/:id/documentation", r.handler.CreateOrUpdateProductDocumentation)
|
||||
products.DELETE("/:id/documentation", r.handler.DeleteProductDocumentation)
|
||||
}
|
||||
|
||||
// 分类管理
|
||||
|
||||
@@ -50,6 +50,7 @@ func (r *ProductRoutes) Register(router *sharedhttp.GinRouter) {
|
||||
// 产品详情和API配置 - 使用具体路径避免冲突
|
||||
products.GET("/:id", r.productHandler.GetProductDetail)
|
||||
products.GET("/:id/api-config", r.productHandler.GetProductApiConfig)
|
||||
products.GET("/:id/documentation", r.productHandler.GetProductDocumentation)
|
||||
|
||||
// 订阅产品(需要认证)
|
||||
products.POST("/:id/subscribe", r.auth.Handle(), r.productHandler.SubscribeProduct)
|
||||
|
||||
Reference in New Issue
Block a user