getTable(); $inviteUsersCounts = UserInfo::select([ 'inviter_id', DB::raw('count(1) as invite_users_count') ]) ->when($start || $end, function ($builder) use ($start, $end) { if ($start && $end) { return $builder->whereBetween('created_at', [$start, $end]); } return $builder->when($start, fn ($builder) => $builder->where('created_at', '>=', $start)) ->when($end, fn ($builder) => $builder->where('created_at', '<=', $end)); }) ->groupBy('inviter_id'); // 线上订单业绩 $onlineOrderPerformances = Order::select([ 'inviter_id', DB::raw('COUNT(1) AS orders_count'), DB::raw('SUM(point_discount_amount) AS points_deduction_amount'), DB::raw('SUM(total_amount) AS payment_amount'), DB::raw('SUM(profit) AS profit'), ]) ->whereIn('status', [ Order::STATUS_PAID, Order::STATUS_COMPLETED, ]) ->when($start || $end, function ($builder) use ($start, $end) { if ($start && $end) { return $builder->whereBetween('created_at', [$start, $end]); } return $builder->when($start, fn ($builder) => $builder->where('created_at', '>=', $start)) ->when($end, fn ($builder) => $builder->where('created_at', '<=', $end)); }) ->groupBy('inviter_id'); // 线下订单业绩 $offlineOrderPerformances = OfflineOrder::select([ 'staff_id', DB::raw('COUNT(1) AS orders_count'), DB::raw('SUM(points_deduction_amount) AS points_deduction_amount'), DB::raw('SUM(payment_amount) AS payment_amount'), ]) ->where('status', OfflineOrderStatus::Paid) ->when($start || $end, function ($builder) use ($start, $end) { if ($start && $end) { return $builder->whereBetween('created_at', [$start, $end]); } return $builder->when($start, fn ($builder) => $builder->where('created_at', '>=', $start)) ->when($end, fn ($builder) => $builder->where('created_at', '<=', $end)); }) ->groupBy('staff_id'); $builder = UserInfo::with(['user']) ->leftJoinSub($inviteUsersCounts, 'invite_users_counts', fn ($join) => $join->on("{$infoTable}.user_id", '=', 'invite_users_counts.inviter_id')) ->leftJoinSub($onlineOrderPerformances, 'online_performances', fn ($join) => $join->on("{$infoTable}.user_id", '=', 'online_performances.inviter_id')) ->leftJoinSub($offlineOrderPerformances, 'offline_performances', fn ($join) => $join->on("{$infoTable}.user_id", '=', 'offline_performances.staff_id')) ->select([ 'user_id', 'nickname', 'avatar', 'invite_users_count', // 线上订单 DB::raw('online_performances.orders_count AS online_orders_count'), DB::raw('online_performances.points_deduction_amount AS online_points_deduction_amount'), DB::raw('online_performances.payment_amount AS online_payment_amount'), DB::raw('online_performances.profit AS online_profit'), // 线下订单 DB::raw('offline_performances.orders_count AS offline_orders_count'), DB::raw('offline_performances.points_deduction_amount AS offline_points_deduction_amount'), DB::raw('offline_performances.payment_amount AS offline_payment_amount'), ]) ->where('is_company', true); $grid = new Grid($builder); $grid->model()->orderBy('user_id', 'desc'); $grid->combine('online_order', [ 'online_orders_count', 'online_total_amount', 'online_points_deduction_amount', 'online_payment_amount', 'online_profit', ]); $grid->combine('offline_order', [ 'offline_orders_count', 'offline_total_amount', 'offline_points_deduction_amount', 'offline_payment_amount', ]); $grid->column('user_id', 'ID'); $grid->column('phone')->display(fn () => $this->user?->phone)->copyable(); $grid->column('nickname'); $grid->column('invite_users_count')->display(fn ($v) => (int) $v); // 线上订单业绩 $grid->column('online_orders_count')->display(fn ($v) => (int) $v); $grid->column('online_total_amount')->display(fn () => bcdiv($this->online_points_deduction_amount + $this->online_payment_amount, 100, 2)); $grid->column('online_points_deduction_amount')->display(fn ($v) => bcdiv($v, 100, 2)); $grid->column('online_payment_amount')->display(fn ($v) => bcdiv($v, 100, 2)); $grid->column('online_profit')->display(fn ($v) => $v ?? '0.00'); // 线下订单业绩 $grid->column('offline_orders_count')->display(fn ($v) => (int) $v); $grid->column('offline_total_amount')->display(fn () => bcdiv($this->offline_points_deduction_amount + $this->offline_payment_amount, 100, 2)); $grid->column('offline_points_deduction_amount')->display(fn ($v) => bcdiv($v, 100, 2)); $grid->column('offline_payment_amount')->display(fn ($v) => bcdiv($v, 100, 2)); $grid->disableRefreshButton(); $grid->disableFilterButton(); $grid->disableActions(); $grid->filter(function (Grid\Filter $filter) { $filter->panel(); $filter->like('user.phone', '手机号')->width(3); $filter->between('datetime')->datetime()->ignore()->width(4); }); $grid->footer(function ($collection) use ($grid, $infoTable, $onlineOrderPerformances, $offlineOrderPerformances) { // 线上订单 $onlineQuery = UserInfo::query() ->leftJoinSub($onlineOrderPerformances, 'online_performances', fn ($join) => $join->on("{$infoTable}.user_id", '=', 'online_performances.inviter_id')) ->select([ DB::raw('SUM(online_performances.orders_count) AS orders_count'), DB::raw('SUM(online_performances.points_deduction_amount) AS points_deduction_amount'), DB::raw('SUM(online_performances.payment_amount) AS payment_amount'), DB::raw('SUM(online_performances.profit) AS profit'), ]) ->where('is_company', true); // 线下订单 $offlineQuery = UserInfo::query() ->leftJoinSub($offlineOrderPerformances, 'offline_performances', fn ($join) => $join->on("{$infoTable}.user_id", '=', 'offline_performances.staff_id')) ->select([ // 线下订单 DB::raw('SUM(offline_performances.orders_count) AS orders_count'), DB::raw('SUM(offline_performances.points_deduction_amount) AS points_deduction_amount'), DB::raw('SUM(offline_performances.payment_amount) AS payment_amount'), ]) ->where('is_company', true); $grid->model()->getQueries()->unique()->each(function ($value) use (&$onlineQuery, &$offlineQuery) { if (in_array($value['method'], ['paginate', 'get', 'orderBy', 'orderByDesc'], true)) { return; } $onlineQuery = call_user_func_array([$onlineQuery, $value['method']], $value['arguments'] ?? []); $offlineQuery = call_user_func_array([$offlineQuery, $value['method']], $value['arguments'] ?? []); }); $onlineResults = $onlineQuery->first(); $onlineOrdersCount = $onlineResults['orders_count'] ?? 0; $onlinePointsDeductionAmount = bcdiv($onlineResults['points_deduction_amount'] ?? 0, 100, 2); $onlinePaymentAmount = bcdiv($onlineResults['payment_amount'] ?? 0, 100, 2); $onlineTotalAmount = bcadd($onlinePointsDeductionAmount, $onlinePaymentAmount, 2); $onlineProfit = $onlineResults['profit'] ?? 0; $offlineResults = $offlineQuery->first(); $offlineOrdersCount = $offlineResults['orders_count'] ?? 0; $offlinePointsDeductionAmount = bcdiv($offlineResults['points_deduction_amount'] ?? 0, 100, 2); $offlinePaymentAmount = bcdiv($offlineResults['payment_amount'] ?? 0, 100, 2); $offlineTotalAmount = bcadd($offlinePointsDeductionAmount, $offlinePaymentAmount, 2); return <<