first commit
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
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,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user