AdPositionService.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. <?php
  2. namespace App\Modules\AdPosition\Services;
  3. use App\Libs\Singleton;
  4. use App\Modules\AdPosition\Models\AdPosition;
  5. use App\Modules\AdPosition\Models\AdPositionDispatch;
  6. use App\Modules\Trade\Services\OrderService;
  7. use App\Modules\User\Models\QappUser;
  8. class AdPositionService
  9. {
  10. use Singleton;
  11. /**
  12. * @param $uid
  13. * @param $accountId
  14. * @return array
  15. */
  16. public function getAdPositions($uid, $accountId): array
  17. {
  18. myLog('getAdPositions')->info('', compact('uid', 'accountId'));
  19. // 参数判断
  20. if (empty($uid) || empty($accountId)) {
  21. return [];
  22. }
  23. // 获取所有有效广告位
  24. $positions = AdPosition::getAllValidAdPositions();
  25. if (empty($positions)) {
  26. return [];
  27. }
  28. // 获取广告位分配信息
  29. $positionIds = array_column($positions, 'id');
  30. $dispatches = AdPositionDispatch::getValidPositionDispatches($positionIds, $accountId);
  31. if (empty($dispatches)) {
  32. return [];
  33. }
  34. // 获取用户相关数据
  35. $userData = $this->getUserFilterData($uid);
  36. myLog('getAdPositions')->info('', compact('uid', 'userData'));
  37. // 针对分配数据筛选出优先级最高的分配任务
  38. $result = [];
  39. $dispatches = collect($dispatches)->groupBy('ad_position_id')->all();
  40. foreach ($positions as $position) {
  41. // 相关变量获取
  42. $positionId = getProp($position, 'id');
  43. $ident = getProp($position, 'ident');
  44. // 获取对应广告位所有任务
  45. $validDispatches = getProp($dispatches, $positionId, []);
  46. if (empty($validDispatches)) {
  47. continue;
  48. }
  49. // 根据优先级循环匹配,直到匹配到为止
  50. $validDispatches = collect($validDispatches)->sortByDesc('priority')->all();
  51. $validDispatch = [];
  52. foreach ($validDispatches as $value) {
  53. // 过滤条件判断
  54. $filterContentJson = getProp($value, 'filter_condition');
  55. $matchFilter = $this->filterDispatch($filterContentJson, $userData);
  56. if ($matchFilter) {
  57. $validDispatch = $value;
  58. break;
  59. }
  60. }
  61. // 判断
  62. if (empty($validDispatch)) {
  63. continue;
  64. }
  65. // 添加到数据中
  66. $result[$ident][] = $this->buildPositionData($validDispatch, $position);
  67. }
  68. return $result;
  69. }
  70. /**
  71. * 用户的数据
  72. * @param $uid
  73. * @return array
  74. */
  75. private function getUserFilterData($uid): array
  76. {
  77. // 获取用户信息
  78. $user = QappUser::getUserByUid($uid);
  79. $registerAt = getProp($user, 'created_at');
  80. $registerUnix = strtotime($registerAt);
  81. // 获取用户付费情况
  82. $order = OrderService::getUserLastestOrder($uid);
  83. $isPaid = $order ? 1 : 0;
  84. return compact('uid', 'registerUnix', 'isPaid');
  85. }
  86. /**
  87. * 过滤条件筛选
  88. * @param $filterContentJson
  89. * @param $userData
  90. * @return bool
  91. */
  92. private function filterDispatch($filterContentJson, $userData): bool
  93. {
  94. // 过滤条件
  95. $filterContent = json_decode($filterContentJson, true);
  96. if (empty($userData) || empty($filterContentJson) || empty($filterContent)) {
  97. return true;
  98. }
  99. myLog('getAdPositions')->info('', compact('filterContent', 'userData'));
  100. // 判断注册时间
  101. $registerFilter = true;
  102. $registerAtArr = getProp($filterContent, 'registerAt');
  103. if ($registerAtArr) {
  104. // 默认值
  105. $registerFilter = false;
  106. $registerUnix = $userData['registerUnix'];
  107. // 循环条件,满足一条即可
  108. foreach ($registerAtArr as $register) {
  109. $unit = getProp($register, 'unit');
  110. $range = getProp($register, 'range');
  111. sort($range);
  112. [$min, $max] = $range;
  113. $startUnix = strtotime('-' . $max . ' ' . $unit);
  114. $endUnix = strtotime('-' . $min . ' ' . $unit);
  115. if ($registerUnix >= $startUnix && $registerUnix <= $endUnix) {
  116. $registerFilter = true;
  117. break;
  118. }
  119. }
  120. }
  121. // 判断付费情况
  122. $paidFilter = true;
  123. if (getProp($filterContent, 'isPaid') !== '') {
  124. // 获取用户付费情况
  125. $isPaid = getProp($userData, 'isPaid', 0);
  126. $paidFilter = false;
  127. // 有付费
  128. if ($isPaid && (int)getProp($filterContent, 'isPaid') === 1) {
  129. $paidFilter = true;
  130. }
  131. // 未付费
  132. if (!$isPaid && (int)getProp($filterContent, 'isPaid') === 0) {
  133. $paidFilter = true;
  134. }
  135. }
  136. // 两者全部满足条件才可展示
  137. return $registerFilter && $paidFilter;
  138. }
  139. /**
  140. * 返回可显示数据
  141. * @param $validDispatch
  142. * @param $position
  143. * @return array
  144. */
  145. private function buildPositionData($validDispatch, $position): array
  146. {
  147. if (empty($validDispatch)) {
  148. return [];
  149. }
  150. // 链接做特殊处理
  151. $url = getProp($validDispatch, 'link_url');
  152. $urlArr = parse_url($url);
  153. parse_str(getProp($urlArr, 'query'), $queryArr);
  154. // 广告位图片
  155. $image = getProp($validDispatch, 'image_url');
  156. if (empty($image)) {
  157. $image = getProp($position, 'default_img');
  158. }
  159. return [
  160. 'img' => $image,
  161. 'url' => getProp($urlArr, 'path'),
  162. 'title' => getProp($validDispatch, 'title'),
  163. 'params' => $queryArr ?: (object)[]
  164. ];
  165. }
  166. }