企微短剧业务系统

AdvertiserService.php 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <?php
  2. /**
  3. * Created by:PhpStorm
  4. * Author:chenzhiyuan
  5. * Date: 2022/4/23
  6. * Time: 8:13 下午
  7. */
  8. namespace App\Service\Report;
  9. use App\Log;
  10. use App\Models\AuthorizeCorp;
  11. use App\Models\DjOrder;
  12. use App\Models\OfficialAccount;
  13. use App\Models\Report\DjDataCycle;
  14. use App\Models\Report\DjRegUserRangeReport;
  15. /**
  16. * 广告报表关联统计
  17. * Class AdvertiserService
  18. * @package App\Service\Report
  19. */
  20. class AdvertiserService
  21. {
  22. /**
  23. * 循环统计报表
  24. * @param $cropid_str
  25. * @param $begin_date
  26. * @param $end_date
  27. * @param $page
  28. * @param $page_size
  29. * @param $sysGroupId integer
  30. * @return mixed
  31. */
  32. public static function user_reg_range($cropid_str,$begin_date,$end_date,$page,$page_size, $sysGroupId)
  33. {
  34. $mpAppIdList = OfficialAccount::getSysGroupMpAppIdList($sysGroupId, 'AdvertiserService.user_reg_range');
  35. $query = DjRegUserRangeReport::query()
  36. ->whereBetween("date",[$begin_date,$end_date])
  37. ->whereIn('mp_app_id', $mpAppIdList);
  38. //根据主体搜索
  39. $query->groupBy("date");
  40. $total = $query->get()->count();
  41. $query->select("date")
  42. ->selectRaw("sum(advertiser_cost) as advertiser_cost") //当日消耗
  43. ->selectRaw("sum(follow_uv) as follow_uv") //企微关注数
  44. ->selectRaw("round(sum(advertiser_cost)/sum(follow_uv),2) as per_follow_cost") //企微关注成本
  45. ->selectRaw("sum(first_order_ucnt) as first_order_ucnt") //下单人数
  46. ->selectRaw("round(sum(total_convert_amount) / sum(advertiser_cost) * 100 ,2) as total_roi") //总回收
  47. ->selectRaw("sum(total_convert_amount) as total_cvt_amt"); //总回收金额
  48. foreach (DjRegUserRangeReport::count_range_days() as $day){
  49. $query->selectRaw("sum(d".$day."_cvt_amt) as day".$day."_cvt_amt");
  50. }
  51. $list = $query->offset(($page-1)*$page_size)
  52. ->limit($page_size)
  53. ->orderBy("date","desc")
  54. ->get();
  55. # 查询最大日期和最小日期
  56. $startDate = $list->min('date');
  57. $endDate = $list->max('date');
  58. $payUserData = DjOrder::query()->
  59. selectRaw("FROM_UNIXTIME(mp_user_register_time/1000, '%Y-%m-%d') as ref_date, count(distinct(`unionid`)) as pay_user_unique")
  60. ->where('mp_user_register_time', '>=', strtotime($startDate) * 1000)
  61. ->where('mp_user_register_time', '<=', strtotime($endDate.' 23:59:59') * 1000)
  62. ->whereRaw('FROM_UNIXTIME(mp_user_register_time/1000, "%Y-%m-%d") = FROM_UNIXTIME(order_pay_time/1000, "%Y-%m-%d")')
  63. ->where('pay_status', 1)
  64. ->whereIn('bind_app_id', $mpAppIdList)
  65. ->where('is_ad_user', 1)
  66. ->groupBy(['ref_date'])
  67. ->get();
  68. $list = $list->toArray();
  69. foreach ($list as $k=>$item){
  70. # 查询当日新增用户首单人数
  71. $firstDayPaidUserInfo = $payUserData->where('ref_date', $item['date'])->first();
  72. $firstDayPaidUserUnique = $firstDayPaidUserInfo->pay_user_unique ?? 0;
  73. $advertiser_cost_amount = $list[$k]['advertiser_cost'];
  74. foreach (DjRegUserRangeReport::count_range_days() as $day) {
  75. $day_cvt_amt = $list[$k]["day".$day."_cvt_amt"];
  76. //补充ROI
  77. if(strtotime($item['date'])+($day-1)*86400 > time() ){ //大于当前时间,才是空字符串
  78. $list[$k]["day".$day."_roi"] = '';
  79. }elseif(round($day_cvt_amt)>0 && round($advertiser_cost_amount)>0){
  80. $list[$k]["day".$day."_roi"] = round(round($day_cvt_amt) / round($advertiser_cost_amount)*100,2)."%";
  81. }else{
  82. $list[$k]["day".$day."_roi"] = '0.00%';
  83. }
  84. unset($list[$k]["day".$day."_cvt_amt"]);
  85. }
  86. // 首日充值人数(去重)
  87. $list[$k]['pay_user_unique'] = $firstDayPaidUserUnique;
  88. // 企微下单成本(去重)
  89. $list[$k]['first_order_cost_unique'] = $firstDayPaidUserUnique ?
  90. round($list[$k]['advertiser_cost'] / $firstDayPaidUserUnique, 2) : '0.00';
  91. //企微关注数
  92. $list[$k]['follow_uv'] = empty( $list[$k]['follow_uv'])? '0' : $list[$k]['follow_uv'];
  93. //企微下单成本
  94. $list[$k]['per_follow_cost'] = empty( $list[$k]['per_follow_cost'])? '0' : $list[$k]['per_follow_cost'];
  95. //总ROi
  96. $list[$k]['total_roi'] = empty($list[$k]['total_roi']) ? '0.00%' : $list[$k]['total_roi']."%";
  97. //下单成本
  98. $list[$k]['first_order_cost'] = empty(round($list[$k]['advertiser_cost'])) || empty(round($list[$k]['first_order_ucnt'])) ?
  99. '0.00' :
  100. round(round($list[$k]['advertiser_cost'])/round($list[$k]['first_order_ucnt']),2);
  101. //总回收金额
  102. $list[$k]['total_cvt_amt'] = empty($list[$k]['total_cvt_amt']) ? '0.00' : $list[$k]['total_cvt_amt'];
  103. }
  104. //补充头列表
  105. $head = [
  106. ['column'=>'date' ,'name'=>'用户注册时间' , 'notes' => ''],
  107. ['column'=>'advertiser_cost','name'=>'投放消耗', 'notes' => ''],
  108. ['column'=>'follow_uv' ,'name'=>'企微关注数', 'notes' => ''],
  109. ['column'=>'per_follow_cost','name'=>'企微关注成本', 'notes' => ''],
  110. ['column'=>'first_order_cost','name'=>'下单成本', 'notes' => '投放消耗/当日新增用户首单人数'],
  111. ['column'=>'first_order_cost_unique','name'=>'下单成本(去重)', 'notes' => '投放消耗/当日新增用户首单人数(去重)'],
  112. ['column'=>'total_cvt_amt' ,'name'=>'总回收金额', 'notes' => ''],
  113. ['column'=>'total_roi' ,'name'=>'总回收', 'notes' => '总回收金额/投放消耗'],
  114. ];
  115. foreach (DjRegUserRangeReport::count_range_days() as $day) {
  116. $head[] = ['column'=>'day'.$day.'_roi' ,'name'=>'day'.$day , 'notes' => ''];
  117. }
  118. return [$total,$list,$head];
  119. }
  120. // 循环统计报表 (2022-08-23)
  121. public static function userRegRangeNew(
  122. $beginDate,$endDate,$page,$pageSize, $sysGroupId, $firstOrderCostMin, $firstOrderCostMax, $firstOrderCostUniqueMin,
  123. $firstOrderCostUniqueMax, $perFollowCostMin, $perFollowCostMax, $totalRoiMin, $totalRoiMax, $firstDayRoiMin, $firstDayRoiMax)
  124. {
  125. $offset = ($page - 1) * $pageSize;
  126. $query = DjDataCycle::query()
  127. ->select("date", "advertiser_cost", "first_order_ucnt_unique", "first_order_ucnt", "follow_uv",
  128. "total_cvt_amt", "per_follow_cost", "total_roi", "charge_data", "first_day_charge", "first_day_roi",
  129. "first_order_cost", "first_order_cost_unique")
  130. ->where('sys_group_id', $sysGroupId)
  131. ->where('date', '>=', $beginDate)
  132. ->where('date', '<=', $endDate)
  133. ->where(function($query) use ($firstOrderCostMin, $firstOrderCostMax, $firstOrderCostUniqueMin, $firstOrderCostUniqueMax
  134. , $perFollowCostMin, $perFollowCostMax, $totalRoiMin, $totalRoiMax, $firstDayRoiMin, $firstDayRoiMax){
  135. if(!is_null($firstOrderCostMin)) $query->where('first_order_cost', '>=', $firstOrderCostMin);
  136. if(!is_null($firstOrderCostMax)) $query->where('first_order_cost', '<=', $firstOrderCostMax);
  137. if(!is_null($firstOrderCostUniqueMin)) $query->where('first_order_cost_unique', '>=', $firstOrderCostUniqueMin);
  138. if(!is_null($firstOrderCostUniqueMax)) $query->where('first_order_cost_unique', '<=', $firstOrderCostUniqueMax);
  139. if(!is_null($perFollowCostMin)) $query->where('per_follow_cost', '>=', $perFollowCostMin);
  140. if(!is_null($perFollowCostMax)) $query->where('per_follow_cost', '<=', $perFollowCostMax);
  141. if(!is_null($totalRoiMin)) $query->where('total_roi', '>=', $totalRoiMin);
  142. if(!is_null($totalRoiMax)) $query->where('total_roi', '<=', $totalRoiMax);
  143. if(!is_null($firstDayRoiMin)) $query->where('first_day_roi', '>=', $firstDayRoiMin);
  144. if(!is_null($firstDayRoiMax)) $query->where('first_day_roi', '<=', $firstDayRoiMax);
  145. });
  146. $count = $query->count();
  147. $data = $query->offset($offset)
  148. ->limit($pageSize)
  149. ->orderBy('date', 'desc')
  150. ->get()
  151. ->toArray();
  152. foreach($data as $k=>$val) {
  153. //总ROi
  154. $data[$k]['total_roi'] = empty($data[$k]['total_roi']) ? '0.00%' : ($data[$k]['total_roi'] * 100) . "%";
  155. // 首日roi
  156. $data[$k]['first_day_roi'] = empty($data[$k]['first_day_roi']) ? '0.00%' : ($data[$k]['first_day_roi'] * 100) . '%';
  157. $chargeData = json_decode($val['charge_data'], 1);
  158. foreach($chargeData as $d=>$chargePrice) {
  159. $day = $d+1;
  160. $data[$k]['day'.$day.'_roi'] = $val['advertiser_cost'] != 0 ? round($chargePrice/$val['advertiser_cost'], 4) * 100 . '%' : '0.00%';
  161. }
  162. }
  163. //补充头列表
  164. $head = [
  165. ['column' => 'date', 'name' => '用户注册时间', 'notes' => ''],
  166. ['column' => 'advertiser_cost', 'name' => '投放消耗', 'notes' => ''],
  167. ['column' => 'follow_uv', 'name' => '企微关注数', 'notes' => ''],
  168. ['column' => 'per_follow_cost', 'name' => '企微关注成本', 'notes' => ''],
  169. ['column' => 'first_order_cost', 'name' => '下单成本', 'notes' => '投放消耗/当日新增用户首单人数'],
  170. ['column' => 'first_order_cost_unique', 'name' => '下单成本(去重)', 'notes' => '投放消耗/当日新增用户首单人数(去重)'],
  171. ['column' => 'total_cvt_amt', 'name' => '总回收金额', 'notes' => ''],
  172. ['column' => 'total_roi', 'name' => '总回收', 'notes' => '总回收金额/投放消耗'],
  173. ];
  174. foreach (DjRegUserRangeReport::count_range_days() as $day) {
  175. $head[] = ['column'=>'day'.$day.'_roi' , 'name' => 'day'.$day , 'notes' => ''];
  176. }
  177. return [$count, $data, $head];
  178. }
  179. }