diff --git a/backend/internal/modules/order/handler.go b/backend/internal/modules/order/handler.go index c92989a..67612cb 100644 --- a/backend/internal/modules/order/handler.go +++ b/backend/internal/modules/order/handler.go @@ -1,17 +1,5 @@ package order -import ( - "context" - "errors" - "net/http" - "strconv" - - "hfb_sys/backend/internal/middleware" - "hfb_sys/backend/pkg/response" - - "github.com/gin-gonic/gin" -) - type Handler struct { service *Service } @@ -19,451 +7,3 @@ type Handler struct { 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(c.Request.Context(), 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(c.Request.Context(), userID) - if err != nil { - writeOrderError(c, err) - return - } - response.OK(c, gin.H{"items": items}) -} - -func (h *Handler) AdminList(c *gin.Context) { - page, pageSize := parsePagination(c) - result, err := h.service.ListAdmin(c.Request.Context(), page, pageSize) - if err != nil { - writeOrderError(c, err) - return - } - response.OK(c, result) -} - -func (h *Handler) AdminDetail(c *gin.Context) { - id, ok := parseID(c) - if !ok { - return - } - item, err := h.service.FindAdmin(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), orderID) - if err != nil { - writeOrderError(c, err) - return - } - response.OK(c, item) -} - -func (h *Handler) adminAction(c *gin.Context, fn func(context.Context, 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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), 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 parsePagination(c *gin.Context) (int, int) { - page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) - pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) - if page < 1 { - page = 1 - } - if pageSize < 1 { - pageSize = 20 - } - if pageSize > 100 { - pageSize = 100 - } - return page, pageSize -} - -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", "订单服务暂时不可用") - } -} diff --git a/backend/internal/modules/order/handler_admin.go b/backend/internal/modules/order/handler_admin.go new file mode 100644 index 0000000..92845fb --- /dev/null +++ b/backend/internal/modules/order/handler_admin.go @@ -0,0 +1,110 @@ +package order + +import ( + "context" + + "hfb_sys/backend/internal/middleware" + "hfb_sys/backend/pkg/response" + + "github.com/gin-gonic/gin" +) + +func (h *Handler) AdminList(c *gin.Context) { + page, pageSize := parsePagination(c) + result, err := h.service.ListAdmin(c.Request.Context(), page, pageSize) + if err != nil { + writeOrderError(c, err) + return + } + response.OK(c, result) +} + +func (h *Handler) AdminDetail(c *gin.Context) { + id, ok := parseID(c) + if !ok { + return + } + item, err := h.service.FindAdmin(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), orderID) + if err != nil { + writeOrderError(c, err) + return + } + response.OK(c, item) +} + +func (h *Handler) adminAction(c *gin.Context, fn func(context.Context, 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(c.Request.Context(), 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), + } +} diff --git a/backend/internal/modules/order/handler_error.go b/backend/internal/modules/order/handler_error.go new file mode 100644 index 0000000..e33f6b6 --- /dev/null +++ b/backend/internal/modules/order/handler_error.go @@ -0,0 +1,53 @@ +package order + +import ( + "errors" + "net/http" + + "hfb_sys/backend/pkg/response" + + "github.com/gin-gonic/gin" +) + +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", "订单服务暂时不可用") + } +} diff --git a/backend/internal/modules/order/handler_flow.go b/backend/internal/modules/order/handler_flow.go new file mode 100644 index 0000000..9b917e5 --- /dev/null +++ b/backend/internal/modules/order/handler_flow.go @@ -0,0 +1,185 @@ +package order + +import ( + "hfb_sys/backend/pkg/response" + + "github.com/gin-gonic/gin" +) + +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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), userID, id); err != nil { + writeOrderError(c, err) + return + } + response.OK(c, gin.H{"completed": true}) +} diff --git a/backend/internal/modules/order/handler_parse.go b/backend/internal/modules/order/handler_parse.go new file mode 100644 index 0000000..c80510e --- /dev/null +++ b/backend/internal/modules/order/handler_parse.go @@ -0,0 +1,52 @@ +package order + +import ( + "strconv" + + "hfb_sys/backend/internal/middleware" + "hfb_sys/backend/pkg/response" + + "github.com/gin-gonic/gin" +) + +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 parsePagination(c *gin.Context) (int, int) { + page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) + pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) + if page < 1 { + page = 1 + } + if pageSize < 1 { + pageSize = 20 + } + if pageSize > 100 { + pageSize = 100 + } + return page, pageSize +} diff --git a/backend/internal/modules/order/handler_user.go b/backend/internal/modules/order/handler_user.go new file mode 100644 index 0000000..71d915b --- /dev/null +++ b/backend/internal/modules/order/handler_user.go @@ -0,0 +1,92 @@ +package order + +import ( + "hfb_sys/backend/pkg/response" + + "github.com/gin-gonic/gin" +) + +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(c.Request.Context(), 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(c.Request.Context(), userID) + if err != nil { + writeOrderError(c, err) + return + } + response.OK(c, gin.H{"items": items}) +} + +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(c.Request.Context(), 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(c.Request.Context(), 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(c.Request.Context(), userID, id); err != nil { + writeOrderError(c, err) + return + } + response.OK(c, gin.H{"paid": true}) +}