@@ -28,6 +28,7 @@ func InitTaskCfg() { | |||
Debug = conf.Debug | |||
DB = &conf.DB | |||
Log = &conf.Log | |||
MQ = &conf.MQ | |||
RedisAddr = conf.RedisAddr | |||
} | |||
@@ -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 | |||
} |
@@ -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) | |||
@@ -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 | |||
@@ -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"` | |||
} |
@@ -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调用 | |||
@@ -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 获取年份和周数 | |||
@@ -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小时没签到的用户 | |||
} |
@@ -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 | |||
@@ -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 | |||
} |
@@ -18,6 +18,7 @@ func init() { | |||
cfg.InitTaskCfg() | |||
// 日志配置 | |||
cfg.InitLog() | |||
cfg.InitMq() // 队列初始化 | |||
// 初始化redis | |||
cfg.InitCache() | |||
baseDb := *cfg.DB | |||
@@ -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' |
@@ -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 | |||