Files
hfb_sys/backend/internal/modules/paymentconfig/handler.go
T

281 lines
7.7 KiB
Go

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(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(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(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(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(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(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(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(),
}
}