企微短剧业务系统

CustomerLossService.php 9.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. <?php
  2. namespace App\Service;
  3. use App\Models\AuthorizeCorp;
  4. use App\Models\Report\CustomerLossTrendData;
  5. use App\Models\System\AdminManageCorp;
  6. class CustomerLossService
  7. {
  8. /**
  9. * 账号客户流失数据趋势
  10. * */
  11. public static function getFansLossTrend($params, $sortField, $sortType, $page, $pageSize)
  12. {
  13. # 表头处理
  14. $commonHeader = config('customerLoss.basic');
  15. # 获取day1至day150表头
  16. $daysHeader = [];
  17. for($i = 0;$i < CustomerLossTrendData::CUSTOMER_LOSS_TREND_DAYS;$i++) {
  18. $title = [
  19. 'name' => 'DAY'.($i+1),
  20. 'column' => 'day'.($i+1),
  21. ];
  22. $daysHeader[] = $title;
  23. }
  24. $header = array_merge($commonHeader, $daysHeader);
  25. # 数据项处理
  26. if(isset($params['corpid']) && $params['corpid']) {
  27. list($list, $count) = CustomerLossTrendData::getFansLossTrend($params, $sortField, $sortType, $page, $pageSize);
  28. } else {
  29. # 获取账号可见的corpid
  30. $corpIds = AdminManageCorp::where('sys_user_id', $params['sys_group_id'])->pluck('corpid');
  31. $accountList = AuthorizeCorp::select('corpid')->where('enable', 1)
  32. ->whereIn('id', $corpIds)
  33. ->distinct()->pluck('corpid');
  34. if(empty($accountList)) return [[], 0, $header];
  35. list($list, $count) = CustomerLossTrendData::getFansLossDataSummary(
  36. $params, $accountList, $sortField, $sortType, $page, $pageSize
  37. );
  38. }
  39. if(empty($list)) return [[], 0, $header];
  40. # 企微信息处理
  41. $corpIds = $list->pluck('corpid')->unique();
  42. $accountData = AuthorizeCorp::select('corpid', 'corp_name')->whereIn('corpid', $corpIds)->get();
  43. foreach ($list as $item) {
  44. # 企微名称
  45. $accountInfo = $accountData->where('corpid', $item->corpid)->first();
  46. $item->corp_name = $accountInfo->corp_name ?? '-';
  47. # 消耗金额单位处理
  48. $item->paid = round($item->paid / 100, 2);
  49. # 企微关注成本
  50. $item->follow_cost = round($item->follow_cost / 100, 1);
  51. # 流失率
  52. $item->first_loss_rate = $item->first_loss_rate * 100 . '%';
  53. $item->third_loss_rate = $item->third_loss_rate * 100 . '%';
  54. $item->seventh_loss_rate = $item->seventh_loss_rate * 100 . '%';
  55. $item->fifteenth_loss_rate = $item->fifteenth_loss_rate * 100 . '%';
  56. $item->thirtieth_loss_rate = $item->thirtieth_loss_rate * 100 . '%';
  57. $item->loss_rate = $item->loss_rate * 100 . '%';
  58. # 查询60天数据
  59. $dayInfo = [];
  60. if(isset($params['corpid']) && $params['corpid']) {
  61. $dayData = CustomerLossTrendData::where('enable', 1)
  62. ->where('corpid', $params['corpid'])
  63. ->where('expense_date', $item->expense_date)
  64. ->where('ref_date', '<=', date('Y-m-d', strtotime($item->expense_date.' +59 day')))
  65. ->selectRaw("day_loss_user_count, ref_date, days_type")
  66. ->groupBy(['days_type'])
  67. ->get();
  68. if(!empty($dayData)){
  69. foreach($dayData as $val){
  70. $nd = (strtotime($val['ref_date']) - strtotime($item->expense_date)) / 86400;
  71. $lossCountInfo = $dayData->where('days_type', '=', ($nd+1))->first();
  72. $lossCount = $lossCountInfo->day_loss_user_count ?? 0;
  73. $lossTotal = $dayData->where('days_type', '<=', ($nd+1))->sum('day_loss_user_count');
  74. $newLossRate = $item->add_user_count ? round($lossCount / $item->add_user_count, 4) * 100 . '%' : '0%';
  75. $totalLossRate = $item->add_user_count ? round($lossTotal / $item->add_user_count, 4) * 100 . '%' : '0%';
  76. $dayInfo[$nd] = [
  77. 'days' => 'day' . ($nd + 1),
  78. 'loss_count' => $lossCount,
  79. 'new_loss_rate' => $newLossRate,
  80. 'total_loss_rate'=> $totalLossRate,
  81. ];
  82. }
  83. }
  84. } else {
  85. $dayData = CustomerLossTrendData::where('enable', 1)
  86. ->where('corpid', $item->corpid)
  87. ->where('expense_date', '>=', $item->expense_date)
  88. ->where('expense_date', '<=', $item->expense_date_end)
  89. ->where('ref_date', '<=', strtotime($item->expense_date_end.' +59 day'))
  90. ->selectRaw("sum(day_loss_user_count) as day_loss_user_count,ref_date, expense_date, days_type")
  91. ->groupBy(['days_type'])
  92. ->get();
  93. $paidDataMid = [];
  94. $lossUserTotal = 0;
  95. if(!empty($dayData)){
  96. foreach($dayData as $val){
  97. $nd = (strtotime($val['ref_date']) - strtotime($val['expense_date'])) / 86400;
  98. $lossUserTotal += $val['day_loss_user_count'];
  99. if(isset($paidDataMid[$nd])) {
  100. $paidDataMid[$nd]['loss_user'] += $val['day_loss_user_count'];
  101. $paidDataMid[$nd]['loss_user_total'] += $lossUserTotal;
  102. } else {
  103. $paidDataMid[$nd]['loss_user'] = $val['day_loss_user_count'];
  104. $paidDataMid[$nd]['loss_user_total'] = $lossUserTotal;
  105. }
  106. }
  107. foreach ($paidDataMid as $i=>$v) {
  108. $lossCount = $v['loss_user'] ?? 0;
  109. $lossTotal =$v['loss_user_total'] ?? 0;
  110. $newLossRate = $item->add_user_count ? round( $lossCount / $item->add_user_count, 4) * 100 . '%' : '0%';
  111. $totalLossRate = $item->add_user_count ? round( $lossTotal / $item->add_user_count, 4) * 100 . '%' : '0%';
  112. $dayInfo[$i] = [
  113. 'days' => 'day' . ($i + 1),
  114. 'loss_count' => $lossCount,
  115. 'new_loss_rate' => $newLossRate,
  116. 'total_loss_rate' => $totalLossRate,
  117. ];
  118. }
  119. }
  120. }
  121. $item->day_info = $dayInfo;
  122. }
  123. return [$list, $count, $header];
  124. }
  125. /**
  126. * 账号客户流失数据趋势汇总
  127. * */
  128. public static function getFansLossSummary($params)
  129. {
  130. # 表头处理
  131. $header = config('customerLoss.basic');
  132. # 数据处理
  133. if(isset($params['corpid']) && $params['corpid']) {
  134. $accountList = [$params['corpid']];
  135. } else {
  136. if(isset($params['app_id']) && $params['app_id']) {
  137. $accountList = [$params['account_id']];
  138. } else {
  139. # 获取账号可见的corpid
  140. $corpIds = AdminManageCorp::where('sys_user_id', $params['sys_group_id'])->pluck('corpid');
  141. $accountList = AuthorizeCorp::select('corpid')->where('enable', 1)
  142. ->whereIn('id', $corpIds)
  143. ->distinct()->pluck('corpid');
  144. }
  145. if(empty($accountList)) return [[], $header];
  146. }
  147. $data = CustomerLossTrendData::getFansLossSummary($params, $accountList);
  148. # 消耗金额单位处理
  149. $data->paid = round($data->paid / 100, 2);
  150. # 企微关注成本
  151. $data->follow_cost = round($data->follow_cost / 100, 1);
  152. # 流失率
  153. $data->first_loss_rate = $data->first_loss_rate * 100 . '%';
  154. $data->third_loss_rate = $data->third_loss_rate * 100 . '%';
  155. $data->seventh_loss_rate = $data->seventh_loss_rate * 100 . '%';
  156. $data->fifteenth_loss_rate = $data->fifteenth_loss_rate * 100 . '%';
  157. $data->thirtieth_loss_rate = $data->thirtieth_loss_rate * 100 . '%';
  158. $data->loss_rate = $data->loss_rate * 100 . '%';
  159. if(empty($data)) return [[], $header];
  160. return [$data, $header];
  161. }
  162. /**
  163. * 账号客户流失趋势曲线
  164. * */
  165. public static function getFansLossCurve($params)
  166. {
  167. if(isset($params['corpid']) && $params['corpid']) {
  168. $accountList = [$params['corpid']];
  169. } else {
  170. # 获取账号可见的corpid
  171. $corpIds = AdminManageCorp::where('sys_user_id', $params['sys_group_id'])->pluck('corpid');
  172. $accountList = AuthorizeCorp::select('corpid')->where('enable', 1)
  173. ->whereIn('id', $corpIds)
  174. ->distinct()->pluck('corpid');
  175. if(empty($accountList)) return [];
  176. }
  177. # 客户流失数据汇总曲线
  178. $data = CustomerLossTrendData::getFansLossCurve($params, $accountList);
  179. # 数据处理
  180. foreach($data as $item) {
  181. # 消耗金额
  182. $item->paid = round($item->paid / 100, 2);
  183. }
  184. return $data;
  185. }
  186. }