2024-11-26 11:04:36 +00:00
|
|
|
|
package models
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
2024-11-29 01:40:33 +00:00
|
|
|
|
utils "go-admin/app/admin/models/tools"
|
2024-11-26 11:04:36 +00:00
|
|
|
|
orm "go-admin/common/global"
|
|
|
|
|
"go-admin/logger"
|
2024-11-29 01:40:33 +00:00
|
|
|
|
"log"
|
2024-11-26 11:04:36 +00:00
|
|
|
|
"time"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
ErpCouponUnStarted = 1 // 未开始
|
|
|
|
|
ErpCouponSending = 2 // 发放中
|
|
|
|
|
ErpCouponInProgress = 3 // 进行中
|
|
|
|
|
ErpCouponFinished = 4 // 已结束
|
2024-11-29 01:40:33 +00:00
|
|
|
|
ErpCouponSendFailed = 5 // 发放失败
|
|
|
|
|
|
|
|
|
|
TaskInProgress = "in_progress" // 执行中
|
|
|
|
|
TaskCompleted = "completed" // 已完成
|
|
|
|
|
TaskFailed = "failed" // 发送失败
|
2024-11-26 11:04:36 +00:00
|
|
|
|
)
|
|
|
|
|
|
2024-11-29 01:40:33 +00:00
|
|
|
|
// CouponIssuanceTask 优惠券发放任务表
|
|
|
|
|
type CouponIssuanceTask struct {
|
|
|
|
|
Model
|
|
|
|
|
ErpCouponId uint32 `json:"erp_coupon_id"` // 优惠券id
|
|
|
|
|
ErpCouponName string `json:"erp_coupon_name"` // 优惠券名称
|
|
|
|
|
Status string `json:"status"` // 任务状态:in_progress(执行中)、completed(已完成)、failed(发送失败)
|
|
|
|
|
LastUserID uint32 `json:"last_user_id"` // 上次处理的用户ID
|
|
|
|
|
ErrorMessage string `json:"error_message" gorm:"type:text"` // 错误信息,若任务失败时记录
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-26 11:04:36 +00:00
|
|
|
|
// ErpCoupon 营销管理-优惠券
|
|
|
|
|
type ErpCoupon struct {
|
|
|
|
|
Model
|
2024-11-29 01:40:33 +00:00
|
|
|
|
Name string `json:"name" gorm:"index"` // 优惠券名称
|
|
|
|
|
Remark string `json:"remark"` // 名称备注
|
|
|
|
|
Describe string `json:"describe" gorm:"type:text"` // 优惠券简介
|
|
|
|
|
Rule string `json:"rule" gorm:"type:text"` // 优惠券使用规则
|
|
|
|
|
CategoryNumber string `json:"category_number"` // 可以使用该优惠券的商品分类,如果为空则表示没限制
|
|
|
|
|
ActiveDate uint32 `json:"active_date"` // 有效期(天)
|
|
|
|
|
Amount uint32 `json:"amount"` // 金额(元)
|
|
|
|
|
UserType uint32 `json:"user_type"` // 领取人限制:1-所有人 2-未付费用户 3-已付费用户 4-尊享会员
|
|
|
|
|
Limit uint32 `json:"limit"` // 优惠券叠加限制 0-不限制;1-仅限原价购买时使用
|
|
|
|
|
State uint32 `json:"state" gorm:"index"` // 当前状态 1-未开始;2-发放中;3-进行中;4-已结束;5-发放失败
|
|
|
|
|
SendCount uint32 `json:"send_count"` // 已发放
|
|
|
|
|
UsedCount uint32 `json:"used_count"` // 已使用
|
|
|
|
|
TotalPayAmount float64 `json:"total_pay_amount"` // 支付金额(元)
|
|
|
|
|
PerCustomerAmount float64 `json:"per_customer_amount"` // 客单价(元)
|
|
|
|
|
SmsContent string `json:"sms_content" gorm:"type:text"` // 短信提示内容
|
2024-11-26 11:04:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpMarketingCouponListReq 优惠券列表入参
|
|
|
|
|
type ErpMarketingCouponListReq struct {
|
|
|
|
|
Name string `json:"name" gorm:"index"` // 优惠券名称
|
|
|
|
|
State uint32 `json:"state" gorm:"index"` // 当前状态 1-未开始;2-发放中;3-进行中;4-已结束
|
|
|
|
|
CreatedTimeStart string `json:"created_time_start"` // 创建开始时间
|
|
|
|
|
CreatedTimeEnd string `json:"created_time_end"` // 创建结束时间
|
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 页面条数
|
|
|
|
|
IsExport uint32 `json:"is_export"` // 1-导出
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpMarketingCouponListResp 优惠券列表出参
|
|
|
|
|
type ErpMarketingCouponListResp struct {
|
|
|
|
|
List []ErpCoupon `json:"list"`
|
|
|
|
|
Total int `json:"total"` // 总条数
|
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 页面条数
|
|
|
|
|
ExportUrl string `json:"export_url"` // 导出excel路径
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpMarketingCouponCreateReq 新增优惠券入参
|
|
|
|
|
type ErpMarketingCouponCreateReq struct {
|
2024-11-29 01:40:33 +00:00
|
|
|
|
Name string `json:"name" validate:"required"` // 优惠券名称
|
|
|
|
|
Remark string `json:"remark"` // 名称备注
|
|
|
|
|
Describe string `json:"describe" gorm:"type:text"` // 优惠券简介
|
|
|
|
|
Rule string `json:"rule" gorm:"type:text"` // 优惠券使用规则
|
|
|
|
|
CategoryNumber string `json:"category_number" validate:"required"` // 可以使用该优惠券的商品分类编号,如果为空则表示没限制
|
|
|
|
|
ActiveDate uint32 `json:"active_date" validate:"required"` // 有效期(天)
|
|
|
|
|
Amount uint32 `json:"amount" validate:"required"` // 金额(元)
|
|
|
|
|
UserType uint32 `json:"user_type" validate:"required"` // 领取人限制:1-所有人 2-未付费用户 3-已付费用户 4-尊享会员
|
|
|
|
|
Limit uint32 `json:"limit"` // 优惠券叠加限制 0-不限制;1-仅限原价购买时使用
|
2024-11-26 11:04:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpMarketingCouponEditReq 编辑优惠券入参
|
|
|
|
|
type ErpMarketingCouponEditReq struct {
|
2024-11-29 01:40:33 +00:00
|
|
|
|
ErpCouponId uint32 `json:"erp_coupon_id" validate:"required"` // 优惠券id
|
|
|
|
|
Name string `json:"name" validate:"required"` // 优惠券名称
|
|
|
|
|
Remark string `json:"remark"` // 名称备注
|
|
|
|
|
Describe string `json:"describe" gorm:"type:text"` // 优惠券简介
|
|
|
|
|
Rule string `json:"rule" gorm:"type:text"` // 优惠券使用规则
|
|
|
|
|
CategoryNumber string `json:"category_number" validate:"required"` // 可以使用该优惠券的商品分类,如果为空则表示没限制
|
|
|
|
|
ActiveDate uint32 `json:"active_date" validate:"required"` // 有效期(天)
|
|
|
|
|
Amount uint32 `json:"amount" validate:"required"` // 金额(元)
|
|
|
|
|
UserType uint32 `json:"user_type" validate:"required"` // 领取人限制:1-所有人 2-未付费用户 3-已付费用户 4-尊享会员
|
|
|
|
|
Limit uint32 `json:"limit"` // 优惠券叠加限制 0-不限制;1-仅限原价购买时使用
|
2024-11-26 11:04:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpMarketingCouponDeleteReq 删除优惠券入参
|
|
|
|
|
type ErpMarketingCouponDeleteReq struct {
|
2024-11-29 01:40:33 +00:00
|
|
|
|
ErpCouponId uint32 `json:"erp_coupon_id" validate:"required"` // 优惠券id
|
2024-11-26 11:04:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpMarketingCouponStartReq 启动优惠券发放
|
|
|
|
|
type ErpMarketingCouponStartReq struct {
|
2024-11-29 01:40:33 +00:00
|
|
|
|
ErpCouponId []uint32 `json:"erp_coupon_id" validate:"required"` // 优惠券id
|
|
|
|
|
Remark string `json:"remark" validate:"required"` // 活动名称备注
|
|
|
|
|
SmsContent string `json:"sms_content" validate:"required"` // 短信提示内容
|
2024-11-26 11:04:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpMarketingCouponDataReq 优惠券数据入参
|
|
|
|
|
type ErpMarketingCouponDataReq struct {
|
2024-11-29 01:40:33 +00:00
|
|
|
|
ErpCouponId uint32 `json:"erp_coupon_id" validate:"required"` // 优惠券id
|
2024-11-26 11:04:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpMarketingCouponDataResp 优惠券数据出参
|
|
|
|
|
type ErpMarketingCouponDataResp struct {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// List 查询优惠券列表
|
|
|
|
|
func (m *ErpMarketingCouponListReq) List() (*ErpMarketingCouponListResp, error) {
|
|
|
|
|
resp := &ErpMarketingCouponListResp{
|
|
|
|
|
PageIndex: m.PageIndex,
|
|
|
|
|
PageSize: m.PageSize,
|
|
|
|
|
}
|
|
|
|
|
page := m.PageIndex - 1
|
|
|
|
|
if page < 0 {
|
|
|
|
|
page = 0
|
|
|
|
|
}
|
|
|
|
|
if m.PageSize == 0 {
|
|
|
|
|
m.PageSize = 10
|
|
|
|
|
}
|
|
|
|
|
qs := orm.Eloquent.Table("erp_coupon")
|
|
|
|
|
|
|
|
|
|
if m.Name != "" {
|
|
|
|
|
qs = qs.Where("name = ?", m.Name)
|
|
|
|
|
}
|
|
|
|
|
if m.State != 0 {
|
|
|
|
|
qs = qs.Where("state = ?", m.State)
|
|
|
|
|
}
|
|
|
|
|
if m.CreatedTimeStart != "" {
|
|
|
|
|
parse, err := time.Parse(QueryTimeFormat, m.CreatedTimeStart)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("erpPurchaseOrderList err:", err)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
qs = qs.Where("created_at > ?", parse)
|
|
|
|
|
}
|
|
|
|
|
if m.CreatedTimeEnd != "" {
|
|
|
|
|
parse, err := time.Parse(QueryTimeFormat, m.CreatedTimeEnd)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("erpPurchaseOrderList err:", err)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
qs = qs.Where("created_at < ?", parse)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var count int64
|
|
|
|
|
err := qs.Count(&count).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("count err:", logger.Field("err", err))
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
resp.Total = int(count)
|
|
|
|
|
|
|
|
|
|
var couponList []ErpCoupon
|
|
|
|
|
err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&couponList).Error
|
|
|
|
|
if err != nil && err != RecordNotFound {
|
|
|
|
|
logger.Error("erp_coupon list err:", logger.Field("err", err))
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp.List = couponList
|
|
|
|
|
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CreateErpMarketingCoupon 新增优惠券
|
|
|
|
|
func CreateErpMarketingCoupon(req *ErpMarketingCouponCreateReq) error {
|
|
|
|
|
erpCoupon := &ErpCoupon{
|
|
|
|
|
Name: req.Name,
|
|
|
|
|
Remark: req.Remark,
|
2024-11-29 01:40:33 +00:00
|
|
|
|
Describe: req.Describe,
|
|
|
|
|
Rule: req.Rule,
|
2024-11-26 11:04:36 +00:00
|
|
|
|
CategoryNumber: req.CategoryNumber,
|
|
|
|
|
ActiveDate: req.ActiveDate,
|
|
|
|
|
Amount: req.Amount,
|
|
|
|
|
UserType: req.UserType,
|
|
|
|
|
Limit: req.Limit,
|
|
|
|
|
State: ErpCouponUnStarted,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := orm.Eloquent.Create(erpCoupon).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("create purchase order err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-29 01:40:33 +00:00
|
|
|
|
coupon := &Coupon{
|
|
|
|
|
Name: req.Name,
|
|
|
|
|
Describe: req.Describe,
|
|
|
|
|
Rule: req.Rule,
|
|
|
|
|
CouponType: "deduction",
|
|
|
|
|
Value: req.Amount,
|
|
|
|
|
CategoryNumber: req.CategoryNumber,
|
|
|
|
|
ErpCouponId: erpCoupon.ID,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = orm.Eloquent.Create(coupon).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("create coupon order err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-26 11:04:36 +00:00
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// EditErpMarketingCoupon 编辑优惠券
|
|
|
|
|
func EditErpMarketingCoupon(req *ErpMarketingCouponEditReq) error {
|
|
|
|
|
// 查询订单信息
|
|
|
|
|
var erpCoupon ErpCoupon
|
|
|
|
|
err := orm.Eloquent.Table("erp_coupon").Where("id=?", req.ErpCouponId).Find(&erpCoupon).Error
|
|
|
|
|
if err != nil {
|
2024-11-29 01:40:33 +00:00
|
|
|
|
logger.Error("query erp_coupon err:", logger.Field("err", err))
|
2024-11-26 11:04:36 +00:00
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if erpCoupon.ID == 0 {
|
|
|
|
|
logger.Error("delete err, erpCoupon ID is:", logger.Field("erpCoupon.ID", req.ErpCouponId))
|
|
|
|
|
return errors.New(fmt.Sprintf("编辑失败:未查询到优惠券id[%d]", req.ErpCouponId))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 1-更新优惠券信息
|
|
|
|
|
erpCoupon.Name = req.Name
|
|
|
|
|
erpCoupon.Remark = req.Remark
|
2024-11-29 01:40:33 +00:00
|
|
|
|
erpCoupon.Rule = req.Rule
|
|
|
|
|
erpCoupon.Describe = req.Describe
|
2024-11-26 11:04:36 +00:00
|
|
|
|
erpCoupon.CategoryNumber = req.CategoryNumber
|
|
|
|
|
erpCoupon.ActiveDate = req.ActiveDate
|
|
|
|
|
erpCoupon.Amount = req.Amount
|
|
|
|
|
erpCoupon.UserType = req.UserType
|
|
|
|
|
erpCoupon.Limit = req.Limit
|
|
|
|
|
|
2024-11-29 01:40:33 +00:00
|
|
|
|
begin := orm.Eloquent.Begin()
|
|
|
|
|
err = begin.Model(&ErpCoupon{}).Where("id = ?", req.ErpCouponId).
|
2024-11-26 11:04:36 +00:00
|
|
|
|
Omit("created_at").Save(erpCoupon).Error
|
|
|
|
|
if err != nil {
|
2024-11-29 01:40:33 +00:00
|
|
|
|
begin.Rollback()
|
2024-11-26 11:04:36 +00:00
|
|
|
|
logger.Error("update erp_coupon err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-29 01:40:33 +00:00
|
|
|
|
// 查询订单信息
|
|
|
|
|
var coupon Coupon
|
|
|
|
|
err = orm.Eloquent.Table("coupon").Where("erp_coupon_id=?", req.ErpCouponId).Find(&coupon).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
logger.Error("query coupon err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
coupon.Name = req.Name
|
|
|
|
|
coupon.Describe = req.Describe
|
|
|
|
|
coupon.Rule = req.Rule
|
|
|
|
|
coupon.Value = req.Amount
|
|
|
|
|
|
|
|
|
|
err = begin.Model(&Coupon{}).Where("erp_coupon_id = ?", req.ErpCouponId).
|
|
|
|
|
Omit("created_at").Save(coupon).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
logger.Error("update coupon err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = begin.Commit().Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
logger.Error("commit update erp_coupon err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-26 11:04:36 +00:00
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DeleteErpMarketingCoupon 删除优惠券
|
|
|
|
|
func DeleteErpMarketingCoupon(req *ErpMarketingCouponDeleteReq) error {
|
|
|
|
|
// 查询订单信息
|
|
|
|
|
var erpCoupon ErpCoupon
|
|
|
|
|
err := orm.Eloquent.Table("erp_coupon").Where("id=?", req.ErpCouponId).Find(&erpCoupon).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("purchase order err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if erpCoupon.ID == 0 {
|
|
|
|
|
logger.Error("delete err, erpCoupon ID is:", logger.Field("erpCoupon.ID", req.ErpCouponId))
|
|
|
|
|
return errors.New(fmt.Sprintf("删除失败:未查询到优惠券id[%d]", req.ErpCouponId))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 仅未开始和已结束的订单可删除
|
|
|
|
|
if erpCoupon.State != ErpCouponUnStarted && erpCoupon.State != ErpCouponFinished {
|
|
|
|
|
logger.Error("delete err, erpCoupon.State is:", logger.Field("erpCoupon.State", erpCoupon.State))
|
|
|
|
|
return errors.New("删除失败:仅未开始和已结束的优惠券可删除")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删除优惠订单
|
2024-11-29 01:40:33 +00:00
|
|
|
|
begin := orm.Eloquent.Begin()
|
|
|
|
|
err = begin.Delete(erpCoupon).Error
|
2024-11-26 11:04:36 +00:00
|
|
|
|
if err != nil {
|
2024-11-29 01:40:33 +00:00
|
|
|
|
begin.Rollback()
|
2024-11-26 11:04:36 +00:00
|
|
|
|
logger.Error("erp_coupon delete err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-29 01:40:33 +00:00
|
|
|
|
err = begin.Table("coupon").Where("erp_coupon_id", req.ErpCouponId).Delete(&Coupon{}).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
logger.Error("coupon delete err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = begin.Commit().Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
logger.Error("commit erp_coupon delete err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// StartCouponIssuanceTask 启动发放优惠券的任务
|
|
|
|
|
func StartCouponIssuanceTask(req *ErpMarketingCouponStartReq, taskList []CouponIssuanceTask) error {
|
|
|
|
|
var erpCouponList []ErpCoupon
|
|
|
|
|
err := orm.Eloquent.Table("erp_coupon").Where("id in ?", req.ErpCouponId).Find(&erpCouponList).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("purchase order err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(taskList) < len(erpCouponList) {
|
|
|
|
|
for _, erpCoupon := range erpCouponList {
|
|
|
|
|
exitFlag := false
|
|
|
|
|
for _, task := range taskList {
|
|
|
|
|
if erpCoupon.ID == task.ErpCouponId {
|
|
|
|
|
exitFlag = true
|
|
|
|
|
break
|
|
|
|
|
} else {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !exitFlag {
|
|
|
|
|
// 新建任务
|
|
|
|
|
taskInfo := CouponIssuanceTask{
|
|
|
|
|
ErpCouponId: erpCoupon.ID,
|
|
|
|
|
ErpCouponName: erpCoupon.Name,
|
|
|
|
|
Status: TaskInProgress,
|
|
|
|
|
LastUserID: 0,
|
|
|
|
|
ErrorMessage: "",
|
|
|
|
|
}
|
|
|
|
|
err := orm.Eloquent.Create(&taskInfo).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("create CouponIssuanceTask err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
taskList = append(taskList, taskInfo)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 遍历taskList,获取最小的lastUserID
|
|
|
|
|
var lastUserID uint32
|
|
|
|
|
for _, task := range taskList {
|
|
|
|
|
if lastUserID == 0 {
|
|
|
|
|
lastUserID = task.LastUserID
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if lastUserID > task.LastUserID {
|
|
|
|
|
lastUserID = task.LastUserID
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理任务,从上次中断的用户ID开始
|
|
|
|
|
for {
|
|
|
|
|
// 查询用户ID大于 lastUserID 的用户
|
|
|
|
|
users, err := getUsersAfterID(lastUserID)
|
|
|
|
|
if err != nil || len(users) == 0 {
|
|
|
|
|
log.Println("没有更多用户,任务结束")
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 发放优惠券
|
|
|
|
|
err = issueCouponsToUsers(users, req.ErpCouponId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Printf("发放优惠券失败: %v", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新任务进度:记录处理到的最后一个用户ID
|
|
|
|
|
lastUserID = users[len(users)-1].ID
|
|
|
|
|
//err = updateTaskProgress(req.ErpCouponId, lastUserID, err.Error())
|
|
|
|
|
//if err != nil {
|
|
|
|
|
// log.Printf("更新任务进度失败: %v", err)
|
|
|
|
|
// break
|
|
|
|
|
//}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 任务完成,更新状态
|
|
|
|
|
err = markTaskAsCompleted(req.ErpCouponId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CheckUserType 校验批量选择的优惠券使用人群是否相同
|
|
|
|
|
func CheckUserType(erpCouponId []uint32) bool {
|
|
|
|
|
var erpCouponList []ErpCoupon
|
|
|
|
|
err := orm.Eloquent.Table("erp_coupon").Where("id in ?", erpCouponId).Find(&erpCouponList).Error
|
|
|
|
|
if err != nil || err == RecordNotFound {
|
|
|
|
|
logger.Error("query erp_coupon err:", logger.Field("err", err))
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var userType uint32
|
|
|
|
|
for _, erpCoupon := range erpCouponList {
|
|
|
|
|
if userType == 0 {
|
|
|
|
|
userType = erpCoupon.UserType
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if userType != erpCoupon.UserType {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetTaskProgress 查询优惠券任务执行情况
|
|
|
|
|
func GetTaskProgress(erpCouponId []uint32) ([]CouponIssuanceTask, error) {
|
|
|
|
|
var task []CouponIssuanceTask
|
|
|
|
|
err := orm.Eloquent.Table("coupon_issuance_task").Where("erp_coupon_id in ?", erpCouponId).
|
|
|
|
|
Order("updated_at desc").First(&task).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return task, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getUsersAfterID(lastUserID uint32) ([]UserInfo, error) {
|
|
|
|
|
var users []UserInfo
|
|
|
|
|
err := orm.Eloquent.Model(&UserInfo{}).Where("id > ? ", lastUserID).
|
|
|
|
|
Order("id asc").Limit(100).Find(&users).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return users, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func updateTaskProgress(erpCouponId []uint32, lastUserID uint32, errMsg string) error {
|
|
|
|
|
err := orm.Eloquent.Table("coupon_issuance_task").Where("erp_coupon_id in ?", erpCouponId).
|
|
|
|
|
Updates(map[string]interface{}{
|
|
|
|
|
"last_user_id": lastUserID,
|
|
|
|
|
"error_message": errMsg,
|
|
|
|
|
"updated_at": time.Now(),
|
|
|
|
|
}).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func markTaskAsCompleted(erpCouponId []uint32) error {
|
|
|
|
|
err := orm.Eloquent.Table("coupon_issuance_task").Where("erp_coupon_id in ?", erpCouponId).
|
|
|
|
|
Updates(map[string]interface{}{
|
|
|
|
|
"Status": TaskCompleted,
|
|
|
|
|
"updated_at": time.Now(),
|
|
|
|
|
}).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Printf("更新任务完成状态失败: %v", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
log.Println("任务完成")
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 校验用户是否符合领取优惠券的条件
|
|
|
|
|
func isEligibleForCoupon(user UserInfo, erpCoupon ErpCoupon) bool {
|
|
|
|
|
switch erpCoupon.UserType {
|
|
|
|
|
case 1:
|
|
|
|
|
// 1-所有人:不限制会员等级,所有人均可领取
|
|
|
|
|
return true
|
|
|
|
|
case 2:
|
|
|
|
|
// 2-未付费用户:MemberLevel 不能是 (2, 3, 4, 5)
|
|
|
|
|
if user.MemberLevel == MemberLevelGold ||
|
|
|
|
|
user.MemberLevel == MemberLevelPeriod ||
|
|
|
|
|
user.MemberLevel == MemberLevelPlatinum ||
|
|
|
|
|
user.MemberLevel == MemberLevelBlackGold {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
case 3:
|
|
|
|
|
// 3-已付费用户:MemberLevel 必须是 (2, 3, 4, 5)
|
|
|
|
|
if user.MemberLevel == MemberLevelGold ||
|
|
|
|
|
user.MemberLevel == MemberLevelPeriod ||
|
|
|
|
|
user.MemberLevel == MemberLevelPlatinum ||
|
|
|
|
|
user.MemberLevel == MemberLevelBlackGold {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
default:
|
|
|
|
|
// 未知类型,不发放
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func issueCouponsToUsers(users []UserInfo, erpCouponId []uint32) error {
|
|
|
|
|
var erpCoupon []ErpCoupon
|
|
|
|
|
err := orm.Eloquent.Table("erp_coupon").Where("id in ?", erpCouponId).Find(&erpCoupon).Error
|
|
|
|
|
if err != nil || err == RecordNotFound {
|
|
|
|
|
logger.Error("query erp_coupon err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, user := range users {
|
|
|
|
|
// 根据条件发放优惠券
|
|
|
|
|
if isEligibleForCoupon(user, erpCoupon[0]) {
|
|
|
|
|
// 发放优惠券
|
|
|
|
|
var coupons []Coupon
|
|
|
|
|
err = orm.Eloquent.Table("coupon").Where("erp_coupon_id in ?", erpCouponId).First(&coupons).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("query coupon err:", logger.Field("err", err))
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, coupon := range coupons {
|
|
|
|
|
couponCode, _ := utils.GenerateRandomNumber19()
|
|
|
|
|
userCoupon := &UserCoupon{
|
|
|
|
|
Uid: user.Uid,
|
|
|
|
|
CouponId: coupon.ID,
|
|
|
|
|
CouponType: coupon.CouponType,
|
|
|
|
|
Value: coupon.Value,
|
|
|
|
|
State: 1,
|
|
|
|
|
ActiveStart: time.Now(),
|
|
|
|
|
ActiveEnd: time.Now().AddDate(0, 0, 7),
|
|
|
|
|
RedeemCode: "",
|
|
|
|
|
CategoryNumber: coupon.CategoryNumber,
|
|
|
|
|
Code: couponCode,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = orm.Eloquent.Create(userCoupon).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("create user coupon err:", logger.Field("err", err))
|
|
|
|
|
err = updateTaskProgress(erpCouponId, user.ID, err.Error())
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Printf("更新任务进度失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 发送短信或者消息订阅通知
|
|
|
|
|
err = GtSendMessage([]string{user.Tel}, erpCoupon[0].SmsContent)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error(err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-11-26 11:04:36 +00:00
|
|
|
|
return nil
|
|
|
|
|
}
|