Fish.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. <?php
  2. namespace app\command;
  3. use think\console\Command;
  4. use think\console\Input;
  5. use think\console\Output;
  6. use app\model\Company;
  7. use think\facade\Log;
  8. use app\model\FishCampaign;
  9. use app\model\FishCampaignList;
  10. use clue\Fish as clueFish;
  11. use clue\Tencent;
  12. class Fish extends Command
  13. {
  14. protected function configure()
  15. {
  16. $this->setName('fish')
  17. ->setDescription('Automatically update flying fish clues');
  18. }
  19. protected function execute(Input $input, Output $output)
  20. {
  21. Log::close(NULL);
  22. $list = Company::where("channel_setting <> 'null'")->field('root_id,channel_setting,channel_setting_wh')->select()->toArray();
  23. if (empty($list)) return $output->writeln("没有要执行的任务");
  24. $fish = new clueFish(config('app.fish_clue_appid'), config('app.fish_clue_secret'));
  25. $tencent = new Tencent(config('app.tx_clue_appid'), config('app.tx_clue_secret'));
  26. $fish_wh = new clueFish(config('app.fish_clue_appid_wh'), config('app.fish_clue_secret_wh'));
  27. foreach ($list as $val) {
  28. if(isset($val['channel_setting']) && $val['channel_setting']){
  29. $root_id = $val['root_id'];
  30. $tmp_data = json_decode($val['channel_setting'], true);
  31. $tmp_data = $this->refreshToken($fish, $tmp_data, $root_id);
  32. $start_date = date('Y-m-d', strtotime('-1 day'));
  33. //飞鱼数据
  34. $advertiser_id = explode(',', $tmp_data['fish_adv']);
  35. foreach ($advertiser_id as $va) {
  36. $new_data = $fish->getCampaignListV2($tmp_data['fish_access_token'], ['advertiser_id' => $va, 'start_date' => $start_date, 'end_date' => $start_date, 'page' => 1]);
  37. if ($new_data['code'] == 0) {
  38. $page = $new_data['data']['page_info']['total_page'];
  39. $this->update_fish_campaign_data_new($new_data['data']['rows'], $fish, $tmp_data, $root_id, $start_date, $va, 1);
  40. if ($page > 1) {
  41. for ($i = 1; $i < $page; $i++) {
  42. $page_data = $fish->getCampaignListV2($tmp_data['fish_access_token'], ['advertiser_id' => $va, 'start_date' => $start_date, 'end_date' => $start_date, 'page' => $i + 1]);
  43. if ($page_data['code'] == 0) {
  44. $this->update_fish_campaign_data_new($page_data['data']['rows'], $fish, $tmp_data, $root_id, $start_date, $va, 1);
  45. }
  46. }
  47. }
  48. }
  49. $data = $fish->getCampaignList($tmp_data['fish_access_token'], ['advertiser_id' => $va, 'start_date' => $start_date, 'end_date' => $start_date, 'page' => 1]);
  50. if ($data['code'] == 0) {
  51. //如果广告组数据存在多页
  52. $page = $data['data']['page_info']['total_page'];
  53. $this->update_fish_campaign_data($data['data']['list'], $fish, $tmp_data, $root_id, $start_date, $va, 1);
  54. if ($page > 1) {
  55. for ($i = 1; $i < $page; $i++) {
  56. $page_data = $fish->getCampaignList($tmp_data['fish_access_token'], ['advertiser_id' => $va, 'start_date' => $start_date, 'end_date' => $start_date, 'page' => $i + 1]);
  57. if ($page_data['code'] == 0) {
  58. $this->update_fish_campaign_data($page_data['data']['list'], $fish, $tmp_data, $root_id, $start_date, $va, 1);
  59. }
  60. }
  61. }
  62. }
  63. }
  64. //腾讯数据
  65. $advertiser_id = explode(',', $tmp_data['tx_adv']);
  66. foreach ($advertiser_id as $va) {
  67. $data = $tencent->getCampaignList($tmp_data['tx_access_token'], $va, $start_date);
  68. if ($data['code'] == 0) {
  69. $this->update_tx_campaign_data($data['data']['list'], $tencent, $tmp_data, $root_id, $start_date, $va);
  70. }
  71. }
  72. }
  73. if(isset($val['channel_setting_wh']) && $val['channel_setting_wh']){
  74. $root_id = $val['root_id'];
  75. $tmp_data = json_decode($val['channel_setting_wh'], true);
  76. $tmp_data = $this->refreshTokenV2($fish_wh, $tmp_data, $root_id);
  77. $start_date = date('Y-m-d', strtotime('-1 day'));
  78. $advertiser_id = explode(',', $tmp_data['fish_adv']);
  79. foreach ($advertiser_id as $va) {
  80. $new_data = $fish->getCampaignListV2($tmp_data['fish_access_token'], ['advertiser_id' => $va, 'start_date' => $start_date, 'end_date' => $start_date, 'page' => 1]);
  81. if ($new_data['code'] == 0) {
  82. $page = $new_data['data']['page_info']['total_page'];
  83. $this->update_fish_campaign_data_new($new_data['data']['rows'], $fish, $tmp_data, $root_id, $start_date, $va, 4);
  84. if ($page > 1) {
  85. for ($i = 1; $i < $page; $i++) {
  86. $page_data = $fish->getCampaignListV2($tmp_data['fish_access_token'], ['advertiser_id' => $va, 'start_date' => $start_date, 'end_date' => $start_date, 'page' => $i + 1]);
  87. if ($page_data['code'] == 0) {
  88. $this->update_fish_campaign_data_new($page_data['data']['rows'], $fish, $tmp_data, $root_id, $start_date, $va, 4);
  89. }
  90. }
  91. }
  92. }
  93. $data = $fish_wh->getCampaignList($tmp_data['fish_access_token'], ['advertiser_id' => $va, 'start_date' => $start_date, 'end_date' => $start_date, 'page' => 1]);
  94. if ($data['code'] == 0) {
  95. //如果广告组数据存在多页
  96. $page = $data['data']['page_info']['total_page'];
  97. $this->update_fish_campaign_data($data['data']['list'], $fish_wh, $tmp_data, $root_id, $start_date, $va, 4);
  98. if ($page > 1) {
  99. for ($i = 1; $i < $page; $i++) {
  100. $page_data = $fish_wh->getCampaignList($tmp_data['fish_access_token'], ['advertiser_id' => $va, 'start_date' => $start_date, 'end_date' => $start_date, 'page' => $i + 1]);
  101. if ($page_data['code'] == 0) {
  102. $this->update_fish_campaign_data($page_data['data']['list'], $fish_wh, $tmp_data, $root_id, $start_date, $va, 4);
  103. }
  104. }
  105. }
  106. }
  107. }
  108. }
  109. }
  110. $output->writeln("同步完成");
  111. }
  112. /**
  113. * 更新腾讯广告组
  114. */
  115. public function update_tx_campaign_data($list, $tencent, $tmp_data, $root_id, $start_date, $advertiser_id)
  116. {
  117. $tmp = [];
  118. FishCampaign::where(['root_id' => $root_id, 'data_time' => $start_date, 'advertiser_id' => $advertiser_id, 'type' => 2])->delete();
  119. foreach ($list as $v) {
  120. $c_data['type'] = 2;
  121. $c_data['root_id'] = $root_id;
  122. $c_data['data_time'] = $start_date;
  123. $c_data['advertiser_id'] = $v['account_id'];
  124. $c_data['campaign_id'] = $v['adgroup_id'];
  125. $c_data['campaign_name'] = $v['adgroup_name'];
  126. $c_data['stat_datetime'] = '';
  127. $c_data['inventory'] = '';
  128. $c_data['cost'] = $v['cost'] > 0 ? round($v['cost'] / 100, 2) : 0;
  129. $c_data['show'] = $v['view_count'];
  130. $c_data['avg_show_cost'] = $v['thousand_display_price'];
  131. $c_data['click'] = $v['valid_click_count'];
  132. $c_data['avg_click_cost'] = $v['cpc'] > 0 ? round($v['cpc'] / 100, 2) : 0;
  133. $c_data['ctr'] = $v['ctr'] * 100;
  134. $c_data['convert'] = $v['conversions_count'];
  135. $c_data['convert_cost'] = $v['effective_cost'] > 0 ? round($v['effective_cost'] / 100, 2) : 0;
  136. $c_data['convert_rate'] = $v['view_count'] > 0 ? round($v['conversions_count'] / $v['view_count']) : 0;
  137. $c_data['deep_convert'] = 0;
  138. $c_data['deep_convert_cost'] = 0;
  139. $c_data['deep_convert_rate'] = 0;
  140. $tmp[] = $c_data;
  141. FishCampaignList::where(['root_id' => $root_id, 'data_time' => $start_date, 'advertiser_id' => $advertiser_id, 'campaign_id' => $v['adgroup_id'], 'type' => 2])->delete();
  142. $data = $tencent->getCampaignAdList($tmp_data['tx_access_token'], $advertiser_id, $start_date, $v['adgroup_id']);
  143. if ($data['code'] == 0) {
  144. $this->update_tx_adv_data($data['data']['list'], $root_id, $start_date, $advertiser_id);
  145. }
  146. }
  147. FishCampaign::insertAll($tmp);
  148. }
  149. /**
  150. * 更新腾讯广告组下的计划
  151. */
  152. public function update_tx_adv_data($data, $root_id, $data_time, $advertiser_id)
  153. {
  154. $tmp_adv_list = [];
  155. foreach ($data as $val) {
  156. $c_data['advertiser_id'] = $advertiser_id;
  157. $c_data['campaign_id'] = $val['adgroup_id'];
  158. $c_data['campaign_name'] = $val['ad_name'] ?? '';
  159. $c_data['ad_id'] = $val['ad_id'];
  160. $c_data['ad_name'] = $val['ad_name'] ?? '';
  161. $c_data['stat_datetime'] = $val['date'];
  162. $c_data['cost'] = $val['cost'] > 0 ? round($val['cost'] / 100, 2) : 0;
  163. $c_data['show'] = $val['view_count'];
  164. $c_data['click'] = $val['valid_click_count'];
  165. $c_data['avg_click_cost'] = $val['cpc'] > 0 ? round($val['cpc'] / 100, 2) : 0;
  166. $c_data['ctr'] = $val['ctr'] * 100;
  167. $c_data['convert'] = $val['conversions_count'];
  168. $c_data['convert_cost'] = $val['effective_cost'] > 0 ? round($val['effective_cost'] / 100, 2) : 0;
  169. $c_data['convert_rate'] = $val['view_count'] > 0 ? round($val['conversions_count'] / $val['view_count']) : 0;
  170. $c_data['root_id'] = $root_id;
  171. $c_data['data_time'] = $data_time;
  172. $c_data['type'] = 2;
  173. $tmp_adv_list[] = $c_data;
  174. }
  175. FishCampaignList::insertAll($tmp_adv_list);
  176. }
  177. /**
  178. * 更新数据-新版
  179. */
  180. public function update_fish_campaign_data_new($list, $fish, $tmp_data, $root_id, $data_time, $advertiser_id, $type)
  181. {
  182. $data = [];
  183. foreach ($list as $val) {
  184. //先删除昨日数据后插入数据
  185. FishCampaign::where(['root_id' => $root_id, 'data_time' => $data_time, 'advertiser_id' => $advertiser_id, 'campaign_id' => $val['dimensions']['cdp_project_id'], 'type' => $type])->delete();
  186. FishCampaignList::where(['root_id' => $root_id, 'data_time' => $data_time, 'advertiser_id' => $advertiser_id, 'campaign_id' => $val['dimensions']['cdp_project_id'], 'type' => $type])->delete();
  187. $tmp_val['advertiser_id'] = $advertiser_id;
  188. $tmp_val['data_time'] = $data_time;
  189. $tmp_val['root_id'] = $root_id;
  190. $tmp_val['type'] = $type;
  191. $tmp_val['campaign_id'] = $val['dimensions']['cdp_project_id'];
  192. $tmp_val['campaign_name'] = $val['dimensions']['cdp_project_name'];
  193. $tmp_val['cost'] = $val['metrics']['stat_cost'];
  194. $tmp_val['show'] = $val['metrics']['show_cnt'];
  195. $tmp_val['avg_show_cost'] = $val['metrics']['cpm_platform'];
  196. $tmp_val['click'] = $val['metrics']['click_cnt'];
  197. $tmp_val['avg_click_cost'] = $val['metrics']['cpc_platform'];
  198. $tmp_val['ctr'] = $val['metrics']['ctr'];
  199. $tmp_val['convert'] = $val['metrics']['convert_cnt'];
  200. $tmp_val['convert_cost'] = $val['metrics']['conversion_cost'];
  201. $tmp_val['convert_rate'] = $val['metrics']['conversion_rate'];
  202. $tmp_val['deep_convert'] = $val['metrics']['deep_convert_cnt'];
  203. $tmp_val['deep_convert_cost'] = $val['metrics']['deep_convert_cost'];
  204. $tmp_val['deep_convert_rate'] = $val['metrics']['deep_convert_rate'];
  205. $data[] = $tmp_val;
  206. //循环广告组获取广告组下的计划花费
  207. $adv_data = $fish->getAdListV2($tmp_data['fish_access_token'], ['advertiser_id' => $advertiser_id, 'campaign_ids' => $val['dimensions']['cdp_project_id'], 'start_date' => $data_time, 'end_date' => $data_time, 'page' => 1]);
  208. if ($adv_data['code'] == 0) {
  209. $page = $adv_data['data']['page_info']['total_page'];
  210. $this->update_fish_adv_data_new($adv_data['data']['rows'], $root_id, $data_time, $advertiser_id,$val['dimensions']['cdp_project_id'],$val['dimensions']['cdp_project_name'], $type);
  211. //如果广告计划存在多页
  212. if ($page > 1) {
  213. for ($i = 1; $i < $page; $i++) {
  214. $tmp_adv_data = $fish->getAdListV2($tmp_data['fish_access_token'], ['advertiser_id' => $advertiser_id, 'campaign_ids' => $val['dimensions']['cdp_project_id'], 'start_date' => $data_time, 'end_date' => $data_time, 'page' => $i + 1]);
  215. if ($tmp_adv_data['code'] == 0) {
  216. $this->update_fish_adv_data_new($tmp_adv_data['data']['rows'], $root_id, $data_time, $advertiser_id,$val['dimensions']['cdp_project_id'],$val['dimensions']['cdp_project_name'], $type);
  217. }
  218. }
  219. }
  220. }
  221. }
  222. FishCampaign::insertAll($data);
  223. }
  224. /**
  225. * 更新数据
  226. */
  227. public function update_fish_campaign_data($list, $fish, $tmp_data, $root_id, $data_time, $advertiser_id, $type)
  228. {
  229. $data = [];
  230. foreach ($list as $val) {
  231. //先删除昨日数据后插入数据
  232. FishCampaign::where(['root_id' => $root_id, 'data_time' => $data_time, 'advertiser_id' => $advertiser_id, 'campaign_id' => $val['campaign_id'],'type'=>$type])->delete();
  233. FishCampaignList::where(['root_id' => $root_id, 'data_time' => $data_time, 'advertiser_id' => $advertiser_id, 'campaign_id' => $val['campaign_id'],'type'=>$type])->delete();
  234. $val['advertiser_id'] = $advertiser_id;
  235. $val['data_time'] = $data_time;
  236. $val['root_id'] = $root_id;
  237. $val['type'] = $type;
  238. unset($val['id']);
  239. $data[] = $val;
  240. //循环广告组获取广告组下的计划花费
  241. $adv_data = $fish->getAdList($tmp_data['fish_access_token'], ['advertiser_id' => $advertiser_id, 'campaign_ids' => $val['campaign_id'], 'start_date' => $data_time, 'end_date' => $data_time, 'page' => 1]);
  242. if ($adv_data['code'] == 0) {
  243. $page = $adv_data['data']['page_info']['total_page'];
  244. $this->update_fish_adv_data($adv_data['data']['list'], $root_id, $data_time, $advertiser_id, $type);
  245. //如果广告计划存在多页
  246. if ($page > 1) {
  247. for ($i = 1; $i < $page; $i++) {
  248. $tmp_adv_data = $fish->getAdList($tmp_data['fish_access_token'], ['advertiser_id' => $advertiser_id, 'campaign_ids' => $val['campaign_id'], 'start_date' => $data_time, 'end_date' => $data_time, 'page' => $i + 1]);
  249. if ($tmp_adv_data['code'] == 0) {
  250. $this->update_fish_adv_data($tmp_adv_data['data']['list'], $root_id, $data_time, $advertiser_id, $type);
  251. }
  252. }
  253. }
  254. }
  255. }
  256. FishCampaign::insertAll($data);
  257. }
  258. /**
  259. * 更新广告组下的计划
  260. */
  261. public function update_fish_adv_data($data, $root_id, $data_time, $advertiser_id, $type)
  262. {
  263. $tmp_adv_list = [];
  264. foreach ($data as $val) {
  265. unset($val['id']);
  266. unset($val['avg_show_cost']);
  267. $val['root_id'] = $root_id;
  268. $val['advertiser_id'] = $advertiser_id;
  269. $val['data_time'] = $data_time;
  270. $val['type'] = $type;
  271. $tmp_adv_list[] = $val;
  272. }
  273. FishCampaignList::insertAll($tmp_adv_list);
  274. }
  275. /**
  276. * 更新广告组下的计划-新版
  277. */
  278. public function update_fish_adv_data_new($data, $root_id, $data_time, $advertiser_id, $campaign_id, $campaign_name , $type)
  279. {
  280. $tmp_adv_list = [];
  281. foreach ($data as $val) {
  282. $tmp_val['ad_id'] = $val['dimensions']['cdp_promotion_id'];
  283. $tmp_val['ad_name'] = $val['dimensions']['cdp_promotion_name'];
  284. $tmp_val['cost'] = $val['metrics']['stat_cost'];
  285. $tmp_val['show'] = $val['metrics']['show_cnt'];
  286. $tmp_val['avg_click_cost'] = $val['metrics']['cpm_platform'];
  287. $tmp_val['click'] = $val['metrics']['click_cnt'];
  288. $tmp_val['ctr'] = $val['metrics']['ctr'];
  289. $tmp_val['convert'] = $val['metrics']['convert_cnt'];
  290. $tmp_val['convert_cost'] = $val['metrics']['conversion_cost'];
  291. $tmp_val['convert_rate'] = $val['metrics']['conversion_rate'];
  292. $tmp_val['campaign_id'] = $campaign_id;
  293. $tmp_val['campaign_name'] = $campaign_name;
  294. $tmp_val['root_id'] = $root_id;
  295. $tmp_val['advertiser_id'] = $advertiser_id;
  296. $tmp_val['data_time'] = $data_time;
  297. $tmp_val['type'] = $type;
  298. $tmp_adv_list[] = $tmp_val;
  299. }
  300. FishCampaignList::insertAll($tmp_adv_list);
  301. }
  302. /**
  303. * 刷新token
  304. */
  305. public function refreshToken($fish, $tmp_data, $root_id)
  306. {
  307. $fish_refresh_time = $tmp_data['fish_refresh_time']; //上次token更新时间
  308. if ($fish_refresh_time + 80000 < time()) {
  309. $token = $fish->getRefreshToken($tmp_data['fish_refresh_token']);
  310. if ($token['code'] == 0) {
  311. $tmp_data['fish_access_token'] = $token['data']['access_token'];
  312. $tmp_data['fish_refresh_token'] = $token['data']['refresh_token'];
  313. $tmp_data['fish_refresh_time'] = time();
  314. Company::where(['root_id' => $root_id])->update(['channel_setting' => json_encode($tmp_data)]);
  315. } else {
  316. $tmp_data['fish_access_token'] = '';
  317. $tmp_data['fish_refresh_token'] = '';
  318. Company::where(['root_id' => $root_id])->update(['channel_setting' => json_encode($tmp_data)]);
  319. }
  320. }
  321. return $tmp_data;
  322. }
  323. /**
  324. * 刷新token
  325. */
  326. public function refreshTokenV2($fish, $tmp_data, $root_id)
  327. {
  328. $fish_refresh_time = $tmp_data['fish_refresh_time']; //上次token更新时间
  329. if ($fish_refresh_time + 80000 < time()) {
  330. $token = $fish->getRefreshToken($tmp_data['fish_refresh_token']);
  331. if ($token['code'] == 0) {
  332. $tmp_data['fish_access_token'] = $token['data']['access_token'];
  333. $tmp_data['fish_refresh_token'] = $token['data']['refresh_token'];
  334. $tmp_data['fish_refresh_time'] = time();
  335. Company::where(['root_id' => $root_id])->update(['channel_setting_wh' => json_encode($tmp_data)]);
  336. } else {
  337. $tmp_data['fish_access_token'] = '';
  338. $tmp_data['fish_refresh_token'] = '';
  339. Company::where(['root_id' => $root_id])->update(['channel_setting_wh' => json_encode($tmp_data)]);
  340. }
  341. }
  342. return $tmp_data;
  343. }
  344. }