| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 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 { | 
					
						
							| 
									
										
										
										
											2025-08-03 23:30:30 +08:00
										 |  |  |  | 		// 根据错误类型返回对应的错误码和预定义错误消息 | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 		errorCode := api.GetErrorCode(err) | 
					
						
							| 
									
										
										
										
											2025-08-03 23:30:30 +08:00
										 |  |  |  | 		errorMessage := api.GetErrorMessage(err) | 
					
						
							|  |  |  |  | 		response := dto.NewErrorResponse(errorCode, errorMessage, transactionId) | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 		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 | 
					
						
							| 
									
										
										
										
											2025-08-02 02:54:21 +08:00
										 |  |  |  | 	if err := h.validator.BindAndValidate(c, &req); err != nil { | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 		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 | 
					
						
							| 
									
										
										
										
											2025-09-01 18:29:59 +08:00
										 |  |  |  | // @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] | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 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 | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-18 14:13:16 +08:00
										 |  |  |  | 	// 调用应用服务层进行加密 | 
					
						
							|  |  |  |  | 	encryptedData, err := h.appService.EncryptParams(c.Request.Context(), userID, &cmd) | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2025-08-18 14:13:16 +08:00
										 |  |  |  | 		h.logger.Error("加密参数失败", zap.Error(err)) | 
					
						
							|  |  |  |  | 		h.responseBuilder.BadRequest(c, "加密参数失败") | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 		return | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-18 14:13:16 +08:00
										 |  |  |  | 	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, "用户未登录") | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 		return | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-18 14:13:16 +08:00
										 |  |  |  | 	var cmd commands.DecryptCommand | 
					
						
							|  |  |  |  | 	if err := h.validator.BindAndValidate(c, &cmd); err != nil { | 
					
						
							|  |  |  |  | 		h.responseBuilder.BadRequest(c, "请求参数错误") | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 		return | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-18 14:13:16 +08:00
										 |  |  |  | 	// 调用应用服务层进行解密 | 
					
						
							|  |  |  |  | 	decryptedData, err := h.appService.DecryptParams(c.Request.Context(), userID, &cmd) | 
					
						
							|  |  |  |  | 	if err != nil { | 
					
						
							|  |  |  |  | 		h.logger.Error("解密参数失败", zap.Error(err)) | 
					
						
							|  |  |  |  | 		h.responseBuilder.BadRequest(c, "解密参数失败") | 
					
						
							|  |  |  |  | 		return | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-08-18 14:13:16 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 	h.responseBuilder.Success(c, decryptedData, "解密成功") | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-27 22:19:19 +08:00
										 |  |  |  | // 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, "获取表单配置成功") | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | // 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 | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 23:44:01 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 	// 产品名称筛选 | 
					
						
							|  |  |  |  | 	if productName := c.Query("product_name"); productName != "" { | 
					
						
							|  |  |  |  | 		filters["product_name"] = productName | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 23:44:01 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 	// 状态筛选 | 
					
						
							|  |  |  |  | 	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调用记录成功") | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-02 02:54:21 +08:00
										 |  |  |  | // 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调用记录成功") | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-12 01:15:09 +08:00
										 |  |  |  | // ExportAdminApiCalls 导出管理端API调用记录 | 
					
						
							|  |  |  |  | // @Summary 导出管理端API调用记录 | 
					
						
							|  |  |  |  | // @Description 管理员导出API调用记录,支持Excel和CSV格式 | 
					
						
							|  |  |  |  | // @Tags API调用管理 | 
					
						
							|  |  |  |  | // @Accept json | 
					
						
							|  |  |  |  | // @Produce application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,text/csv | 
					
						
							|  |  |  |  | // @Security Bearer | 
					
						
							|  |  |  |  | // @Param user_ids query string false "用户ID列表,逗号分隔" | 
					
						
							|  |  |  |  | // @Param product_ids query string false "产品ID列表,逗号分隔" | 
					
						
							|  |  |  |  | // @Param start_time query string false "开始时间" format(date-time) | 
					
						
							|  |  |  |  | // @Param end_time query string false "结束时间" format(date-time) | 
					
						
							|  |  |  |  | // @Param format query string false "导出格式" Enums(excel, csv) default(excel) | 
					
						
							|  |  |  |  | // @Success 200 {file} file "导出文件" | 
					
						
							|  |  |  |  | // @Failure 400 {object} map[string]interface{} "请求参数错误" | 
					
						
							|  |  |  |  | // @Failure 401 {object} map[string]interface{} "未认证" | 
					
						
							|  |  |  |  | // @Failure 500 {object} map[string]interface{} "服务器内部错误" | 
					
						
							|  |  |  |  | // @Router /api/v1/admin/api-calls/export [get] | 
					
						
							|  |  |  |  | func (h *ApiHandler) ExportAdminApiCalls(c *gin.Context) { | 
					
						
							|  |  |  |  | 	// 解析查询参数 | 
					
						
							|  |  |  |  | 	filters := make(map[string]interface{}) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 用户ID筛选 | 
					
						
							|  |  |  |  | 	if userIds := c.Query("user_ids"); userIds != "" { | 
					
						
							|  |  |  |  | 		filters["user_ids"] = userIds | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 产品ID筛选 | 
					
						
							|  |  |  |  | 	if productIds := c.Query("product_ids"); productIds != "" { | 
					
						
							|  |  |  |  | 		filters["product_ids"] = productIds | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 时间范围筛选 | 
					
						
							|  |  |  |  | 	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 | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 获取导出格式,默认为excel | 
					
						
							|  |  |  |  | 	format := c.DefaultQuery("format", "excel") | 
					
						
							|  |  |  |  | 	if format != "excel" && format != "csv" { | 
					
						
							|  |  |  |  | 		h.responseBuilder.BadRequest(c, "不支持的导出格式") | 
					
						
							|  |  |  |  | 		return | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 调用应用服务导出数据 | 
					
						
							|  |  |  |  | 	fileData, err := h.appService.ExportAdminApiCalls(c.Request.Context(), filters, format) | 
					
						
							|  |  |  |  | 	if err != nil { | 
					
						
							|  |  |  |  | 		h.logger.Error("导出API调用记录失败", zap.Error(err)) | 
					
						
							|  |  |  |  | 		h.responseBuilder.BadRequest(c, "导出API调用记录失败") | 
					
						
							|  |  |  |  | 		return | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	// 设置响应头 | 
					
						
							|  |  |  |  | 	contentType := "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" | 
					
						
							|  |  |  |  | 	filename := "API调用记录.xlsx" | 
					
						
							|  |  |  |  | 	if format == "csv" { | 
					
						
							|  |  |  |  | 		contentType = "text/csv;charset=utf-8" | 
					
						
							|  |  |  |  | 		filename = "API调用记录.csv" | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	c.Header("Content-Type", contentType) | 
					
						
							|  |  |  |  | 	c.Header("Content-Disposition", "attachment; filename="+filename) | 
					
						
							|  |  |  |  | 	c.Data(200, contentType, fileData) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | // 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 | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2025-09-12 01:15:09 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | // GetUserBalanceAlertSettings 获取用户余额预警设置 | 
					
						
							|  |  |  |  | // @Summary 获取用户余额预警设置 | 
					
						
							|  |  |  |  | // @Description 获取当前用户的余额预警配置 | 
					
						
							|  |  |  |  | // @Tags 用户设置 | 
					
						
							|  |  |  |  | // @Accept json | 
					
						
							|  |  |  |  | // @Produce json | 
					
						
							|  |  |  |  | // @Success 200 {object} map[string]interface{} "获取成功" | 
					
						
							|  |  |  |  | // @Failure 401 {object} map[string]interface{} "未授权" | 
					
						
							|  |  |  |  | // @Failure 500 {object} map[string]interface{} "服务器内部错误" | 
					
						
							|  |  |  |  | // @Router /api/v1/user/balance-alert/settings [get] | 
					
						
							|  |  |  |  | func (h *ApiHandler) GetUserBalanceAlertSettings(c *gin.Context) { | 
					
						
							|  |  |  |  | 	userID := c.GetString("user_id") | 
					
						
							|  |  |  |  | 	if userID == "" { | 
					
						
							|  |  |  |  | 		h.responseBuilder.Unauthorized(c, "用户未登录") | 
					
						
							|  |  |  |  | 		return | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	settings, err := h.appService.GetUserBalanceAlertSettings(c.Request.Context(), userID) | 
					
						
							|  |  |  |  | 	if err != nil { | 
					
						
							|  |  |  |  | 		h.logger.Error("获取用户余额预警设置失败", | 
					
						
							|  |  |  |  | 			zap.String("user_id", userID), | 
					
						
							|  |  |  |  | 			zap.Error(err)) | 
					
						
							|  |  |  |  | 		h.responseBuilder.InternalError(c, "获取预警设置失败") | 
					
						
							|  |  |  |  | 		return | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	h.responseBuilder.Success(c, settings, "获取成功") | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // UpdateUserBalanceAlertSettings 更新用户余额预警设置 | 
					
						
							|  |  |  |  | // @Summary 更新用户余额预警设置 | 
					
						
							|  |  |  |  | // @Description 更新当前用户的余额预警配置 | 
					
						
							|  |  |  |  | // @Tags 用户设置 | 
					
						
							|  |  |  |  | // @Accept json | 
					
						
							|  |  |  |  | // @Produce json | 
					
						
							|  |  |  |  | // @Param request body map[string]interface{} 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/user/balance-alert/settings [put] | 
					
						
							|  |  |  |  | func (h *ApiHandler) UpdateUserBalanceAlertSettings(c *gin.Context) { | 
					
						
							|  |  |  |  | 	userID := c.GetString("user_id") | 
					
						
							|  |  |  |  | 	if userID == "" { | 
					
						
							|  |  |  |  | 		h.responseBuilder.Unauthorized(c, "用户未登录") | 
					
						
							|  |  |  |  | 		return | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	var request struct { | 
					
						
							|  |  |  |  | 		Enabled    bool    `json:"enabled" binding:"required"` | 
					
						
							|  |  |  |  | 		Threshold  float64 `json:"threshold" binding:"required,min=0"` | 
					
						
							|  |  |  |  | 		AlertPhone string  `json:"alert_phone" binding:"required"` | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if err := c.ShouldBindJSON(&request); err != nil { | 
					
						
							|  |  |  |  | 		h.responseBuilder.BadRequest(c, "请求参数错误: "+err.Error()) | 
					
						
							|  |  |  |  | 		return | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	err := h.appService.UpdateUserBalanceAlertSettings(c.Request.Context(), userID, request.Enabled, request.Threshold, request.AlertPhone) | 
					
						
							|  |  |  |  | 	if err != nil { | 
					
						
							|  |  |  |  | 		h.logger.Error("更新用户余额预警设置失败", | 
					
						
							|  |  |  |  | 			zap.String("user_id", userID), | 
					
						
							|  |  |  |  | 			zap.Error(err)) | 
					
						
							|  |  |  |  | 		h.responseBuilder.InternalError(c, "更新预警设置失败") | 
					
						
							|  |  |  |  | 		return | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	h.responseBuilder.Success(c, gin.H{}, "更新成功") | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // TestBalanceAlertSms 测试余额预警短信 | 
					
						
							|  |  |  |  | // @Summary 测试余额预警短信 | 
					
						
							|  |  |  |  | // @Description 发送测试预警短信到指定手机号 | 
					
						
							|  |  |  |  | // @Tags 用户设置 | 
					
						
							|  |  |  |  | // @Accept json | 
					
						
							|  |  |  |  | // @Produce json | 
					
						
							|  |  |  |  | // @Param request body map[string]interface{} 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/user/balance-alert/test-sms [post] | 
					
						
							|  |  |  |  | func (h *ApiHandler) TestBalanceAlertSms(c *gin.Context) { | 
					
						
							|  |  |  |  | 	userID := c.GetString("user_id") | 
					
						
							|  |  |  |  | 	if userID == "" { | 
					
						
							|  |  |  |  | 		h.responseBuilder.Unauthorized(c, "用户未登录") | 
					
						
							|  |  |  |  | 		return | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	var request struct { | 
					
						
							|  |  |  |  | 		Phone     string  `json:"phone" binding:"required,len=11"` | 
					
						
							|  |  |  |  | 		Balance   float64 `json:"balance" binding:"required"` | 
					
						
							|  |  |  |  | 		AlertType string  `json:"alert_type" binding:"required,oneof=low_balance arrears"` | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	if err := c.ShouldBindJSON(&request); err != nil { | 
					
						
							|  |  |  |  | 		h.responseBuilder.BadRequest(c, "请求参数错误: "+err.Error()) | 
					
						
							|  |  |  |  | 		return | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	err := h.appService.TestBalanceAlertSms(c.Request.Context(), userID, request.Phone, request.Balance, request.AlertType) | 
					
						
							|  |  |  |  | 	if err != nil { | 
					
						
							|  |  |  |  | 		h.logger.Error("发送测试预警短信失败", | 
					
						
							|  |  |  |  | 			zap.String("user_id", userID), | 
					
						
							|  |  |  |  | 			zap.Error(err)) | 
					
						
							|  |  |  |  | 		h.responseBuilder.InternalError(c, "发送测试短信失败") | 
					
						
							|  |  |  |  | 		return | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	h.responseBuilder.Success(c, gin.H{}, "测试短信发送成功") | 
					
						
							|  |  |  |  | } |