taskUtil.go 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945
  1. package task
  2. import (
  3. "context"
  4. "encoding/csv"
  5. "fmt"
  6. "github.com/gogf/gf/container/garray"
  7. "github.com/gogf/gf/os/gcron"
  8. "github.com/gogf/gf/os/gfile"
  9. "github.com/gogf/gf/os/glog"
  10. "github.com/gogf/gf/util/gutil"
  11. "gmanager/library/codeutil"
  12. "gmanager/library/mongo/gameinfo"
  13. "log"
  14. "strconv"
  15. "strings"
  16. "time"
  17. "github.com/gogf/gf/container/gmap"
  18. "github.com/gogf/gf/frame/g"
  19. "github.com/gogf/gf/os/gtime"
  20. "github.com/gogf/gf/util/gconv"
  21. "go.mongodb.org/mongo-driver/bson"
  22. "go.mongodb.org/mongo-driver/bson/primitive"
  23. )
  24. var serverMap *gmap.TreeMap
  25. func init() {
  26. serverMap = gmap.NewTreeMap(gutil.ComparatorInt, true)
  27. glog.Info("timer start")
  28. gcron.AddSingleton("0 30 1 * * *", Liucun)
  29. gcron.AddSingleton("0 30 1 * * *", LiucunByServer)
  30. // 每日凌晨一点 统计计算LTV需要的值:取每天新增的角色数及他们的每日充值金额
  31. gcron.AddSingleton("0 0 1 * * ?", StatisticalLTV)
  32. gcron.AddSingleton("0 0 1 * * ?", StatisticalLTV_Server)
  33. /**
  34. 每小时的5秒后执行
  35. */
  36. // 新增注册人数
  37. gcron.AddSingleton("5 0 * * * ?", Hour)
  38. // 新增登录人数
  39. gcron.AddSingleton("5 0 * * * ?", HourLogin)
  40. /**
  41. 30分钟执行一次
  42. */
  43. // 统计充值人数、充值总额(刷新统计值)
  44. gcron.AddSingleton("0 0,30 * * * ?", StatisticalRecharge)
  45. gcron.AddSingleton("0 0,30 * * * ?", StatisticalRecharge_Server)
  46. // 判断是否需要导出表格
  47. if "1" == g.Config().GetString("game.export") {
  48. // 按天执行 0 10 0 * * *
  49. // 订单信息表: log_charge
  50. gcron.AddSingleton("0 10 0 * * *", logCharge)
  51. // 道具消耗表: log_throw
  52. gcron.AddSingleton("0 10 0 * * *", logThrow)
  53. // 道具发放表: log_goods
  54. gcron.AddSingleton("0 10 0 * * *", logGoods)
  55. // 按月度执行 0 0 0 1 * *
  56. // 道具信息表: goods_info
  57. gcron.AddSingleton("0 0 0 1 * *", goodsInfo)
  58. // 用户账号与角色对应关系表: log_role
  59. gcron.AddSingleton("0 0 0 1 * *", logRole)
  60. }
  61. }
  62. // 处理留存数据
  63. func Liucun() {
  64. //只算今天的情况
  65. date := g.Config().GetString("startday")
  66. startTime := gtime.NewFromStr(date)
  67. for {
  68. daystartTime := startTime.Local().TimestampMilli()
  69. dayendTime := startTime.Clone().AddDate(0, 0, 1).Local().TimestampMilli() - 1
  70. //fmt.Println(daystartTime, dayendTime)
  71. //fmt.Println(startTime.Date())
  72. //获得今天的新增的玩家
  73. users := gameinfo.ModelRegister.FindNew(daystartTime, dayendTime)
  74. usersList := gconv.SliceAny(users)
  75. userStr := gconv.Ints(usersList)
  76. regStartTime := startTime.Clone()
  77. days := 0
  78. tempDate := startTime.Format("Y-m-d")
  79. for {
  80. regdaystartTime := regStartTime.Local().TimestampMilli()
  81. regdayendTime := regStartTime.Clone().AddDate(0, 0, 1).Local().TimestampMilli() - 1
  82. if regStartTime.DayOfYear() == gtime.Now().DayOfYear() {
  83. break
  84. }
  85. bs := bson.D{{"creatday", tempDate}, {"day", days}}
  86. info := gameinfo.ModelLiucun.FindOneBson(bs)
  87. if info != 0 {
  88. regStartTime = regStartTime.AddDate(0, 0, 1)
  89. days++
  90. continue
  91. }
  92. userLoginNum := gameinfo.ModeLogin.FindLogin(regdaystartTime, regdayendTime, userStr)
  93. //fmt.Println("login", days, userLoginNum)
  94. logLiucun := new(gameinfo.LogLiucun)
  95. logLiucun.Id = primitive.NewObjectID()
  96. logLiucun.CreatDay = tempDate
  97. logLiucun.NewUser = len(usersList)
  98. logLiucun.DayCount = userLoginNum
  99. logLiucun.Day = days
  100. gameinfo.ModelLiucun.InsertOne(logLiucun)
  101. regStartTime2 := regStartTime.Clone().Format("Y-m-d")
  102. payTimeS := regStartTime2 + " 00:00:00"
  103. payTimeE := regStartTime2 + " 23:59:59"
  104. payUserNum := gameinfo.ModelPay.FindPay(payTimeS, payTimeE, userStr, "")
  105. logPayLiucun := new(gameinfo.LogPayLiucun)
  106. logPayLiucun.Id = primitive.NewObjectID()
  107. logPayLiucun.CreatDay = tempDate
  108. logPayLiucun.NewUser = len(usersList)
  109. logPayLiucun.DayCount = payUserNum
  110. logPayLiucun.Day = days
  111. gameinfo.ModelPayLiucun.InsertOne(logPayLiucun)
  112. regStartTime = regStartTime.AddDate(0, 0, 1)
  113. days++
  114. }
  115. //fmt.Println("new user", users)
  116. startTime = startTime.AddDate(0, 0, 1)
  117. if startTime.DayOfYear() == gtime.Now().DayOfYear() {
  118. break
  119. }
  120. continue
  121. }
  122. fmt.Println("Liucun end")
  123. }
  124. // 处理各服务器的留存数据
  125. func LiucunByServer() {
  126. date := g.Config().GetString("startday")
  127. startTime := gtime.NewFromStr(date)
  128. for {
  129. daystartTime := startTime.Local().TimestampMilli()
  130. dayendTime := startTime.Clone().AddDate(0, 0, 1).Local().TimestampMilli() - 1
  131. //获得今天的新增的各服务器玩家
  132. result := gameinfo.ModelRegister.FindRegisterByServer(daystartTime, dayendTime)
  133. var showsWithInfo []bson.M
  134. if err := result.All(context.TODO(), &showsWithInfo); err != nil {
  135. fmt.Println(err)
  136. }
  137. for _, v := range showsWithInfo {
  138. serverId := gconv.String(v["_id"])
  139. days := 0
  140. tempDate := startTime.Format("Y-m-d")
  141. regStartTime := startTime.Clone()
  142. //根据时间范围和区服id查询注册的用户
  143. list := garray.New(false)
  144. bs := bson.D{{"register.registerTime", bson.D{{"$gte", daystartTime}, {"$lte", dayendTime}}}, {"register.serverId", serverId}}
  145. datas := gameinfo.ModelRegister.FindAllBson(bs)
  146. var showsWithInfo1 []bson.M
  147. if err := datas.All(context.TODO(), &showsWithInfo1); err != nil {
  148. fmt.Println(err)
  149. }
  150. for _, v1 := range showsWithInfo1 {
  151. s2 := v1["register"].(primitive.M)
  152. list.Append(s2["uid"])
  153. }
  154. usersList := gconv.SliceAny(list)
  155. for {
  156. regdaystartTime := regStartTime.Local().TimestampMilli()
  157. regdayendTime := regStartTime.Clone().AddDate(0, 0, 1).Local().TimestampMilli() - 1
  158. if regStartTime.DayOfYear() == gtime.Now().DayOfYear() {
  159. break
  160. }
  161. bs1 := bson.D{{"creatday", tempDate}, {"day", days}}
  162. info := gameinfo.ModelLiucun.FindOneBson_ServerId(bs1, serverId)
  163. if info != 0 {
  164. regStartTime = regStartTime.AddDate(0, 0, 1)
  165. days++
  166. continue
  167. }
  168. userLoginNum := gameinfo.ModeLogin.FindLogin1(regdaystartTime, regdayendTime, gconv.Ints(usersList), serverId)
  169. //fmt.Println("login", days, userLoginNum)
  170. logLiucun := new(gameinfo.LogLiucun)
  171. logLiucun.Id = primitive.NewObjectID()
  172. logLiucun.CreatDay = tempDate
  173. logLiucun.NewUser = len(usersList)
  174. logLiucun.DayCount = userLoginNum
  175. logLiucun.Day = days
  176. gameinfo.ModelLiucun.InsertOne_ServerId(logLiucun, serverId)
  177. regStartTime2 := regStartTime.Clone().Format("Y-m-d")
  178. payTimeS := regStartTime2 + " 00:00:00"
  179. payTimeE := regStartTime2 + " 23:59:59"
  180. payUserNum := gameinfo.ModelPay.FindPay(payTimeS, payTimeE, gconv.Ints(usersList), serverId)
  181. logPayLiucun := new(gameinfo.LogPayLiucun)
  182. logPayLiucun.Id = primitive.NewObjectID()
  183. logPayLiucun.CreatDay = tempDate
  184. logPayLiucun.NewUser = len(usersList)
  185. logPayLiucun.DayCount = payUserNum
  186. logPayLiucun.Day = days
  187. gameinfo.ModelPayLiucun.InsertOne_ServerId(logPayLiucun, serverId)
  188. regStartTime = regStartTime.AddDate(0, 0, 1)
  189. days++
  190. }
  191. }
  192. //结束条件
  193. startTime = startTime.AddDate(0, 0, 1)
  194. if startTime.DayOfYear() == gtime.Now().DayOfYear() {
  195. break
  196. }
  197. continue
  198. }
  199. fmt.Println("LiucunByServer end")
  200. }
  201. // 新增注册人数
  202. func Hour() {
  203. // 获取当前系统时间 取值到小时 后面拼接00分00秒
  204. newTime := time.Now().Format("2006-01-02 15")
  205. newTimeStr := string(newTime + ":00:00")
  206. fmt.Println("当前时间整点:" + newTimeStr)
  207. // 时间格式化
  208. timeLayout := "2006-01-02 15:04:05"
  209. // 字符串转成time
  210. t, _ := time.ParseInLocation(timeLayout, newTimeStr, time.Local)
  211. // 1小时前
  212. h, _ := time.ParseDuration("-1h")
  213. h1 := t.Add(h)
  214. fmt.Printf("查询时间范围 %d点 - %d点\n", h1.Hour(), t.Hour())
  215. // 转成时间戳
  216. hourStratTime := h1.UnixNano() / 1e6
  217. hourEndTime := t.UnixNano() / 1e6
  218. tempDate := gtime.NewFromTimeStamp(hourStratTime).Format("Y-m-d")
  219. bs := bson.D{{"creatday", tempDate}, {"hour", h1.Hour()}}
  220. info := gameinfo.ModelHour.FindOneBson(bs)
  221. if info != 0 {
  222. return
  223. }
  224. count := 0
  225. result := gameinfo.ModelRegister.FindRegisterByServer(hourStratTime, hourEndTime)
  226. var showsWithInfo []bson.M
  227. if err := result.All(context.TODO(), &showsWithInfo); err != nil {
  228. fmt.Println(err)
  229. }
  230. for _, v := range showsWithInfo {
  231. count = count + gconv.Int(v["count"])
  232. logHour := new(gameinfo.LogHour)
  233. logHour.Id = primitive.NewObjectID()
  234. logHour.CreatDay = tempDate
  235. logHour.NewUser = gconv.Int(v["count"])
  236. logHour.Hour = h1.Hour()
  237. gameinfo.ModelHour.InsertOneByServer(logHour, gconv.String(v["_id"]))
  238. fmt.Println("服务器", gconv.String(v["_id"]), " 新增注册人数", gconv.Int(v["count"]))
  239. }
  240. logHour := new(gameinfo.LogHour)
  241. logHour.Id = primitive.NewObjectID()
  242. logHour.CreatDay = tempDate
  243. logHour.NewUser = count
  244. logHour.Hour = h1.Hour()
  245. gameinfo.ModelHour.InsertOne(logHour)
  246. fmt.Println("新增总注册人数", count)
  247. fmt.Println("Hour end")
  248. }
  249. // 新增登录人数
  250. func HourLogin() {
  251. // 获取当前系统时间 取值到小时 后面拼接00分00秒
  252. newTime := time.Now().Format("2006-01-02 15")
  253. newTimeStr := string(newTime + ":00:00")
  254. // 时间格式化
  255. timeLayout := "2006-01-02 15:04:05"
  256. // 字符串转成time
  257. t, _ := time.ParseInLocation(timeLayout, newTimeStr, time.Local)
  258. // 1小时前
  259. h, _ := time.ParseDuration("-1h")
  260. h1 := t.Add(h)
  261. // 转成时间戳
  262. hourStratTime := h1.UnixNano() / 1e6
  263. hourEndTime := t.UnixNano() / 1e6
  264. // 根据开始时间取年月日
  265. tempDate := gtime.NewFromTimeStamp(hourStratTime).Format("Y-m-d")
  266. bs := bson.D{{"creatday", tempDate}, {"hour", h1.Hour()}}
  267. info := gameinfo.ModelHourLogin.FindOneBson(bs)
  268. if info != 0 {
  269. return
  270. }
  271. //查询各服务器的登录人数
  272. result := gameinfo.ModeLogin.FindLoginByServer(hourStratTime, hourEndTime)
  273. var showsWithInfo []bson.M
  274. if err := result.All(context.TODO(), &showsWithInfo); err != nil {
  275. fmt.Println(err)
  276. }
  277. serverList := garray.New(false)
  278. userList := garray.New(false)
  279. //遍历数据到集合
  280. for _, v := range showsWithInfo {
  281. if !serverList.Contains(v["serverId"]) {
  282. serverList.Append(v["serverId"])
  283. }
  284. if !userList.Contains(v["uid"]) {
  285. userList.Append(v["uid"])
  286. }
  287. }
  288. //遍历服务器集合
  289. serverList.Iterator(func(k int, v interface{}) bool {
  290. count := 0
  291. for _, v1 := range showsWithInfo {
  292. if v == v1["serverId"] {
  293. count = count + 1
  294. }
  295. }
  296. logHourLogin := new(gameinfo.LogHourLogin)
  297. logHourLogin.Id = primitive.NewObjectID()
  298. logHourLogin.CreatDay = tempDate
  299. logHourLogin.NewUser = count
  300. logHourLogin.Hour = h1.Hour()
  301. gameinfo.ModelHourLogin.InsertOneByServer(logHourLogin, gconv.String(v))
  302. fmt.Println("服务器", gconv.String(v), " 新增登录人数", count)
  303. return true
  304. })
  305. logHourLogin := new(gameinfo.LogHourLogin)
  306. logHourLogin.Id = primitive.NewObjectID()
  307. logHourLogin.CreatDay = tempDate
  308. logHourLogin.NewUser = userList.Len()
  309. logHourLogin.Hour = h1.Hour()
  310. gameinfo.ModelHourLogin.InsertOne(logHourLogin)
  311. fmt.Println("新增总登录人数", userList.Len())
  312. fmt.Println("HourLogin end")
  313. }
  314. // 统计充值信息
  315. func StatisticalRecharge() {
  316. nowTime := time.Now().Format("2006-01-02")
  317. // 判断用户去重集合
  318. userList := garray.New(false)
  319. var newRechargeNum, newRechargeAmount, newRechargeCount, rechargeNum, rechargeAmount, rechargeCount int64
  320. // 新注册的用户
  321. daystartTime := gtime.NewFromStr(nowTime).Local().TimestampMilli()
  322. dayendTime := gtime.NewFromStr(nowTime).Clone().AddDate(0, 0, 1).Local().TimestampMilli() - 1
  323. users := gameinfo.ModelRegister.FindNew(daystartTime, dayendTime)
  324. // 查询当天支付数据
  325. stime := nowTime + " 00:00:00"
  326. etime := nowTime + " 23:59:59"
  327. filter := bson.D{
  328. {"creattime", bson.D{{"$gte", stime}, {"$lte", etime}}},
  329. {"status", 1},
  330. {"handlestatus", 1}}
  331. payList := gameinfo.ModelPay.GetPayInfoTask(filter)
  332. for payList.Next(context.TODO()) {
  333. var pay gameinfo.Pay
  334. err := payList.Decode(&pay)
  335. if err != nil {
  336. //log.Fatal(err)
  337. log.Println(err)
  338. continue
  339. }
  340. if !userList.Contains(pay.Uid) {
  341. rechargeNum = rechargeNum + 1
  342. }
  343. rechargeCount = rechargeCount + 1
  344. rechargeAmount = rechargeAmount + gconv.Int64(pay.Money)
  345. //是新注册的用户
  346. if users.Contains(pay.Uid) {
  347. if !userList.Contains(pay.Uid) {
  348. newRechargeNum = newRechargeNum + 1
  349. }
  350. newRechargeCount = newRechargeCount + 1
  351. newRechargeAmount = newRechargeAmount + gconv.Int64(pay.Money)
  352. }
  353. userList.Append(pay.Uid)
  354. }
  355. // 统计充值
  356. statisticalRecharge := gameinfo.StatisticalRecharge{}
  357. // 查询是否已经有当天数据
  358. one := gameinfo.ModelStatisticalRecharge.FindOne("creatday", nowTime)
  359. var sr gameinfo.StatisticalRecharge
  360. err := one.Decode(&sr)
  361. if err != nil {
  362. statisticalRecharge.Id = primitive.NewObjectID()
  363. } else {
  364. statisticalRecharge.Id = sr.Id
  365. }
  366. statisticalRecharge.CreatDay = nowTime
  367. //统计新增充值(当日注册且付费的人数和金额、付费次数)
  368. statisticalRecharge.NewRechargeNum = gconv.Int(newRechargeNum)
  369. statisticalRecharge.NewRechargeAmount = gconv.Float64(newRechargeAmount)
  370. statisticalRecharge.NewRechargeCount = gconv.Int(newRechargeCount)
  371. //统计充值总数(人数和金额、付费次数)
  372. statisticalRecharge.RechargeNum = gconv.Int(rechargeNum)
  373. statisticalRecharge.RechargeAmount = gconv.Float64(rechargeAmount)
  374. statisticalRecharge.RechargeCount = gconv.Int(rechargeCount)
  375. gameinfo.ModelStatisticalRecharge.InsertAndUpdateStatisticalRecharge(statisticalRecharge.Id, statisticalRecharge, "")
  376. fmt.Println("StatisticalRecharge end")
  377. }
  378. // 统计各服务器充值信息
  379. func StatisticalRecharge_Server() {
  380. nowTime := time.Now().Format("2006-01-02")
  381. stime := nowTime + " 00:00:00"
  382. etime := nowTime + " 23:59:59"
  383. // 判断用户去重集合
  384. userList := garray.New(false)
  385. //获得今天的新增的玩家
  386. daystartTime := gtime.NewFromStr(nowTime).Local().TimestampMilli()
  387. dayendTime := gtime.NewFromStr(nowTime).Clone().AddDate(0, 0, 1).Local().TimestampMilli() - 1
  388. users := gameinfo.ModelRegister.FindNew(daystartTime, dayendTime)
  389. // 取pay表符合条件的服务器id
  390. filter := bson.D{
  391. {"creattime", bson.D{{"$gte", stime}, {"$lte", etime}}},
  392. {"status", 1},
  393. {"handlestatus", 1}}
  394. serverList := gameinfo.ModelPay.GetPayServerId(filter)
  395. var showsWithInfo []bson.M
  396. if err := serverList.All(context.TODO(), &showsWithInfo); err != nil {
  397. fmt.Println(err)
  398. }
  399. // 遍历服务器id
  400. for _, m := range showsWithInfo {
  401. var newRechargeNum, newRechargeAmount, newRechargeCount, rechargeNum, rechargeAmount, rechargeCount int64
  402. //查询支付数据
  403. serverFilter := bson.D{
  404. {"creattime", bson.D{{"$gte", stime}, {"$lte", etime}}},
  405. {"status", gconv.Int32(1)},
  406. {"region", gconv.Int32(m["region"])},
  407. {"handlestatus", gconv.Int32(1)}}
  408. payList := gameinfo.ModelPay.GetPayInfoTask(serverFilter)
  409. for payList.Next(context.TODO()) {
  410. var pay gameinfo.Pay
  411. err := payList.Decode(&pay)
  412. if err != nil {
  413. //log.Fatal(err)
  414. log.Println(err)
  415. continue
  416. }
  417. if !userList.Contains(pay.Uid) {
  418. rechargeNum = rechargeNum + 1
  419. }
  420. rechargeCount = rechargeCount + 1
  421. rechargeAmount = rechargeAmount + gconv.Int64(pay.Money)
  422. //是新注册的用户
  423. if users.Contains(pay.Uid) {
  424. if !userList.Contains(pay.Uid) {
  425. newRechargeNum = newRechargeNum + 1
  426. }
  427. newRechargeCount = newRechargeCount + 1
  428. newRechargeAmount = newRechargeAmount + gconv.Int64(pay.Money)
  429. }
  430. userList.Append(pay.Uid)
  431. }
  432. // 统计充值
  433. statisticalRecharge := gameinfo.StatisticalRecharge{}
  434. // 查询是否已经有当天数据
  435. one := gameinfo.ModelStatisticalRecharge.FindOne_ServerId("creatday", nowTime, gconv.String(m["region"]))
  436. var sr gameinfo.StatisticalRecharge
  437. err := one.Decode(&sr)
  438. if err != nil {
  439. statisticalRecharge.Id = primitive.NewObjectID()
  440. } else {
  441. statisticalRecharge.Id = sr.Id
  442. }
  443. statisticalRecharge.CreatDay = nowTime
  444. //统计新增充值(当日注册且付费的人数和金额、付费次数)
  445. statisticalRecharge.NewRechargeNum = gconv.Int(newRechargeNum)
  446. statisticalRecharge.NewRechargeAmount = gconv.Float64(newRechargeAmount)
  447. statisticalRecharge.NewRechargeCount = gconv.Int(newRechargeCount)
  448. //统计充值总数(人数和金额、付费次数)
  449. statisticalRecharge.RechargeNum = gconv.Int(rechargeNum)
  450. statisticalRecharge.RechargeAmount = gconv.Float64(rechargeAmount)
  451. statisticalRecharge.RechargeCount = gconv.Int(rechargeCount)
  452. gameinfo.ModelStatisticalRecharge.InsertAndUpdateStatisticalRecharge(statisticalRecharge.Id, statisticalRecharge, gconv.String(m["region"]))
  453. }
  454. fmt.Println("StatisticalRecharge_Server end")
  455. }
  456. // 统计计算LTV需要金额
  457. func StatisticalLTV() {
  458. date := g.Config().GetString("startday")
  459. startTime := gtime.NewFromStr(date)
  460. for {
  461. daystartTime := startTime.Local().TimestampMilli()
  462. dayendTime := startTime.Clone().AddDate(0, 0, 1).Local().TimestampMilli() - 1
  463. //获得今天的新增的角色
  464. users := gameinfo.ModelRegister.FindNew(daystartTime, dayendTime)
  465. usersList := gconv.SliceAny(users)
  466. tempDate := startTime.Clone().Format("Y-m-d")
  467. regStartTime := startTime.Clone()
  468. days := 0
  469. for {
  470. if regStartTime.DayOfYear() == gtime.Now().DayOfYear() {
  471. break
  472. }
  473. // 查询 已存在当天的第n天数据 跳过
  474. bs := bson.D{{"creatday", tempDate}, {"day", days}}
  475. info := gameinfo.ModelLtv.FindOneBson(bs)
  476. if info != 0 {
  477. regStartTime = regStartTime.AddDate(0, 0, 1)
  478. days++
  479. continue
  480. }
  481. tempDate2 := regStartTime.Clone().Format("Y-m-d")
  482. stime2 := tempDate2 + " 00:00:00"
  483. etime2 := tempDate2 + " 23:59:59"
  484. totleAmount := gameinfo.ModelPay.GetLtvStatistical(stime2, etime2, gconv.Ints(usersList), "")
  485. logLTV := new(gameinfo.LogLTV)
  486. logLTV.Id = primitive.NewObjectID()
  487. logLTV.CreatDay = tempDate
  488. logLTV.NewUser = len(usersList)
  489. logLTV.DayAmount = totleAmount
  490. logLTV.Day = days
  491. logLTV.LogTime = gtime.Now().TimestampMilli()
  492. gameinfo.ModelLtv.InsertOne(logLTV)
  493. regStartTime = regStartTime.AddDate(0, 0, 1)
  494. days++
  495. }
  496. startTime = startTime.AddDate(0, 0, 1)
  497. if startTime.DayOfYear() == gtime.Now().DayOfYear() {
  498. break
  499. }
  500. }
  501. fmt.Println("StatisticalLTV end")
  502. }
  503. // 统计计算各服务器LTV需要金额
  504. func StatisticalLTV_Server() {
  505. date := g.Config().GetString("startday")
  506. startTime := gtime.NewFromStr(date)
  507. for {
  508. daystartTime := startTime.Local().TimestampMilli()
  509. dayendTime := startTime.Clone().AddDate(0, 0, 1).Local().TimestampMilli() - 1
  510. //获得各服务器的新增角色数
  511. users := gameinfo.ModelRegister.FindRegisterByServer(daystartTime, dayendTime)
  512. var showsWithInfo []bson.M
  513. if err := users.All(context.TODO(), &showsWithInfo); err != nil {
  514. fmt.Println(err)
  515. }
  516. for _, v := range showsWithInfo {
  517. tempDate := startTime.Clone().Format("Y-m-d")
  518. regStartTime := startTime.Clone()
  519. days := 0
  520. list := garray.New(false)
  521. serverId := gconv.String(v["_id"])
  522. //count := gconv.String(v["count"])
  523. filter := bson.D{
  524. {"register.registerTime", bson.D{{"$gte", daystartTime}, {"$lte", dayendTime}}},
  525. {"register.serverId", gconv.String(serverId)},
  526. }
  527. datas := gameinfo.ModelRegister.FindAllBson(filter)
  528. var showsWithInfo1 []bson.M
  529. if err := datas.All(context.TODO(), &showsWithInfo1); err != nil {
  530. fmt.Println(err)
  531. }
  532. for _, v1 := range showsWithInfo1 {
  533. s2 := v1["register"].(primitive.M)
  534. list.Append(s2["uid"])
  535. }
  536. usersList := gconv.SliceAny(list)
  537. for {
  538. if regStartTime.DayOfYear() == gtime.Now().DayOfYear() {
  539. break
  540. }
  541. // 查询 已存在当天的第n天数据 跳过
  542. bs := bson.D{{"creatday", tempDate}, {"day", days}}
  543. info := gameinfo.ModelLtv.FindOneBson_ServerId(bs, serverId)
  544. if info != 0 {
  545. regStartTime = regStartTime.AddDate(0, 0, 1)
  546. days++
  547. continue
  548. }
  549. tempDate2 := regStartTime.Clone().Format("Y-m-d")
  550. stime2 := tempDate2 + " 00:00:00"
  551. etime2 := tempDate2 + " 23:59:59"
  552. totleAmount := gameinfo.ModelPay.GetLtvStatistical(stime2, etime2, gconv.Ints(usersList), serverId)
  553. logLTV := new(gameinfo.LogLTV)
  554. logLTV.Id = primitive.NewObjectID()
  555. logLTV.CreatDay = tempDate
  556. logLTV.NewUser = len(usersList)
  557. logLTV.DayAmount = totleAmount
  558. logLTV.Day = days
  559. logLTV.LogTime = gtime.Now().TimestampMilli()
  560. gameinfo.ModelLtv.InsertOne_ServerId(logLTV, serverId)
  561. regStartTime = regStartTime.AddDate(0, 0, 1)
  562. days++
  563. }
  564. }
  565. //fmt.Println(startTime)
  566. startTime = startTime.AddDate(0, 0, 1)
  567. if startTime.DayOfYear() == gtime.Now().DayOfYear() {
  568. break
  569. }
  570. }
  571. fmt.Println("StatisticalLTV_Server end")
  572. }
  573. // 订单信息表: log_charge_{日期}_{区服号}_{游戏名}.txt (按天级别)
  574. func logCharge() {
  575. // 读取配置表
  576. itemConfig := codeutil.GetItemConfig()
  577. rechargeCommodityConfig := codeutil.GetRechargeCommodityConfig()
  578. // 取游戏名称
  579. gameName := g.Config().GetString("game.name")
  580. // 格式化时间
  581. nowDate := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
  582. stime := nowDate + " 00:00:00"
  583. etime := nowDate + " 23:59:59"
  584. // 遍历需要导出表格的服务器
  585. servers := gameinfo.ModelServer.FindAllBson(bson.D{{"exportdata", "1"}})
  586. for servers.Next(context.TODO()) {
  587. var serverInfo gameinfo.ServerInfo
  588. err := servers.Decode(&serverInfo)
  589. if err != nil {
  590. //log.Fatal(err)
  591. log.Println(err)
  592. continue
  593. }
  594. // 导出文件名称
  595. fileName := "log_charge_" + nowDate + "_" + gconv.String(serverInfo.ServerId) + "_" + gameName + ".txt"
  596. file, err := gfile.Create(fileName)
  597. if err != nil {
  598. fmt.Println("open file is failed, err: ", err.Error())
  599. }
  600. w := csv.NewWriter(file)
  601. // 查询订单信息
  602. filter := bson.D{
  603. {"creattime", bson.D{{"$gte", stime}, {"$lte", etime}}},
  604. {"status", gconv.Int32(1)},
  605. {"region", gconv.Int32(serverInfo.ServerId)},
  606. {"handlestatus", gconv.Int32(1)}}
  607. payList := gameinfo.ModelPay.GetPayInfoTask(filter)
  608. for payList.Next(context.TODO()) {
  609. var pay gameinfo.Pay
  610. err := payList.Decode(&pay)
  611. if err != nil {
  612. //log.Fatal(err)
  613. log.Println(err)
  614. continue
  615. }
  616. // 拼接内容
  617. bugType := ""
  618. if (gconv.Int(pay.PayItem) >= 1 && gconv.Int(pay.PayItem) <= 6) {
  619. bugType = "1"
  620. } else {
  621. bugType = "2"
  622. }
  623. // 从缓存中取对应value
  624. baseRewards, _ := rechargeCommodityConfig.Get(gconv.String(pay.PayItem))
  625. baseRewards = gconv.Map(baseRewards)["BaseReward"]
  626. // 如果有多条奖励
  627. if strings.Contains(gconv.String(baseRewards), "|") {
  628. split := strings.Split(gconv.String(baseRewards), "|")
  629. for _, baseReward := range split {
  630. //fmt.Println(baseReward)
  631. goodsId := strings.Split(baseReward, "#")[0]
  632. goodsName, _ := itemConfig.Get(gconv.String(goodsId))
  633. // 还差付款渠道
  634. data := gconv.String(pay.Billno)+"\t"+gconv.String(pay.OpenId)+"\t"+gconv.String(goodsId)+"\t"+gconv.String(goodsName)+"\t"+bugType+"\t"+gconv.String(pay.Creattime)+"\t" +
  635. ""+gconv.String(serverInfo.Timezone)+"\t"+gconv.String(serverInfo.Currency)+"\t"+gconv.String(pay.PayWay)+"\t"+gconv.String(pay.Money)
  636. w.Write([]string{data})
  637. // 刷新缓冲
  638. w.Flush()
  639. }
  640. } else {
  641. // 只有一条奖励
  642. if strings.Contains(gconv.String(baseRewards), "#") {
  643. goodsId := strings.Split(gconv.String(baseRewards), "#")[0]
  644. goodsName, _ := itemConfig.Get(gconv.String(goodsId))
  645. // 还差付款渠道
  646. data := gconv.String(pay.Billno)+"\t"+gconv.String(pay.OpenId)+"\t"+gconv.String(goodsId)+"\t"+gconv.String(goodsName)+"\t"+bugType+"\t"+gconv.String(pay.Creattime)+"\t" +
  647. ""+gconv.String(serverInfo.Timezone)+"\t"+gconv.String(serverInfo.Currency)+"\t"+gconv.String(pay.PayWay)+"\t"+gconv.String(pay.Money)
  648. w.Write([]string{data})
  649. // 刷新缓冲
  650. w.Flush()
  651. }
  652. }
  653. }
  654. // 关闭
  655. itemConfig.Close()
  656. rechargeCommodityConfig.Close()
  657. file.Close()
  658. //删除生成的文件
  659. //os.Remove("./" + fileName)
  660. fmt.Println("logCharge end")
  661. }
  662. }
  663. // 道具消耗表: log_throw_{日期}_{区服号}_{游戏名}.txt (按天级别)
  664. func logThrow() {
  665. // 取配置中游戏名称
  666. gameName := g.Config().GetString("game.name")
  667. // 格式化时间
  668. nowDate := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
  669. daystartTime := gtime.NewFromStr(nowDate).Local().TimestampMilli()
  670. dayendTime := gtime.NewFromStr(nowDate).Clone().AddDate(0, 0, 1).Local().TimestampMilli() - 1
  671. // 遍历需要导出表格的服务器
  672. servers := gameinfo.ModelServer.FindAllBson(bson.D{{"exportdata", "1"}})
  673. for servers.Next(context.TODO()) {
  674. openIdMap := gmap.New()
  675. var serverInfo gameinfo.ServerInfo
  676. err := servers.Decode(&serverInfo)
  677. if err != nil {
  678. //log.Fatal(err)
  679. log.Println(err)
  680. continue
  681. }
  682. // 导出文件名称
  683. fileName := "log_throw_" + nowDate + "_" + gconv.String(serverInfo.ServerId) + "_" + gameName + ".txt"
  684. file, err := gfile.Create(fileName)
  685. if err != nil {
  686. fmt.Println("open file is failed, err: ", err.Error())
  687. }
  688. w := csv.NewWriter(file)
  689. // 查询时间范围内的所有道具消耗信息
  690. itemlogs := gameinfo.ModelItemlog.FindUser(bson.D{{"time", bson.D{{"$gte", gconv.String(daystartTime)}, {"$lte", gconv.String(dayendTime)}}}, {"type", gconv.Int32(1)}}, serverInfo.ServerId)
  691. for itemlogs.Next(context.TODO()) {
  692. var itemLog gameinfo.ItemLog
  693. err := itemlogs.Decode(&itemLog)
  694. if err != nil {
  695. //log.Fatal(err)
  696. log.Println(err)
  697. continue
  698. }
  699. // 处理文本内容
  700. openId := ""
  701. // 根据uid查询对应openid 没有就去查然后放到map 下次用判断map中有没有对应uid
  702. if openIdMap.Contains(itemLog.Uid) {
  703. openId = gconv.String(openIdMap.Get(itemLog.Uid))
  704. } else {
  705. users := gameinfo.ModelUserInfo.FindAllBson(bson.D{{"serverId", gconv.String(serverInfo.ServerId)}, {"uid", gconv.Int32(itemLog.Uid)}})
  706. for users.Next(context.TODO()) {
  707. var userInfo gameinfo.UserInfo
  708. err := users.Decode(&userInfo)
  709. if err != nil {
  710. //log.Fatal(err)
  711. log.Println(err)
  712. continue
  713. }
  714. openId = userInfo.OpenId
  715. }
  716. openIdMap.Set(itemLog.Uid, openId)
  717. }
  718. data := openId+"\t"+gconv.String(itemLog.ItemId)+"\t"+gconv.String(gtime.NewFromTimeStamp(gconv.Int64(itemLog.Time)).Format("Y-m-d H:i:s"))+"\t"+gconv.String(serverInfo.Timezone)+"\t"+gconv.String(itemLog.ItemNum)
  719. w.Write([]string{data})
  720. // 刷新缓冲
  721. w.Flush()
  722. }
  723. }
  724. fmt.Println("logThrow end")
  725. }
  726. // 道具发放表:log_goods_{日期_{区服号}_{游戏名}.txt (按天级别)
  727. func logGoods() {
  728. rechargeCommodityConfig := codeutil.GetRechargeCommodityConfig()
  729. // 去配置中游戏名称
  730. gameName := g.Config().GetString("game.name")
  731. // 遍历需要导出表格的服务器
  732. nowDate := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
  733. stime := nowDate + " 00:00:00"
  734. etime := nowDate + " 23:59:59"
  735. daystartTime := gtime.NewFromStr(nowDate).Local().TimestampMilli()
  736. dayendTime := gtime.NewFromStr(nowDate).Clone().AddDate(0, 0, 1).Local().TimestampMilli() - 1
  737. // 遍历需要导出表格的服务器
  738. servers := gameinfo.ModelServer.FindAllBson(bson.D{{"exportdata", "1"}})
  739. for servers.Next(context.TODO()) {
  740. openIdMap := gmap.New()
  741. var serverInfo gameinfo.ServerInfo
  742. err := servers.Decode(&serverInfo)
  743. if err != nil {
  744. //log.Fatal(err)
  745. log.Println(err)
  746. continue
  747. }
  748. // 导出文件名称
  749. fileName := "log_goods_" + nowDate + "_" + gconv.String(serverInfo.ServerId) + "_" + gameName + ".txt"
  750. file, err := gfile.Create(fileName)
  751. if err != nil {
  752. fmt.Println("open file is failed, err: ", err.Error())
  753. }
  754. w := csv.NewWriter(file)
  755. // 查询支付订单信息
  756. // 查询订单信息
  757. filter := bson.D{
  758. {"creattime", bson.D{{"$gte", stime}, {"$lte", etime}}},
  759. {"status", gconv.Int32(1)},
  760. {"region", gconv.Int32(serverInfo.ServerId)},
  761. {"handlestatus", gconv.Int32(1)}}
  762. payList := gameinfo.ModelPay.GetPayInfoTask(filter)
  763. for payList.Next(context.TODO()) {
  764. var pay gameinfo.Pay
  765. err := payList.Decode(&pay)
  766. if err != nil {
  767. //log.Fatal(err)
  768. log.Println(err)
  769. continue
  770. }
  771. // 从缓存中取对应value
  772. rechargeCommodity, _ := rechargeCommodityConfig.Get(gconv.String(pay.PayItem))
  773. baseRewards := gconv.Map(rechargeCommodity)["BaseReward"]
  774. // 如果有多条奖励
  775. if strings.Contains(gconv.String(baseRewards), "|") {
  776. split := strings.Split(gconv.String(baseRewards), "|")
  777. priceWeights := strings.Split(gconv.String(gconv.Map(rechargeCommodity)["PriceWeight"]), "#")
  778. var totalWeight float64
  779. for _, priceWeight := range priceWeights {
  780. totalWeight += gconv.Float64(priceWeight)
  781. }
  782. if len(split) == len(priceWeights) {
  783. for i := 0; i < len(split); i++ {
  784. percentage, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", gconv.Float64(priceWeights[i])/float64(totalWeight)), 64)
  785. gainPrice, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", percentage * gconv.Float64(gconv.Map(rechargeCommodity)["Price"])), 64)
  786. coinName := ""
  787. data := pay.OpenId+"\t"+strings.Split(split[i], "#")[0]+"\t"+pay.Creattime+"\t"+
  788. gconv.String(serverInfo.Timezone)+"\t"+gconv.String(strings.Split(split[i], "#")[1])+"\t0"+"\t"+gconv.String(gainPrice)+"\t"+coinName+"\t0"
  789. w.Write([]string{data})
  790. w.Flush()
  791. }
  792. }
  793. } else {
  794. // 只有一条奖励
  795. if strings.Contains(gconv.String(baseRewards), "#") {
  796. coinName := ""
  797. data := pay.OpenId+"\t"+strings.Split(gconv.String(baseRewards), "#")[0]+"\t"+pay.Creattime+"\t"+
  798. gconv.String(serverInfo.Timezone)+"\t"+gconv.String(strings.Split(gconv.String(baseRewards), "#")[1])+"\t0"+"\t"+gconv.String(gconv.Float64(gconv.Map(rechargeCommodity)["Price"]))+"\t"+coinName+"\t0"
  799. w.Write([]string{data})
  800. w.Flush()
  801. }
  802. }
  803. }
  804. // 查询日期范围内所有物品获取信息
  805. itemlogs := gameinfo.ModelItemlog.FindUser(bson.D{{"time", bson.D{{"$gte", gconv.String(daystartTime)}, {"$lte", gconv.String(dayendTime)}}}, {"type", gconv.Int32(0)}}, serverInfo.ServerId)
  806. for itemlogs.Next(context.TODO()) {
  807. var itemLog gameinfo.ItemLog
  808. err := itemlogs.Decode(&itemLog)
  809. if err != nil {
  810. //log.Fatal(err)
  811. log.Println(err)
  812. continue
  813. }
  814. openId := ""
  815. if openIdMap.Contains(itemLog.Uid) {
  816. openId = gconv.String(openIdMap.Get(itemLog.Uid))
  817. } else {
  818. users := gameinfo.ModelUserInfo.FindAllBson(bson.D{{"serverId", gconv.String(serverInfo.ServerId)}, {"uid", gconv.Int32(itemLog.Uid)}})
  819. for users.Next(context.TODO()) {
  820. var userInfo gameinfo.UserInfo
  821. err := users.Decode(&userInfo)
  822. if err != nil {
  823. //log.Fatal(err)
  824. log.Println(err)
  825. continue
  826. }
  827. openId = userInfo.OpenId
  828. }
  829. openIdMap.Set(itemLog.Uid, openId)
  830. }
  831. //itemLog.Reason
  832. // gainSource: 0表示现金购买获取,1表示游戏币购买获取, 2表示通过活动等免费获取,3表示道具合成获取,4表示道具分解获取
  833. gainSource := "gainSource"
  834. // gain_price, — 获取道具时的价格,付费购买的道具标注用户实际支付的价格,免费获取道具价格统一为0,合成/分解获取的道具价格统一0.针对礼包涉及到多个道具的情况,拆成单独的道具,
  835. // 价格为单个道具的商城价格*礼包整体折扣率.如果涉及到无价格的道具,需要cp估算出来一个价格
  836. gainPrice := "gainPrice"
  837. // coin_name 传游戏币名称,如果非游戏币购买获得,则传空
  838. coinName := "coinName"
  839. // coin_cost 游戏币消耗数量,如果非游戏币购买获得,则传0
  840. coinCost := "coinCost"
  841. data := openId+"\t"+gconv.String(itemLog.ItemId)+"\t"+gconv.String(gtime.NewFromTimeStamp(gconv.Int64(itemLog.Time)).Format("Y-m-d H:i:s"))+"\t"+
  842. gconv.String(serverInfo.Timezone)+"\t"+gconv.String(itemLog.ItemNum)+"\t"+gainSource+"\t"+gainPrice+"\t"+coinName+"\t"+coinCost
  843. w.Write([]string{data})
  844. // 刷新缓冲
  845. w.Flush()
  846. }
  847. }
  848. rechargeCommodityConfig.Close()
  849. fmt.Println("logGoods end")
  850. }
  851. //道具信息表:goods_info_{游戏名称}.txt (按照月度级别)
  852. func goodsInfo() {
  853. gameName := g.Config().GetString("game.name")
  854. // 导出文件名称
  855. fileName := "goods_info_" + gameName + ".txt"
  856. fmt.Println(fileName)
  857. fmt.Println("goodsInfo end")
  858. }
  859. // 用户账号与角色对应关系表: log_role_{游戏名}.txt (按照月度级别)
  860. func logRole() {
  861. // 取配置中的游戏名
  862. gameName := g.Config().GetString("game.name")
  863. // 导出文件名称
  864. fileName := "log_role_" + gameName + ".txt"
  865. file, err := gfile.Create(fileName)
  866. if err != nil {
  867. fmt.Println("open file is failed, err: ", err.Error())
  868. }
  869. w := csv.NewWriter(file)
  870. // 所有用户信息
  871. allUser := gameinfo.ModelUserInfo.FindAllBson(bson.D{})
  872. for allUser.Next(context.TODO()) {
  873. var userInfo gameinfo.UserInfo
  874. err := allUser.Decode(&userInfo)
  875. if err != nil {
  876. //log.Fatal(err)
  877. log.Println(err)
  878. continue
  879. }
  880. // 在充值信息中查询有无充值记录
  881. sort := bson.D{{"creattime", -1}}
  882. filter := bson.D{{"status", gconv.Int32(1)}, {"handlestatus", gconv.Int32(1)}, {"openid", userInfo.OpenId}}
  883. userPay := gameinfo.ModelPay.GetSortList(filter, sort)
  884. list := g.ListAnyAny{}
  885. for userPay.Next(context.TODO()) {
  886. dayMap := gmap.New()
  887. var pay gameinfo.Pay
  888. err := userPay.Decode(&pay)
  889. if err != nil {
  890. //log.Fatal(err)
  891. log.Println(err)
  892. continue
  893. }
  894. dayMap.Set("creattime", pay.Creattime)
  895. list = append(g.ListAnyAny{gconv.Map(dayMap)}, list...)
  896. }
  897. // 0:免费用户,1:付费用户
  898. accountType := "0"
  899. firstPayDay := ""
  900. lastPayDay := ""
  901. // 如果是付费用户
  902. if len(list) > 0 {
  903. // 排序后 取第一条和最后一条分别为首充时间和最后一次充值时间
  904. firstPayDay = gconv.String(gconv.Map(list[0])["creattime"])
  905. lastPayDay = gconv.String(gconv.Map(list[len(list) - 1])["creattime"])
  906. accountType = "1"
  907. }
  908. data := gconv.String(userInfo.OpenId)+"\t"+gconv.String(userInfo.OpenId)+"\t"+firstPayDay+"\t"+lastPayDay+"\t"+accountType
  909. w.Write([]string{data})
  910. // 刷新缓冲
  911. w.Flush()
  912. }
  913. fmt.Println("logRole end")
  914. }