1、零售优惠券发放相关接口优化;

2、增加微信订阅通知发送逻辑;
3、增加定时刷新刷新access_token逻辑;
This commit is contained in:
chenlin 2024-11-29 18:47:58 +08:00
parent 0d1f3c3aa8
commit 40227538f9
8 changed files with 436 additions and 102 deletions

View File

@ -58,7 +58,7 @@ func ErpMarketingCouponCreate(c *gin.Context) {
err := tools.Validate(req) //必填参数校验
if err != nil {
app.Error(c, http.StatusBadRequest, err, "参数错误:缺少必填参数")
app.Error(c, http.StatusBadRequest, err, err.Error())
return
}
@ -96,7 +96,7 @@ func ErpMarketingCouponEdit(c *gin.Context) {
err := tools.Validate(req) //必填参数校验
if err != nil {
app.Error(c, http.StatusBadRequest, err, "参数错误:缺少必填参数")
app.Error(c, http.StatusBadRequest, err, err.Error())
return
}
@ -129,7 +129,7 @@ func ErpMarketingCouponDelete(c *gin.Context) {
err := tools.Validate(req) //必填参数校验
if err != nil {
app.Error(c, http.StatusBadRequest, err, "参数错误优惠券id为空")
app.Error(c, http.StatusBadRequest, err, err.Error())
return
}
@ -162,7 +162,7 @@ func ErpMarketingCouponStart(c *gin.Context) {
err := tools.Validate(req) //必填参数校验
if err != nil {
app.Error(c, http.StatusBadRequest, err, "参数错误优惠券id为空")
app.Error(c, http.StatusBadRequest, err, err.Error())
return
}
@ -174,6 +174,8 @@ func ErpMarketingCouponStart(c *gin.Context) {
}
var waitSendTaskList []model.CouponIssuanceTask
if len(taskList) != 0 {
for _, task := range taskList {
switch task.Status {
case model.TaskInProgress: // 执行中
@ -188,6 +190,7 @@ func ErpMarketingCouponStart(c *gin.Context) {
waitSendTaskList = append(waitSendTaskList, task)
}
}
}
// 校验批量选择的优惠券使用人群是否相同
if !model.CheckUserType(req.ErpCouponId) {
@ -195,9 +198,11 @@ func ErpMarketingCouponStart(c *gin.Context) {
}
// 更新短信和备注
err = orm.Eloquent.Table("erp_coupon").Where("erp_coupon_id in ?", req.ErpCouponId).
err = orm.Eloquent.Table("erp_coupon").Where("id in ?", req.ErpCouponId).
Updates(map[string]interface{}{
"remark": req.Remark,
"state": model.ErpCouponSending,
"start_time": time.Now(),
"sms_content": req.SmsContent,
"updated_at": time.Now(),
}).Error

View File

@ -5,7 +5,6 @@ import (
"crypto/md5"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"go-admin/logger"
"io"
@ -51,9 +50,9 @@ type GtSendMessageResp struct {
}
func GtSendMessage(phoneList []string, content string) error {
if len(phoneList) > GetSmsNumberRemaining() { // 待发送短信超出剩余可用数量
return errors.New("短信剩余数量不足")
}
//if len(phoneList) > GetSmsNumberRemaining() { // 待发送短信超出剩余可用数量
// return errors.New("短信剩余数量不足")
//}
params := make(map[string]interface{}, 0)
nowTime := time.Now()
@ -70,12 +69,12 @@ func GtSendMessage(phoneList []string, content string) error {
}
fmt.Println("resp:", resp)
// 更新已使用的短信数量
err = UpdateSmsUsedCount(len(phoneList))
if err != nil {
logger.Error("UpdateSmsUsedCount err", logger.Field("sms count", len(phoneList)), logger.Field("err", err))
return err
}
//// 更新已使用的短信数量
//err = UpdateSmsUsedCount(len(phoneList))
//if err != nil {
// logger.Error("UpdateSmsUsedCount err", logger.Field("sms count", len(phoneList)), logger.Field("err", err))
// return err
//}
return nil
}

View File

@ -1,12 +1,17 @@
package models
import (
"bytes"
"encoding/json"
"errors"
"fmt"
utils "go-admin/app/admin/models/tools"
orm "go-admin/common/global"
"go-admin/logger"
"io/ioutil"
"log"
"net/http"
"net/url"
"time"
)
@ -20,8 +25,24 @@ const (
TaskInProgress = "in_progress" // 执行中
TaskCompleted = "completed" // 已完成
TaskFailed = "failed" // 发送失败
AccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token"
WXAppID = "wx806c079463b5b56c"
WXSecret = "cb125688bf4e482f66e8c46062d568fc"
WxSubscribeMessage = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token="
TemplateId = "aP3c503T3wn-tJtpDccvxtNi7b1qjrwavFFfo-k2SAQ"
WxJumpUrl = "/pages/voucher/voucher" // 跳转微信小程序的页面路径
)
// WxAccessToken 微信access_token
type WxAccessToken struct {
Model
Appid string `json:"appid"` // 小程序appid
AccessToken string `json:"access_token"` // 获取到的凭证
ExpiresTime time.Time `json:"expires_time"` // 凭证有效时间
}
// CouponIssuanceTask 优惠券发放任务表
type CouponIssuanceTask struct {
Model
@ -36,7 +57,7 @@ type CouponIssuanceTask struct {
type ErpCoupon struct {
Model
Name string `json:"name" gorm:"index"` // 优惠券名称
Remark string `json:"remark"` // 名称备注
Remark string `json:"remark"` // 备注
Describe string `json:"describe" gorm:"type:text"` // 优惠券简介
Rule string `json:"rule" gorm:"type:text"` // 优惠券使用规则
CategoryNumber string `json:"category_number"` // 可以使用该优惠券的商品分类,如果为空则表示没限制
@ -44,6 +65,7 @@ type ErpCoupon struct {
Amount uint32 `json:"amount"` // 金额(元)
UserType uint32 `json:"user_type"` // 领取人限制1-所有人 2-未付费用户 3-已付费用户 4-尊享会员
Limit uint32 `json:"limit"` // 优惠券叠加限制 0-不限制1-仅限原价购买时使用
StartTime *time.Time `json:"start_time"` // 启动时间
State uint32 `json:"state" gorm:"index"` // 当前状态 1-未开始2-发放中3-进行中4-已结束5-发放失败
SendCount uint32 `json:"send_count"` // 已发放
UsedCount uint32 `json:"used_count"` // 已使用
@ -75,7 +97,7 @@ type ErpMarketingCouponListResp struct {
// ErpMarketingCouponCreateReq 新增优惠券入参
type ErpMarketingCouponCreateReq struct {
Name string `json:"name" validate:"required"` // 优惠券名称
Remark string `json:"remark"` // 名称备注
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"` // 可以使用该优惠券的商品分类编号,如果为空则表示没限制
@ -187,7 +209,7 @@ func CreateErpMarketingCoupon(req *ErpMarketingCouponCreateReq) error {
Rule: req.Rule,
CategoryNumber: req.CategoryNumber,
ActiveDate: req.ActiveDate,
Amount: req.Amount,
Amount: req.Amount * 100,
UserType: req.UserType,
Limit: req.Limit,
State: ErpCouponUnStarted,
@ -204,9 +226,10 @@ func CreateErpMarketingCoupon(req *ErpMarketingCouponCreateReq) error {
Describe: req.Describe,
Rule: req.Rule,
CouponType: "deduction",
Value: req.Amount,
Value: req.Amount * 100,
CategoryNumber: req.CategoryNumber,
ErpCouponId: erpCoupon.ID,
ActiveEnd: Now().AddDate(0, 0, int(req.ActiveDate)),
}
err = orm.Eloquent.Create(coupon).Error
@ -385,10 +408,11 @@ func StartCouponIssuanceTask(req *ErpMarketingCouponStartReq, taskList []CouponI
}
}
var nTotalCount int
// 处理任务从上次中断的用户ID开始
for {
// 查询用户ID大于 lastUserID 的用户
users, err := getUsersAfterID(lastUserID)
users, err := getUsersAfterID(lastUserID, erpCouponList[0].UserType)
if err != nil || len(users) == 0 {
log.Println("没有更多用户,任务结束")
break
@ -403,6 +427,7 @@ func StartCouponIssuanceTask(req *ErpMarketingCouponStartReq, taskList []CouponI
// 更新任务进度记录处理到的最后一个用户ID
lastUserID = users[len(users)-1].ID
nTotalCount += len(users)
//err = updateTaskProgress(req.ErpCouponId, lastUserID, err.Error())
//if err != nil {
// log.Printf("更新任务进度失败: %v", err)
@ -411,7 +436,7 @@ func StartCouponIssuanceTask(req *ErpMarketingCouponStartReq, taskList []CouponI
}
// 任务完成,更新状态
err = markTaskAsCompleted(req.ErpCouponId)
err = markTaskAsCompleted(req.ErpCouponId, nTotalCount)
if err != nil {
return nil
}
@ -447,17 +472,33 @@ 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 {
if err != nil && err.Error() != "record not found" {
return nil, err
}
return task, nil
}
func getUsersAfterID(lastUserID uint32) ([]UserInfo, error) {
func getUsersAfterID(lastUserID, userType uint32) ([]UserInfo, error) {
var err error
var users []UserInfo
err := orm.Eloquent.Model(&UserInfo{}).Where("id > ? ", lastUserID).
switch userType {
case 2: // 2-未付费用户MemberLevel 不能是 (2, 3, 4, 5)
err = orm.Eloquent.Model(&UserInfo{}).Where("id > ? and member_level not in ?", lastUserID, []uint32{
MemberLevelGold, MemberLevelPeriod, MemberLevelPlatinum, MemberLevelBlackGold}).
Order("id asc").Limit(100).Find(&users).Error
case 3:
// 3-已付费用户MemberLevel 必须是 (2, 3, 4, 5)
err = orm.Eloquent.Model(&UserInfo{}).Where("id > ? and member_level in ?", lastUserID, []uint32{
MemberLevelGold, MemberLevelPeriod, MemberLevelPlatinum, MemberLevelBlackGold}).
Order("id asc").Limit(100).Find(&users).Error
case 1: // 1-所有人:不限制会员等级,所有人均可领取
default:
err = orm.Eloquent.Model(&UserInfo{}).Where("id > ?", lastUserID).
Order("id asc").Limit(100).Find(&users).Error
}
if err != nil {
return nil, err
}
@ -477,7 +518,7 @@ func updateTaskProgress(erpCouponId []uint32, lastUserID uint32, errMsg string)
return nil
}
func markTaskAsCompleted(erpCouponId []uint32) error {
func markTaskAsCompleted(erpCouponId []uint32, nTotalCount int) error {
err := orm.Eloquent.Table("coupon_issuance_task").Where("erp_coupon_id in ?", erpCouponId).
Updates(map[string]interface{}{
"Status": TaskCompleted,
@ -488,6 +529,17 @@ func markTaskAsCompleted(erpCouponId []uint32) error {
return err
}
err = orm.Eloquent.Table("erp_coupon").Where("id in ?", erpCouponId).
Updates(map[string]interface{}{
"state": ErpCouponInProgress,
"send_count": nTotalCount,
"updated_at": time.Now(),
}).Error
if err != nil {
log.Printf("更新任务完成状态失败: %v", err)
return err
}
log.Println("任务完成")
return nil
}
@ -550,7 +602,7 @@ func issueCouponsToUsers(users []UserInfo, erpCouponId []uint32) error {
Value: coupon.Value,
State: 1,
ActiveStart: time.Now(),
ActiveEnd: time.Now().AddDate(0, 0, 7),
ActiveEnd: coupon.ActiveEnd,
RedeemCode: "",
CategoryNumber: coupon.CategoryNumber,
Code: couponCode,
@ -567,12 +619,192 @@ func issueCouponsToUsers(users []UserInfo, erpCouponId []uint32) error {
}
}
// 发送短信或者消息订阅通知
// 发送订阅通知
var wxToken WxAccessToken
err = orm.Eloquent.Table("wx_access_token").Where("appid = ?", WXAppID).First(&wxToken).Error
if err != nil {
logger.Error("query wx_access_token err:", logger.Field("err", err))
}
if wxToken.ID == 0 || wxToken.ExpiresTime.Before(time.Now()) {
CheckAccessToken()
err = orm.Eloquent.Table("wx_access_token").Where("appid = ?", WXAppID).First(&wxToken).Error
if err != nil {
logger.Error("query wx_access_token err:", logger.Field("err", err))
}
}
toUserOpenid := user.WxOpenID
templateId := TemplateId
data := map[string]interface{}{
"thing1": map[string]interface{}{"value": coupons[0].Name},
"thing5": map[string]interface{}{"value": coupons[0].Describe},
"date3": map[string]interface{}{"value": coupons[0].ActiveEnd.Format("2006年01月02日")},
"thing4": map[string]interface{}{"value": coupons[0].Rule},
}
//developer为开发版trial为体验版formal为正式版默认为正式版
_, err = SendMessage(wxToken.AccessToken, toUserOpenid, templateId, data, WxJumpUrl, "trial")
if err != nil {
// 如果订阅通知发送失败,则发送短信
err = GtSendMessage([]string{user.Tel}, erpCoupon[0].SmsContent)
if err != nil {
logger.Error(err.Error())
}
}
}
}
return nil
}
// Response 请求微信返回基础数据
type Response struct {
Errcode int `json:"errcode"`
Errmsg string `json:"errmsg"`
}
// AccessTokenResponse 返回给用户的数据
type AccessTokenResponse struct {
AccessToken string `json:"access_token"` // 获取到的凭证
ExpiresIn int64 `json:"expires_in"` // 凭证有效时间单位秒。目前是7200秒之内的值。
}
type accessTokenResponse struct {
Response
AccessTokenResponse
}
// CheckAccessToken 定期更新access_token
func CheckAccessToken() {
accessToken, err := GetWxAccessToken()
if err != nil {
logger.Error("query wx_access_token err:", logger.Field("err", err))
} else {
now := time.Now()
twoHoursLater := now.Add(2 * time.Hour)
// 查询access_token
var wxToken WxAccessToken
err = orm.Eloquent.Table("wx_access_token").Where("appid = ?", WXAppID).First(&wxToken).Error
if err != nil {
logger.Error("query wx_access_token err:", logger.Field("err", err))
}
if wxToken.ID != 0 { // 更新
// 更新access_token
err = orm.Eloquent.Table("wx_access_token").Where("appid = ?", WXAppID).
Updates(map[string]interface{}{
"access_token": accessToken,
"expires_time": twoHoursLater,
}).Error
if err != nil {
logger.Errorf("更新wx_access_token失败: %v", err)
}
} else { // 插入
tempToken := &WxAccessToken{
Appid: WXAppID,
AccessToken: accessToken.AccessToken,
ExpiresTime: twoHoursLater,
}
err = orm.Eloquent.Create(tempToken).Error
if err != nil {
logger.Error("create wx_access_token err:", logger.Field("err", err))
}
}
}
}
// GetWxAccessToken 获取小程序的access_token
func GetWxAccessToken() (lures AccessTokenResponse, err error) {
api, err := code2url(WXAppID, WXSecret)
if err != nil {
return
}
res, err := http.Get(api)
if err != nil {
return
}
defer res.Body.Close()
if res.StatusCode != 200 {
err = errors.New("微信服务器发生错误")
return
}
var data accessTokenResponse
err = json.NewDecoder(res.Body).Decode(&data)
if err != nil {
return
}
if data.Errcode != 0 {
err = errors.New(data.Errmsg)
return
}
lures = data.AccessTokenResponse
return
}
// 拼接 获取 session_key 的 URL
func code2url(appID, secret string) (string, error) {
url, err := url.Parse(AccessTokenUrl)
if err != nil {
return "", err
}
query := url.Query()
query.Set("appid", appID)
query.Set("secret", secret)
query.Set("grant_type", "client_credential")
url.RawQuery = query.Encode()
return url.String(), nil
}
// SendMessage 发送订阅消息
func SendMessage(accessToken, toUserOpenid, templateId string, data interface{}, page, miniprogramState string) (
[]byte, error) {
url := fmt.Sprintf("%s%s", WxSubscribeMessage, accessToken)
body := map[string]interface{}{
"touser": toUserOpenid,
"template_id": templateId,
"data": data,
"page": page,
"miniprogramState": miniprogramState,
"lang": "zh_CN",
}
rsp, err := HttpRequest(http.MethodPost, url, body)
return rsp, err
}
func HttpRequest(method, url string, reqBody interface{}) ([]byte, error) {
client := http.Client{}
reqBodyBytes, err := json.Marshal(reqBody)
if err != nil {
return nil, err
}
reqBodyReader := bytes.NewReader(reqBodyBytes)
req, err := http.NewRequest(method, url, reqBodyReader)
if err != nil {
return nil, err
}
rsp, err := client.Do(req)
if err != nil {
return nil, err
}
defer rsp.Body.Close()
if rsp.StatusCode != 200 {
return nil, errors.New(fmt.Sprintf("response Status err:%d", rsp.StatusCode))
}
rspBody, err := ioutil.ReadAll(rsp.Body)
if err != nil {
return nil, err
}
return rspBody, nil
}

View File

@ -181,6 +181,13 @@ func run() error {
if err != nil {
fmt.Println("err:", err)
}
// 刷新access_token
err = s.Every(1).Hour().Do(models.CheckAccessToken)
if err != nil {
fmt.Println("err:", err)
}
<-s.Start()
}()

View File

@ -8982,20 +8982,20 @@ const docTemplate = `{
},
"amount": {
"description": "金额(元)",
"type": "number"
"type": "integer"
},
"category_number": {
"description": "可以使用该优惠券的商品分类,如果为空则表示没限制",
"type": "string"
},
"content": {
"description": "优惠内容",
"type": "string"
},
"createdAt": {
"description": "创建时间",
"type": "string"
},
"describe": {
"description": "优惠券简介",
"type": "string"
},
"id": {
"description": "数据库记录编号",
"type": "integer"
@ -9013,15 +9013,27 @@ const docTemplate = `{
"type": "number"
},
"remark": {
"description": "名称备注",
"description": "备注",
"type": "string"
},
"rule": {
"description": "优惠券使用规则",
"type": "string"
},
"send_count": {
"description": "已发放",
"type": "integer"
},
"sms_content": {
"description": "短信提示内容",
"type": "string"
},
"start_time": {
"description": "启动时间",
"type": "string"
},
"state": {
"description": "当前状态 1-未开始2-发放中3-进行中4-已结束",
"description": "当前状态 1-未开始2-发放中3-进行中4-已结束5-发放失败",
"type": "integer"
},
"total_pay_amount": {
@ -9595,14 +9607,14 @@ const docTemplate = `{
},
"amount": {
"description": "金额(元)",
"type": "number"
"type": "integer"
},
"category_number": {
"description": "可以使用该优惠券的商品分类编号,如果为空则表示没限制",
"type": "string"
},
"content": {
"description": "优惠内容/使用说明",
"describe": {
"description": "优惠券简介",
"type": "string"
},
"limit": {
@ -9614,7 +9626,11 @@ const docTemplate = `{
"type": "string"
},
"remark": {
"description": "名称备注",
"description": "备注",
"type": "string"
},
"rule": {
"description": "优惠券使用规则",
"type": "string"
},
"user_type": {
@ -9667,14 +9683,14 @@ const docTemplate = `{
},
"amount": {
"description": "金额(元)",
"type": "number"
"type": "integer"
},
"category_number": {
"description": "可以使用该优惠券的商品分类,如果为空则表示没限制",
"type": "string"
},
"content": {
"description": "优惠内容/使用说明",
"describe": {
"description": "优惠券简介",
"type": "string"
},
"erp_coupon_id": {
@ -9693,6 +9709,10 @@ const docTemplate = `{
"description": "名称备注",
"type": "string"
},
"rule": {
"description": "优惠券使用规则",
"type": "string"
},
"user_type": {
"description": "领取人限制1-所有人 2-未付费用户 3-已付费用户 4-尊享会员",
"type": "integer"
@ -9762,13 +9782,26 @@ const docTemplate = `{
"models.ErpMarketingCouponStartReq": {
"type": "object",
"required": [
"erp_coupon_id"
"erp_coupon_id",
"remark",
"sms_content"
],
"properties": {
"erp_coupon_id": {
"description": "优惠券id",
"type": "array",
"items": {
"type": "integer"
}
},
"remark": {
"description": "活动名称备注",
"type": "string"
},
"sms_content": {
"description": "短信提示内容",
"type": "string"
}
}
},
"models.ErpOrder": {

View File

@ -8971,20 +8971,20 @@
},
"amount": {
"description": "金额(元)",
"type": "number"
"type": "integer"
},
"category_number": {
"description": "可以使用该优惠券的商品分类,如果为空则表示没限制",
"type": "string"
},
"content": {
"description": "优惠内容",
"type": "string"
},
"createdAt": {
"description": "创建时间",
"type": "string"
},
"describe": {
"description": "优惠券简介",
"type": "string"
},
"id": {
"description": "数据库记录编号",
"type": "integer"
@ -9002,15 +9002,27 @@
"type": "number"
},
"remark": {
"description": "名称备注",
"description": "备注",
"type": "string"
},
"rule": {
"description": "优惠券使用规则",
"type": "string"
},
"send_count": {
"description": "已发放",
"type": "integer"
},
"sms_content": {
"description": "短信提示内容",
"type": "string"
},
"start_time": {
"description": "启动时间",
"type": "string"
},
"state": {
"description": "当前状态 1-未开始2-发放中3-进行中4-已结束",
"description": "当前状态 1-未开始2-发放中3-进行中4-已结束5-发放失败",
"type": "integer"
},
"total_pay_amount": {
@ -9584,14 +9596,14 @@
},
"amount": {
"description": "金额(元)",
"type": "number"
"type": "integer"
},
"category_number": {
"description": "可以使用该优惠券的商品分类编号,如果为空则表示没限制",
"type": "string"
},
"content": {
"description": "优惠内容/使用说明",
"describe": {
"description": "优惠券简介",
"type": "string"
},
"limit": {
@ -9603,7 +9615,11 @@
"type": "string"
},
"remark": {
"description": "名称备注",
"description": "备注",
"type": "string"
},
"rule": {
"description": "优惠券使用规则",
"type": "string"
},
"user_type": {
@ -9656,14 +9672,14 @@
},
"amount": {
"description": "金额(元)",
"type": "number"
"type": "integer"
},
"category_number": {
"description": "可以使用该优惠券的商品分类,如果为空则表示没限制",
"type": "string"
},
"content": {
"description": "优惠内容/使用说明",
"describe": {
"description": "优惠券简介",
"type": "string"
},
"erp_coupon_id": {
@ -9682,6 +9698,10 @@
"description": "名称备注",
"type": "string"
},
"rule": {
"description": "优惠券使用规则",
"type": "string"
},
"user_type": {
"description": "领取人限制1-所有人 2-未付费用户 3-已付费用户 4-尊享会员",
"type": "integer"
@ -9751,13 +9771,26 @@
"models.ErpMarketingCouponStartReq": {
"type": "object",
"required": [
"erp_coupon_id"
"erp_coupon_id",
"remark",
"sms_content"
],
"properties": {
"erp_coupon_id": {
"description": "优惠券id",
"type": "array",
"items": {
"type": "integer"
}
},
"remark": {
"description": "活动名称备注",
"type": "string"
},
"sms_content": {
"description": "短信提示内容",
"type": "string"
}
}
},
"models.ErpOrder": {

View File

@ -1728,16 +1728,16 @@ definitions:
type: integer
amount:
description: 金额(元)
type: number
type: integer
category_number:
description: 可以使用该优惠券的商品分类,如果为空则表示没限制
type: string
content:
description: 优惠内容
type: string
createdAt:
description: 创建时间
type: string
describe:
description: 优惠券简介
type: string
id:
description: 数据库记录编号
type: integer
@ -1751,13 +1751,22 @@ definitions:
description: 客单价(元)
type: number
remark:
description: 名称备注
description: 备注
type: string
rule:
description: 优惠券使用规则
type: string
send_count:
description: 已发放
type: integer
sms_content:
description: 短信提示内容
type: string
start_time:
description: 启动时间
type: string
state:
description: 当前状态 1-未开始2-发放中3-进行中4-已结束
description: 当前状态 1-未开始2-发放中3-进行中4-已结束5-发放失败
type: integer
total_pay_amount:
description: 支付金额(元)
@ -2172,12 +2181,12 @@ definitions:
type: integer
amount:
description: 金额(元)
type: number
type: integer
category_number:
description: 可以使用该优惠券的商品分类编号,如果为空则表示没限制
type: string
content:
description: 优惠内容/使用说明
describe:
description: 优惠券简介
type: string
limit:
description: 优惠券叠加限制 0-不限制1-仅限原价购买时使用
@ -2186,7 +2195,10 @@ definitions:
description: 优惠券名称
type: string
remark:
description: 名称备注
description: 备注
type: string
rule:
description: 优惠券使用规则
type: string
user_type:
description: 领取人限制1-所有人 2-未付费用户 3-已付费用户 4-尊享会员
@ -2223,12 +2235,12 @@ definitions:
type: integer
amount:
description: 金额(元)
type: number
type: integer
category_number:
description: 可以使用该优惠券的商品分类,如果为空则表示没限制
type: string
content:
description: 优惠内容/使用说明
describe:
description: 优惠券简介
type: string
erp_coupon_id:
description: 优惠券id
@ -2242,6 +2254,9 @@ definitions:
remark:
description: 名称备注
type: string
rule:
description: 优惠券使用规则
type: string
user_type:
description: 领取人限制1-所有人 2-未付费用户 3-已付费用户 4-尊享会员
type: integer
@ -2300,9 +2315,19 @@ definitions:
properties:
erp_coupon_id:
description: 优惠券id
items:
type: integer
type: array
remark:
description: 活动名称备注
type: string
sms_content:
description: 短信提示内容
type: string
required:
- erp_coupon_id
- remark
- sms_content
type: object
models.ErpOrder:
properties:

BIN
static/导零售.xlsx Normal file

Binary file not shown.