This commit is contained in:
2025-12-19 17:05:09 +08:00
parent cc3472ff40
commit 39c46937ea
307 changed files with 87686 additions and 129 deletions

View File

@@ -0,0 +1,92 @@
package handlers
import (
"strings"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"tyapi-server/internal/application/product"
"tyapi-server/internal/shared/interfaces"
)
// FileDownloadHandler 文件下载处理器
type FileDownloadHandler struct {
uiComponentAppService product.UIComponentApplicationService
responseBuilder interfaces.ResponseBuilder
logger *zap.Logger
}
// NewFileDownloadHandler 创建文件下载处理器
func NewFileDownloadHandler(
uiComponentAppService product.UIComponentApplicationService,
responseBuilder interfaces.ResponseBuilder,
logger *zap.Logger,
) *FileDownloadHandler {
return &FileDownloadHandler{
uiComponentAppService: uiComponentAppService,
responseBuilder: responseBuilder,
logger: logger,
}
}
// DownloadUIComponentFile 下载UI组件文件
// @Summary 下载UI组件文件
// @Description 下载UI组件文件
// @Tags 文件下载
// @Accept json
// @Produce application/octet-stream
// @Param id path string true "UI组件ID"
// @Success 200 {file} file "文件内容"
// @Failure 400 {object} interfaces.Response "请求参数错误"
// @Failure 404 {object} interfaces.Response "UI组件不存在或文件不存在"
// @Failure 500 {object} interfaces.Response "服务器内部错误"
// @Router /api/v1/ui-components/{id}/download [get]
func (h *FileDownloadHandler) DownloadUIComponentFile(c *gin.Context) {
id := c.Param("id")
if id == "" {
h.responseBuilder.BadRequest(c, "UI组件ID不能为空")
return
}
// 获取UI组件信息
component, err := h.uiComponentAppService.GetUIComponentByID(c.Request.Context(), id)
if err != nil {
h.logger.Error("获取UI组件失败", zap.Error(err), zap.String("id", id))
h.responseBuilder.InternalError(c, "获取UI组件失败")
return
}
if component == nil {
h.responseBuilder.NotFound(c, "UI组件不存在")
return
}
if component.FilePath == nil {
h.responseBuilder.NotFound(c, "UI组件文件不存在")
return
}
// 获取文件路径
filePath, err := h.uiComponentAppService.DownloadUIComponentFile(c.Request.Context(), id)
if err != nil {
h.logger.Error("获取UI组件文件路径失败", zap.Error(err), zap.String("id", id))
h.responseBuilder.InternalError(c, "获取UI组件文件路径失败")
return
}
// 设置下载文件名
fileName := component.ComponentName
if !strings.HasSuffix(strings.ToLower(fileName), ".zip") {
fileName += ".zip"
}
// 设置响应头
c.Header("Content-Description", "File Transfer")
c.Header("Content-Transfer-Encoding", "binary")
c.Header("Content-Disposition", "attachment; filename="+fileName)
c.Header("Content-Type", "application/octet-stream")
// 发送文件
c.File(filePath)
}

View File

@@ -0,0 +1,551 @@
package handlers
import (
"fmt"
"strconv"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"tyapi-server/internal/application/product"
"tyapi-server/internal/shared/interfaces"
)
// UIComponentHandler UI组件HTTP处理器
type UIComponentHandler struct {
uiComponentAppService product.UIComponentApplicationService
responseBuilder interfaces.ResponseBuilder
validator interfaces.RequestValidator
logger *zap.Logger
}
// NewUIComponentHandler 创建UI组件HTTP处理器
func NewUIComponentHandler(
uiComponentAppService product.UIComponentApplicationService,
responseBuilder interfaces.ResponseBuilder,
validator interfaces.RequestValidator,
logger *zap.Logger,
) *UIComponentHandler {
return &UIComponentHandler{
uiComponentAppService: uiComponentAppService,
responseBuilder: responseBuilder,
validator: validator,
logger: logger,
}
}
// CreateUIComponent 创建UI组件
// @Summary 创建UI组件
// @Description 管理员创建新的UI组件
// @Tags UI组件管理
// @Accept json
// @Produce json
// @Param request body product.CreateUIComponentRequest true "创建UI组件请求"
// @Success 200 {object} interfaces.Response{data=entities.UIComponent} "创建成功"
// @Failure 400 {object} interfaces.Response "请求参数错误"
// @Failure 500 {object} interfaces.Response "服务器内部错误"
// @Router /api/v1/admin/ui-components [post]
func (h *UIComponentHandler) CreateUIComponent(c *gin.Context) {
var req product.CreateUIComponentRequest
// 一次性读取请求体并绑定到结构体
if err := c.ShouldBindJSON(&req); err != nil {
h.logger.Error("验证创建UI组件请求失败", zap.Error(err))
h.responseBuilder.BadRequest(c, fmt.Sprintf("请求参数错误: %v", err))
return
}
// 使用结构体数据记录日志
h.logger.Info("创建UI组件请求数据",
zap.String("component_code", req.ComponentCode),
zap.String("component_name", req.ComponentName),
zap.String("description", req.Description),
zap.String("version", req.Version),
zap.Bool("is_active", req.IsActive),
zap.Int("sort_order", req.SortOrder))
component, err := h.uiComponentAppService.CreateUIComponent(c.Request.Context(), req)
if err != nil {
h.logger.Error("创建UI组件失败", zap.Error(err), zap.String("component_code", req.ComponentCode))
if err == product.ErrComponentCodeAlreadyExists {
h.responseBuilder.BadRequest(c, "UI组件编码已存在")
return
}
h.responseBuilder.InternalError(c, fmt.Sprintf("创建UI组件失败: %v", err))
return
}
h.responseBuilder.Success(c, component)
}
// CreateUIComponentWithFile 创建UI组件并上传文件
// @Summary 创建UI组件并上传文件
// @Description 管理员创建新的UI组件并同时上传文件
// @Tags UI组件管理
// @Accept multipart/form-data
// @Produce json
// @Param component_code formData string true "组件编码"
// @Param component_name formData string true "组件名称"
// @Param description formData string false "组件描述"
// @Param version formData string false "组件版本"
// @Param is_active formData bool false "是否启用"
// @Param sort_order formData int false "排序"
// @Param file formData file true "组件文件"
// @Success 200 {object} interfaces.Response{data=entities.UIComponent} "创建成功"
// @Failure 400 {object} interfaces.Response "请求参数错误"
// @Failure 500 {object} interfaces.Response "服务器内部错误"
// @Router /api/v1/admin/ui-components/create-with-file [post]
func (h *UIComponentHandler) CreateUIComponentWithFile(c *gin.Context) {
// 创建请求结构体
var req product.CreateUIComponentRequest
// 从表单数据中获取组件信息
req.ComponentCode = c.PostForm("component_code")
req.ComponentName = c.PostForm("component_name")
req.Description = c.PostForm("description")
req.Version = c.PostForm("version")
req.IsActive = c.PostForm("is_active") == "true"
if sortOrderStr := c.PostForm("sort_order"); sortOrderStr != "" {
if sortOrder, err := strconv.Atoi(sortOrderStr); err == nil {
req.SortOrder = sortOrder
}
}
// 验证必需字段
if req.ComponentCode == "" {
h.responseBuilder.BadRequest(c, "组件编码不能为空")
return
}
if req.ComponentName == "" {
h.responseBuilder.BadRequest(c, "组件名称不能为空")
return
}
// 获取上传的文件
form, err := c.MultipartForm()
if err != nil {
h.logger.Error("获取表单数据失败", zap.Error(err))
h.responseBuilder.BadRequest(c, "获取表单数据失败")
return
}
files := form.File["files"]
if len(files) == 0 {
h.responseBuilder.BadRequest(c, "请上传组件文件")
return
}
// 检查文件大小100MB
for _, fileHeader := range files {
if fileHeader.Size > 100*1024*1024 {
h.responseBuilder.BadRequest(c, fmt.Sprintf("文件 %s 大小不能超过100MB", fileHeader.Filename))
return
}
}
// 获取路径信息
paths := c.PostFormArray("paths")
// 记录请求日志
h.logger.Info("创建UI组件并上传文件请求",
zap.String("component_code", req.ComponentCode),
zap.String("component_name", req.ComponentName),
zap.String("description", req.Description),
zap.String("version", req.Version),
zap.Bool("is_active", req.IsActive),
zap.Int("sort_order", req.SortOrder),
zap.Int("files_count", len(files)),
zap.Strings("paths", paths))
// 调用应用服务创建组件并上传文件
component, err := h.uiComponentAppService.CreateUIComponentWithFilesAndPaths(c.Request.Context(), req, files, paths)
if err != nil {
h.logger.Error("创建UI组件并上传文件失败", zap.Error(err), zap.String("component_code", req.ComponentCode))
if err == product.ErrComponentCodeAlreadyExists {
h.responseBuilder.BadRequest(c, "UI组件编码已存在")
return
}
h.responseBuilder.InternalError(c, fmt.Sprintf("创建UI组件并上传文件失败: %v", err))
return
}
h.responseBuilder.Success(c, component)
}
// GetUIComponent 获取UI组件详情
// @Summary 获取UI组件详情
// @Description 根据ID获取UI组件详情
// @Tags UI组件管理
// @Accept json
// @Produce json
// @Param id path string true "UI组件ID"
// @Success 200 {object} interfaces.Response{data=entities.UIComponent} "获取成功"
// @Failure 400 {object} interfaces.Response "请求参数错误"
// @Failure 404 {object} interfaces.Response "UI组件不存在"
// @Failure 500 {object} interfaces.Response "服务器内部错误"
// @Router /api/v1/admin/ui-components/{id} [get]
func (h *UIComponentHandler) GetUIComponent(c *gin.Context) {
id := c.Param("id")
if id == "" {
h.responseBuilder.BadRequest(c, "UI组件ID不能为空")
return
}
component, err := h.uiComponentAppService.GetUIComponentByID(c.Request.Context(), id)
if err != nil {
h.logger.Error("获取UI组件失败", zap.Error(err), zap.String("id", id))
h.responseBuilder.InternalError(c, "获取UI组件失败")
return
}
if component == nil {
h.responseBuilder.NotFound(c, "UI组件不存在")
return
}
h.responseBuilder.Success(c, component)
}
// UpdateUIComponent 更新UI组件
// @Summary 更新UI组件
// @Description 更新UI组件信息
// @Tags UI组件管理
// @Accept json
// @Produce json
// @Param id path string true "UI组件ID"
// @Param request body product.UpdateUIComponentRequest true "更新UI组件请求"
// @Success 200 {object} interfaces.Response "更新成功"
// @Failure 400 {object} interfaces.Response "请求参数错误"
// @Failure 404 {object} interfaces.Response "UI组件不存在"
// @Failure 500 {object} interfaces.Response "服务器内部错误"
// @Router /api/v1/admin/ui-components/{id} [put]
func (h *UIComponentHandler) UpdateUIComponent(c *gin.Context) {
id := c.Param("id")
if id == "" {
h.responseBuilder.BadRequest(c, "UI组件ID不能为空")
return
}
var req product.UpdateUIComponentRequest
// 设置ID
req.ID = id
// 验证请求
if err := h.validator.Validate(c, &req); err != nil {
h.logger.Error("验证更新UI组件请求失败", zap.Error(err))
return
}
err := h.uiComponentAppService.UpdateUIComponent(c.Request.Context(), req)
if err != nil {
h.logger.Error("更新UI组件失败", zap.Error(err), zap.String("id", id))
if err == product.ErrComponentNotFound {
h.responseBuilder.NotFound(c, "UI组件不存在")
return
}
if err == product.ErrComponentCodeAlreadyExists {
h.responseBuilder.BadRequest(c, "UI组件编码已存在")
return
}
h.responseBuilder.InternalError(c, "更新UI组件失败")
return
}
h.responseBuilder.Success(c, nil)
}
// DeleteUIComponent 删除UI组件
// @Summary 删除UI组件
// @Description 删除UI组件
// @Tags UI组件管理
// @Accept json
// @Produce json
// @Param id path string true "UI组件ID"
// @Success 200 {object} interfaces.Response "删除成功"
// @Failure 400 {object} interfaces.Response "请求参数错误"
// @Failure 404 {object} interfaces.Response "UI组件不存在"
// @Failure 500 {object} interfaces.Response "服务器内部错误"
// @Router /api/v1/admin/ui-components/{id} [delete]
func (h *UIComponentHandler) DeleteUIComponent(c *gin.Context) {
id := c.Param("id")
if id == "" {
h.responseBuilder.BadRequest(c, "UI组件ID不能为空")
return
}
err := h.uiComponentAppService.DeleteUIComponent(c.Request.Context(), id)
if err != nil {
h.logger.Error("删除UI组件失败", zap.Error(err), zap.String("id", id))
if err == product.ErrComponentNotFound {
h.responseBuilder.NotFound(c, "UI组件不存在")
return
}
h.responseBuilder.InternalError(c, "删除UI组件失败")
return
}
h.responseBuilder.Success(c, nil)
}
// ListUIComponents 获取UI组件列表
// @Summary 获取UI组件列表
// @Description 获取UI组件列表支持分页和筛选
// @Tags UI组件管理
// @Accept json
// @Produce json
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(10)
// @Param keyword query string false "关键词搜索"
// @Param is_active query bool false "是否启用"
// @Param sort_by query string false "排序字段" default(sort_order)
// @Param sort_order query string false "排序方向" default(asc)
// @Success 200 {object} interfaces.Response{data=product.ListUIComponentsResponse} "获取成功"
// @Failure 500 {object} interfaces.Response "服务器内部错误"
// @Router /api/v1/admin/ui-components [get]
func (h *UIComponentHandler) ListUIComponents(c *gin.Context) {
// 解析查询参数
req := product.ListUIComponentsRequest{}
if pageStr := c.Query("page"); pageStr != "" {
if page, err := strconv.Atoi(pageStr); err == nil {
req.Page = page
}
}
if pageSizeStr := c.Query("page_size"); pageSizeStr != "" {
if pageSize, err := strconv.Atoi(pageSizeStr); err == nil {
req.PageSize = pageSize
}
}
req.Keyword = c.Query("keyword")
if isActiveStr := c.Query("is_active"); isActiveStr != "" {
if isActive, err := strconv.ParseBool(isActiveStr); err == nil {
req.IsActive = &isActive
}
}
req.SortBy = c.DefaultQuery("sort_by", "sort_order")
req.SortOrder = c.DefaultQuery("sort_order", "asc")
response, err := h.uiComponentAppService.ListUIComponents(c.Request.Context(), req)
if err != nil {
h.logger.Error("获取UI组件列表失败", zap.Error(err))
h.responseBuilder.InternalError(c, "获取UI组件列表失败")
return
}
h.responseBuilder.Success(c, response)
}
// UploadUIComponentFile 上传UI组件文件
// @Summary 上传UI组件文件
// @Description 上传UI组件文件
// @Tags UI组件管理
// @Accept multipart/form-data
// @Produce json
// @Param id path string true "UI组件ID"
// @Param file formData file true "UI组件文件(ZIP格式)"
// @Success 200 {object} interfaces.Response{data=string} "上传成功,返回文件路径"
// @Failure 400 {object} interfaces.Response "请求参数错误"
// @Failure 404 {object} interfaces.Response "UI组件不存在"
// @Failure 500 {object} interfaces.Response "服务器内部错误"
// @Router /api/v1/admin/ui-components/{id}/upload [post]
func (h *UIComponentHandler) UploadUIComponentFile(c *gin.Context) {
id := c.Param("id")
if id == "" {
h.responseBuilder.BadRequest(c, "UI组件ID不能为空")
return
}
// 获取上传的文件
file, err := c.FormFile("file")
if err != nil {
h.logger.Error("获取上传文件失败", zap.Error(err))
h.responseBuilder.BadRequest(c, "获取上传文件失败")
return
}
// 检查文件大小100MB
if file.Size > 100*1024*1024 {
h.responseBuilder.BadRequest(c, "文件大小不能超过100MB")
return
}
filePath, err := h.uiComponentAppService.UploadUIComponentFile(c.Request.Context(), id, file)
if err != nil {
h.logger.Error("上传UI组件文件失败", zap.Error(err), zap.String("id", id))
if err == product.ErrComponentNotFound {
h.responseBuilder.NotFound(c, "UI组件不存在")
return
}
if err == product.ErrInvalidFileType {
h.responseBuilder.BadRequest(c, "文件类型错误")
return
}
h.responseBuilder.InternalError(c, "上传UI组件文件失败")
return
}
h.responseBuilder.Success(c, filePath)
}
// UploadAndExtractUIComponentFile 上传并解压UI组件文件
// @Summary 上传并解压UI组件文件
// @Description 上传文件并自动解压到组件文件夹仅ZIP文件支持解压
// @Tags UI组件管理
// @Accept multipart/form-data
// @Produce json
// @Param id path string true "UI组件ID"
// @Param file formData file true "UI组件文件(任意格式ZIP格式支持自动解压)"
// @Success 200 {object} interfaces.Response "上传成功"
// @Failure 400 {object} interfaces.Response "请求参数错误"
// @Failure 404 {object} interfaces.Response "UI组件不存在"
// @Failure 500 {object} interfaces.Response "服务器内部错误"
// @Router /api/v1/admin/ui-components/{id}/upload-extract [post]
func (h *UIComponentHandler) UploadAndExtractUIComponentFile(c *gin.Context) {
id := c.Param("id")
if id == "" {
h.responseBuilder.BadRequest(c, "UI组件ID不能为空")
return
}
// 获取上传的文件
file, err := c.FormFile("file")
if err != nil {
h.logger.Error("获取上传文件失败", zap.Error(err))
h.responseBuilder.BadRequest(c, "获取上传文件失败")
return
}
// 检查文件大小100MB
if file.Size > 100*1024*1024 {
h.responseBuilder.BadRequest(c, "文件大小不能超过100MB")
return
}
err = h.uiComponentAppService.UploadAndExtractUIComponentFile(c.Request.Context(), id, file)
if err != nil {
h.logger.Error("上传并解压UI组件文件失败", zap.Error(err), zap.String("id", id))
if err == product.ErrComponentNotFound {
h.responseBuilder.NotFound(c, "UI组件不存在")
return
}
if err == product.ErrInvalidFileType {
h.responseBuilder.BadRequest(c, "文件类型错误")
return
}
h.responseBuilder.InternalError(c, "上传并解压UI组件文件失败")
return
}
h.responseBuilder.Success(c, nil)
}
// GetUIComponentFolderContent 获取UI组件文件夹内容
// @Summary 获取UI组件文件夹内容
// @Description 获取UI组件文件夹内容
// @Tags UI组件管理
// @Accept json
// @Produce json
// @Param id path string true "UI组件ID"
// @Success 200 {object} interfaces.Response{data=[]FileInfo} "获取成功"
// @Failure 400 {object} interfaces.Response "请求参数错误"
// @Failure 404 {object} interfaces.Response "UI组件不存在"
// @Failure 500 {object} interfaces.Response "服务器内部错误"
// @Router /api/v1/admin/ui-components/{id}/folder-content [get]
func (h *UIComponentHandler) GetUIComponentFolderContent(c *gin.Context) {
id := c.Param("id")
if id == "" {
h.responseBuilder.BadRequest(c, "UI组件ID不能为空")
return
}
files, err := h.uiComponentAppService.GetUIComponentFolderContent(c.Request.Context(), id)
if err != nil {
h.logger.Error("获取UI组件文件夹内容失败", zap.Error(err), zap.String("id", id))
if err == product.ErrComponentNotFound {
h.responseBuilder.NotFound(c, "UI组件不存在")
return
}
h.responseBuilder.InternalError(c, "获取UI组件文件夹内容失败")
return
}
h.responseBuilder.Success(c, files)
}
// DeleteUIComponentFolder 删除UI组件文件夹
// @Summary 删除UI组件文件夹
// @Description 删除UI组件文件夹
// @Tags UI组件管理
// @Accept json
// @Produce json
// @Param id path string true "UI组件ID"
// @Success 200 {object} interfaces.Response "删除成功"
// @Failure 400 {object} interfaces.Response "请求参数错误"
// @Failure 404 {object} interfaces.Response "UI组件不存在"
// @Failure 500 {object} interfaces.Response "服务器内部错误"
// @Router /api/v1/admin/ui-components/{id}/folder [delete]
func (h *UIComponentHandler) DeleteUIComponentFolder(c *gin.Context) {
id := c.Param("id")
if id == "" {
h.responseBuilder.BadRequest(c, "UI组件ID不能为空")
return
}
err := h.uiComponentAppService.DeleteUIComponentFolder(c.Request.Context(), id)
if err != nil {
h.logger.Error("删除UI组件文件夹失败", zap.Error(err), zap.String("id", id))
if err == product.ErrComponentNotFound {
h.responseBuilder.NotFound(c, "UI组件不存在")
return
}
h.responseBuilder.InternalError(c, "删除UI组件文件夹失败")
return
}
h.responseBuilder.Success(c, nil)
}
// DownloadUIComponentFile 下载UI组件文件
// @Summary 下载UI组件文件
// @Description 下载UI组件文件
// @Tags UI组件管理
// @Accept json
// @Produce application/octet-stream
// @Param id path string true "UI组件ID"
// @Success 200 {file} file "文件内容"
// @Failure 400 {object} interfaces.Response "请求参数错误"
// @Failure 404 {object} interfaces.Response "UI组件不存在或文件不存在"
// @Failure 500 {object} interfaces.Response "服务器内部错误"
// @Router /api/v1/admin/ui-components/{id}/download [get]
func (h *UIComponentHandler) DownloadUIComponentFile(c *gin.Context) {
id := c.Param("id")
if id == "" {
h.responseBuilder.BadRequest(c, "UI组件ID不能为空")
return
}
filePath, err := h.uiComponentAppService.DownloadUIComponentFile(c.Request.Context(), id)
if err != nil {
h.logger.Error("下载UI组件文件失败", zap.Error(err), zap.String("id", id))
if err == product.ErrComponentNotFound {
h.responseBuilder.NotFound(c, "UI组件不存在")
return
}
if err == product.ErrComponentFileNotFound {
h.responseBuilder.NotFound(c, "UI组件文件不存在")
return
}
h.responseBuilder.InternalError(c, "下载UI组件文件失败")
return
}
// 这里应该实现文件下载逻辑,返回文件内容
// 由于我们使用的是本地文件存储,可以直接返回文件
c.File(filePath)
}

View File

@@ -2,6 +2,7 @@ package routes
import (
"tyapi-server/internal/infrastructure/http/handlers"
component_report "tyapi-server/internal/shared/component_report"
sharedhttp "tyapi-server/internal/shared/http"
"tyapi-server/internal/shared/middleware"
@@ -11,7 +12,7 @@ import (
// ProductRoutes 产品路由
type ProductRoutes struct {
productHandler *handlers.ProductHandler
componentReportHandler *handlers.ComponentReportHandler
componentReportHandler *component_report.ComponentReportHandler
auth *middleware.JWTAuthMiddleware
optionalAuth *middleware.OptionalAuthMiddleware
logger *zap.Logger
@@ -20,7 +21,7 @@ type ProductRoutes struct {
// NewProductRoutes 创建产品路由
func NewProductRoutes(
productHandler *handlers.ProductHandler,
componentReportHandler *handlers.ComponentReportHandler,
componentReportHandler *component_report.ComponentReportHandler,
auth *middleware.JWTAuthMiddleware,
optionalAuth *middleware.OptionalAuthMiddleware,
logger *zap.Logger,
@@ -58,19 +59,24 @@ func (r *ProductRoutes) Register(router *sharedhttp.GinRouter) {
// 订阅产品(需要认证)
products.POST("/:id/subscribe", r.auth.Handle(), r.productHandler.SubscribeProduct)
}
// 组件报告相关路由(需要认证
componentReport := products.Group("/:id/component-report", r.auth.Handle())
{
// 获取报告下载信息
componentReport.GET("/info", r.componentReportHandler.GetReportDownloadInfo)
// 创建支付订单(暂时注释,后续实现)
// componentReport.POST("/create-order", r.componentReportHandler.CreateReportPaymentOrder)
// 下载报告文件
componentReport.GET("/download/:downloadId", r.componentReportHandler.DownloadReport)
}
// 组件报告 - 需要认证
componentReport := engine.Group("/api/v1/component-report", r.auth.Handle())
{
// 生成并下载 example.json 文件
componentReport.POST("/download-example-json", r.componentReportHandler.DownloadExampleJSON)
// 生成并下载示例报告ZIP文件
componentReport.POST("/generate-and-download", r.componentReportHandler.GenerateAndDownloadZip)
}
// 产品组件报告相关接口 - 需要认证
componentReportGroup := products.Group("/:id/component-report", r.auth.Handle())
{
componentReportGroup.GET("/check", r.componentReportHandler.CheckDownloadAvailability)
componentReportGroup.GET("/info", r.componentReportHandler.GetDownloadInfo)
componentReportGroup.POST("/create-order", r.componentReportHandler.CreatePaymentOrder)
componentReportGroup.GET("/check-payment/:orderId", r.componentReportHandler.CheckPaymentStatus)
}
// 分类 - 公开接口
@@ -103,9 +109,6 @@ func (r *ProductRoutes) Register(router *sharedhttp.GinRouter) {
// 取消订阅
subscriptions.POST("/:id/cancel", r.productHandler.CancelMySubscription)
}
// 我的组件报告下载历史
my.GET("/component-reports", r.componentReportHandler.GetUserDownloadHistory)
}
r.logger.Info("产品路由注册完成")

View File

@@ -0,0 +1,48 @@
package routes
import (
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"tyapi-server/internal/infrastructure/http/handlers"
"tyapi-server/internal/shared/interfaces"
)
// UIComponentRoutes UI组件路由
type UIComponentRoutes struct {
uiComponentHandler *handlers.UIComponentHandler
logger *zap.Logger
}
// NewUIComponentRoutes 创建UI组件路由
func NewUIComponentRoutes(
uiComponentHandler *handlers.UIComponentHandler,
logger *zap.Logger,
) *UIComponentRoutes {
return &UIComponentRoutes{
uiComponentHandler: uiComponentHandler,
logger: logger,
}
}
// RegisterRoutes 注册UI组件路由
func (r *UIComponentRoutes) RegisterRoutes(router *gin.RouterGroup, authMiddleware interfaces.Middleware) {
uiComponentGroup := router.Group("/ui-components")
uiComponentGroup.Use(authMiddleware.Handle())
{
// UI组件管理
uiComponentGroup.POST("", r.uiComponentHandler.CreateUIComponent) // 创建UI组件
uiComponentGroup.POST("/create-with-file", r.uiComponentHandler.CreateUIComponentWithFile) // 创建UI组件并上传文件
uiComponentGroup.GET("", r.uiComponentHandler.ListUIComponents) // 获取UI组件列表
uiComponentGroup.GET("/:id", r.uiComponentHandler.GetUIComponent) // 获取UI组件详情
uiComponentGroup.PUT("/:id", r.uiComponentHandler.UpdateUIComponent) // 更新UI组件
uiComponentGroup.DELETE("/:id", r.uiComponentHandler.DeleteUIComponent) // 删除UI组件
// 文件操作
uiComponentGroup.POST("/:id/upload", r.uiComponentHandler.UploadUIComponentFile) // 上传UI组件文件
uiComponentGroup.POST("/:id/upload-extract", r.uiComponentHandler.UploadAndExtractUIComponentFile) // 上传并解压UI组件文件
uiComponentGroup.GET("/:id/folder-content", r.uiComponentHandler.GetUIComponentFolderContent) // 获取UI组件文件夹内容
uiComponentGroup.DELETE("/:id/folder", r.uiComponentHandler.DeleteUIComponentFolder) // 删除UI组件文件夹
uiComponentGroup.GET("/:id/download", r.uiComponentHandler.DownloadUIComponentFile) // 下载UI组件文件
}
}