WechatCustumerPushStatistical.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. <?php
  2. namespace App\Console\Commands;
  3. use App\Modules\OfficialAccount\Services\CustomMsgService;
  4. use App\Modules\Statistic\Services\WapVisitStatService;
  5. use Illuminate\Console\Command;
  6. use App\Modules\Subscribe\Models\Order;
  7. use Redis;
  8. use DB;
  9. use App\Modules\OfficialAccount\Models\CustomSendDayStats;
  10. use App\Modules\OfficialAccount\Models\CustomSendStats;
  11. use Log;
  12. class WechatCustumerPushStatistical extends Command
  13. {
  14. /**
  15. * The name and signature of the console command.
  16. *
  17. * @var string
  18. */
  19. protected $signature = 'pay:wcps {--auto} {--all}';
  20. /**
  21. * The console command description.
  22. *
  23. * @var string
  24. */
  25. protected $description = '微信推送数据统计任务';
  26. /**
  27. * Create a new command instance.
  28. *
  29. * @return void
  30. */
  31. public function __construct()
  32. {
  33. parent::__construct();
  34. }
  35. /**
  36. * Execute the console command.
  37. *
  38. * @return mixed
  39. */
  40. public function handle()
  41. {
  42. $all = $this->option('all');
  43. if($all){
  44. $this->autoAll();
  45. }
  46. $auto = $this->option('auto');
  47. if($auto){
  48. $this->updateAutoCustomStats(date('Y-m-d',time()-1*86400));
  49. $this->updateAutoCustomStats(date('Y-m-d',time()-2*86400));
  50. $this->updateAutoCustomStats(date('Y-m-d',time()-3*86400));
  51. $this->totalStats();
  52. }
  53. if(!$all && !$auto){
  54. $this->dayStat();
  55. }
  56. }
  57. public function dayStat()
  58. {
  59. //Redis::sadd('push:activity:distribution_channel_id:'.$this->distribution_channel_id.'from:'.$from.':date:'.date('Y-m-d'),$this->uid);
  60. //Redis::hincrby('customer:push:click:activity:distribution_channel_id:'.$this->distribution_channel_id.'from:'.$from,date('Y-m-d'),1);
  61. //Redis::sadd('push:distribution_channel_id:'.$distribution_channel_id.'from:'.$from,date('Y-m-d'),decrypt($uid_cookie));
  62. //Redis::hincrby('customer:push:click:distribution_channel_id:'.$distribution_channel_id.'from:'.$from,date('Y-m-d'),1);
  63. $day = date('Y-m-d', time() - 86400);
  64. $channel = $this->getChannel();
  65. if (!$channel) return false;
  66. foreach ($channel as $key => $value) {
  67. if ($value->from == 'recovery_push') {
  68. $click_num = Redis::scard('push:activity:distribution_channel_id:' . $value->distribution_channel_id . 'from:recovery_push:date:' . $day);
  69. } else {
  70. $click_num = Redis::scard('push:distribution_channel_id:' . $value->distribution_channel_id . 'from:' . $value->from . ':date:' . $day);
  71. }
  72. $order = Order::where('distribution_channel_id', $value->distribution_channel_id)
  73. ->where('from_type', $value->from)
  74. ->where('status', 'PAID')
  75. ->select(DB::raw('count(*) as count'), DB::raw('sum(price) as money'))
  76. ->whereBetween('created_at', [$day, date('Y-m-d')])
  77. ->first();
  78. if ($value->push_user_num <= 0) {
  79. $success_pay_rate = 0;
  80. $click_rate = 0;
  81. } else {
  82. $success_pay_rate = round($order->count / $value->push_user_num, 4) * 100;
  83. $click_rate = round($click_num / $value->push_user_num, 4) * 100;
  84. }
  85. CustomSendDayStats::where('id', $value->id)->update([
  86. 'click_num' => $click_num,
  87. 'amount' => $order->money,
  88. 'success_pay_num' => $order->count,
  89. 'success_pay_rate' => $success_pay_rate,
  90. 'click_rate' => $click_rate
  91. ]);
  92. $res = CustomSendStats::where('distribution_channel_id', $value->distribution_channel_id)->where('from', $value->from)->first();
  93. if ($res) {
  94. $all_user = $res->push_user_num + $value->push_user_num;
  95. if ($all_user == 0) {
  96. $success_pay_rate = 0;
  97. $click_rate = 0;
  98. } else {
  99. $success_pay_rate = round(($res->success_pay_num + $order->count) / $all_user, 4) * 100;
  100. $click_rate = round(($res->click_num + $click_num) / $all_user, 4) * 100;
  101. }
  102. $res->push_user_num = $all_user;
  103. $res->click_num = $res->click_num + $click_num;
  104. $res->amount = $res->amount + $order->money;
  105. $res->success_pay_num = $res->success_pay_num + $order->count;
  106. $res->click_rate = $click_rate;
  107. $res->success_pay_rate = $success_pay_rate;
  108. $res->save();
  109. } else {
  110. CustomSendStats::create([
  111. 'distribution_channel_id' => $value->distribution_channel_id,
  112. 'push_user_num' => $value->push_user_num,
  113. 'click_num' => $click_num,
  114. 'amount' => $order->money,
  115. 'success_pay_num' => $order->count,
  116. 'success_pay_rate' => $success_pay_rate,
  117. 'from' => $value->from,
  118. 'click_rate' => $click_rate
  119. ]);
  120. }
  121. }
  122. }
  123. public function getChannel()
  124. {
  125. $day = date('Y-m-d', time() - 86400);
  126. $channel = CustomSendDayStats::select('id', 'distribution_channel_id', 'from', 'push_user_num')->where('date', $day)->get();
  127. return $channel;
  128. }
  129. private function autoAll(){
  130. $start = '2018-04-27';
  131. $end = date('Y-m-d',time()-86400);
  132. while (strtotime($start) <= strtotime($end)){
  133. $this->updateAutoCustomStats($start);
  134. $start = date('Y-m-d',strtotime($start)+86400);
  135. }
  136. $this->totalStats(true);
  137. }
  138. private function updateAutoCustomStats($day)
  139. {
  140. $data = $this->autoCustomTrusteeship($day);
  141. if (empty($data))
  142. return false;
  143. foreach ($data as $info) {
  144. $res = null;
  145. $res = CustomSendStats::where('from', 'auto_custom_trusteeship')
  146. ->where('distribution_channel_id', $info['distribution_channel_id'])
  147. ->first();
  148. if (!$res) {
  149. CustomSendStats::create([
  150. 'distribution_channel_id' => $info['distribution_channel_id'],
  151. 'date' => $day,
  152. 'push_user_num' => $info['push_user_num'],
  153. 'click_num' => $info['click_num'],
  154. 'amount' => $info['amount'],
  155. 'success_pay_num' => $info['success_pay_num'],
  156. 'success_pay_rate' => $info['success_pay_rate'],
  157. 'from' => $info['from'],
  158. 'click_rate' => $info['click_rate']
  159. ]);
  160. }
  161. //custom_send_day_stats
  162. $channel = CustomSendDayStats::where('date', $day)
  163. ->where('distribution_channel_id',$info['distribution_channel_id'])
  164. ->where('from',$info['from'])
  165. ->first();
  166. if($channel){
  167. $channel->push_user_num = $info['push_user_num'];
  168. $channel->click_num = $info['click_num'];
  169. $channel->amount = $info['amount'];
  170. $channel->success_pay_num = $info['success_pay_num'];
  171. $channel->success_pay_rate = $info['success_pay_rate'];
  172. $channel->click_rate = $info['click_rate'];
  173. $channel->save();
  174. }else{
  175. CustomSendDayStats::create($info);
  176. }
  177. }
  178. }
  179. private function totalStats($is_all=false){
  180. //2018-04-27 16:29:45
  181. $res = CustomSendStats::where('from', 'auto_custom_trusteeship')
  182. ->get();
  183. if ($res) {
  184. foreach ($res as $val) {
  185. if($is_all){
  186. $start = '2018-04-27 16:29:00';
  187. $start_date = '2018-04-27';
  188. $visit_date = ['2018-04-27',date('Y-m-d',time()-86400)];
  189. }else{
  190. $start = $val->updated_at->format('Y-m-d H:i:s');
  191. $start_date =$val->updated_at->format('Y-m-d');
  192. $visit_date = $start_date;
  193. }
  194. //echo $start.'---------'.$start_date.PHP_EOL;
  195. $push_info = CustomMsgService::customSendMsgsByTrusteeshipByChannelId(
  196. $val->distribution_channel_id,
  197. '2018-04-27 16:29:00'
  198. );
  199. $val->push_user_num = $push_info->user_num;
  200. $from = $this->getFromFromIds($push_info->ids);
  201. $visit_info = $this->getAutoCustomVisitInfo(
  202. $val->distribution_channel_id,
  203. $from,
  204. $visit_date
  205. );
  206. if($is_all){
  207. $val->click_num = $visit_info['uv'];
  208. }else{
  209. $val->click_num += $visit_info['uv'];
  210. }
  211. $order_info = $this->getOrderInfo(
  212. $val->distribution_channel_id, $from,
  213. [$start, date('Y-m-d H:i:s')]
  214. );
  215. //$val->amount = $val->amount+$order_info['amount'];
  216. if($is_all){
  217. $val->amount = $order_info['amount'];
  218. $val->success_pay_num = $order_info['count'];
  219. }else{
  220. $val->amount += $order_info['amount'];
  221. $val->success_pay_num += $order_info['count'];
  222. }
  223. if( $val->push_user_num){
  224. $val->success_pay_rate = round($val->success_pay_num / $val->push_user_num, 4) * 100;
  225. }
  226. if($val->push_user_num){
  227. $val->click_rate = round($val->click_num / $val->push_user_num, 4) * 100;
  228. }
  229. $val->save();
  230. }
  231. }
  232. }
  233. //客服消息托管数据
  234. private function autoCustomTrusteeship($send_day)
  235. {
  236. //distribution_channel_id ids user_num
  237. $res = CustomMsgService::customSendMsgsByTrusteeshipGroup($send_day);
  238. $data = [];
  239. if (!$res) {
  240. return $data;
  241. }
  242. foreach ($res as $v) {
  243. $temp = [];
  244. $temp['distribution_channel_id'] = $v->distribution_channel_id;
  245. $temp['push_user_num'] = $v->user_num?$v->user_num:0;
  246. $from = $this->getFromFromIds($v->ids);
  247. $visit_info = $this->getAutoCustomVisitInfo(
  248. $v->distribution_channel_id,
  249. $from,
  250. [$send_day, date('Y-m-d', strtotime($send_day) + 86400 * 3)]
  251. );
  252. $temp['click_num'] = $visit_info['uv']?$visit_info['uv']:0;
  253. $temp['date'] = $send_day;
  254. $order_info = $this->getOrderInfo(
  255. $v->distribution_channel_id, $from,
  256. [$send_day, date('Y-m-d 23:59:59', strtotime($send_day) + 86400 * 3)]
  257. );
  258. $temp['amount'] = $order_info['amount']?$order_info['amount']:0;
  259. $temp['success_pay_num'] = $order_info['count']?$order_info['count']:0;
  260. if ($v->user_num) {
  261. $temp['success_pay_rate'] = round(($order_info['count']) / $v->user_num, 4) * 100;
  262. $temp['click_rate'] = round($temp['click_num'] / $v->user_num, 4) * 100;
  263. } else {
  264. $temp['success_pay_rate'] = 0;
  265. $temp['click_rate'] = 0;
  266. }
  267. $temp['from'] = 'auto_custom_trusteeship';
  268. $data[] = $temp;
  269. }
  270. return $data;
  271. }
  272. private function getFromFromIds($ids)
  273. {
  274. if (!$ids)
  275. return [];
  276. $id_arr = explode(',', $ids);
  277. $res = [];
  278. foreach ($id_arr as $v) {
  279. for ($i = 1; $i <= 4; $i++) {
  280. array_push($res, sprintf('custom_%s_%s', $v, $i));
  281. }
  282. }
  283. return $res;
  284. }
  285. private function getAutoCustomVisitInfo($distribution_channel_id, $from, $day)
  286. {
  287. return WapVisitStatService::getUvAndPVByFromAndDay($distribution_channel_id, $from, $day);
  288. }
  289. private function getOrderInfo($distribution_channel_id, $from, $day)
  290. {
  291. $order = Order::where('distribution_channel_id', $distribution_channel_id)
  292. ->whereIn('from_type', $from)
  293. ->where('status', 'PAID')
  294. ->select(DB::raw('count(*) as count'), DB::raw('sum(price) as money'))
  295. ->where('created_at', '>=', $day[0])
  296. ->where('created_at', '<', $day[1])
  297. ->first();
  298. if ($order) {
  299. return ['count' => $order->count, 'amount' => $order->money];
  300. }
  301. return ['count' => 0, 'amount' => 0];
  302. }
  303. }