123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- 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/jybase/redis"
- "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"
- )
- const (
- TableWinnerInfo2210 = "winner_info_22_10"
- Mold1 = "1" // 中奖类型 1:小米智能音响
- Mold2 = "2" // 中奖类型 2:ipad
- ActivityMode1 = 1 // 双十一
- ActivityMode2 = 2 // 双十二
- )
- var (
- flag = false // 是否已经查询到
- monitorConfig config.OrderMonitorConfig
- ruleWinNumFlag []map[int]struct{}
- )
- func init() {
- // 获取配置信息
- monitorConfig = config.OrderMonitorConfig{
- DateSpecial: date.FormatDate(>ime.NewFromStrLayout(gcfg.Instance().MustGet(gctx.New(), "orderMonitor.dateSpecial").String(), "2006-01-02T15:04:05Z").Time, date.Date_Short_Layout),
- OpenCron: gcfg.Instance().MustGet(gctx.New(), "orderMonitor.openCron").String(),
- 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("加载活动规则配置失败")
- }
- }
- // SelectOrderTask 订单监控
- func SelectOrderTask() {
- if !monitorConfig.Switch {
- logger.Info("订单监控开关未打开,不再启动定时任务")
- return
- }
- // 活动已结束 不再启动定时任务
- if time.Now().After(activity.MembershipDay.Ed) {
- logger.Info("活动时间已结束,不再启动定时任务")
- return
- }
- var (
- err error
- ctx = gctx.New()
- )
- // 订单查询任务
- switch monitorConfig.ActivityMode {
- case ActivityMode1: // 双十一活动的模式 每天的第多少名
- _, err = gcron.Add(ctx, monitorConfig.SelectCron, monitor, "selectJob")
- logger.Info("add selectJob 1")
- 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)
- }
- logger.Info("初始化待查询的获奖顺序到内存")
- _, err = gcron.Add(ctx, monitorConfig.SelectCron, monitorMode2, "selectJob")
- logger.Info("add selectJob 2")
- }
- if err != nil {
- logger.Error("定时任务selectJob添加失败", err)
- return
- }
- if time.Now().Before(activity.MembershipDay.T2) { // 活动未开始
- gcron.Stop("selectJob") // 停掉订单查询任务 等后边的定时任务开启
- logger.Info("活动还未开始,暂停查询任务 selectJob stop")
- }
- // 开启定时开启任务
- _, err = gcron.Add(ctx, monitorConfig.OpenCron, func(ctx context.Context) {
- now := time.Now()
- if now.After(activity.MembershipDay.Ed) { // 活动已结束 移除掉任务
- logger.Info("活动结束,移除任务")
- gcron.Remove("openCronJob")
- gcron.Remove("selectJob")
- return
- }
- // 活动时间范围内 开启订单查询的定时任务
- _, inTime, _ := activity.MembershipDay.InActivity()
- if inTime {
- if gcron.Search("selectJob").Status() == gcron.StatusStopped {
- flag = false // 重置
- gcron.Start("selectJob")
- logger.Info("开启 selectJob 任务")
- }
- }
- }, "openCronJob")
- if err != nil {
- logger.Error("定时任务openCronJob失败", err)
- }
- logger.Info("openCronJob 启动成功")
- }
- // 订单监控 双十一 查询活动期间的每天的第多少名
- func monitor(ctx context.Context) {
- logger.Info("开始本轮订单查询")
- _, inTime, _ := activity.MembershipDay.InActivity()
- if inTime {
- // 如果需要查第111个 日期范围内 特殊日期
- if date.NowFormat(date.Date_Short_Layout) == monitorConfig.DateSpecial {
- logger.Info(fmt.Sprintf("开始查询第%v个人员", monitorConfig.WinNumbersSpecial))
- rs111 := selectOrder(monitorConfig.WinNumbersSpecial)
- if rs111 != nil {
- logger.Info(fmt.Sprintf("查询到第%v个人员", monitorConfig.WinNumbersSpecial))
- saveData := map[string]interface{}{
- "phone": rs111["user_phone"],
- "userid": rs111["user_id"],
- "winnerdate": rs111["pay_time"],
- "mold": Mold2,
- "createdate": date.NowFormat(date.Date_Full_Layout),
- }
- if existWinnerInfo() {
- logger.Info("当日已存在中奖信息")
- flag = true
- } else {
- if saveWinnerInfo(saveData) {
- flag = true
- logger.Info("中奖信息保存成功:", saveData)
- } else {
- logger.Error("中奖信息保存失败:", saveData)
- }
- }
- }
- } else {
- rs := selectOrder(monitorConfig.WinNumberDaily)
- if rs != nil { // 查到了
- logger.Info(fmt.Sprintf("查询到第%d个人员", monitorConfig.WinNumberDaily))
- data := map[string]interface{}{
- "phone": rs["user_phone"],
- "userid": rs["user_id"],
- "winnerdate": rs["pay_time"],
- "mold": Mold1,
- "createdate": date.NowFormat(date.Date_Full_Layout),
- }
- if existWinnerInfo() {
- logger.Info("当日已存在中奖信息")
- flag = true
- } else {
- if saveWinnerInfo(data) {
- flag = true
- logger.Info("中奖信息保存成功:", data)
- } else {
- logger.Error("中奖信息保存失败:", data)
- }
- }
- }
- }
- if flag {
- logger.Info("今日已查询到 暂停任务")
- gcron.Stop("selectJob")
- logger.Info("selectJob stop")
- }
- }
- }
- // 双十二活动 查询活动期间的第多少名
- func monitorMode2(ctx context.Context) {
- logger.Info("开始本轮订单查询")
- if time.Now().Before(activity.MembershipDay.T2) { // 活动未开始
- logger.Info("当前时间不在活动时间范围内")
- return
- }
- 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 { // 不在待查询的map中
- continue
- }
- rs := selectOrder2(num, rules.Products, rules.PriceLimit, rules.PriceStart, rules.PriceEnd, date.FormatDate(&activity.MembershipDay.T2, date.Date_Full_Layout), date.FormatDate(&activity.MembershipDay.Ed, date.Date_Full_Layout))
- if len(rs) == 0 {
- 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)
- delete(ruleWinNumFlag[i], num) // 从待查找的key中删除
- } else {
- logger.Info("保存失败", data)
- }
- }
- }
- if len(ruleWinNumFlag[i]) > 0 {
- logger.Info(ruleWinNumFlag[i])
- needSelect = true // 存在未查询到的 定时任务不用关闭
- }
- }
- if time.Now().After(activity.MembershipDay.Ed) { // 活动已结束
- logger.Info("活动已结束")
- needSelect = false
- }
- if !needSelect { // 不用再找了 结束任务
- gcron.Remove("selectJob")
- gcron.Remove("openCronJob")
- logger.Info("结束了")
- }
- }
- // 查订单表
- func selectOrder(num int) map[string]interface{} {
- sql := `SELECT
- order_code,
- user_phone,
- user_id,
- pay_time
- FROM
- dataexport_order
- WHERE order_status = 1 and
- product_type IN (
- "VIP订阅",
- "大会员",
- "数据流量包"
- )
- AND is_backstage_order = 0 and pay_time is not null
- AND TO_DAYS(pay_time) = to_days(now())
- ORDER BY
- pay_time
- LIMIT ?,1
- `
- rs := db.Mysql.SelectBySql(sql, num-1)
- if rs != nil && len(*rs) == 1 {
- return (*rs)[0]
- }
- logger.Info("未查到", rs)
- 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 pay_time >=? and pay_time<?` + productTypeStr +
- priceLimitStr + ` AND is_backstage_order = 0 and pay_time is not null
- ORDER BY pay_time LIMIT ?,1`
- rs := db.Mysql.SelectBySql(sql, values...)
- if rs != nil && len(*rs) == 1 {
- return (*rs)[0]
- }
- logger.Info(num, "未查到", rs)
- return nil
- }
- // 保存中奖人员信息
- func saveWinnerInfo(data map[string]interface{}) bool {
- // 清缓存
- redis.Del(activity.BidderPlanRedis, activity.WinnerInfoKey)
- logger.Info("save winner info ")
- return db.Mysql.Insert(TableWinnerInfo2210, data) > 0
- }
- // 当天是否已经保存过中奖信息
- func existWinnerInfo() bool {
- 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
- }
|