1、优化零售优惠相关功能;
2、短信标签go2switch批量修改为go2ns; 3、优化查询零售订单支付状态接口,新增pay_init状态查询;
This commit is contained in:
parent
45543566ef
commit
0d1f3c3aa8
|
@ -2,12 +2,15 @@ package market
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
model "go-admin/app/admin/models"
|
||||
orm "go-admin/common/global"
|
||||
"go-admin/logger"
|
||||
"go-admin/tools"
|
||||
"go-admin/tools/app"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ErpMarketingCouponList 优惠券列表
|
||||
|
@ -150,6 +153,60 @@ func ErpMarketingCouponDelete(c *gin.Context) {
|
|||
// @Success 200 {object} app.Response
|
||||
// @Router /api/v1/marketing/coupon/start [post]
|
||||
func ErpMarketingCouponStart(c *gin.Context) {
|
||||
var req = new(model.ErpMarketingCouponStartReq)
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
logger.Error("ShouldBindJSON err:", logger.Field("err", err))
|
||||
app.Error(c, http.StatusBadRequest, err, "参数错误:"+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
err := tools.Validate(req) //必填参数校验
|
||||
if err != nil {
|
||||
app.Error(c, http.StatusBadRequest, err, "参数错误:优惠券id为空")
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否有正在进行的任务
|
||||
taskList, err := model.GetTaskProgress(req.ErpCouponId)
|
||||
if err != nil {
|
||||
app.Error(c, http.StatusInternalServerError, err, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var waitSendTaskList []model.CouponIssuanceTask
|
||||
for _, task := range taskList {
|
||||
switch task.Status {
|
||||
case model.TaskInProgress: // 执行中
|
||||
app.Error(c, http.StatusInternalServerError, errors.New(fmt.Sprintf("[%s]已在执行中,请勿重复启动", task.ErpCouponName)),
|
||||
fmt.Sprintf("[%s]已在执行中,请勿重复启动", task.ErpCouponName))
|
||||
return
|
||||
case model.TaskCompleted: // 已完成
|
||||
app.Error(c, http.StatusInternalServerError, errors.New(fmt.Sprintf("[%s]已执行完成", task.ErpCouponName)),
|
||||
fmt.Sprintf("[%s]已执行完成", task.ErpCouponName))
|
||||
return
|
||||
default:
|
||||
waitSendTaskList = append(waitSendTaskList, task)
|
||||
}
|
||||
}
|
||||
|
||||
// 校验批量选择的优惠券使用人群是否相同
|
||||
if !model.CheckUserType(req.ErpCouponId) {
|
||||
app.Error(c, http.StatusInternalServerError, errors.New("优惠券适用人群不同,不能同时启动"), "优惠券适用人群不同,不能同时启动")
|
||||
}
|
||||
|
||||
// 更新短信和备注
|
||||
err = orm.Eloquent.Table("erp_coupon").Where("erp_coupon_id in ?", req.ErpCouponId).
|
||||
Updates(map[string]interface{}{
|
||||
"remark": req.Remark,
|
||||
"sms_content": req.SmsContent,
|
||||
"updated_at": time.Now(),
|
||||
}).Error
|
||||
if err != nil {
|
||||
logger.Errorf("更新任务完成状态失败: %v", err)
|
||||
app.Error(c, http.StatusInternalServerError, err, err.Error())
|
||||
}
|
||||
|
||||
go model.StartCouponIssuanceTask(req, waitSendTaskList)
|
||||
|
||||
app.OK(c, nil, "启动成功")
|
||||
return
|
||||
|
|
|
@ -840,7 +840,7 @@ func GroupSendMessage(c *gin.Context) {
|
|||
|
||||
fmt.Println("tels:", tels)
|
||||
fmt.Println("Message:", groupMessageTemplate.Message)
|
||||
//groupMessageTemplate.Message = "【go2switch】温馨提示:您的会员即将过期,请在过期之前将卡归还到门店,如有问题联系客服"
|
||||
//groupMessageTemplate.Message = "【go2ns】温馨提示:您的会员即将过期,请在过期之前将卡归还到门店,如有问题联系客服"
|
||||
err = models.GtSendMessage(strings.Split(tels, ","), groupMessageTemplate.Message)
|
||||
if err != nil {
|
||||
logger.Errorf("SmsSend err:", logger.Field("err", err))
|
||||
|
|
|
@ -26,6 +26,7 @@ type Coupon struct {
|
|||
MemberLevel uint32 `json:"member_level"` // 会员等级 1-用户 2-会员
|
||||
CategoryNumber string `json:"category_number"` // 可以使用该优惠券的商品分类,如果为空则表示没限制
|
||||
CommodityNumber string `json:"commodity_number"` // 可以使用该优惠券的商品编号,如果为空则表示没限制
|
||||
ErpCouponId uint32 `json:"erp_coupon_id"` // 零售业务推送优惠券ID
|
||||
IsDraw bool `json:"is_draw" gorm:"-"` //
|
||||
}
|
||||
|
||||
|
|
|
@ -2514,7 +2514,7 @@ func QueryErpOrderPayStatus(billSn string) (*ErpOrderPayResp, error) {
|
|||
|
||||
// 查询待支付订单
|
||||
var orderRecordInfo ErpOrderRecord
|
||||
err = orm.Eloquent.Table("erp_order_record").Where("bill_sn = ? and status in (?)", billSn, []string{Paying, PayOk}).
|
||||
err = orm.Eloquent.Table("erp_order_record").Where("bill_sn = ? and status in (?)", billSn, []string{PayInit, Paying, PayOk}).
|
||||
Find(&orderRecordInfo).Error
|
||||
if err != nil {
|
||||
logger.Error("未查询到订单:", logger.Field("err", err))
|
||||
|
|
|
@ -1458,7 +1458,7 @@ func MemberExpirationReminder() {
|
|||
// return
|
||||
//}
|
||||
//
|
||||
//content := "【go2switch】温馨提示:您的会员即将过期,请在过期之前将卡归还到门店,如有问题联系客服"
|
||||
//content := "【go2ns】温馨提示:您的会员即将过期,请在过期之前将卡归还到门店,如有问题联系客服"
|
||||
//for i, _ := range users {
|
||||
// if users[i].Tel == "" {
|
||||
// continue
|
||||
|
@ -1546,7 +1546,7 @@ func ExpireMemberSMSSend() {
|
|||
|
||||
func ExpireMemberSMSSendDay(day uint32, nowTime time.Time) {
|
||||
smsSend := &ExpireMemberSmsSend{
|
||||
Message: fmt.Sprintf("【go2switch】您的租卡会员已过期%d天,卡带未归还产生滞纳金%d元,请及时续费会员或归还卡带,以避免对您造成不必要的损失。", day, day*2),
|
||||
Message: fmt.Sprintf("【go2ns】您的租卡会员已过期%d天,卡带未归还产生滞纳金%d元,请及时续费会员或归还卡带,以避免对您造成不必要的损失。", day, day*2),
|
||||
SendTime: nowTime,
|
||||
Tel: "",
|
||||
Status: 1,
|
||||
|
|
|
@ -3,8 +3,10 @@ package models
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
utils "go-admin/app/admin/models/tools"
|
||||
orm "go-admin/common/global"
|
||||
"go-admin/logger"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -13,24 +15,41 @@ const (
|
|||
ErpCouponSending = 2 // 发放中
|
||||
ErpCouponInProgress = 3 // 进行中
|
||||
ErpCouponFinished = 4 // 已结束
|
||||
ErpCouponSendFailed = 5 // 发放失败
|
||||
|
||||
TaskInProgress = "in_progress" // 执行中
|
||||
TaskCompleted = "completed" // 已完成
|
||||
TaskFailed = "failed" // 发送失败
|
||||
)
|
||||
|
||||
// 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"` // 错误信息,若任务失败时记录
|
||||
}
|
||||
|
||||
// ErpCoupon 营销管理-优惠券
|
||||
type ErpCoupon struct {
|
||||
Model
|
||||
Name string `json:"name" gorm:"index"` // 优惠券名称
|
||||
Remark string `json:"remark"` // 名称备注
|
||||
Content string `json:"content"` // 优惠内容
|
||||
CategoryNumber string `json:"category_number"` // 可以使用该优惠券的商品分类,如果为空则表示没限制
|
||||
ActiveDate uint32 `json:"active_date"` // 有效期(天)
|
||||
Amount float64 `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-已结束
|
||||
SendCount uint32 `json:"send_count"` // 已发放
|
||||
UsedCount uint32 `json:"used_count"` // 已使用
|
||||
TotalPayAmount float64 `json:"total_pay_amount"` // 支付金额(元)
|
||||
PerCustomerAmount float64 `json:"per_customer_amount"` // 客单价(元)
|
||||
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"` // 短信提示内容
|
||||
}
|
||||
|
||||
// ErpMarketingCouponListReq 优惠券列表入参
|
||||
|
@ -55,42 +74,46 @@ type ErpMarketingCouponListResp struct {
|
|||
|
||||
// ErpMarketingCouponCreateReq 新增优惠券入参
|
||||
type ErpMarketingCouponCreateReq struct {
|
||||
Name string `json:"name" validate:"required"` // 优惠券名称
|
||||
Remark string `json:"remark"` // 名称备注
|
||||
Content string `json:"content"` // 优惠内容/使用说明
|
||||
CategoryNumber string `json:"category_number" validate:"required"` // 可以使用该优惠券的商品分类编号,如果为空则表示没限制
|
||||
ActiveDate uint32 `json:"active_date" validate:"required"` // 有效期(天)
|
||||
Amount float64 `json:"amount" validate:"required"` // 金额(元)
|
||||
UserType uint32 `json:"user_type" validate:"required"` // 领取人限制:1-所有人 2-未付费用户 3-已付费用户 4-尊享会员
|
||||
Limit uint32 `json:"limit"` // 优惠券叠加限制 0-不限制;1-仅限原价购买时使用
|
||||
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-仅限原价购买时使用
|
||||
}
|
||||
|
||||
// ErpMarketingCouponEditReq 编辑优惠券入参
|
||||
type ErpMarketingCouponEditReq struct {
|
||||
ErpCouponId uint32 `json:"erp_coupon_id" validate:"required"` // 优惠券id
|
||||
Name string `json:"name" validate:"required"` // 优惠券名称
|
||||
Remark string `json:"remark"` // 名称备注
|
||||
Content string `json:"content"` // 优惠内容/使用说明
|
||||
CategoryNumber string `json:"category_number" validate:"required"` // 可以使用该优惠券的商品分类,如果为空则表示没限制
|
||||
ActiveDate uint32 `json:"active_date" validate:"required"` // 有效期(天)
|
||||
Amount float64 `json:"amount" validate:"required"` // 金额(元)
|
||||
UserType uint32 `json:"user_type" validate:"required"` // 领取人限制:1-所有人 2-未付费用户 3-已付费用户 4-尊享会员
|
||||
Limit uint32 `json:"limit"` // 优惠券叠加限制 0-不限制;1-仅限原价购买时使用
|
||||
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-仅限原价购买时使用
|
||||
}
|
||||
|
||||
// ErpMarketingCouponDeleteReq 删除优惠券入参
|
||||
type ErpMarketingCouponDeleteReq struct {
|
||||
ErpCouponId uint32 `json:"erp_coupon_id" binding:"required"` // 优惠券id
|
||||
ErpCouponId uint32 `json:"erp_coupon_id" validate:"required"` // 优惠券id
|
||||
}
|
||||
|
||||
// ErpMarketingCouponStartReq 启动优惠券发放
|
||||
type ErpMarketingCouponStartReq struct {
|
||||
ErpCouponId uint32 `json:"erp_coupon_id" binding:"required"` // 优惠券id
|
||||
ErpCouponId []uint32 `json:"erp_coupon_id" validate:"required"` // 优惠券id
|
||||
Remark string `json:"remark" validate:"required"` // 活动名称备注
|
||||
SmsContent string `json:"sms_content" validate:"required"` // 短信提示内容
|
||||
}
|
||||
|
||||
// ErpMarketingCouponDataReq 优惠券数据入参
|
||||
type ErpMarketingCouponDataReq struct {
|
||||
ErpCouponId uint32 `json:"erp_coupon_id" binding:"required"` // 优惠券id
|
||||
ErpCouponId uint32 `json:"erp_coupon_id" validate:"required"` // 优惠券id
|
||||
}
|
||||
|
||||
// ErpMarketingCouponDataResp 优惠券数据出参
|
||||
|
@ -160,7 +183,8 @@ func CreateErpMarketingCoupon(req *ErpMarketingCouponCreateReq) error {
|
|||
erpCoupon := &ErpCoupon{
|
||||
Name: req.Name,
|
||||
Remark: req.Remark,
|
||||
Content: req.Content,
|
||||
Describe: req.Describe,
|
||||
Rule: req.Rule,
|
||||
CategoryNumber: req.CategoryNumber,
|
||||
ActiveDate: req.ActiveDate,
|
||||
Amount: req.Amount,
|
||||
|
@ -175,6 +199,22 @@ func CreateErpMarketingCoupon(req *ErpMarketingCouponCreateReq) error {
|
|||
return err
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -184,7 +224,7 @@ func EditErpMarketingCoupon(req *ErpMarketingCouponEditReq) 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))
|
||||
logger.Error("query erp_coupon err:", logger.Field("err", err))
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -196,20 +236,52 @@ func EditErpMarketingCoupon(req *ErpMarketingCouponEditReq) error {
|
|||
// 1-更新优惠券信息
|
||||
erpCoupon.Name = req.Name
|
||||
erpCoupon.Remark = req.Remark
|
||||
erpCoupon.Content = req.Content
|
||||
erpCoupon.Rule = req.Rule
|
||||
erpCoupon.Describe = req.Describe
|
||||
erpCoupon.CategoryNumber = req.CategoryNumber
|
||||
erpCoupon.ActiveDate = req.ActiveDate
|
||||
erpCoupon.Amount = req.Amount
|
||||
erpCoupon.UserType = req.UserType
|
||||
erpCoupon.Limit = req.Limit
|
||||
|
||||
err = orm.Eloquent.Model(&ErpCoupon{}).Where("id = ?", req.ErpCouponId).
|
||||
begin := orm.Eloquent.Begin()
|
||||
err = begin.Model(&ErpCoupon{}).Where("id = ?", req.ErpCouponId).
|
||||
Omit("created_at").Save(erpCoupon).Error
|
||||
if err != nil {
|
||||
begin.Rollback()
|
||||
logger.Error("update erp_coupon err:", logger.Field("err", err))
|
||||
return err
|
||||
}
|
||||
|
||||
// 查询订单信息
|
||||
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
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -235,11 +307,272 @@ func DeleteErpMarketingCoupon(req *ErpMarketingCouponDeleteReq) error {
|
|||
}
|
||||
|
||||
// 删除优惠订单
|
||||
err = orm.Eloquent.Delete(erpCoupon).Error
|
||||
begin := orm.Eloquent.Begin()
|
||||
err = begin.Delete(erpCoupon).Error
|
||||
if err != nil {
|
||||
begin.Rollback()
|
||||
logger.Error("erp_coupon delete err:", logger.Field("err", err))
|
||||
return err
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -2267,7 +2267,7 @@ func TakeExpressStatePush(pushReq *ExpressStatePushReq) {
|
|||
// if userInfo.Tel == "" {
|
||||
// return
|
||||
// }
|
||||
// err = SmsSend(userInfo.Tel, "【go2switch】温馨提示:您的收回卡已签收,请及时检查卡带确认功能正常,如有问题,请于签收后48小时内通过小程序发起异常反馈。")
|
||||
// err = SmsSend(userInfo.Tel, "【go2ns】温馨提示:您的收回卡已签收,请及时检查卡带确认功能正常,如有问题,请于签收后48小时内通过小程序发起异常反馈。")
|
||||
// if err != nil {
|
||||
// logger.Errorf("SmsSend err:",logger.Field("err",err))
|
||||
// return
|
||||
|
@ -2303,7 +2303,7 @@ func TakeExpressStatePush(pushReq *ExpressStatePushReq) {
|
|||
if userInfo.Tel == "" {
|
||||
return
|
||||
}
|
||||
err = GtSendMessage([]string{userInfo.Tel}, "【go2switch】温馨提示:您的收回卡已签收,请及时检查卡带确认功能正常,如有问题,请于签收后48小时内通过小程序发起异常反馈。")
|
||||
err = GtSendMessage([]string{userInfo.Tel}, "【go2ns】温馨提示:您的收回卡已签收,请及时检查卡带确认功能正常,如有问题,请于签收后48小时内通过小程序发起异常反馈。")
|
||||
if err != nil {
|
||||
logger.Errorf("SmsSend err:", logger.Field("err", err))
|
||||
return
|
||||
|
@ -2344,7 +2344,7 @@ func TakeExpressStatePush(pushReq *ExpressStatePushReq) {
|
|||
if userInfo.Tel == "" {
|
||||
return
|
||||
}
|
||||
err = GtSendMessage([]string{userInfo.Tel}, "【go2switch】温馨提示:您的借卡已签收,请及时检查卡带确认功能正常,如有问题,请于签收后48小时内通过小程序发起异常反馈。")
|
||||
err = GtSendMessage([]string{userInfo.Tel}, "【go2ns】温馨提示:您的借卡已签收,请及时检查卡带确认功能正常,如有问题,请于签收后48小时内通过小程序发起异常反馈。")
|
||||
if err != nil {
|
||||
logger.Errorf("SmsSend err:", logger.Field("err", err))
|
||||
return
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package tools
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"github.com/holdno/snowFlakeByGo"
|
||||
"math/big"
|
||||
mathrand "math/rand"
|
||||
"time"
|
||||
|
||||
|
@ -105,3 +107,24 @@ func RandomLenNum(length int) string {
|
|||
}
|
||||
return str
|
||||
}
|
||||
|
||||
func GenerateRandomNumber19() (string, error) {
|
||||
// Define the maximum number for a single digit (0-9)
|
||||
const digits = "0123456789"
|
||||
const length = 19
|
||||
|
||||
// To store the generated number
|
||||
number := make([]byte, length)
|
||||
|
||||
for i := 0; i < length; i++ {
|
||||
// Generate a random index from 0 to 9
|
||||
index, err := rand.Int(rand.Reader, big.NewInt(int64(len(digits))))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// Convert the index to a byte and add it to the number
|
||||
number[i] = digits[index.Int64()]
|
||||
}
|
||||
|
||||
return string(number), nil
|
||||
}
|
||||
|
|
|
@ -3539,7 +3539,7 @@ func SendMessageMemberRenewal() {
|
|||
}
|
||||
}
|
||||
if len(tels) > 0 {
|
||||
message := "【go2switch】提醒:您的租卡会员时长仅剩余一个月,现在续费最高立减200元!赶快进入小程序领取优惠吧~"
|
||||
message := "【go2ns】提醒:您的租卡会员时长仅剩余一个月,现在续费最高立减200元!赶快进入小程序领取优惠吧~"
|
||||
err = GtSendMessage(tels, message)
|
||||
if err != nil {
|
||||
logger.Errorf("SmsSend err:", logger.Field("err", err))
|
||||
|
|
|
@ -10,7 +10,7 @@ func TestSend(t *testing.T) {
|
|||
tel := "13714071204,17727927738"
|
||||
//tel := "17602181899"
|
||||
|
||||
models.SmsSend(tel, "【go2switch】温馨提示:您的会员即将过期,请在过期之前将卡归还到门店,如有问题联系客服")
|
||||
models.SmsSend(tel, "【go2ns】温馨提示:您的会员即将过期,请在过期之前将卡归还到门店,如有问题联系客服")
|
||||
}
|
||||
|
||||
func TestGtSendMessage(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user