企微短剧业务系统

ActiveFansTrendService.php 52KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062
  1. <?php
  2. namespace App\Service;
  3. use App\Log;
  4. use App\Models\AdqAccountTrendData;
  5. use App\Models\DramaSeries;
  6. use App\Models\Es\AccountDataTrend;
  7. use App\Models\MpAccountTrendData;
  8. use App\Models\OfficialAccount;
  9. use App\Models\OfficialAccountRelation;
  10. use App\Models\OfficialWebUserActionSetId;
  11. use App\Models\TencentAdAuth;
  12. use App\Support\EmailQueue;
  13. class ActiveFansTrendService
  14. {
  15. /**
  16. * 获取粉丝激活趋势
  17. * */
  18. public static function getAdqActiveFansTrend($params, $sortField, $sortType, $page, $pageSize)
  19. {
  20. # 表头处理
  21. $commonHeader = config('activeFans.basic');
  22. # 获取day1至day150表头
  23. $daysHeader = [];
  24. for($i = 0;$i < AdqAccountTrendData::ADQ_ACTIVE_FANS_DAYS;$i++) {
  25. $title = [
  26. 'name' => 'DAY'.($i+1),
  27. 'column' => 'day'.($i+1)
  28. ];
  29. $daysHeader[] = $title;
  30. }
  31. $header = array_merge($commonHeader, $daysHeader);
  32. # 查询数据
  33. if(isset($params['account_id']) && $params['account_id']) {
  34. list($list, $count) = AdqAccountTrendData::getActiveFansTrend($params, $sortField, $sortType, $page, $pageSize);
  35. } else {
  36. # 获取企业下的adq账号
  37. $accountList = OfficialWebUserActionSetId::select('account_id')->where('enable', 1)
  38. ->where('sys_group_id', $params['sys_group_id'])
  39. ->distinct()->pluck('account_id');
  40. if(empty($accountList)) return [[], 0, $header];
  41. list($list, $count) = AdqAccountTrendData::getActiveFansSummaryData(
  42. $params, $accountList, $sortField, $sortType, $page, $pageSize
  43. );
  44. }
  45. if(empty($list)) return [[], 0, $header];
  46. # 获取短剧信息
  47. $playletIds = $list->pluck('playlet_id')->unique();
  48. $playletData = DramaSeries::select('id', 'name')->whereIn('id', $playletIds)
  49. ->where('sys_group_id', $params['sys_group_id'])
  50. ->get();
  51. foreach ($list as $item) {
  52. # 短剧信息处理
  53. $playletInfo = $playletData->where('id', $item->playlet_id)->first();
  54. $item->playlet_name = $playletInfo->name ?? '-';
  55. # 消耗金额单位处理
  56. $item->paid = $item->paid / 100;
  57. # 企微关注成本
  58. $item->follow_cost = round($item->follow_cost / 100, 1);
  59. # 首日roi
  60. $item->first_roi = $item->first_roi * 100 . '%';
  61. # 用户累计充值金额
  62. $item->pay_money_total = $item->pay_money_total / 100;
  63. # 首日下单成本
  64. $item->first_charge_user_cost = round($item->first_charge_user_cost / 100, 2);
  65. # 首日新增用户充值金额
  66. $item->pay_money = $item->pay_money / 100;
  67. # 当天新增用户arpu
  68. $item->day_paid_user_arpu = round($item->day_paid_user_arpu / 100, 2);
  69. # 总回本率
  70. $item->cost_cover_rate = $item->cost_cover_rate * 100 . '%';
  71. # 累计付费用户arpu
  72. $item->paid_user_arpu = round($item->paid_user_arpu / 100, 2);
  73. # 企微关注人数
  74. $item->scan_follow_count = intval($item->scan_follow_count);
  75. # 累计激活下单成本
  76. $item->pay_user_cost = round($item->pay_user_cost / 100, 2);
  77. # 查询150天数据
  78. $dayInfo = [];
  79. if(isset($params['account_id']) && $params['account_id']) {
  80. $dayData = AdqAccountTrendData::where('enable', 1)
  81. ->where(function($query) use ($params) {
  82. if(isset($params['plat_order_type']) && is_numeric($params['plat_order_type']))
  83. $query->where('plat_order_type', $params['plat_order_type']);
  84. })
  85. ->where('account_id', $params['account_id'])
  86. ->where(function($query) use($params) {
  87. if($params['playlet_id'])
  88. $query->where('playlet_id', $params['playlet_id']);
  89. })
  90. ->where('expense_date', $item->expense_date)
  91. ->where('ref_date', '<=', date('Y-m-d', strtotime($item->expense_date.' +149 day')))
  92. ->selectRaw("sum(active_fans) as active_fans,sum(pay_money) as pay_money, sum(pay_money_total) as pay_money_total, ref_date")
  93. ->groupBy(['days_type'])
  94. ->get();
  95. if(!empty($dayData)){
  96. foreach($dayData as $val){
  97. $nd = (strtotime($val['ref_date']) - strtotime($item->expense_date)) / 86400;
  98. $new_roi = $item->paid ? round($val['pay_money'] / 100 / $item->paid, 4) * 100 . '%' : '0%';
  99. $total_roi = $item->paid ? round($val['pay_money_total'] / 100 / $item->paid, 4) * 100 . '%' : '0%';
  100. $income_times = $item->pay_money ? round($val['pay_money_total'] / 100 / $item->pay_money, 2) : '0%';
  101. $dayInfo[$nd] = [
  102. 'days' => 'day' . ($nd + 1),
  103. 'pay_money' => round($val['pay_money']/100, 2),
  104. 'new_roi' => $new_roi,
  105. 'total_roi' => $total_roi,
  106. 'income_times' => $income_times,
  107. 'charge_user' => $val['active_fans']
  108. ];
  109. }
  110. }
  111. } else {
  112. $dayData = AdqAccountTrendData::where('enable', 1)
  113. ->where(function($query) use ($params) {
  114. if(isset($params['plat_order_type']) && is_numeric($params['plat_order_type']))
  115. $query->where('plat_order_type', $params['plat_order_type']);
  116. })
  117. ->where('account_id', $item->account_id)
  118. ->where('playlet_id', $item->playlet_id)
  119. ->where('expense_date', '>=', $item->expense_date)
  120. ->where('expense_date', '<=', $item->expense_date_end)
  121. ->where('ref_date', '<=', strtotime($item->expense_date_end.' +149 day'))
  122. ->selectRaw("sum(active_fans) as active_fans,sum(pay_money) as pay_money, sum(pay_money_total) as pay_money_total, ref_date, expense_date, plat_order_type")
  123. ->groupBy(['days_type'])
  124. ->get();
  125. $paidDataMid = [];
  126. $payMoneyTotal = 0;
  127. if(!empty($dayData)){
  128. foreach($dayData as $val){
  129. $nd = (strtotime($val['ref_date']) - strtotime($val['expense_date'])) / 86400;
  130. $payMoneyTotal += $val['pay_money'];
  131. if(isset($paidDataMid[$nd])) {
  132. $paidDataMid[$nd]['active_fans'] += $val['active_fans'];
  133. $paidDataMid[$nd]['pay_money'] += $val['pay_money'];
  134. $paidDataMid[$nd]['pay_money_total'] += $payMoneyTotal;
  135. } else {
  136. $paidDataMid[$nd]['active_fans'] = $val['active_fans'];
  137. $paidDataMid[$nd]['pay_money'] = $val['pay_money'];
  138. $paidDataMid[$nd]['pay_money_total'] = $payMoneyTotal;
  139. }
  140. }
  141. foreach ($paidDataMid as $i=>$v) {
  142. $new_roi = $item->paid ? round($v['pay_money'] / 100 / $item->paid, 4) * 100 . '%' : '0%';
  143. $total_roi = $item->paid ? round($v['pay_money_total'] / 100 / $item->paid, 4) * 100 . '%' : '0%';
  144. $income_times = $item->pay_money ? round($v['pay_money_total'] / 100 / $item->pay_money, 2) : '0%';
  145. $dayInfo[$i] = [
  146. 'days' => 'day' . ($i+1),
  147. 'pay_money' => round($v['pay_money']/100, 2),
  148. 'new_roi' => $new_roi,
  149. 'total_roi' => $total_roi,
  150. 'income_times' => $income_times,
  151. 'charge_user' => $v['active_fans']
  152. ];
  153. }
  154. }
  155. }
  156. $item->day_info = $dayInfo;
  157. }
  158. return [$list, $count, $header];
  159. }
  160. /**
  161. * 从ES获取粉丝激活趋势
  162. * */
  163. public static function getActiveFansTrend($params, $sortField, $sortType, $page, $pageSize)
  164. {
  165. # 表头处理
  166. $commonHeader = config('activeFans.basic');
  167. # 获取day1至day150表头
  168. $daysHeader = [];
  169. for($i = 0;$i < AdqAccountTrendData::ADQ_ACTIVE_FANS_DAYS;$i++) {
  170. $title = [
  171. 'name' => 'DAY'.($i+1),
  172. 'column' => 'day'.($i+1)
  173. ];
  174. $daysHeader[] = $title;
  175. }
  176. $header = array_merge($commonHeader, $daysHeader);
  177. try {
  178. # 获取当前登录账号可见的账号范围
  179. if($params['ad_type'] == 1) { // adq账号
  180. $authAccountList = PitcherService::adqAccountListForUser(
  181. $params['admin_id'], $params['sys_group_id'], $params['is_system_admin']
  182. );
  183. } elseif ($params['ad_type'] == 2) { // mp账号
  184. $authAccountList = OfficialAccount::getAccountMpAppIdList(
  185. $params['admin_id'], $params['sys_group_id'], $params['is_system_admin']
  186. );
  187. } else {
  188. $authAccountList = [];
  189. }
  190. if(empty($authAccountList)) return [[], 0, $header];
  191. # 数据项处理
  192. if(isset($params['account_id']) && $params['account_id']) {
  193. $params['account_id'] = explode(',', $params['account_id']);
  194. foreach ($params['account_id'] as $index=>$accountId) {
  195. if(!in_array($accountId, $authAccountList)) unset($params['account_id'][$index]);
  196. }
  197. if(empty($params['account_id'])) return [[], 0, $header];
  198. list($list, $count) = AccountDataTrend::getActiveFansTrend($params, $sortField, $sortType, $page, $pageSize);
  199. } else {
  200. # 获取企业下的adq账号
  201. $adqAccountList = OfficialWebUserActionSetId::select('account_id')->where('enable', 1)
  202. ->where('sys_group_id', $params['sys_group_id'])
  203. ->whereIn('account_id', $authAccountList)
  204. ->distinct()->pluck('account_id')->toArray();
  205. # 获取企业下的mp账号
  206. $mpAccountList = OfficialAccountRelation::selectRaw('app_id')->where('enable', 1)
  207. ->where('sys_group_id', $params['sys_group_id'])
  208. ->whereIn('app_id', $authAccountList)
  209. ->distinct()->pluck('app_id')->toArray();
  210. $accountList = array_merge($adqAccountList, $mpAccountList);
  211. if(empty($accountList)) return [[], 0, $header];
  212. list($list, $count) = AccountDataTrend::getActiveFansSummaryData($params, $accountList, $sortField, $sortType, $page, $pageSize);
  213. }
  214. if(empty($list)) return [[], 0, $header];
  215. # 获取短剧信息
  216. $playletIds = array_unique(array_column($list, 'playlet_id'));
  217. $playletData = DramaSeries::select('id', 'name')->whereIn('id', $playletIds)
  218. ->where('sys_group_id', $params['sys_group_id'])
  219. ->get();
  220. # 获取对应的mp账号信息
  221. $mpAccountData = TencentAdAuth::selectRaw('wechat_account_id, account_name')
  222. ->where('enable', 1)
  223. ->where('wechat_account_id', '>', '')
  224. ->get();
  225. foreach ($list as &$item) {
  226. # 账号名称处理
  227. if(is_array($item['account_id'])) {
  228. $accountCount = count($item['account_id']);
  229. if($accountCount == 1) {
  230. $item['account_id'] = $item['account_id'][0];
  231. $mpAccountInfo = $mpAccountData->where('wechat_account_id', $item['account_id'])->first();
  232. $item['account_name'] = $mpAccountInfo->account_name ?? $item['account_id'];
  233. } else {
  234. $accountNameStr = '';
  235. foreach ($item['account_id'] as $v) {
  236. $mpAccountInfo = $mpAccountData->where('wechat_account_id', $v)->first();
  237. $accountNameStr .= $mpAccountInfo->account_name ?? $v;
  238. $accountNameStr .= ',';
  239. }
  240. $item['account_name'] = trim($accountNameStr, ',');
  241. }
  242. } else {
  243. $mpAccountInfo = $mpAccountData->where('wechat_account_id', $item['account_id'])->first();
  244. $item['account_name'] = $mpAccountInfo->account_name ?? $item['account_id'];
  245. }
  246. # 短剧信息处理
  247. $playletInfo = $playletData->where('id', $item['playlet_id'])->first();
  248. $item['playlet_name'] = $playletInfo['name'] ?? '-';
  249. # 消耗金额单位处理
  250. $item['paid'] = $item['paid'] / 100;
  251. # 企微关注成本
  252. $item['follow_cost'] = round($item['follow_cost'] / 100, 1);
  253. # 首日roi
  254. $item['first_roi'] = round($item['first_roi'] * 100, 2) . '%';
  255. # 用户累计充值金额
  256. $item['pay_money_total'] = $item['pay_money_total'] / 100;
  257. # 首日下单成本
  258. $item['first_charge_user_cost'] = round($item['first_charge_user_cost'] / 100, 2);
  259. # 首日新增用户充值金额
  260. $item['pay_money'] = $item['pay_money'] / 100;
  261. # 当天新增用户arpu
  262. $item['day_paid_user_arpu'] = round($item['day_paid_user_arpu'] / 100, 2);
  263. # 总回本率
  264. $item['cost_cover_rate'] = round($item['cost_cover_rate'] * 100, 2) . '%';
  265. # 累计付费用户arpu
  266. $item['paid_user_arpu'] = round($item['paid_user_arpu'] / 100, 2);
  267. # 企微关注人数
  268. $item['scan_follow_count'] = intval($item['scan_follow_count']);
  269. # 累计激活下单成本
  270. $item['pay_user_cost'] = round($item['pay_user_cost'] / 100, 2);
  271. # 查询150天数据
  272. $dayInfo = [];
  273. if(isset($params['account_id']) && $params['account_id']) {
  274. # 查询该投放日期的后150天数据
  275. $dayData = AccountDataTrend::getDataAfterExpense($params, $item['expense_date']);
  276. if(!empty($dayData)){
  277. foreach($dayData as $val){
  278. $nd = (strtotime($val['ref_date']) - strtotime($item['expense_date'])) / 86400;
  279. $new_roi = $item['paid'] ? round($val['pay_money'] / 100 / $item['paid'], 4) * 100 . '%' : '0%';
  280. $total_roi = $item['paid'] ? round($val['pay_money_total'] / 100 / $item['paid'], 4) * 100 . '%' : '0%';
  281. $income_times = $item['pay_money'] ? round($val['pay_money_total'] / 100 / $item['pay_money'], 2) : 0;
  282. $dayInfo[$nd] = [
  283. 'days' => 'day' . ($nd+1),
  284. 'pay_money' => round($val['pay_money']/100, 2),
  285. 'new_roi' => $new_roi,
  286. 'total_roi' => $total_roi,
  287. 'income_times' => $income_times,
  288. 'charge_user' => $val['active_fans']
  289. ];
  290. }
  291. }
  292. } else {
  293. # 获取账号在指定时间范围内的投放效果数据趋势
  294. $dayData = AccountDataTrend::getDataAfterExpense(
  295. $params, $item['expense_date'], $item['expense_date_end'], $item['account_id']
  296. );
  297. $paidDataMid = [];
  298. $payMoneyTotal = 0;
  299. if(!empty($dayData)){
  300. foreach($dayData as $val){
  301. $nd = (strtotime($val['ref_date']) - strtotime($val['expense_date'])) / 86400;
  302. $payMoneyTotal += $val['pay_money'];
  303. if(isset($paidDataMid[$nd])) {
  304. $paidDataMid[$nd]['active_fans'] += $val['active_fans'];
  305. $paidDataMid[$nd]['pay_money'] += $val['pay_money'];
  306. $paidDataMid[$nd]['pay_money_total'] += $payMoneyTotal;
  307. } else {
  308. $paidDataMid[$nd]['active_fans'] = $val['active_fans'];
  309. $paidDataMid[$nd]['pay_money'] = $val['pay_money'];
  310. $paidDataMid[$nd]['pay_money_total'] = $payMoneyTotal;
  311. }
  312. }
  313. foreach ($paidDataMid as $i=>$v) {
  314. $new_roi = $item['paid'] ? round($v['pay_money'] / 100 / $item['paid'], 4) * 100 . '%' : '0%';
  315. $total_roi = $item['paid'] ? round($v['pay_money_total'] / 100 / $item['paid'], 4) * 100 . '%' : '0%';
  316. $income_times = $item['pay_money'] ? round($v['pay_money_total'] / 100 / $item['pay_money'], 2) : '0';
  317. $dayInfo[$i] = [
  318. 'days' => 'day' . ($i+1),
  319. 'pay_money' => round($v['pay_money']/100, 2),
  320. 'new_roi' => $new_roi,
  321. 'total_roi' => $total_roi,
  322. 'income_times' => $income_times,
  323. 'charge_user' => $v['active_fans']
  324. ];
  325. }
  326. }
  327. }
  328. $item['day_info'] = $dayInfo;
  329. }
  330. } catch (\Exception $e) {
  331. EmailQueue::rPush('粉丝激活趋势列表接口异常', $e->getTraceAsString(), ['xiaohua.hou@kuxuan-inc.com'], '粉丝激活趋势列表接口异常');
  332. Log::logError('粉丝激活趋势列表接口异常', [
  333. 'params' => $params,
  334. 'sort_field' => $sortField,
  335. 'sort_type' => $sortType,
  336. 'line' => $e->getLine(),
  337. 'msg' => $e->getMessage()
  338. ], 'GetActiveFansTrend');
  339. return [[], 0, $header];
  340. }
  341. return [$list, $count, $header];
  342. }
  343. /**
  344. * 获取粉丝激活趋势
  345. * */
  346. public static function getMpActiveFansTrend($params, $sortField, $sortType, $page, $pageSize)
  347. {
  348. # 表头处理
  349. $commonHeader = config('activeFans.mp_basic');
  350. # 获取day1至day150表头
  351. $daysHeader = [];
  352. for($i = 0;$i < MpAccountTrendData::MP_ACTIVE_FANS_DAYS;$i++) {
  353. $title = [
  354. 'name' => 'DAY'.($i+1),
  355. 'column' => 'day'.($i+1)
  356. ];
  357. $daysHeader[] = $title;
  358. }
  359. $header = array_merge($commonHeader, $daysHeader);
  360. # 查询数据
  361. if(isset($params['app_id']) && $params['app_id']) {
  362. list($list, $count) = MpAccountTrendData::getActiveFansTrend($params, $sortField, $sortType, $page, $pageSize);
  363. } else {
  364. # 获取企业下的mp账号
  365. $accountList = OfficialAccountRelation::selectRaw('app_id')->where('enable', 1)
  366. ->where('sys_group_id', $params['sys_group_id'])
  367. ->distinct()->pluck('app_id');
  368. if(empty($accountList)) return [[], 0, $header];
  369. list($list, $count) = MpAccountTrendData::getActiveFansSummaryData(
  370. $params, $accountList, $sortField, $sortType, $page, $pageSize
  371. );
  372. }
  373. if(empty($list)) return [[], 0, $header];
  374. # 获取短剧信息
  375. $playletIds = $list->pluck('playlet_id')->unique();
  376. $playletData = DramaSeries::select('id', 'name')->whereIn('id', $playletIds)
  377. ->where('sys_group_id', $params['sys_group_id'])
  378. ->get();
  379. # 获取列表中的公众号appId信息
  380. $appIds = $list->pluck('app_id')->unique();
  381. $accountData = OfficialAccount::select('mp_app_id', 'mp_name')->whereIn('mp_app_id', $appIds)->get();
  382. foreach ($list as $item) {
  383. # 短剧信息处理
  384. $playletInfo = $playletData->where('id', $item->playlet_id)->first();
  385. $item->playlet_name = $playletInfo->name ?? '-';
  386. # 消耗金额单位处理
  387. $item->paid = $item->paid / 100;
  388. # 企微关注成本
  389. $item->follow_cost = round($item->follow_cost / 100, 1);
  390. # 首日roi
  391. $item->first_roi = $item->first_roi * 100 . '%';
  392. # 用户累计充值金额
  393. $item->pay_money_total = $item->pay_money_total / 100;
  394. # 首日下单成本
  395. $item->first_charge_user_cost = round($item->first_charge_user_cost / 100, 2);
  396. # 首日新增用户充值金额
  397. $item->pay_money = $item->pay_money / 100;
  398. # 当天新增用户arpu
  399. $item->day_paid_user_arpu = round($item->day_paid_user_arpu / 100, 2);
  400. # 总回本率
  401. $item->cost_cover_rate = $item->cost_cover_rate * 100 . '%';
  402. # 累计付费用户arpu
  403. $item->paid_user_arpu = round($item->paid_user_arpu / 100, 2);
  404. # 企微关注人数
  405. $item->scan_follow_count = intval($item->scan_follow_count);
  406. # 累计激活下单成本
  407. $item->pay_user_cost = round($item->pay_user_cost / 100, 2);
  408. # 公众号名称
  409. $accountInfo = $accountData->where('mp_app_id', $item->app_id)->first();
  410. $item->app_name = $accountInfo->mp_name ?? '-';
  411. # 查询150天数据
  412. $dayInfo = [];
  413. if(isset($params['app_id']) && $params['app_id']) {
  414. $dayData = MpAccountTrendData::where('enable', 1)
  415. ->where(function($query) use ($params) {
  416. if(isset($params['plat_order_type']) && is_numeric($params['plat_order_type']))
  417. $query->where('plat_order_type', $params['plat_order_type']);
  418. if($params['playlet_id'])
  419. $query->where('playlet_id', $params['playlet_id']);
  420. })
  421. ->where('app_id', $params['app_id'])
  422. ->where('expense_date', $item->expense_date)
  423. ->where('ref_date', '<=', date('Y-m-d', strtotime($item->expense_date.' +149 day')))
  424. ->selectRaw("sum(active_fans) as active_fans,sum(pay_money) as pay_money, sum(pay_money_total) as pay_money_total, ref_date")
  425. ->groupBy(['days_type'])
  426. ->get();
  427. if(!empty($dayData)){
  428. foreach($dayData as $val){
  429. $nd = (strtotime($val['ref_date']) - strtotime($item->expense_date)) / 86400;
  430. $new_roi = $item->paid ? round($val['pay_money'] / 100 / $item->paid, 4) * 100 . '%' : '0%';
  431. $total_roi = $item->paid ? round($val['pay_money_total'] / 100 / $item->paid, 4) * 100 . '%' : '0%';
  432. $income_times = $item->pay_money ? round($val['pay_money_total'] / 100 / $item->pay_money, 2) : '0%';
  433. $dayInfo[$nd] = [
  434. 'days' => 'day' . ($nd + 1),
  435. 'pay_money' => round($val['pay_money']/100, 2),
  436. 'new_roi' => $new_roi,
  437. 'total_roi' => $total_roi,
  438. 'income_times' => $income_times,
  439. 'charge_user' => $val['active_fans']
  440. ];
  441. }
  442. }
  443. } else {
  444. $dayData = MpAccountTrendData::where('enable', 1)
  445. ->where(function($query) use ($params) {
  446. if(isset($params['plat_order_type']) && is_numeric($params['plat_order_type']))
  447. $query->where('plat_order_type', $params['plat_order_type']);
  448. })
  449. ->where('app_id', $item->app_id)
  450. ->where('playlet_id', $item->playlet_id)
  451. ->where('expense_date', '>=', $item->expense_date)
  452. ->where('expense_date', '<=', $item->expense_date_end)
  453. ->where('ref_date', '<=', strtotime($item->expense_date_end.' +149 day'))
  454. ->selectRaw("sum(active_fans) as active_fans,sum(pay_money) as pay_money, sum(pay_money_total) as pay_money_total, ref_date, expense_date, plat_order_type")
  455. ->groupBy(['days_type'])
  456. ->get();
  457. $paidDataMid = [];
  458. $payMoneyTotal = 0;
  459. if(!empty($dayData)){
  460. foreach($dayData as $val){
  461. $nd = (strtotime($val['ref_date']) - strtotime($val['expense_date'])) / 86400;
  462. $payMoneyTotal += $val['pay_money'];
  463. if(isset($paidDataMid[$nd])) {
  464. $paidDataMid[$nd]['active_fans'] += $val['active_fans'];
  465. $paidDataMid[$nd]['pay_money'] += $val['pay_money'];
  466. $paidDataMid[$nd]['pay_money_total'] += $payMoneyTotal;
  467. } else {
  468. $paidDataMid[$nd]['active_fans'] = $val['active_fans'];
  469. $paidDataMid[$nd]['pay_money'] = $val['pay_money'];
  470. $paidDataMid[$nd]['pay_money_total'] = $payMoneyTotal;
  471. }
  472. }
  473. foreach ($paidDataMid as $i=>$v) {
  474. $new_roi = $item->paid ? round($v['pay_money'] / 100 / $item->paid, 4) * 100 . '%' : '0%';
  475. $total_roi = $item->paid ? round($v['pay_money_total'] / 100 / $item->paid, 4) * 100 . '%' : '0%';
  476. $income_times = $item->pay_money ? round($v['pay_money_total'] / 100 / $item->pay_money, 2) : '0%';
  477. $dayInfo[$i] = [
  478. 'days' => 'day' . ($i+1),
  479. 'pay_money' => round($v['pay_money']/100, 2),
  480. 'new_roi' => $new_roi,
  481. 'total_roi' => $total_roi,
  482. 'income_times' => $income_times,
  483. 'charge_user' => $v['active_fans']
  484. ];
  485. }
  486. }
  487. }
  488. $item->day_info = $dayInfo;
  489. }
  490. return [$list, $count, $header];
  491. }
  492. /**
  493. * ADQ投放粉丝激活趋势汇总
  494. * */
  495. public static function getAdqFansActiveSummary($params)
  496. {
  497. # 表头处理
  498. $header = config('activeFans.summary');
  499. # 数据处理
  500. if(isset($params['account_id']) && $params['account_id']) {
  501. $accountList = [$params['account_id']];
  502. } else {
  503. # 获取企业下的adq账号
  504. $accountList = OfficialWebUserActionSetId::select('account_id')->where('enable', 1)
  505. ->where('sys_group_id', $params['sys_group_id'])
  506. ->distinct()->pluck('account_id');
  507. if(empty($accountList)) return [[], $header];
  508. }
  509. $data = AdqAccountTrendData::activeFansDataCollect($params, $accountList);
  510. if(empty($data)) return [[], $header];
  511. # 获取累计回收金额
  512. $recycleData = AdqAccountTrendData::getCumulativeMoney($params, $accountList, true, [1, 3, 7, 15, 30]);
  513. # 3日消耗最早日期和最晚日期
  514. $threeDaysBegin = $recycleData->where('days_type', 3)->min('expense_date');
  515. $threeDaysEnd = $recycleData->where('days_type', 3)->max('expense_date');
  516. # 首日新增用户累计充值金额
  517. $threeDaysFirstPaid = $recycleData->where('expense_date', '>=', $threeDaysBegin)->where('expense_date', '<=', $threeDaysEnd)
  518. ->where('days_type', 1)
  519. ->sum('pay_money');
  520. # 3天累计回收金额
  521. $threeDaysMoney = $recycleData->where('days_type', 3)->sum('pay_money_total');
  522. $data->three_days_rate = $threeDaysFirstPaid ? round($threeDaysMoney / $threeDaysFirstPaid, 2) : "0";
  523. # 7日消耗最早日期和最晚日期
  524. $sevenDaysBegin = $recycleData->where('days_type', 7)->min('expense_date');
  525. $sevenDaysEnd = $recycleData->where('days_type', 7)->max('expense_date');
  526. # 首日新增用户累计充值金额
  527. $sevenDaysFirstPaid = $recycleData->where('expense_date', '>=', $sevenDaysBegin)->where('expense_date', '<=', $sevenDaysEnd)
  528. ->where('days_type', 1)
  529. ->sum('pay_money');
  530. # 7天累计回收金额
  531. $sevenDaysMoney = $recycleData->where('days_type', 7)->sum('pay_money_total');
  532. $data->seven_days_rate = $sevenDaysFirstPaid ? round($sevenDaysMoney / $sevenDaysFirstPaid, 2) : "0";
  533. # 15日消耗最早日期和最晚日期
  534. $fifteenDaysBegin = $recycleData->where('days_type', 15)->min('expense_date');
  535. $fifteenDaysEnd = $recycleData->where('days_type', 15)->max('expense_date');
  536. # 首日新增用户累计充值金额
  537. $fifteenDaysFirstPaid = $recycleData->where('expense_date', '>=', $fifteenDaysBegin)->where('expense_date', '<=', $fifteenDaysEnd)
  538. ->where('days_type', 1)
  539. ->sum('pay_money');
  540. # 15天累计回收金额
  541. $fifteenDaysMoney = $recycleData->where('days_type', 15)->sum('pay_money_total');
  542. $data->fifteen_days_rate = $fifteenDaysFirstPaid ? round($fifteenDaysMoney / $fifteenDaysFirstPaid, 2) : "0";
  543. # 30日消耗最早日期和最晚日期
  544. $thirtyDaysBegin = $recycleData->where('days_type', 30)->min('expense_date');
  545. $thirtyDaysEnd = $recycleData->where('days_type', 30)->max('expense_date');
  546. # 首日新增用户累计充值金额
  547. $thirtyDaysFirstPaid = $recycleData->where('expense_date', '>=', $thirtyDaysBegin)->where('expense_date', '<=', $thirtyDaysEnd)
  548. ->where('days_type', 1)
  549. ->sum('pay_money');
  550. # 30天累计回收金额
  551. $thirtyDaysMoney = $recycleData->where('days_type', 30)->sum('pay_money_total');
  552. $data->thirty_days_rate = $thirtyDaysFirstPaid ? round($thirtyDaysMoney / $thirtyDaysFirstPaid, 2) : "0";
  553. # 消耗金额单位处理
  554. $data->paid = $data->paid / 100;
  555. # 企微关注成本
  556. $data->follow_cost = round($data->follow_cost / 100, 1);
  557. # 首日roi
  558. $data->first_roi = $data->first_roi * 100 . '%';
  559. # 总回本率
  560. $data->cost_cover_rate = $data->cost_cover_rate * 100 . '%';
  561. # 首日新增用户充值金额
  562. $data->pay_money = $data->pay_money / 100;
  563. # 用户累计充值金额
  564. $data->pay_money_total = $data->pay_money_total / 100;
  565. # 首日下单成本
  566. $data->first_charge_user_cost = round($data->first_charge_user_cost / 100, 2);
  567. # 累计激活下单成本
  568. $data->pay_user_cost = round($data->pay_user_cost / 100, 2);
  569. # 累计下单成本
  570. $data->charge_user_cost = round($data->charge_user_cost / 100, 2);
  571. # 首日付费用户arpu
  572. $data->day_paid_user_arpu = round($data->day_paid_user_arpu / 100, 2);
  573. # 累计付费用户arpu
  574. $data->paid_user_arpu = round($data->paid_user_arpu / 100, 2);
  575. # 企微关注人数
  576. $data->scan_follow_count = intval($data->scan_follow_count);
  577. return [$data, $header];
  578. }
  579. /**
  580. * 获取投放粉丝激活趋势汇总(ADQ+MP)
  581. * */
  582. public static function getFansActiveSummary($params)
  583. {
  584. # 表头处理
  585. $header = config('activeFans.summary');
  586. # 获取当前登录账号可见的账号范围
  587. if($params['ad_type'] == 1) { // adq账号
  588. $authAccountList = PitcherService::adqAccountListForUser(
  589. $params['admin_id'], $params['sys_group_id'], $params['is_system_admin']
  590. );
  591. } elseif ($params['ad_type'] == 1) { // mp账号
  592. $authAccountList = OfficialAccount::getAccountMpAppIdList(
  593. $params['admin_id'], $params['sys_group_id'], $params['is_system_admin']
  594. );
  595. } else { // adq+mp
  596. $authAccountList = PitcherService::adAccountList('', $params['sys_group_id'], $params['admin_id'], $params['is_system_admin']);
  597. $authAccountList = array_column($authAccountList, 'account_id');
  598. }
  599. if(empty($authAccountList)) return [[], $header];
  600. # 数据处理
  601. if(isset($params['account_id']) && $params['account_id']) {
  602. $accountList = explode(',', $params['account_id']);
  603. foreach ($accountList as $index=>$accountId) {
  604. if(!in_array($accountId, $authAccountList)) unset($accountList[$index]);
  605. }
  606. } else {
  607. # 获取企业下的adq账号
  608. $adqAccountList = OfficialWebUserActionSetId::select('account_id')->where('enable', 1)
  609. ->where('sys_group_id', $params['sys_group_id'])
  610. ->whereIn('account_id', $authAccountList)
  611. ->distinct()->pluck('account_id')->toArray();
  612. # 获取企业下的mp账号
  613. $mpAccountList = OfficialAccountRelation::selectRaw('app_id')->where('enable', 1)
  614. ->where('sys_group_id', $params['sys_group_id'])
  615. ->whereIn('app_id', $authAccountList)
  616. ->distinct()->pluck('app_id')->toArray();
  617. $accountList = array_merge($adqAccountList, $mpAccountList);
  618. }
  619. if(empty($accountList)) return [[], $header];
  620. $data = AccountDataTrend::activeFansDataCollect($params, $accountList);
  621. if(empty($data)) return [[], $header];
  622. # 获取累计回收金额
  623. $recycleData = collect(AccountDataTrend::getCumulativeMoney($params, $accountList, [1, 3, 7, 15, 30]));
  624. # 3日消耗最早日期和最晚日期
  625. $threeDaysBegin = $recycleData->where('days_type', 3)->min('expense_date');
  626. $threeDaysEnd = $recycleData->where('days_type', 3)->max('expense_date');
  627. # 首日新增用户累计充值金额
  628. $threeDaysFirstPaid = $recycleData->where('expense_date', '>=', $threeDaysBegin)->where('expense_date', '<=', $threeDaysEnd)
  629. ->where('days_type', 1)
  630. ->sum('pay_money');
  631. # 3天累计回收金额
  632. $threeDaysMoney = $recycleData->where('days_type', 3)->sum('pay_money_total');
  633. $data['three_days_rate'] = $threeDaysFirstPaid ? round($threeDaysMoney / $threeDaysFirstPaid, 2) : "0";
  634. # 7日消耗最早日期和最晚日期
  635. $sevenDaysBegin = $recycleData->where('days_type', 7)->min('expense_date');
  636. $sevenDaysEnd = $recycleData->where('days_type', 7)->max('expense_date');
  637. # 首日新增用户累计充值金额
  638. $sevenDaysFirstPaid = $recycleData->where('expense_date', '>=', $sevenDaysBegin)->where('expense_date', '<=', $sevenDaysEnd)
  639. ->where('days_type', 1)
  640. ->sum('pay_money');
  641. # 7天累计回收金额
  642. $sevenDaysMoney = $recycleData->where('days_type', 7)->sum('pay_money_total');
  643. $data['seven_days_rate'] = $sevenDaysFirstPaid ? round($sevenDaysMoney / $sevenDaysFirstPaid, 2) : "0";
  644. # 15日消耗最早日期和最晚日期
  645. $fifteenDaysBegin = $recycleData->where('days_type', 15)->min('expense_date');
  646. $fifteenDaysEnd = $recycleData->where('days_type', 15)->max('expense_date');
  647. # 首日新增用户累计充值金额
  648. $fifteenDaysFirstPaid = $recycleData->where('expense_date', '>=', $fifteenDaysBegin)->where('expense_date', '<=', $fifteenDaysEnd)
  649. ->where('days_type', 1)
  650. ->sum('pay_money');
  651. # 15天累计回收金额
  652. $fifteenDaysMoney = $recycleData->where('days_type', 15)->sum('pay_money_total');
  653. $data['fifteen_days_rate'] = $fifteenDaysFirstPaid ? round($fifteenDaysMoney / $fifteenDaysFirstPaid, 2) : "0";
  654. # 30日消耗最早日期和最晚日期
  655. $thirtyDaysBegin = $recycleData->where('days_type', 30)->min('expense_date');
  656. $thirtyDaysEnd = $recycleData->where('days_type', 30)->max('expense_date');
  657. # 首日新增用户累计充值金额
  658. $thirtyDaysFirstPaid = $recycleData->where('expense_date', '>=', $thirtyDaysBegin)->where('expense_date', '<=', $thirtyDaysEnd)
  659. ->where('days_type', 1)
  660. ->sum('pay_money');
  661. # 30天累计回收金额
  662. $thirtyDaysMoney = $recycleData->where('days_type', 30)->sum('pay_money_total');
  663. $data['thirty_days_rate'] = $thirtyDaysFirstPaid ? round($thirtyDaysMoney / $thirtyDaysFirstPaid, 2) : "0";
  664. # 消耗金额单位处理
  665. $data['paid'] = $data['paid'] / 100;
  666. # 企微关注成本
  667. $data['follow_cost'] = round($data['follow_cost'] / 100, 1);
  668. # 首日roi
  669. $data['first_roi'] = round($data['first_roi'] * 100, 2) . '%';
  670. # 总回本率
  671. $data['cost_cover_rate'] = round($data['cost_cover_rate'] * 100, 2) . '%';
  672. # 首日新增用户充值金额
  673. $data['pay_money'] = $data['pay_money'] / 100;
  674. # 用户累计充值金额
  675. $data['pay_money_total'] = $data['pay_money_total'] / 100;
  676. # 首日下单成本
  677. $data['first_charge_user_cost'] = round($data['first_charge_user_cost'] / 100, 2);
  678. # 累计激活下单成本
  679. $data['pay_user_cost'] = round($data['pay_user_cost'] / 100, 2);
  680. # 累计下单成本
  681. $data['charge_user_cost'] = round($data['charge_user_cost'] / 100, 2);
  682. # 首日付费用户arpu
  683. $data['day_paid_user_arpu'] = round($data['day_paid_user_arpu'] / 100, 2);
  684. # 累计付费用户arpu
  685. $data['paid_user_arpu'] = round($data['paid_user_arpu'] / 100, 2);
  686. # 企微关注人数
  687. $data['scan_follow_count'] = intval($data['scan_follow_count']);
  688. return [$data, $header];
  689. }
  690. /**
  691. * MP投放粉丝激活趋势汇总
  692. * */
  693. public static function getMpFansActiveSummary($params)
  694. {
  695. # 表头处理
  696. $header = config('activeFans.summary');
  697. # 数据处理
  698. if(isset($params['app_id']) && $params['app_id']) {
  699. $accountList = [$params['app_id']];
  700. } else {
  701. # 获取企业下的adq账号
  702. $accountList = OfficialAccountRelation::selectRaw('app_id')->where('enable', 1)
  703. ->where('sys_group_id', $params['sys_group_id'])
  704. ->distinct()->pluck('app_id');
  705. if(empty($accountList)) return [[], $header];
  706. }
  707. $data = MpAccountTrendData::activeFansDataCollect($params, $accountList);
  708. if(empty($data)) return [[], $header];
  709. # 获取累计回收金额
  710. $recycleData = MpAccountTrendData::getCumulativeMoney($params, $accountList, true, [1, 3, 7, 15, 30]);
  711. # 3日消耗最早日期和最晚日期
  712. $threeDaysBegin = $recycleData->where('days_type', 3)->min('expense_date');
  713. $threeDaysEnd = $recycleData->where('days_type', 3)->max('expense_date');
  714. # 首日新增用户累计充值金额
  715. $threeDaysFirstPaid = $recycleData->where('expense_date', '>=', $threeDaysBegin)->where('expense_date', '<=', $threeDaysEnd)
  716. ->where('days_type', 1)
  717. ->sum('pay_money');
  718. # 3天累计回收金额
  719. $threeDaysMoney = $recycleData->where('days_type', 3)->sum('pay_money_total');
  720. $data->three_days_rate = $threeDaysFirstPaid ? round($threeDaysMoney / $threeDaysFirstPaid, 2) : "0";
  721. # 7日消耗最早日期和最晚日期
  722. $sevenDaysBegin = $recycleData->where('days_type', 7)->min('expense_date');
  723. $sevenDaysEnd = $recycleData->where('days_type', 7)->max('expense_date');
  724. # 首日新增用户累计充值金额
  725. $sevenDaysFirstPaid = $recycleData->where('expense_date', '>=', $sevenDaysBegin)->where('expense_date', '<=', $sevenDaysEnd)
  726. ->where('days_type', 1)
  727. ->sum('pay_money');
  728. # 7天累计回收金额
  729. $sevenDaysMoney = $recycleData->where('days_type', 7)->sum('pay_money_total');
  730. $data->seven_days_rate = $sevenDaysFirstPaid ? round($sevenDaysMoney / $sevenDaysFirstPaid, 2) : "0";
  731. # 15日消耗最早日期和最晚日期
  732. $fifteenDaysBegin = $recycleData->where('days_type', 15)->min('expense_date');
  733. $fifteenDaysEnd = $recycleData->where('days_type', 15)->max('expense_date');
  734. # 首日新增用户累计充值金额
  735. $fifteenDaysFirstPaid = $recycleData->where('expense_date', '>=', $fifteenDaysBegin)->where('expense_date', '<=', $fifteenDaysEnd)
  736. ->where('days_type', 1)
  737. ->sum('pay_money');
  738. # 15天累计回收金额
  739. $fifteenDaysMoney = $recycleData->where('days_type', 15)->sum('pay_money_total');
  740. $data->fifteen_days_rate = $fifteenDaysFirstPaid ? round($fifteenDaysMoney / $fifteenDaysFirstPaid, 2) : "0";
  741. # 30日消耗最早日期和最晚日期
  742. $thirtyDaysBegin = $recycleData->where('days_type', 30)->min('expense_date');
  743. $thirtyDaysEnd = $recycleData->where('days_type', 30)->max('expense_date');
  744. # 首日新增用户累计充值金额
  745. $thirtyDaysFirstPaid = $recycleData->where('expense_date', '>=', $thirtyDaysBegin)->where('expense_date', '<=', $thirtyDaysEnd)
  746. ->where('days_type', 1)
  747. ->sum('pay_money');
  748. # 30天累计回收金额
  749. $thirtyDaysMoney = $recycleData->where('days_type', 30)->sum('pay_money_total');
  750. $data->thirty_days_rate = $thirtyDaysFirstPaid ? round($thirtyDaysMoney / $thirtyDaysFirstPaid, 2) : "0";
  751. # 消耗金额单位处理
  752. $data->paid = $data->paid / 100;
  753. # 企微关注成本
  754. $data->follow_cost = round($data->follow_cost / 100, 1);
  755. # 首日roi
  756. $data->first_roi = $data->first_roi * 100 . '%';
  757. # 总回本率
  758. $data->cost_cover_rate = $data->cost_cover_rate * 100 . '%';
  759. # 首日新增用户充值金额
  760. $data->pay_money = $data->pay_money / 100;
  761. # 用户累计充值金额
  762. $data->pay_money_total = $data->pay_money_total / 100;
  763. # 累计激活下单成本
  764. $data->pay_user_cost = round($data->pay_user_cost / 100, 2);
  765. # 首日下单成本
  766. $data->first_charge_user_cost = round($data->first_charge_user_cost / 100, 2);
  767. # 累计下单成本
  768. $data->charge_user_cost = round($data->charge_user_cost / 100, 2);
  769. # 首日付费用户arpu
  770. $data->day_paid_user_arpu = round($data->day_paid_user_arpu / 100, 2);
  771. # 累计付费用户arpu
  772. $data->paid_user_arpu = round($data->paid_user_arpu / 100, 2);
  773. # 企微关注人数
  774. $data->scan_follow_count = intval($data->scan_follow_count);
  775. return [$data, $header];
  776. }
  777. /**
  778. * Adq账号粉丝激活趋势曲线
  779. * */
  780. public static function getAdqActiveFansCurve($params)
  781. {
  782. if(isset($params['account_id']) && $params['account_id']) {
  783. $accountList = [$params['account_id']];
  784. } else {
  785. # 获取企业下的adq账号
  786. $accountList = OfficialWebUserActionSetId::select('account_id')->where('enable', 1)
  787. ->where('sys_group_id', $params['sys_group_id'])
  788. ->distinct()->pluck('account_id');
  789. if(empty($accountList)) return [];
  790. }
  791. # Adq账号数据汇总曲线
  792. $data = AdqAccountTrendData::getActiveFansCurve($params, $accountList);
  793. # 获取累计回收金额
  794. $recycleData = AdqAccountTrendData::getCumulativeMoney($params, $accountList, true);
  795. if(empty($data)) return [];
  796. # 数据处理
  797. foreach($data as $item) {
  798. # 消耗金额
  799. $item->paid = $item->paid / 100;
  800. # 首日roi
  801. $item->first_roi = $item->first_roi * 100;
  802. # 3天累计回收金额
  803. $threeDaysInfo = $recycleData->where('days_type', 3)->where('expense_date', $item->expense_date)->first();
  804. $threeDaysMoney = $threeDaysInfo->pay_money_total ?? 0;
  805. $item->three_days_rate = $item->pay_money ? round($threeDaysMoney / $item->pay_money, 4) * 100 : 0;
  806. # 获取7天累计回收金额
  807. $sevenDaysInfo = $recycleData->where('days_type', 7)->where('expense_date', $item->expense_date)->first();
  808. $sevenDaysMoney = $sevenDaysInfo->pay_money_total ?? 0;
  809. $item->seven_days_rate = $item->pay_money ? round($sevenDaysMoney / $item->pay_money, 4) * 100 : 0;
  810. # 获取15天累计回收金额
  811. $fifteenDaysInfo = $recycleData->where('days_type', 15)->where('expense_date', $item->expense_date)->first();
  812. $fifteenDaysMoney = $fifteenDaysInfo->pay_money_total ?? 0;
  813. $item->fifteen_days_rate = $item->pay_money ? round($fifteenDaysMoney / $item->pay_money, 4) * 100 : 0;
  814. # 获取30天累计回收金额
  815. $thirtyDaysInfo = $recycleData->where('days_type', 30)->where('expense_date', $item->expense_date)->first();
  816. $thirtyDaysMoney = $thirtyDaysInfo->pay_money_total ?? 0;
  817. $item->thirty_days_rate = $item->pay_money ? round($thirtyDaysMoney / $item->pay_money, 4) * 100 : 0;
  818. # 首日新增用户充值金额
  819. $item->pay_money = $item->pay_money / 100;
  820. }
  821. return $data;
  822. }
  823. /**
  824. * 账号粉丝激活趋势曲线(ADQ+MP)
  825. * */
  826. public static function getActiveFansCurve($params)
  827. {
  828. # 获取当前登录账号可见的账号范围
  829. if($params['ad_type'] == 1) { // adq账号
  830. $authAccountList = PitcherService::adqAccountListForUser(
  831. $params['admin_id'], $params['sys_group_id'], $params['is_system_admin']
  832. );
  833. } elseif ($params['ad_type'] == 2) { // mp账号
  834. $authAccountList = OfficialAccount::getAccountMpAppIdList(
  835. $params['admin_id'], $params['sys_group_id'], $params['is_system_admin']
  836. );
  837. } else { // adq+mp
  838. $authAccountList = PitcherService::adAccountList('', $params['sys_group_id'], $params['admin_id'], $params['is_system_admin']);
  839. $authAccountList = array_column($authAccountList, 'account_id');
  840. }
  841. if(empty($authAccountList)) return [];
  842. if(isset($params['account_id']) && $params['account_id']) {
  843. $accountList = explode(',', $params['account_id']);
  844. foreach ($accountList as $index=>$accountId) {
  845. if(!in_array($accountId, $authAccountList)) unset($accountList[$index]);
  846. }
  847. } else {
  848. # 获取企业下的adq账号
  849. $adqAccountList = OfficialWebUserActionSetId::select('account_id')->where('enable', 1)
  850. ->where('sys_group_id', $params['sys_group_id'])
  851. ->whereIn('account_id', $authAccountList)
  852. ->distinct()->pluck('account_id')->toArray();
  853. # 获取企业下的mp账号
  854. $mpAccountList = OfficialAccountRelation::selectRaw('app_id')->where('enable', 1)
  855. ->where('sys_group_id', $params['sys_group_id'])
  856. ->whereIn('app_id', $authAccountList)
  857. ->distinct()->pluck('app_id')->toArray();
  858. $accountList = array_merge($adqAccountList, $mpAccountList);
  859. }
  860. if(empty($accountList)) return [];
  861. # 账号数据汇总曲线
  862. $data = AccountDataTrend::getActiveFansCurve($params, $accountList);
  863. if(empty($data)) return [];
  864. # 获取累计回收金额
  865. $recycleData = collect(AccountDataTrend::getCumulativeMoney($params, $accountList));
  866. // $recycleData = AdqAccountTrendData::getCumulativeMoney($params, $accountList, true);
  867. # 数据处理
  868. foreach($data as &$item) {
  869. # 消耗金额
  870. $item['paid'] = $item['paid'] / 100;
  871. # 首日roi
  872. $item['first_roi'] = round($item['first_roi'] * 100, 4);
  873. # 3天累计回收金额
  874. $threeDaysInfo = $recycleData->where('days_type', 3)->where('expense_date', $item['expense_date'])->first();
  875. $threeDaysMoney = $threeDaysInfo['pay_money_total'] ?? 0;
  876. $item['three_days_rate'] = $item['pay_money'] ? round($threeDaysMoney / $item['pay_money'], 4) * 100 : 0;
  877. # 获取7天累计回收金额
  878. $sevenDaysInfo = $recycleData->where('days_type', 7)->where('expense_date', $item['expense_date'])->first();
  879. $sevenDaysMoney = $sevenDaysInfo['pay_money_total'] ?? 0;
  880. $item['seven_days_rate'] = $item['pay_money'] ? round($sevenDaysMoney / $item['pay_money'], 4) * 100 : 0;
  881. # 获取15天累计回收金额
  882. $fifteenDaysInfo = $recycleData->where('days_type', 15)->where('expense_date', $item['expense_date'])->first();
  883. $fifteenDaysMoney = $fifteenDaysInfo['pay_money_total'] ?? 0;
  884. $item['fifteen_days_rate'] = $item['pay_money'] ? round($fifteenDaysMoney / $item['pay_money'], 4) * 100 : 0;
  885. # 获取30天累计回收金额
  886. $thirtyDaysInfo = $recycleData->where('days_type', 30)->where('expense_date', $item['expense_date'])->first();
  887. $thirtyDaysMoney = $thirtyDaysInfo['pay_money_total'] ?? 0;
  888. $item['thirty_days_rate'] = $item['pay_money'] ? round($thirtyDaysMoney / $item['pay_money'], 4) * 100 : 0;
  889. # 首日新增用户充值金额
  890. $item['pay_money'] = $item['pay_money'] / 100;
  891. }
  892. return $data;
  893. }
  894. /**
  895. * mp账号粉丝激活趋势曲线
  896. * */
  897. public static function getMpActiveFansCurve($params)
  898. {
  899. if(isset($params['app_id']) && $params['app_id']) {
  900. $accountList = [$params['app_id']];
  901. } else {
  902. # 获取企业下的adq账号
  903. $accountList = OfficialAccountRelation::selectRaw('app_id')->where('enable', 1)
  904. ->where('sys_group_id', $params['sys_group_id'])
  905. ->distinct()->pluck('app_id');
  906. if(empty($accountList)) return [];
  907. }
  908. # mp账号数据汇总曲线
  909. $data = MpAccountTrendData::getActiveFansCurve($params, $accountList);
  910. # 获取累计回收金额
  911. $recycleData = MpAccountTrendData::getCumulativeMoney($params, $accountList, true);
  912. if(empty($data)) return [];
  913. # 数据处理
  914. foreach($data as $item) {
  915. # 消耗金额
  916. $item->paid = $item->paid / 100;
  917. # 首日roi
  918. $item->first_roi = $item->first_roi * 100;
  919. # 3天累计回收金额
  920. $threeDaysInfo = $recycleData->where('days_type', 3)->where('expense_date', $item->expense_date)->first();
  921. $threeDaysMoney = $threeDaysInfo->pay_money_total ?? 0;
  922. $item->three_days_rate = $item->pay_money ? round($threeDaysMoney / $item->pay_money, 4) * 100 : 0;
  923. # 获取7天累计回收金额
  924. $sevenDaysInfo = $recycleData->where('days_type', 7)->where('expense_date', $item->expense_date)->first();
  925. $sevenDaysMoney = $sevenDaysInfo->pay_money_total ?? 0;
  926. $item->seven_days_rate = $item->pay_money ? round($sevenDaysMoney / $item->pay_money, 4) * 100 : 0;
  927. # 获取15天累计回收金额
  928. $fifteenDaysInfo = $recycleData->where('days_type', 15)->where('expense_date', $item->expense_date)->first();
  929. $fifteenDaysMoney = $fifteenDaysInfo->pay_money_total ?? 0;
  930. $item->fifteen_days_rate = $item->pay_money ? round($fifteenDaysMoney / $item->pay_money, 4) * 100 : 0;
  931. # 获取30天累计回收金额
  932. $thirtyDaysInfo = $recycleData->where('days_type', 30)->where('expense_date', $item->expense_date)->first();
  933. $thirtyDaysMoney = $thirtyDaysInfo->pay_money_total ?? 0;
  934. $item->thirty_days_rate = $item->pay_money ? round($thirtyDaysMoney / $item->pay_money, 4) * 100 : 0;
  935. # 首日新增用户充值金额
  936. $item->pay_money = $item->pay_money / 100;
  937. }
  938. return $data;
  939. }
  940. }