企微短剧业务系统

StatisticsService.php 110KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605
  1. <?php
  2. namespace App\Service;
  3. use App\Log;
  4. use App\Models\AdqAccountTrendData;
  5. use App\Models\AdqUser;
  6. use App\Models\Customer;
  7. use App\Models\DjOrder;
  8. use App\Models\CustomerDetails;
  9. use App\Models\CustomerDayReport;
  10. use App\Models\AuthorizeCorp;
  11. use App\Models\DjUser;
  12. use App\Models\Es\AccountDataTrend;
  13. use App\Models\OfficialWebUserActionSetId;
  14. use App\Models\TencentAdDailyReport;
  15. use App\Models\WxOfficialAccountFanRecord;
  16. use App\Models\OfficialAccount;
  17. use App\Models\PopularizPlayletPlans;
  18. use App\Models\PopularizeMoments;
  19. use App\Models\PopularizeAppids;
  20. use App\Models\CorpMapping;
  21. use App\Models\DramaUserRela;
  22. use App\Models\PlayletTrendStatistics;
  23. use App\Models\DramaSeries;
  24. use App\Models\ActiveFansData;
  25. use App\Models\CustomerHourRecord;
  26. use App\RedisModel;
  27. use App\Models\System\Users;
  28. use App\Models\System\AdminManageCorp;
  29. class StatisticsService
  30. {
  31. const OPERATE_DAY_RETRIEVE = 'Playlet::NewOperateDayRetrieveRds';
  32. const ADQ_OPERATE_DAY_RETRIEVE = 'Playlet::AdqOperateDayRetrieveRds';
  33. public static function custTotal($corpid)
  34. {
  35. $start = date('Y-m-d');
  36. $last_time = date('Y-m-d H:i:s', strtotime('-1 day')); //昨日同时段
  37. $last_day = date('Y-m-d', strtotime('-1 day')); //昨日起始时间
  38. $cust_total_info = CustomerDetails::suffix($corpid)
  39. ->where('corpid', $corpid)
  40. ->where('enable', 1)
  41. ->selectRaw('count(distinct(external_userid)) as cust_total')
  42. ->first();
  43. $cust_total_uc = $cust_total_info->cust_total ?? 0;
  44. $cust_total_tadd = CustomerDetails::suffix($corpid)
  45. ->where('corpid', $corpid)
  46. ->where('enable', 1)
  47. ->where('createtime', '>', strtotime($last_time))
  48. ->select('external_userid')
  49. ->distinct()
  50. ->pluck('external_userid')
  51. ->all();
  52. if( empty($cust_total_tadd) ){
  53. $cust_total_uc_compare = 0;
  54. } else {
  55. //过滤之前在其他客服处注册的
  56. $cust_tadd_ago = CustomerDetails::suffix($corpid)
  57. ->where('corpid', $corpid)
  58. ->whereIn('external_userid', $cust_total_tadd)
  59. ->where('createtime', '<', strtotime($last_time))
  60. ->select('external_userid')
  61. ->distinct()
  62. ->pluck('external_userid')
  63. ->all();
  64. $cust_total_uc_compare = count($cust_total_tadd) - count($cust_tadd_ago);
  65. }
  66. $cust_new_tadd = CustomerDetails::suffix($corpid)
  67. ->where('corpid', $corpid)
  68. ->where('enable', 1)
  69. ->where('createtime', '>', strtotime($start))
  70. ->select('external_userid')
  71. ->distinct()
  72. ->pluck('external_userid')
  73. ->all();
  74. if( empty($cust_new_tadd) ){
  75. $cust_add_uc = 0;
  76. } else {
  77. //过滤之前在其他客服处注册的
  78. $cust_new_ago = CustomerDetails::suffix($corpid)
  79. ->where('corpid', $corpid)
  80. ->whereIn('external_userid', $cust_new_tadd)
  81. ->where('createtime', '<', strtotime($start))
  82. ->select('external_userid')
  83. ->distinct()
  84. ->pluck('external_userid')
  85. ->all();
  86. $cust_add_uc = count($cust_new_tadd) - count($cust_new_ago);
  87. }
  88. $last_cust_new_tadd = CustomerDetails::suffix($corpid)
  89. ->where('corpid', $corpid)
  90. ->where('enable', 1)
  91. ->where('createtime', '>=', strtotime($last_day))
  92. ->where('createtime', '<=', strtotime($last_time))
  93. ->select('external_userid')
  94. ->distinct()
  95. ->pluck('external_userid')
  96. ->all();
  97. if( empty($last_cust_new_tadd) ){
  98. $last_cust_add_uc = 0;
  99. } else {
  100. //过滤之前在其他客服处注册的
  101. $last_cust_new_ago = CustomerDetails::suffix($corpid)
  102. ->where('corpid', $corpid)
  103. ->whereIn('external_userid', $last_cust_new_tadd)
  104. ->where('createtime', '<', strtotime($last_day))
  105. ->select('external_userid')
  106. ->distinct()
  107. ->pluck('external_userid')
  108. ->all();
  109. $last_cust_add_uc = count($last_cust_new_tadd) - count($last_cust_new_ago);
  110. }
  111. $cust_add_uc_compare = $cust_add_uc - $last_cust_add_uc;
  112. $cust_tloss = CustomerDetails::suffix($corpid)
  113. ->where('loss_time', '>=', $start)
  114. ->where('enable', 0)
  115. ->where('corpid', $corpid)
  116. ->select('external_userid')
  117. ->distinct()
  118. ->pluck('external_userid')
  119. ->all();
  120. #过滤真正流失的
  121. if( empty($cust_tloss) ){
  122. $cust_loss_uc = 0;
  123. } else {
  124. $cust_noloss = CustomerDetails::suffix($corpid)
  125. ->where('enable', 1)
  126. ->where('corpid', $corpid)
  127. ->whereIn('external_userid', $cust_tloss)
  128. ->select('external_userid')
  129. ->distinct()
  130. ->pluck('external_userid')
  131. ->all();
  132. $cust_loss_uc = count($cust_tloss) - count($cust_noloss);
  133. }
  134. $last_cust_tloss = CustomerDetails::suffix($corpid)
  135. ->where('loss_time', '>=', $last_day)
  136. ->where('loss_time', '<=', $last_time)
  137. ->where('enable', 0)
  138. ->where('corpid', $corpid)
  139. ->select('external_userid')
  140. ->distinct()
  141. ->pluck('external_userid')
  142. ->all();
  143. #过滤真正流失的
  144. if( empty($last_cust_tloss) ){
  145. $last_cust_loss_uc = 0;
  146. } else {
  147. $last_cust_tloss = array_diff($last_cust_tloss, $cust_tloss); //若昨日时段流失客户同时在今日也有流失,说明昨日没真正流失,要排除
  148. $last_cust_noloss = CustomerDetails::suffix($corpid)
  149. ->where('enable', 1)
  150. ->where('corpid', $corpid)
  151. ->whereIn('external_userid', $last_cust_tloss)
  152. ->select('external_userid')
  153. ->distinct()
  154. ->pluck('external_userid')
  155. ->all();
  156. $last_cust_loss_uc = count($last_cust_tloss) - count($last_cust_noloss);
  157. }
  158. $cust_loss_uc_compare = $cust_loss_uc - $last_cust_loss_uc;
  159. //先查关联公众号
  160. $official_account_uc = null;
  161. $official_account_uc_compare = null;
  162. $appids = OfficialAccount::where('corp_id', $corpid)->pluck('mp_app_id')->all();
  163. if( !empty($appids) ){
  164. $official_info = WxOfficialAccountFanRecord::whereIn('app_id', $appids)
  165. ->where('record_at', date('Y-m-d H:00:00', strtotime('-1 hour') ))
  166. ->selectRaw('sum(follow_uv) as follow_uv')
  167. ->first();
  168. $official_account_uc = $official_info->follow_uv ?? null;// 公众号关注数
  169. //昨日同时段关注数
  170. $lastday_h = date('Y-m-d H:00:00', strtotime('-1 day'));
  171. $last_official = WxOfficialAccountFanRecord::whereIn('app_id', $appids)
  172. ->where('record_at', $lastday_h)
  173. ->selectRaw('sum(follow_uv) as follow_uv')
  174. ->first();
  175. $last_official_account_uc = $last_official->follow_uv ?? null;;// 昨天同时段公众号关注数
  176. #公众号关注对比
  177. $official_account_uc_compare = $official_account_uc - $last_official_account_uc;
  178. }
  179. $cust_pay_uc = null;
  180. $cust_pay_amount = null; //付费金额
  181. $cust_pay = DjOrder::where('system_corpid', $corpid)
  182. ->where('pay_status', 1)
  183. ->where('is_ad_user', 1)
  184. ->where('order_pay_time', '>=', strtotime($start).'000')
  185. ->where('enable', 1)
  186. ->selectRaw('count(distinct(unionid)) as cust_uc, sum(pay_money) as pay_amount')
  187. ->first();
  188. if( isset($cust_pay->cust_uc) ){
  189. $cust_pay_uc = $cust_pay->cust_uc;
  190. $cust_pay_amount = round($cust_pay->pay_amount/10000, 2);
  191. }
  192. //昨日同时段付费
  193. $last_cust_pay_uc = null;
  194. $last_cust_pay_amount = null; //付费金额
  195. $last_cust_pay = DjOrder::where('system_corpid', $corpid)
  196. ->where('pay_status', 1)
  197. ->where('is_ad_user', 1)
  198. ->where('order_pay_time', '>=', strtotime($last_day).'000')
  199. ->where('order_pay_time', '<=', strtotime($last_time).'000')
  200. ->where('enable', 1)
  201. ->selectRaw('count(distinct(unionid)) as cust_uc, sum(pay_money) as pay_amount')
  202. ->first();
  203. if( isset($last_cust_pay->cust_uc) ){
  204. $last_cust_pay_uc = $last_cust_pay->cust_uc;
  205. $last_cust_pay_amount = round($last_cust_pay->pay_amount/10000, 2);
  206. }
  207. $cust_pay_uc_compare = $cust_pay_uc - $last_cust_pay_uc;
  208. $cust_pay_amount_compare = $cust_pay_amount - $last_cust_pay_amount;
  209. $result = compact('cust_total_uc', 'cust_total_uc_compare', 'cust_add_uc', 'cust_add_uc_compare', 'cust_loss_uc', 'cust_loss_uc_compare', 'official_account_uc', 'official_account_uc_compare', 'cust_pay_uc', 'cust_pay_uc_compare', 'cust_pay_amount', 'cust_pay_amount_compare');
  210. return $result;
  211. }
  212. public static function custTrends($corpid, $start, $end, $user_id=null){
  213. if(!$user_id){
  214. $type = 0;
  215. } else {
  216. $type = 1;
  217. }
  218. $res = CustomerDayReport::where('corpid', $corpid)
  219. ->where('idate', '>=', $start)
  220. ->where('idate', '<=', $end)
  221. ->where('type', $type)
  222. ->where(function($query) use($user_id){
  223. if($user_id) $query->where('user_id', $user_id);
  224. })
  225. ->orderBy('idate', 'asc')
  226. ->get();
  227. return $res;
  228. }
  229. public static function playletPopulariz($principalName, $mpAppId, $start, $end, $playletId, $operators, $page, $pagesize)
  230. {
  231. $mpAppIds = null;
  232. if($principalName){
  233. $mpAppIds = PopularizeAppids::where('principalName', $principalName)->pluck('mpAppId')->all();
  234. if( empty($mpAppIds) ){
  235. return [[], 0];
  236. }
  237. }
  238. $offset = ($page-1) * $pagesize;
  239. $listQuery = PopularizPlayletPlans::where(function($query) use($start, $end, $playletId, $operators, $mpAppId, $mpAppIds){
  240. if($start) $query->where('create_time', '>=', $start);
  241. if($end) $query->where('create_time', '<=', $end.' 23:59:59');
  242. if($playletId) $query->where('playletId', '=', $playletId);
  243. if($operators) $query->where('operators', '=', $operators);
  244. if($mpAppId) $query->where('mpAppId', $mpAppId);
  245. if($mpAppIds) $query->whereIn('mpAppId', $mpAppIds);
  246. });
  247. $count = $listQuery->count();
  248. if(!$count){
  249. return [[], 0];
  250. }
  251. $list = $listQuery->orderBy('create_time', 'desc')
  252. ->offset($offset)
  253. ->limit($pagesize)
  254. ->get();
  255. return [$list, $count];
  256. }
  257. public static function momentsPopulariz($principalName, $mpAppId, $start, $end, $playletId, $operators, $page, $pagesize)
  258. {
  259. $mpAppIds = null;
  260. if($principalName){
  261. $mpAppIds = PopularizeAppids::where('principalName', $principalName)->pluck('mpAppId')->all();
  262. if( empty($mpAppIds) ){
  263. return [[], 0];
  264. }
  265. }
  266. $offset = ($page-1) * $pagesize;
  267. $listQuery = PopularizeMoments::where(function($query) use($start, $end, $playletId, $operators, $mpAppId, $mpAppIds){
  268. if($start) $query->where('create_time', '>=', $start);
  269. if($end) $query->where('create_time', '<=', $end.' 23:59:59');
  270. if($playletId) $query->where('playletId', '=', $playletId);
  271. if($operators) $query->where('operators', '=', $operators);
  272. if($mpAppId) $query->where('mpAppId', $mpAppId);
  273. if($mpAppIds) $query->whereIn('mpAppId', $mpAppIds);
  274. });
  275. $count = $listQuery->count();
  276. if(!$count){
  277. return [[], 0];
  278. }
  279. $list = $listQuery->orderBy('create_time', 'desc')
  280. ->offset($offset)
  281. ->limit($pagesize)
  282. ->get();
  283. return [$list, $count];
  284. }
  285. public static function corpidToMpAppId($corpid)
  286. {
  287. return CorpMapping::where('corpid', $corpid)->value('platform_corpid');
  288. }
  289. public static function popularizAccounts($type)
  290. {
  291. $list = PopularizeAppids::where(function($query) use($type){
  292. if($type==1) $query->where('serviceType', 10);
  293. if($type==2) $query->where('serviceType', 2);
  294. if(!$type) $query->whereIn('serviceType', [10, 2]);
  295. })
  296. ->where('enable', 1)
  297. ->select('mpAppId', 'nickName', 'serviceType')
  298. ->get();
  299. return $list;
  300. }
  301. public static function popularizPlaylets($mpAppId, $type)
  302. {
  303. if(!$type){
  304. //朋友圈短剧
  305. $list = PopularizeMoments::where('mpAppId', $mpAppId)
  306. ->where('playletTitle','>', '')
  307. ->select('playletId', 'playletTitle')
  308. ->groupBy('playletId')
  309. ->get();
  310. return $list;
  311. } else {
  312. $list = PopularizPlayletPlans::where('mpAppId', $mpAppId)
  313. ->where('playletTitle','>', '')
  314. ->select('playletId', 'playletTitle')
  315. ->groupBy('playletId')
  316. ->get();
  317. return $list;
  318. }
  319. }
  320. public static function popularizCompanys($type)
  321. {
  322. $list = PopularizeAppids::select('principalName')
  323. ->distinct()
  324. ->where('principalName', '>', '')
  325. ->where(function($query) use($type){
  326. if($type==1) $query->where('serviceType', 10);
  327. if($type==2) $query->where('serviceType', 2);
  328. if(!$type) $query->whereIn('serviceType', [10, 2]);
  329. })
  330. ->get();
  331. return $list;
  332. }
  333. public static function operateDayRetrieve($app_id, $start, $end, $page, $pagesize, $drama_id, $sysGroupId)
  334. {
  335. $today_date = date('Y-m-d');
  336. // 若选择截止日期大于今日,则将截止日期修改为今日
  337. if( !$end || $end>$today_date ){
  338. $end = $today_date;
  339. }
  340. #定义回收时段
  341. $retrievePart = array(); // 动态表头对应的默认回收数据
  342. $retrieveColumns = array(); // 动态表头
  343. $dmonth = $ddmonth = date('Y-m-01'); //当前月份
  344. $dymonth = date('Y-01-01');//当年一月
  345. // 今年月份表头以及对应默认值格式化
  346. while($dmonth>=$dymonth){
  347. $retrievePart[$dmonth] = 0;
  348. $retrieveColumns[] = [
  349. 'name'=> intval( substr($dmonth, 5, 2) ).' 月份用户回收',
  350. 'column' => $dmonth
  351. ];
  352. $dmonth = date('Y-m-01', strtotime($dmonth.' -1 month'));
  353. }
  354. $lyear = date('Y') - 1; // 去年
  355. $retrievePart[$lyear] = 0; // 去年对应的默认回收数据
  356. $retrieveColumns[] = [
  357. 'name' => substr($lyear, 2, 2). '年用户回收',
  358. 'column' => $lyear
  359. ];
  360. $retrievePart['other_pay_uv'] = 0;
  361. $retrievePart['other_pay_money'] = 0;
  362. $retrieveColumns[] = [
  363. 'name' => '非投放回收人数',
  364. 'column' => 'other_pay_uv'
  365. ];
  366. $retrieveColumns[] = [
  367. 'name' => '非投放回收金额',
  368. 'column' => 'other_pay_money'
  369. ];
  370. // 总回收表头字段及默认值
  371. $retrievePart['total_pay'] = 0;
  372. $retrieveColumns[] = [
  373. 'name' => '运营总回收',
  374. 'column' => 'total_pay'
  375. ];
  376. $mpAppIdList = OfficialAccount::getSysGroupMpAppIdList($sysGroupId, 'StatisticsService.operateDayRetrieve');
  377. if(empty($mpAppIdList)) {
  378. return [
  379. 'list' => [],
  380. 'total'=> 0,
  381. 'retrieveColumns' => null
  382. ];
  383. }
  384. //短剧筛选,获取对应公众号,时间
  385. if($drama_id){
  386. $drama_info = DramaUserRela::query()
  387. ->where('drama_id', $drama_id)
  388. ->where(function($query) use($app_id){
  389. if($app_id) $query->where('app_id', $app_id);
  390. })
  391. ->where('sys_group_id', $sysGroupId)
  392. ->get();
  393. if( $drama_info->isEmpty() ){
  394. return [
  395. 'list' => [],
  396. 'total'=> 0,
  397. 'retrieveColumns' => null
  398. ];
  399. }
  400. return self::operateDayRetrieveDrama($drama_info, $start, $end, $retrievePart, $retrieveColumns, $page,
  401. $pagesize, $mpAppIdList);
  402. }
  403. if( !$start ){
  404. $start = date('Y-m-d', strtotime('-12 month'));
  405. }
  406. if(empty($app_id)) {
  407. $rds_key = StatisticsService::OPERATE_DAY_RETRIEVE . $sysGroupId;
  408. } else {
  409. $rds_key = StatisticsService::OPERATE_DAY_RETRIEVE . $app_id;
  410. }
  411. $rdsData = RedisModel::get($rds_key);
  412. if($rdsData){
  413. $rdsData = json_decode($rdsData, true);
  414. }
  415. $total = (strtotime($end) - strtotime($start))/86400+1;
  416. $offset = ($page-1) * $pagesize;
  417. $np_num = $total<$pagesize ? $total : $pagesize;
  418. $pend = date('Y-m-d', strtotime($end .' -'.$offset.' day'));
  419. $pstart = date('Y-m-d', strtotime($pend .' -'.($np_num-1).' day'));
  420. if($pend<$start){
  421. return [
  422. 'list' => [],
  423. 'total'=> $total,
  424. 'retrieveColumns' => null
  425. ];
  426. }
  427. if($pstart<$start){
  428. $pstart = $start;
  429. }
  430. $data = array();
  431. while($pstart<=$pend){
  432. if( isset($rdsData[$pend]) ){
  433. $data[] = $rdsData[$pend];
  434. } else {
  435. $retrieveInfo = $retrievePart;
  436. #查日报
  437. $cost = null;
  438. $fan_new = null;
  439. $dayReport = TencentAdDailyReport::query()
  440. ->where('ref_date', $pend)
  441. ->where(function($query) use($sysGroupId, $mpAppIdList, $app_id){
  442. if($app_id) $query->where('app_id', $app_id);
  443. if(!empty($sysGroupId)) $query->whereIn('app_id', $mpAppIdList);
  444. })
  445. ->selectRaw('sum(paid) as cost, sum(scan_follow_count) as fan_new')
  446. ->first();
  447. if( isset($dayReport->cost) ){
  448. $cost = round($dayReport->cost/100, 2);
  449. $fan_new = $dayReport->fan_new;
  450. }
  451. #查当日订单
  452. $orders = DjOrder::query()
  453. ->where('order_pay_time', '>=', strtotime($pend.' 00:00:00').'000')
  454. ->where('order_pay_time', '<=', strtotime($pend.' 23:59:59').'000' )
  455. ->where('enable', 1)
  456. ->where('pay_status', 1)
  457. ->where('is_ad_user', 1)
  458. ->where('order_type', 1)
  459. //->where('order_source', 1)
  460. ->where(function($query) use($sysGroupId, $mpAppIdList, $app_id){
  461. if($app_id) $query->where('bind_app_id', $app_id);
  462. if(!empty($sysGroupId)) $query->whereIn('bind_app_id', $mpAppIdList);
  463. })
  464. ->select('mp_user_register_time', 'pay_money', 'external_userid')
  465. ->get();
  466. $otherOrders = DjOrder::query()
  467. ->selectRaw('count(distinct(openid)) as pay_uv, sum(pay_money) as pay_money')
  468. ->where('order_pay_time', '>=', strtotime($pend.' 00:00:00').'000')
  469. ->where('order_pay_time', '<=', strtotime($pend.' 23:59:59').'000' )
  470. ->where('enable', 1)
  471. ->where('pay_status', 1)
  472. ->where('is_ad_user', 0)
  473. ->where('order_type', 1)
  474. // ->whereNotIn('bind_app_id', $mpAppIdList)
  475. ->where(function($query) use($app_id, $sysGroupId){
  476. // if($app_id) $query->where('bind_app_id', $app_id);
  477. if($sysGroupId) $query->where('sys_group_id', $sysGroupId);
  478. })->first();
  479. $new_pay_arr = [];
  480. $new_pay_money = 0;
  481. if( !$orders->isEmpty() ){
  482. foreach($orders as $order){
  483. $order->pay_money = round($order->pay_money/10000, 2);
  484. $pay_date = date('Y-m-d', substr($order->mp_user_register_time, 0, 10));
  485. if( $pay_date==$pend ){
  486. //新用户
  487. $new_pay_arr[] = $order->external_userid;
  488. $new_pay_money += $order->pay_money;
  489. if($pay_date>=$dymonth){
  490. //今年的
  491. $mon_key = substr($pay_date, 0, 7).'-01';
  492. $retrieveInfo[$mon_key] += $order->pay_money;
  493. } else {
  494. //往年
  495. if(substr($pay_date,0,4)==$lyear){
  496. $retrieveInfo[$lyear] += $order->pay_money;
  497. }
  498. }
  499. } else {
  500. if($pay_date>=$dymonth){
  501. //今年的
  502. $mon_key = substr($pay_date, 0, 7).'-01';
  503. $retrieveInfo[$mon_key] += $order->pay_money;
  504. } else {
  505. //往年
  506. if(substr($pay_date,0,4)==$lyear){
  507. $retrieveInfo[$lyear] += $order->pay_money;
  508. }
  509. }
  510. }
  511. if($pay_date<$ddmonth){
  512. $retrieveInfo['total_pay'] += $order->pay_money;
  513. }
  514. }
  515. $new_pay_money = round($new_pay_money, 2);
  516. $retrieveInfo = array_map(function($val){
  517. return round($val, 2);
  518. }, $retrieveInfo);
  519. }
  520. $new_pay_uc = count( array_unique($new_pay_arr) );
  521. $new_roi = $cost>0 ? round($new_pay_money/$cost, 2) : null;
  522. $new_cost = $new_pay_uc>0 ? round($cost/$new_pay_uc, 2) : null;
  523. $other_pay_uv = isset($otherOrders->pay_uv) ? $otherOrders->pay_uv : null;
  524. $other_pay_money = isset($otherOrders->pay_money) ? round($otherOrders->pay_money/10000, 2) : null;
  525. $retrieveInfo['other_pay_uv'] = $other_pay_uv;
  526. $retrieveInfo['other_pay_money'] = $other_pay_money;
  527. $data[] = [
  528. 'date' => $pend,
  529. 'cost' => $cost,
  530. 'fan_new' => $fan_new,
  531. 'new_pay_uc' => $new_pay_uc,
  532. 'new_pay_money' => $new_pay_money,
  533. 'new_roi' => $new_roi,
  534. 'new_cost' => $new_cost,
  535. 'retrieveInfo' => $retrieveInfo,
  536. ];
  537. }
  538. $pend = date('Y-m-d', strtotime($pend.' -1 day'));
  539. }
  540. return [
  541. 'list' => $data,
  542. 'total' => $total,
  543. 'retrieveColumns' => $retrieveColumns
  544. ];
  545. }
  546. public static function operateDayRetrieveSecond($app_id, $start, $end, $page, $pagesize, $drama_id, $sysGroupId)
  547. {
  548. $today_date = date('Y-m-d');
  549. // 若选择截止日期大于今日,则将截止日期修改为今日
  550. if( !$end || $end>$today_date ){
  551. $end = $today_date;
  552. }
  553. #定义回收时段
  554. $retrievePart = array(); // 动态表头对应的默认回收数据
  555. $retrieveColumns = array(); // 动态表头
  556. $dmonth = $ddmonth = date('Y-m-01'); //当前月份
  557. $dymonth = date('2022-01-01');//当年一月
  558. // 今年月份表头以及对应默认值格式化
  559. while($dmonth>=$dymonth){
  560. $retrievePart[$dmonth] = 0;
  561. $retrieveColumns[] = [
  562. 'name'=> intval( substr($dmonth, 5, 2) ).' 月份用户回收',
  563. 'column' => $dmonth
  564. ];
  565. $dmonth = date('Y-m-01', strtotime($dmonth.' -1 month'));
  566. }
  567. $lyear = date('Y') - 1; // 去年
  568. // $retrievePart[$lyear] = 0; // 去年对应的默认回收数据
  569. // $retrieveColumns[] = [
  570. // 'name' => substr($lyear, 2, 2). '年用户回收',
  571. // 'column' => $lyear
  572. // ];
  573. $retrievePart['other_pay_uv'] = 0;
  574. $retrievePart['other_pay_money'] = 0;
  575. $retrieveColumns[] = [
  576. 'name' => '非投放回收人数',
  577. 'column' => 'other_pay_uv'
  578. ];
  579. $retrieveColumns[] = [
  580. 'name' => '非投放回收金额',
  581. 'column' => 'other_pay_money'
  582. ];
  583. // 总回收表头字段及默认值
  584. $retrievePart['total_pay'] = 0;
  585. $retrieveColumns[] = [
  586. 'name' => '运营总回收',
  587. 'column' => 'total_pay'
  588. ];
  589. $mpAppIdList = OfficialAccount::getSysGroupMpAppIdList($sysGroupId, 'StatisticsService.operateDayRetrieve');
  590. if(empty($mpAppIdList)) {
  591. return [
  592. 'list' => [],
  593. 'total'=> 0,
  594. 'retrieveColumns' => null
  595. ];
  596. }
  597. //短剧筛选,获取对应公众号,时间
  598. if($drama_id){
  599. $drama_info = DramaUserRela::query()
  600. ->where('drama_id', $drama_id)
  601. ->where(function($query) use($app_id){
  602. if($app_id) $query->where('app_id', $app_id);
  603. })
  604. ->where('sys_group_id', $sysGroupId)
  605. ->get();
  606. if( $drama_info->isEmpty() ){
  607. return [
  608. 'list' => [],
  609. 'total'=> 0,
  610. 'retrieveColumns' => null
  611. ];
  612. }
  613. return self::operateDayRetrieveDrama($drama_info, $start, $end, $retrievePart, $retrieveColumns, $page,
  614. $pagesize, $mpAppIdList);
  615. }
  616. if( !$start ){
  617. $start = date('Y-m-d', strtotime('-12 month'));
  618. }
  619. // if(empty($app_id)) {
  620. // $rds_key = StatisticsService::OPERATE_DAY_RETRIEVE . $sysGroupId;
  621. // } else {
  622. // $rds_key = StatisticsService::OPERATE_DAY_RETRIEVE . $app_id;
  623. // }
  624. //
  625. // $rdsData = RedisModel::get($rds_key);
  626. // if($rdsData){
  627. // $rdsData = json_decode($rdsData, true);
  628. // }
  629. $rdsData = [];
  630. $total = (strtotime($end) - strtotime($start))/86400+1;
  631. $offset = ($page-1) * $pagesize;
  632. $np_num = $total<$pagesize ? $total : $pagesize;
  633. $pend = date('Y-m-d', strtotime($end .' -'.$offset.' day'));
  634. $pstart = date('Y-m-d', strtotime($pend .' -'.($np_num-1).' day'));
  635. if($pend<$start){
  636. return [
  637. 'list' => [],
  638. 'total'=> $total,
  639. 'retrieveColumns' => null
  640. ];
  641. }
  642. if($pstart<$start){
  643. $pstart = $start;
  644. }
  645. $data = array();
  646. while($pstart<=$pend){
  647. if( isset($rdsData[$pend]) ){
  648. $data[] = $rdsData[$pend];
  649. } else {
  650. $retrieveInfo = $retrievePart;
  651. #查日报
  652. $cost = null;
  653. $fan_new = null;
  654. $dayReport = TencentAdDailyReport::query()
  655. ->where('ref_date', $pend)
  656. ->where(function($query) use($sysGroupId, $mpAppIdList, $app_id){
  657. if($app_id) $query->where('app_id', $app_id);
  658. if(!empty($sysGroupId)) $query->whereIn('app_id', $mpAppIdList);
  659. })
  660. ->selectRaw('sum(paid) as cost, sum(scan_follow_count) as fan_new')
  661. ->first();
  662. if( isset($dayReport->cost) ){
  663. $cost = round($dayReport->cost/100, 2);
  664. $fan_new = $dayReport->fan_new;
  665. }
  666. #查当日订单
  667. $orders = DjOrder::query()
  668. ->where('order_pay_time', '>=', strtotime($pend.' 00:00:00').'000')
  669. ->where('order_pay_time', '<=', strtotime($pend.' 23:59:59').'000' )
  670. ->where('enable', 1)
  671. ->where('pay_status', 1)
  672. ->where('is_ad_user', 1)
  673. ->where('order_type', 1)
  674. //->where('order_source', 1)
  675. ->where(function($query) use($sysGroupId, $mpAppIdList, $app_id){
  676. if($app_id) $query->where('bind_app_id', $app_id);
  677. if(!empty($sysGroupId)) $query->whereIn('bind_app_id', $mpAppIdList);
  678. })
  679. ->select('mp_user_register_time', 'pay_money', 'external_userid')
  680. ->get();
  681. $otherOrders = DjOrder::query()
  682. ->selectRaw('count(distinct(openid)) as pay_uv, sum(pay_money) as pay_money')
  683. ->where('order_pay_time', '>=', strtotime($pend.' 00:00:00').'000')
  684. ->where('order_pay_time', '<=', strtotime($pend.' 23:59:59').'000' )
  685. ->where('enable', 1)
  686. ->where('pay_status', 1)
  687. ->where('is_ad_user', 0)
  688. ->where('order_type', 1)
  689. // ->whereNotIn('bind_app_id', $mpAppIdList)
  690. ->where(function($query) use($app_id, $sysGroupId){
  691. // if($app_id) $query->where('bind_app_id', $app_id);
  692. if($sysGroupId) $query->where('sys_group_id', $sysGroupId);
  693. })->first();
  694. $new_pay_arr = [];
  695. $new_pay_money = 0;
  696. if( !$orders->isEmpty() ){
  697. foreach($orders as $order){
  698. $order->pay_money = round($order->pay_money/10000, 2);
  699. $pay_date = date('Y-m-d', substr($order->mp_user_register_time, 0, 10));
  700. if( $pay_date==$pend ){
  701. //新用户
  702. $new_pay_arr[] = $order->external_userid;
  703. $new_pay_money += $order->pay_money;
  704. if($pay_date>=$dymonth){
  705. //今年的
  706. $mon_key = substr($pay_date, 0, 7).'-01';
  707. $retrieveInfo[$mon_key] += $order->pay_money;
  708. } else {
  709. //往年
  710. if(substr($pay_date,0,4)==$lyear){
  711. $retrieveInfo[$lyear] += $order->pay_money;
  712. }
  713. }
  714. } else {
  715. if($pay_date>=$dymonth){
  716. //今年的
  717. $mon_key = substr($pay_date, 0, 7).'-01';
  718. $retrieveInfo[$mon_key] += $order->pay_money;
  719. } else {
  720. //往年
  721. if(substr($pay_date,0,4)==$lyear){
  722. $retrieveInfo[$lyear] += $order->pay_money;
  723. }
  724. }
  725. }
  726. if($pay_date<$ddmonth){
  727. $retrieveInfo['total_pay'] += $order->pay_money;
  728. }
  729. }
  730. $new_pay_money = round($new_pay_money, 2);
  731. $retrieveInfo = array_map(function($val){
  732. return round($val, 2);
  733. }, $retrieveInfo);
  734. }
  735. $new_pay_uc = count( array_unique($new_pay_arr) );
  736. $new_roi = $cost>0 ? round($new_pay_money/$cost, 2) : null;
  737. $new_cost = $new_pay_uc>0 ? round($cost/$new_pay_uc, 2) : null;
  738. $other_pay_uv = isset($otherOrders->pay_uv) ? $otherOrders->pay_uv : null;
  739. $other_pay_money = isset($otherOrders->pay_money) ? round($otherOrders->pay_money/10000, 2) : null;
  740. $retrieveInfo['other_pay_uv'] = $other_pay_uv;
  741. $retrieveInfo['other_pay_money'] = $other_pay_money;
  742. $data[] = [
  743. 'date' => $pend,
  744. 'cost' => $cost,
  745. 'fan_new' => $fan_new,
  746. 'new_pay_uc' => $new_pay_uc,
  747. 'new_pay_money' => $new_pay_money,
  748. 'new_roi' => $new_roi,
  749. 'new_cost' => $new_cost,
  750. 'retrieveInfo' => $retrieveInfo,
  751. ];
  752. }
  753. $pend = date('Y-m-d', strtotime($pend.' -1 day'));
  754. }
  755. return [
  756. 'list' => $data,
  757. 'total' => $total,
  758. 'retrieveColumns' => $retrieveColumns
  759. ];
  760. }
  761. public static function operateDayRetrieveDrama($drama_info, $start, $end, $retrievePart, $retrieveColumns, $page,
  762. $pagesize, $mpAppIdList)
  763. {
  764. $ddmonth = date('Y-m-01');//当前月份
  765. $dymonth = date('Y-01-01');//当年一月
  766. $lyear = date('Y') - 1;
  767. $data = array();
  768. foreach($drama_info as $item){
  769. $app_id = $item->app_id;
  770. if($start){
  771. if($item->start_date<$start){
  772. $item->start_date = $start;
  773. }
  774. }
  775. if($end){
  776. if($item->end_date>$end){
  777. $item->end_date = $end;
  778. }
  779. }
  780. $sdate = $item->start_date;
  781. $edate = $item->end_date;
  782. while($edate>=$sdate){
  783. $retrieveInfo = $retrievePart;
  784. #查日报
  785. $cost = null;
  786. $fan_new = null;
  787. $dayReport = TencentAdDailyReport::query()
  788. ->where('ref_date', $edate)
  789. ->where(function($query) use($app_id){
  790. if($app_id) $query->where('app_id', $app_id);
  791. })
  792. // ->whereIn('app_id', $mpAppIdList)
  793. ->selectRaw('sum(paid) as cost, sum(scan_follow_count) as fan_new')
  794. ->first();
  795. if( isset($dayReport->cost) ){
  796. $cost = round($dayReport->cost/100, 2);
  797. $fan_new = $dayReport->fan_new;
  798. }
  799. #查当日订单
  800. $orders = DjOrder::query()
  801. ->where('order_pay_time', '>=', strtotime($edate.' 00:00:00').'000')
  802. ->where('order_pay_time', '<=', strtotime($edate.' 23:59:59').'000' )
  803. ->where('enable', 1)
  804. ->where('pay_status', 1)
  805. ->where('is_ad_user', 1)
  806. ->where('order_type', 1)
  807. ->where(function($query) use($app_id){
  808. if($app_id) $query->where('bind_app_id', $app_id);
  809. })
  810. // ->whereIn('bind_app_id', $mpAppIdList)
  811. ->select('mp_user_register_time', 'pay_money', 'external_userid')
  812. ->get();
  813. $otherOrders = DjOrder::query()
  814. ->selectRaw('count(distinct(openid)) as pay_uv, sum(pay_money) as pay_money')
  815. ->where('order_pay_time', '>=', strtotime($edate.' 00:00:00').'000')
  816. ->where('order_pay_time', '<=', strtotime($edate.' 23:59:59').'000' )
  817. ->where('enable', 1)
  818. ->where('pay_status', 1)
  819. ->where('is_ad_user', 0)
  820. ->where('order_type', 1)
  821. ->where(function($query) use($app_id){
  822. if($app_id) $query->where('bind_app_id', $app_id);
  823. })->first();
  824. $new_pay_arr = [];
  825. $new_pay_money = 0;
  826. if( !$orders->isEmpty() ){
  827. foreach($orders as $order){
  828. $order->pay_money = round($order->pay_money/10000, 2);
  829. $pay_date = date('Y-m-d', substr($order->mp_user_register_time, 0, 10));
  830. if( $pay_date==$edate ){
  831. //新用户
  832. $new_pay_arr[] = $order->external_userid;
  833. $new_pay_money += $order->pay_money;
  834. if($pay_date>=$dymonth){
  835. //今年的
  836. $mon_key = substr($pay_date, 0, 7).'-01';
  837. $retrieveInfo[$mon_key] += $order->pay_money;
  838. } else {
  839. //往年
  840. if(substr($pay_date,0,4)==$lyear){
  841. $retrieveInfo[$lyear] += $order->pay_money;
  842. }
  843. }
  844. } else {
  845. if($pay_date>=$dymonth){
  846. //今年的
  847. $mon_key = substr($pay_date, 0, 7).'-01';
  848. $retrieveInfo[$mon_key] += $order->pay_money;
  849. } else {
  850. //往年
  851. if(substr($pay_date,0,4)==$lyear){
  852. $retrieveInfo[$lyear] += $order->pay_money;
  853. }
  854. }
  855. }
  856. if($pay_date<$ddmonth){
  857. $retrieveInfo['total_pay'] += $order->pay_money;
  858. }
  859. }
  860. $new_pay_money = round($new_pay_money, 2);
  861. $retrieveInfo = array_map(function($val){
  862. return round($val, 2);
  863. }, $retrieveInfo);
  864. }
  865. $new_pay_uc = count( array_unique($new_pay_arr) );
  866. $new_roi = $cost>0 ? round($new_pay_money/$cost, 2) : null;
  867. $new_cost = $new_pay_uc>0 ? round($cost/$new_pay_uc, 2) : null;
  868. $other_pay_uv = isset($otherOrders->pay_uv) ? $otherOrders->pay_uv : 0;
  869. $other_pay_money = isset($$otherOrders->pay_money) ? round($otherOrders->pay_money/10000, 2) : 0;
  870. $retrieveInfo['other_pay_uv'] = $other_pay_uv;
  871. $retrieveInfo['other_pay_money'] = $other_pay_money;
  872. if( isset($data[$edate]) ){
  873. $data[$edate]['cost'] += $cost;
  874. $data[$edate]['fan_new'] += $fan_new;
  875. $data[$edate]['new_pay_uc'] += $new_pay_uc;
  876. $data[$edate]['new_pay_money'] += $new_pay_money;
  877. // $data[$edate]['other_pay_uc'] += $other_pay_uv;
  878. // $data[$edate]['other_pay_money'] += $other_pay_money;
  879. foreach($retrieveInfo as $k=>$v){
  880. $data[$edate]['retrieveInfo'][$k] += $v;
  881. }
  882. } else {
  883. $data[$edate] = [
  884. 'date' => $edate,
  885. 'cost' => $cost,
  886. 'fan_new' => $fan_new,
  887. 'new_pay_uc' => $new_pay_uc,
  888. 'new_pay_money' => $new_pay_money,
  889. 'new_roi' => $new_roi,
  890. 'new_cost' => $new_cost,
  891. 'retrieveInfo' => $retrieveInfo,
  892. // 'other_pay_uc' => $other_pay_uv,
  893. // 'other_pay_money' => $other_pay_money,
  894. ];
  895. }
  896. $edate = date('Y-m-d', strtotime($edate.' -1 day'));
  897. }
  898. }
  899. if( !empty($data) ){
  900. krsort($data);
  901. foreach($data as $k=>&$v){
  902. $v['new_roi'] = $v['cost']>0 ? round($v['new_pay_money']/$v['cost'], 2) : null;
  903. $v['new_cost'] = $v['new_pay_uc']>0 ? round($v['cost']/$v['new_pay_uc'], 2) : null;
  904. }
  905. }
  906. $offset = ($page-1) * $pagesize;
  907. $total = count($data);
  908. $list = array_slice(array_values($data), $offset, $pagesize);
  909. return [
  910. 'list' => $list,
  911. 'total' => $total,
  912. 'retrieveColumns' => $retrieveColumns
  913. ];
  914. }
  915. public static function operateDayRetrieveAdq($start, $end, $page, $pagesize, $sysGroupId)
  916. {
  917. $today_date = date('Y-m-d');
  918. // 若选择截止日期大于今日,则将截止日期修改为今日
  919. if( !$end || $end>$today_date ){
  920. $end = $today_date;
  921. }
  922. #定义回收时段
  923. $retrievePart = array(); // 动态表头对应的默认回收数据
  924. $retrieveColumns = array(); // 动态表头
  925. $dmonth = $ddmonth = date('Y-m-01'); //当前月份
  926. $dymonth = date('Y-01-01');//当年一月
  927. // 今年月份表头以及对应默认值格式化
  928. while($dmonth>=$dymonth){
  929. $retrievePart[$dmonth] = 0;
  930. $retrieveColumns[] = [
  931. 'name'=> intval( substr($dmonth, 5, 2) ).' 月份用户回收',
  932. 'column' => $dmonth
  933. ];
  934. $dmonth = date('Y-m-01', strtotime($dmonth.' -1 month'));
  935. }
  936. $lyear = date('Y') - 1; // 去年
  937. $retrievePart[$lyear] = 0; // 去年对应的默认回收数据
  938. $retrieveColumns[] = [
  939. 'name' => substr($lyear, 2, 2). '年用户回收',
  940. 'column' => $lyear
  941. ];
  942. $retrievePart['other_pay_uv'] = 0;
  943. $retrievePart['other_pay_money'] = 0;
  944. $retrieveColumns[] = [
  945. 'name' => '非投放回收人数',
  946. 'column' => 'other_pay_uv'
  947. ];
  948. $retrieveColumns[] = [
  949. 'name' => '非投放回收金额',
  950. 'column' => 'other_pay_money'
  951. ];
  952. // 总回收表头字段及默认值
  953. $retrievePart['total_pay'] = 0;
  954. $retrieveColumns[] = [
  955. 'name' => '运营总回收',
  956. 'column' => 'total_pay'
  957. ];
  958. $adqAccountIdList = OfficialWebUserActionSetId::getSysGroupAccountIdList($sysGroupId, 'StatisticsService.operateDayRetrieveAdq');
  959. if(empty($adqAccountIdList)) {
  960. return [
  961. 'list' => [],
  962. 'total'=> 0,
  963. 'retrieveColumns' => null
  964. ];
  965. }
  966. if( !$start ){
  967. $start = date('Y-m-d', strtotime('-12 month'));
  968. }
  969. $rds_key = StatisticsService::ADQ_OPERATE_DAY_RETRIEVE . $sysGroupId;
  970. $rdsData = RedisModel::get($rds_key);
  971. if($rdsData){
  972. $rdsData = json_decode($rdsData, true);
  973. }
  974. $total = (strtotime($end) - strtotime($start))/86400+1;
  975. $offset = ($page-1) * $pagesize;
  976. $np_num = $total<$pagesize ? $total : $pagesize;
  977. $pend = date('Y-m-d', strtotime($end .' -'.$offset.' day'));
  978. $pstart = date('Y-m-d', strtotime($pend .' -'.($np_num-1).' day'));
  979. if($pend<$start){
  980. return [
  981. 'list' => [],
  982. 'total'=> $total,
  983. 'retrieveColumns' => null
  984. ];
  985. }
  986. if($pstart<$start){
  987. $pstart = $start;
  988. }
  989. $data = array();
  990. while($pstart<=$pend){
  991. if( isset($rdsData[$pend]) ){
  992. $data[] = $rdsData[$pend];
  993. } else {
  994. $retrieveInfo = $retrievePart;
  995. #查日报
  996. $cost = null;
  997. $fan_new = null;
  998. $dayReport = TencentAdDailyReport::query()
  999. ->where('ref_date', $pend)
  1000. ->where(function($query) use($sysGroupId, $adqAccountIdList){
  1001. if(!empty($sysGroupId)) $query->whereIn('account_id', $adqAccountIdList);
  1002. })
  1003. ->selectRaw('sum(paid) as cost, sum(scan_follow_count) as fan_new')
  1004. ->first();
  1005. if( isset($dayReport->cost) ){
  1006. $cost = round($dayReport->cost/100, 2);
  1007. $fan_new = $dayReport->fan_new;
  1008. }
  1009. #查当日订单
  1010. $orders = DjOrder::query()
  1011. ->where('order_pay_time', '>=', strtotime($pend.' 00:00:00').'000')
  1012. ->where('order_pay_time', '<=', strtotime($pend.' 23:59:59').'000' )
  1013. ->where('enable', 1)
  1014. ->where('pay_status', 1)
  1015. ->where('order_type', 2)
  1016. ->where('is_ad_user', 1)
  1017. ->where(function($query) use($sysGroupId, $adqAccountIdList){
  1018. if(!empty($sysGroupId)) $query->whereIn('adq_account_id', $adqAccountIdList);
  1019. // if(!empty($sysGroupId)) $query->where('sys_group_id', $sysGroupId);
  1020. })
  1021. ->select('mp_user_register_time', 'pay_money', 'external_userid')
  1022. ->get();
  1023. $otherOrders = DjOrder::query()
  1024. ->selectRaw('count(distinct(openid)) as pay_uv, sum(pay_money) as pay_money')
  1025. ->where('order_pay_time', '>=', strtotime($pend.' 00:00:00').'000')
  1026. ->where('order_pay_time', '<=', strtotime($pend.' 23:59:59').'000' )
  1027. ->where('enable', 1)
  1028. ->where('pay_status', 1)
  1029. ->where('is_ad_user', 0)
  1030. ->where('order_type', 2)
  1031. ->where(function($query) use($sysGroupId){
  1032. if($sysGroupId) $query->where('sys_group_id', $sysGroupId);
  1033. })->first();
  1034. $new_pay_arr = [];
  1035. $new_pay_money = 0;
  1036. if( !$orders->isEmpty() ){
  1037. foreach($orders as $order){
  1038. $order->pay_money = round($order->pay_money/10000, 2);
  1039. $pay_date = date('Y-m-d', substr($order->mp_user_register_time, 0, 10));
  1040. if( $pay_date==$pend ){
  1041. //新用户
  1042. $new_pay_arr[] = $order->external_userid;
  1043. $new_pay_money += $order->pay_money;
  1044. if($pay_date>=$dymonth){
  1045. //今年的
  1046. $mon_key = substr($pay_date, 0, 7).'-01';
  1047. $retrieveInfo[$mon_key] += $order->pay_money;
  1048. } else {
  1049. //往年
  1050. if(substr($pay_date,0,4)==$lyear){
  1051. $retrieveInfo[$lyear] += $order->pay_money;
  1052. }
  1053. }
  1054. } else {
  1055. if($pay_date>=$dymonth){
  1056. //今年的
  1057. $mon_key = substr($pay_date, 0, 7).'-01';
  1058. $retrieveInfo[$mon_key] += $order->pay_money;
  1059. } else {
  1060. //往年
  1061. if(substr($pay_date,0,4)==$lyear){
  1062. $retrieveInfo[$lyear] += $order->pay_money;
  1063. }
  1064. }
  1065. }
  1066. if($pay_date<$ddmonth){
  1067. $retrieveInfo['total_pay'] += $order->pay_money;
  1068. }
  1069. }
  1070. $new_pay_money = round($new_pay_money, 2);
  1071. $retrieveInfo = array_map(function($val){
  1072. return round($val, 2);
  1073. }, $retrieveInfo);
  1074. }
  1075. $new_pay_uc = count( array_unique($new_pay_arr) );
  1076. $new_roi = $cost>0 ? round($new_pay_money/$cost, 2) : null;
  1077. $new_cost = $new_pay_uc>0 ? round($cost/$new_pay_uc, 2) : null;
  1078. $other_pay_uv = isset($otherOrders->pay_uv) ? $otherOrders->pay_uv : null;
  1079. $other_pay_money = isset($otherOrders->pay_money) ? round($otherOrders->pay_money/10000, 2) : null;
  1080. $retrieveInfo['other_pay_uv'] = $other_pay_uv;
  1081. $retrieveInfo['other_pay_money'] = $other_pay_money;
  1082. $data[] = [
  1083. 'date' => $pend,
  1084. 'cost' => $cost,
  1085. 'fan_new' => $fan_new,
  1086. 'new_pay_uc' => $new_pay_uc,
  1087. 'new_pay_money' => $new_pay_money,
  1088. 'new_roi' => $new_roi,
  1089. 'new_cost' => $new_cost,
  1090. 'retrieveInfo' => $retrieveInfo,
  1091. ];
  1092. }
  1093. $pend = date('Y-m-d', strtotime($pend.' -1 day'));
  1094. }
  1095. return [
  1096. 'list' => $data,
  1097. 'total' => $total,
  1098. 'retrieveColumns' => $retrieveColumns
  1099. ];
  1100. }
  1101. public static function operateDayRetrieveAdqSecond($start, $end, $page, $pagesize, $sysGroupId)
  1102. {
  1103. $today_date = date('Y-m-d');
  1104. // 若选择截止日期大于今日,则将截止日期修改为今日
  1105. if( !$end || $end>$today_date ){
  1106. $end = $today_date;
  1107. }
  1108. #定义回收时段
  1109. $retrievePart = array(); // 动态表头对应的默认回收数据
  1110. $retrieveColumns = array(); // 动态表头
  1111. $dmonth = $ddmonth = date('Y-m-01'); //当前月份
  1112. $dymonth = date('2022-01-01');//当年一月
  1113. // 今年月份表头以及对应默认值格式化
  1114. while($dmonth>=$dymonth){
  1115. $retrievePart[$dmonth] = 0;
  1116. $retrieveColumns[] = [
  1117. 'name'=> intval( substr($dmonth, 5, 2) ).' 月份用户回收',
  1118. 'column' => $dmonth
  1119. ];
  1120. $dmonth = date('Y-m-01', strtotime($dmonth.' -1 month'));
  1121. }
  1122. $lyear = date('Y') - 1; // 去年
  1123. // $retrievePart[$lyear] = 0; // 去年对应的默认回收数据
  1124. // $retrieveColumns[] = [
  1125. // 'name' => substr($lyear, 2, 2). '年用户回收',
  1126. // 'column' => $lyear
  1127. // ];
  1128. $retrievePart['other_pay_uv'] = 0;
  1129. $retrievePart['other_pay_money'] = 0;
  1130. $retrieveColumns[] = [
  1131. 'name' => '非投放回收人数',
  1132. 'column' => 'other_pay_uv'
  1133. ];
  1134. $retrieveColumns[] = [
  1135. 'name' => '非投放回收金额',
  1136. 'column' => 'other_pay_money'
  1137. ];
  1138. // 总回收表头字段及默认值
  1139. $retrievePart['total_pay'] = 0;
  1140. $retrieveColumns[] = [
  1141. 'name' => '运营总回收',
  1142. 'column' => 'total_pay'
  1143. ];
  1144. $adqAccountIdList = OfficialWebUserActionSetId::getSysGroupAccountIdList($sysGroupId, 'StatisticsService.operateDayRetrieveAdq');
  1145. if(empty($adqAccountIdList)) {
  1146. return [
  1147. 'list' => [],
  1148. 'total'=> 0,
  1149. 'retrieveColumns' => null
  1150. ];
  1151. }
  1152. if( !$start ){
  1153. $start = date('Y-m-d', strtotime('-12 month'));
  1154. }
  1155. // $rds_key = StatisticsService::ADQ_OPERATE_DAY_RETRIEVE . $sysGroupId;
  1156. // $rdsData = RedisModel::get($rds_key);
  1157. // if($rdsData){
  1158. // $rdsData = json_decode($rdsData, true);
  1159. // }
  1160. $rdsData = [];
  1161. $total = (strtotime($end) - strtotime($start))/86400+1;
  1162. $offset = ($page-1) * $pagesize;
  1163. $np_num = $total<$pagesize ? $total : $pagesize;
  1164. $pend = date('Y-m-d', strtotime($end .' -'.$offset.' day'));
  1165. $pstart = date('Y-m-d', strtotime($pend .' -'.($np_num-1).' day'));
  1166. if($pend<$start){
  1167. return [
  1168. 'list' => [],
  1169. 'total'=> $total,
  1170. 'retrieveColumns' => null
  1171. ];
  1172. }
  1173. if($pstart<$start){
  1174. $pstart = $start;
  1175. }
  1176. $data = array();
  1177. while($pstart<=$pend){
  1178. if( isset($rdsData[$pend]) ){
  1179. $data[] = $rdsData[$pend];
  1180. } else {
  1181. $retrieveInfo = $retrievePart;
  1182. #查日报
  1183. $cost = null;
  1184. $fan_new = null;
  1185. $dayReport = TencentAdDailyReport::query()
  1186. ->where('ref_date', $pend)
  1187. ->where(function($query) use($sysGroupId, $adqAccountIdList){
  1188. if(!empty($sysGroupId)) $query->whereIn('account_id', $adqAccountIdList);
  1189. })
  1190. ->selectRaw('sum(paid) as cost, sum(scan_follow_count) as fan_new')
  1191. ->first();
  1192. if( isset($dayReport->cost) ){
  1193. $cost = round($dayReport->cost/100, 2);
  1194. $fan_new = $dayReport->fan_new;
  1195. }
  1196. #查当日订单
  1197. $orders = DjOrder::query()
  1198. ->where('order_pay_time', '>=', strtotime($pend.' 00:00:00').'000')
  1199. ->where('order_pay_time', '<=', strtotime($pend.' 23:59:59').'000' )
  1200. ->where('enable', 1)
  1201. ->where('pay_status', 1)
  1202. ->where('order_type', 2)
  1203. ->where('is_ad_user', 1)
  1204. ->where(function($query) use($sysGroupId, $adqAccountIdList){
  1205. if(!empty($sysGroupId)) $query->whereIn('adq_account_id', $adqAccountIdList);
  1206. // if(!empty($sysGroupId)) $query->where('sys_group_id', $sysGroupId);
  1207. })
  1208. ->select('mp_user_register_time', 'pay_money', 'external_userid')
  1209. ->get();
  1210. $otherOrders = DjOrder::query()
  1211. ->selectRaw('count(distinct(openid)) as pay_uv, sum(pay_money) as pay_money')
  1212. ->where('order_pay_time', '>=', strtotime($pend.' 00:00:00').'000')
  1213. ->where('order_pay_time', '<=', strtotime($pend.' 23:59:59').'000' )
  1214. ->where('enable', 1)
  1215. ->where('pay_status', 1)
  1216. ->where('is_ad_user', 0)
  1217. ->where('order_type', 2)
  1218. ->where(function($query) use($sysGroupId){
  1219. if($sysGroupId) $query->where('sys_group_id', $sysGroupId);
  1220. })->first();
  1221. $new_pay_arr = [];
  1222. $new_pay_money = 0;
  1223. if( !$orders->isEmpty() ){
  1224. foreach($orders as $order){
  1225. $order->pay_money = round($order->pay_money/10000, 2);
  1226. $pay_date = date('Y-m-d', substr($order->mp_user_register_time, 0, 10));
  1227. if( $pay_date==$pend ){
  1228. //新用户
  1229. $new_pay_arr[] = $order->external_userid;
  1230. $new_pay_money += $order->pay_money;
  1231. if($pay_date>=$dymonth){
  1232. //今年的
  1233. $mon_key = substr($pay_date, 0, 7).'-01';
  1234. $retrieveInfo[$mon_key] += $order->pay_money;
  1235. } else {
  1236. //往年
  1237. if(substr($pay_date,0,4)==$lyear){
  1238. $retrieveInfo[$lyear] += $order->pay_money;
  1239. }
  1240. }
  1241. } else {
  1242. if($pay_date>=$dymonth){
  1243. //今年的
  1244. $mon_key = substr($pay_date, 0, 7).'-01';
  1245. $retrieveInfo[$mon_key] += $order->pay_money;
  1246. } else {
  1247. //往年
  1248. if(substr($pay_date,0,4)==$lyear){
  1249. $retrieveInfo[$lyear] += $order->pay_money;
  1250. }
  1251. }
  1252. }
  1253. if($pay_date<$ddmonth){
  1254. $retrieveInfo['total_pay'] += $order->pay_money;
  1255. }
  1256. }
  1257. $new_pay_money = round($new_pay_money, 2);
  1258. $retrieveInfo = array_map(function($val){
  1259. return round($val, 2);
  1260. }, $retrieveInfo);
  1261. }
  1262. $new_pay_uc = count( array_unique($new_pay_arr) );
  1263. $new_roi = $cost>0 ? round($new_pay_money/$cost, 2) : null;
  1264. $new_cost = $new_pay_uc>0 ? round($cost/$new_pay_uc, 2) : null;
  1265. $other_pay_uv = isset($otherOrders->pay_uv) ? $otherOrders->pay_uv : null;
  1266. $other_pay_money = isset($otherOrders->pay_money) ? round($otherOrders->pay_money/10000, 2) : null;
  1267. $retrieveInfo['other_pay_uv'] = $other_pay_uv;
  1268. $retrieveInfo['other_pay_money'] = $other_pay_money;
  1269. $data[] = [
  1270. 'date' => $pend,
  1271. 'cost' => $cost,
  1272. 'fan_new' => $fan_new,
  1273. 'new_pay_uc' => $new_pay_uc,
  1274. 'new_pay_money' => $new_pay_money,
  1275. 'new_roi' => $new_roi,
  1276. 'new_cost' => $new_cost,
  1277. 'retrieveInfo' => $retrieveInfo,
  1278. ];
  1279. }
  1280. $pend = date('Y-m-d', strtotime($pend.' -1 day'));
  1281. }
  1282. return [
  1283. 'list' => $data,
  1284. 'total' => $total,
  1285. 'retrieveColumns' => $retrieveColumns
  1286. ];
  1287. }
  1288. public static function throwPersonData($start, $end, $user_id, $drama_id, $sysGroupId, $adminId, $isSystemAdmin
  1289. , $appId, $launchAccountId, $closingDate)
  1290. {
  1291. $mpAccountList = OfficialAccount::getAccountMpAppIdList($adminId, $sysGroupId, $isSystemAdmin);
  1292. $adqAccountList = PitcherService::adqAccountListForUser($adminId, $sysGroupId, $isSystemAdmin);
  1293. $launchAccountIdList = [];
  1294. if($launchAccountId) {
  1295. $launchAccountIdList = [$launchAccountId];
  1296. } else if($appId) {
  1297. # 当前绑定关系查询
  1298. $launchAccountIdList = AdqUser::getAccountIdList($appId);
  1299. # 历史绑定关系查询
  1300. $historyLaunchAccountIdList = PlayletTrendStatistics::getAccountListByAppId($appId, $start, $end);
  1301. $launchAccountIdList = array_values(array_unique(array_merge($launchAccountIdList, $historyLaunchAccountIdList)));
  1302. }
  1303. if($closingDate && $closingDate < $end) {
  1304. $end = $closingDate;
  1305. }
  1306. #先筛选剧集
  1307. $list = DramaUserRela::query()
  1308. ->where('start_date', '<=', $end)
  1309. ->where('end_date', '>=', $start)
  1310. ->where(function($query) use($user_id, $drama_id, $appId, $launchAccountId, $launchAccountIdList){
  1311. if($user_id) $query->where('user_id', $user_id);
  1312. if($drama_id) $query->where('drama_id', $drama_id);
  1313. if($appId || $launchAccountId) $query->whereIn('account_id', $launchAccountIdList);
  1314. })
  1315. ->where(function ($query) use($mpAccountList, $adqAccountList) {
  1316. $query->whereIn('app_id', $mpAccountList)->orWhereIn('account_id', $adqAccountList);
  1317. })
  1318. ->where('enable', 1)
  1319. ->where('sys_group_id', $sysGroupId)
  1320. ->select('drama_id', 'user_id', 'app_id', 'account_id', 'start_date', 'end_date')
  1321. ->get();
  1322. if($list->isEmpty()){
  1323. return null;
  1324. }
  1325. $data = [
  1326. 'cost' => 0,
  1327. 'pay_money' => 0,
  1328. 'first_day_pay' => 0,
  1329. 'first_charge' => 0,
  1330. 'scan_follow_total' => 0,
  1331. 'new_pay_uc' => 0,
  1332. 'day3_charge' => 0,
  1333. 'day7_charge' => 0,
  1334. 'day3_first_day_pay' => 0,
  1335. 'day7_first_day_pay' => 0,
  1336. 'followers_number' => 0,
  1337. 'repeat_fans' => 0,
  1338. ];
  1339. $accountIdList = $list->pluck('account_id')->toArray();
  1340. $accountIdList = array_filter($accountIdList);
  1341. $relationList = AdqUser::getAppIdList($accountIdList);
  1342. $accounts = OfficialAccount::query()->pluck('mp_name', 'mp_app_id');
  1343. foreach($list as $key => $item){
  1344. #查对应时间信息
  1345. $item->start_date = max($item->start_date, $start);
  1346. $item->end_date = min($item->end_date, $end);
  1347. if($closingDate) {
  1348. $item->day3_end_date = (strtotime($item->end_date . '+2 days') > strtotime($closingDate)) ?
  1349. date('Y-m-d', strtotime($closingDate . '-2 days')) : $item->end_date;
  1350. $item->day7_end_date = (strtotime($item->end_date . '+6 days') > strtotime($closingDate)) ?
  1351. date('Y-m-d', strtotime($closingDate . '-6 days')) : $item->end_date;
  1352. } else {
  1353. $item->day3_end_date = (strtotime($item->end_date . '+2 days') > strtotime(date('Y-m-d'))) ?
  1354. date('Y-m-d', strtotime('-2 days')) : $item->end_date;
  1355. $item->day7_end_date = (strtotime($item->end_date . '+6 days') > strtotime(date('Y-m-d'))) ?
  1356. date('Y-m-d', strtotime('-6 days')) : $item->end_date;
  1357. }
  1358. if(!empty($item->app_id)) {
  1359. $res = PlayletTrendStatistics::query()
  1360. ->where('playlet_id', $item->drama_id)
  1361. ->where('ref_date', '>=', $item->start_date)
  1362. ->where('ref_date', '<=', $item->end_date)
  1363. ->where('app_id', $item->app_id)
  1364. ->where('user_id', $item->user_id)
  1365. ->where('enable', 1)
  1366. ->selectRaw('sum(day_paid) as cost, sum(charge_total) as pay_money, sum(new_user_charge) '
  1367. .'as first_day_pay, sum(scan_follow_count) as scan_follow_total, sum(new_user_charge_uv) as new_pay_uc,'
  1368. .' sum(first_user_charge) as first_charge, sum(followers_number) as followers_number, sum(repeat_fans) as'
  1369. .' repeat_fans')
  1370. ->first();
  1371. # 3天倍率金额
  1372. if(!empty($item->day3_end_date)) {
  1373. $day3Charge = PlayletTrendStatistics::query()->where('playlet_id', $item->drama_id)
  1374. ->where('ref_date', '>=', $item->start_date)
  1375. ->where('ref_date', '<=', $item->day3_end_date)
  1376. ->where('app_id', $item->app_id)
  1377. ->where('user_id', $item->user_id)
  1378. ->where('enable', 1)
  1379. ->selectRaw('sum(new_user_charge) as day3_first_day_pay, sum(day3_charge) as day3_charge')
  1380. ->first();
  1381. } else {
  1382. $day3Charge = null;
  1383. }
  1384. # 7天倍率金额
  1385. if(!empty($item->day7_end_date)) {
  1386. $day7Charge = PlayletTrendStatistics::query()->where('playlet_id', $item->drama_id)
  1387. ->where('ref_date', '>=', $item->start_date)
  1388. ->where('ref_date', '<=', $item->day7_end_date)
  1389. ->where('app_id', $item->app_id)
  1390. ->where('user_id', $item->user_id)
  1391. ->where('enable', 1)
  1392. ->selectRaw('sum(new_user_charge) as day7_first_day_pay, sum(day7_charge) as day7_charge')
  1393. ->first();
  1394. } else {
  1395. $day7Charge = null;
  1396. }
  1397. $paramsData = [
  1398. 'account_id' => $item->app_id,
  1399. 'start_date' => $item->start_date,
  1400. 'end_date' => $item->end_date,
  1401. 'closing_date' => $closingDate
  1402. ];
  1403. } else {
  1404. $res = PlayletTrendStatistics::query()->where('playlet_id', $item->drama_id)
  1405. ->where('ref_date', '>=', $item->start_date)
  1406. ->where('ref_date', '<=', $item->end_date)
  1407. ->where('app_id', $item->account_id)
  1408. ->where('user_id', $item->user_id)
  1409. ->where('enable', 1)
  1410. ->selectRaw('sum(day_paid) as cost, sum(charge_total) as pay_money, sum(new_user_charge) '
  1411. .'as first_day_pay, sum(scan_follow_count) as scan_follow_total, sum(new_user_charge_uv) as new_pay_uc,'
  1412. .' sum(first_user_charge) as first_charge, sum(followers_number) as followers_number, sum(repeat_fans) '
  1413. .' as repeat_fans')
  1414. ->first();
  1415. # 3天倍率金额
  1416. if(!empty($item->day3_end_date)) {
  1417. $day3Charge = PlayletTrendStatistics::query()->where('playlet_id', $item->drama_id)
  1418. ->where('ref_date', '>=', $item->start_date)
  1419. ->where('ref_date', '<=', $item->day3_end_date)
  1420. ->where('app_id', $item->account_id)
  1421. ->where('user_id', $item->user_id)
  1422. ->where('enable', 1)
  1423. ->selectRaw('sum(new_user_charge) as day3_first_day_pay, sum(day3_charge) as day3_charge')
  1424. ->first();
  1425. } else {
  1426. $day3Charge = null;
  1427. }
  1428. # 7天倍率金额
  1429. if(!empty($item->day7_end_date)) {
  1430. $day7Charge = PlayletTrendStatistics::query()->where('playlet_id', $item->drama_id)
  1431. ->where('ref_date', '>=', $item->start_date)
  1432. ->where('ref_date', '<=', $item->day7_end_date)
  1433. ->where('app_id', $item->account_id)
  1434. ->where('user_id', $item->user_id)
  1435. ->where('enable', 1)
  1436. ->selectRaw('sum(new_user_charge) as day7_first_day_pay, sum(day7_charge) as day7_charge')
  1437. ->first();
  1438. } else {
  1439. $day7Charge = null;
  1440. }
  1441. # 获取绑定信息
  1442. $bindInformation = PlayletTrendStatistics::getAccountBindInformation($item->account_id, $item->start_date, $item->end_date, $accounts);
  1443. #adq账号
  1444. if(!empty($bindInformation['bind_app_list'])) {
  1445. $item->official_account_id = array_column($bindInformation['bind_app_list'], 'app_id');
  1446. } else {
  1447. $relationInfo = $relationList->where('account_id', $item->account_id)->first();
  1448. $officialAccountId = $relationInfo->app_id ?? null;
  1449. $item->official_account_id = !empty($officialAccountId) ? [$officialAccountId] : [];
  1450. }
  1451. # 判断筛选公众号与当前公众号是否有交集
  1452. if(!empty($appId) && empty(array_intersect($item->official_account_id, $appId))) {
  1453. unset($list[$key]);
  1454. continue;
  1455. }
  1456. $paramsData = [
  1457. 'account_id' => $item->account_id,
  1458. 'start_date' => $item->start_date,
  1459. 'end_date' => $item->end_date,
  1460. 'closing_date' => $closingDate
  1461. ];
  1462. }
  1463. if($closingDate) {
  1464. $chargeTotal = AccountDataTrend::getChargeTotal($paramsData);
  1465. $res->pay_money = round($chargeTotal/100, 2);
  1466. }
  1467. if( !isset($res->cost) ){
  1468. $item->cost = 0;
  1469. $item->pay_money = 0;
  1470. $item->first_day_pay = 0;
  1471. $item->first_charge = 0;
  1472. $item->scan_follow_total = 0;
  1473. $item->new_pay_uc = 0;
  1474. $item->day3_charge = 0;
  1475. $item->day7_charge = 0;
  1476. $item->day3_first_day_pay = 0;
  1477. $item->day7_first_day_pay = 0;
  1478. $item->followers_number = 0;
  1479. $item->repeat_fans = 0;
  1480. } else {
  1481. $item->cost = $res->cost;
  1482. $item->pay_money = $res->pay_money;
  1483. $item->first_day_pay = $res->first_day_pay;
  1484. $item->first_charge = $res->first_charge;
  1485. $item->scan_follow_total = $res->scan_follow_total;
  1486. $item->new_pay_uc = $res->new_pay_uc;
  1487. $item->day3_charge = $day3Charge->day3_charge ?? 0;
  1488. $item->day7_charge = $day7Charge->day7_charge ?? 0;
  1489. $item->day3_first_day_pay = $day3Charge->day3_first_day_pay ?? 0;
  1490. $item->day7_first_day_pay = $day7Charge->day7_first_day_pay ?? 0;
  1491. $item->followers_number = $res->followers_number??0;
  1492. $item->repeat_fans = $res->repeat_fans??0;
  1493. }
  1494. $data['cost'] += $item->cost;
  1495. $data['pay_money'] += $item->pay_money;
  1496. $data['first_day_pay'] += $item->first_day_pay;
  1497. $data['first_charge'] += $item->first_charge;
  1498. $data['scan_follow_total'] += $item->scan_follow_total;
  1499. $data['followers_number'] += $item->followers_number;
  1500. $data['repeat_fans'] += $item->repeat_fans;
  1501. $data['new_pay_uc'] += $item->new_pay_uc;
  1502. $data['day3_charge'] += $item->day3_charge;
  1503. $data['day7_charge'] += $item->day7_charge;
  1504. $data['day3_first_day_pay'] += $item->day3_first_day_pay;
  1505. $data['day7_first_day_pay'] += $item->day7_first_day_pay;
  1506. }
  1507. // 累计消耗
  1508. $data['cost'] = round($data['cost'], 2);
  1509. // 累计充值
  1510. $data['pay_money'] = round($data['pay_money'], 2);
  1511. // 每日新用户充值金额之和
  1512. $data['first_day_pay'] = round($data['first_day_pay'], 2);
  1513. // 首日roi
  1514. $data['first_day_roi'] = $data['cost']>0 ? round($data['first_day_pay']/$data['cost'], 2) : null;
  1515. // 新用户首单充值金额
  1516. $data['first_charge'] = round($data['first_charge'], 2);
  1517. // 新用户首单roi
  1518. $data['first_roi'] = $data['cost'] >0 ? round($data['first_charge']/$data['cost'], 2) : null;
  1519. // 总毛利额
  1520. $data['profile'] = $data['pay_money'] - $data['cost'];
  1521. // 回本率
  1522. $data['recall_rate'] = $data['cost']>0 ? round($data['pay_money']/$data['cost']*100, 2) : null;
  1523. // 企微关注成本
  1524. $data['qw_cost'] = $data['scan_follow_total']>0 ? round($data['cost']/$data['scan_follow_total'], 2) : null;
  1525. // 企微加粉成本
  1526. $data['followers_cost'] = $data['followers_number'] > 0 ? round($data['cost'] / $data['followers_number'], 2) : null;
  1527. // 新注册用户成本
  1528. $data['new_cost'] = $data['new_pay_uc']>0 ? round($data['cost']/$data['new_pay_uc'], 2) : null;
  1529. // 3天倍率
  1530. $data['three_days_rate'] = $data['day3_first_day_pay']>0 ? round($data['day3_charge'] / $data['day3_first_day_pay'], 2) : "0";
  1531. // 3天充值金额
  1532. $data['day3_charge'] = round($data['day3_charge'], 2);
  1533. // 3天首日充值
  1534. $data['day3_first_day_pay'] = round($data['day3_first_day_pay'], 2);
  1535. // 7天倍率
  1536. $data['seven_days_rate'] = $data['day7_first_day_pay']>0 ? round($data['day7_charge'] / $data['day7_first_day_pay'], 2) : "0";
  1537. // 7天充值金额
  1538. $data['day7_charge'] = round($data['day7_charge'], 2);
  1539. // 7天首日充值金额
  1540. $data['day7_first_day_pay'] = round($data['day7_first_day_pay'], 2);
  1541. // 留存复粉率
  1542. $data['repeat_rate'] = $data['followers_number'] > 0 ? round($data['repeat_fans'] / $data['followers_number'] * 100, 2) : '0';
  1543. return $data;
  1544. }
  1545. public static function throwPersonList($start, $end, $user_id, $drama_id, $page, $pageSize, $sysGroupId, $sortField
  1546. , $adminId, $isSystemAdmin, $appId, $launchAccountId, $closingDate)
  1547. {
  1548. $mpAccountList = OfficialAccount::getAccountMpAppIdList($adminId, $sysGroupId, $isSystemAdmin);
  1549. $adqAccountList = PitcherService::adqAccountListForUser($adminId, $sysGroupId, $isSystemAdmin);
  1550. $launchAccountIdList = [];
  1551. if($launchAccountId) {
  1552. $launchAccountIdList = [$launchAccountId];
  1553. } else if($appId) {
  1554. # 当前绑定关系查询
  1555. $launchAccountIdList = AdqUser::getAccountIdList($appId);
  1556. # 历史绑定关系查询
  1557. $historyLaunchAccountIdList = PlayletTrendStatistics::getAccountListByAppId($appId, $start, $end);
  1558. $launchAccountIdList = array_values(array_unique(array_merge($launchAccountIdList, $historyLaunchAccountIdList)));
  1559. }
  1560. if('date' != $sortField || !empty($appId)) {
  1561. # 由于公众号筛选时的日期与列表中实际日期并不一致,因此需要再列表中将不符合条件的数据过滤掉,从而导致要查询所有的数据
  1562. list($data, $count) = self::throwPersonListBySort($start, $end, $user_id, $drama_id, $page, $pageSize
  1563. , $sysGroupId, $sortField, $mpAccountList, $adqAccountList, $appId, $launchAccountId, $launchAccountIdList
  1564. , $closingDate);
  1565. return [$data, $count];
  1566. }
  1567. if($closingDate && $closingDate < $end) {
  1568. $end = $closingDate;
  1569. }
  1570. $offset = ($page-1) * $pageSize;
  1571. #先筛选剧集
  1572. $listQuery = DramaUserRela::query()->where('sys_group_id', $sysGroupId)
  1573. ->where('start_date', '<=', $end)->where('end_date', '>=', $start)
  1574. ->where(function($query) use($user_id, $drama_id, $appId, $launchAccountId, $launchAccountIdList){
  1575. if($user_id) $query->where('user_id', $user_id);
  1576. if($drama_id) $query->where('drama_id', $drama_id);
  1577. if($appId || $launchAccountId) $query->whereIn('account_id', $launchAccountIdList);
  1578. })
  1579. ->where(function ($query) use($mpAccountList, $adqAccountList) {
  1580. $query->whereIn('app_id', $mpAccountList)->orWhereIn('account_id', $adqAccountList);
  1581. })->where('enable', 1);
  1582. $total = $listQuery->count();
  1583. $list = $listQuery->select('drama_id', 'user_id', 'app_id', 'account_id', 'start_date', 'end_date', 'disable_date')
  1584. ->orderBy('start_date', 'desc')
  1585. ->offset($offset)
  1586. ->limit($pageSize)
  1587. ->get();
  1588. if($list->isEmpty()){
  1589. return [[], 0];
  1590. }
  1591. // self::throwPersonListFormat($list, $start, $end);
  1592. NewStatisticsService::throwPersonListFormat($list, $start, $end, $closingDate, $appId);
  1593. return [$list,$total];
  1594. }
  1595. public static function throwPersonListBySort($start, $end, $user_id, $drama_id, $page, $pageSize, $sysGroupId
  1596. , $sortField, $mpAccountList, $adqAccountList, $appId, $launchAccountId, $launchAccountIdList, $closingDate)
  1597. {
  1598. if($closingDate && $closingDate < $end) {
  1599. $end = $closingDate;
  1600. }
  1601. $offset = ($page-1) * $pageSize;
  1602. #先筛选剧集
  1603. $listQuery = DramaUserRela::query()->where('sys_group_id', $sysGroupId)
  1604. ->where('start_date', '<=', $end)->where('end_date', '>=', $start)
  1605. ->where(function($query) use($user_id, $drama_id, $appId, $launchAccountId, $launchAccountIdList){
  1606. if($user_id) $query->where('user_id', $user_id);
  1607. if($drama_id) $query->where('drama_id', $drama_id);
  1608. if($appId || $launchAccountId) $query->whereIn('account_id', $launchAccountIdList);
  1609. })
  1610. ->where(function ($query) use($mpAccountList, $adqAccountList) {
  1611. $query->whereIn('app_id', $mpAccountList)
  1612. ->orWhereIn('account_id', $adqAccountList);
  1613. })->where('enable', 1);
  1614. // $total = $listQuery->count();
  1615. $list = $listQuery->select('drama_id', 'user_id', 'app_id', 'account_id', 'start_date', 'end_date', 'disable_date')
  1616. ->get();
  1617. if($list->isEmpty()){
  1618. return [[], 0];
  1619. }
  1620. // self::throwPersonListFormat($list, $start, $end);
  1621. NewStatisticsService::throwPersonListFormat($list, $start, $end, $closingDate, $appId);
  1622. // 内存中排序
  1623. $list = json_decode(json_encode($list), 1);
  1624. $key = array_column($list, $sortField);
  1625. array_multisort($key, SORT_DESC, $list);
  1626. $list = array_values($list);
  1627. $total = count($list);
  1628. // 分页
  1629. $list = array_splice($list, $offset, $pageSize);
  1630. return [$list,$total];
  1631. }
  1632. public static function throwPersonListFormat(&$list, $start, $end) {
  1633. $uids = $list->pluck('user_id');
  1634. $dramaids = $list->pluck('drama_id');
  1635. $accountIdList = $list->pluck('account_id')->toArray();
  1636. $accountIdList = array_filter($accountIdList);
  1637. $accounts = OfficialAccount::query()->pluck('mp_name', 'mp_app_id');
  1638. $users = Users::query()->whereIn('id', $uids)->pluck('name', 'id');
  1639. $playlets = DramaSeries::query()->whereIn('id', $dramaids)->pluck('name', 'id');
  1640. $relationList = AdqUser::getAppIdList($accountIdList);
  1641. $accountData = RedisModel::get(PlayletTrendStatistics::ACCOUNT_USER_LIST);
  1642. $accountData = !empty($accountData) ? json_decode($accountData, 1) : [];
  1643. foreach($list as $item){
  1644. #查对应时间信息
  1645. $item->start_date = $item->start_date>$start ? $item->start_date : $start;
  1646. $item->end_date = $item->end_date<$end ? $item->end_date : $end;
  1647. $item->day3_end_date = (strtotime($item->end_date . '+2 days') > strtotime(date('Y-m-d'))) ?
  1648. date('Y-m-d', strtotime('-2 days')) : $item->end_date;
  1649. $item->day7_end_date = (strtotime($item->end_date . '+6 days') > strtotime(date('Y-m-d'))) ?
  1650. date('Y-m-d', strtotime('-6 days')) : $item->end_date;
  1651. if(!empty($item->app_id)){
  1652. $res = PlayletTrendStatistics::query()->where('playlet_id', $item->drama_id)
  1653. ->where('ref_date', '>=', $item->start_date)
  1654. ->where('ref_date', '<=', $item->end_date)
  1655. ->where('app_id', $item->app_id)
  1656. ->where('user_id', $item->user_id)
  1657. ->where('enable', 1)
  1658. ->selectRaw('sum(day_paid) as cost, sum(charge_total) as pay_money, sum(new_user_charge) '
  1659. .'as first_day_pay, sum(scan_follow_count) as scan_follow_total, sum(new_user_charge_uv) as new_pay_uc')
  1660. ->first();
  1661. #公众号
  1662. $item->account_name = $accounts->get($item->app_id) ?? null;
  1663. $item->official_account_name = null;
  1664. # 3天倍率金额
  1665. if(!empty($item->day3_end_date)) {
  1666. $day3Charge = PlayletTrendStatistics::query()->where('playlet_id', $item->drama_id)
  1667. ->where('ref_date', '>=', $item->start_date)
  1668. ->where('ref_date', '<=', $item->day3_end_date)
  1669. ->where('app_id', $item->app_id)
  1670. ->where('user_id', $item->user_id)
  1671. ->where('enable', 1)
  1672. ->selectRaw('sum(new_user_charge) as day3_first_day_pay, sum(day3_charge) as day3_charge')
  1673. ->first();
  1674. } else {
  1675. $day3Charge = null;
  1676. }
  1677. # 7天倍率金额
  1678. if(!empty($item->day7_end_date)) {
  1679. $day7Charge = PlayletTrendStatistics::query()->where('playlet_id', $item->drama_id)
  1680. ->where('ref_date', '>=', $item->start_date)
  1681. ->where('ref_date', '<=', $item->day7_end_date)
  1682. ->where('app_id', $item->app_id)
  1683. ->where('user_id', $item->user_id)
  1684. ->where('enable', 1)
  1685. ->selectRaw('sum(new_user_charge) as day7_first_day_pay, sum(day7_charge) as day7_charge')
  1686. ->first();
  1687. } else {
  1688. $day7Charge = null;
  1689. }
  1690. } else {
  1691. $res = PlayletTrendStatistics::query()->where('playlet_id', $item->drama_id)
  1692. ->where('ref_date', '>=', $item->start_date)
  1693. ->where('ref_date', '<=', $item->end_date)
  1694. ->where('app_id', $item->account_id)
  1695. ->where('user_id', $item->user_id)
  1696. ->where('enable', 1)
  1697. ->selectRaw('sum(day_paid) as cost, sum(charge_total) as pay_money, sum(new_user_charge) '
  1698. .'as first_day_pay, sum(scan_follow_count) as scan_follow_total, sum(new_user_charge_uv) as new_pay_uc')
  1699. ->first();
  1700. #adq账号
  1701. $item->account_name = $item->account_id;
  1702. $relationInfo = $relationList->where('account_id', $item->account_id)->first();
  1703. $officialAccountId = $relationInfo->app_id ?? null;
  1704. $item->official_account_name = $accounts->get($officialAccountId) ?? null;
  1705. # 3天倍率金额
  1706. if(!empty($item->day3_end_date)) {
  1707. $day3Charge = PlayletTrendStatistics::query()->where('playlet_id', $item->drama_id)
  1708. ->where('ref_date', '>=', $item->start_date)
  1709. ->where('ref_date', '<=', $item->day3_end_date)
  1710. ->where('app_id', $item->account_id)
  1711. ->where('user_id', $item->user_id)
  1712. ->where('enable', 1)
  1713. ->selectRaw('sum(new_user_charge) as day3_first_day_pay, sum(day3_charge) as day3_charge')
  1714. ->first();
  1715. } else {
  1716. $day3Charge = null;
  1717. }
  1718. # 7天倍率金额
  1719. if(!empty($item->day7_end_date)) {
  1720. $day7Charge = PlayletTrendStatistics::query()->where('playlet_id', $item->drama_id)
  1721. ->where('ref_date', '>=', $item->start_date)
  1722. ->where('ref_date', '<=', $item->day7_end_date)
  1723. ->where('app_id', $item->account_id)
  1724. ->where('user_id', $item->user_id)
  1725. ->where('enable', 1)
  1726. ->selectRaw('sum(new_user_charge) as day7_first_day_pay, sum(day7_charge) as day7_charge')
  1727. ->first();
  1728. } else {
  1729. $day7Charge = null;
  1730. }
  1731. }
  1732. if( !isset($res->cost) ){
  1733. $item->cost = null;
  1734. $item->pay_money = null;
  1735. $item->first_day_roi = null;
  1736. $item->profile = null;
  1737. $item->recall_rate = null;
  1738. $item->qw_cost = null;
  1739. $item->new_cost = null;
  1740. $item->scan_follow_total = null;
  1741. $item->three_days_rate = null;
  1742. $item->seven_days_rate = null;
  1743. $item->day3_charge = null;
  1744. $item->day7_charge = null;
  1745. } else {
  1746. // 累计消耗
  1747. $item->cost = round($res->cost, 2);
  1748. // 累计充值
  1749. $item->pay_money = round($res->pay_money, 2);
  1750. // 首日充值金额
  1751. $item->first_day_pay = round($res->first_day_pay, 2);
  1752. // 首日roi
  1753. $item->first_day_roi = $res->cost>0 ? round($res->first_day_pay/$res->cost, 2) : null;
  1754. // 总毛利额
  1755. $item->profile = $res->pay_money - $res->cost;
  1756. // 回本率
  1757. $item->recall_rate = $res->cost>0 ? round($res->pay_money/$res->cost*100, 2) : null;
  1758. // 企微关注用户成本
  1759. $item->qw_cost = $res->scan_follow_total>0 ? round($res->cost/$res->scan_follow_total, 2) : null;
  1760. // 新用户下单成本
  1761. $item->new_cost = $res->new_pay_uc>0 ? round($res->cost/$res->new_pay_uc, 2) : null;
  1762. // 企微关注数
  1763. $item->scan_follow_total = $res->scan_follow_total;
  1764. // 3天倍率
  1765. $item->three_days_rate = !empty($day3Charge->day3_first_day_pay) && $day3Charge->day3_first_day_pay > 0 ? round($day3Charge->day3_charge / $day3Charge->day3_first_day_pay, 2) : "0";
  1766. // 3天充值
  1767. $item->day3_charge = round($day3Charge->day3_charge, 2);
  1768. // 7天倍率
  1769. $item->seven_days_rate = !empty($day7Charge->day7_first_day_pay) && $day7Charge->day7_first_day_pay > 0 ? round($day7Charge->day7_charge / $day7Charge->day7_first_day_pay, 2) : "0";
  1770. // 7天充值
  1771. $item->day7_charge = round($day7Charge->day7_charge, 2);
  1772. }
  1773. #投手
  1774. $item->user_name = $users->get($item->user_id) ?? null;
  1775. #剧集
  1776. $item->playletTitle = $playlets->get($item->drama_id) ?? null;
  1777. #客服
  1778. $item->user_list = $accountData[$item->account_id] ?? [];
  1779. }
  1780. return ;
  1781. }
  1782. public static function officialTrendTotal($start, $end, $appId, $sysGroupId)
  1783. {
  1784. $mpAppIdList = OfficialAccount::getSysGroupMpAppIdList($sysGroupId, 'StatisticsService.officialTrendTotal');
  1785. $cost_info = TencentAdDailyReport::where('enable', 1)
  1786. ->where(function($query) use($appId, $start, $end){
  1787. if($appId) $query->where('app_id', $appId);
  1788. if($start) $query->where('ref_date', '>=', $start);
  1789. if($end) $query->where('ref_date', '<=', $end);
  1790. })
  1791. ->whereIn('app_id', $mpAppIdList)
  1792. ->selectRaw('sum(paid) as cost,
  1793. sum(scan_follow_count) as qw_fans,
  1794. sum(follow_uv) as of_fans
  1795. ')
  1796. ->first();
  1797. if( empty($cost_info) ){
  1798. return [];
  1799. }
  1800. $pay_info = ActiveFansData::where('enable', 1)
  1801. ->where(function($query) use($appId, $start, $end){
  1802. if($appId) $query->where('app_id', $appId);
  1803. if($start) $query->where('expense_date', '>=', $start);
  1804. if($end) $query->where('expense_date', '<=', $end);
  1805. })
  1806. ->whereIn('app_id', $mpAppIdList)
  1807. ->selectRaw('sum(active_fans) as pay_ucnt,
  1808. sum(pay_count) as pay_cnt,
  1809. sum(pay_money) as pay_money
  1810. ')
  1811. ->first();
  1812. $first_pay_info = ActiveFansData::where('enable', 1)
  1813. ->where(function($query) use($appId, $start, $end){
  1814. if($appId) $query->where('app_id', $appId);
  1815. if($start) $query->where('expense_date', '>=', $start);
  1816. if($end) $query->where('expense_date', '<=', $end);
  1817. })
  1818. ->whereIn('app_id', $mpAppIdList)
  1819. ->whereRaw('expense_date=ref_date')
  1820. ->selectRaw('sum(active_fans) as pay_ucnt,
  1821. sum(pay_count) as pay_cnt,
  1822. sum(pay_money) as pay_money
  1823. ')
  1824. ->first();
  1825. $result = array();
  1826. $result['first_roi'] = $cost_info->cost>0 && isset($first_pay_info->pay_money) ? round($first_pay_info->pay_money/$cost_info->cost, 2) : null;
  1827. $result['cost'] = round($cost_info->cost/100);
  1828. $result['qw_fans'] = $cost_info->qw_fans;
  1829. $result['qw_fans_cost'] = $cost_info->qw_fans>0 ? round($cost_info->cost/100/$cost_info->qw_fans, 2) : null;
  1830. $result['first_pay_money'] = isset($first_pay_info->pay_money) ? round($first_pay_info->pay_money/100, 2) : null;
  1831. $result['pay_money'] = isset($pay_info->pay_money) ? round($pay_info->pay_money/100, 2) : null;
  1832. $result['of_fans'] = $cost_info->of_fans;
  1833. $result['income_rate'] = $cost_info->cost>0 && isset($pay_info->pay_money) ? round($pay_info->pay_money/$cost_info->cost*100, 2) : null;
  1834. $result['first_pay_ucnt'] = $first_pay_info->pay_ucnt ?? null;
  1835. $result['first_pay_cnt'] = $first_pay_info->pay_cnt ?? null;
  1836. $result['pay_ucnt'] = $pay_info->pay_ucnt ?? null;
  1837. $result['pay_cnt'] = $pay_info->pay_cnt ?? null;
  1838. $result['pay_ucnt_cost'] = isset($pay_info->pay_ucnt) && $pay_info->pay_ucnt>0 ? round($cost_info->cost/100/$pay_info->pay_ucnt, 2) : null;
  1839. return $result;
  1840. }
  1841. public static function officialTrendList($start, $end, $appId, $page, $pagesize, $sysGroupId)
  1842. {
  1843. $mpAppIdList = OfficialAccount::getSysGroupMpAppIdList($sysGroupId, 'StatisticsService.officialTrendList');
  1844. $cost_query = TencentAdDailyReport::where('enable', 1)
  1845. ->where(function($query) use($appId, $start, $end){
  1846. if($appId) $query->where('app_id', $appId);
  1847. if($start) $query->where('ref_date', '>=', $start);
  1848. if($end) $query->where('ref_date', '<=', $end);
  1849. })
  1850. ->whereIn('app_id', $mpAppIdList);
  1851. #150天数据初始定义
  1852. $day_columns = $day_arr = array();
  1853. // for($i=0; $i<150; $i++){
  1854. for($i=0; $i<60; $i++){
  1855. $day_columns[$i] = 'day'. ($i+1);
  1856. $day_arr[$i] = null;
  1857. }
  1858. $total = (clone $cost_query)->count();
  1859. if($total == 0){
  1860. return [[], 0, $day_columns];
  1861. }
  1862. $offset = ($page-1) * $pagesize;
  1863. $list = $cost_query->selectRaw('ref_date, app_id, paid as cost, scan_follow_count as qw_fans, follow_uv as of_fans')
  1864. ->orderBy('ref_date', 'desc')
  1865. ->offset($offset)
  1866. ->limit($pagesize)
  1867. ->get();
  1868. if( $list->isEmpty() ){
  1869. return [[], 0, $day_columns];
  1870. }
  1871. #公众号名字
  1872. $app_ids = $list->pluck('app_id')->toArray();
  1873. $accounts = OfficialAccount::whereIn('mp_app_id', $app_ids)->pluck('mp_name', 'mp_app_id')->toArray();
  1874. $data = array();
  1875. foreach ($list as $cost_info) {
  1876. $cost_info->app_name = $accounts[$cost_info->app_id] ?? '';
  1877. $app_id = $cost_info->app_id;
  1878. #当天收入信息
  1879. $first_pay_info = ActiveFansData::where('enable', 1)
  1880. ->where('app_id', $app_id)
  1881. ->where('expense_date', '=', $cost_info->ref_date)
  1882. ->where('ref_date', '=', $cost_info->ref_date)
  1883. ->selectRaw('active_fans as pay_ucnt,
  1884. pay_count as pay_cnt,
  1885. pay_money
  1886. ')
  1887. ->first();
  1888. #到今日累计信息
  1889. $pay_info = ActiveFansData::where('enable', 1)
  1890. ->where('app_id', $app_id)
  1891. ->where('expense_date', '=', $cost_info->ref_date)
  1892. ->selectRaw('sum(active_fans) as pay_ucnt,
  1893. sum(pay_count) as pay_cnt,
  1894. sum(pay_money) as pay_money
  1895. ')
  1896. ->first();
  1897. #查150天数据
  1898. $day_info = $day_arr;
  1899. $end_date = date('Y-m-d', strtotime($cost_info->ref_date.' +149 day'));
  1900. $day_data = ActiveFansData::where('enable', 1)
  1901. ->where('app_id', $app_id)
  1902. ->where('expense_date', '=', $cost_info->ref_date)
  1903. ->where('ref_date', '<=', $end_date)
  1904. ->select('pay_money', 'pay_money_total', 'ref_date')
  1905. ->get()
  1906. ->toArray();
  1907. if( !empty($day_data) ){
  1908. foreach($day_data as $val){
  1909. $nd = (strtotime($val['ref_date']) - strtotime($cost_info->ref_date))/86400;
  1910. $new_roi = $cost_info->cost>0 ? round($val['pay_money'] / $cost_info->cost, 4) * 100 . '%' : null;
  1911. $total_roi = $cost_info->cost>0 ? round($val['pay_money_total'] / $cost_info->cost, 4) * 100 . '%' : null;
  1912. $income_times = isset($first_pay_info->pay_money) && $first_pay_info->pay_money>0 ? round($val['pay_money_total'] / $first_pay_info->pay_money, 2) : null;
  1913. $day_info[$nd] = [
  1914. 'date' => $val['ref_date'],
  1915. 'pay_money' => round($val['pay_money']/100, 2),
  1916. 'new_roi' => $new_roi,
  1917. 'total_roi' => $total_roi,
  1918. 'income_times' => $income_times
  1919. ];
  1920. }
  1921. }
  1922. $result = array();
  1923. $result['ref_date'] = $cost_info->ref_date;
  1924. $result['app_id'] = $cost_info->app_id;
  1925. $result['app_name'] = $cost_info->app_name;
  1926. $result['first_roi'] = $cost_info->cost>0 && isset($first_pay_info->pay_money) ? round($first_pay_info->pay_money/$cost_info->cost, 2) : null;
  1927. $result['cost'] = round($cost_info->cost/100, 2);
  1928. $result['qw_fans'] = $cost_info->qw_fans;
  1929. $result['qw_fans_cost'] = $cost_info->qw_fans>0 ? round($cost_info->cost/100/$cost_info->qw_fans, 2) : null;
  1930. $result['first_pay_money'] = isset($first_pay_info->pay_money) ? round($first_pay_info->pay_money/100, 2) : null;
  1931. $result['pay_money'] = isset($pay_info->pay_money) ? round($pay_info->pay_money/100, 2) : null;
  1932. $result['of_fans'] = $cost_info->of_fans;
  1933. $result['income_rate'] = $cost_info->cost>0 && isset($pay_info->pay_money) ? round($pay_info->pay_money/$cost_info->cost*100, 2) : null;
  1934. $result['first_pay_ucnt'] = $first_pay_info->pay_ucnt ?? null;
  1935. $result['first_pay_cnt'] = $first_pay_info->pay_cnt ?? null;
  1936. $result['pay_ucnt'] = $pay_info->pay_ucnt ?? null;
  1937. $result['pay_cnt'] = $pay_info->pay_cnt ?? null;
  1938. $result['pay_ucnt_cost'] = isset($pay_info->pay_ucnt) && $pay_info->pay_ucnt>0 ?
  1939. round($cost_info->cost/100/$pay_info->pay_ucnt, 2) : null;
  1940. $result['day_info'] = $day_info;
  1941. $data[] = $result;
  1942. }
  1943. return [$data, $total, $day_columns];
  1944. }
  1945. public static function pitcherData($stDate, $enDate, $userId, $page, $pageSize, $sortField, $sysGroupId, $adminId
  1946. , $isSystemAdmin)
  1947. {
  1948. $summary = [
  1949. 'sum_paid' => 0,// 消耗
  1950. 'sum_charge' => 0,// 累计充值
  1951. 'sum_roi' => 0,// 首日roi
  1952. 'first_roi' => 0,// 首日首单roi
  1953. 'sum_profit' => 0,// 利润额
  1954. 'sum_recover_rate' => 0,// 回本率
  1955. 'sum_day_charge' => 0,// 新用户首日充值金额
  1956. 'qw_cost' => 0,
  1957. 'new_cost' => 0,
  1958. 'new_pay_uc' => 0,//首日下单人数
  1959. 'followers_cost' => 0,// 企微实际加粉成本
  1960. 'followers_number' => 0,// 企微实际加粉人数
  1961. ];
  1962. $list = [];
  1963. // $mpAppIdList = OfficialAccount::getSysGroupMpAppIdList($sysGroupId, 'StatisticsService.pitcherData');
  1964. // $accountIdList = OfficialWebUserActionSetId::query()
  1965. // ->where('sys_group_id', $sysGroupId)
  1966. // ->where('enable', 1)
  1967. // ->get();
  1968. //
  1969. // $accountIdList = $accountIdList->isNotEmpty() ? $accountIdList->pluck('account_id')->toArray() : [];
  1970. // $accountIdList = array_merge($accountIdList, $mpAppIdList);
  1971. $accountIdList = PitcherService::adAccountList(null, $sysGroupId, $adminId, $isSystemAdmin);
  1972. $accountIdList = array_column($accountIdList, 'account_id');
  1973. // 初始化对象
  1974. $query = PlayletTrendStatistics::query()
  1975. ->whereBetween('ref_date', [$stDate, $enDate])
  1976. ->where(function ($query) use ($userId, $stDate, $enDate) {
  1977. if (!empty($userId)) $query->where('user_id', $userId);
  1978. })
  1979. ->where('enable', 1)
  1980. ->whereIn('app_id', $accountIdList);
  1981. $total = (clone $query)->select(['user_id'])->distinct()->get()->count();
  1982. if ($total > 0) {
  1983. // 统计汇总数据
  1984. $summaryData = (clone $query)
  1985. ->selectRaw('SUM(day_paid) AS sum_paid, SUM(new_user_charge) AS sum_day_charge, SUM(charge_total)'
  1986. .' AS sum_charge, sum(scan_follow_count) as scan_follow_total, sum(new_user_charge_uv) as new_pay_uc, '
  1987. .'sum(first_user_charge) as sum_first_charge, sum(followers_number) as followers_number')
  1988. ->first();
  1989. $summary['sum_paid'] = $summaryData->sum_paid ?? 0;
  1990. $summary['sum_charge'] = $summaryData->sum_charge ?? 0;
  1991. $summary['sum_day_charge'] = $summaryData->sum_day_charge ?? 0;
  1992. $summary['sum_first_charge'] = $summaryData->sum_first_charge ?? 0;
  1993. $summary['sum_roi'] = $summaryData->sum_paid > 0 ? round($summaryData->sum_day_charge / $summaryData->sum_paid, 2) : 0;
  1994. $summary['first_roi'] = $summaryData->sum_paid > 0 ? round($summaryData->sum_first_charge / $summaryData->sum_paid, 2) : 0;
  1995. $summary['sum_profit'] = round($summaryData->sum_charge - $summaryData->sum_paid, 2);
  1996. $summary['sum_recover_rate'] = ($summaryData->sum_paid > 0 ? round(($summaryData->sum_charge / $summaryData->sum_paid) * 100, 2) : 0) . '%';
  1997. $summary['qw_cost'] = $summaryData->scan_follow_total>0 ? round($summaryData->sum_paid/$summaryData->scan_follow_total, 2) : null;
  1998. $summary['new_cost'] = $summaryData->new_pay_uc>0 ? round($summaryData->sum_paid/$summaryData->new_pay_uc, 2) : null;
  1999. $summary['new_pay_uc'] = $summaryData->new_pay_uc ?? 0;
  2000. $summary['followers_cost'] = $summaryData->followers_number>0?round($summaryData->sum_paid/$summaryData->followers_number, 2) : null;
  2001. $summary['followers_number'] = $summaryData->followers_number ?? 0;
  2002. // 统计列表数据
  2003. $listData = (clone $query)
  2004. ->select(['user_id'])
  2005. ->selectRaw('COUNT(DISTINCT ref_date) AS date_num')
  2006. ->selectRaw('COUNT(DISTINCT app_id) AS app_num')
  2007. ->selectRaw('SUM(day_paid) AS day_paid')
  2008. ->selectRaw('SUM(charge_total) AS charge_total')
  2009. ->selectRaw('SUM(new_user_charge) AS new_user_charge_total')
  2010. ->selectRaw('IF(SUM(day_paid) > 0, SUM(new_user_charge) / SUM(day_paid), 0) AS roi')
  2011. ->selectRaw('(SUM(charge_total) - SUM(day_paid)) AS profit')
  2012. ->selectRaw('IF(SUM(day_paid) > 0, SUM(charge_total) / SUM(day_paid), 0) AS recover_rate')
  2013. ->selectRaw('IF(SUM(scan_follow_count) > 0, SUM(day_paid) / SUM(scan_follow_count), 0) AS qw_cost')
  2014. ->selectRaw('IF(SUM(new_user_charge_uv) > 0, SUM(day_paid) / SUM(new_user_charge_uv), 0) AS new_cost')
  2015. ->selectRaw('IF(SUM(day_paid) > 0, SUM(first_user_charge) / SUM(day_paid), 0) as first_roi')
  2016. ->selectRaw('IF(SUM(followers_number) > 0, SUM(day_paid) / SUM(followers_number), 0) AS followers_cost')
  2017. ->selectRaw('SUM(followers_number) AS followers_number')
  2018. ->groupBy('user_id')
  2019. ->orderByDesc($sortField)
  2020. ->offset(($page - 1) * $pageSize)
  2021. ->limit($pageSize)
  2022. ->get();
  2023. $userList = Users::query()
  2024. ->whereIn('id', $listData->pluck('user_id'))
  2025. ->pluck('name', 'id');
  2026. foreach ($listData as $value) {
  2027. $value->new_user_charge = round($value->new_user_charge, 2);
  2028. $value->roi = round($value->roi * 100, 1) . '%';
  2029. $value->first_roi = round($value->first_roi * 100, 1) . '%';
  2030. $value->profit = round($value->profit, 2);
  2031. $value->recover_rate = round($value->recover_rate * 100, 2) . '%';
  2032. $value->user_name = $userList->get($value->user_id) ?? null;
  2033. $value->qw_cost = round($value->qw_cost, 2);
  2034. $value->new_cost = round($value->new_cost, 2);
  2035. $value->followers_cost=round($value->followers_cost, 2);
  2036. $uniqueNewChargeUser = DataStatisticsService::statisticsDataUniqueUser($stDate, $enDate, null
  2037. , $value->user_id, $sysGroupId, 1, $adminId, $isSystemAdmin);
  2038. $uniqueNewChargeUser = isset($uniqueNewChargeUser['new_user_charge_uv_unique']) ? $uniqueNewChargeUser['new_user_charge_uv_unique'] : 0;
  2039. $value->unique_new_cost = ($uniqueNewChargeUser > 0) ? round($value->day_paid / $uniqueNewChargeUser, 2) : 0;
  2040. }
  2041. $list = $listData->toArray();
  2042. }
  2043. $data = [
  2044. 'list' => $list,
  2045. 'summary' => $summary,
  2046. ];
  2047. return [$data, $total];
  2048. }
  2049. public static function getAuthCorpids($admin_id)
  2050. {
  2051. $ids = AdminManageCorp::where('sys_user_id', $admin_id)
  2052. ->where('is_delete', 0)
  2053. ->pluck('corpid')
  2054. ->all();
  2055. if( empty($ids) ){
  2056. return [];
  2057. }
  2058. $corpids = AuthorizeCorp::whereIn('id', $ids)->where('enable', 1)->pluck('corpid')->all();
  2059. return $corpids;
  2060. }
  2061. public static function custTotalNew($corpid, $group_admin_id, $is_system_admin, $sys_group_id)
  2062. {
  2063. // $corpids = null;
  2064. // if($is_system_admin==0){
  2065. // $corpids = self::getAuthCorpids($group_admin_id);
  2066. // }
  2067. $corpids = self::getAuthCorpids($sys_group_id);
  2068. $date = date('Y-m-d', strtotime('-5 minute'));
  2069. $last_date = date('Y-m-d', strtotime($date. ' -1 day'));
  2070. $h = (int)date('H', strtotime('-5 minute'));
  2071. if($corpid){
  2072. $today = CustomerHourRecord::select(
  2073. 'cust_total_uc',
  2074. 'cust_add_uc',
  2075. 'cust_loss_uc',
  2076. 'official_account_uc',
  2077. 'cust_pay_uc',
  2078. 'cust_pay_amount',
  2079. 'cust_pay_uc_total',
  2080. 'cust_loss_uc_total',
  2081. 'cust_pay_amount_total'
  2082. )
  2083. ->where('corpid', $corpid)
  2084. ->where('idate', $date)
  2085. ->where('hour', $h)
  2086. ->where(function($query) use($corpids){
  2087. if(!empty($corpids)) $query->whereIn('corpid', $corpids);
  2088. })
  2089. ->first();
  2090. $last = CustomerHourRecord::select(
  2091. 'cust_total_uc',
  2092. 'cust_add_uc',
  2093. 'cust_loss_uc',
  2094. 'official_account_uc',
  2095. 'cust_pay_uc',
  2096. 'cust_pay_amount',
  2097. 'cust_pay_uc_total',
  2098. 'cust_loss_uc_total',
  2099. 'cust_pay_amount_total'
  2100. )
  2101. ->where('corpid', $corpid)
  2102. ->where('idate', $last_date)
  2103. ->where('hour', $h)
  2104. ->where(function($query) use($corpids){
  2105. if(!empty($corpids)) $query->whereIn('corpid', $corpids);
  2106. })
  2107. ->first();
  2108. } else {
  2109. $today = CustomerHourRecord::selectRaw(
  2110. 'sum(cust_total_uc) as cust_total_uc,' .
  2111. 'sum(cust_add_uc) as cust_add_uc,' .
  2112. 'sum(cust_loss_uc) as cust_loss_uc,' .
  2113. 'sum(official_account_uc) as official_account_uc,' .
  2114. 'sum(cust_pay_uc) as cust_pay_uc,' .
  2115. 'sum(cust_pay_amount) as cust_pay_amount,' .
  2116. 'sum(cust_pay_uc_total) as cust_pay_uc_total,' .
  2117. 'sum(cust_loss_uc_total) as cust_loss_uc_total,' .
  2118. 'sum(cust_pay_amount_total) as cust_pay_amount_total'
  2119. )
  2120. ->where('idate', $date)
  2121. ->where('hour', $h)
  2122. ->where(function($query) use($corpids){
  2123. if(!empty($corpids)) $query->whereIn('corpid', $corpids);
  2124. })
  2125. ->first();
  2126. $last = CustomerHourRecord::selectRaw(
  2127. 'sum(cust_total_uc) as cust_total_uc,' .
  2128. 'sum(cust_add_uc) as cust_add_uc,' .
  2129. 'sum(cust_loss_uc) as cust_loss_uc,' .
  2130. 'sum(official_account_uc) as official_account_uc,' .
  2131. 'sum(cust_pay_uc) as cust_pay_uc,' .
  2132. 'sum(cust_pay_amount) as cust_pay_amount,' .
  2133. 'sum(cust_pay_uc_total) as cust_pay_uc_total,' .
  2134. 'sum(cust_loss_uc_total) as cust_loss_uc_total,' .
  2135. 'sum(cust_pay_amount_total) as cust_pay_amount_total'
  2136. )
  2137. ->where('idate', $last_date)
  2138. ->where('hour', $h)
  2139. ->where(function($query) use($corpids){
  2140. if(!empty($corpids)) $query->whereIn('corpid', $corpids);
  2141. })
  2142. ->first();
  2143. }
  2144. if(empty($today)){
  2145. return null;
  2146. }
  2147. $today->cust_total_uc_compare = $today->cust_total_uc - ($last->cust_total_uc ?? 0);
  2148. $today->cust_add_uc_compare = $today->cust_add_uc - ($last->cust_add_uc ?? 0);
  2149. $today->cust_loss_uc_compare = $today->cust_loss_uc - ($last->cust_loss_uc ?? 0);
  2150. $today->official_account_uc_compare = $today->official_account_uc - ($last->official_account_uc ?? 0);
  2151. $today->cust_pay_uc_compare = $today->cust_pay_uc - ($last->cust_pay_uc ?? 0);
  2152. $today->cust_pay_amount_compare = $today->cust_pay_amount - ($last->cust_pay_amount ?? 0);
  2153. $today->charge_user_cost = $today->cust_pay_uc_total > 0 ? round($today->cust_pay_amount_total / $today->cust_pay_uc_total) : 0;
  2154. $last->charge_user_cost = $last->cust_pay_uc_total > 0 ? round($last->cust_pay_amount_total / $last->cust_pay_uc_total) : 0;
  2155. $today->charge_user_cost_compare = $today->charge_user_cost - $last->charge_user_cost;
  2156. return $today;
  2157. }
  2158. public static function custTrendsNew($corpid, $start, $end, $group_admin_id, $is_system_admin, $sys_group_id)
  2159. {
  2160. // $corpids = null;
  2161. // if($is_system_admin==0){
  2162. // $corpids = self::getAuthCorpids($group_admin_id);
  2163. // }
  2164. $corpids = self::getAuthCorpids($sys_group_id);
  2165. $res = CustomerDayReport::selectRaw(
  2166. 'sum(cust_total_uc) as cust_total_uc,' .
  2167. 'sum(cust_add_uc) as cust_add_uc,' .
  2168. 'sum(cust_loss_uc) as cust_loss_uc,' .
  2169. 'sum(cust_gain_uc) as cust_gain_uc,' .
  2170. 'sum(official_account_uc) as official_account_uc,' .
  2171. 'sum(cust_pay_uc) as cust_pay_uc,' .
  2172. 'sum(cust_pay_amount) as cust_pay_amount,' .
  2173. 'sum(total_cust_pay_amount) as total_cust_pay_amount,' .
  2174. 'sum(total_cost) as total_cost,' .
  2175. 'idate'
  2176. )
  2177. ->where('idate', '>=', $start)
  2178. ->where('idate', '<=', $end)
  2179. ->where(function($query) use($corpid){
  2180. if($corpid) $query->where('corpid', $corpid);
  2181. })
  2182. ->where(function($query) use($corpids){
  2183. if(!empty($corpids)) $query->whereIn('corpid', $corpids);
  2184. })
  2185. ->groupBy('idate')
  2186. ->orderBy('idate', 'asc')
  2187. ->get();
  2188. foreach ($res as $val) {
  2189. # 付费用户客单价 = 付费金额/付费人数
  2190. $val->charge_user_cost = $val->cust_pay_uc > 0 ? round($val->cust_pay_amount / $val->cust_pay_uc) : 0;
  2191. }
  2192. return $res;
  2193. }
  2194. public static function custDataList($corpid, $group_admin_id, $is_system_admin, $sys_group_id)
  2195. {
  2196. // $corpids = null;
  2197. // if($is_system_admin==0){
  2198. // $corpids = self::getAuthCorpids($group_admin_id);
  2199. // }
  2200. $corpids = self::getAuthCorpids($sys_group_id);
  2201. $date = date('Y-m-d', strtotime('-5 minute'));
  2202. $h = (int)date('H', strtotime('-5 minute'));
  2203. $list = CustomerHourRecord::select(
  2204. 'cust_total_uc',
  2205. 'cust_add_uc',
  2206. 'cust_loss_uc',
  2207. 'official_account_uc',
  2208. 'cust_pay_uc',
  2209. 'cust_pay_amount',
  2210. 'cust_pay_uc_total',
  2211. 'cust_loss_uc_total',
  2212. 'cust_pay_amount_total',
  2213. 'corpid'
  2214. )
  2215. ->where('idate', $date)
  2216. ->where('hour', $h)
  2217. ->where(function($query) use($corpid){
  2218. if($corpid) $query->where('corpid', $corpid);
  2219. })
  2220. ->where(function($query) use($corpids){
  2221. if(!empty($corpids)) $query->whereIn('corpid', $corpids);
  2222. })
  2223. ->get();
  2224. foreach($list as $item){
  2225. #获取企微名称
  2226. $item->corp_name = AuthorizeCorp::where('corpid', $item->corpid)->value('corp_name');
  2227. # 付费用户客单价 = 付费金额/付费人数
  2228. $item->charge_user_cost = $item->cust_pay_uc_total > 0 ? round($item->cust_pay_amount_total / $item->cust_pay_uc_total) : 0;
  2229. }
  2230. return $list;
  2231. }
  2232. /**
  2233. * 获取累计充值用户(去重)
  2234. * */
  2235. public static function chargeUserUnique($appId, $start, $end, $sysGroupId)
  2236. {
  2237. # 组装数据
  2238. if($appId) {
  2239. $mpAppIdList = array($appId);
  2240. } else {
  2241. $mpAppIdList = OfficialAccount::getSysGroupMpAppIdList($sysGroupId, 'StatisticsService.chargeUserUnique');
  2242. }
  2243. $accountData = array();
  2244. foreach ($mpAppIdList as $appId) {
  2245. $datum = [
  2246. 'app_id' => $appId,
  2247. 'start_date' => $start,
  2248. 'end_date' => $end
  2249. ];
  2250. array_push($accountData, $datum);
  2251. }
  2252. # 获取累计充值用户
  2253. return DjOrderService::getChargeUserTotalUnique($accountData);
  2254. }
  2255. public static function firstDayChargeUserUnique($appId, $start, $end, $sysGroupId)
  2256. {
  2257. # 组装数据
  2258. if($appId) {
  2259. $mpAppIdList = array($appId);
  2260. } else {
  2261. $mpAppIdList = OfficialAccount::getSysGroupMpAppIdList($sysGroupId, 'StatisticsService.chargeUserUnique');
  2262. }
  2263. $accountData = array();
  2264. foreach ($mpAppIdList as $appId) {
  2265. $datum = [
  2266. 'app_id' => $appId,
  2267. 'start_date' => $start,
  2268. 'end_date' => $end
  2269. ];
  2270. array_push($accountData, $datum);
  2271. }
  2272. # 获取累计充值用户
  2273. return DjOrder::getFirstDayChargeUserNum($accountData);
  2274. }
  2275. }