refactor(utils): 修复密码哈希比较逻辑错误 feat(user): 新增按状态筛选优惠券接口 docs: 添加虚拟发货与任务中心相关文档 fix(wechat): 修正Code2Session上下文传递问题 test: 补充订单折扣与积分转换测试用例 build: 更新配置文件与构建脚本 style: 清理多余的空行与注释
83 lines
2.3 KiB
Go
83 lines
2.3 KiB
Go
package user
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
"bindbox-game/internal/repository/mysql/dao"
|
|
"bindbox-game/internal/repository/mysql/model"
|
|
|
|
"gorm.io/gorm/clause"
|
|
)
|
|
|
|
// CancelOrder 取消订单
|
|
func (s *service) CancelOrder(ctx context.Context, userID int64, orderID int64, reason string) (*model.Orders, error) {
|
|
var updatedOrder *model.Orders
|
|
err := s.writeDB.Transaction(func(tx *dao.Query) error {
|
|
// 1. 查询订单
|
|
order, err := tx.Orders.WithContext(ctx).Clauses(clause.Locking{Strength: "UPDATE"}).Where(tx.Orders.ID.Eq(orderID), tx.Orders.UserID.Eq(userID)).First()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if order == nil {
|
|
return errors.New("order not found")
|
|
}
|
|
|
|
// 2. 校验状态
|
|
if order.Status != 1 {
|
|
return errors.New("order cannot be cancelled")
|
|
}
|
|
|
|
// 3. 退还积分
|
|
if order.PointsAmount > 0 {
|
|
refundReason := "cancel_order"
|
|
if reason != "" {
|
|
refundReason = refundReason + ":" + reason
|
|
}
|
|
|
|
// Get Rate
|
|
ratePtsPerCent, _ := s.CentsToPoints(ctx, 1)
|
|
if ratePtsPerCent <= 0 {
|
|
ratePtsPerCent = 1
|
|
}
|
|
pointsToRefund := order.PointsAmount * ratePtsPerCent
|
|
|
|
// Update User Points
|
|
existing, _ := tx.UserPoints.WithContext(ctx).Clauses(clause.Locking{Strength: "UPDATE"}).Where(tx.UserPoints.UserID.Eq(userID)).First()
|
|
if existing == nil {
|
|
if err := tx.UserPoints.WithContext(ctx).Omit(tx.UserPoints.ValidEnd).Create(&model.UserPoints{UserID: userID, Points: pointsToRefund}); err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
if _, err := tx.UserPoints.WithContext(ctx).Where(tx.UserPoints.ID.Eq(existing.ID)).Updates(map[string]any{"points": existing.Points + pointsToRefund}); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
// Log
|
|
led := &model.UserPointsLedger{UserID: userID, Action: "refund_points", Points: pointsToRefund, RefTable: "orders", RefID: order.OrderNo, Remark: refundReason}
|
|
if err := tx.UserPointsLedger.WithContext(ctx).Create(led); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// 4. 更新订单状态
|
|
updates := map[string]any{
|
|
tx.Orders.Status.ColumnName().String(): 3,
|
|
tx.Orders.CancelledAt.ColumnName().String(): time.Now(),
|
|
}
|
|
if _, err := tx.Orders.WithContext(ctx).Where(tx.Orders.ID.Eq(order.ID)).Updates(updates); err != nil {
|
|
return err
|
|
}
|
|
|
|
updatedOrder = order
|
|
updatedOrder.Status = 3
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return updatedOrder, nil
|
|
}
|