package paymentconfig import ( "encoding/json" "net/http" "strconv" "time" "hfb_sys/backend/internal/middleware" "hfb_sys/backend/pkg/response" "github.com/gin-gonic/gin" ) type Handler struct { service *Service } func NewHandler(service *Service) *Handler { return &Handler{service: service} } // List 获取支付配置列表 // @Summary 获取支付配置列表 // @Tags 管理后台-支付配置 // @Param provider query string false "支付服务商" // @Param status query string false "状态" // @Param environment query string false "环境" // @Param page query int false "页码" // @Param page_size query int false "每页数量" // @Success 200 {object} response.Response{data=ListResponse} // @Router /admin/payment-configs [get] func (h *Handler) List(c *gin.Context) { var query ListQuery if err := c.ShouldBindQuery(&query); err != nil { response.BadRequest(c, "参数错误") return } resp, err := h.service.List(c.Request.Context(), query) if err != nil { response.Error(c, http.StatusInternalServerError, "internal_error", "查询失败") return } response.OK(c, resp) } // Get 获取单个支付配置 // @Summary 获取单个支付配置 // @Tags 管理后台-支付配置 // @Param id path int true "配置ID" // @Param include_secret query bool false "是否包含密钥" // @Success 200 {object} response.Response{data=ConfigDTO} // @Router /admin/payment-configs/{id} [get] func (h *Handler) Get(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { response.BadRequest(c, "无效的ID") return } includeSecret := c.Query("include_secret") == "true" config, err := h.service.Get(c.Request.Context(), id, includeSecret) if err == ErrConfigNotFound { response.NotFound(c, "配置不存在") return } if err != nil { response.Error(c, http.StatusInternalServerError, "internal_error", "查询失败") return } response.OK(c, config) } // ExportBackup 导出支付配置备份 // @Summary 导出支付配置备份 // @Tags 管理后台-支付配置 // @Success 200 {file} file "支付配置备份 JSON" // @Router /admin/payment-configs/export [get] func (h *Handler) ExportBackup(c *gin.Context) { adminID, ok := currentAdminID(c) if !ok { response.Unauthorized(c, "未授权") return } backup, err := h.service.ExportBackup(c.Request.Context(), adminID, auditMeta(c)) if err == ErrDecryptionFailed { response.Error(c, http.StatusInternalServerError, "decrypt_failed", "密钥解密失败") return } if err != nil { response.Error(c, http.StatusInternalServerError, "internal_error", "导出失败") return } data, err := json.MarshalIndent(backup, "", " ") if err != nil { response.Error(c, http.StatusInternalServerError, "internal_error", "导出失败") return } filename := "payment-config-backup-" + time.Now().Format("20060102-150405") + ".json" contentType := "application/json; charset=utf-8" c.Header("Content-Disposition", `attachment; filename="`+filename+`"`) c.Data(http.StatusOK, contentType, data) } // ImportBackup 导入支付配置备份 // @Summary 导入支付配置备份 // @Tags 管理后台-支付配置 // @Param body body ExportBackup true "支付配置备份 JSON" // @Success 200 {object} response.Response{data=ImportBackupResult} // @Router /admin/payment-configs/import [post] func (h *Handler) ImportBackup(c *gin.Context) { adminID, ok := currentAdminID(c) if !ok { response.Unauthorized(c, "未授权") return } var backup ExportBackup if err := c.ShouldBindJSON(&backup); err != nil { response.BadRequest(c, "备份文件格式错误") return } result, err := h.service.ImportBackup(c.Request.Context(), backup, adminID, auditMeta(c)) if err == ErrInvalidBackup || err == ErrEmptyBackup || err == ErrInvalidProvider || err == ErrNameRequired || err == ErrMerchantIDRequired || err == ErrGatewayURLRequired || err == ErrSignKeyRequired || err == ErrNotifyKeyRequired || err == ErrNotifyURLRequired || err == ErrInvalidSignType || err == ErrInvalidStatus || err == ErrAppIDRequired || err == ErrSerialNoRequired || err == ErrTermNoRequired { response.BadRequest(c, err.Error()) return } if err == ErrEncryptionFailed { response.Error(c, http.StatusInternalServerError, "encrypt_failed", "密钥加密失败") return } if err != nil { response.Error(c, http.StatusInternalServerError, "internal_error", "导入失败") return } response.OK(c, result) } // Create 创建支付配置 // @Summary 创建支付配置 // @Tags 管理后台-支付配置 // @Param body body CreateRequest true "创建请求" // @Success 200 {object} response.Response{data=ConfigDTO} // @Router /admin/payment-configs [post] func (h *Handler) Create(c *gin.Context) { adminID, ok := currentAdminID(c) if !ok { response.Unauthorized(c, "未授权") return } var req CreateRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "参数错误: "+err.Error()) return } config, err := h.service.Create(c.Request.Context(), req, adminID, auditMeta(c)) if err == ErrNameRequired || err == ErrMerchantIDRequired || err == ErrGatewayURLRequired || err == ErrSignKeyRequired || err == ErrNotifyKeyRequired || err == ErrInvalidProvider || err == ErrNotifyURLRequired || err == ErrInvalidSignType || err == ErrAppIDRequired || err == ErrInvalidStatus || err == ErrSerialNoRequired || err == ErrTermNoRequired { response.BadRequest(c, err.Error()) return } if err != nil { response.Error(c, http.StatusInternalServerError, "internal_error", "创建失败") return } response.OK(c, config) } // Update 更新支付配置 // @Summary 更新支付配置 // @Tags 管理后台-支付配置 // @Param id path int true "配置ID" // @Param body body UpdateRequest true "更新请求" // @Success 200 {object} response.Response{data=ConfigDTO} // @Router /admin/payment-configs/{id} [put] func (h *Handler) Update(c *gin.Context) { adminID, ok := currentAdminID(c) if !ok { response.Unauthorized(c, "未授权") return } id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { response.BadRequest(c, "无效的ID") return } var req UpdateRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "参数错误: "+err.Error()) return } config, err := h.service.Update(c.Request.Context(), id, req, adminID, auditMeta(c)) if err == ErrConfigNotFound { response.NotFound(c, "配置不存在") return } if err == ErrInvalidSignType || err == ErrInvalidStatus || err == ErrNotifyURLRequired { response.BadRequest(c, err.Error()) return } if err != nil { response.Error(c, http.StatusInternalServerError, "internal_error", "更新失败") return } response.OK(c, config) } // Delete 删除支付配置 // @Summary 删除支付配置 // @Tags 管理后台-支付配置 // @Param id path int true "配置ID" // @Success 200 {object} response.Response // @Router /admin/payment-configs/{id} [delete] func (h *Handler) Delete(c *gin.Context) { adminID, ok := currentAdminID(c) if !ok { response.Unauthorized(c, "未授权") return } id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { response.BadRequest(c, "无效的ID") return } err = h.service.Delete(c.Request.Context(), id, adminID, auditMeta(c)) if err == ErrConfigNotFound { response.NotFound(c, "配置不存在") return } if err == ErrCannotDeleteInUse { response.BadRequest(c, "配置正在使用中,无法删除") return } if err != nil { response.Error(c, http.StatusInternalServerError, "internal_error", "删除失败") return } response.OK(c, gin.H{"message": "删除成功"}) } func currentAdminID(c *gin.Context) (uint64, bool) { val, exists := c.Get(middleware.ContextAdminID) if !exists { return 0, false } id, ok := val.(uint64) return id, ok } func auditMeta(c *gin.Context) AuditMeta { return AuditMeta{ IP: c.ClientIP(), UserAgent: c.Request.UserAgent(), } }