package handler import ( "dianshang/internal/service" "dianshang/pkg/response" "dianshang/pkg/utils" "strconv" "time" "github.com/gin-gonic/gin" ) // AdminOrderHandler 管理后台订单处理器 type AdminOrderHandler struct { orderService *service.OrderService } // NewAdminOrderHandler 创建管理后台订单处理器 func NewAdminOrderHandler(orderService *service.OrderService) *AdminOrderHandler { return &AdminOrderHandler{ orderService: orderService, } } // GetOrderList 获取订单列表 func (h *AdminOrderHandler) GetOrderList(c *gin.Context) { page := utils.StringToInt(c.DefaultQuery("page", "1")) pageSize := utils.StringToInt(c.DefaultQuery("page_size", "10")) status := c.Query("status") orderNo := c.Query("order_no") userID := utils.StringToUint(c.Query("user_id")) startDate := c.Query("start_date") endDate := c.Query("end_date") if page <= 0 { page = 1 } if pageSize <= 0 || pageSize > 100 { pageSize = 10 } // 构建查询条件 conditions := make(map[string]interface{}) if status != "" { conditions["status"] = status } if orderNo != "" { conditions["order_no"] = orderNo } if userID > 0 { conditions["user_id"] = userID } if startDate != "" { conditions["start_date"] = startDate } if endDate != "" { conditions["end_date"] = endDate } orders, pagination, err := h.orderService.GetOrderListForAdmin(page, pageSize, conditions) if err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, gin.H{ "list": orders, "pagination": pagination, }) } // GetOrderDetail 获取订单详情 func (h *AdminOrderHandler) GetOrderDetail(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.BadRequest(c, "无效的订单ID") return } order, err := h.orderService.GetOrderDetailForAdmin(uint(id)) if err != nil { response.ErrorWithMessage(c, response.ERROR, "订单不存在") return } response.Success(c, order) } // UpdateOrderStatus 更新订单状态 func (h *AdminOrderHandler) UpdateOrderStatus(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.BadRequest(c, "无效的订单ID") return } var req struct { Status int `json:"status" binding:"required"` Remark string `json:"remark"` } if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "请求参数错误") return } if err := h.orderService.UpdateOrderStatusByAdmin(uint(id), req.Status, req.Remark); err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, nil) } // ShipOrder 发货 func (h *AdminOrderHandler) ShipOrder(c *gin.Context) { idStr := c.Param("id") if idStr == "" { response.BadRequest(c, "无效的订单ID") return } orderID, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.BadRequest(c, "无效的订单ID") return } var req struct { LogisticsCompany string `json:"logistics_company" binding:"required"` TrackingNumber string `json:"tracking_number" binding:"required"` Remark string `json:"remark"` } if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "请求参数错误") return } if err := h.orderService.ShipOrderByID(uint(orderID), req.LogisticsCompany, req.TrackingNumber); err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, nil) } // RefundOrder 退款 func (h *AdminOrderHandler) RefundOrder(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.BadRequest(c, "无效的订单ID") return } var req struct { RefundAmount float64 `json:"refund_amount" binding:"required"` RefundReason string `json:"refund_reason" binding:"required"` Remark string `json:"remark"` } if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "请求参数错误") return } // 获取管理员ID adminID := uint(0) if adminIDValue, exists := c.Get("user_id"); exists { adminID = adminIDValue.(uint) } if err := h.orderService.RefundOrder(uint(id), req.RefundAmount, req.RefundReason, adminID); err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, nil) } // CancelOrder 取消订单 func (h *AdminOrderHandler) CancelOrder(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.BadRequest(c, "无效的订单ID") return } var req struct { CancelReason string `json:"cancel_reason" binding:"required"` Remark string `json:"remark"` } if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "请求参数错误") return } // 获取管理员ID adminID := uint(0) if adminIDValue, exists := c.Get("user_id"); exists { adminID = adminIDValue.(uint) } if err := h.orderService.CancelOrderByAdmin(uint(id), req.CancelReason, adminID); err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, nil) } // GetLogisticsInfo 获取物流信息 func (h *AdminOrderHandler) GetLogisticsInfo(c *gin.Context) { orderNo := c.Param("orderNo") if orderNo == "" { response.BadRequest(c, "无效的订单号") return } logisticsInfo, err := h.orderService.GetLogisticsInfo(orderNo) if err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, logisticsInfo) } // UpdateOrderStatusNew 更新订单状态(新版本) func (h *AdminOrderHandler) UpdateOrderStatusNew(c *gin.Context) { orderIDStr := c.Param("id") orderID, err := strconv.ParseUint(orderIDStr, 10, 32) if err != nil { response.BadRequest(c, "无效的订单ID") return } var req struct { Status int `json:"status" binding:"required"` Reason string `json:"reason"` } if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "请求参数错误") return } // 获取管理员ID adminID := uint(0) if id, exists := c.Get("user_id"); exists { adminID = id.(uint) } if err := h.orderService.UpdateOrderStatus(uint(orderID), req.Status, adminID); err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, nil) } // BatchUpdateOrderStatus 批量更新订单状态 func (h *AdminOrderHandler) BatchUpdateOrderStatus(c *gin.Context) { var req struct { OrderIDs []uint `json:"order_ids" binding:"required"` Status int `json:"status" binding:"required"` Reason string `json:"reason"` } if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "请求参数错误") return } // 获取管理员ID adminID := uint(0) if id, exists := c.Get("user_id"); exists { adminID = id.(uint) } if err := h.orderService.BatchUpdateOrderStatus(req.OrderIDs, req.Status, adminID); err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, nil) } // ProcessRefund 处理退款 func (h *AdminOrderHandler) ProcessRefund(c *gin.Context) { orderIDStr := c.Param("id") orderID, err := strconv.ParseUint(orderIDStr, 10, 32) if err != nil { response.BadRequest(c, "无效的订单ID") return } var req struct { RefundAmount float64 `json:"refund_amount" binding:"required"` RefundReason string `json:"refund_reason" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "请求参数错误") return } // 获取管理员ID adminID := uint(0) if id, exists := c.Get("user_id"); exists { adminID = id.(uint) } if err := h.orderService.ProcessRefund(uint(orderID), req.RefundAmount, req.RefundReason, adminID); err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, nil) } // GetOrderStatistics 获取订单统计 func (h *AdminOrderHandler) GetOrderStatistics(c *gin.Context) { statistics, err := h.orderService.GetOrderStatistics() if err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, statistics) } // GetDailyOrderStatistics 获取每日订单统计 func (h *AdminOrderHandler) GetDailyOrderStatistics(c *gin.Context) { daysStr := c.DefaultQuery("days", "7") days, err := strconv.Atoi(daysStr) if err != nil || days <= 0 { days = 7 } statistics, err := h.orderService.GetDailyOrderStatistics(days) if err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, statistics) } // GetOrdersByDateRange 根据日期范围获取订单 func (h *AdminOrderHandler) GetOrdersByDateRange(c *gin.Context) { startDate := c.Query("start_date") endDate := c.Query("end_date") statusStr := c.DefaultQuery("status", "0") pageStr := c.DefaultQuery("page", "1") limitStr := c.DefaultQuery("limit", "20") status, _ := strconv.Atoi(statusStr) page, _ := strconv.Atoi(pageStr) limit, _ := strconv.Atoi(limitStr) if page <= 0 { page = 1 } if limit <= 0 { limit = 20 } offset := (page - 1) * limit orders, total, err := h.orderService.GetOrdersByDateRange(startDate, endDate, status, offset, limit) if err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, gin.H{ "list": orders, "total": total, "page": page, "limit": limit, }) } // ExportOrdersToExcel 导出订单到Excel func (h *AdminOrderHandler) ExportOrdersToExcel(c *gin.Context) { // 获取查询条件 conditions := make(map[string]interface{}) if startDate := c.Query("start_date"); startDate != "" { conditions["start_date"] = startDate } if endDate := c.Query("end_date"); endDate != "" { conditions["end_date"] = endDate } if statusStr := c.Query("status"); statusStr != "" { if status, err := strconv.Atoi(statusStr); err == nil && status > 0 { conditions["status"] = status } } if orderNo := c.Query("order_no"); orderNo != "" { conditions["order_no"] = orderNo } exportData, err := h.orderService.ExportOrdersToExcel(conditions) if err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } // 这里应该生成Excel文件并返回下载链接 // 暂时返回数据,实际项目中需要使用Excel库生成文件 response.Success(c, gin.H{ "data": exportData, "filename": "orders_" + time.Now().Format("20060102_150405") + ".xlsx", "message": "导出成功", }) } // GetOrderTrends 获取订单趋势 func (h *AdminOrderHandler) GetOrderTrends(c *gin.Context) { daysStr := c.DefaultQuery("days", "30") days, err := strconv.Atoi(daysStr) if err != nil || days <= 0 { days = 30 } trends, err := h.orderService.GetOrderTrends(days) if err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, trends) } // GetPendingOrdersCount 获取待处理订单数量 func (h *AdminOrderHandler) GetPendingOrdersCount(c *gin.Context) { count, err := h.orderService.GetPendingOrdersCount() if err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, gin.H{ "pending_count": count, }) } // GetOrderSummary 获取订单概览 func (h *AdminOrderHandler) GetOrderSummary(c *gin.Context) { // 获取基本统计 statistics, err := h.orderService.GetOrderStatistics() if err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } // 获取待处理订单数量 pendingCount, err := h.orderService.GetPendingOrdersCount() if err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } // 获取7天趋势 trends, err := h.orderService.GetOrderTrends(7) if err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } summary := gin.H{ "statistics": statistics, "pending_count": pendingCount, "trends": trends, "updated_at": time.Now().Format("2006-01-02 15:04:05"), } response.Success(c, summary) } // BatchProcessOrders 批量处理订单 func (h *AdminOrderHandler) BatchProcessOrders(c *gin.Context) { var req struct { OrderIDs []uint `json:"order_ids" binding:"required"` Action string `json:"action" binding:"required"` // "ship", "cancel", "refund" Data gin.H `json:"data"` // 额外数据,如物流信息等 } if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "请求参数错误") return } // 获取管理员ID adminID := uint(0) if id, exists := c.Get("user_id"); exists { adminID = id.(uint) } switch req.Action { case "ship": // 批量发货 logisticsCompany, _ := req.Data["logistics_company"].(string) trackingNumber, _ := req.Data["tracking_number"].(string) if logisticsCompany == "" || trackingNumber == "" { response.BadRequest(c, "发货需要提供物流公司和运单号") return } for _, orderID := range req.OrderIDs { // 这里需要根据订单ID获取订单号 order, err := h.orderService.GetOrderDetailForAdmin(orderID) if err != nil { response.ErrorWithMessage(c, response.ERROR, "订单不存在: "+err.Error()) return } if err := h.orderService.ShipOrder(order.OrderNo, logisticsCompany, trackingNumber); err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } } case "cancel": // 批量取消 cancelReason, _ := req.Data["cancel_reason"].(string) if cancelReason == "" { cancelReason = "管理员批量取消" } for _, orderID := range req.OrderIDs { if err := h.orderService.CancelOrderByAdmin(orderID, cancelReason, adminID); err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } } case "status": // 批量更新状态 status, ok := req.Data["status"].(float64) if !ok { response.BadRequest(c, "状态更新需要提供status字段") return } if err := h.orderService.BatchUpdateOrderStatus(req.OrderIDs, int(status), adminID); err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } default: response.BadRequest(c, "不支持的操作类型") return } response.Success(c, nil) } // ExportOrders 导出订单 func (h *AdminOrderHandler) ExportOrders(c *gin.Context) { startDate := c.Query("start_date") endDate := c.Query("end_date") status := c.Query("status") // 构建查询条件 conditions := make(map[string]interface{}) if status != "" { conditions["status"] = status } if startDate != "" { conditions["start_date"] = startDate } if endDate != "" { conditions["end_date"] = endDate } // 获取所有符合条件的订单(不分页) orders, _, err := h.orderService.GetOrderListForAdmin(1, 10000, conditions) if err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } // 设置响应头 c.Header("Content-Type", "application/vnd.ms-excel") c.Header("Content-Disposition", "attachment; filename=orders_"+time.Now().Format("20060102150405")+".csv") // 简单的CSV格式导出 csvData := "订单号,用户ID,订单状态,订单金额,创建时间\n" for _, order := range orders { csvData += order.OrderNo + "," + strconv.Itoa(int(order.UserID)) + "," + strconv.Itoa(order.Status) + "," + strconv.FormatFloat(order.TotalAmount, 'f', 2, 64) + "," + order.CreatedAt.Format("2006-01-02 15:04:05") + "\n" } c.String(200, csvData) }