331 lines
11 KiB
Go
331 lines
11 KiB
Go
package handler
|
||
|
||
import (
|
||
"dianshang/internal/service"
|
||
"dianshang/pkg/logger"
|
||
"dianshang/pkg/response"
|
||
"strconv"
|
||
"time"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
type AdminRefundHandler struct {
|
||
refundService *service.RefundService
|
||
orderService *service.OrderService
|
||
}
|
||
|
||
func NewAdminRefundHandler(refundService *service.RefundService, orderService *service.OrderService) *AdminRefundHandler {
|
||
return &AdminRefundHandler{
|
||
refundService: refundService,
|
||
orderService: orderService,
|
||
}
|
||
}
|
||
|
||
// GetPendingRefunds 获取待处理的退款申请
|
||
// @Summary 获取待处理的退款申请
|
||
// @Description 管理员获取所有待处理的退款申请(分页)
|
||
// @Tags 管理员-退款管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param page query int false "页码" default(1)
|
||
// @Param page_size query int false "每页数量" default(10)
|
||
// @Success 200 {object} response.Response{data=response.PageResponse{list=[]model.Refund}}
|
||
// @Failure 400 {object} response.Response
|
||
// @Router /admin/refunds/pending [get]
|
||
func (h *AdminRefundHandler) GetPendingRefunds(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
|
||
}
|
||
|
||
// 获取待处理的退款申请
|
||
refunds, total, err := h.refundService.GetPendingRefunds(c.Request.Context(), page, pageSize)
|
||
if err != nil {
|
||
logger.Error("获取待处理退款申请失败", "error", err)
|
||
response.ErrorWithMessage(c, response.ERROR, "获取待处理退款申请失败")
|
||
return
|
||
}
|
||
|
||
response.Page(c, refunds, total, page, pageSize)
|
||
}
|
||
|
||
// ProcessRefund 处理退款申请
|
||
// @Summary 处理退款申请
|
||
// @Description 管理员审核并处理退款申请
|
||
// @Tags 管理员-退款管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param refund_id path int true "退款ID"
|
||
// @Param request body ProcessRefundRequest true "处理退款请求"
|
||
// @Success 200 {object} response.Response
|
||
// @Failure 400 {object} response.Response
|
||
// @Router /admin/refunds/{refund_id}/process [post]
|
||
func (h *AdminRefundHandler) ProcessRefund(c *gin.Context) {
|
||
refundIDStr := c.Param("id")
|
||
logger.Info("ProcessRefund开始", "refund_id_param", refundIDStr, "path", c.Request.URL.Path)
|
||
refundID, err := strconv.ParseUint(refundIDStr, 10, 32)
|
||
if err != nil {
|
||
logger.Error("解析退款ID失败", "refund_id_str", refundIDStr, "error", err)
|
||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "无效的退款ID")
|
||
return
|
||
}
|
||
|
||
var req ProcessRefundRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
logger.Error("绑定处理退款参数失败", "error", err)
|
||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "参数错误: "+err.Error())
|
||
return
|
||
}
|
||
|
||
// 从上下文获取管理员ID(中间件设置的是user_id)
|
||
adminID, exists := c.Get("user_id")
|
||
if !exists {
|
||
response.Error(c, response.ERROR_UNAUTHORIZED)
|
||
return
|
||
}
|
||
|
||
err = h.refundService.ProcessRefund(c.Request.Context(), uint(refundID), adminID.(uint), req.AdminRemark)
|
||
if err != nil {
|
||
logger.Error("处理退款申请失败", "error", err, "refundID", refundID, "adminID", adminID)
|
||
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
||
return
|
||
}
|
||
|
||
logger.Info("退款申请处理成功", "refundID", refundID, "adminID", adminID)
|
||
response.Success(c, "处理成功")
|
||
}
|
||
|
||
// RejectRefund 拒绝退款申请
|
||
// @Summary 拒绝退款申请
|
||
// @Description 管理员拒绝退款申请
|
||
// @Tags 管理员-退款管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param refund_id path int true "退款ID"
|
||
// @Param request body RejectRefundRequest true "拒绝退款请求"
|
||
// @Success 200 {object} response.Response
|
||
// @Failure 400 {object} response.Response
|
||
// @Router /admin/refunds/{refund_id}/reject [post]
|
||
func (h *AdminRefundHandler) RejectRefund(c *gin.Context) {
|
||
refundIDStr := c.Param("id")
|
||
refundID, err := strconv.ParseUint(refundIDStr, 10, 32)
|
||
if err != nil {
|
||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "无效的退款ID")
|
||
return
|
||
}
|
||
|
||
var req RejectRefundRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
logger.Error("绑定拒绝退款参数失败", "error", err)
|
||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "参数错误: "+err.Error())
|
||
return
|
||
}
|
||
|
||
// 从上下文获取管理员ID(中间件设置的是user_id)
|
||
adminID, exists := c.Get("user_id")
|
||
if !exists {
|
||
response.Error(c, response.ERROR_UNAUTHORIZED)
|
||
return
|
||
}
|
||
|
||
err = h.refundService.RejectRefund(c.Request.Context(), uint(refundID), adminID.(uint), req.RejectReason)
|
||
if err != nil {
|
||
logger.Error("拒绝退款申请失败", "error", err, "refundID", refundID, "adminID", adminID)
|
||
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
||
return
|
||
}
|
||
|
||
logger.Info("退款申请已拒绝", "refundID", refundID, "adminID", adminID, "reason", req.RejectReason)
|
||
response.Success(c, "拒绝成功")
|
||
}
|
||
|
||
// GetAllRefunds 获取所有退款记录
|
||
// @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 "退款状态筛选"
|
||
// @Param user_id query int false "用户ID筛选"
|
||
// @Success 200 {object} response.Response{data=response.PageResponse{list=[]model.Refund}}
|
||
// @Failure 400 {object} response.Response
|
||
// @Router /admin/refunds [get]
|
||
func (h *AdminRefundHandler) GetAllRefunds(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
|
||
}
|
||
|
||
// 获取筛选参数
|
||
status := c.Query("status")
|
||
userID := c.Query("user_id")
|
||
|
||
// 获取所有退款记录
|
||
refunds, total, err := h.refundService.GetAllRefunds(c.Request.Context(), page, pageSize, status, userID)
|
||
if err != nil {
|
||
logger.Error("获取退款记录失败", "error", err)
|
||
response.ErrorWithMessage(c, response.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 /admin/refunds/{refund_id} [get]
|
||
func (h *AdminRefundHandler) GetRefundDetail(c *gin.Context) {
|
||
refundIDStr := c.Param("id")
|
||
refundID, err := strconv.ParseUint(refundIDStr, 10, 32)
|
||
if err != nil {
|
||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "无效的退款ID")
|
||
return
|
||
}
|
||
|
||
refund, err := h.refundService.GetRefundDetailForAdmin(c.Request.Context(), uint(refundID))
|
||
if err != nil {
|
||
logger.Error("获取退款详情失败", "error", err, "refundID", refundID)
|
||
response.ErrorWithMessage(c, response.ERROR, err.Error())
|
||
return
|
||
}
|
||
|
||
response.Success(c, refund)
|
||
}
|
||
|
||
// GetRefundLogs 获取退款日志
|
||
// @Summary 获取退款日志
|
||
// @Description 管理员获取指定退款的操作日志
|
||
// @Tags 管理员-退款管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param refund_id path int true "退款ID"
|
||
// @Success 200 {object} response.Response{data=[]model.RefundLog}
|
||
// @Failure 400 {object} response.Response
|
||
// @Router /admin/refunds/{refund_id}/logs [get]
|
||
func (h *AdminRefundHandler) GetRefundLogs(c *gin.Context) {
|
||
refundIDStr := c.Param("id")
|
||
refundID, err := strconv.ParseUint(refundIDStr, 10, 32)
|
||
if err != nil {
|
||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "无效的退款ID")
|
||
return
|
||
}
|
||
|
||
// 获取退款日志
|
||
logs, err := h.refundService.GetRefundLogs(c.Request.Context(), uint(refundID))
|
||
if err != nil {
|
||
logger.Error("获取退款日志失败", "error", err, "refundID", refundID)
|
||
response.ErrorWithMessage(c, response.ERROR, "获取退款日志失败")
|
||
return
|
||
}
|
||
|
||
logger.Info("获取退款日志成功", "refundID", refundID, "logCount", len(logs))
|
||
response.Success(c, logs)
|
||
}
|
||
|
||
// GetRefundStatistics 获取退款统计
|
||
// @Summary 获取退款统计
|
||
// @Description 获取退款统计数据
|
||
// @Tags 管理员-退款管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param start_date query string false "开始日期"
|
||
// @Param end_date query string false "结束日期"
|
||
// @Success 200 {object} response.Response
|
||
// @Failure 400 {object} response.Response
|
||
// @Router /admin/refunds/statistics [get]
|
||
func (h *AdminRefundHandler) GetRefundStatistics(c *gin.Context) {
|
||
startDate := c.Query("start_date")
|
||
endDate := c.Query("end_date")
|
||
|
||
// 如果没有提供日期,默认查询最近30天
|
||
if startDate == "" || endDate == "" {
|
||
now := time.Now()
|
||
endDate = now.Format("2006-01-02")
|
||
startDate = now.AddDate(0, 0, -30).Format("2006-01-02")
|
||
}
|
||
|
||
// 解析日期
|
||
startTime, err := time.Parse("2006-01-02", startDate)
|
||
if err != nil {
|
||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "开始日期格式错误")
|
||
return
|
||
}
|
||
endTime, err := time.Parse("2006-01-02", endDate)
|
||
if err != nil {
|
||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "结束日期格式错误")
|
||
return
|
||
}
|
||
|
||
// 设置时间范围到一天的结束
|
||
endTime = endTime.Add(23*time.Hour + 59*time.Minute + 59*time.Second)
|
||
|
||
// 使用退款服务获取真实统计数据
|
||
stats, err := h.refundService.GetRefundStatistics(c.Request.Context(), startTime, endTime)
|
||
if err != nil {
|
||
logger.Error("获取退款统计失败", "error", err)
|
||
response.ErrorWithMessage(c, response.ERROR, "获取退款统计失败")
|
||
return
|
||
}
|
||
|
||
response.Success(c, stats)
|
||
}
|
||
|
||
// 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 /admin/refunds/{refund_id}/query [post]
|
||
func (h *AdminRefundHandler) QueryRefundStatus(c *gin.Context) {
|
||
refundIDStr := c.Param("id")
|
||
refundID, err := strconv.ParseUint(refundIDStr, 10, 32)
|
||
if err != nil {
|
||
response.ErrorWithMessage(c, response.ERROR_INVALID_PARAMS, "无效的退款ID")
|
||
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, "查询完成")
|
||
}
|
||
|
||
// 请求结构体
|
||
type ProcessRefundRequest struct {
|
||
AdminRemark string `json:"admin_remark" binding:"max=500"`
|
||
}
|
||
|
||
type RejectRefundRequest struct {
|
||
RejectReason string `json:"reject_reason" binding:"required,max=500"`
|
||
} |