bindbox-game/internal/service/user/order_coupons.go
邹方成 45815bfb7d chore: 清理无用文件与优化代码结构
refactor(utils): 修复密码哈希比较逻辑错误
feat(user): 新增按状态筛选优惠券接口
docs: 添加虚拟发货与任务中心相关文档
fix(wechat): 修正Code2Session上下文传递问题
test: 补充订单折扣与积分转换测试用例
build: 更新配置文件与构建脚本
style: 清理多余的空行与注释
2025-12-18 17:35:55 +08:00

76 lines
3.1 KiB
Go

package user
import (
"context"
"time"
"bindbox-game/internal/repository/mysql/model"
)
// RecordOrderCouponUsage 记录订单使用的用户券与本次抵扣金额
func (s *service) RecordOrderCouponUsage(ctx context.Context, orderID int64, userCouponID int64, appliedAmount int64) error {
if orderID <= 0 || userCouponID <= 0 || appliedAmount <= 0 {
return nil
}
return s.repo.GetDbW().Exec("INSERT INTO order_coupons (order_id, user_coupon_id, applied_amount, created_at) VALUES (?,?,?,NOW(3))", orderID, userCouponID, appliedAmount).Error
}
// DeductCouponsForPaidOrder 支付成功后扣减金额券余额或核销一次性券
func (s *service) DeductCouponsForPaidOrder(ctx context.Context, userID int64, orderID int64, paidAt time.Time) error {
type row struct {
UserCouponID int64
AppliedAmount int64
Status int32
UsedOrderID int64
DiscountType int32
}
var rows []row
// 若结构表不存在或无数据,不报错(由调用方做降级处理)
_ = s.repo.GetDbR().Raw("SELECT oc.user_coupon_id AS user_coupon_id, oc.applied_amount AS applied_amount, uc.status AS status, uc.used_order_id AS used_order_id, sc.discount_type AS discount_type FROM order_coupons oc JOIN user_coupons uc ON uc.id=oc.user_coupon_id JOIN system_coupons sc ON sc.id=uc.coupon_id WHERE oc.order_id=?", orderID).Scan(&rows).Error
for _, r := range rows {
// 幂等:已核销且绑定本订单,跳过
if r.Status == 2 && r.UsedOrderID == orderID {
continue
}
if r.DiscountType == 1 { // 金额券
var bal int64
_ = s.repo.GetDbR().Raw("SELECT COALESCE(balance_amount,0) FROM user_coupons WHERE id=?", r.UserCouponID).Scan(&bal).Error
nb := bal - r.AppliedAmount
if nb < 0 {
nb = 0
}
if nb == 0 {
_ = s.repo.GetDbW().Exec("UPDATE user_coupons SET balance_amount=?, status=2, used_order_id=?, used_at=? WHERE id=?", nb, orderID, paidAt, r.UserCouponID).Error
} else {
_ = s.repo.GetDbW().Exec("UPDATE user_coupons SET balance_amount=?, used_order_id=?, used_at=? WHERE id=?", nb, orderID, paidAt, r.UserCouponID).Error
}
var uid int64
_ = s.repo.GetDbR().Raw("SELECT user_id FROM user_coupons WHERE id=?", r.UserCouponID).Scan(&uid).Error
ledger := &model.UserCouponLedger{
UserID: uid,
UserCouponID: r.UserCouponID,
ChangeAmount: -r.AppliedAmount,
BalanceAfter: nb,
OrderID: orderID,
Action: "apply",
CreatedAt: time.Now(),
}
_ = s.repo.GetDbW().Create(ledger).Error
} else { // 满减/折扣券:一次性核销
_ = s.repo.GetDbW().Exec("UPDATE user_coupons SET status=2, used_order_id=?, used_at=? WHERE id=?", orderID, paidAt, r.UserCouponID).Error
var uid int64
_ = s.repo.GetDbR().Raw("SELECT user_id FROM user_coupons WHERE id=?", r.UserCouponID).Scan(&uid).Error
ledger := &model.UserCouponLedger{
UserID: uid,
UserCouponID: r.UserCouponID,
ChangeAmount: -r.AppliedAmount,
BalanceAfter: 0,
OrderID: orderID,
Action: "apply",
CreatedAt: time.Now(),
}
_ = s.repo.GetDbW().Create(ledger).Error
}
}
return nil
}