package order import ( "errors" "net/http" "strconv" "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} } func (h *Handler) Create(c *gin.Context) { userID, ok := currentUserID(c) if !ok { response.Unauthorized(c, "缺少用户上下文") return } var req CreateRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "订单信息不完整") return } item, err := h.service.Create(userID, req) if err != nil { writeOrderError(c, err) return } response.Created(c, item) } func (h *Handler) List(c *gin.Context) { userID, ok := currentUserID(c) if !ok { response.Unauthorized(c, "缺少用户上下文") return } items, err := h.service.ListForUser(userID) if err != nil { writeOrderError(c, err) return } response.OK(c, gin.H{"items": items}) } func (h *Handler) AdminList(c *gin.Context) { items, err := h.service.ListAdmin() if err != nil { writeOrderError(c, err) return } response.OK(c, gin.H{"items": items}) } func (h *Handler) AdminDetail(c *gin.Context) { id, ok := parseID(c) if !ok { return } item, err := h.service.FindAdmin(id) if err != nil { writeOrderError(c, err) return } response.OK(c, item) } func (h *Handler) AdminHandoffRecords(c *gin.Context) { id, ok := parseID(c) if !ok { return } items, err := h.service.HandoffRecordsAdmin(id) if err != nil { writeOrderError(c, err) return } response.OK(c, gin.H{"items": items}) } func (h *Handler) AdminClose(c *gin.Context) { h.adminAction(c, h.service.AdminClose, gin.H{"closed": true}) } func (h *Handler) AdminMarkAbnormal(c *gin.Context) { h.adminAction(c, h.service.AdminMarkAbnormal, gin.H{"abnormal": true}) } func (h *Handler) AdminRefund(c *gin.Context) { orderID, ok := parseID(c) if !ok { return } item, err := h.service.AdminRefund(orderID) if err != nil { writeOrderError(c, err) return } response.OK(c, item) } func (h *Handler) AdminRefundStatus(c *gin.Context) { orderID, ok := parseID(c) if !ok { return } item, err := h.service.AdminRefundStatus(orderID) if err != nil { writeOrderError(c, err) return } response.OK(c, item) } func (h *Handler) adminAction(c *gin.Context, fn func(uint64, uint64, AdminActionRequest, AuditMeta) error, okData gin.H) { adminID, ok := currentAdminID(c) if !ok { response.Unauthorized(c, "缺少管理员上下文") return } id, ok := parseID(c) if !ok { return } var req AdminActionRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "操作原因不能为空") return } if err := fn(adminID, id, req, auditMeta(c)); err != nil { writeOrderError(c, err) return } response.OK(c, okData) } func auditMeta(c *gin.Context) AuditMeta { return AuditMeta{ IP: c.ClientIP(), UserAgent: c.GetHeader("User-Agent"), RequestID: middleware.GetRequestID(c), } } func (h *Handler) Detail(c *gin.Context) { userID, ok := currentUserID(c) if !ok { response.Unauthorized(c, "缺少用户上下文") return } id, ok := parseID(c) if !ok { return } item, err := h.service.FindForUser(userID, id) if err != nil { writeOrderError(c, err) return } response.OK(c, item) } func (h *Handler) Cancel(c *gin.Context) { userID, ok := currentUserID(c) if !ok { response.Unauthorized(c, "缺少用户上下文") return } id, ok := parseID(c) if !ok { return } if err := h.service.Cancel(userID, id); err != nil { writeOrderError(c, err) return } response.OK(c, gin.H{"cancelled": true}) } func (h *Handler) Pay(c *gin.Context) { userID, ok := currentUserID(c) if !ok { response.Unauthorized(c, "缺少用户上下文") return } id, ok := parseID(c) if !ok { return } if err := h.service.Pay(userID, id); err != nil { writeOrderError(c, err) return } response.OK(c, gin.H{"paid": true}) } func (h *Handler) SubmitHandoff(c *gin.Context) { userID, ok := currentUserID(c) if !ok { response.Unauthorized(c, "缺少用户上下文") return } id, ok := parseID(c) if !ok { return } var req SubmitHandoffRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "交接说明不能为空") return } record, err := h.service.SubmitHandoff(userID, id, req) if err != nil { writeOrderError(c, err) return } response.Created(c, record) } func (h *Handler) ConfirmReceive(c *gin.Context) { userID, ok := currentUserID(c) if !ok { response.Unauthorized(c, "缺少用户上下文") return } id, ok := parseID(c) if !ok { return } if err := h.service.ConfirmReceive(userID, id); err != nil { writeOrderError(c, err) return } response.OK(c, gin.H{"received": true}) } func (h *Handler) HandoffRecords(c *gin.Context) { userID, ok := currentUserID(c) if !ok { response.Unauthorized(c, "缺少用户上下文") return } id, ok := parseID(c) if !ok { return } items, err := h.service.HandoffRecords(userID, id) if err != nil { writeOrderError(c, err) return } response.OK(c, gin.H{"items": items}) } func (h *Handler) SubmitReturn(c *gin.Context) { userID, ok := currentUserID(c) if !ok { response.Unauthorized(c, "缺少用户上下文") return } id, ok := parseID(c) if !ok { return } var req SubmitReturnRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "归还说明不能为空") return } record, err := h.service.SubmitReturn(userID, id, req) if err != nil { writeOrderError(c, err) return } response.Created(c, record) } func (h *Handler) ConfirmReturn(c *gin.Context) { userID, ok := currentUserID(c) if !ok { response.Unauthorized(c, "缺少用户上下文") return } id, ok := parseID(c) if !ok { return } if err := h.service.ConfirmReturn(userID, id); err != nil { writeOrderError(c, err) return } response.OK(c, gin.H{"completed": true}) } func (h *Handler) SubmitCheckout(c *gin.Context) { userID, ok := currentUserID(c) if !ok { response.Unauthorized(c, "缺少用户上下文") return } id, ok := parseID(c) if !ok { return } var req SubmitCheckoutRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "结账说明不能为空") return } record, err := h.service.SubmitCheckout(userID, id, req) if err != nil { writeOrderError(c, err) return } response.Created(c, record) } func (h *Handler) ConfirmCheckout(c *gin.Context) { userID, ok := currentUserID(c) if !ok { response.Unauthorized(c, "缺少用户上下文") return } id, ok := parseID(c) if !ok { return } if err := h.service.ConfirmCheckout(userID, id); err != nil { writeOrderError(c, err) return } response.OK(c, gin.H{"completed": true}) } func (h *Handler) CounterCheckout(c *gin.Context) { userID, ok := currentUserID(c) if !ok { response.Unauthorized(c, "缺少用户上下文") return } id, ok := parseID(c) if !ok { return } var req CounterCheckoutRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "结账修正原因不能为空") return } checkout, err := h.service.CounterCheckout(userID, id, req) if err != nil { writeOrderError(c, err) return } response.OK(c, checkout) } func (h *Handler) AcceptCheckout(c *gin.Context) { userID, ok := currentUserID(c) if !ok { response.Unauthorized(c, "缺少用户上下文") return } id, ok := parseID(c) if !ok { return } if err := h.service.AcceptCheckout(userID, id); err != nil { writeOrderError(c, err) return } response.OK(c, gin.H{"completed": true}) } func currentUserID(c *gin.Context) (uint64, bool) { value, ok := c.Get(middleware.ContextUserID) if !ok { return 0, false } userID, ok := value.(uint64) return userID, ok } func currentAdminID(c *gin.Context) (uint64, bool) { value, ok := c.Get(middleware.ContextAdminID) if !ok { return 0, false } adminID, ok := value.(uint64) return adminID, ok } func parseID(c *gin.Context) (uint64, bool) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil || id == 0 { response.BadRequest(c, "ID 不正确") return 0, false } return id, true } func writeOrderError(c *gin.Context, err error) { switch { case errors.Is(err, ErrDependencyUnavailable): response.ServiceUnavailable(c, "数据库未连接") case errors.Is(err, ErrInvalidRentHours): response.BadRequest(c, "订单信息不符合规则") case errors.Is(err, ErrListingUnavailable): response.Error(c, http.StatusConflict, "listing_unavailable", "该账号暂不可租") case errors.Is(err, ErrCannotRentOwnListing): response.BadRequest(c, "不能租用自己发布的账号") case errors.Is(err, ErrInsufficientBalance): response.Error(c, http.StatusConflict, "insufficient_balance", "钱包余额不足,请先充值") case errors.Is(err, ErrChannelPaymentRequired): response.Error(c, http.StatusGone, "channel_payment_required", "请使用第三方支付入口完成订单付款") case errors.Is(err, ErrOrderCannotPay): response.Error(c, http.StatusConflict, "order_cannot_pay", "当前订单不能支付") case errors.Is(err, ErrOrderCannotCancel): response.Error(c, http.StatusConflict, "order_cannot_cancel", "当前订单不能取消") case errors.Is(err, ErrOrderCannotHandoff): response.Error(c, http.StatusConflict, "order_cannot_handoff", "当前订单不能交接") case errors.Is(err, ErrOrderCannotReceive): response.Error(c, http.StatusConflict, "order_cannot_receive", "当前订单不能确认收号") case errors.Is(err, ErrOrderCannotReturn): response.Error(c, http.StatusConflict, "order_cannot_return", "当前订单不能归还") case errors.Is(err, ErrOrderCannotComplete): response.Error(c, http.StatusConflict, "order_cannot_complete", "当前订单不能完成") case errors.Is(err, ErrCheckoutCannotSubmit): response.Error(c, http.StatusConflict, "checkout_cannot_submit", "当前订单不能发起结账") case errors.Is(err, ErrCheckoutCannotConfirm): response.Error(c, http.StatusConflict, "checkout_cannot_confirm", "当前结账不能确认") case errors.Is(err, ErrCheckoutCannotCounter): response.Error(c, http.StatusConflict, "checkout_cannot_counter", "当前结账不能修改") case errors.Is(err, ErrInvalidCheckoutAmount): response.BadRequest(c, "结账金额不符合规则") case errors.Is(err, ErrPermissionDenied): response.Error(c, http.StatusForbidden, "permission_denied", "无权操作该订单") case IsNotFound(err): response.Error(c, http.StatusNotFound, "not_found", "订单不存在") default: response.Error(c, http.StatusInternalServerError, "internal_error", "订单服务暂时不可用") } }