Forráskód Böngészése

feat:双十二抽奖定时任务

fuwencai 2 éve
szülő
commit
e2f4dc4d6b
3 módosított fájl, 183 hozzáadás és 17 törlés
  1. 15 5
      config/config.go
  2. 14 4
      etc/config.yaml
  3. 154 8
      task/ordermonitor.go

+ 15 - 5
config/config.go

@@ -69,11 +69,21 @@ type pushConfig struct {
 }
 
 type OrderMonitorConfig struct {
-	DateSpecial       string // 特别奖品活动日期
-	OpenCron          string // 每天开启订单查询的任务
-	SelectCron        string // 每5分钟查询一次
-	WinNumberDaily    int    // 每天第xx个付款获得奖品
-	WinNumbersSpecial int    // 第xxx个付款获得特殊奖品
+	DateSpecial       string     // 特别奖品活动日期
+	OpenCron          string     // 每天开启订单查询的任务
+	SelectCron        string     // 每5分钟查询一次
+	WinNumberDaily    int        // 每天第xx个付款获得奖品
+	WinNumbersSpecial int        // 第xxx个付款获得特殊奖品
+	Switch            bool       // 是否开启定时任务
+	ActivityMode      int        //  # 1. 每天第多少名  2. 活动期间内一共第多少名(双十二)
+	Rules             []struct { // 双十二活动规则
+		WinNum     []int    // 获奖的下单顺序
+		Mold       int      // 奖品 3 免单
+		Products   []string // # 参加活动的产品
+		PriceLimit bool     // 是否有实付金额限制
+		PriceStart int      // 实付金额最低  单位(分)
+		PriceEnd   int      // 实付金额最高  单位(分)
+	}
 }
 
 //var Config *config

+ 14 - 4
etc/config.yaml

@@ -75,7 +75,7 @@ jyactivity: # 临时活动
   dateRange: #活动时间
     t1: 2022-05-25 00:00:00 #预热活动
     t2: 2022-10-19 00:00:00 #活动开始
-    ed: 2022-11-12 00:00:00 #活动结束
+    ed: 2022-11-22 00:00:00 #活动结束
   missions: #任务列表
     buysubvip: #购买超级订阅
       points: 800
@@ -111,9 +111,19 @@ productCode:
   subscriptionYear: 1014
 
 # 订单监控
-orderMonitor :
+orderMonitor:
   dateSpecial: 2022-10-19         # 特殊奖品活动日期 (第111名活动日期)
   openCron: "0 0 6 * * *"         # 每天6点开启
-  selectCron: "0 */5 6-22 * * *"    # 查询订单的表达式  6点到22点 每五分钟查询一次
+  selectCron: "0 */2 * * * *"    # 查询订单的表达式  6点到22点 每五分钟查询一次
   winNumberDaily: 11       # 每天第xx个付款获得奖品1
-  winNumbersSpecial: 111   # 第xxx个付款获得特殊奖品
+  winNumbersSpecial: 111   # 第xxx个付款获得特殊奖品
+
+  switch: true  # 是否开启定时任务
+  activityMode: 2  # 1. 每天第多少名  2. 活动期间内一共第多少名(双十二)
+  rules:
+    - winNum: [ 2,12,22,122,1212,2222 ] # 活动期间第XXX,XXX个支付中奖
+      mold: 3 # 3 免单
+      products: [ vip订阅,数据流量包 ] # 参加活动的产品
+      priceLimit: true  # 是否有实付金额限制
+      priceStart: 30000 # 实付金额最低  单位 分
+      priceEnd: 100000  # 实付金额最高 单位分

+ 154 - 8
task/ordermonitor.go

@@ -1,17 +1,20 @@
 package task
 
 import (
+	"app.yhyue.com/moapp/jybase/common"
 	"app.yhyue.com/moapp/jybase/date"
 	"app.yhyue.com/moapp/jybase/go-logger/logger"
 	"app.yhyue.com/moapp/message/config"
 	"app.yhyue.com/moapp/message/db"
 	"app.yhyue.com/moapp/message/handler/activity"
 	"context"
+	"encoding/json"
 	"fmt"
 	"github.com/gogf/gf/v2/os/gcfg"
 	"github.com/gogf/gf/v2/os/gcron"
 	"github.com/gogf/gf/v2/os/gctx"
 	"github.com/gogf/gf/v2/os/gtime"
+	"strings"
 	"time"
 )
 
@@ -19,12 +22,15 @@ const (
 	TableWinnerInfo2210 = "winner_info_22_10"
 	Mold1               = "1" // 中奖类型 1:小米智能音响
 	Mold2               = "2" // 中奖类型 2:ipad
+	ActivityMode1       = 1   // 双十一
+	ActivityMode2       = 2   // 双十二
 
 )
 
 var (
-	flag          = false // 是否已经查询到
-	monitorConfig config.OrderMonitorConfig
+	flag           = false // 是否已经查询到
+	monitorConfig  config.OrderMonitorConfig
+	ruleWinNumFlag = []map[int]struct{}{}
 )
 
 func init() {
@@ -35,6 +41,13 @@ func init() {
 		SelectCron:        gcfg.Instance().MustGet(gctx.New(), "orderMonitor.selectCron").String(),
 		WinNumberDaily:    gcfg.Instance().MustGet(gctx.New(), "orderMonitor.winNumberDaily").Int(),
 		WinNumbersSpecial: gcfg.Instance().MustGet(gctx.New(), "orderMonitor.winNumbersSpecial").Int(),
+		Switch:            gcfg.Instance().MustGet(gctx.New(), "orderMonitor.switch").Bool(),
+		ActivityMode:      gcfg.Instance().MustGet(gctx.New(), "orderMonitor.activityMode").Int(),
+	}
+	rules, _ := gcfg.Instance().MustGet(gctx.New(), "orderMonitor.rules").MarshalJSON()
+	err := json.Unmarshal(rules, &monitorConfig.Rules)
+	if err != nil {
+		panic("加载活动规则配置失败")
 	}
 }
 
@@ -49,7 +62,21 @@ func SelectOrderTask() {
 		ctx = gctx.New()
 	)
 	// 订单查询任务
-	_, err = gcron.Add(ctx, monitorConfig.SelectCron, monitor, "selectJob")
+	switch monitorConfig.ActivityMode {
+	case ActivityMode1: // 双十一活动的模式 每天的第多少名
+		_, err = gcron.Add(ctx, monitorConfig.SelectCron, monitor, "selectJob")
+	case ActivityMode2: // 活动期间的第多少名
+		// 初始化
+		for i := 0; i < len(monitorConfig.Rules); i++ {
+			rule := monitorConfig.Rules[i]
+			tmp := map[int]struct{}{}
+			for j := 0; j < len(rule.WinNum); j++ {
+				tmp[rule.WinNum[j]] = struct{}{}
+			}
+			ruleWinNumFlag = append(ruleWinNumFlag, tmp)
+		}
+		_, err = gcron.Add(ctx, monitorConfig.SelectCron, monitorMode2, "selectJob")
+	}
 	if err != nil {
 		logger.Error("定时任务selectJob添加失败", err)
 	}
@@ -65,13 +92,16 @@ func SelectOrderTask() {
 			logger.Info("活动结束,移除任务")
 			gcron.Remove("openCronJob")
 			gcron.Remove("selectJob")
+			return
 		}
 		// 活动时间范围内 开启订单查询的定时任务
 		_, inTime, _ := activity.MembershipDay.InActivity()
 		if inTime {
-			flag = false // 重置
-			gcron.Start("selectJob")
-			logger.Info("开启 selectJob 任务")
+			if gcron.Search("selectJob").Status() != gcron.StatusRunning {
+				flag = false // 重置
+				gcron.Start("selectJob")
+				logger.Info("开启 selectJob 任务")
+			}
 		}
 	}, "openCronJob")
 	if err != nil {
@@ -80,7 +110,7 @@ func SelectOrderTask() {
 	logger.Info("openCronJob 启动成功")
 }
 
-//  订单监控
+//  订单监控 双十一 查询活动期间的每天的第多少名
 func monitor(ctx context.Context) {
 	logger.Info("开始本轮订单查询")
 	_, inTime, _ := activity.MembershipDay.InActivity()
@@ -142,6 +172,68 @@ func monitor(ctx context.Context) {
 	}
 }
 
+// 双十二活动  查询活动期间的第多少名
+func monitorMode2(ctx context.Context) {
+	logger.Info("开始本轮订单查询")
+	_, inTime, _ := activity.MembershipDay.InActivity()
+	if inTime {
+		needSelect := false
+		// 遍历活动抽奖规则
+		for i := 0; i < len(monitorConfig.Rules); i++ {
+			rules := monitorConfig.Rules[i]
+			if len(ruleWinNumFlag[i]) == 0 {
+				continue
+			}
+			// 遍历中奖顺序
+			for _, num := range rules.WinNum {
+				if _, ok := ruleWinNumFlag[i][num]; !ok {
+					continue
+				}
+				rs := selectOrder2(num, rules.Products, rules.PriceLimit, rules.PriceStart, rules.PriceEnd, date.FormatDate(&activity.MembershipDay.T2, date.Date_Short_Layout), date.FormatDate(&activity.MembershipDay.Ed, date.Date_Short_Layout))
+				if len(rs) == 0 {
+					logger.Info(num, "未查到")
+					continue
+					//break // 如果没有查询到 等待下一轮任务再查询
+				}
+				logger.Info(num, "查到")
+				data := map[string]interface{}{
+					"phone":      rs["user_phone"],
+					"userid":     rs["user_id"],
+					"winnerdate": rs["pay_time"],
+					"mold":       rules.Mold,
+					"createdate": date.NowFormat(date.Date_Full_Layout),
+					"ordercode":  rs["order_code"],
+				}
+				if existOrderWinnerInfo(common.ObjToString(rs["order_code"])) {
+					// 删除查找的key
+					delete(ruleWinNumFlag[i], num)
+					logger.Info("该订单中奖信息重复保存", data)
+				} else {
+					// 存库
+					if saveWinnerInfo(data) {
+						logger.Info("保存成功", data)
+						// 删除查找的key
+						delete(ruleWinNumFlag[i], num)
+					} else {
+						logger.Info("保存失败", data)
+					}
+				}
+			}
+			if len(ruleWinNumFlag[i]) > 0 {
+				// 存在未查询到的
+				logger.Info(ruleWinNumFlag[i])
+				needSelect = true
+			}
+		}
+		if !needSelect {
+			//  不用再找了 结束任务
+			gcron.Remove("selectJob")
+			gcron.Remove("openCronJob")
+			logger.Info("结束了")
+		}
+	}
+}
+
 // 查订单表
 func selectOrder(num int) map[string]interface{} {
 	sql := `SELECT
@@ -171,12 +263,66 @@ LIMIT ?,1
 	return nil
 }
 
+// 查询活动期间指定支付顺序的订单
+func selectOrder2(num int, productType []string, priceLimit bool, priceStart, priceEnd int, startTime, endTime string) map[string]interface{} {
+	var products []string
+	var values []interface{}
+	productTypeStr := "" // 产品类型
+	priceLimitStr := ""  // 价格限制
+	values = append(values, startTime, endTime)
+	// 拼接产品类型
+	if len(productType) > 0 {
+		for i := 0; i < len(productType); i++ {
+			products = append(products, "?")
+			values = append(values, productType[i])
+		}
+		productTypeStr = fmt.Sprintf(" and product_type IN (%s) ", strings.Join(products, ","))
+	}
+	// 拼接价格限制
+	if priceLimit {
+		if priceStart != 0 {
+			priceLimitStr = " and pay_money>=? "
+			values = append(values, priceStart)
+		}
+		if priceEnd != 0 {
+			priceLimitStr += " and pay_money<=? "
+			values = append(values, priceEnd)
+		}
+	}
+	values = append(values, num-1)
+	sql := `SELECT
+        order_code,
+        user_phone,
+        user_id,
+        pay_time
+FROM
+        dataexport_order
+WHERE order_status = 1 and create_time >=? and create_time<?` + productTypeStr +
+		priceLimitStr + ` AND is_backstage_order = 0
+ ORDER BY pay_time  LIMIT ?,1`
+	rs := db.Mysql.SelectBySql(sql, values...)
+	logger.Info(sql, values)
+	if rs != nil && len(*rs) == 1 {
+		return (*rs)[0]
+	}
+	logger.Info("未查到", rs)
+	return nil
+}
+
 // 保存中奖人员信息
 func saveWinnerInfo(data map[string]interface{}) bool {
 	logger.Info("save winner info ")
 	return db.Mysql.Insert(TableWinnerInfo2210, data) > 0
 }
+
+// 当天是否已经保存过中奖信息
 func existWinnerInfo() bool {
-	logger.Info("save winner info ")
+	logger.Info("select winner info ")
 	return db.Mysql.CountBySql("SELECT count(id) as count FROM jianyu.winner_info_22_10 where TO_DAYS(createdate) = TO_DAYS(NOW());") > 0
 }
+
+// 中奖订单号是否已经保存过
+func existOrderWinnerInfo(orderCode string) bool {
+	logger.Info("select order winner info ")
+	return db.Mysql.CountBySql("SELECT count(id) as count FROM jianyu.winner_info_22_10 where ordercode = ?", orderCode) > 0
+}