|
@@ -0,0 +1,160 @@
|
|
|
|
+<?php
|
|
|
|
+
|
|
|
|
+namespace General\Services\Activity;
|
|
|
|
+
|
|
|
|
+use General\Helpers\CommonHelper;
|
|
|
|
+use General\Models\Activity\Activity;
|
|
|
|
+use General\Models\Order\Order;
|
|
|
|
+use General\Models\Order\Product;
|
|
|
|
+use Illuminate\Support\Facades\DB;
|
|
|
|
+use Redis;
|
|
|
|
+
|
|
|
|
+class ActivityService
|
|
|
|
+{
|
|
|
|
+ public function getCommonActivitiesWithStats(int $channel_id, $is_all = false)
|
|
|
|
+ {
|
|
|
|
+ $search_obj = Activity::leftjoin('activity_statistic', function ($join) use ($channel_id) {
|
|
|
|
+ $join->on('activity.id', '=', 'activity_statistic.activity_id')
|
|
|
|
+ ->where('activity_statistic.distribution_channel_id', '=', $channel_id);
|
|
|
|
+ })
|
|
|
|
+ ->select([
|
|
|
|
+ 'activity.id', 'activity.name', 'activity.created_at', 'activity.start_time', 'activity.price_title',
|
|
|
|
+ 'activity.end_time', 'activity.activity_page',
|
|
|
|
+ 'activity_statistic.success_order_num', 'activity_statistic.recharge_amount',
|
|
|
|
+ 'activity_statistic.order_num', 'activity_statistic.pv', 'promotion_stats_created', 'merchants_stats_created'
|
|
|
|
+ ])
|
|
|
|
+ ->where('token', '!=', '')->orderBy('activity.created_at', 'desc');
|
|
|
|
+ $is_inner = CommonHelper::isInnerSites($channel_id);
|
|
|
|
+ $create_types = $is_inner ? [1, 2] : [1, 3];
|
|
|
|
+ $search_obj->where(function ($query) use ($channel_id, $create_types) {
|
|
|
|
+ $query->whereIn('create_type', $create_types)
|
|
|
|
+ ->orWhere(function ($q) use ($channel_id) {
|
|
|
|
+ $q->Where('create_type', 4)->where('activity.distribution_channel_id', $channel_id);
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ if ($is_all) {
|
|
|
|
+ $activities = $search_obj->get();
|
|
|
|
+ } else {
|
|
|
|
+ $activities = $search_obj->paginate();
|
|
|
|
+ }
|
|
|
|
+ foreach ($activities as &$item) {
|
|
|
|
+ if ($item->promotion_stats_created || $item->merchants_stats_created) {
|
|
|
|
+ $item->totalChargeAmount = $item->recharge_amount ? $item->recharge_amount : 0;
|
|
|
|
+ $item->orderCount = $item->success_order_num ? $item->success_order_num : 0;
|
|
|
|
+ } else {
|
|
|
|
+ $order_info = Order::select(DB::raw('count(*) as order_count,sum(price) as total_charge_amount'))
|
|
|
|
+ ->where([
|
|
|
|
+ ['activity_id', '=', $item->id],
|
|
|
|
+ ['status', '=', 'PAID'],
|
|
|
|
+ ['distribution_channel_id', '=', $channel_id],
|
|
|
|
+ ['created_at', '>=', $item->start_time]
|
|
|
|
+ ])->first();
|
|
|
|
+ $item->totalChargeAmount = $order_info ? $order_info->total_charge_amount : 0;
|
|
|
|
+ $item->orderCount = $order_info ? $order_info->order_count : 0;
|
|
|
|
+ }
|
|
|
|
+ if ($item->price_title) {
|
|
|
|
+ $item->price = $item->price_title;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return $activities;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public function getChannelActivitiesWithStats(int $channel_id, $is_all = false)
|
|
|
|
+ {
|
|
|
|
+ $search_obj = Activity::leftjoin('activity_statistic', function ($join) use ($channel_id) {
|
|
|
|
+ $join->on('activity.id', '=', 'activity_statistic.activity_id');
|
|
|
|
+ $join->where('activity_statistic.distribution_channel_id', '=', $channel_id);
|
|
|
|
+ })
|
|
|
|
+ ->select([
|
|
|
|
+ 'activity.id', 'activity.name', 'activity.created_at', 'activity.start_time', 'activity.price_title',
|
|
|
|
+ 'activity.end_time', 'activity.activity_page', 'activity.setting',
|
|
|
|
+ 'activity_statistic.success_order_num', 'activity_statistic.recharge_amount',
|
|
|
|
+ 'activity_statistic.order_num', 'activity_statistic.pv', 'promotion_stats_created', 'merchants_stats_created'
|
|
|
|
+ ])->whereIn('create_type', [0, 5])->where('activity.distribution_channel_id', $channel_id);
|
|
|
|
+ if ($is_all) {
|
|
|
|
+ $activities = $search_obj->get();
|
|
|
|
+ } else {
|
|
|
|
+ $activities = $search_obj->paginate();
|
|
|
|
+ }
|
|
|
|
+ foreach ($activities as &$item) {
|
|
|
|
+ if ($item->merchants_stats_created) {
|
|
|
|
+ $item->totalChargeAmount = $item->recharge_amount;
|
|
|
|
+ $item->orderCount = $item->order_num;
|
|
|
|
+ $item->successOrderCount = $item->success_order_num;
|
|
|
|
+ $item->pageUserNum = $item->pv;
|
|
|
|
+ } else {
|
|
|
|
+ $stats = $this->getActivityUvPv($item->id, $channel_id);
|
|
|
|
+ $item->totalChargeAmount = $stats['order_sum'];
|
|
|
|
+ $item->orderCount = $stats['button_pv'];
|
|
|
|
+ $item->successOrderCount = $stats['order_num'];
|
|
|
|
+ $item->pageUserNum = $stats['page_uv'];
|
|
|
|
+ }
|
|
|
|
+ //价格
|
|
|
|
+ $activity_setting = $item->setting;
|
|
|
|
+ if ($activity_setting) {
|
|
|
|
+ $activity_setting_list = json_decode($activity_setting, true);
|
|
|
|
+ if (isset($activity_setting_list['product_info']) && count($activity_setting_list['product_info']) > 1) {
|
|
|
|
+ $second_product_id = $activity_setting_list['product_info'][1]['product_id'];
|
|
|
|
+ $second_price_info = Product::find($second_product_id);
|
|
|
|
+ $item->price = sprintf('%s、 %s', $item->product->price, $second_price_info->price);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ $item->successrate = '0%';
|
|
|
|
+ if ($item->orderCount) {
|
|
|
|
+ $item->successrate = (string)round(($item->successOrderCount / (int)($item->orderCount)) * 100, 4) . '%';
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return $activities;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 活动统计
|
|
|
|
+ * @param $activity_id
|
|
|
|
+ * @param $channel_id
|
|
|
|
+ * @return array
|
|
|
|
+ */
|
|
|
|
+ public function getActivityUvPv($activity_id, $channel_id)
|
|
|
|
+ {
|
|
|
|
+ $activity = Activity::find($activity_id);
|
|
|
|
+
|
|
|
|
+ $uv_key_format = 'activity:%s:distribution_channel_id:%s:date:%s:uv';
|
|
|
|
+ $pv_key_format = 'activity:%s:distribution_channel_id:%s:pv';
|
|
|
|
+
|
|
|
|
+ $start = strtotime($activity->start_time);
|
|
|
|
+ $end_time = strtotime($activity->end_time);
|
|
|
|
+ $end = time() > $end_time ? $end_time : time();
|
|
|
|
+ $page_pv = 0;
|
|
|
|
+ $page_uv = 0;
|
|
|
|
+ $visit_info = $this->getActivityUvAndPv($channel_id, $activity_id);
|
|
|
|
+ $page_pv = $visit_info['pv'];
|
|
|
|
+ $page_uv = $visit_info['uv'];
|
|
|
|
+ $order_info = Order::select(DB::raw("count(distinct uid) as user_num,count(1) as order_num"))->where('activity_id', $activity_id)->where('created_at', '>=', $activity->start_time)->where('distribution_channel_id', $channel_id)->first();
|
|
|
|
+ $button_uv = (int)$order_info->user_num;
|
|
|
|
+ $button_pv = (int)$order_info->order_num;
|
|
|
|
+ $paid_info = Order::select(DB::raw("sum(price) as recharge_amount,count(1) as order_num"))->where('activity_id', $activity_id)->where('status', 'PAID')->where('created_at', '>=', $activity->start_time)->where('distribution_channel_id', $channel_id)->first();
|
|
|
|
+ $order_num = (int)$paid_info->order_num;
|
|
|
|
+ $order_sum = (float)$paid_info->recharge_amount;
|
|
|
|
+ return compact('page_pv', 'page_uv', 'button_pv', 'button_uv', 'order_num', 'order_sum');
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 获取活动的pv uv
|
|
|
|
+ * @param int $channel_id
|
|
|
|
+ * @param int $activity_id
|
|
|
|
+ * @return array
|
|
|
|
+ */
|
|
|
|
+ public function getActivityUvAndPv(int $channel_id, int $activity_id): array
|
|
|
|
+ {
|
|
|
|
+ $day = date('Y-m-d');
|
|
|
|
+ $uv_key_format = 'activity:%s:distribution_channel_id:%s:date:%s:uv';
|
|
|
|
+ $pv_key_format = 'activity:%s:distribution_channel_id:%s:pv';
|
|
|
|
+ $sql_format = "select sum(pv) as pv,sum(uv) as uv from wap_visit_stats WHERE `key`=%s and from_type='%s' and `day` >= '2018-01-10' and type=2 ";
|
|
|
|
+ $sql = sprintf($sql_format, $channel_id, $activity_id);
|
|
|
|
+ $res = DB::select($sql);
|
|
|
|
+ $today_pv = (int)Redis::hget(sprintf($pv_key_format, $activity_id, $channel_id), $day);
|
|
|
|
+ $today_uv = (int)Redis::scard(sprintf($uv_key_format, $activity_id, $channel_id, $day));
|
|
|
|
+ $uv = $res[0]->uv + $today_uv;
|
|
|
|
+ $pv = $res[0]->pv + $today_pv;
|
|
|
|
+ return compact('uv', 'pv');
|
|
|
|
+ }
|
|
|
|
+}
|