RecordPlatformData.php 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. <?php
  2. namespace App\Services;
  3. use App\Facade\TableName;
  4. use Carbon\Carbon;
  5. use Illuminate\Database\Query\Expression;
  6. use Illuminate\Support\Facades\DB;
  7. class RecordPlatformData
  8. {
  9. // 注册留存 $date = Y-m-d
  10. public function Retain($time1, $time2, $field)
  11. {
  12. //$time1 = Carbon::parse($time1)->format('Y-m-d');
  13. $time2 = $time2->format('Ymd');
  14. $RecordPlatformDataModel = new \App\Models\RecordPlatformData();
  15. $count = DB::connection('read')
  16. ->table($this->withNoLock(TableName::QPAccountsDB() . 'AccountsInfo as ai'))
  17. ->whereExists(function ($query) use ($time2) {
  18. $query->from($this->withNoLock(TableName::QPRecordDB() . 'RecordUserGamePlay as rl'))
  19. ->select('rl.UserID')
  20. // ->whereRaw("rl.UserID=ai.UserID and DateID=CONVERT(VARCHAR(100),DATEADD(dd,$dateNum,'$date'),112)");
  21. ->whereRaw("rl.UserID=ai.UserID and DateID=$time2");
  22. })
  23. ->whereDate('RegisterDate', Carbon::parse($time1)->format('Y-m-d'))
  24. ->selectRaw("count(ai.UserID) $field,Channel")
  25. ->groupBy('Channel')
  26. ->get();
  27. $GroupChannelList = $count->map(function ($value) {
  28. return (array)$value;
  29. })->toArray();
  30. $AllChannelList = $count->sum($field);
  31. foreach ($GroupChannelList as $GroupChannel) {
  32. $firstChannel = $RecordPlatformDataModel
  33. ->where(['Channel' => $GroupChannel['Channel'], 'DateID' => $time1])
  34. ->lock('with(nolock)')
  35. ->first();
  36. if ($firstChannel) {
  37. $RecordPlatformDataModel
  38. ->where(['Channel' => $GroupChannel['Channel'], 'DateID' => $time1])
  39. ->update([$field => $GroupChannel[$field]]);
  40. } else {
  41. $RecordPlatformDataModel->insert([
  42. 'Channel' => $GroupChannel['Channel'],
  43. 'DateID' => $time1,
  44. $field => $GroupChannel[$field],
  45. ]);
  46. }
  47. }
  48. $firstAllChannel = $RecordPlatformDataModel
  49. ->where(['Channel' => -1, 'DateID' => $time1])
  50. ->lock('with(nolock)')
  51. ->first();
  52. if ($firstAllChannel) {
  53. $RecordPlatformDataModel
  54. ->where(['Channel' => -1, 'DateID' => $time1])
  55. ->update([$field => $AllChannelList]);
  56. } else {
  57. $RecordPlatformDataModel->insert([
  58. 'Channel' => -1,
  59. 'DateID' => $time1,
  60. $field => $AllChannelList,
  61. ]);
  62. }
  63. return true;
  64. }
  65. // 活跃留存 $date = Y-m-d
  66. public function activeRetain($time1, $time2, $field)
  67. {
  68. $time2 = $time2->format('Ymd');
  69. $RecordPlatformDataModel = new \App\Models\RecordPlatformData();
  70. $count = DB::connection('read')
  71. ->table($this->withNoLock(TableName::QPRecordDB() . 'RecordUserLogin as rul'))
  72. ->join($this->withNoLock(TableName::QPAccountsDB() . 'AccountsInfo as ai'), 'rul.UserID', 'ai.UserID')
  73. ->whereExists(function ($query) use ($time2) {
  74. $query->from($this->withNoLock(TableName::QPRecordDB() . 'RecordUserLogin as rl'))
  75. ->select('rl.UserID')
  76. ->whereRaw("rl.UserID=rul.UserID and DateID=$time2");
  77. })
  78. ->where('DateID', $time1)
  79. ->selectRaw("count(rul.UserID) $field,Channel")
  80. ->groupBy('Channel')
  81. ->get();
  82. $GroupChannelList = $count->map(function ($value) {
  83. return (array)$value;
  84. })->toArray();
  85. $AllChannelList = $count->sum($field);
  86. foreach ($GroupChannelList as $GroupChannel) {
  87. $firstChannel = $RecordPlatformDataModel
  88. ->where(['Channel' => $GroupChannel['Channel'], 'DateID' => $time1])
  89. ->lock('with(nolock)')
  90. ->first();
  91. if ($firstChannel) {
  92. $RecordPlatformDataModel
  93. ->where(['Channel' => $GroupChannel['Channel'], 'DateID' => $time1])
  94. ->update([$field => $GroupChannel[$field]]);
  95. } else {
  96. $RecordPlatformDataModel->insert([
  97. 'Channel' => $GroupChannel['Channel'],
  98. 'DateID' => $time1,
  99. $field => $GroupChannel[$field],
  100. ]);
  101. }
  102. }
  103. $firstAllChannel = $RecordPlatformDataModel
  104. ->where(['Channel' => -1, 'DateID' => $time1])
  105. ->lock('with(nolock)')
  106. ->first();
  107. if ($firstAllChannel) {
  108. $RecordPlatformDataModel
  109. ->where(['Channel' => -1, 'DateID' => $time1])
  110. ->update([$field => $AllChannelList]);
  111. } else {
  112. $RecordPlatformDataModel->insert([
  113. 'Channel' => -1,
  114. 'DateID' => $time1,
  115. $field => $AllChannelList,
  116. ]);
  117. }
  118. return true;
  119. }
  120. // 付费留存 $date = Y-m-d
  121. /**
  122. * @param $time1 // 充值日期
  123. * @param $time2 // 充值第二天日期
  124. * @param $field // 查找/修改 的字段
  125. * @return bool
  126. */
  127. public function payRetain($time1, $time2, $field)
  128. {
  129. $time2 = $time2->format('Ymd');
  130. $RecordPlatformDataModel = new \App\Models\RecordPlatformData();
  131. $dateID = $time1;
  132. $count = DB::connection('read')
  133. ->table($this->withNoLock(TableName::QPRecordDB() . 'RecordUserDataStatisticsNew as record'))
  134. ->join($this->withNoLock(TableName::QPAccountsDB() . 'AccountsInfo as ai'), 'record.UserID', 'ai.UserID')
  135. ->whereExists(function ($query) use ($time2) {
  136. $query->from($this->withNoLock(TableName::QPRecordDB() . 'RecordUserGamePlay as rl'))
  137. ->select('rl.UserID')
  138. ->whereRaw("rl.UserID=record.UserID and DateID=$time2");
  139. })
  140. ->where('Recharge', '>', 0)
  141. ->where('DateID', $time1)
  142. ->where([
  143. ['ai.RegisterDate', '>=', Carbon::createFromFormat('Ymd', $time1)->format('Y-m-d')],
  144. ['ai.RegisterDate', '<', Carbon::createFromFormat('Ymd', $time1)->addDay(1)
  145. ->format('Y-m-d')]
  146. ])
  147. ->selectRaw("count(record.UserID) $field,Channel")
  148. ->groupBy('Channel')
  149. ->get();
  150. $GroupChannelList = $count->map(function ($value) {
  151. return (array)$value;
  152. })->toArray();
  153. $AllChannelList = $count->sum($field);
  154. foreach ($GroupChannelList as $GroupChannel) {
  155. $firstChannel = $RecordPlatformDataModel
  156. ->where(['Channel' => $GroupChannel['Channel'], 'DateID' => $dateID])
  157. ->lock('with(nolock)')
  158. ->first();
  159. if ($firstChannel) {
  160. $RecordPlatformDataModel
  161. ->where(['Channel' => $GroupChannel['Channel'], 'DateID' => $dateID])
  162. ->update([$field => $GroupChannel[$field]]);
  163. } else {
  164. $RecordPlatformDataModel->insert([
  165. 'Channel' => $GroupChannel['Channel'],
  166. 'DateID' => $dateID,
  167. $field => $GroupChannel[$field],
  168. ]);
  169. }
  170. }
  171. $firstAllChannel = $RecordPlatformDataModel
  172. ->where(['Channel' => -1, 'DateID' => $dateID])
  173. ->lock('with(nolock)')
  174. ->first();
  175. if ($firstAllChannel) {
  176. $RecordPlatformDataModel
  177. ->where(['Channel' => -1, 'DateID' => $dateID])
  178. ->update([$field => $AllChannelList]);
  179. } else {
  180. $RecordPlatformDataModel->insert([
  181. 'Channel' => -1,
  182. 'DateID' => $dateID,
  183. $field => $AllChannelList,
  184. ]);
  185. }
  186. return true;
  187. }
  188. /**
  189. * 统计老付费用户(非当日注册)当日有/无充值的平均游戏局数,写入 RecordPlatformData
  190. *
  191. * @param string $dateID Ymd
  192. * @param \Carbon\Carbon $date
  193. * @return bool
  194. */
  195. public function oldPayUserAvgGameCountStat($dateID, $date)
  196. {
  197. $dao = new \App\dao\RecordPlatformData\RecordPlatformData();
  198. $stats = $dao->oldPayUserAvgGameCountStatBundle($dateID, $date);
  199. $withRecharge = $stats['withRecharge'];
  200. $withoutRecharge = $stats['withoutRecharge'];
  201. $withRechargeAll = $stats['withRechargeAll'];
  202. $withoutRechargeAll = $stats['withoutRechargeAll'];
  203. $withoutRechargeByChannel = $withoutRecharge->keyBy('Channel');
  204. foreach ($withRecharge as $item) {
  205. $paySecond = $withoutRechargeByChannel->get($item->Channel);
  206. $dao->Update([
  207. 'DateID' => $dateID,
  208. 'PayGameCount' => round($item->PayGameCount ?? 0, 2),
  209. 'PaySecond' => round($paySecond->PaySecond ?? 0, 2),
  210. ], $item->Channel, $item->Channel, $dateID);
  211. }
  212. foreach ($withoutRecharge as $item) {
  213. if ($withRecharge->firstWhere('Channel', $item->Channel)) {
  214. continue;
  215. }
  216. $dao->Update([
  217. 'DateID' => $dateID,
  218. 'PayGameCount' => 0,
  219. 'PaySecond' => round($item->PaySecond ?? 0, 2),
  220. ], $item->Channel, $item->Channel, $dateID);
  221. }
  222. $dao->Update([
  223. 'DateID' => $dateID,
  224. 'PayGameCount' => round($withRechargeAll->PayGameCount ?? 0, 2),
  225. 'PaySecond' => round($withoutRechargeAll->PaySecond ?? 0, 2),
  226. ], -1, -1, $dateID);
  227. return true;
  228. }
  229. /**
  230. * Build SQL Server table expression with NOLOCK hint for read-heavy statistics queries.
  231. *
  232. * @param string $table
  233. * @return Expression
  234. */
  235. private function withNoLock($table)
  236. {
  237. return DB::raw($table . ' WITH (NOLOCK)');
  238. }
  239. }