synthesis.go 42 KB

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