package app import ( "context" "strconv" "strings" "time" "github.com/gofiber/fiber/v2" "go.uber.org/zap" "github.com/break/junhong_cmp_fiber/internal/middleware" "github.com/break/junhong_cmp_fiber/internal/model" "github.com/break/junhong_cmp_fiber/internal/model/dto" "github.com/break/junhong_cmp_fiber/internal/store/postgres" "github.com/break/junhong_cmp_fiber/pkg/constants" "github.com/break/junhong_cmp_fiber/pkg/errors" "github.com/break/junhong_cmp_fiber/pkg/response" ) type ClientRechargeOrderHandler struct { rechargeOrderStore *postgres.RechargeOrderStore paymentStore *postgres.PaymentStore logger *zap.Logger } func NewClientRechargeOrderHandler( rechargeOrderStore *postgres.RechargeOrderStore, paymentStore *postgres.PaymentStore, logger *zap.Logger, ) *ClientRechargeOrderHandler { return &ClientRechargeOrderHandler{ rechargeOrderStore: rechargeOrderStore, paymentStore: paymentStore, logger: logger, } } func (h *ClientRechargeOrderHandler) ListRechargeOrders(c *fiber.Ctx) error { var req dto.ClientRechargeOrderListRequest if err := c.QueryParser(&req); err != nil { return errors.New(errors.CodeInvalidParam) } if req.Page < 1 { req.Page = 1 } if req.PageSize < 1 { req.PageSize = constants.DefaultPageSize } if req.PageSize > constants.MaxPageSize { req.PageSize = constants.MaxPageSize } customerID, ok := middleware.GetCustomerID(c) if !ok || customerID == 0 { return errors.New(errors.CodeUnauthorized) } skipCtx := context.WithValue(c.UserContext(), constants.ContextKeySubordinateShopIDs, []uint{}) params := &postgres.ListRechargeOrderParams{ Page: req.Page, PageSize: req.PageSize, UserID: &customerID, } if assetType, assetID, ok := middleware.GetCurrentAsset(c); ok { params.ResourceType = &assetType params.ResourceID = &assetID } if req.Status > 0 { params.Status = &req.Status } orders, total, err := h.rechargeOrderStore.List(skipCtx, params) if err != nil { return errors.Wrap(errors.CodeDatabaseError, err, "查询充值订单失败") } items := make([]dto.ClientRechargeOrderListItem, 0, len(orders)) for _, order := range orders { if order == nil { continue } items = append(items, dto.ClientRechargeOrderListItem{ RechargeOrderID: order.ID, RechargeOrderNo: order.RechargeOrderNo, Amount: order.Amount, Status: order.Status, StatusName: getRechargeOrderStatusName(order.Status), AutoPurchaseStatus: order.AutoPurchaseStatus, CreatedAt: order.CreatedAt.Format(time.RFC3339), }) } return response.SuccessWithPagination(c, items, total, req.Page, req.PageSize) } func (h *ClientRechargeOrderHandler) GetRechargeOrderDetail(c *fiber.Ctx) error { idStr := c.Params("id") if idStr == "" { return errors.New(errors.CodeInvalidParam) } id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { return errors.New(errors.CodeInvalidParam) } customerID, ok := middleware.GetCustomerID(c) if !ok || customerID == 0 { return errors.New(errors.CodeUnauthorized) } skipCtx := context.WithValue(c.UserContext(), constants.ContextKeySubordinateShopIDs, []uint{}) order, err := h.rechargeOrderStore.GetByID(skipCtx, uint(id)) if err != nil { if strings.Contains(err.Error(), "record not found") { return errors.New(errors.CodeNotFound, "充值订单不存在") } return errors.Wrap(errors.CodeDatabaseError, err, "查询充值订单失败") } if order.UserID != customerID { return errors.New(errors.CodeForbidden, "无权访问该充值订单") } payments, _ := h.paymentStore.ListByOrderID(skipCtx, order.ID, model.PaymentOrderTypeRecharge) var paymentDetails []dto.ClientRechargeOrderPaymentDetail for _, p := range payments { if p == nil { continue } paymentDetails = append(paymentDetails, dto.ClientRechargeOrderPaymentDetail{ PaymentID: p.ID, PaymentNo: p.PaymentNo, PaymentMethod: p.PaymentMethod, Amount: p.Amount, Status: p.Status, StatusName: getPaymentStatusName(p.Status), ThirdPartyTradeNo: p.ThirdPartyTradeNo, PaidAt: formatTimePtr(p.PaidAt), CreatedAt: p.CreatedAt.Format(time.RFC3339), }) } resp := &dto.ClientRechargeOrderDetail{ RechargeOrderID: order.ID, RechargeOrderNo: order.RechargeOrderNo, Amount: order.Amount, Status: order.Status, StatusName: getRechargeOrderStatusName(order.Status), AutoPurchaseStatus: order.AutoPurchaseStatus, LinkedPackageIDs: order.LinkedPackageIDs, CreatedAt: order.CreatedAt.Format(time.RFC3339), PaidAt: formatTimePtr(order.PaidAt), Payments: paymentDetails, } return response.Success(c, resp) } func getRechargeOrderStatusName(status int) string { switch status { case model.RechargeOrderStatusPending: return "待支付" case model.RechargeOrderStatusPaid: return "已支付" case model.RechargeOrderStatusClosed: return "已关闭" case model.RechargeOrderStatusRefunded: return "已退款" default: return "未知" } } func getPaymentStatusName(status int) string { switch status { case model.PaymentRecordStatusPending: return "待支付" case model.PaymentRecordStatusPaid: return "已支付" case model.PaymentRecordStatusFailed: return "已失败" case model.PaymentRecordStatusRefunded: return "已退款" default: return "未知" } } func formatTimePtr(t *time.Time) string { if t == nil { return "" } return t.Format(time.RFC3339) }