修正了取消订单等操作
This commit is contained in:
parent
6137740b13
commit
c235e1f293
@ -96,6 +96,19 @@ func (b *OrderMember) GetOrderMember(c *gin.Context) {
|
|||||||
|
|
||||||
// PutCancelOrderMember 取消会员订单
|
// PutCancelOrderMember 取消会员订单
|
||||||
func (b *OrderMember) PutCancelOrderMember(c *gin.Context) {
|
func (b *OrderMember) PutCancelOrderMember(c *gin.Context) {
|
||||||
|
orderMemberRequest := requests.OrderMemberRequest{}
|
||||||
|
req := orderMemberRequest.CancelOrderMember
|
||||||
|
if err := c.ShouldBind(&req); err != nil {
|
||||||
|
responses.FailWithMessage(err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 参数验证
|
||||||
|
if err := global.Validate.Struct(req); err != nil {
|
||||||
|
responses.FailWithMessage(utils.Translate(err), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
id := c.Param("order_id")
|
id := c.Param("order_id")
|
||||||
if id == "" {
|
if id == "" {
|
||||||
responses.FailWithMessage("缺少参数", c)
|
responses.FailWithMessage("缺少参数", c)
|
||||||
@ -127,7 +140,7 @@ func (b *OrderMember) PutCancelOrderMember(c *gin.Context) {
|
|||||||
|
|
||||||
// 取消单项订单
|
// 取消单项订单
|
||||||
orderMemberService := service.OrderMemberService{}
|
orderMemberService := service.OrderMemberService{}
|
||||||
res, err := orderMemberService.CancelOrderMember(tx, orderMember.UserId, orderId, 2)
|
res, err := orderMemberService.CancelOrderMember(tx, orderMember, req.RefundAmount, 2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
responses.FailWithMessage(err.Error(), c)
|
responses.FailWithMessage(err.Error(), c)
|
||||||
|
|||||||
@ -68,6 +68,19 @@ func (b *OrderSingle) GetOrderSinglePage(c *gin.Context) {
|
|||||||
|
|
||||||
// PutCancelOrderSingle 取消单项订单
|
// PutCancelOrderSingle 取消单项订单
|
||||||
func (b *OrderSingle) PutCancelOrderSingle(c *gin.Context) {
|
func (b *OrderSingle) PutCancelOrderSingle(c *gin.Context) {
|
||||||
|
orderSingleRequest := requests.OrderSingleRequest{}
|
||||||
|
req := orderSingleRequest.CancelOrderSingle
|
||||||
|
if err := c.ShouldBind(&req); err != nil {
|
||||||
|
responses.FailWithMessage(err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 参数验证
|
||||||
|
if err := global.Validate.Struct(req); err != nil {
|
||||||
|
responses.FailWithMessage(utils.Translate(err), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
id := c.Param("order_id")
|
id := c.Param("order_id")
|
||||||
if id == "" {
|
if id == "" {
|
||||||
responses.FailWithMessage("缺少参数", c)
|
responses.FailWithMessage("缺少参数", c)
|
||||||
@ -83,9 +96,7 @@ func (b *OrderSingle) PutCancelOrderSingle(c *gin.Context) {
|
|||||||
|
|
||||||
// 获取订单数据
|
// 获取订单数据
|
||||||
orderSingleDao := dao.OrderSingleDao{}
|
orderSingleDao := dao.OrderSingleDao{}
|
||||||
maps := make(map[string]interface{})
|
orderSingle, err := orderSingleDao.GetOrderSingleById(orderId)
|
||||||
maps["order_id"] = orderId
|
|
||||||
orderSingle, err := orderSingleDao.GetOrderSingle(maps)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
responses.FailWithMessage("订单异常", c)
|
responses.FailWithMessage("订单异常", c)
|
||||||
return
|
return
|
||||||
@ -101,7 +112,7 @@ func (b *OrderSingle) PutCancelOrderSingle(c *gin.Context) {
|
|||||||
|
|
||||||
// 取消单项订单
|
// 取消单项订单
|
||||||
orderSingleService := service.OrderSingleService{}
|
orderSingleService := service.OrderSingleService{}
|
||||||
res, err := orderSingleService.CancelOrderSingle(tx, orderSingle.UserId, orderId, 2)
|
res, err := orderSingleService.CancelOrderSingle(tx, orderSingle, req.RefundAmount, 2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
responses.FailWithMessage(err.Error(), c)
|
responses.FailWithMessage(err.Error(), c)
|
||||||
|
|||||||
@ -45,6 +45,15 @@ func (r *OrderMemberCouponDao) DeleteOrderMemberCouponById(tx *gorm.DB, OrderMem
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetOrderMemberCouponListByOrderId 获取列表-订单id
|
||||||
|
func (r *OrderMemberCouponDao) GetOrderMemberCouponListByOrderId(orderId int64) (m []*model.OrderMemberCoupon, err error) {
|
||||||
|
err = global.Db.Where("order_id = ?", orderId).Find(&m).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
// EditOrderMemberCoupon 修改
|
// EditOrderMemberCoupon 修改
|
||||||
func (r *OrderMemberCouponDao) EditOrderMemberCoupon(tx *gorm.DB, maps interface{}, data interface{}) error {
|
func (r *OrderMemberCouponDao) EditOrderMemberCoupon(tx *gorm.DB, maps interface{}, data interface{}) error {
|
||||||
err := tx.Model(&model.OrderMemberCoupon{}).Where(maps).Updates(data).Error
|
err := tx.Model(&model.OrderMemberCoupon{}).Where(maps).Updates(data).Error
|
||||||
|
|||||||
@ -37,6 +37,15 @@ func (r *OrderSingleCouponDao) GetOrderSingleCouponByOrderId(orderId int64) (m *
|
|||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetOrderSingleCouponListByOrderId 获取列表-订单id
|
||||||
|
func (r *OrderSingleCouponDao) GetOrderSingleCouponListByOrderId(orderId int64) (m []*model.OrderSingleCoupon, err error) {
|
||||||
|
err = global.Db.Where("order_id = ?", orderId).Find(&m).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
// DeleteOrderSingleCoupon 删除
|
// DeleteOrderSingleCoupon 删除
|
||||||
func (r *OrderSingleCouponDao) DeleteOrderSingleCoupon(tx *gorm.DB, maps interface{}) error {
|
func (r *OrderSingleCouponDao) DeleteOrderSingleCoupon(tx *gorm.DB, maps interface{}) error {
|
||||||
err := tx.Where(maps).Delete(&model.OrderSingleCoupon{}).Error
|
err := tx.Where(maps).Delete(&model.OrderSingleCoupon{}).Error
|
||||||
|
|||||||
@ -37,6 +37,13 @@ type OrderSingleDto struct {
|
|||||||
MemberExpireDate *model.LocalTime `json:"member_expire_date"` // 用户会员到期时间(非会员时为null)
|
MemberExpireDate *model.LocalTime `json:"member_expire_date"` // 用户会员到期时间(非会员时为null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OrderRefundDto 订单退款
|
||||||
|
type OrderRefundDto struct {
|
||||||
|
RefundStatus int `json:"refund_status"` // 订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常 7:部分退款)
|
||||||
|
SuccessTime string `json:"success_time"` // 退款成功时间
|
||||||
|
RefundId string `json:"refund_id"` // 系统退款编号
|
||||||
|
}
|
||||||
|
|
||||||
// GetOrderSingleListDto 列表
|
// GetOrderSingleListDto 列表
|
||||||
func GetOrderSingleListDto(m []*model.OrderSingle) []*OrderSingleDto {
|
func GetOrderSingleListDto(m []*model.OrderSingle) []*OrderSingleDto {
|
||||||
// 处理返回值
|
// 处理返回值
|
||||||
|
|||||||
@ -17,7 +17,7 @@ type OrderMemberRefund struct {
|
|||||||
RefundStatus int `gorm:"column:refund_status;type:tinyint(1);default:0;comment:订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常 7:部分退款)" json:"refund_status"`
|
RefundStatus int `gorm:"column:refund_status;type:tinyint(1);default:0;comment:订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常 7:部分退款)" json:"refund_status"`
|
||||||
RefundTotal float64 `gorm:"column:refund_total;type:decimal(10,2) unsigned;default:0.00;comment:退款金额" json:"refund_total"`
|
RefundTotal float64 `gorm:"column:refund_total;type:decimal(10,2) unsigned;default:0.00;comment:退款金额" json:"refund_total"`
|
||||||
RefundReason string `gorm:"column:refund_reason;type:varchar(255);comment:退款原因" json:"refund_reason"`
|
RefundReason string `gorm:"column:refund_reason;type:varchar(255);comment:退款原因" json:"refund_reason"`
|
||||||
SuccessTime LocalTime `gorm:"column:success_time;type:datetime;comment:退款成功时间" json:"success_time"`
|
SuccessTime *LocalTime `gorm:"column:success_time;type:datetime;comment:退款成功时间" json:"success_time"`
|
||||||
Model
|
Model
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ type OrderSingleRefund struct {
|
|||||||
RefundStatus int `gorm:"column:refund_status;type:tinyint(1);default:0;comment:订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常 7:部分退款)" json:"refund_status"`
|
RefundStatus int `gorm:"column:refund_status;type:tinyint(1);default:0;comment:订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常 7:部分退款)" json:"refund_status"`
|
||||||
RefundTotal float64 `gorm:"column:refund_total;type:decimal(10,2) unsigned;default:0.00;comment:退款金额" json:"refund_total"`
|
RefundTotal float64 `gorm:"column:refund_total;type:decimal(10,2) unsigned;default:0.00;comment:退款金额" json:"refund_total"`
|
||||||
RefundReason string `gorm:"column:refund_reason;type:varchar(255);comment:退款原因" json:"refund_reason"`
|
RefundReason string `gorm:"column:refund_reason;type:varchar(255);comment:退款原因" json:"refund_reason"`
|
||||||
SuccessTime LocalTime `gorm:"column:success_time;type:datetime;comment:退款成功时间" json:"success_time"`
|
SuccessTime *LocalTime `gorm:"column:success_time;type:datetime;comment:退款成功时间" json:"success_time"`
|
||||||
Model
|
Model
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package requests
|
|||||||
type OrderMemberRequest struct {
|
type OrderMemberRequest struct {
|
||||||
GetOrderMemberPage // 获取会员订单列表-分页
|
GetOrderMemberPage // 获取会员订单列表-分页
|
||||||
PutOrderMemberDeleteStatus // 操作会员订单删除状态
|
PutOrderMemberDeleteStatus // 操作会员订单删除状态
|
||||||
|
CancelOrderMember // 取消会员订单
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOrderMemberPage 获取会员订单列表-分页
|
// GetOrderMemberPage 获取会员订单列表-分页
|
||||||
@ -26,3 +27,8 @@ type GetOrderMemberPage struct {
|
|||||||
type PutOrderMemberDeleteStatus struct {
|
type PutOrderMemberDeleteStatus struct {
|
||||||
IsDelete int `json:"is_delete" form:"is_delete" label:"删除状态"` // 用户删除状态(0:否 1:是)
|
IsDelete int `json:"is_delete" form:"is_delete" label:"删除状态"` // 用户删除状态(0:否 1:是)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CancelOrderMember 取消会员订单
|
||||||
|
type CancelOrderMember struct {
|
||||||
|
RefundAmount *float64 `json:"refund_amount" form:"refund_amount" label:"退款金额"`
|
||||||
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package requests
|
|||||||
type OrderSingleRequest struct {
|
type OrderSingleRequest struct {
|
||||||
GetOrderSinglePage // 获取单项订单列表-分页
|
GetOrderSinglePage // 获取单项订单列表-分页
|
||||||
PutOrderSingleDeleteStatus // 操作单项订单删除状态
|
PutOrderSingleDeleteStatus // 操作单项订单删除状态
|
||||||
|
CancelOrderSingle // 取消单项订单
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOrderSinglePage 获取单项订单列表-分页
|
// GetOrderSinglePage 获取单项订单列表-分页
|
||||||
@ -26,3 +27,8 @@ type GetOrderSinglePage struct {
|
|||||||
type PutOrderSingleDeleteStatus struct {
|
type PutOrderSingleDeleteStatus struct {
|
||||||
IsDelete int `json:"is_delete" form:"is_delete" label:"删除状态"` // 用户删除状态(0:否 1:是)
|
IsDelete int `json:"is_delete" form:"is_delete" label:"删除状态"` // 用户删除状态(0:否 1:是)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CancelOrderSingle 取消单项订单
|
||||||
|
type CancelOrderSingle struct {
|
||||||
|
RefundAmount *float64 `json:"refund_amount" form:"refund_amount" label:"退款金额"`
|
||||||
|
}
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import (
|
|||||||
"hepa-calc-admin-api/extend/weChat"
|
"hepa-calc-admin-api/extend/weChat"
|
||||||
"hepa-calc-admin-api/global"
|
"hepa-calc-admin-api/global"
|
||||||
"hepa-calc-admin-api/utils"
|
"hepa-calc-admin-api/utils"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -21,9 +22,9 @@ type OrderMemberService struct {
|
|||||||
|
|
||||||
// CancelOrderMember 取消会员订单
|
// CancelOrderMember 取消会员订单
|
||||||
// cancelReason:订单取消原因(1:主动取消 2:后台取消 3:支付超时取消)
|
// cancelReason:订单取消原因(1:主动取消 2:后台取消 3:支付超时取消)
|
||||||
func (r *OrderMemberService) CancelOrderMember(tx *gorm.DB, userId, orderId int64, cancelReason int) (bool, error) {
|
func (r *OrderMemberService) CancelOrderMember(tx *gorm.DB, orderMember *model.OrderMember, refundAmount *float64, cancelReason int) (bool, error) {
|
||||||
// 检测多次请求
|
// 检测多次请求
|
||||||
redisKey := "CancelOrderMember" + fmt.Sprintf("%d", userId) + fmt.Sprintf("%d", orderId)
|
redisKey := "CancelOrderMember" + fmt.Sprintf("%d", orderMember.UserId) + fmt.Sprintf("%d", orderMember.OrderId)
|
||||||
res, _ := global.Redis.Get(context.Background(), redisKey).Result()
|
res, _ := global.Redis.Get(context.Background(), redisKey).Result()
|
||||||
if res != "" {
|
if res != "" {
|
||||||
return false, errors.New("请勿重复操作")
|
return false, errors.New("请勿重复操作")
|
||||||
@ -39,15 +40,6 @@ func (r *OrderMemberService) CancelOrderMember(tx *gorm.DB, userId, orderId int6
|
|||||||
return false, errors.New("取消订单失败")
|
return false, errors.New("取消订单失败")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取订单数据
|
|
||||||
orderMemberDao := dao.OrderMemberDao{}
|
|
||||||
maps := make(map[string]interface{})
|
|
||||||
maps["order_id"] = orderId
|
|
||||||
orderMember, err := orderMemberDao.GetOrderMember(maps)
|
|
||||||
if err != nil {
|
|
||||||
return false, errors.New("订单异常")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 订单状态(1:待支付 2:已完成 3:已取消)
|
// 订单状态(1:待支付 2:已完成 3:已取消)
|
||||||
if orderMember.OrderStatus == 2 {
|
if orderMember.OrderStatus == 2 {
|
||||||
return false, errors.New("订单已完成,无法取消")
|
return false, errors.New("订单已完成,无法取消")
|
||||||
@ -95,7 +87,9 @@ func (r *OrderMemberService) CancelOrderMember(tx *gorm.DB, userId, orderId int6
|
|||||||
orderMemberData["cancel_time"] = time.Now().Format("2006-01-02 15:04:05")
|
orderMemberData["cancel_time"] = time.Now().Format("2006-01-02 15:04:05")
|
||||||
orderMemberData["cancel_remarks"] = utils.OrderCancelReasonToString(cancelReason)
|
orderMemberData["cancel_remarks"] = utils.OrderCancelReasonToString(cancelReason)
|
||||||
orderMemberData["updated_at"] = time.Now().Format("2006-01-02 15:04:05")
|
orderMemberData["updated_at"] = time.Now().Format("2006-01-02 15:04:05")
|
||||||
err = orderMemberDao.EditOrderMemberById(tx, orderId, orderMemberData)
|
|
||||||
|
orderMemberDao := dao.OrderMemberDao{}
|
||||||
|
err = orderMemberDao.EditOrderMemberById(tx, orderMember.OrderId, orderMemberData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, errors.New("订单取消失败")
|
return false, errors.New("订单取消失败")
|
||||||
}
|
}
|
||||||
@ -104,7 +98,7 @@ func (r *OrderMemberService) CancelOrderMember(tx *gorm.DB, userId, orderId int6
|
|||||||
if orderMember.CouponAmountTotal != 0 {
|
if orderMember.CouponAmountTotal != 0 {
|
||||||
// 获取订单优惠卷数据
|
// 获取订单优惠卷数据
|
||||||
orderMemberCouponDao := dao.OrderMemberCouponDao{}
|
orderMemberCouponDao := dao.OrderMemberCouponDao{}
|
||||||
orderMemberCoupon, err := orderMemberCouponDao.GetOrderMemberCouponByOrderId(orderId)
|
orderMemberCoupon, err := orderMemberCouponDao.GetOrderMemberCouponByOrderId(orderMember.OrderId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return false, errors.New("订单取消失败")
|
return false, errors.New("订单取消失败")
|
||||||
@ -114,6 +108,20 @@ func (r *OrderMemberService) CancelOrderMember(tx *gorm.DB, userId, orderId int6
|
|||||||
userCouponService.ReturnUserCoupon(tx, orderMemberCoupon.UserCouponId)
|
userCouponService.ReturnUserCoupon(tx, orderMemberCoupon.UserCouponId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 退还订单优惠卷
|
||||||
|
err = r.OrderCouponRefund(tx, orderMember)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 订单退款
|
||||||
|
_, err = r.OrderRefund(tx, orderMember, refundAmount, utils.OrderCancelReasonToString(cancelReason))
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,3 +191,126 @@ func (r *OrderMemberService) GetAppPrepay(m *model.OrderMember) (prepay *app.Pre
|
|||||||
|
|
||||||
return prepay, nil
|
return prepay, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OrderRefund 订单退款
|
||||||
|
func (r *OrderMemberService) OrderRefund(tx *gorm.DB, order *model.OrderMember, refundAmount *float64, refundReason string) (*model.OrderMemberRefund, error) {
|
||||||
|
var refundStatus int
|
||||||
|
var successTime time.Time
|
||||||
|
var refundId string
|
||||||
|
|
||||||
|
// 判断订单支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款)
|
||||||
|
if order.PayStatus != 2 {
|
||||||
|
// 非已支付,无需退款
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测退款金额
|
||||||
|
if *refundAmount > order.PaymentAmountTotal {
|
||||||
|
return nil, errors.New("退款金额不可超过实付金额")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 退款编号
|
||||||
|
refundNo := strconv.FormatInt(global.Snowflake.Generate().Int64(), 10)
|
||||||
|
|
||||||
|
// 退款金额为0
|
||||||
|
if *refundAmount <= 0 {
|
||||||
|
// 支付金额为0,模拟退款
|
||||||
|
refundId = "模拟退款:" + strconv.FormatInt(global.Snowflake.Generate().Int64(), 10)
|
||||||
|
refundStatus = 3
|
||||||
|
successTime = time.Now()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 退款金额大于0
|
||||||
|
if *refundAmount > 0 {
|
||||||
|
refundRequest := weChat.RefundRequest{
|
||||||
|
TransactionId: order.EscrowTradeNo,
|
||||||
|
OutTradeNo: order.OrderNo,
|
||||||
|
OutRefundNo: refundNo,
|
||||||
|
Reason: refundReason,
|
||||||
|
RefundAmount: int64(*refundAmount * 100),
|
||||||
|
PaymentAmountTotal: int64(order.PaymentAmountTotal * 100),
|
||||||
|
NotifyUrl: config.C.Wechat.RefundNotifyDomain + config.C.Wechat.RefundNotifyUrl,
|
||||||
|
}
|
||||||
|
|
||||||
|
refund, err := refundRequest.Refund()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if refund.Status == nil {
|
||||||
|
return nil, errors.New("退款状态错误")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理订单状态
|
||||||
|
switch *refund.Status {
|
||||||
|
case "SUCCESS": // 退款成功
|
||||||
|
refundStatus = 3
|
||||||
|
if refund.SuccessTime != nil {
|
||||||
|
successTime = *refund.SuccessTime
|
||||||
|
}
|
||||||
|
case "CLOSED": // 退款关闭
|
||||||
|
|
||||||
|
refundStatus = 5
|
||||||
|
case "PROCESSING": // 退款处理中
|
||||||
|
refundStatus = 2
|
||||||
|
case "ABNORMAL": // 退款异常
|
||||||
|
return nil, errors.New("退款状态错误")
|
||||||
|
default:
|
||||||
|
return nil, errors.New("退款状态错误")
|
||||||
|
}
|
||||||
|
|
||||||
|
if refund.RefundId == nil {
|
||||||
|
return nil, errors.New("缺少退款订单编号")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 退款编号
|
||||||
|
refundId = *refund.RefundId
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增退款表
|
||||||
|
orderRefund := &model.OrderMemberRefund{
|
||||||
|
UserId: order.UserId,
|
||||||
|
OrderId: order.OrderId,
|
||||||
|
OrderNo: order.OrderNo,
|
||||||
|
RefundNo: refundNo,
|
||||||
|
RefundId: refundId,
|
||||||
|
RefundStatus: refundStatus,
|
||||||
|
RefundTotal: *refundAmount,
|
||||||
|
RefundReason: refundReason,
|
||||||
|
}
|
||||||
|
|
||||||
|
if refundStatus == 3 && !successTime.IsZero() {
|
||||||
|
t := model.LocalTime(successTime)
|
||||||
|
orderRefund.SuccessTime = &t
|
||||||
|
}
|
||||||
|
|
||||||
|
orderMemberRefundDao := dao.OrderMemberRefundDao{}
|
||||||
|
orderMemberRefund, err := orderMemberRefundDao.AddOrderMemberRefund(tx, orderRefund)
|
||||||
|
if err != nil || orderMemberRefund == nil {
|
||||||
|
return nil, errors.New(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return orderMemberRefund, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrderCouponRefund 订单优惠卷退还
|
||||||
|
func (r *OrderMemberService) OrderCouponRefund(tx *gorm.DB, order *model.OrderMember) error {
|
||||||
|
// 订单优惠金额为0,无需退还优惠卷
|
||||||
|
if order.CouponAmountTotal == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取订单优惠卷数据
|
||||||
|
orderMemberCouponDao := dao.OrderMemberCouponDao{}
|
||||||
|
orderMemberCoupons, err := orderMemberCouponDao.GetOrderMemberCouponListByOrderId(order.OrderId)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("优惠卷数据错误")
|
||||||
|
}
|
||||||
|
|
||||||
|
userCouponService := &UserCouponService{}
|
||||||
|
for _, coupon := range orderMemberCoupons {
|
||||||
|
_ = userCouponService.ReturnUserCoupon(tx, coupon.UserCouponId)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import (
|
|||||||
"hepa-calc-admin-api/extend/weChat"
|
"hepa-calc-admin-api/extend/weChat"
|
||||||
"hepa-calc-admin-api/global"
|
"hepa-calc-admin-api/global"
|
||||||
"hepa-calc-admin-api/utils"
|
"hepa-calc-admin-api/utils"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -21,9 +22,9 @@ type OrderSingleService struct {
|
|||||||
|
|
||||||
// CancelOrderSingle 取消单项订单
|
// CancelOrderSingle 取消单项订单
|
||||||
// cancelReason:订单取消原因(1:主动取消 2:后台取消 3:支付超时取消)
|
// cancelReason:订单取消原因(1:主动取消 2:后台取消 3:支付超时取消)
|
||||||
func (r *OrderSingleService) CancelOrderSingle(tx *gorm.DB, userId, orderId int64, cancelReason int) (bool, error) {
|
func (r *OrderSingleService) CancelOrderSingle(tx *gorm.DB, orderSingle *model.OrderSingle, refundAmount *float64, cancelReason int) (bool, error) {
|
||||||
// 检测多次请求
|
// 检测多次请求
|
||||||
redisKey := "CancelOrderSingle" + fmt.Sprintf("%d", userId) + fmt.Sprintf("%d", orderId)
|
redisKey := "CancelOrderSingle" + fmt.Sprintf("%d", orderSingle.UserId) + fmt.Sprintf("%d", orderSingle.OrderId)
|
||||||
res, _ := global.Redis.Get(context.Background(), redisKey).Result()
|
res, _ := global.Redis.Get(context.Background(), redisKey).Result()
|
||||||
if res != "" {
|
if res != "" {
|
||||||
return false, errors.New("请勿重复操作")
|
return false, errors.New("请勿重复操作")
|
||||||
@ -39,15 +40,6 @@ func (r *OrderSingleService) CancelOrderSingle(tx *gorm.DB, userId, orderId int6
|
|||||||
return false, errors.New("取消订单失败")
|
return false, errors.New("取消订单失败")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取订单数据
|
|
||||||
orderSingleDao := dao.OrderSingleDao{}
|
|
||||||
maps := make(map[string]interface{})
|
|
||||||
maps["order_id"] = orderId
|
|
||||||
orderSingle, err := orderSingleDao.GetOrderSingle(maps)
|
|
||||||
if err != nil {
|
|
||||||
return false, errors.New("订单异常")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 订单状态(1:待支付 2:已完成 3:已取消)
|
// 订单状态(1:待支付 2:已完成 3:已取消)
|
||||||
if orderSingle.OrderStatus == 2 {
|
if orderSingle.OrderStatus == 2 {
|
||||||
return false, errors.New("订单已完成,无法取消")
|
return false, errors.New("订单已完成,无法取消")
|
||||||
@ -95,23 +87,25 @@ func (r *OrderSingleService) CancelOrderSingle(tx *gorm.DB, userId, orderId int6
|
|||||||
orderSingleData["cancel_time"] = time.Now().Format("2006-01-02 15:04:05")
|
orderSingleData["cancel_time"] = time.Now().Format("2006-01-02 15:04:05")
|
||||||
orderSingleData["cancel_remarks"] = utils.OrderCancelReasonToString(cancelReason)
|
orderSingleData["cancel_remarks"] = utils.OrderCancelReasonToString(cancelReason)
|
||||||
orderSingleData["updated_at"] = time.Now().Format("2006-01-02 15:04:05")
|
orderSingleData["updated_at"] = time.Now().Format("2006-01-02 15:04:05")
|
||||||
err = orderSingleDao.EditOrderSingleById(tx, orderId, orderSingleData)
|
|
||||||
|
orderSingleDao := dao.OrderSingleDao{}
|
||||||
|
err = orderSingleDao.EditOrderSingleById(tx, orderSingle.OrderId, orderSingleData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, errors.New("订单取消失败")
|
return false, errors.New("订单取消失败")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 退还订单优惠卷
|
// 退还订单优惠卷
|
||||||
if orderSingle.CouponAmountTotal != 0 {
|
err = r.OrderCouponRefund(tx, orderSingle)
|
||||||
// 获取订单优惠卷数据
|
|
||||||
orderSingleCouponDao := dao.OrderSingleCouponDao{}
|
|
||||||
orderSingleCoupon, err := orderSingleCouponDao.GetOrderSingleCouponByOrderId(orderId)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return false, errors.New("订单取消失败")
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
userCouponService := &UserCouponService{}
|
// 订单退款
|
||||||
userCouponService.ReturnUserCoupon(tx, orderSingleCoupon.UserCouponId)
|
_, err = r.OrderRefund(tx, orderSingle, refundAmount, utils.OrderCancelReasonToString(cancelReason))
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
@ -223,3 +217,126 @@ func (r *OrderSingleService) CompleteUnPayOrderSingle(tx *gorm.DB, userId int64)
|
|||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OrderRefund 订单退款
|
||||||
|
func (r *OrderSingleService) OrderRefund(tx *gorm.DB, order *model.OrderSingle, refundAmount *float64, refundReason string) (*model.OrderSingleRefund, error) {
|
||||||
|
var refundStatus int
|
||||||
|
var successTime time.Time
|
||||||
|
var refundId string
|
||||||
|
|
||||||
|
// 判断订单支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款)
|
||||||
|
if order.PayStatus != 2 {
|
||||||
|
// 非已支付,无需退款
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测退款金额
|
||||||
|
if *refundAmount > order.PaymentAmountTotal {
|
||||||
|
return nil, errors.New("退款金额不可超过实付金额")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 退款编号
|
||||||
|
refundNo := strconv.FormatInt(global.Snowflake.Generate().Int64(), 10)
|
||||||
|
|
||||||
|
// 退款金额为0
|
||||||
|
if *refundAmount <= 0 {
|
||||||
|
// 支付金额为0,模拟退款
|
||||||
|
refundId = "模拟退款:" + strconv.FormatInt(global.Snowflake.Generate().Int64(), 10)
|
||||||
|
refundStatus = 3
|
||||||
|
successTime = time.Now()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 退款金额大于0
|
||||||
|
if *refundAmount > 0 {
|
||||||
|
refundRequest := weChat.RefundRequest{
|
||||||
|
TransactionId: order.EscrowTradeNo,
|
||||||
|
OutTradeNo: order.OrderNo,
|
||||||
|
OutRefundNo: refundNo,
|
||||||
|
Reason: refundReason,
|
||||||
|
RefundAmount: int64(*refundAmount * 100),
|
||||||
|
PaymentAmountTotal: int64(order.PaymentAmountTotal * 100),
|
||||||
|
NotifyUrl: config.C.Wechat.RefundNotifyDomain + config.C.Wechat.RefundNotifyUrl,
|
||||||
|
}
|
||||||
|
|
||||||
|
refund, err := refundRequest.Refund()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if refund.Status == nil {
|
||||||
|
return nil, errors.New("退款状态错误")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理订单状态
|
||||||
|
switch *refund.Status {
|
||||||
|
case "SUCCESS": // 退款成功
|
||||||
|
refundStatus = 3
|
||||||
|
if refund.SuccessTime != nil {
|
||||||
|
successTime = *refund.SuccessTime
|
||||||
|
}
|
||||||
|
case "CLOSED": // 退款关闭
|
||||||
|
|
||||||
|
refundStatus = 5
|
||||||
|
case "PROCESSING": // 退款处理中
|
||||||
|
refundStatus = 2
|
||||||
|
case "ABNORMAL": // 退款异常
|
||||||
|
return nil, errors.New("退款状态错误")
|
||||||
|
default:
|
||||||
|
return nil, errors.New("退款状态错误")
|
||||||
|
}
|
||||||
|
|
||||||
|
if refund.RefundId == nil {
|
||||||
|
return nil, errors.New("缺少退款订单编号")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 退款编号
|
||||||
|
refundId = *refund.RefundId
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增退款表
|
||||||
|
orderRefund := &model.OrderSingleRefund{
|
||||||
|
UserId: order.UserId,
|
||||||
|
OrderId: order.OrderId,
|
||||||
|
OrderNo: order.OrderNo,
|
||||||
|
RefundNo: refundNo,
|
||||||
|
RefundId: refundId,
|
||||||
|
RefundStatus: refundStatus,
|
||||||
|
RefundTotal: *refundAmount,
|
||||||
|
RefundReason: refundReason,
|
||||||
|
}
|
||||||
|
|
||||||
|
if refundStatus == 3 && !successTime.IsZero() {
|
||||||
|
t := model.LocalTime(successTime)
|
||||||
|
orderRefund.SuccessTime = &t
|
||||||
|
}
|
||||||
|
|
||||||
|
orderSingleRefundDao := dao.OrderSingleRefundDao{}
|
||||||
|
orderSingleRefund, err := orderSingleRefundDao.AddOrderSingleRefund(tx, orderRefund)
|
||||||
|
if err != nil || orderSingleRefund == nil {
|
||||||
|
return nil, errors.New(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return orderSingleRefund, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrderCouponRefund 订单优惠卷退还
|
||||||
|
func (r *OrderSingleService) OrderCouponRefund(tx *gorm.DB, order *model.OrderSingle) error {
|
||||||
|
// 订单优惠金额为0,无需退还优惠卷
|
||||||
|
if order.CouponAmountTotal == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取订单优惠卷数据
|
||||||
|
orderSingleCouponDao := dao.OrderSingleCouponDao{}
|
||||||
|
orderSingleCoupons, err := orderSingleCouponDao.GetOrderSingleCouponListByOrderId(order.OrderId)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("优惠卷数据错误")
|
||||||
|
}
|
||||||
|
|
||||||
|
userCouponService := &UserCouponService{}
|
||||||
|
for _, coupon := range orderSingleCoupons {
|
||||||
|
_ = userCouponService.ReturnUserCoupon(tx, coupon.UserCouponId)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user