ActivityService.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. <?php
  2. namespace App\Modules\Activity\Services;
  3. use App\Modules\Activity\Models\Activity;
  4. use App\Modules\Statistic\Services\WapVisitStatService;
  5. use App\Modules\Subscribe\Models\Order;
  6. use App\Modules\Trade\Services\OrderService;
  7. use DB;
  8. use Redis;
  9. class ActivityService
  10. {
  11. /**
  12. * 查询活动信息
  13. * @param array $params
  14. * @param bool $is_all
  15. * @return mixed
  16. */
  17. static function search($params = [], $is_all = false)
  18. {
  19. return Activity::search($params, $is_all);
  20. }
  21. /**
  22. * 查询活动id
  23. * @param array $params
  24. * @param bool $is_all
  25. * @return mixed
  26. */
  27. static function getActivityIds($params = [])
  28. {
  29. return Activity::getActivityIds($params);
  30. }
  31. /**
  32. * 查询活动的的充值信息
  33. * @param array $params
  34. * @param bool $is_all
  35. * @return mixed
  36. */
  37. static function getActivityRechargeInfo($params = [], $is_all = false)
  38. {
  39. return OrderService::search($params, $is_all);
  40. }
  41. /**
  42. * 更新活动控制开关
  43. * @param $activity_id
  44. * @param $params
  45. * @return mixed
  46. */
  47. static function updateShowSwitch($activity_id, $params)
  48. {
  49. return Activity::updateShowSwitch($activity_id, $params);
  50. }
  51. /**
  52. * 根据id获取
  53. * @param $id
  54. * @return mixed
  55. */
  56. static function getById($id)
  57. {
  58. return Activity::find($id);
  59. }
  60. /**
  61. * 根据token获取
  62. * @param $id
  63. * @return mixed
  64. */
  65. static function getByToken($token)
  66. {
  67. return Activity::where('token', $token)->first();
  68. }
  69. /**
  70. * 活动统计
  71. * @param $activity_id
  72. * @param $distribution_channel_id
  73. * @return array
  74. */
  75. static function getActivityUvPv($activity_id, $distribution_channel_id)
  76. {
  77. $activity = self::getById($activity_id);
  78. $uv_key_format = 'activity:%s:distribution_channel_id:%s:date:%s:uv';
  79. $pv_key_format = 'activity:%s:distribution_channel_id:%s:pv';
  80. $start = strtotime($activity->start_time);
  81. $end_time = strtotime($activity->end_time);
  82. $end = time() > $end_time ? $end_time : time();
  83. $page_pv = 0;
  84. $page_uv = 0;
  85. $visit_info = WapVisitStatService::getActivityUvAndPv($distribution_channel_id, $activity_id);
  86. $page_pv = $visit_info['pv'];
  87. $page_uv = $visit_info['uv'];
  88. /*while ($start<$end){
  89. $temp_day = date('Y-m-d',$start);
  90. $uv_key = sprintf($uv_key_format, $activity_id, $distribution_channel_id,$temp_day);
  91. $puv = Redis::scard($uv_key);
  92. if($puv) $page_uv += $puv;
  93. $start += 86400;
  94. }
  95. $pv_key = sprintf($pv_key_format, $activity_id, $distribution_channel_id);
  96. $pv_all = Redis::hgetAll($pv_key);
  97. if($pv_all){
  98. foreach ($pv_all as $v){
  99. $page_pv += $v;
  100. }
  101. }*/
  102. $button_pv = Order::where('activity_id', $activity_id)->where('distribution_channel_id', $distribution_channel_id)->count();
  103. $button_uv = DB::select('select ifnull(count(distinct uid),0) as count from orders where activity_id=' . $activity_id . ' and distribution_channel_id=' . $distribution_channel_id);
  104. $button_uv = $button_uv[0]->count;
  105. $order_num = Order::where('activity_id', $activity_id)->where('status', 'PAID')->where('distribution_channel_id', $distribution_channel_id)->count();
  106. $order_sum = Order::where('activity_id', $activity_id)->where('status', 'PAID')->where('distribution_channel_id', $distribution_channel_id)->sum('price');
  107. $sql = 'select ifnull(count(*),0) as count from orders a where activity_id=' . $activity_id . ' and status="PAID" and distribution_channel_id= ' . $distribution_channel_id . ' and EXISTS (select uid from orders b where created_at <="' . $activity->start_time . '" and b.uid=a.uid)';
  108. $re_order_info = DB::select($sql);
  109. $re_order = $re_order_info[0]->count;
  110. return compact('page_pv', 'page_uv', 'button_pv', 'button_uv', 'order_num', 're_order', 'order_sum');
  111. }
  112. static function ActivityStats($activity_id)
  113. {
  114. $sql = "select a.*,b.price,b.order_num as success_order from(
  115. select date(created_at) as `date`,distribution_channel_id,count(*) as order_num,count(DISTINCT uid) as uv
  116. from orders
  117. where activity_id={$activity_id} GROUP by date(created_at),distribution_channel_id
  118. ) a
  119. left join (
  120. select date(created_at) as `date`,distribution_channel_id,sum(price) as price,count(*) as order_num
  121. from orders
  122. where activity_id={$activity_id} and `status`='PAID' GROUP by date(created_at),distribution_channel_id
  123. ) b on a.`date`=b.`date` and a.distribution_channel_id=b.distribution_channel_id";
  124. $res = DB::select($sql);
  125. $activity = self::getById($activity_id);
  126. $data = [];
  127. $uv_key_format = 'activity:%s:distribution_channel_id:%s:date:%s:uv';
  128. foreach ($res as $v) {
  129. $temp = [];
  130. $temp['date'] = $v->date;
  131. $temp['distribution_channel_id'] = $v->distribution_channel_id;
  132. $temp['button_pv'] = $v->order_num;
  133. $temp['order_num'] = $v->success_order ? $v->success_order : 0;
  134. $sql1 = 'select ifnull(count(*),0) as count from orders a where activity_id=' . $activity_id . ' and status="PAID" and date(created_at)="' . $v->date . '" and distribution_channel_id= ' . $v->distribution_channel_id . ' and not EXISTS (select uid from orders b where created_at <="' . $activity->start_time . '" and b.uid=a.uid)';
  135. $sql2 = 'select ifnull(count(*),0) as count from orders a where activity_id=' . $activity_id . ' and status="PAID" and from_type="reader" and date(created_at)="' . $v->date . '" and distribution_channel_id= ' . $v->distribution_channel_id . ' and not EXISTS (select uid from orders b where created_at <="' . $activity->start_time . '" and b.uid=a.uid)';
  136. $re_order_info = DB::select($sql1);
  137. $re_order_info2 = DB::select($sql2);
  138. $temp['first_charge'] = $re_order_info[0]->count ? $re_order_info[0]->count : 0;
  139. $temp['first_charge_reader'] = $re_order_info2[0]->count ? $re_order_info2[0]->count : 0;
  140. $temp['button_uv'] = $v->uv;
  141. $uv_key = sprintf($uv_key_format, $activity_id, $v->distribution_channel_id, $v->date);
  142. $puv = Redis::scard($uv_key);
  143. $puv = $puv ? $puv : 0;
  144. $temp['page_uv'] = $puv;
  145. $from = 'reader';
  146. $reader_uv = Redis::scard('push:distribution_channel_id:' . $v->distribution_channel_id . 'from:' . $from . ':date:' . $v->date);
  147. $temp['reader_uv'] = $reader_uv ? $reader_uv : 0;
  148. $data[] = $temp;
  149. }
  150. $sql3 = "select a.*,b.price,b.order_num as success_order from(
  151. select date(created_at) as `date`,distribution_channel_id,count(*) as order_num,count(DISTINCT uid) as uv
  152. from orders
  153. where activity_id=$activity_id and from_type='reader' GROUP by date(created_at),distribution_channel_id
  154. ) a
  155. left join (
  156. select date(created_at) as `date`,distribution_channel_id,sum(price) as price,count(*) as order_num
  157. from orders
  158. where activity_id=$activity_id and `status`='PAID' and from_type='reader' GROUP by date(created_at),distribution_channel_id
  159. ) b on a.`date`=b.`date` and a.distribution_channel_id=b.distribution_channel_id";
  160. $res2 = DB::select($sql3);
  161. foreach ($data as &$v) {
  162. $v['reader_order_num'] = 0;
  163. $v['reader_order_success_num'] = 0;
  164. foreach ($res2 as $val) {
  165. if ($v['date'] == $val->date && $val->distribution_channel_id == $v['distribution_channel_id']) {
  166. $v['reader_order_num'] = $val->order_num ? $val->order_num : 0;
  167. $v['reader_order_success_num'] = $val->success_order ? $val->success_order : 0;
  168. }
  169. }
  170. }
  171. return $data;
  172. }
  173. public static function createActivity(array $param)
  174. {
  175. return Activity::create($param);
  176. }
  177. public static function getActivitySetting()
  178. {
  179. $activity_settng_key = 'activity:setting';
  180. $res = Redis::get($activity_settng_key);
  181. if ($res) {
  182. return json_decode($res, 1);
  183. }
  184. return null;
  185. }
  186. static function ActivityStatsI(int $activity_id): array
  187. {
  188. $activity_info = self::getById($activity_id);
  189. $sql_format = "select
  190. distribution_channel_id,date(created_at) as `day`,COUNT(*) as order_num,
  191. count(case when `status`='PAID' then `status` else null end) as success,
  192. GROUP_CONCAT(case when `status`='PAID' and `from_type`='reader' then uid else null end) as reader_uids,
  193. GROUP_CONCAT(case when `status`='PAID' and `from_type`='signcallback' then uid else null end) as signcallback_uids,
  194. sum(case when `status`='PAID' then `price` else null end) as sums,
  195. count(case when `from_type`='reader' then `uid` else null end) as reader_order,
  196. count(DISTINCT uid) as button_uv,
  197. count(case when `from_type`='reader' and `status`='PAID' then `uid` else null end) as reader_success_order,
  198. count(case when `from_type`='signcallback' then `uid` else null end) as signcallback_order,
  199. count(case when `from_type`='signcallback' and `status`='PAID' then `uid` else null end) as signcallback_success_order
  200. from orders where activity_id=%s
  201. and created_at BETWEEN '%s' and '%s'
  202. GROUP by distribution_channel_id,date(created_at)";
  203. $sql = sprintf($sql_format, $activity_id, $activity_info->start_time, $activity_info->end_time);
  204. $res = DB::select($sql);
  205. $data = [];
  206. foreach ($res as $v) {
  207. $temp['day'] = $v->day;
  208. $temp['siteid'] = $v->distribution_channel_id;
  209. $temp['button_uv'] = $v->button_uv;
  210. $temp['order_num'] = $v->order_num;
  211. $temp['success_order_num'] = $v->success;
  212. $temp['reader_order'] = $v->reader_order;
  213. $temp['reader_success_order'] = $v->reader_success_order;
  214. $temp['signcallback_order'] = $v->signcallback_order;
  215. $temp['signcallback_success_order'] = $v->signcallback_success_order;
  216. $sql1 = 'select ifnull(count(DISTINCT uid),0) as `count` from orders a where activity_id=' . $activity_id . ' and status="PAID" and date(created_at)="' . $v->day . '" and distribution_channel_id= ' . $v->distribution_channel_id . ' and not EXISTS (select uid from orders b where created_at <="' . $activity_info->start_time . '" and b.uid=a.uid and b.status="PAID")';
  217. $res1 = DB::select($sql1);
  218. $temp['first_charge_num'] = $res1[0]->count;
  219. $reader_uv_pv_info = WapVisitStatService::getSitePvAndUvOneDay($v->distribution_channel_id, 'reader', $v->day);
  220. $signcallback_uv_pv_info = WapVisitStatService::getSitePvAndUvOneDay($v->distribution_channel_id, 'signcallback', $v->day);
  221. $pv_uv_info = WapVisitStatService::getActivityUvAndPvByDay($v->distribution_channel_id, $activity_id, $v->day);
  222. $temp['uv'] = $pv_uv_info['uv'];
  223. $temp['reader_uv'] = $reader_uv_pv_info['uv'];
  224. $temp['signcallback_uv'] = $signcallback_uv_pv_info['uv'];
  225. $sq2 = "select count(distinct uid) as `count` from orders WHERE uid in (%s) and created_at<='%s' ";
  226. if ($v->reader_uids) {
  227. $v->reader_uids = rtrim($v->reader_uids, ',');
  228. $temp_reader_second = DB::select(sprintf($sq2, $v->reader_uids, $activity_info->start_time));
  229. $temp['reader_first_charge'] = $v->reader_success_order - (int)$temp_reader_second[0]->count;
  230. } else {
  231. $temp['reader_first_charge'] = 0;
  232. }
  233. if ($v->signcallback_uids) {
  234. $v->signcallback_uids = rtrim($v->signcallback_uids, ',');
  235. $temp_reader_second = DB::select(sprintf($sq2, $v->signcallback_uids, $activity_info->start_time));
  236. $temp['signcallback_first_charge'] = $v->signcallback_success_order - (int)$temp_reader_second[0]->count;
  237. } else {
  238. $temp['signcallback_first_charge'] = 0;
  239. }
  240. $data[] = $temp;
  241. }
  242. return $data;
  243. }
  244. static function yearActivityStats(int $activity_id): array
  245. {
  246. $activity_info = self::getById($activity_id);
  247. $sql_format = "select
  248. distribution_channel_id,date(created_at) as `day`,COUNT(*) as order_num,
  249. count(case when `status`='PAID' then `status` else null end) as success,
  250. GROUP_CONCAT(case when `status`='PAID' then uid else null end) as uids,
  251. sum(case when `status`='PAID' then `price` else null end) as sums,
  252. price from orders where activity_id=%s
  253. and
  254. created_at BETWEEN '%s' and '%s'
  255. GROUP by distribution_channel_id,date(created_at),price";
  256. $sql = sprintf($sql_format, $activity_id, $activity_info->start_time, $activity_info->end_time);
  257. $res = DB::select($sql);
  258. $data = [];
  259. foreach ($res as $v) {
  260. $temp['siteid'] = $v->distribution_channel_id;
  261. $temp['day'] = $v->day;
  262. $temp['price'] = $v->price;
  263. $temp['order_num'] = $v->order_num;
  264. $temp['success'] = $v->success;
  265. $temp['uv'] = 0;
  266. $second_sql_fromat = "SELECT COUNT(DISTINCT uid) as counts FROM orders WHERE uid in (%s) and `status` = 'PAID' and created_at<='%s'";
  267. if ($v->uids) {
  268. $v->uids = rtrim($v->uids, ',');
  269. $second_sql = sprintf($second_sql_fromat, $v->uids, $activity_info->start_time);
  270. $temp_res = DB::select($second_sql);
  271. $temp['first_charge'] = $v->success - (int)$temp_res[0]->counts;
  272. } else {
  273. $temp['first_charge'] = $v->success;
  274. }
  275. $pv_uv_info = WapVisitStatService::getActivityUvAndPvByDay($v->distribution_channel_id, $activity_id, $v->day);
  276. $temp['sums'] = $v->sums;
  277. $temp['uv'] = $pv_uv_info['uv'];
  278. $data[] = $temp;
  279. $temp = null;
  280. }
  281. return $data;
  282. }
  283. public static function selectNowActiveActivity($distribution_channel_id){
  284. return Activity::where('start_time','<=',date('Y-m-d H:i:s'))
  285. ->where('end_time','>=',date('Y-m-d H:i:s'))
  286. ->where(function ($query) use ($distribution_channel_id){
  287. $query->where('distribution_channel_id',$distribution_channel_id)
  288. ->orWhere(function ($q)use($distribution_channel_id){
  289. if(isInnerSites($distribution_channel_id)){
  290. $q->whereIn('create_type',[1,2]);
  291. } else{
  292. $q->whereIn('create_type',[1,3]);
  293. }
  294. });
  295. })
  296. ->orderBy('priority','desc')
  297. ->orderBy('id','desc')
  298. ->select('id','name','customer_msg','create_type','setting','activity_page')
  299. ->first();
  300. }
  301. public static function selectNowActiveActivityV3($distribution_channel_id)
  302. {
  303. //1,管理后台单个站点
  304. if (isInnerSites($distribution_channel_id)) {
  305. $distribution_channel_ids = [-1,-2,$distribution_channel_id];
  306. } else {
  307. $distribution_channel_ids = [-1,-3,$distribution_channel_id];
  308. }
  309. $result = Activity::where('start_time', '<=', date('Y-m-d H:i:s'))
  310. ->where('end_time', '>=', date('Y-m-d H:i:s'))->whereIn('distribution_channel_id', $distribution_channel_ids)
  311. ->select('id', 'name', 'customer_msg', 'create_type', 'setting', 'activity_page')
  312. ->orderBy('priority', 'desc')
  313. ->first();
  314. return $result;
  315. }
  316. }