AdPlanService.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: Elton
  5. * Date: 2020/5/22
  6. * Time: 10:18
  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\main\constants\AdConstants;
  13. use think\Config;
  14. class AdPlanService
  15. {
  16. /**
  17. * @var AdPlanService
  18. */
  19. private static $self;
  20. protected $allPositions = [
  21. AdConstants::AD_P_XQ,
  22. AdConstants::AD_P_ZG,
  23. AdConstants::AD_P_YDYDB,
  24. AdConstants::AD_P_ZJYD,
  25. AdConstants::AD_P_SJ,
  26. AdConstants::AD_P_YDYCD,
  27. AdConstants::AD_P_YDY_ZJ_A,
  28. AdConstants::AD_P_YDY_ZJ_B,
  29. AdConstants::AD_P_YDY_ZJ_C,
  30. AdConstants::AD_P_PAY_SCREEN,
  31. AdConstants::AD_P_READ_SCREEN,
  32. AdConstants::AD_P_SIGN_SUCESS,
  33. AdConstants::AD_P_USER_CENTER,
  34. AdConstants::AD_P_TOP_INDEX,
  35. AdConstants::AD_P_CAT_INDEX,
  36. AdConstants::AD_P_CAT_SUB,
  37. AdConstants::AD_P_INDEX_BANNER_A,
  38. AdConstants::AD_P_YDY_TOP,
  39. AdConstants::AD_P_YDY_CHAPTER_SCREEN,
  40. AdConstants::AD_P_INDEX_BANNER_B,
  41. AdConstants::AD_P_INDEX_FLOAT_FRAME,
  42. AdConstants::AD_P_DETAIL_FLOAT_FRAME,
  43. ];
  44. // 福利广告位置
  45. protected $welfarePositions = [
  46. AdConstants::AD_WELFARE_YDQ,
  47. AdConstants::AD_WELFARE_SIGN,
  48. AdConstants::AD_WELFARE_RECHARGE,
  49. AdConstants::AD_WELFARE_RECENT,
  50. ];
  51. /**
  52. * @return AdPlanService
  53. */
  54. public static function instance()
  55. {
  56. if(self::$self == NULL){
  57. self::$self = new self();
  58. }
  59. return self::$self;
  60. }
  61. /**
  62. * @return AdManage
  63. */
  64. public function getAdManageModel()
  65. {
  66. return model('AdManage');
  67. }
  68. /**
  69. * @return AdMaterial
  70. */
  71. public function getAdMaterialModel()
  72. {
  73. return model('AdMaterial');
  74. }
  75. /**
  76. * 刷新所有广告计划
  77. */
  78. public function refreshAllAd()
  79. {
  80. try {
  81. $allAdPlans = [];
  82. $allAdPlans['positions'] = $this->getPositionPlans();
  83. $allAdPlans['materials'] = $this->getAllMaterials();
  84. // 增加福利广告计划和素材
  85. $allAdPlans['welfare_plans'] = $this->getWelfarePlans();
  86. $allAdPlans['welfare_materials'] = $this->getAllWelfareMaterials();
  87. Redis::instance()->set(AdConstants::AD_FULL, json_encode($allAdPlans));
  88. Redis::instance()->set(AdConstants::AD_LATEST_VERSION, substr(md5(time()),0,11));
  89. $this->_updatePlanFlag();
  90. } catch (\Exception $exception) {
  91. LogService::error($exception->getMessage());
  92. }
  93. }
  94. /**
  95. * 刷新缓存后更新广告计划Flag,通知 Job 广告计划有更新
  96. */
  97. private function _updatePlanFlag()
  98. {
  99. try {
  100. $this->getAdManageModel()
  101. ->where('show_endtime', '>=', time())
  102. ->where('state', '=', '1')
  103. ->where("!ISNULL(user_group_id)")
  104. ->update(['flag' => 1]);
  105. LogService::info('AD:更新广告计划Flag');
  106. } catch (\Exception $exception) {
  107. LogService::info('AD:更新广告计划Flag, Error:' . $exception->getMessage());
  108. }
  109. }
  110. /**
  111. * 返回所有的可用素材 (非福利广告素材)
  112. * @return array
  113. */
  114. public function getAllMaterials()
  115. {
  116. $allMaterials = [];
  117. $material_arr = $this->getAdMaterialModel()
  118. ->where('type', 'in', '0,1,2')
  119. ->where('state', '=', '1')
  120. ->where('show_endtime', '>=', time())
  121. ->where('material_position', '<>', '')
  122. ->order('weight', 'desc')
  123. ->order('createtime', 'desc')
  124. ->select();
  125. if ($material_arr) {
  126. foreach ($material_arr as $k => $material) {
  127. $allMaterials[$material->id] = [
  128. 'type' => $material->type,
  129. 'img_url' => $this->getRealUrl($material->img_url),
  130. 'link_url' => $material->link_url,
  131. 'js_code' => $material->js_code,
  132. 'ad_baidu' => $material->ad_baidu,
  133. 'weight' => $material->weight,
  134. 'show_starttime' => $material->show_starttime,
  135. 'show_endtime' => $material->show_endtime,
  136. ];
  137. }
  138. }
  139. return $allMaterials;
  140. }
  141. /**
  142. * 返回所有的可用福利广告素材
  143. * @return array
  144. */
  145. public function getAllWelfareMaterials()
  146. {
  147. $allMaterials = [];
  148. $material_arr = $this->getAdMaterialModel()
  149. ->where('type', '=', '3')
  150. ->where('state', '=', '1')
  151. ->where('show_endtime', '>=', time())
  152. ->order('weight', 'desc')
  153. ->order('createtime', 'desc')
  154. ->select();
  155. if ($material_arr) {
  156. foreach ($material_arr as $k => $material) {
  157. $allMaterials[$material->id] = [
  158. 'type' => $material->type,
  159. 'link_game' => $material->link_game,
  160. 'weight' => $material->weight,
  161. 'show_starttime' => $material->show_starttime,
  162. 'show_endtime' => $material->show_endtime,
  163. ];
  164. }
  165. }
  166. return $allMaterials;
  167. }
  168. /**
  169. * 返回 [位置 => 广告计划] 映射关系
  170. * @return array
  171. */
  172. public function getWelfarePlans()
  173. {
  174. $tmp_plans = [];
  175. // 获取所有未结束的广告计划
  176. $adWelfarePlans = $this->getAdManageModel()
  177. ->join('ad_user_group', 'ad_manage.user_group_id = ad_user_group.id', 'left')
  178. ->where('ad_type', '=', '2')
  179. ->where('show_endtime', '>=', time())
  180. ->where('state', '=', '1')
  181. ->where("!ISNULL(user_group_id)")
  182. ->field('ad_manage.*, ad_user_group.group_name, ad_user_group.group_type')
  183. ->order('weight', 'desc')
  184. ->order('createtime', 'desc')
  185. ->select();
  186. if ($adWelfarePlans) {
  187. foreach ($adWelfarePlans as $key => $plan) {
  188. $tmp_plans[$plan->id] = $this->getAdWelfarePlanItem($plan);
  189. }
  190. }
  191. return $tmp_plans;
  192. }
  193. /**
  194. * 获取所有福利广告计划(用户组 => 非全部用户)
  195. * 给 push 消息使用
  196. */
  197. public function welfarePlans(){
  198. $data = [];
  199. $adWelfarePlans = $this->getAdManageModel()
  200. ->join('ad_user_group', 'ad_manage.user_group_id = ad_user_group.id', 'left')
  201. ->where('ad_type', '=', '2')
  202. ->where('show_endtime', '>=', time())
  203. ->where('state', '=', '1')
  204. ->where("!ISNULL(user_group_id)")
  205. ->where('ad_user_group.group_type', '<>', '0')
  206. ->field('ad_manage.id plan_id, ad_user_group.id user_group_id, ad_user_group.group_name, ad_user_group.group_type, ad_user_group.user_json')
  207. ->order('ad_manage.weight', 'desc')
  208. ->order('ad_manage.createtime', 'desc')
  209. ->select();
  210. if ($adWelfarePlans) {
  211. foreach ($adWelfarePlans as $plan) {
  212. $item = [];
  213. if ($plan->group_type == '1') {
  214. // 如果是自定义用户,从PolarDb数据库中查询自定义的用户ID
  215. $ad_user_group = model('AdUserGroupExtend')->where('user_group_id', '=', $plan->user_group_id)->find();
  216. if ($ad_user_group) {
  217. $item['user_ids'] = $ad_user_group->user_ids;
  218. } else {
  219. $item['user_ids'] = '';
  220. }
  221. } else {
  222. $item['user_ids'] = '';
  223. }
  224. $item['plan_id'] = $plan->plan_id;
  225. $item['group_type'] = $plan->group_type;
  226. $item['user_json'] = $plan->user_json;
  227. array_push($data, $item);
  228. }
  229. }
  230. return $data;
  231. }
  232. /**
  233. * 获取福利计划广告推送的内容
  234. */
  235. public function getWelfareContent()
  236. {
  237. try{
  238. $data = [];
  239. // 获取定时PUSH的广告内容
  240. $adWelfareObj = $this->getAdManageModel()
  241. ->join('ad_user_group', 'ad_manage.user_group_id = ad_user_group.id', 'left')
  242. ->where('ad_type', '=', '2')
  243. ->where('show_endtime', '>=', time())
  244. ->where('state', '=', '1')
  245. ->where("!ISNULL(user_group_id)")
  246. ->where('welfare_json', '<>', '')
  247. ->where('ad_user_group.group_type', '<>', '0')
  248. ->field('ad_manage.id plan_id, ad_manage.welfare_json')
  249. ->order('ad_manage.weight', 'desc')
  250. ->order('ad_manage.createtime', 'desc')
  251. ->find();
  252. if ($adWelfareObj) {
  253. $plan_id = $adWelfareObj->plan_id;
  254. $welfare_json_arr = json_decode(trim($adWelfareObj->welfare_json), true);
  255. $data['title'] = $welfare_json_arr['smart_title'] ?? '';
  256. $data['description'] = $welfare_json_arr['smart_deputy_title'] ?? '';
  257. $data['picurl'] = $welfare_json_arr['smart_icon'] ?? '';
  258. $materialObj = $this->getAdMaterialModel()
  259. ->where('type', '=', '3')
  260. ->where('link_game', '<>', '')
  261. ->order('weight', 'desc')
  262. ->order('id', 'desc')
  263. ->find();
  264. $url = $materialObj->link_game ?? '';
  265. $data['url'] = $url . "?ad_plan={$plan_id}&uid={uid}";
  266. }
  267. return $data;
  268. }catch (\Exception $exception){
  269. LogService::error("AD:" . $exception->getMessage());
  270. }
  271. }
  272. /**
  273. * @return array
  274. */
  275. public function getPositionPlans()
  276. {
  277. $position_plans = []; // 位置 => 广告计划 映射关系
  278. foreach ($this->allPositions as $k => $position) {
  279. $tmp_plans = [];
  280. // 获取所有未结束的广告计划
  281. $adPlans = $this->getAdManageModel()
  282. ->join('ad_user_group', 'ad_manage.user_group_id = ad_user_group.id', 'left')
  283. ->where('show_endtime', '>=', time())
  284. ->where('state', '=', '1')
  285. ->where("find_in_set($position,show_position)")
  286. ->where("!ISNULL(user_group_id)")
  287. ->field('ad_manage.*, ad_user_group.group_name, ad_user_group.group_type')
  288. ->order('weight', 'desc')
  289. ->order('createtime', 'desc')
  290. ->select();
  291. if ($adPlans) {
  292. foreach ($adPlans as $key => $plan) {
  293. $tmp_plans[$plan->id] = $this->getAdPlanItem($plan,$position);
  294. }
  295. }
  296. $position_plans[$position] = $tmp_plans;
  297. }
  298. return $position_plans;
  299. }
  300. /**
  301. * @param $url
  302. * @return mixed
  303. */
  304. public function getRealUrl($url)
  305. {
  306. $patten = "/^http[s]?:/";
  307. if (!preg_match($patten, $url)) {
  308. $url = Config::get('Site.cdnurl') . '/' . $url;
  309. }
  310. return $url;
  311. }
  312. /**
  313. * 返回 福利广告计划 实体对象
  314. * @param $plan
  315. * @param $position
  316. * @return array
  317. */
  318. public function getAdWelfarePlanItem(&$plan)
  319. {
  320. $welfare_arr = json_decode($plan->welfare_json, true);
  321. $data = [
  322. 'ad_type' => $plan->ad_type,
  323. 'show_starttime' => $plan->show_starttime,
  324. 'show_endtime' => $plan->show_endtime,
  325. 'weight' => $plan->weight,
  326. 'group_type' => $plan->group_type,
  327. ];
  328. $data = array_merge($data, $welfare_arr);
  329. return $data;
  330. }
  331. /**
  332. * 返回 广告计划 实体对象
  333. * @param $plan
  334. * @param $position
  335. * @return array
  336. */
  337. public function getAdPlanItem(&$plan, $position)
  338. {
  339. $data = [
  340. 'material_ids' => $this->getPositionMaterial($position),
  341. 'ad_type' => $plan->ad_type,
  342. 'show_starttime' => $plan->show_starttime,
  343. 'show_endtime' => $plan->show_endtime,
  344. 'is_slide' => $plan->show_type,
  345. 'weight' => $plan->weight,
  346. 'group_type' => $plan->group_type,
  347. 'chapter_num' => $plan->chapter_num,
  348. 'chapter_start_num' => $plan->chapter_start_num,
  349. 'chapter_step_num' => $plan->chapter_step_num
  350. ];
  351. return $data;
  352. }
  353. /**
  354. * 根据位置返回匹配的素材ID
  355. * @param string $show_position 展示位置 1,2,3 || 1
  356. * @return array
  357. */
  358. public function getPositionMaterial($show_position = '')
  359. {
  360. $tmp_arr = [];
  361. if ($show_position) {
  362. $position = explode(',', $show_position);
  363. foreach ($position as $k => $position) {
  364. $material_arr = $this->getAdMaterialModel()
  365. ->where('state', '=', '1')
  366. ->where("find_in_set($position,material_position)")
  367. ->order('weight', 'desc')
  368. ->order('createtime', 'desc')
  369. ->select();
  370. if ($material_arr) {
  371. foreach ($material_arr as $k => $material) {
  372. array_push($tmp_arr, $material->id);
  373. }
  374. }
  375. }
  376. }
  377. $tmp_arr = array_unique($tmp_arr);
  378. sort($tmp_arr);
  379. return $tmp_arr;
  380. }
  381. /**
  382. * 返回所有的广告位
  383. * @return array
  384. */
  385. public function getAllAdPositions()
  386. {
  387. return $this->allPositions;
  388. }
  389. /**
  390. * 获取福利互动广告内容
  391. * @param $plan_id 福利广告ID
  392. * @return array|mixed
  393. */
  394. public function getWelfarePlan($plan_id)
  395. {
  396. $data = [];
  397. $redis_key = AdConstants::AD_PLAN . $plan_id;
  398. if ($plan = Redis::instance()->get($redis_key)) {
  399. $data = json_decode($plan, true);
  400. } else {
  401. $plan = $this->getAdManageModel()
  402. ->where('ad_type', '=', 2)
  403. ->where('id', '=', $plan_id)
  404. ->where('welfare_json', '<>', '')
  405. ->find();
  406. if ($plan) {
  407. Redis::instance()->set($redis_key, $plan->welfare_json, 86400);
  408. $data = json_decode($plan->welfare_json, true);
  409. }
  410. }
  411. return $data;
  412. }
  413. /**
  414. * 维护广告计划中的flag字段
  415. * @param $user_group_id
  416. * @param $group_type 0:全部,1:自定义,2:条件筛选
  417. */
  418. public function updateFlagByUserGroup($user_group_id, $group_type = 0)
  419. {
  420. try {
  421. if ($group_type) {
  422. $this->getAdManageModel()->update(['flag' => 1], ['user_group_id' => $user_group_id]);
  423. }
  424. } catch (\Exception $exception) {
  425. LogService::info('AD:广告计划更新Flag标志失败');
  426. }
  427. }
  428. }