AdService.php 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: Elton
  5. * Date: 2020/5/19
  6. * Time: 9:58
  7. */
  8. namespace app\common\service;
  9. use app\common\library\Redis;
  10. use app\common\model\AdManage;
  11. use app\common\model\AdMaterial;
  12. use app\common\model\object\UserObject;
  13. use app\main\constants\AdConstants;
  14. // 该类已弃用
  15. class AdService
  16. {
  17. /**
  18. * @var AdService
  19. */
  20. private static $self;
  21. /**
  22. * @return AdService
  23. */
  24. public static function instance()
  25. {
  26. if(self::$self == NULL){
  27. self::$self = new self();
  28. }
  29. return self::$self;
  30. }
  31. /**
  32. * @return AdManage
  33. */
  34. public function getAdManageModel()
  35. {
  36. return model('AdManage');
  37. }
  38. /**
  39. * @return AdMaterial
  40. */
  41. public function getAdMaterialModel()
  42. {
  43. return model('AdMaterial');
  44. }
  45. /**
  46. * 第一步:根据位置查询所有匹配的广告计划ID
  47. * @param $position_code 位置编号
  48. * @return string 匹配的广告计划ID
  49. */
  50. public function getAllPlan($position_code)
  51. {
  52. // 这里从缓存哩读数据
  53. $data = $this->getAllAd();
  54. if ($data) {
  55. $arr = [];
  56. foreach ($data as $k => $item) {
  57. if (in_array($position_code, explode(',', $item['show_position']))) {
  58. array_push($arr, $item['id']);
  59. };
  60. }
  61. return implode(',', $arr);
  62. } else {
  63. return '';
  64. }
  65. }
  66. /**
  67. * 第二步:遍历所有计划,过滤出匹配用户ID的计划
  68. * @param $position_code
  69. * @param $uid
  70. * @param $channel_id
  71. * @return array
  72. */
  73. public function getMatchPlan($position_code, $uid, $channel_id)
  74. {
  75. $match_plans = [];
  76. $plans = $this->getAllPlan($position_code);
  77. if ($plans) {
  78. $plan_arr = explode(',', $plans);
  79. foreach ($plan_arr as $k => $ad_id) {
  80. // $ad_id => 计划ID
  81. // 这里需要获取用户渠道ID AD:JU:计划id:渠道号
  82. $redis_key = AdConstants::AD_JU_KEY . $ad_id . $channel_id;
  83. $uid_str = Redis::instance()->get($redis_key);
  84. if($uid_str){
  85. $uid_arr = implode(',', $uid_str);
  86. if(in_array($uid, $uid_arr)){
  87. array_push($match_plan, $ad_id);
  88. }
  89. }
  90. }
  91. }
  92. return $match_plans;
  93. }
  94. /**
  95. * 第三步:通过计划查找合适的素材
  96. * @param $position_code 位置编号
  97. * @param $uid 用户ID
  98. * @param $channel_id 渠道ID
  99. * @return array
  100. */
  101. public function getMatchAdMaterial($position_code, $uid, $channel_id)
  102. {
  103. $matchPlans = $this->getMatchPlan($position_code, $uid, $channel_id);
  104. $banner_ad_ids = []; //
  105. $screen_material_ids = []; //插屏
  106. if ($matchPlans) {
  107. foreach ($matchPlans as $k => $ad_id) {
  108. // $ad_id => ad_manage 对应ID
  109. $redis_key = AdConstants::AD_P_KEY.$ad_id;
  110. $redis_data = Redis::instance()->get($redis_key);
  111. if($redis_data){
  112. $obj = json_decode($redis_data);
  113. if ($obj->ad_type == '1') {
  114. //插屏广告
  115. if ($obj->state) {
  116. array_push($screen_material_ids, $ad_id);
  117. }
  118. } else {
  119. //Banner广告
  120. if ($obj->state) {
  121. array_push($banner_ad_ids, $ad_id);
  122. }
  123. }
  124. }
  125. }
  126. }
  127. $data = [];
  128. switch ($position_code) {
  129. case AdConstants::AD_P_XQ:
  130. //书籍详情页
  131. $data = $this->_getMultiMaterial($banner_ad_ids,$uid,AdConstants::AD_P_XQ);
  132. break;
  133. case AdConstants::AD_P_ZG:
  134. //追更页
  135. $data = $this->_getMultiMaterial($banner_ad_ids,$uid,AdConstants::AD_P_ZG);
  136. break;
  137. case AdConstants::AD_P_YDYDB:
  138. //阅读页底部
  139. $data = $this->_getMultiMaterial($banner_ad_ids,$uid,AdConstants::AD_P_YDYDB);
  140. break;
  141. case AdConstants::AD_P_ZJYD:
  142. //最近阅读
  143. $data = $this->_getOneMaterial($banner_ad_ids,$uid,AdConstants::AD_P_ZJYD);
  144. break;
  145. case AdConstants::AD_P_SJ:
  146. //书架
  147. $data = $this->_getOneMaterial($banner_ad_ids,$uid,AdConstants::AD_P_SJ);
  148. break;
  149. case AdConstants::AD_P_YDYCD:
  150. //阅读页顶部菜单下拉
  151. $data = $this->_getOneMaterial($banner_ad_ids,$uid,AdConstants::AD_P_YDYCD);
  152. break;
  153. case AdConstants::AD_P_YDY_ZJ_A:
  154. //阅读页中间1
  155. $data = $this->_getOneMaterial($banner_ad_ids,$uid,AdConstants::AD_P_YDY_ZJ_A, 'screen');
  156. break;
  157. default:
  158. //阅读页中间2 AdConstants::AD_P_YDY_ZJ_B
  159. $data = $this->_getOneMaterial($banner_ad_ids, $uid,AdConstants::AD_P_YDY_ZJ_B,'screen');
  160. }
  161. return $data;
  162. }
  163. /**
  164. * 获取单个Banner 素材
  165. * @param array $banner_ad_ids
  166. * @param $uid
  167. * @param string $type
  168. * @param int $position
  169. * @return array
  170. */
  171. private function _getOneMaterial(array $banner_ad_ids, $uid, $position = 0, $type = 'banner')
  172. {
  173. // 打点广告ID
  174. $dot_ad_ids = implode(',', $banner_ad_ids);
  175. $rst = [];
  176. // 从缓存哩取数据
  177. $data = $this->getMaterial($type);
  178. if($data){
  179. $idx = rand(0, count($data)-1);
  180. $item = $data[$idx];
  181. $rst = [
  182. 'material_id' =>$item->id,
  183. 'img_url' =>$item->img_url,
  184. 'link_url' =>$item->link_url,
  185. 'ad_ids' => $dot_ad_ids,
  186. 'position' => $position,
  187. 'user_id' => $uid
  188. ];
  189. }
  190. return $rst;
  191. }
  192. /**
  193. * @param array $ad_ids
  194. * @param $uid
  195. * @param int $position
  196. * @param string $type
  197. * @return array
  198. */
  199. private function _getMultiMaterial(array $ad_ids, $uid, $position = 0, $type = 'banner')
  200. {
  201. // 打点广告ID
  202. $dot_ad_ids = implode(',', $ad_ids);
  203. $rst = [];
  204. $data = $this->getMaterial($type);
  205. if (count($data)) {
  206. for ($i = 0; $i < 3; $i++) {
  207. $idx = rand(0, count($data) - 1);
  208. $item = $data[$idx];
  209. array_push($rst, [
  210. 'material_id' => $item->id,
  211. 'img_url' => $item->img_url,
  212. 'link_url' => $item->link_url,
  213. 'ad_ids' => $dot_ad_ids,
  214. 'position' => $position,
  215. 'user_id' => $uid
  216. ]);
  217. }
  218. }
  219. return $rst;
  220. }
  221. /**
  222. * @param $type banner | screen
  223. * @return array
  224. */
  225. public function getMaterial($type)
  226. {
  227. $rst = [];
  228. $material_ids = Redis::instance()->get(AdConstants::AD_SC_IDS);
  229. if ($material_ids) {
  230. $arr = explode(',', $material_ids);
  231. foreach ($arr as $k => $id) {
  232. $material_str = Redis::instance()->get(AdConstants::AD_M_KEY . $id);
  233. if ($material_str) {
  234. $obj = json_decode($material_str);
  235. if ($type == 'banner') {
  236. if ($obj->ad_type == '0') {
  237. // Banner广告
  238. array_push($rst, $obj);
  239. }
  240. } else {
  241. if ($obj->ad_type == '1') {
  242. //插屏广告
  243. array_push($rst, $obj);
  244. }
  245. }
  246. }
  247. }
  248. }
  249. return $rst;
  250. }
  251. public function getAllAd()
  252. {
  253. $rst = [];
  254. $ad_ids = Redis::instance()->get(AdConstants::AD_P_IDS);
  255. if ($ad_ids) {
  256. $arr = explode(',', $ad_ids);
  257. foreach ($arr as $k => $id) {
  258. $ad_str = Redis::instance()->get(AdConstants::AD_P_KEY . $id);
  259. if ($ad_str) {
  260. $obj = json_decode($ad_str);
  261. if ($obj->show_starttime <= time() && $obj->show_endtime >= time()) {
  262. array_push($rst, $obj);
  263. }
  264. }
  265. }
  266. }
  267. return $rst;
  268. }
  269. }