synthesis.go 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353
  1. package service
  2. import (
  3. "context"
  4. "math"
  5. "sort"
  6. "time"
  7. mhayaTime "github.com/mhaya/extend/time"
  8. cutils "github.com/mhaya/extend/utils"
  9. "github.com/mhaya/game/game_cluster/internal/code"
  10. "github.com/mhaya/game/game_cluster/internal/constant"
  11. "github.com/mhaya/game/game_cluster/internal/mdb"
  12. "github.com/mhaya/game/game_cluster/internal/mdb/eventmodels"
  13. "github.com/mhaya/game/game_cluster/internal/mdb/models"
  14. "github.com/mhaya/game/game_cluster/nodes/webadmin/common"
  15. "github.com/mhaya/game/game_cluster/nodes/webadmin/entity"
  16. "github.com/mhaya/game/game_cluster/nodes/webadmin/model"
  17. mhayaLogger "github.com/mhaya/logger"
  18. "github.com/spf13/cast"
  19. "go.mongodb.org/mongo-driver/bson"
  20. "go.mongodb.org/mongo-driver/bson/primitive"
  21. "go.mongodb.org/mongo-driver/mongo"
  22. "go.mongodb.org/mongo-driver/mongo/options"
  23. "gorm.io/gorm"
  24. )
  25. type Synthesis struct {
  26. nodeId string
  27. db *mongo.Database
  28. }
  29. func NewSynthesis(nodeId string) *Synthesis {
  30. return &Synthesis{
  31. nodeId: nodeId,
  32. db: mdb.MDB,
  33. }
  34. }
  35. // 综合统计
  36. func (s *Synthesis) Overview(req entity.OverviewReq) (*entity.OverviewResp, *code.Result) {
  37. page, pageSize := checkPageParam(req.Page, req.Size)
  38. // 构建查询条件
  39. filter := bson.M{}
  40. if req.UserName != "" {
  41. filter["userName"] = req.UserName
  42. }
  43. // 设置分页选项
  44. findOptions := options.Find()
  45. findOptions.SetSkip(int64((page - 1) * pageSize))
  46. findOptions.SetLimit(int64(pageSize))
  47. findOptions.SetSort(bson.D{{"createTime", -1}})
  48. ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
  49. defer cancel()
  50. collection := mdb.MDB.Collection(constant.CNamePlayer)
  51. // 查询数据
  52. var results []*entity.OverviewDetail
  53. cursor, err := collection.Find(ctx, filter, findOptions)
  54. if err != nil {
  55. mhayaLogger.Warnf("Overview Find error:%v", err)
  56. return nil, common.NewResult(code.InternalError)
  57. }
  58. defer cursor.Close(ctx)
  59. // 解析结果
  60. for cursor.Next(ctx) {
  61. var result entity.OverviewDetail
  62. if err := cursor.Decode(&result); err != nil {
  63. mhayaLogger.Warnf("Overview Decode error:%v", err)
  64. return nil, common.NewResult(code.InternalError)
  65. }
  66. results = append(results, &result)
  67. }
  68. if err := cursor.Err(); err != nil {
  69. mhayaLogger.Warnf("Overview cursor error:%v", err)
  70. return nil, common.NewResult(code.InternalError)
  71. }
  72. // TODO 综合统计相关信息
  73. // TODO 获取总数total
  74. var count int64
  75. return &entity.OverviewResp{
  76. Details: results,
  77. Total: count,
  78. }, nil
  79. }
  80. // 统计用户相关信息
  81. func (s *Synthesis) UserList(req entity.UserListReq) (*entity.UserListResp, *code.Result) {
  82. page, pageSize := checkPageParam(req.Page, req.Size)
  83. playerMgr := NewPlayerManage()
  84. // 根据条件查询
  85. if req.UserName != "" {
  86. detail, codeResult := s.getUserDetail(req.UserName)
  87. if codeResult != nil {
  88. mhayaLogger.Warnf("UserList getUserDetail error:%v", codeResult)
  89. return nil, codeResult
  90. }
  91. if detail == nil {
  92. return nil, nil
  93. }
  94. var results []*entity.UserListDetail
  95. results = append(results, detail)
  96. return &entity.UserListResp{
  97. Details: results,
  98. Total: 1,
  99. }, nil
  100. }
  101. // 查询列表
  102. listResp, codeResult := playerMgr.List(context.Background(), entity.PlayerListReq{
  103. Page: page,
  104. Size: pageSize,
  105. })
  106. if codeResult != nil {
  107. mhayaLogger.Warnf("UserList List error:%v", codeResult)
  108. return nil, codeResult
  109. }
  110. var results []*entity.UserListDetail
  111. for _, detail := range listResp.Details {
  112. ret, codeResult := s.getUserDetail(detail.UserName)
  113. if codeResult != nil {
  114. mhayaLogger.Warnf("UserList getUserDetail error:%v", codeResult)
  115. return nil, codeResult
  116. }
  117. if detail != nil {
  118. results = append(results, ret)
  119. }
  120. }
  121. count, codeResult := playerMgr.GetPlayerTotalCount()
  122. if codeResult != nil {
  123. mhayaLogger.Warnf("UserList GetPlayerTotalCount codeResult:%v", codeResult)
  124. return nil, codeResult
  125. }
  126. return &entity.UserListResp{
  127. Details: results,
  128. Total: int64(count),
  129. }, nil
  130. }
  131. func (s *Synthesis) getUserDetail(userName string) (*entity.UserListDetail, *code.Result) {
  132. playerMgr := NewPlayerManage()
  133. // 获取注册记录
  134. registerRecord, codeResult := playerMgr.GetRegisterRecord(userName)
  135. if codeResult != nil {
  136. mhayaLogger.Warnf("getUserDetail GetRegisterRecord error:%v", codeResult)
  137. return nil, codeResult
  138. }
  139. if registerRecord == nil {
  140. mhayaLogger.Warnf("getUserDetail registerRecord:%v", registerRecord)
  141. return nil, nil
  142. }
  143. // 获取用户的首次登录记录
  144. firstLoginRecord, codeResult := playerMgr.GetPlayerFirstLoginRecord(userName)
  145. if codeResult != nil {
  146. mhayaLogger.Warnf("getUserDetail GetPlayerFirstLoginRecord error:%v", codeResult)
  147. return nil, codeResult
  148. }
  149. if firstLoginRecord == nil {
  150. mhayaLogger.Warnf("getUserDetail firstLoginRecord:%v", firstLoginRecord)
  151. return nil, nil
  152. }
  153. // 获取最新的用户登录记录
  154. loginRecord, codeResult := playerMgr.GetPlayerLastestLoginRecord(userName)
  155. if codeResult != nil {
  156. mhayaLogger.Warnf("getUserDetail GetPlayerLastestLoginRecord error:%v", codeResult)
  157. return nil, codeResult
  158. }
  159. if loginRecord == nil {
  160. mhayaLogger.Warnf("getUserDetail loginRecord:%v", loginRecord)
  161. return nil, nil
  162. }
  163. return &entity.UserListDetail{
  164. UserName: userName,
  165. OpenId: loginRecord.TgId,
  166. CreateTime: registerRecord.CreateAt,
  167. FirstLoginDate: firstLoginRecord.CreateAt,
  168. LoginIP: loginRecord.Ip,
  169. LastLoginTime: loginRecord.CreateAt,
  170. TonWall: loginRecord.TonWall,
  171. Fingerprint: loginRecord.Fingerprint,
  172. }, nil
  173. }
  174. func (s *Synthesis) FindMDBUserLogDaily(req entity.UserLogDailyReq) (*entity.UserLogDailyResp, *code.Result) {
  175. page, pageSize := checkPageParam(req.Page, req.Size)
  176. // 定义上下文
  177. ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
  178. defer cancel()
  179. // 指定集合
  180. collection := mdb.MDB.Collection(constant.CNamePlayerDailyRecord)
  181. // 构建查询条件 - 如果查询值为空那就不添加查询条件
  182. filter := bson.M{}
  183. if req.StartTime != 0 {
  184. filter["daily"] = bson.M{
  185. "$gte": req.StartTime,
  186. "$lte": req.EndTime,
  187. }
  188. }
  189. if req.Platform != "" && req.Platform != "all" {
  190. filter["platform"] = req.Platform
  191. }
  192. if req.Channel != "" {
  193. filter["channel"] = req.Channel
  194. }
  195. // 计算总数
  196. count, err := collection.CountDocuments(ctx, filter)
  197. if err != nil {
  198. mhayaLogger.Warnf("FindMDBUserLogDaily CountDocuments error:%v", err)
  199. return nil, common.NewResult(code.InternalError)
  200. }
  201. // 执行查询
  202. opts := options.Find()
  203. opts.SetSkip(int64((page - 1) * pageSize))
  204. opts.SetLimit(int64(pageSize))
  205. opts.SetSort(bson.D{{"daily", -1}})
  206. cursor, err := collection.Find(ctx, filter, opts)
  207. if err != nil {
  208. mhayaLogger.Warnf("FindMDBUserLogDaily Find error:%v", err)
  209. return nil, common.NewResult(code.InternalError)
  210. }
  211. defer cursor.Close(ctx)
  212. // 解析查询结果
  213. var results []*entity.UserLogDailyDetail
  214. for cursor.Next(ctx) {
  215. var result *entity.UserLogDailyDetail
  216. err := cursor.Decode(&result)
  217. if err != nil {
  218. mhayaLogger.Warnf("FindMDBUserLogDaily Decode error:%v", err)
  219. return nil, common.NewResult(code.InternalError)
  220. }
  221. results = append(results, result)
  222. }
  223. // 同一天的数据全部放到platform= ALl 且数据累加
  224. // 如果没有platform=all 的那就新增一个 同一个时间段只能有一个 platform=all
  225. // 将同一天的数据累加到platform=all的记录中
  226. allPlatformRecordMap := make(map[int64]*entity.UserLogDailyDetail)
  227. for _, result := range results {
  228. allPlatformRecordMap[result.Timestamp] = &entity.UserLogDailyDetail{
  229. Timestamp: result.Timestamp,
  230. Platform: "all",
  231. }
  232. }
  233. for _, v := range results {
  234. if v.Timestamp == allPlatformRecordMap[v.Timestamp].Timestamp {
  235. allPlatformRecordMap[v.Timestamp].Registered += v.Registered
  236. allPlatformRecordMap[v.Timestamp].LoggedIn += v.LoggedIn
  237. allPlatformRecordMap[v.Timestamp].NewActive += v.NewActive
  238. allPlatformRecordMap[v.Timestamp].OldActive += v.OldActive
  239. allPlatformRecordMap[v.Timestamp].TotalPoints += v.TotalPoints
  240. allPlatformRecordMap[v.Timestamp].UProduced += v.UProduced
  241. allPlatformRecordMap[v.Timestamp].UCashout += v.UCashout
  242. allPlatformRecordMap[v.Timestamp].NewLogin += v.NewLogin
  243. allPlatformRecordMap[v.Timestamp].OldLogin += v.OldLogin
  244. }
  245. }
  246. // 替换原有结果
  247. for _, record := range allPlatformRecordMap {
  248. results = append(results, record)
  249. }
  250. return &entity.UserLogDailyResp{
  251. Details: results,
  252. Total: count,
  253. }, nil
  254. }
  255. // FindWithdrawal 根据请求查询提现记录
  256. func (s *Synthesis) FindWithdrawal(req entity.UserWithdrawalReq) (*entity.UserWithdrawalResp, *code.Result) {
  257. page, pageSize := checkPageParam(req.Page, req.Size)
  258. if !constant.CurrencyValid(req.Currency) {
  259. mhayaLogger.Warnf("FindWithdrawal unknow currency:%v", req.Currency)
  260. return nil, common.NewResult(code.ParamError)
  261. }
  262. var records []*eventmodels.UserWithdrawEventContent
  263. where := &eventmodels.UserWithdrawEventContent{
  264. UserBasic: eventmodels.UserBasic{
  265. UserId: req.UserName,
  266. UserName: req.NickName,
  267. },
  268. EventBasic: eventmodels.EventBasic{
  269. ServerId: s.nodeId,
  270. Status: req.Withdrawal,
  271. },
  272. WithdrawId: req.ID,
  273. Currency: req.Currency,
  274. Address: req.Address,
  275. State: req.State,
  276. }
  277. db := mdb.LogstashDB.Model(&eventmodels.UserWithdrawEventContent{}).Where(where).Order("create_at")
  278. if req.StartTime > 0 && req.EndTime > 0 && req.StartTime <= req.EndTime {
  279. db = db.Where("create_at >= ? and create_at <= ?", req.StartTime, req.EndTime)
  280. }
  281. if req.AmountMin > 0 && req.AmountMax > 0 && req.AmountMin <= req.AmountMax {
  282. db = db.Where("amount >= ? and amount <= ?", req.AmountMin, req.AmountMax)
  283. }
  284. if req.AfterAmountMin > 0 && req.AfterAmountMax > 0 && req.AfterAmountMin <= req.AfterAmountMax {
  285. db = db.Where("after_balance >= ? and after_balance <= ?", req.AfterAmountMin, req.AfterAmountMax)
  286. }
  287. pages := Paginate(db, page, pageSize)
  288. err := db.Scopes(pages.Limit).Find(&records).Error
  289. if err != nil && err != gorm.ErrRecordNotFound {
  290. mhayaLogger.Warnf("FindWithdrawal Find error:%v", err)
  291. return nil, common.NewResult(code.InternalError)
  292. }
  293. var results []*entity.UserWithdrawalDetail
  294. for _, v := range records {
  295. results = append(results, &entity.UserWithdrawalDetail{
  296. Id: v.WithdrawId,
  297. UserName: v.UserId,
  298. NickName: v.UserName,
  299. OpenId: v.TgId,
  300. Status: v.State,
  301. Reason: v.Reason,
  302. Withdrawal: v.Status,
  303. Amount: int(v.Amount),
  304. AfterAmount: int(v.AfterBalance),
  305. Type: v.Currency,
  306. Address: v.Address,
  307. CreateAt: v.CreateAt,
  308. UpdateAt: v.CreateAt,
  309. })
  310. }
  311. return &entity.UserWithdrawalResp{
  312. Details: results,
  313. Total: pages.Count,
  314. }, nil
  315. }
  316. // 导出提现记录
  317. func (s *Synthesis) WithdrawalExport(req entity.UserWithdrawalExportReq) (*entity.UserWithdrawalResp, *code.Result) {
  318. ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
  319. defer cancel()
  320. collection := mdb.MDB.Collection(constant.CNameCashOutRecord)
  321. // 构建过滤器
  322. filter := bson.M{}
  323. if req.UserName != "" {
  324. filter["userName"] = req.UserName
  325. }
  326. if req.NickName != "" {
  327. filter["nickName"] = req.NickName
  328. }
  329. if req.ID != "" {
  330. filter["_id"], _ = primitive.ObjectIDFromHex(req.ID)
  331. }
  332. if req.Address != "" {
  333. filter["address"] = req.Address
  334. }
  335. if req.State > 0 {
  336. filter["state"] = req.State
  337. }
  338. if req.Withdrawal > 0 {
  339. filter["withdrawal"] = req.Withdrawal
  340. }
  341. if req.StartTime > 0 && req.EndTime > 0 && req.StartTime <= req.EndTime {
  342. filter["createAt"] = bson.M{
  343. "$gte": req.StartTime,
  344. "$lte": req.EndTime,
  345. }
  346. }
  347. if req.AmountMin > 0 && req.AmountMax > 0 && req.AmountMin <= req.AmountMax {
  348. filter["amount"] = bson.M{
  349. "$gte": req.AmountMin,
  350. "$lte": req.AmountMax,
  351. }
  352. }
  353. if req.AfterAmountMin > 0 && req.AfterAmountMax > 0 && req.AfterAmountMin <= req.AfterAmountMax {
  354. filter["after_amount"] = bson.M{
  355. "$gte": req.AfterAmountMin,
  356. "$lte": req.AfterAmountMax,
  357. }
  358. }
  359. findOptions := options.Find()
  360. findOptions.SetSort(bson.D{{"createAt", -1}})
  361. // 获取总数total
  362. count, err := collection.CountDocuments(ctx, filter)
  363. if err != nil {
  364. mhayaLogger.Warnf("WithdrawalExportData CountDocuments error:%v", err)
  365. return nil, common.NewResult(code.InternalError)
  366. }
  367. // 查询数据
  368. var results []*entity.UserWithdrawalDetail
  369. cursor, err := collection.Find(ctx, filter, findOptions)
  370. if err != nil {
  371. mhayaLogger.Warnf("WithdrawalExportData Find error:%v", err)
  372. return nil, common.NewResult(code.InternalError)
  373. }
  374. defer cursor.Close(ctx)
  375. // 解析结果
  376. for cursor.Next(ctx) {
  377. var result entity.UserWithdrawalDetail
  378. if err := cursor.Decode(&result); err != nil {
  379. mhayaLogger.Warnf("WithdrawalExportData Decode error:%v", err)
  380. return nil, common.NewResult(code.InternalError)
  381. }
  382. results = append(results, &result)
  383. }
  384. if err := cursor.Err(); err != nil {
  385. mhayaLogger.Warnf("WithdrawalExportData cursor error:%v", err)
  386. return nil, common.NewResult(code.InternalError)
  387. }
  388. return &entity.UserWithdrawalResp{
  389. Details: results,
  390. Total: count,
  391. }, nil
  392. }
  393. // WithdrawalStatus 更新提现状态
  394. func (s *Synthesis) WithdrawalStatus(req entity.UserWithdrawalStatus) *code.Result {
  395. // ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
  396. // defer cancel()
  397. collection := mdb.MDB.Collection(constant.CNameCashOutRecord)
  398. // 更新条件
  399. updateCondition := bson.M{"userName": req.UserName}
  400. // 更新内容
  401. updateContent := bson.M{"$set": bson.M{"status": req.Status}}
  402. // 设置更新选项
  403. updateOptions := options.Update() // 设置 upsert 选项
  404. // 执行更新操作
  405. _, err := collection.UpdateOne(context.TODO(), updateCondition, updateContent, updateOptions)
  406. if err != nil {
  407. mhayaLogger.Warnf("WithdrawalStatus UpdateOne error:%v", err)
  408. return common.NewResult(code.InternalError)
  409. }
  410. return nil
  411. }
  412. // WithdrawalStatusBatch 更新提现状态
  413. func (s *Synthesis) WithdrawalStatusBatch(req entity.UserWithdrawalStatusBatch) *code.Result {
  414. collection := mdb.MDB.Collection(constant.CNameCashOutRecord)
  415. if len(req.ID) == 0 {
  416. return common.NewResult(code.ParamError)
  417. }
  418. for _, id := range req.ID {
  419. objID := primitive.ObjectID{}
  420. objID, _ = primitive.ObjectIDFromHex(id)
  421. updateCondition := bson.M{"_id": objID}
  422. updateContent := bson.M{}
  423. withdrawal := models.CashOutRecord{}
  424. err := collection.FindOne(context.TODO(), updateCondition).Decode(&withdrawal)
  425. if err != nil {
  426. mhayaLogger.Warnf("WithdrawalStatusBatch FindOne error:%v", err)
  427. continue
  428. }
  429. if req.Withdrawal != 0 {
  430. if withdrawal.Status == 1 {
  431. updateContent = bson.M{"$set": bson.M{"withdrawal": req.Withdrawal}}
  432. } else {
  433. continue
  434. }
  435. }
  436. if req.Status > 0 {
  437. if withdrawal.Status != 0 {
  438. continue
  439. }
  440. updateContent = bson.M{"$set": bson.M{"status": req.Status}}
  441. }
  442. updateOptions := options.Update().SetUpsert(true)
  443. _, err = collection.UpdateOne(context.TODO(), updateCondition, updateContent, updateOptions)
  444. if err != nil {
  445. mhayaLogger.Warnf("WithdrawalStatusBatch UpdateOne error:%v", err)
  446. continue
  447. }
  448. }
  449. return nil
  450. }
  451. // FindUserCountryCount 查询用户国家分布
  452. //
  453. // 返回值为 UserCountryResp 的切片和错误。
  454. func (s *Synthesis) FindUserCountryCount() (*entity.UserCountryResp, *code.Result) {
  455. // 选择数据库和集合
  456. collection := mdb.MDB.Collection(constant.CNamePlayerCountryByIPStat)
  457. // 定义聚合管道
  458. // 定义聚合管道
  459. pipeline := []bson.D{
  460. {
  461. {Key: "$project", Value: bson.D{
  462. {Key: "playerRegisterCountry", Value: bson.D{{Key: "$objectToArray", Value: "$playerRegisterCountry"}}},
  463. }},
  464. },
  465. {
  466. {Key: "$unwind", Value: "$playerRegisterCountry"},
  467. },
  468. {
  469. {Key: "$group", Value: bson.D{
  470. {Key: "_id", Value: "$playerRegisterCountry.k"},
  471. {Key: "totalValue", Value: bson.D{{Key: "$sum", Value: "$playerRegisterCountry.v"}}},
  472. }},
  473. },
  474. {
  475. {Key: "$project", Value: bson.D{
  476. {Key: "_id", Value: 0},
  477. {Key: "countryKey", Value: "$_id"},
  478. {Key: "totalValue", Value: 1},
  479. }},
  480. },
  481. }
  482. // 执行聚合查询
  483. cursor, err := collection.Aggregate(context.TODO(), pipeline)
  484. if err != nil {
  485. mhayaLogger.Warnf("FindUserCountryCount Aggregate error:%v", err)
  486. return nil, common.NewResult(code.InternalError)
  487. }
  488. defer cursor.Close(context.TODO())
  489. // 遍历查询结果
  490. var results []bson.M
  491. if err := cursor.All(context.TODO(), &results); err != nil {
  492. mhayaLogger.Warnf("FindUserCountryCount All error:%v", err)
  493. return nil, common.NewResult(code.InternalError)
  494. }
  495. var totalIPCount int64
  496. var data []*entity.UserCountryDetail
  497. // 将结果转换为 UserCountryDetail
  498. for _, r := range results {
  499. var resp entity.UserCountryDetail
  500. resp.Country = r["countryKey"].(string)
  501. resp.IPCount = int(r["totalValue"].(int32))
  502. totalIPCount += int64(resp.IPCount)
  503. data = append(data, &resp)
  504. }
  505. for _, v := range data {
  506. // 保留小数点后两位
  507. v.Percentage = math.Round(float64(v.IPCount)/float64(totalIPCount)*10000) / 100
  508. }
  509. // 根据阈值过滤结果
  510. otherCount := 0
  511. otherPercentage := 0.00
  512. filteredResults := make([]*entity.UserCountryDetail, 0)
  513. threshold := 1.00
  514. for _, r := range data {
  515. if r.Percentage >= threshold {
  516. filteredResults = append(filteredResults, r)
  517. // 保留小数点后两位
  518. r.Percentage = math.Round(r.Percentage*100) / 100
  519. otherPercentage += r.Percentage
  520. } else {
  521. otherCount += r.IPCount
  522. }
  523. }
  524. // 将其他国家添加到过滤后的结果中
  525. if otherCount > 0 {
  526. p := 100.00 - math.Round(otherPercentage*100)/100
  527. filteredResults = append(filteredResults, &entity.UserCountryDetail{
  528. Country: "other",
  529. IPCount: otherCount,
  530. Percentage: math.Round(p*100) / 100,
  531. })
  532. }
  533. return &entity.UserCountryResp{
  534. Details: filteredResults,
  535. }, nil
  536. }
  537. // FindUserRetention UserRetentionResp 用户留存率
  538. // 1. 获取指定日期范围内的注册用户数量
  539. // 2. 获取指定日期范围内的活跃用户数量
  540. // 3. 计算留存率
  541. // 4. 返回结果
  542. func (s *Synthesis) FindUserRetention(req entity.UserRetentionReq) (*entity.UserRetentionResp, *code.Result) {
  543. playerPreserve := models.GetPlayerPreserve(req.StartTime, req.EndTime)
  544. // 查询数据
  545. var results []*entity.UserRetentionDetail
  546. for key, v := range playerPreserve {
  547. var retention entity.Retention
  548. for _, vv := range v {
  549. if vv.ID == 1 {
  550. retention.Day1 = entity.DayRetention{
  551. LoggedIn: vv.Ratio,
  552. LoginDate: key,
  553. }
  554. }
  555. if vv.ID == 3 {
  556. retention.Day3 = entity.DayRetention{
  557. LoggedIn: vv.Ratio,
  558. LoginDate: key,
  559. }
  560. }
  561. if vv.ID == 7 {
  562. retention.Day7 = entity.DayRetention{
  563. LoggedIn: vv.Ratio,
  564. LoginDate: key,
  565. }
  566. }
  567. if vv.ID == 14 {
  568. retention.Day14 = entity.DayRetention{
  569. LoggedIn: vv.Ratio,
  570. LoginDate: key,
  571. }
  572. }
  573. if vv.ID == 30 {
  574. retention.Day30 = entity.DayRetention{
  575. LoggedIn: vv.Ratio,
  576. LoginDate: key,
  577. }
  578. }
  579. }
  580. results = append(results, &entity.UserRetentionDetail{
  581. RegistrationDate: key,
  582. RetentionData: retention,
  583. })
  584. }
  585. return &entity.UserRetentionResp{
  586. Details: results,
  587. }, nil
  588. }
  589. // FindUserLevel 用户等级统计
  590. func (s *Synthesis) FindUserLevel() (*entity.UserLevelCountResp, *code.Result) {
  591. ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
  592. defer cancel()
  593. collection := mdb.MDB.Collection(constant.CNamePlayerLevelStat)
  594. // 查询所有文档
  595. cursor, err := collection.Find(ctx, bson.M{})
  596. if err != nil {
  597. mhayaLogger.Warnf("FindUserLevel Find error:%v", err)
  598. return nil, common.NewResult(code.InternalError)
  599. }
  600. defer cursor.Close(ctx)
  601. var results []*entity.UserLevelCountDetail
  602. var reData []*models.PlayerLevelStat
  603. for cursor.Next(ctx) {
  604. var result models.PlayerLevelStat
  605. if err := cursor.Decode(&result); err != nil {
  606. mhayaLogger.Warnf("FindUserLevel Decode error:%v", err)
  607. return nil, common.NewResult(code.InternalError)
  608. }
  609. reData = append(reData, &result)
  610. }
  611. if err := cursor.Err(); err != nil {
  612. mhayaLogger.Warnf("FindUserLevel cursor error:%v", err)
  613. return nil, common.NewResult(code.InternalError)
  614. }
  615. dataMap := make(map[string]int)
  616. for _, v := range reData {
  617. for key, v1 := range v.ServerLevel {
  618. dataMap[key] += v1
  619. }
  620. }
  621. keys := make([]string, 0, len(dataMap))
  622. for k := range dataMap {
  623. keys = append(keys, k)
  624. }
  625. sort.Strings(keys)
  626. for _, v := range keys {
  627. results = append(results, &entity.UserLevelCountDetail{
  628. Level: cast.ToInt(v),
  629. UserCount: dataMap[v],
  630. })
  631. }
  632. return &entity.UserLevelCountResp{
  633. Details: results,
  634. }, nil
  635. }
  636. func (s *Synthesis) InsertRecord(param model.UserOperationLog) {
  637. mhayaLogger.Warnf("InsertRecord param:%#v", param)
  638. record := new(model.UserOperationLog)
  639. collection := mdb.MDB.Collection(record.TableName())
  640. insertData := bson.M{}
  641. insertData["user_name"] = param.Username
  642. insertData["role_id"] = param.RoleId
  643. insertData["url"] = param.Path
  644. insertData["method"] = param.Method
  645. insertData["status_code"] = param.StatusCode
  646. insertData["dur"] = param.Dur
  647. insertData["client_ip"] = param.ClientIP
  648. insertData["error_message"] = param.ErrorMessage
  649. insertData["created_at"] = mhayaTime.Now().Unix()
  650. _, err := collection.InsertOne(context.Background(), insertData)
  651. if err != nil {
  652. mhayaLogger.Warnf("InsertRecord InsertOne error:%v", err)
  653. return
  654. }
  655. }
  656. func (s *Synthesis) RecordList(req entity.RecordListReq) (*entity.RecordListResp, *code.Result) {
  657. page, pageSize := checkPageParam(req.Page, req.Size)
  658. var records []*eventmodels.BackendOperationEventContent
  659. where := &eventmodels.BackendOperationEventContent{
  660. UserBasic: eventmodels.UserBasic{
  661. UserName: req.UserName,
  662. },
  663. EventBasic: eventmodels.EventBasic{
  664. ServerId: s.nodeId,
  665. },
  666. RoleId: req.RoleId,
  667. Path: req.Path,
  668. StatusCode: req.StatusCode,
  669. ClientIP: req.ClientIP,
  670. }
  671. db := mdb.LogstashDB.Model(&eventmodels.BackendOperationEventContent{}).Where(where).Order("create_at")
  672. if req.StartTime > 0 && req.EndTime > 0 && req.StartTime <= req.EndTime {
  673. db = db.Where("create_at >= ? and create_at <= ?", req.StartTime, req.EndTime)
  674. }
  675. if req.DurMin > 0 && req.DurMax > 0 && req.DurMin <= req.DurMax {
  676. db = db.Where("dur >= ? and dur <= ?", req.DurMin, req.DurMax)
  677. }
  678. pages := Paginate(db, page, pageSize)
  679. err := db.Scopes(pages.Limit).Find(&records).Error
  680. if err != nil && err != gorm.ErrRecordNotFound {
  681. mhayaLogger.Warnf("RecordList Find error:%v", err)
  682. return nil, common.NewResult(code.InternalError)
  683. }
  684. var results []*entity.RecordListDetail
  685. for _, v := range records {
  686. results = append(results, &entity.RecordListDetail{
  687. Username: v.UserName,
  688. RoleId: v.RoleId,
  689. Path: v.Path,
  690. Method: v.Method,
  691. StatusCode: v.StatusCode,
  692. Dur: v.Dur,
  693. ClientIP: v.ClientIP,
  694. ErrorMessage: v.ErrorMessage,
  695. CreatedAt: v.CreateAt,
  696. })
  697. }
  698. return &entity.RecordListResp{
  699. Details: results,
  700. Total: pages.Count,
  701. }, nil
  702. }
  703. // 转盘统计
  704. func (s *Synthesis) Turntable(req entity.TurntableReq) (*entity.TurntableResp, *code.Result) {
  705. page, pageSize := checkPageParam(req.Page, req.Size)
  706. var records []*eventmodels.TurntableEventContent
  707. where := &eventmodels.TurntableEventContent{
  708. UserBasic: eventmodels.UserBasic{
  709. UserId: req.UserName,
  710. },
  711. }
  712. db := mdb.LogstashDB.Model(&eventmodels.TurntableEventContent{}).Where(where).Order("create_at")
  713. if req.StartTime > 0 && req.EndTime > 0 && req.StartTime <= req.EndTime {
  714. db = db.Where("create_at >= ? and create_at <= ?", req.StartTime, req.EndTime)
  715. }
  716. pages := Paginate(db, page, pageSize)
  717. err := db.Scopes(pages.Limit).Find(&records).Error
  718. if err != nil && err != gorm.ErrRecordNotFound {
  719. mhayaLogger.Warnf("Turntable Find error:%v", err)
  720. return nil, common.NewResult(code.InternalError)
  721. }
  722. var results []*entity.TurntableDetail
  723. for _, v := range records {
  724. results = append(results, &entity.TurntableDetail{
  725. UserName: v.UserName,
  726. OpenId: v.TgId,
  727. TurntableExecutionTime: v.CreateAt,
  728. PrizeName: v.PrizeName,
  729. PrizeNumber: v.PrizeNumber,
  730. })
  731. }
  732. return &entity.TurntableResp{
  733. Details: results,
  734. Total: pages.Count,
  735. }, nil
  736. }
  737. // 资产统计
  738. func (s *Synthesis) Assets(req entity.AssetsReq) (*entity.AssetsResp, *code.Result) {
  739. page, pageSize := checkPageParam(req.Page, req.Size)
  740. playerMgr := NewPlayerManage()
  741. // 根据条件查询
  742. if req.UserName != "" {
  743. registerRecord, codeResult := playerMgr.GetRegisterRecord(req.UserName)
  744. if codeResult != nil {
  745. mhayaLogger.Warnf("Assets GetRegisterRecord error:%v", codeResult)
  746. return nil, codeResult
  747. }
  748. if registerRecord == nil {
  749. mhayaLogger.Warnf("Assets registerRecord:%v", registerRecord)
  750. return nil, nil
  751. }
  752. var results []*entity.AssetsDetail
  753. detail, codeResult := s.getAsset(req.UserName)
  754. if codeResult != nil {
  755. mhayaLogger.Warnf("Assets getAsset error:%v", codeResult)
  756. return nil, codeResult
  757. }
  758. results = append(results, detail)
  759. return &entity.AssetsResp{
  760. Details: results,
  761. Total: 1,
  762. }, nil
  763. }
  764. // 查询列表
  765. listResp, codeResult := playerMgr.List(context.Background(), entity.PlayerListReq{
  766. Page: page,
  767. Size: pageSize,
  768. })
  769. if codeResult != nil {
  770. mhayaLogger.Warnf("Assets List error:%v", codeResult)
  771. return nil, codeResult
  772. }
  773. var results []*entity.AssetsDetail
  774. for _, detail := range listResp.Details {
  775. ret, codeResult := s.getAsset(detail.UserName)
  776. if codeResult != nil {
  777. mhayaLogger.Warnf("Assets getAsset error:%v", codeResult)
  778. return nil, codeResult
  779. }
  780. results = append(results, ret)
  781. }
  782. count, codeResult := playerMgr.GetPlayerTotalCount()
  783. if codeResult != nil {
  784. mhayaLogger.Warnf("Assets GetPlayerTotalCount codeResult:%v", codeResult)
  785. return nil, codeResult
  786. }
  787. return &entity.AssetsResp{
  788. Details: results,
  789. Total: int64(count),
  790. }, nil
  791. }
  792. func (s *Synthesis) getAsset(userName string) (*entity.AssetsDetail, *code.Result) {
  793. var totalUsdtAmount int64
  794. var totalTonAmount int64
  795. where := &eventmodels.AssetsEventContent{
  796. UserBasic: eventmodels.UserBasic{
  797. UserId: userName,
  798. },
  799. EventBasic: eventmodels.EventBasic{
  800. ServerId: s.nodeId,
  801. },
  802. }
  803. where.Currency = string(constant.UsdtCurrency)
  804. err := mdb.LogstashDB.Model(&eventmodels.AssetsEventContent{}).Where(where).Pluck("SUM(amount) as total_amount", &totalUsdtAmount).Error
  805. if err != nil {
  806. mhayaLogger.Warnf("getAsset Pluck UsdtCurrency error:%v", err)
  807. return nil, common.NewResult(code.InternalError)
  808. }
  809. where.Currency = string(constant.TonCurrency)
  810. err = mdb.LogstashDB.Model(&eventmodels.AssetsEventContent{}).Where(where).Pluck("SUM(amount) as total_amount", &totalTonAmount).Error
  811. if err != nil {
  812. mhayaLogger.Warnf("getAsset Pluck TonCurrency error:%v", err)
  813. return nil, common.NewResult(code.InternalError)
  814. }
  815. return &entity.AssetsDetail{
  816. UserName: userName,
  817. TonValue: cutils.QuoInt64ByRatioToFloat64(totalTonAmount, constant.MoneyRatio),
  818. UsdtValue: cutils.QuoInt64ByRatioToFloat64(totalUsdtAmount, constant.MoneyRatio),
  819. StatisticalDate: mhayaTime.Now().Unix(),
  820. }, nil
  821. }
  822. // 资产变动记录
  823. func (s *Synthesis) AssetsRecord(req entity.AssetsRecordReq) (*entity.AssetsRecordResp, *code.Result) {
  824. page, pageSize := checkPageParam(req.Page, req.Size)
  825. if !constant.CurrencyValid(req.Currency) {
  826. mhayaLogger.Warnf("AssetsRecord unknow currency:%v", req.Currency)
  827. return nil, common.NewResult(code.ParamError)
  828. }
  829. if req.OperationType != string(constant.IncreaseOp) && req.OperationType != string(constant.DecreaseOp) {
  830. mhayaLogger.Warnf("AssetsRecord unknow OperationType:%v", req.OperationType)
  831. return nil, common.NewResult(code.ParamError)
  832. }
  833. var records []*eventmodels.AssetsEventContent
  834. where := &eventmodels.AssetsEventContent{
  835. UserBasic: eventmodels.UserBasic{
  836. UserId: req.UserName,
  837. },
  838. EventBasic: eventmodels.EventBasic{
  839. ServerId: s.nodeId,
  840. },
  841. OperationType: req.OperationType,
  842. Currency: req.Currency,
  843. Amount: req.Amount,
  844. }
  845. db := mdb.LogstashDB.Model(&eventmodels.AssetsEventContent{}).Where(where).Order("create_at")
  846. if req.StartTime > 0 && req.EndTime > 0 && req.StartTime <= req.EndTime {
  847. db = db.Where("create_at >= ? and create_at <= ?", req.StartTime, req.EndTime)
  848. }
  849. pages := Paginate(db, page, pageSize)
  850. err := db.Scopes(pages.Limit).Find(&records).Error
  851. if err != nil && err != gorm.ErrRecordNotFound {
  852. mhayaLogger.Warnf("Invite Find error:%v", err)
  853. return nil, common.NewResult(code.InternalError)
  854. }
  855. var results []*entity.AssetsRecordDetail
  856. for _, v := range records {
  857. results = append(results, &entity.AssetsRecordDetail{
  858. UserName: v.UserName,
  859. AssetType: string(v.Currency),
  860. AssetsGrowth: v.Amount,
  861. AcquisitionTime: v.CreateAt,
  862. SourceOfAssetAcquisition: v.Reason,
  863. })
  864. }
  865. return &entity.AssetsRecordResp{
  866. Details: results,
  867. Total: pages.Count,
  868. }, nil
  869. }
  870. // 邀请统计
  871. func (s *Synthesis) Invite(req entity.InviteReq) (*entity.InviteResp, *code.Result) {
  872. page, pageSize := checkPageParam(req.Page, req.Size)
  873. var records []*eventmodels.InviteEventContent
  874. where := &eventmodels.InviteEventContent{
  875. UserBasic: eventmodels.UserBasic{
  876. UserId: req.UserName,
  877. },
  878. }
  879. db := mdb.LogstashDB.Model(&eventmodels.InviteEventContent{}).Where(where).Order("create_at")
  880. pages := Paginate(db, page, pageSize)
  881. err := db.Scopes(pages.Limit).Find(&records).Error
  882. if err != nil && err != gorm.ErrRecordNotFound {
  883. mhayaLogger.Warnf("Invite Find error:%v", err)
  884. return nil, common.NewResult(code.InternalError)
  885. }
  886. var results []*entity.InviteDetail
  887. for _, v := range records {
  888. results = append(results, &entity.InviteDetail{
  889. UserName: v.UserName,
  890. OpenId: v.TgId,
  891. InviteID: v.UserId,
  892. IfInviteVIP: v.IfInviteUserTgVip,
  893. InviteTime: v.CreateAt,
  894. SuccessfulInvitationsLV2: int64(v.InviteUserLevel2),
  895. CumulativesuccessfulInvitations: int64(v.ContinuousInviteUserCount),
  896. InvitationChannel: v.Channel,
  897. })
  898. }
  899. return &entity.InviteResp{
  900. Details: results,
  901. Total: pages.Count,
  902. }, nil
  903. }
  904. // 活跃统计
  905. func (s *Synthesis) Active(req entity.ActiveReq) (*entity.ActiveResp, *code.Result) {
  906. page, pageSize := checkPageParam(req.Page, req.Size)
  907. playerMgr := NewPlayerManage()
  908. // 根据条件查询
  909. if req.UserName != "" {
  910. detail, codeResult := s.getActive(req.UserName)
  911. if codeResult != nil {
  912. mhayaLogger.Warnf("Active getActive error:%v", codeResult)
  913. return nil, codeResult
  914. }
  915. if detail == nil {
  916. return nil, nil
  917. }
  918. var results []*entity.ActiveDetail
  919. results = append(results, detail)
  920. return &entity.ActiveResp{
  921. Details: results,
  922. Total: 1,
  923. }, nil
  924. }
  925. // 查询列表
  926. listResp, codeResult := playerMgr.List(context.Background(), entity.PlayerListReq{
  927. Page: page,
  928. Size: pageSize,
  929. })
  930. if codeResult != nil {
  931. mhayaLogger.Warnf("Active List error:%v", codeResult)
  932. return nil, codeResult
  933. }
  934. var results []*entity.ActiveDetail
  935. for _, detail := range listResp.Details {
  936. detail, codeResult := s.getActive(detail.UserName)
  937. if codeResult != nil {
  938. mhayaLogger.Warnf("Active getActive error:%v", codeResult)
  939. return nil, codeResult
  940. }
  941. if detail != nil {
  942. results = append(results, detail)
  943. }
  944. }
  945. count, codeResult := playerMgr.GetPlayerTotalCount()
  946. if codeResult != nil {
  947. mhayaLogger.Warnf("Active GetPlayerTotalCount codeResult:%v", codeResult)
  948. return nil, codeResult
  949. }
  950. return &entity.ActiveResp{
  951. Details: results,
  952. Total: count,
  953. }, nil
  954. }
  955. func (s *Synthesis) getActive(userName string) (*entity.ActiveDetail, *code.Result) {
  956. playerMgr := NewPlayerManage()
  957. // 获取注册记录
  958. registerRecord, codeResult := playerMgr.GetRegisterRecord(userName)
  959. if codeResult != nil {
  960. mhayaLogger.Warnf("getActive GetRegisterRecord error:%v", codeResult)
  961. return nil, codeResult
  962. }
  963. if registerRecord == nil {
  964. mhayaLogger.Warnf("getActive registerRecord:%v", registerRecord)
  965. return nil, nil
  966. }
  967. // 获取最新的用户登录记录
  968. loginRecord, codeResult := playerMgr.GetPlayerLastestLoginRecord(userName)
  969. if codeResult != nil {
  970. mhayaLogger.Warnf("getActive GetPlayerLastestLoginRecord error:%v", codeResult)
  971. return nil, codeResult
  972. }
  973. if loginRecord == nil {
  974. mhayaLogger.Warnf("getActive loginRecord:%v", loginRecord)
  975. return nil, nil
  976. }
  977. // 邀请成功人数
  978. inviteCount, codeResult := playerMgr.GetSuccessfulInvitations(userName, 0)
  979. if codeResult != nil {
  980. mhayaLogger.Warnf("getActive GetSuccessfulInvitations error:%v", codeResult)
  981. return nil, codeResult
  982. }
  983. // 提现次数
  984. withdrawCount, codeResult := playerMgr.GetWithdrawalCount(userName, -1)
  985. if codeResult != nil {
  986. mhayaLogger.Warnf("getActive GetWithdrawalCount error:%v", codeResult)
  987. return nil, codeResult
  988. }
  989. // 累计提现金额
  990. // TODO 暂定USDT
  991. cumulativeWithdrawalAmount, codeResult := playerMgr.GetCumulativeWithdrawalAmount(userName, string(constant.UsdtCurrency), -1)
  992. if codeResult != nil {
  993. mhayaLogger.Warnf("getActive GetCumulativeWithdrawalAmount error:%v", codeResult)
  994. return nil, codeResult
  995. }
  996. // 转盘实际抽奖次数
  997. turntableRuns, codeResult := playerMgr.GetTurntableRuns(userName)
  998. if codeResult != nil {
  999. mhayaLogger.Warnf("getActive GetTurntableRuns error:%v", codeResult)
  1000. return nil, codeResult
  1001. }
  1002. return &entity.ActiveDetail{
  1003. UserName: userName,
  1004. IfUserVip: loginRecord.IfTgVip,
  1005. CreateTime: registerRecord.CreateAt,
  1006. LastLoginTime: loginRecord.CreateAt,
  1007. MaxSuccessions: loginRecord.ContinuousDaysMax,
  1008. SuccessfulInvitations: inviteCount,
  1009. Withdrawals: withdrawCount,
  1010. CumulativeWithdrawalAmount: cumulativeWithdrawalAmount,
  1011. TurntableRuns: turntableRuns,
  1012. }, nil
  1013. }
  1014. // 任务完成度统计
  1015. func (s *Synthesis) TaskCompletion(req entity.TaskCompletionReq) (*entity.TaskCompletionResp, *code.Result) {
  1016. page, pageSize := checkPageParam(req.Page, req.Size)
  1017. playerMgr := NewPlayerManage()
  1018. // 根据条件查询
  1019. if req.UserName != "" {
  1020. detail, codeResult := s.getTaskCompletionDetail(req.UserName)
  1021. if codeResult != nil {
  1022. mhayaLogger.Warnf("TaskCompletion getTaskCompletionDetail error:%v", codeResult)
  1023. return nil, codeResult
  1024. }
  1025. if detail == nil {
  1026. return nil, nil
  1027. }
  1028. var results []*entity.TaskCompletionDetail
  1029. results = append(results, detail)
  1030. return &entity.TaskCompletionResp{
  1031. Details: results,
  1032. Total: 1,
  1033. }, nil
  1034. }
  1035. // 查询列表
  1036. listResp, codeResult := playerMgr.List(context.Background(), entity.PlayerListReq{
  1037. Page: page,
  1038. Size: pageSize,
  1039. })
  1040. if codeResult != nil {
  1041. mhayaLogger.Warnf("TaskCompletion List error:%v", codeResult)
  1042. return nil, codeResult
  1043. }
  1044. var results []*entity.TaskCompletionDetail
  1045. for _, detail := range listResp.Details {
  1046. ret, codeResult := s.getTaskCompletionDetail(detail.UserName)
  1047. if codeResult != nil {
  1048. mhayaLogger.Warnf("TaskCompletion getTaskCompletionDetail error:%v", codeResult)
  1049. return nil, codeResult
  1050. }
  1051. if detail != nil {
  1052. results = append(results, ret)
  1053. }
  1054. }
  1055. count, codeResult := playerMgr.GetPlayerTotalCount()
  1056. if codeResult != nil {
  1057. mhayaLogger.Warnf("TaskCompletion GetPlayerTotalCount codeResult:%v", codeResult)
  1058. return nil, codeResult
  1059. }
  1060. return &entity.TaskCompletionResp{
  1061. Details: results,
  1062. Total: int64(count),
  1063. }, nil
  1064. }
  1065. func (s *Synthesis) getTaskCompletionDetail(userName string) (*entity.TaskCompletionDetail, *code.Result) {
  1066. playerMgr := NewPlayerManage()
  1067. // 获取注册记录
  1068. registerRecord, codeResult := playerMgr.GetRegisterRecord(userName)
  1069. if codeResult != nil {
  1070. mhayaLogger.Warnf("getTaskCompletionDetail GetRegisterRecord error:%v", codeResult)
  1071. return nil, codeResult
  1072. }
  1073. if registerRecord == nil {
  1074. mhayaLogger.Warnf("getTaskCompletionDetail registerRecord:%v", registerRecord)
  1075. return nil, nil
  1076. }
  1077. // 获取用户加入频道的记录
  1078. // TODO 需要定义tg频道
  1079. joinTgRecord, codeResult := playerMgr.GetJoinRecord(userName, "TgChannel")
  1080. if codeResult != nil {
  1081. mhayaLogger.Warnf("getTaskCompletionDetail GetJoinRecord error:%v", codeResult)
  1082. return nil, codeResult
  1083. }
  1084. // TODO 需要定义DC频道
  1085. joinDcRecord, codeResult := playerMgr.GetJoinRecord(userName, "DcChannel")
  1086. if codeResult != nil {
  1087. mhayaLogger.Warnf("getTaskCompletionDetail GetJoinRecord error:%v", codeResult)
  1088. return nil, codeResult
  1089. }
  1090. // 获取用户关注的记录
  1091. // TODO 需要定义Twitter
  1092. followTwitterRecord, codeResult := playerMgr.GetFollowRecord(userName, "Twitter")
  1093. if codeResult != nil {
  1094. mhayaLogger.Warnf("getTaskCompletionDetail GetFollowRecord error:%v", codeResult)
  1095. return nil, codeResult
  1096. }
  1097. // TODO 需要定义Youtube
  1098. followYoutubeRecord, codeResult := playerMgr.GetFollowRecord(userName, "Youtube")
  1099. if codeResult != nil {
  1100. mhayaLogger.Warnf("getTaskCompletionDetail GetFollowRecord error:%v", codeResult)
  1101. return nil, codeResult
  1102. }
  1103. // 获取最新的用户信息更新记录
  1104. updateRecord, codeResult := playerMgr.GetPlayerLastestUpdateRecord(userName)
  1105. if codeResult != nil {
  1106. mhayaLogger.Warnf("getTaskCompletionDetail GetPlayerLastestUpdateRecord error:%v", codeResult)
  1107. return nil, codeResult
  1108. }
  1109. // 邀请成功人数
  1110. inviteCount, codeResult := playerMgr.GetSuccessfulInvitations(userName, 0)
  1111. if codeResult != nil {
  1112. mhayaLogger.Warnf("getTaskCompletionDetail GetSuccessfulInvitations error:%v", codeResult)
  1113. return nil, codeResult
  1114. }
  1115. return &entity.TaskCompletionDetail{
  1116. UserName: userName,
  1117. DicePerDay: 0, // TODO
  1118. IsJoinTgChannel: func() bool {
  1119. return joinTgRecord != nil
  1120. }(),
  1121. IsFollowTwitter: func() bool {
  1122. return followTwitterRecord != nil
  1123. }(),
  1124. IsJoinDcChannel: func() bool {
  1125. return joinDcRecord != nil
  1126. }(),
  1127. IsBindTwitter: func() bool {
  1128. return updateRecord.XId == ""
  1129. }(),
  1130. IsFollowYoutube: func() bool {
  1131. return followYoutubeRecord != nil
  1132. }(),
  1133. InviteNumber: inviteCount,
  1134. }, nil
  1135. }
  1136. // 用户行为检测
  1137. func (s *Synthesis) BehaviorMonitoring(req entity.BehaviorMonitoringReq) (*entity.BehaviorMonitoringResp, *code.Result) {
  1138. page, pageSize := checkPageParam(req.Page, req.Size)
  1139. var records []*eventmodels.DiceEventContent
  1140. where := &eventmodels.DiceEventContent{
  1141. UserBasic: eventmodels.UserBasic{
  1142. UserId: req.UserName,
  1143. },
  1144. }
  1145. db := mdb.LogstashDB.Model(&eventmodels.DiceEventContent{}).Where(where).Order("create_at")
  1146. pages := Paginate(db, page, pageSize)
  1147. err := db.Scopes(pages.Limit).Find(&records).Error
  1148. if err != nil && err != gorm.ErrRecordNotFound {
  1149. mhayaLogger.Warnf("BehaviorMonitoring Find error:%v", err)
  1150. return nil, common.NewResult(code.InternalError)
  1151. }
  1152. var results []*entity.BehaviorMonitoringDetail
  1153. for _, v := range records {
  1154. results = append(results, &entity.BehaviorMonitoringDetail{
  1155. UserName: v.UserName,
  1156. DieExecutionTime: v.CreateAt,
  1157. })
  1158. }
  1159. return &entity.BehaviorMonitoringResp{
  1160. Details: results,
  1161. Total: pages.Count,
  1162. }, nil
  1163. }