package service import ( "context" "strings" "git.lzcwy.cn/zhengchiliu/zt-closet-manage-backend/global" "git.lzcwy.cn/zhengchiliu/zt-closet-manage-backend/internal/dto" "git.lzcwy.cn/zhengchiliu/zt-closet-manage-backend/internal/mysqldao" "git.lzcwy.cn/zhengchiliu/zt-closet-manage-backend/internal/mysqlmodel" "git.lzcwy.cn/zhengchiliu/zt-closet-manage-backend/pkg/errcode" ) // OrderService 订单与退款管理服务。 type OrderService struct { orderDao *mysqldao.OrderDao refundDao *mysqldao.RefundDao } // NewOrderService 创建订单服务。 func NewOrderService() *OrderService { return &OrderService{ orderDao: mysqldao.NewOrderDao(), refundDao: mysqldao.NewRefundDao(), } } // List 分页查询订单。 func (s *OrderService) List(ctx context.Context, request *dto.OrderListRequest) (*dto.OrderListResponse, *errcode.Error) { ctx, span := global.Tracer.Start(ctx, "svc.AdminOrderList") defer span.End() page, pageSize := normalizePage(request.Page, request.PageSize) list, total, err := s.orderDao.OrderList(ctx, mysqldao.OrderListParams{ OrderNo: strings.TrimSpace(request.OrderNo), UserID: request.UserID, Status: request.Status, Page: page, Size: pageSize, }) if err != nil { return nil, errcode.DatabaseError } items := make([]dto.OrderItem, 0, len(list)) for i := range list { items = append(items, buildOrderItem(&list[i])) } return &dto.OrderListResponse{ PageResponse: dto.PageResponse{Total: total, Page: page, PageSize: pageSize}, List: items, }, nil } // Get 订单详情。 func (s *OrderService) Get(ctx context.Context, orderNo string) (*dto.OrderItem, *errcode.Error) { ctx, span := global.Tracer.Start(ctx, "svc.AdminOrderGet") defer span.End() order, err := s.orderDao.OrderGetByOrderNo(ctx, orderNo) if err != nil { if isNotFound(err) { return nil, errcode.OrderNotFound } return nil, errcode.DatabaseError } item := buildOrderItem(order) return &item, nil } // RefundList 分页查询退款单。 func (s *OrderService) RefundList(ctx context.Context, request *dto.RefundListRequest) (*dto.RefundListResponse, *errcode.Error) { ctx, span := global.Tracer.Start(ctx, "svc.AdminRefundList") defer span.End() page, pageSize := normalizePage(request.Page, request.PageSize) // status 未传时 query 绑定为 nil,与「待处理=0」天然区分。 withStatus := request.Status != nil var status int8 if withStatus { status = *request.Status } list, total, err := s.refundDao.RefundList(ctx, mysqldao.RefundListParams{ Status: status, WithStatus: withStatus, OrderNo: strings.TrimSpace(request.OrderNo), Page: page, Size: pageSize, }) if err != nil { return nil, errcode.DatabaseError } items := make([]dto.RefundItem, 0, len(list)) for i := range list { items = append(items, buildRefundItem(&list[i])) } return &dto.RefundListResponse{ PageResponse: dto.PageResponse{Total: total, Page: page, PageSize: pageSize}, List: items, }, nil } // RefundApprove 审核通过:待处理(0) → 退款中(1)。 // 实际打款由运营在微信商户平台人工完成,业务服务退款回调负责后续「成功(2)」流转与权益回收。 func (s *OrderService) RefundApprove(ctx context.Context, adminID int64, refundNo string, request *dto.RefundAuditRequest) *errcode.Error { ctx, span := global.Tracer.Start(ctx, "svc.AdminRefundApprove") defer span.End() if _, err := s.refundDao.RefundGetByRefundNo(ctx, refundNo); err != nil { if isNotFound(err) { return errcode.RefundNotFound } return errcode.DatabaseError } ok, err := s.refundDao.RefundTransition(ctx, refundNo, RefundStatusPending, RefundStatusProcessing, "") if err != nil { return errcode.DatabaseError } if !ok { return errcode.RefundStatusInvalid.WithDetails("仅待处理状态的退款单可审核") } return nil } // RefundReject 审核驳回:待处理(0) → 失败(3),记录驳回原因。 func (s *OrderService) RefundReject(ctx context.Context, adminID int64, refundNo string, request *dto.RefundAuditRequest) *errcode.Error { ctx, span := global.Tracer.Start(ctx, "svc.AdminRefundReject") defer span.End() if _, err := s.refundDao.RefundGetByRefundNo(ctx, refundNo); err != nil { if isNotFound(err) { return errcode.RefundNotFound } return errcode.DatabaseError } ok, err := s.refundDao.RefundTransition(ctx, refundNo, RefundStatusPending, RefundStatusFailed, strings.TrimSpace(request.Reason)) if err != nil { return errcode.DatabaseError } if !ok { return errcode.RefundStatusInvalid.WithDetails("仅待处理状态的退款单可审核") } return nil } // buildOrderItem 订单模型 → 响应。 func buildOrderItem(o *mysqlmodel.Order) dto.OrderItem { return dto.OrderItem{ OrderNo: o.OrderNo, UserID: o.UserID, GoodsID: o.GoodsID, GoodsName: o.GoodsName, UnitPrice: o.UnitPrice, TotalAmount: o.TotalAmount, PayAmount: o.PayAmount, PayChannel: o.PayChannel, OrderStatus: o.OrderStatus, TransactionID: o.TransactionID, MemberDays: o.MemberDays, UploadQuota: o.CosQuota, AIRecommendQuota: o.AIRecommendQuota, ClosetShareQuota: o.ClosetShareQuota, OutfitShareQuota: o.OutfitShareQuota, ExpireTime: o.ExpireTime, PayTime: o.PayTime, RefundTime: o.RefundTime, RefundAmount: o.RefundAmount, Remark: o.Remark, XPayProductID: o.XPayProductID, XPayPlatform: o.XPayPlatform, XPayEnv: o.XPayEnv, CreatedAt: o.CreatedAt, } } // buildRefundItem 退款单模型 → 响应。 func buildRefundItem(r *mysqlmodel.RefundFlowLog) dto.RefundItem { return dto.RefundItem{ RefundNo: r.RefundNo, OrderNo: r.OrderNo, UserID: r.UserID, RefundAmount: r.RefundAmount, RefundReason: r.RefundReason, Status: r.Status, ApplyTime: r.ApplyTime, SuccessTime: r.SuccessTime, FailReason: r.FailReason, CreatedAt: r.CreatedAt, } }