mh_goadmin_server/app/admin/models/user_vm.go
chenlin 9c72b52723 1、修改库存调拨入库编号生成规则;
2、修改商品资料前端入参分页错误时,接口报错的缺陷;
3、修复串码商品(手动添加)零售退货订单审核失败的缺陷;
4、优惠券增加商品编号字段;
5、取消会员时扣减积分,尊享会员优惠券更新为过期状态;
2024-09-20 11:09:50 +08:00

268 lines
8.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package models
import (
"errors"
"fmt"
orm "go-admin/common/global"
"go-admin/logger"
"gorm.io/gorm"
"time"
)
const (
VmEventBuyGoods = "buy_goods" // 购买商品积分抵扣
VmEventBuyGoodsReject = "buy_goods_reject" // 购买商品积分抵扣取消
VmEventOpenMember = "open_member" // 开通会员奖励
VmEventInvite1Member = "invite_1_member" // 邀请会员奖励
VmEventInvite2Member = "invite_2_member" // 邀请会员奖励
VmEventUserShareCard = "user_share_card" // 用户共享卡收益
VmEventAttendance = "attendance" // 连续签到获取积分
VmEventErpOrderSale = "erp_order_sale" // 零售销售获得积分
VmEventErpOrderReject = "erp_order_reject" // 零售退货扣除积分
VmEventExpired = "vm_expired" // 积分过期扣减
VmEventCancelMember = "cancel_member" // 取消租卡会员
VmEventCancelPrivilegeMember = "cancel_privilege_member" // 取消尊享会员
)
// 用户积分
// gen:qs
//
//go:generate goqueryset -in user_vm.go
type UserVm struct {
Model
Uid uint32 `json:"uid" gorm:"column:uid;unique_index"`
Vm uint32 `json:"vm"`
//UserVm uint32 `json:"user_vm"`
}
// 用户积分-变动记录
// gen:qs
type UserVmRecord struct {
Model
Uid uint32 `json:"uid" gorm:"column:uid;unique_index"` // 用户ID
BeforeVm uint32 `json:"before_vm"` // 变动前
AfterVm uint32 `json:"after_vm"` // 变动后
Alter int `json:"alter"` // 数值
Event string `json:"event" gorm:"type:varchar(100)"` // 事件
Describe string `json:"describe" gorm:"type:text"` // 描述
ErpOrderId uint32 `json:"erp_order_id" gorm:"index"` // 零售订单id
BillSn string `json:"bill_sn"` // 零售订单编号
ExpiryDate time.Time `json:"expiry_date"` // 积分过期时间
UsedVm int `json:"used_vm"` // 已使用积分
ExpiryVm int `json:"expiry_vm" gorm:"-"` // 即将过期的积分
User *UserInfo `json:"user,omitempty" gorm:"-"` // 用户信息
}
func UserVmUpdate(gdb *gorm.DB, billSn string, uid uint32, amount int, event, describe string) error {
var userVm UserVm
err := orm.Eloquent.Table("user_vm").
Where("uid=?", uid).Find(&userVm).Error
if err != nil {
logger.Error("share card retrieve cards err:", logger.Field("err", err))
return err
}
// 变动前的积分
nBeforeVm := userVm.Vm
flag := false
begin := gdb
if gdb == nil {
flag = true
begin = orm.Eloquent.Begin()
}
if userVm.Uid == 0 { // 没有积分记录
if amount < 0 {
begin.Rollback()
logger.Error("amount lt 0")
return errors.New("amount lt 0")
}
userVm = UserVm{
Uid: uid,
Vm: uint32(amount),
}
err = begin.Create(&userVm).Error
if err != nil {
begin.Rollback()
logger.Error("err:", logger.Field("err", err))
return err
}
} else {
// 如果用户积分不够抵扣则扣到0为止
if int(userVm.Vm)+amount <= 0 {
sql := fmt.Sprintf("UPDATE user_vm SET vm = ? WHERE uid=?")
err = begin.Exec(sql, 0, uid).Error
} else {
sql := fmt.Sprintf("UPDATE user_vm SET vm = vm+? WHERE uid=?")
err = begin.Exec(sql, amount, uid).Error
}
if err != nil {
begin.Rollback()
logger.Error("err:", logger.Field("err", err))
return err
}
}
vmRecord := &UserVmRecord{
Uid: uid,
BeforeVm: uint32(nBeforeVm),
AfterVm: 0, // 默认值为 0
Alter: amount,
Event: event,
Describe: describe,
BillSn: billSn,
}
if newValue := int(userVm.Vm) + amount; newValue > 0 {
vmRecord.AfterVm = uint32(newValue)
}
// 如果是正积分,则记录该订单对应积分的有效时间
if amount > 0 {
vmRecord.ExpiryDate = time.Now().AddDate(1, 0, 0)
if event == VmEventBuyGoodsReject { // 使用积分购买商品后取消
err = RefundPoints(gdb, uid, amount)
if err != nil {
begin.Rollback()
logger.Error("err:", logger.Field("err", err))
return err
}
}
} else { // 如果是负积分,则记录积分使用情况;优先扣除最早获得的积分
if event == VmEventBuyGoods || event == VmEventErpOrderReject { // 使用积分购买商品,或者零售退货扣除积分
err = UsePoints(gdb, uid, -amount)
if err != nil {
begin.Rollback()
logger.Error("err:", logger.Field("err", err))
return err
}
}
}
err = begin.Create(vmRecord).Error
if err != nil {
begin.Rollback()
logger.Error("err:", logger.Field("err", err))
return err
}
if flag {
err = begin.Commit().Error
if err != nil {
begin.Rollback()
logger.Error("err:", logger.Field("err", err))
return err
}
}
return nil
}
// GetUserAvailablePointsRecords 查找用户的所有可用积分记录,按时间排序
func GetUserAvailablePointsRecords(uid uint32) []UserVmRecord {
var userVmRecord []UserVmRecord
err := orm.Eloquent.Table("user_vm_record").Where("uid = ? and event in (?)",
uid, []string{VmEventOpenMember, VmEventInvite1Member, VmEventInvite2Member, VmEventUserShareCard,
VmEventAttendance, VmEventErpOrderSale}).
Order("created_at DESC").
Find(&userVmRecord).Error
if err != nil {
logger.Error("get user_vm_record err:", logger.Field("err", err))
return []UserVmRecord{}
}
return userVmRecord
}
func UsePoints(gdb *gorm.DB, uid uint32, points int) error {
// 1. 查找用户的所有可用积分记录,按时间排序
records := GetUserAvailablePointsRecords(uid)
remaining := points
for _, record := range records {
available := record.Alter - record.UsedVm // 计算该订单剩余可用积分
if available >= remaining {
// 该订单的剩余积分足够
record.UsedVm += remaining
// 更新积分记录
err := gdb.Omit("created_at").Save(record).Error
if err != nil {
logger.Error("update user_vm_record err:", logger.Field("err", err))
return err
}
break
} else {
// 该订单的剩余积分不足,全部使用,继续扣减下一条记录
record.UsedVm = record.Alter
remaining -= available
// 更新积分记录
err := gdb.Omit("created_at").Save(record).Error
if err != nil {
logger.Error("update user_vm_record err:", logger.Field("err", err))
return err
}
}
}
return nil
}
// GetUserUsedPointsRecords 查找用户的已使用积分记录,按使用时间倒序排序
func GetUserUsedPointsRecords(uid uint32) []UserVmRecord {
var userVmRecord []UserVmRecord
err := orm.Eloquent.Table("user_vm_record").Where("uid = ? and event in (?)",
uid, []string{VmEventOpenMember, VmEventInvite1Member, VmEventInvite2Member, VmEventUserShareCard,
VmEventAttendance, VmEventErpOrderSale}).
Where("used_vm != 0").
Order("created_at DESC").
Find(&userVmRecord).Error
if err != nil {
logger.Error("get user_vm_record err:", logger.Field("err", err))
return []UserVmRecord{}
}
return userVmRecord
}
// RefundPoints 查找用户的已使用积分记录,按使用时间倒序排序
func RefundPoints(gdb *gorm.DB, uid uint32, points int) error {
// 1. 查找用户的已使用积分记录,按使用时间倒序排序
usedRecords := GetUserUsedPointsRecords(uid)
remaining := points
for _, record := range usedRecords {
used := record.UsedVm // 获取该订单已使用的积分
if used >= remaining {
// 该订单已使用的积分足够返还
record.UsedVm -= remaining
// 更新积分记录
err := gdb.Omit("created_at").Save(record).Error
if err != nil {
logger.Error("RefundPoints update user_vm_record err:", logger.Field("err", err))
return err
}
break
} else {
// 该订单已使用的积分不足以完全返还,全部返还后继续处理下一条记录
record.UsedVm = 0
remaining -= used
// 更新积分记录
err := gdb.Omit("created_at").Save(record).Error
if err != nil {
logger.Error("RefundPoints update user_vm_record err:", logger.Field("err", err))
return err
}
}
}
return nil
}