package handler import ( "strconv" "github.com/break/junhong_cmp_fiber/internal/model" "github.com/break/junhong_cmp_fiber/internal/service/order" "github.com/break/junhong_cmp_fiber/pkg/errors" "github.com/break/junhong_cmp_fiber/pkg/response" "github.com/gofiber/fiber/v2" "go.uber.org/zap" ) // OrderHandler 订单处理器 type OrderHandler struct { orderService *order.Service logger *zap.Logger } // NewOrderHandler 创建订单处理器实例 func NewOrderHandler(orderService *order.Service, logger *zap.Logger) *OrderHandler { return &OrderHandler{ orderService: orderService, logger: logger, } } // CreateOrder 创建订单 // POST /api/v1/orders func (h *OrderHandler) CreateOrder(c *fiber.Ctx) error { var req model.CreateOrderRequest // 解析请求体 if err := c.BodyParser(&req); err != nil { h.logger.Warn("解析请求体失败", zap.String("path", c.Path()), zap.Error(err)) return response.Error(c, fiber.StatusBadRequest, errors.CodeBadRequest, "请求参数格式错误") } // 验证请求参数 if err := validate.Struct(&req); err != nil { h.logger.Warn("参数验证失败", zap.String("path", c.Path()), zap.Any("request", req), zap.Error(err)) return response.Error(c, fiber.StatusBadRequest, errors.CodeBadRequest, err.Error()) } // 调用服务层创建订单 orderResp, err := h.orderService.CreateOrder(c.Context(), &req) if err != nil { if e, ok := err.(*errors.AppError); ok { httpStatus := fiber.StatusInternalServerError if e.Code == errors.CodeNotFound { httpStatus = fiber.StatusNotFound } return response.Error(c, httpStatus, e.Code, e.Message) } h.logger.Error("创建订单失败", zap.String("order_id", req.OrderID), zap.Error(err)) return response.Error(c, fiber.StatusInternalServerError, errors.CodeInternalError, "创建订单失败") } h.logger.Info("订单创建成功", zap.Uint("order_id", orderResp.ID), zap.String("order_no", orderResp.OrderID)) return response.Success(c, orderResp) } // GetOrder 获取订单详情 // GET /api/v1/orders/:id func (h *OrderHandler) GetOrder(c *fiber.Ctx) error { // 获取路径参数 idStr := c.Params("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { h.logger.Warn("订单ID格式错误", zap.String("id", idStr), zap.Error(err)) return response.Error(c, fiber.StatusBadRequest, errors.CodeBadRequest, "订单ID格式错误") } // 调用服务层获取订单 orderResp, err := h.orderService.GetOrderByID(c.Context(), uint(id)) if err != nil { if e, ok := err.(*errors.AppError); ok { httpStatus := fiber.StatusInternalServerError if e.Code == errors.CodeNotFound { httpStatus = fiber.StatusNotFound } return response.Error(c, httpStatus, e.Code, e.Message) } h.logger.Error("获取订单失败", zap.Uint("order_id", uint(id)), zap.Error(err)) return response.Error(c, fiber.StatusInternalServerError, errors.CodeInternalError, "获取订单失败") } return response.Success(c, orderResp) } // UpdateOrder 更新订单信息 // PUT /api/v1/orders/:id func (h *OrderHandler) UpdateOrder(c *fiber.Ctx) error { // 获取路径参数 idStr := c.Params("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { h.logger.Warn("订单ID格式错误", zap.String("id", idStr), zap.Error(err)) return response.Error(c, fiber.StatusBadRequest, errors.CodeBadRequest, "订单ID格式错误") } var req model.UpdateOrderRequest // 解析请求体 if err := c.BodyParser(&req); err != nil { h.logger.Warn("解析请求体失败", zap.String("path", c.Path()), zap.Error(err)) return response.Error(c, fiber.StatusBadRequest, errors.CodeBadRequest, "请求参数格式错误") } // 验证请求参数 if err := validate.Struct(&req); err != nil { h.logger.Warn("参数验证失败", zap.String("path", c.Path()), zap.Any("request", req), zap.Error(err)) return response.Error(c, fiber.StatusBadRequest, errors.CodeBadRequest, err.Error()) } // 调用服务层更新订单 orderResp, err := h.orderService.UpdateOrder(c.Context(), uint(id), &req) if err != nil { if e, ok := err.(*errors.AppError); ok { httpStatus := fiber.StatusInternalServerError if e.Code == errors.CodeNotFound { httpStatus = fiber.StatusNotFound } return response.Error(c, httpStatus, e.Code, e.Message) } h.logger.Error("更新订单失败", zap.Uint("order_id", uint(id)), zap.Error(err)) return response.Error(c, fiber.StatusInternalServerError, errors.CodeInternalError, "更新订单失败") } h.logger.Info("订单更新成功", zap.Uint("order_id", uint(id))) return response.Success(c, orderResp) } // ListOrders 获取订单列表(分页) // GET /api/v1/orders func (h *OrderHandler) ListOrders(c *fiber.Ctx) error { // 获取查询参数 page, err := strconv.Atoi(c.Query("page", "1")) if err != nil || page < 1 { page = 1 } pageSize, err := strconv.Atoi(c.Query("page_size", "20")) if err != nil || pageSize < 1 { pageSize = 20 } if pageSize > 100 { pageSize = 100 // 限制最大页大小 } // 可选的用户ID过滤 var userID uint if userIDStr := c.Query("user_id"); userIDStr != "" { if id, err := strconv.ParseUint(userIDStr, 10, 32); err == nil { userID = uint(id) } } // 调用服务层获取订单列表 var orders []model.Order var total int64 if userID > 0 { // 按用户ID查询 orders, total, err = h.orderService.ListOrdersByUserID(c.Context(), userID, page, pageSize) } else { // 查询所有订单 orders, total, err = h.orderService.ListOrders(c.Context(), page, pageSize) } if err != nil { if e, ok := err.(*errors.AppError); ok { return response.Error(c, fiber.StatusInternalServerError, e.Code, e.Message) } h.logger.Error("获取订单列表失败", zap.Int("page", page), zap.Int("page_size", pageSize), zap.Uint("user_id", userID), zap.Error(err)) return response.Error(c, fiber.StatusInternalServerError, errors.CodeInternalError, "获取订单列表失败") } // 构造响应 totalPages := int(total) / pageSize if int(total)%pageSize > 0 { totalPages++ } listResp := model.ListOrdersResponse{ Orders: make([]model.OrderResponse, 0, len(orders)), Page: page, PageSize: pageSize, Total: total, TotalPages: totalPages, } // 转换为响应格式 for _, o := range orders { listResp.Orders = append(listResp.Orders, model.OrderResponse{ ID: o.ID, OrderID: o.OrderID, UserID: o.UserID, Amount: o.Amount, Status: o.Status, Remark: o.Remark, PaidAt: o.PaidAt, CompletedAt: o.CompletedAt, CreatedAt: o.CreatedAt, UpdatedAt: o.UpdatedAt, }) } return response.Success(c, listResp) }