package handlers import ( "strconv" "time" "tyapi-server/internal/application/api" "tyapi-server/internal/application/api/commands" "tyapi-server/internal/application/api/dto" "tyapi-server/internal/shared/interfaces" "github.com/gin-gonic/gin" "go.uber.org/zap" ) // ApiHandler API调用HTTP处理器 type ApiHandler struct { appService api.ApiApplicationService responseBuilder interfaces.ResponseBuilder validator interfaces.RequestValidator logger *zap.Logger } // NewApiHandler 创建API调用HTTP处理器 func NewApiHandler( appService api.ApiApplicationService, responseBuilder interfaces.ResponseBuilder, validator interfaces.RequestValidator, logger *zap.Logger, ) *ApiHandler { return &ApiHandler{ appService: appService, responseBuilder: responseBuilder, validator: validator, logger: logger, } } // HandleApiCall 统一API调用入口 // @Summary API调用 // @Description 统一API调用入口,参数加密传输 // @Tags API调用 // @Accept json // @Produce json // @Param request body commands.ApiCallCommand true "API调用请求" // @Success 200 {object} dto.ApiCallResponse "调用成功" // @Failure 400 {object} dto.ApiCallResponse "请求参数错误" // @Failure 401 {object} dto.ApiCallResponse "未授权" // @Failure 429 {object} dto.ApiCallResponse "请求过于频繁" // @Failure 500 {object} dto.ApiCallResponse "服务器内部错误" // @Router /api/v1/:api_name [post] func (h *ApiHandler) HandleApiCall(c *gin.Context) { // 1. 基础参数校验 accessId := c.GetHeader("Access-Id") if accessId == "" { response := dto.NewErrorResponse(1005, "缺少Access-Id", "") c.JSON(200, response) return } // 2. 绑定和校验请求参数 var cmd commands.ApiCallCommand cmd.ClientIP = c.ClientIP() cmd.AccessId = accessId cmd.ApiName = c.Param("api_name") if err := h.validator.BindAndValidate(c, &cmd); err != nil { response := dto.NewErrorResponse(1003, "请求参数结构不正确", "") c.JSON(200, response) return } // 3. 调用应用服务 transactionId, encryptedResp, err := h.appService.CallApi(c.Request.Context(), &cmd) if err != nil { // 根据错误类型返回对应的错误码和预定义错误消息 errorCode := api.GetErrorCode(err) errorMessage := api.GetErrorMessage(err) response := dto.NewErrorResponse(errorCode, errorMessage, transactionId) c.JSON(200, response) // API调用接口统一返回200状态码 return } // 4. 返回成功响应 response := dto.NewSuccessResponse(transactionId, encryptedResp) c.JSON(200, response) } // GetUserApiKeys 获取用户API密钥 func (h *ApiHandler) GetUserApiKeys(c *gin.Context) { userID := h.getCurrentUserID(c) if userID == "" { h.responseBuilder.Unauthorized(c, "用户未登录") return } result, err := h.appService.GetUserApiKeys(c.Request.Context(), userID) if err != nil { h.logger.Error("获取用户API密钥失败", zap.Error(err)) h.responseBuilder.BadRequest(c, err.Error()) return } h.responseBuilder.Success(c, result, "获取API密钥成功") } // GetUserWhiteList 获取用户白名单列表 func (h *ApiHandler) GetUserWhiteList(c *gin.Context) { userID := h.getCurrentUserID(c) if userID == "" { h.responseBuilder.Unauthorized(c, "用户未登录") return } result, err := h.appService.GetUserWhiteList(c.Request.Context(), userID) if err != nil { h.logger.Error("获取用户白名单失败", zap.Error(err)) h.responseBuilder.BadRequest(c, err.Error()) return } h.responseBuilder.Success(c, result, "获取白名单成功") } // AddWhiteListIP 添加白名单IP func (h *ApiHandler) AddWhiteListIP(c *gin.Context) { userID := h.getCurrentUserID(c) if userID == "" { h.responseBuilder.Unauthorized(c, "用户未登录") return } var req dto.WhiteListRequest if err := h.validator.BindAndValidate(c, &req); err != nil { h.responseBuilder.BadRequest(c, "请求参数错误") return } err := h.appService.AddWhiteListIP(c.Request.Context(), userID, req.IPAddress) if err != nil { h.logger.Error("添加白名单IP失败", zap.Error(err)) h.responseBuilder.BadRequest(c, err.Error()) return } h.responseBuilder.Success(c, nil, "添加白名单IP成功") } // DeleteWhiteListIP 删除白名单IP // @Summary 删除白名单IP // @Description 从当前用户的白名单中删除指定IP地址 // @Tags API管理 // @Accept json // @Produce json // @Security Bearer // @Param ip path string true "IP地址" // @Success 200 {object} map[string]interface{} "删除白名单IP成功" // @Failure 400 {object} map[string]interface{} "请求参数错误" // @Failure 401 {object} map[string]interface{} "未认证" // @Failure 500 {object} map[string]interface{} "服务器内部错误" // @Router /api/v1/my/whitelist/{ip} [delete] func (h *ApiHandler) DeleteWhiteListIP(c *gin.Context) { userID := h.getCurrentUserID(c) if userID == "" { h.responseBuilder.Unauthorized(c, "用户未登录") return } ipAddress := c.Param("ip") if ipAddress == "" { h.responseBuilder.BadRequest(c, "IP地址不能为空") return } err := h.appService.DeleteWhiteListIP(c.Request.Context(), userID, ipAddress) if err != nil { h.logger.Error("删除白名单IP失败", zap.Error(err)) h.responseBuilder.BadRequest(c, err.Error()) return } h.responseBuilder.Success(c, nil, "删除白名单IP成功") } // EncryptParams 加密参数接口(用于前端调试) // @Summary 加密参数 // @Description 用于前端调试时加密API调用参数 // @Tags API调试 // @Accept json // @Produce json // @Param request body commands.EncryptCommand true "加密请求" // @Success 200 {object} dto.EncryptResponse "加密成功" // @Failure 400 {object} dto.EncryptResponse "请求参数错误" // @Failure 401 {object} dto.EncryptResponse "未授权" // @Router /api/v1/encrypt [post] func (h *ApiHandler) EncryptParams(c *gin.Context) { userID := h.getCurrentUserID(c) if userID == "" { h.responseBuilder.Unauthorized(c, "用户未登录") return } var cmd commands.EncryptCommand if err := h.validator.BindAndValidate(c, &cmd); err != nil { h.responseBuilder.BadRequest(c, "请求参数错误") return } // 调用应用服务层进行加密 encryptedData, err := h.appService.EncryptParams(c.Request.Context(), userID, &cmd) if err != nil { h.logger.Error("加密参数失败", zap.Error(err)) h.responseBuilder.BadRequest(c, "加密参数失败") return } response := dto.EncryptResponse{ EncryptedData: encryptedData, } h.responseBuilder.Success(c, response, "加密成功") } // DecryptParams 解密参数 // @Summary 解密参数 // @Description 使用密钥解密加密的数据 // @Tags API调试 // @Accept json // @Produce json // @Security Bearer // @Param request body commands.DecryptCommand true "解密请求" // @Success 200 {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/decrypt [post] func (h *ApiHandler) DecryptParams(c *gin.Context) { userID := h.getCurrentUserID(c) if userID == "" { h.responseBuilder.Unauthorized(c, "用户未登录") return } var cmd commands.DecryptCommand if err := h.validator.BindAndValidate(c, &cmd); err != nil { h.responseBuilder.BadRequest(c, "请求参数错误") return } // 调用应用服务层进行解密 decryptedData, err := h.appService.DecryptParams(c.Request.Context(), userID, &cmd) if err != nil { h.logger.Error("解密参数失败", zap.Error(err)) h.responseBuilder.BadRequest(c, "解密参数失败") return } h.responseBuilder.Success(c, decryptedData, "解密成功") } // GetFormConfig 获取指定API的表单配置 // @Summary 获取表单配置 // @Description 获取指定API的表单配置,用于前端动态生成表单 // @Tags API调试 // @Accept json // @Produce json // @Security Bearer // @Param api_code path string true "API代码" // @Success 200 {object} map[string]interface{} "获取成功" // @Failure 400 {object} map[string]interface{} "请求参数错误" // @Failure 401 {object} map[string]interface{} "未授权" // @Failure 404 {object} map[string]interface{} "API接口不存在" // @Router /api/v1/form-config/{api_code} [get] func (h *ApiHandler) GetFormConfig(c *gin.Context) { userID := h.getCurrentUserID(c) if userID == "" { h.responseBuilder.Unauthorized(c, "用户未登录") return } apiCode := c.Param("api_code") if apiCode == "" { h.responseBuilder.BadRequest(c, "API代码不能为空") return } h.logger.Info("获取表单配置", zap.String("api_code", apiCode), zap.String("user_id", userID)) // 获取表单配置 config, err := h.appService.GetFormConfig(c.Request.Context(), apiCode) if err != nil { h.logger.Error("获取表单配置失败", zap.String("api_code", apiCode), zap.String("user_id", userID), zap.Error(err)) h.responseBuilder.BadRequest(c, "获取表单配置失败") return } if config == nil { h.responseBuilder.BadRequest(c, "API接口不存在") return } h.logger.Info("获取表单配置成功", zap.String("api_code", apiCode), zap.String("user_id", userID), zap.Int("field_count", len(config.Fields))) h.responseBuilder.Success(c, config, "获取表单配置成功") } // getCurrentUserID 获取当前用户ID func (h *ApiHandler) getCurrentUserID(c *gin.Context) string { if userID, exists := c.Get("user_id"); exists { if id, ok := userID.(string); ok { return id } } return "" } // GetUserApiCalls 获取用户API调用记录 // @Summary 获取用户API调用记录 // @Description 获取当前用户的API调用记录列表,支持分页和筛选 // @Tags API管理 // @Accept json // @Produce json // @Security Bearer // @Param page query int false "页码" default(1) // @Param page_size query int false "每页数量" default(10) // @Param start_time query string false "开始时间 (格式: 2006-01-02 15:04:05)" // @Param end_time query string false "结束时间 (格式: 2006-01-02 15:04:05)" // @Param transaction_id query string false "交易ID" // @Param product_name query string false "产品名称" // @Param status query string false "状态 (pending/success/failed)" // @Success 200 {object} dto.ApiCallListResponse "获取成功" // @Failure 400 {object} map[string]interface{} "请求参数错误" // @Failure 401 {object} map[string]interface{} "未认证" // @Failure 500 {object} map[string]interface{} "服务器内部错误" // @Router /api/v1/my/api-calls [get] func (h *ApiHandler) GetUserApiCalls(c *gin.Context) { userID := h.getCurrentUserID(c) if userID == "" { h.responseBuilder.Unauthorized(c, "用户未登录") return } // 解析查询参数 page := h.getIntQuery(c, "page", 1) pageSize := h.getIntQuery(c, "page_size", 10) // 构建筛选条件 filters := make(map[string]interface{}) // 时间范围筛选 if startTime := c.Query("start_time"); startTime != "" { if t, err := time.Parse("2006-01-02 15:04:05", startTime); err == nil { filters["start_time"] = t } } if endTime := c.Query("end_time"); endTime != "" { if t, err := time.Parse("2006-01-02 15:04:05", endTime); err == nil { filters["end_time"] = t } } // 交易ID筛选 if transactionId := c.Query("transaction_id"); transactionId != "" { filters["transaction_id"] = transactionId } // 产品名称筛选 if productName := c.Query("product_name"); productName != "" { filters["product_name"] = productName } // 状态筛选 if status := c.Query("status"); status != "" { filters["status"] = status } // 构建分页选项 options := interfaces.ListOptions{ Page: page, PageSize: pageSize, Sort: "created_at", Order: "desc", } result, err := h.appService.GetUserApiCalls(c.Request.Context(), userID, filters, options) if err != nil { h.logger.Error("获取用户API调用记录失败", zap.Error(err)) h.responseBuilder.BadRequest(c, "获取API调用记录失败") return } h.responseBuilder.Success(c, result, "获取API调用记录成功") } // GetAdminApiCalls 获取管理端API调用记录 // @Summary 获取管理端API调用记录 // @Description 管理员获取API调用记录,支持筛选和分页 // @Tags API管理 // @Accept json // @Produce json // @Security Bearer // @Param page query int false "页码" default(1) // @Param page_size query int false "每页数量" default(10) // @Param user_id query string false "用户ID" // @Param transaction_id query string false "交易ID" // @Param product_name query string false "产品名称" // @Param status query string false "状态" // @Param start_time query string false "开始时间" format(date-time) // @Param end_time query string false "结束时间" format(date-time) // @Param sort_by query string false "排序字段" // @Param sort_order query string false "排序方向" Enums(asc, desc) // @Success 200 {object} dto.ApiCallListResponse "获取API调用记录成功" // @Failure 400 {object} map[string]interface{} "请求参数错误" // @Failure 401 {object} map[string]interface{} "未认证" // @Failure 500 {object} map[string]interface{} "服务器内部错误" // @Router /api/v1/admin/api-calls [get] func (h *ApiHandler) GetAdminApiCalls(c *gin.Context) { // 解析查询参数 page := h.getIntQuery(c, "page", 1) pageSize := h.getIntQuery(c, "page_size", 10) // 构建筛选条件 filters := make(map[string]interface{}) // 用户ID筛选 if userId := c.Query("user_id"); userId != "" { filters["user_id"] = userId } // 时间范围筛选 if startTime := c.Query("start_time"); startTime != "" { if t, err := time.Parse("2006-01-02 15:04:05", startTime); err == nil { filters["start_time"] = t } } if endTime := c.Query("end_time"); endTime != "" { if t, err := time.Parse("2006-01-02 15:04:05", endTime); err == nil { filters["end_time"] = t } } // 交易ID筛选 if transactionId := c.Query("transaction_id"); transactionId != "" { filters["transaction_id"] = transactionId } // 产品名称筛选 if productName := c.Query("product_name"); productName != "" { filters["product_name"] = productName } // 状态筛选 if status := c.Query("status"); status != "" { filters["status"] = status } // 构建分页选项 options := interfaces.ListOptions{ Page: page, PageSize: pageSize, Sort: "created_at", Order: "desc", } result, err := h.appService.GetAdminApiCalls(c.Request.Context(), filters, options) if err != nil { h.logger.Error("获取管理端API调用记录失败", zap.Error(err)) h.responseBuilder.BadRequest(c, "获取API调用记录失败") return } h.responseBuilder.Success(c, result, "获取API调用记录成功") } // getIntQuery 获取整数查询参数 func (h *ApiHandler) 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 }