package handler import ( "dianshang/internal/service" "dianshang/pkg/logger" "dianshang/pkg/response" "strconv" "github.com/gin-gonic/gin" ) type RefundHandler struct { refundService *service.RefundService } func NewRefundHandler(refundService *service.RefundService) *RefundHandler { return &RefundHandler{ refundService: refundService, } } // CreateRefund 创建退款申请 // @Summary 创建退款申请 // @Description 用户申请退款 // @Tags 退款管理 // @Accept json // @Produce json // @Param request body service.CreateRefundRequest true "退款申请信息" // @Success 200 {object} response.Response{data=model.Refund} // @Failure 400 {object} response.Response // @Router /api/refunds [post] func (h *RefundHandler) CreateRefund(c *gin.Context) { var req service.CreateRefundRequest if err := c.ShouldBindJSON(&req); err != nil { logger.Error("绑定退款申请参数失败", "error", err) response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "参数错误: "+err.Error()) return } // 从上下文获取用户ID(假设已通过中间件设置) userID, exists := c.Get("user_id") if !exists { response.Error(c, response.ERROR_UNAUTHORIZED) return } req.UserID = userID.(uint) refund, err := h.refundService.CreateRefund(c.Request.Context(), &req) if err != nil { logger.Error("创建退款申请失败", "error", err, "userID", req.UserID, "orderID", req.OrderID) response.ErrorWithMessage(c, response.ERROR, err.Error()) return } logger.Info("退款申请创建成功", "refundID", refund.ID, "userID", req.UserID) response.Success(c, refund) } // GetRefundsByOrder 获取订单的退款记录 // @Summary 获取订单的退款记录 // @Description 用户获取指定订单的所有退款记录 // @Tags 退款管理 // @Accept json // @Produce json // @Param order_id path int true "订单ID" // @Success 200 {object} response.Response{data=[]model.Refund} // @Failure 400 {object} response.Response // @Router /api/orders/{order_id}/refunds [get] func (h *RefundHandler) GetRefundsByOrder(c *gin.Context) { orderIDStr := c.Param("order_id") orderID, err := strconv.ParseUint(orderIDStr, 10, 32) if err != nil { response.Error(c, response.ERROR_INVALID_PARAMS) return } // 从上下文获取用户ID userID, exists := c.Get("user_id") if !exists { response.Error(c, response.ERROR_UNAUTHORIZED) return } refunds, err := h.refundService.GetRefundsByOrderID(c.Request.Context(), uint(orderID), userID.(uint)) if err != nil { logger.Error("获取订单退款记录失败", "error", err, "orderID", orderID, "userID", userID) response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, refunds) } // GetUserRefunds 获取用户的退款记录 // @Summary 获取用户的退款记录 // @Description 用户获取自己的所有退款记录(分页) // @Tags 退款管理 // @Accept json // @Produce json // @Param page query int false "页码" default(1) // @Param page_size query int false "每页数量" default(10) // @Param status query int false "退款状态筛选" // @Success 200 {object} response.Response{data=response.PageResponse{list=[]model.Refund}} // @Failure 400 {object} response.Response // @Router /api/user/refunds [get] func (h *RefundHandler) GetUserRefunds(c *gin.Context) { // 获取分页参数 page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10")) if page < 1 { page = 1 } if pageSize < 1 || pageSize > 100 { pageSize = 10 } // 从上下文获取用户ID userID, exists := c.Get("user_id") if !exists { response.Error(c, response.ERROR_UNAUTHORIZED) return } refunds, total, err := h.refundService.GetRefundsByUserID(c.Request.Context(), userID.(uint), page, pageSize) if err != nil { logger.Error("获取用户退款记录失败", "error", err, "userID", userID) response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Page(c, refunds, total, page, pageSize) } // GetRefundDetail 获取退款详情 // @Summary 获取退款详情 // @Description 用户获取指定退款记录的详细信息 // @Tags 退款管理 // @Accept json // @Produce json // @Param refund_id path int true "退款ID" // @Success 200 {object} response.Response{data=model.Refund} // @Failure 400 {object} response.Response // @Router /api/refunds/{refund_id} [get] func (h *RefundHandler) GetRefundDetail(c *gin.Context) { refundIDStr := c.Param("id") refundID, err := strconv.ParseUint(refundIDStr, 10, 32) if err != nil { response.Error(c, response.ERROR_INVALID_PARAMS) return } // 从上下文获取用户ID userID, exists := c.Get("user_id") if !exists { response.Error(c, response.ERROR_UNAUTHORIZED) return } refund, err := h.refundService.GetRefundByID(c.Request.Context(), uint(refundID), userID.(uint)) if err != nil { logger.Error("获取退款详情失败", "error", err, "refundID", refundID, "userID", userID) response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, refund) } // QueryRefundStatus 查询退款状态 // @Summary 查询退款状态 // @Description 用户主动查询退款状态 // @Tags 退款管理 // @Accept json // @Produce json // @Param refund_id path int true "退款ID" // @Success 200 {object} response.Response // @Failure 400 {object} response.Response // @Router /api/refunds/{refund_id}/query [post] func (h *RefundHandler) QueryRefundStatus(c *gin.Context) { refundIDStr := c.Param("id") refundID, err := strconv.ParseUint(refundIDStr, 10, 32) if err != nil { response.Error(c, response.ERROR_INVALID_PARAMS) return } err = h.refundService.QueryRefundStatus(c.Request.Context(), uint(refundID)) if err != nil { logger.Error("查询退款状态失败", "error", err, "refundID", refundID) response.ErrorWithMessage(c, response.ERROR, err.Error()) return } logger.Info("查询退款状态成功", "refundID", refundID) response.Success(c, "查询完成") } // SyncRefundAndOrderStatus 同步退款状态和订单状态 // @Summary 同步退款状态和订单状态 // @Description 修复退款状态已成功但订单状态未更新的问题 // @Tags 退款管理 // @Accept json // @Produce json // @Success 200 {object} response.Response // @Failure 400 {object} response.Response // @Router /api/admin/refunds/sync-status [post] func (h *RefundHandler) SyncRefundAndOrderStatus(c *gin.Context) { err := h.refundService.SyncRefundAndOrderStatus(c.Request.Context()) if err != nil { logger.Error("同步退款状态和订单状态失败", "error", err) response.ErrorWithMessage(c, response.ERROR, err.Error()) return } logger.Info("同步退款状态和订单状态成功") response.Success(c, "同步完成") } // RefundCallback 微信退款回调 // @Summary 微信退款回调 // @Description 处理微信退款回调通知 // @Tags 退款管理 // @Accept json // @Produce json // @Success 200 {object} response.Response // @Failure 400 {object} response.Response // @Router /api/refunds/callback [post] func (h *RefundHandler) RefundCallback(c *gin.Context) { logger.Info("收到微信退款回调") // 读取请求体 body, err := c.GetRawData() if err != nil { logger.Error("读取退款回调数据失败", "error", err) response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "读取回调数据失败") return } // 获取请求头 headers := make(map[string]string) for key, values := range c.Request.Header { if len(values) > 0 { headers[key] = values[0] } } logger.Info("退款回调数据", "bodyLength", len(body)) // 处理微信退款回调(service层会解析和解密数据) notify, err := h.refundService.HandleWeChatRefundNotify(c.Request.Context(), body, headers) if err != nil { logger.Error("处理退款回调失败", "error", err) response.ErrorWithMessage(c, response.ERROR, "处理回调失败: "+err.Error()) return } // 根据回调类型处理 if notify.EventType == "REFUND.SUCCESS" { // 退款成功,更新退款状态 err = h.refundService.HandleRefundCallback(c.Request.Context(), notify) if err != nil { logger.Error("处理退款成功回调失败", "error", err) response.ErrorWithMessage(c, response.ERROR, "处理退款成功回调失败: "+err.Error()) return } } logger.Info("退款回调处理成功") response.Success(c, gin.H{ "code": "SUCCESS", "message": "处理成功", }) }