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