diff --git a/app/cfg/init_task.go b/app/cfg/init_task.go index 0eec20e..efa0365 100644 --- a/app/cfg/init_task.go +++ b/app/cfg/init_task.go @@ -28,6 +28,7 @@ func InitTaskCfg() { Debug = conf.Debug DB = &conf.DB Log = &conf.Log + MQ = &conf.MQ RedisAddr = conf.RedisAddr } diff --git a/app/hdl/hdl_callback_advertising.go b/app/hdl/hdl_callback_advertising.go new file mode 100644 index 0000000..dc2919d --- /dev/null +++ b/app/hdl/hdl_callback_advertising.go @@ -0,0 +1,86 @@ +package hdl + +import ( + "applet/app/db" + "applet/app/md" + "applet/app/utils" + "code.fnuoos.com/EggPlanet/egg_models.git/src/implement" + "code.fnuoos.com/EggPlanet/egg_models.git/src/model" + "code.fnuoos.com/go_rely_warehouse/zyos_go_mq.git/rabbit" + "crypto/sha256" + "encoding/json" + "github.com/gin-gonic/gin" + "github.com/tidwall/gjson" + "strings" +) + +func CallbackChuanshanjia(c *gin.Context) { + userId := c.Query("user_id") + transId := c.Query("trans_id") + primeRit := c.Query("prime_rit") + sign := c.Query("sign") + extra := c.Query("extra") + id := gjson.Get(extra, "id").String() + types := gjson.Get(extra, "type").String() + phonePlatform := strings.ToLower(gjson.Get(extra, "platform").String()) + platform := "chuanshanjia" + NewAdvertisingSpaceDb := implement.NewAdvertisingSpaceDb(db.Db) + space, _ := NewAdvertisingSpaceDb.GetAdvertisingSpace(id) + if space == nil { + c.String(200, "{\"is_verify\":true,\"reason\":20000}") + return + } + spaceData := gjson.Get(space.Info, platform+"."+phonePlatform+"_ad_id").String() + spaceList := make([]map[string]string, 0) + json.Unmarshal([]byte(spaceData), &spaceList) + spaceKey := "" + for _, v := range spaceList { + if v["id"] == primeRit { //找到对应广告位的key + spaceKey = v["key"] + } + } + keyStr := spaceKey + ":" + transId + h := sha256.New() + //写入数据:将字符串 s 转换为字节切片并写入哈希对象 h。这一步是计算哈希的关键。 + h.Write([]byte(keyStr)) + //计算哈希值:h.Sum(nil) 计算当前哈希值并返回一个字节切片 bs。传入 nil 表示不需要额外的字节切片来存储结果。 + bs := h.Sum(nil) + if string(bs) != sign { + c.String(200, "{\"is_verify\":true,\"reason\":50002}") + return + } + exist, _ := db.Db.Where("platform=? and oid=?", platform, transId).Exist(&model.AdvertisingCallback{}) + if exist { + c.String(200, "{\"is_verify\":true,\"reason\":20000}") + return + } + var tmp = model.AdvertisingCallback{ + Platform: platform, + Oid: transId, + Uid: utils.StrToInt(userId), + Extra: extra, + SpaceId: primeRit, + } + db.Db.Insert(&tmp) + // 写入mq处理 + ch, err := rabbit.Cfg.Pool.GetChannel() + if err == nil { + defer ch.Release() + } + if types == "incentive_eggSmash" { //首页砸蛋 + arg := md.AdvertisingWatch{Id: utils.IntToStr(tmp.Id)} + err := ch.PublishV2(md.EggAdvertisingQueueExchange, arg, md.EggAdvertisingSmash) + if err != nil { + ch.PublishV2(md.EggAdvertisingQueueExchange, arg, md.EggAdvertisingSmash) + } + } + if types == "incentive_eggSign" { //首页签到 + arg := md.AdvertisingWatch{Id: utils.IntToStr(tmp.Id)} + err := ch.PublishV2(md.EggAdvertisingQueueExchange, arg, md.EggAdvertisingSign) + if err != nil { + ch.PublishV2(md.EggAdvertisingQueueExchange, arg, md.EggAdvertisingSign) + } + } + c.String(200, "{\"is_verify\":true,\"reason\":20000}") + return +} diff --git a/app/hdl/hdl_login.go b/app/hdl/hdl_login.go index c030eb9..2ff11bb 100644 --- a/app/hdl/hdl_login.go +++ b/app/hdl/hdl_login.go @@ -160,6 +160,7 @@ func WechatLogin(c *gin.Context) { userModel.LastLoginIp = utils.GetIP(c.Request) userModel.UpdateAt = now.Format("2006-01-02 15:04:05") newUserDb.UpdateUser(userModel, "open_id,avatar,nickname,last_login_ip,last_login_at,update_at") + svc.UserImeiAdd(c, userModel.Id) token, err = svc.HandleLoginToken(userModel) if err != nil { e.OutErr(c, e.ERR, err.Error()) @@ -441,7 +442,6 @@ func commReq(c *gin.Context, req md.RegisterReq) { return } svc.UserImeiAdd(c, user.Id) - e.OutSuc(c, md.LoginResponse{ Token: token, }, nil) diff --git a/app/hdl/hdl_user.go b/app/hdl/hdl_user.go index 20c0376..bc1d228 100644 --- a/app/hdl/hdl_user.go +++ b/app/hdl/hdl_user.go @@ -7,6 +7,7 @@ import ( "applet/app/svc" "applet/app/utils" "code.fnuoos.com/EggPlanet/egg_models.git/src/implement" + "code.fnuoos.com/EggPlanet/egg_models.git/src/model" "github.com/gin-gonic/gin" "github.com/syyongx/php2go" ) @@ -153,6 +154,20 @@ func UserBindParent(c *gin.Context) { e.OutErr(c, 400, e.NewErr(400, "绑定失败,请重试")) return } + initLV := 1 + ur := new(model.UserRelate) + ur.ParentUid = user.Id + ur.Uid = ownUser.Id + ur.Level = initLV + ur.InviteTime = ownUser.CreateAt + userRelateDb := implement.NewUserRelateDb(db.Db) + _, err = userRelateDb.UserRelateInsert(ur) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err) + return + } + // 插入多级关联 + go svc.RoutineMultiRelate(ur.ParentUid, ur.Uid, initLV) //TODO 绑定成功后 加群之类的怎么处理 e.OutSuc(c, "success", nil) return diff --git a/app/md/md_mq.go b/app/md/md_mq.go index 7725347..b5ef86e 100644 --- a/app/md/md_mq.go +++ b/app/md/md_mq.go @@ -2,7 +2,10 @@ package md const ( EggJpushRecordQueueExchange = "egg.jpush" + EggAdvertisingQueueExchange = "egg.advertising" EggJpushRecordQueue = "jpush_record" + EggAdvertisingSmash = "advertising_smash" + EggAdvertisingSign = "advertising_sign" EggAliyunSmsRecordQueueExchange = "egg.aliyun_sms" EggAliyunSmsRecordQueue = "aliyun_sms_record" ) @@ -23,3 +26,6 @@ type AliyunSmsRecordFundData struct { Code string `json:"code"` Extra string `json:"extra"` } +type AdvertisingWatch struct { + Id string `json:"id"` +} diff --git a/app/router/router.go b/app/router/router.go index adb5e72..b40d378 100644 --- a/app/router/router.go +++ b/app/router/router.go @@ -54,6 +54,11 @@ func route(r *gin.RouterGroup) { r.Any("/createSign", hdl.CreateSign) r.Any("/aesDecryptByECB", hdl.AesDecryptByECB) r.GET("/article/html", hdl.ArticleHtml) //H5渲染的文章 + rCallback := r.Group("/callback") + { + rCallback.GET("/advertising/chuanshanjia", hdl.CallbackChuanshanjia) //穿山甲广告回调 + } + r.Use(mw.CheckSign) r.Any("/testCreateSign", hdl.TestCreateSign) r.GET("/openApp/start", hdl.Start) //打开app调用 diff --git a/app/svc/svc_common.go b/app/svc/svc_common.go index 1141349..449f32b 100644 --- a/app/svc/svc_common.go +++ b/app/svc/svc_common.go @@ -71,8 +71,31 @@ func UserImeiAdd(c *gin.Context, uid int64) { user.LastLoginAt = time.Now().Format("2006-01-02 15:04:05") user.LastLoginIp = c.ClientIP() db.Db.Where("id=?", user.Id).Cols("last_login_at,last_login_ip").Update(user) + UpdateUserTime(user.Id, "login") + } +} +func UpdateUserTime(uid int64, types string) { + count, _ := db.Db.Where("uid=?", uid).Count(&model.UserNoticeTime{}) + if count == 0 { + tmp := &model.UserNoticeTime{Uid: int(uid)} + if types == "login" { + tmp.LoginTime = int(time.Now().Unix()) + } else { + tmp.SignTime = int(time.Now().Unix()) + } + db.Db.Insert(tmp) + } else { + tmp := &model.UserNoticeTime{} + str := "" + if types == "login" { + str = "login_time" + tmp.LoginTime = int(time.Now().Unix()) + } else { + str = "sign_time" + tmp.SignTime = int(time.Now().Unix()) + } + db.Db.Where("uid=?", uid).Cols(str).Update(tmp) } - } // GetYearsAndWeekStr 获取年份和周数 diff --git a/app/task/init.go b/app/task/init.go index 7a07305..dee4b35 100644 --- a/app/task/init.go +++ b/app/task/init.go @@ -92,7 +92,6 @@ func initTasks() { jobs[taskMd.CronEggEnergyDealFundData] = taskEggEnergyDealFundData jobs[taskMd.AliyunSmsRecord] = taskAliyunSmsRecord //阿里云短信 jobs[taskMd.JpushRecord] = taskJpushRecord //极光推送 - - jobs[taskMd.NoLoginSend] = taskNoLoginSend //推送 或短信给 X小时没登陆的用户 - jobs[taskMd.NoSignSend] = taskNoSignSend //推送 或短信给 X小时没签到的用户 + jobs[taskMd.NoLoginSend] = taskNoLoginSend //推送 或短信给 X小时没登陆的用户 + jobs[taskMd.NoSignSend] = taskNoSignSend //推送 或短信给 X小时没签到的用户 } diff --git a/app/task/svc/svc_no_login_send.go b/app/task/svc/svc_no_login_send.go index e955b06..aaea451 100644 --- a/app/task/svc/svc_no_login_send.go +++ b/app/task/svc/svc_no_login_send.go @@ -3,10 +3,12 @@ package svc import ( "applet/app/db" "applet/app/md" + "applet/app/utils" "applet/app/utils/cache" "code.fnuoos.com/EggPlanet/egg_models.git/src/model" "code.fnuoos.com/go_rely_warehouse/zyos_go_mq.git/rabbit" "fmt" + "strings" "time" "xorm.io/xorm" ) @@ -27,67 +29,49 @@ func NoLoginSend(eg *xorm.Engine) { } cache.SetEx(key, PessimismLockValue, 3600*8) //8小时 notice := make([]model.JpushNotice, 0) - eg.Where("type='login' and is_show=1").Desc("day").Find(¬ice) - sms := make([]model.AliyunSmsNotice, 0) - eg.Where("type='login' and is_show=1").Desc("day").Find(&sms) - - //tmp := make(map[string]map[string]string) - //for _,v:=range notice{ - // - //} - - now := time.Now().Unix() + err = eg.Where("type='login' and (jpush_open=1 or sms_open=1)").Desc("day").Find(¬ice) + fmt.Println(err) for _, v := range notice { - commNoLoginSend(eg, ch, 1, v.Title, v.Content, time.Unix(now-int64(v.Day)*3600, 0).Format("2006-01-02 15:04:05"), time.Unix(now-int64(v.NoticeDay)*3600, 0).Format("2006-01-02 15:04:05")) + commNoLoginSend(eg, ch, 1, v) } cache.Del(key) } -func commNoLoginSend(eg *xorm.Engine, ch *rabbit.Channel, p int, title, content, lastLoginAt, loginNoticeTime string) { +func commNoLoginSend(eg *xorm.Engine, ch *rabbit.Channel, p int, data model.JpushNotice) { + now := time.Now().Unix() + lastLoginAt := now - int64(data.Day)*3600 + loginNoticeTime := now - int64(data.NoticeDay)*3600 sql := ` -SELECT u.id,u.phone,unt.id as unt_id FROM user u -LEFT JOIN user_notice_time unt on u.id=unt.uid -WHERE u.last_login_at<'%s' and unt.login_notice_time<'%s' +SELECT u.id,u.phone,u.nickname,unt.id as unt_id,unt.login_time,unt.login_notice_time FROM user_notice_time unt +LEFT JOIN user u on u.id=unt.uid +WHERE unt.login_time<'%d' and unt.login_notice_time<'%d' and unt.login_time>0 %s ` - sql = fmt.Sprintf(sql, lastLoginAt, loginNoticeTime) + sql = fmt.Sprintf(sql, lastLoginAt, loginNoticeTime, "limit "+utils.IntToStr((p-1)*1000)+",1000") userList, _ := db.QueryNativeString(eg, sql) - uids := "" - phones := "" if len(userList) == 0 { return } - //TODO - extra := "{\"content\":\"" + "" + "\"}" + extra := "" for _, v := range userList { - if uids == "" { - phones += v["phone"] - uids += v["id"] - } else { - phones += "," + v["phone"] - uids += "," + v["id"] - } - eg.Where("id=?", v["unt_id"]).Cols("login_notice_time").Update(&model.UserNoticeTime{LoginNoticeTime: time.Now()}) - } - if uids == "" && phones == "" { - return - } - if uids != "" { - //TODO 替换数据 - arg := md.JpushRecordFundData{UserId: uids, Target: "1", Platform: "all", Title: title, Content: content} + hour := (now - utils.StrToInt64(v["login_time"])) / 3600 + data.Content = strings.ReplaceAll(data.Content, "{昵称}", v["nickname"]) + data.Content = strings.ReplaceAll(data.Content, "{手机号}", v["phone"]) + data.Content = strings.ReplaceAll(data.Content, "{小时}", utils.Int64ToStr(hour)) + extra = "{\"hour\":\"" + utils.Int64ToStr(hour) + "\",\"name\":\"" + v["name"] + "\",\"phone\":\"" + v["phone"] + "\"}" + arg := md.JpushRecordFundData{UserId: v["id"], Target: "1", Platform: "all", Title: data.Title, Content: data.Content} err := ch.PublishV2(md.EggJpushRecordQueueExchange, arg, md.EggJpushRecordQueue) if err != nil { ch.PublishV2(md.EggJpushRecordQueueExchange, arg, md.EggJpushRecordQueue) } - } - if phones != "" { - arg := md.AliyunSmsRecordFundData{Phone: phones, Title: title, Content: content, Code: content, Extra: extra} - err := ch.PublishV2(md.EggAliyunSmsRecordQueueExchange, arg, md.EggAliyunSmsRecordQueue) + arg1 := md.AliyunSmsRecordFundData{Phone: v["phone"], Title: data.Title, Content: data.Content, Code: data.SmsCode, Extra: extra} + err = ch.PublishV2(md.EggAliyunSmsRecordQueueExchange, arg1, md.EggAliyunSmsRecordQueue) if err != nil { - ch.PublishV2(md.EggAliyunSmsRecordQueueExchange, arg, md.EggAliyunSmsRecordQueue) + ch.PublishV2(md.EggAliyunSmsRecordQueueExchange, arg1, md.EggAliyunSmsRecordQueue) } + eg.Where("id=?", v["unt_id"]).Cols("login_notice_time").Update(&model.UserNoticeTime{LoginNoticeTime: int(time.Now().Unix())}) } if len(userList) == 1000 { p++ - commNoLoginSend(eg, ch, p, title, content, lastLoginAt, loginNoticeTime) + commNoLoginSend(eg, ch, p, data) return } return diff --git a/app/task/svc/svc_no_sign_send.go b/app/task/svc/svc_no_sign_send.go new file mode 100644 index 0000000..c675e2e --- /dev/null +++ b/app/task/svc/svc_no_sign_send.go @@ -0,0 +1,78 @@ +package svc + +import ( + "applet/app/db" + "applet/app/md" + "applet/app/utils" + "applet/app/utils/cache" + "code.fnuoos.com/EggPlanet/egg_models.git/src/model" + "code.fnuoos.com/go_rely_warehouse/zyos_go_mq.git/rabbit" + "fmt" + "strings" + "time" + "xorm.io/xorm" +) + +func NoSignSend(eg *xorm.Engine) { + PessimismLockValue := "NoSignSend" + ch, err := rabbit.Cfg.Pool.GetChannel() + if err != nil { + return + } + defer ch.Release() + key := fmt.Sprintf("NoSignSend") + //TODO::增加“悲观锁”防止串行 + getString, _ := cache.GetString(key) + if getString == PessimismLockValue { + fmt.Println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", "上一次未执行完") + return + } + cache.SetEx(key, PessimismLockValue, 3600*8) //8小时 + notice := make([]model.JpushNotice, 0) + eg.Where("type='sign' and (jpush_open=1 or sms_open=1)").Desc("day").Find(¬ice) + for _, v := range notice { + commNoSignSend(eg, ch, 1, v) + } + cache.Del(key) +} +func commNoSignSend(eg *xorm.Engine, ch *rabbit.Channel, p int, data model.JpushNotice) { + now := time.Now().Unix() + lastLoginAt := now - int64(data.Day)*3600 + loginNoticeTime := now - int64(data.NoticeDay)*3600 + sql := ` +SELECT u.id,u.phone,u.nickname,unt.id as unt_id,unt.sign_time,unt.sign_notice_time FROM user_notice_time unt +LEFT JOIN user u on u.id=unt.uid +WHERE unt.sign_time<'%d' and unt.sign_notice_time<'%d' and unt.sign_time>0 %s +` + sql = fmt.Sprintf(sql, lastLoginAt, loginNoticeTime, "limit "+utils.IntToStr((p-1)*1000)+",1000") + userList, _ := db.QueryNativeString(eg, sql) + if len(userList) == 0 { + return + } + extra := "" + for _, v := range userList { + hour := (now - utils.StrToInt64(v["sign_time"])) / 3600 + data.Content = strings.ReplaceAll(data.Content, "{昵称}", v["nickname"]) + data.Content = strings.ReplaceAll(data.Content, "{手机号}", v["phone"]) + data.Content = strings.ReplaceAll(data.Content, "{小时}", utils.Int64ToStr(hour)) + extra = "{\"hour\":\"" + utils.Int64ToStr(hour) + "\",\"name\":\"" + v["name"] + "\",\"phone\":\"" + v["phone"] + "\"}" + arg := md.JpushRecordFundData{UserId: v["id"], Target: "1", Platform: "all", Title: data.Title, Content: data.Content} + err := ch.PublishV2(md.EggJpushRecordQueueExchange, arg, md.EggJpushRecordQueue) + if err != nil { + ch.PublishV2(md.EggJpushRecordQueueExchange, arg, md.EggJpushRecordQueue) + } + arg1 := md.AliyunSmsRecordFundData{Phone: v["phone"], Title: data.Title, Content: data.Content, Code: data.SmsCode, Extra: extra} + err = ch.PublishV2(md.EggAliyunSmsRecordQueueExchange, arg1, md.EggAliyunSmsRecordQueue) + if err != nil { + ch.PublishV2(md.EggAliyunSmsRecordQueueExchange, arg1, md.EggAliyunSmsRecordQueue) + } + eg.Where("id=?", v["unt_id"]).Cols("sign_notice_time").Update(&model.UserNoticeTime{SignNoticeTime: int(time.Now().Unix())}) + } + if len(userList) == 1000 { + p++ + commNoSignSend(eg, ch, p, data) + return + } + return + +} diff --git a/cmd/task/main.go b/cmd/task/main.go index ec3c112..9bd3765 100644 --- a/cmd/task/main.go +++ b/cmd/task/main.go @@ -18,6 +18,7 @@ func init() { cfg.InitTaskCfg() // 日志配置 cfg.InitLog() + cfg.InitMq() // 队列初始化 // 初始化redis cfg.InitCache() baseDb := *cfg.DB diff --git a/etc/task.yml b/etc/task.yml index 056b5ba..6126e20 100644 --- a/etc/task.yml +++ b/etc/task.yml @@ -35,3 +35,9 @@ log: file_max_size: 256 file_max_age: 1 file_name: 'task.log' + +mq: + host: '116.62.62.35' + port: '5672' + user: 'zhios' + pwd: 'ZHIoscnfnuo123' \ No newline at end of file diff --git a/go.mod b/go.mod index 3421288..dfe5f3e 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( ) require ( - code.fnuoos.com/EggPlanet/egg_models.git v0.2.1-0.20241127081813-15aa08a421b0 + code.fnuoos.com/EggPlanet/egg_models.git v0.2.1-0.20241128030209-743f36ef9dad code.fnuoos.com/EggPlanet/egg_system_rules.git v0.0.4-0.20241127090541-fd005650a340 code.fnuoos.com/go_rely_warehouse/zyos_go_es.git v1.0.1-0.20241118083738-0f22da9ba0be code.fnuoos.com/go_rely_warehouse/zyos_go_mq.git v0.0.5