diff --git a/app/Admin/Controllers/Finance/StoreStatisticController.php b/app/Admin/Controllers/Finance/StoreStatisticController.php index d6ed2ad..94b46a0 100644 --- a/app/Admin/Controllers/Finance/StoreStatisticController.php +++ b/app/Admin/Controllers/Finance/StoreStatisticController.php @@ -3,20 +3,22 @@ namespace App\Admin\Controllers\Finance; use App\Admin\Controllers\AdminController; -use App\Admin\Filters\LedgerFilter; -use App\Admin\Filters\StoreFilter; -use App\Models\Ledger; -use App\Models\Store; -use Illuminate\Http\Request; -use Illuminate\Support\Facades\DB; +use App\Services\StatisticService; class StoreStatisticController extends AdminController { public function index() { if ($this->actionOfGetData()) { + $input = request()->input(); + + $sorts = [ + [request()->input('orderBy') ?: 'sales', request()->input('orderDir') ?: 'desc'], + ['id', 'asc'], + ]; + return $this->response()->success([ - 'items' => $this->getStoreStatistics(request()), + 'items' => (new StatisticService())->stores($input, $sorts), ]); } @@ -47,29 +49,4 @@ class StoreStatisticController extends AdminController ) ); } - - protected function getStoreStatistics(Request $request): array - { - /** @var \Illuminate\Database\Eloquent\Collection */ - $stats = Ledger::with(['store']) - ->select(['store_id', DB::raw('SUM(sales) as sales'), DB::raw('SUM(expenditure) as expenditure')]) - ->filter($request->input(), LedgerFilter::class) - ->groupBy('store_id') - ->get(); - - // 排序规则 - $sortBy = [ - [$request->input('orderBy') ?: 'sales', $request->input('orderDir') ?: 'desc'], - ]; - - return $stats->map(fn ($item) => [ - 'title' => $item->store->title, - 'sales' => trim_zeros($item->sales ?? '0'), - 'expenditure' => trim_zeros($item->expenditure ?? '0'), - ]) - ->sortBy($sortBy) - ->values() - ->map(fn ($item, $key) => array_merge($item, ['ranking' => $key + 1])) - ->all(); - } } diff --git a/app/Admin/Filters/LedgerFilter.php b/app/Admin/Filters/LedgerFilter.php index 4b51b74..8f34a74 100644 --- a/app/Admin/Filters/LedgerFilter.php +++ b/app/Admin/Filters/LedgerFilter.php @@ -44,4 +44,14 @@ class LedgerFilter extends ModelFilter $query->whereIn('check_status', explode(',', $checkStatus)); }); } + + public function startAt($startAt) + { + $this->where('date', '>=', $startAt); + } + + public function endAt($endAt) + { + $this->where('date', '<=', $endAt); + } } diff --git a/app/Http/Controllers/Api/StatisticsController.php b/app/Http/Controllers/Api/StatisticsController.php index f68da6e..2ab7562 100644 --- a/app/Http/Controllers/Api/StatisticsController.php +++ b/app/Http/Controllers/Api/StatisticsController.php @@ -3,13 +3,10 @@ namespace App\Http\Controllers\Api; use App\Admin\Filters\LedgerFilter; -use App\Admin\Filters\StoreFilter; -use App\Http\Resources\StoreResource; use App\Models\Ledger; -use App\Models\Store; +use App\Services\StatisticService; use Illuminate\Database\Eloquent\Collection; use Illuminate\Http\Request; -use Illuminate\Support\Arr; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\DB; @@ -73,7 +70,7 @@ class StatisticsController extends Controller /** * 门店统计 */ - public function stores(Request $request) + public function stores(Request $request, StatisticService $statisticService) { $request->validate( rules: [ @@ -86,22 +83,14 @@ class StatisticsController extends Controller ], ); - $storeLedgerStats = Ledger::select(['store_id', DB::raw('SUM(sales) as sales')]) - ->whereBetween('date', [$request->input('start_at'), $request->input('end_at')]) - ->groupBy('store_id'); + $input = array_merge( + $this->defaultFilterInput($request), + $request->only(['start_at', 'end_at']), + ); - $stores = Store::filter($this->defaultFilterInput($request), StoreFilter::class) - ->leftJoinSub($storeLedgerStats, 'store_ledger_stats', fn ($join) => $join->on('stores.id', '=', 'store_ledger_stats.store_id')) - ->orderBy('sales', 'desc') - ->orderBy('id', 'asc') - ->get(); + $sorts = [['sales', 'desc'], ['id', 'asc']]; - return $stores->map(function (Store $store) { - return [ - 'store' => StoreResource::make($store), - 'sales' => trim_zeros($store->sales ?: 0), - ]; - }); + return $statisticService->stores($input, $sorts); } /** diff --git a/app/Services/StatisticService.php b/app/Services/StatisticService.php new file mode 100644 index 0000000..734c7c3 --- /dev/null +++ b/app/Services/StatisticService.php @@ -0,0 +1,44 @@ +filter(Arr::only($input, ['date_range', 'start_at', 'end_at']), LedgerFilter::class) + ->groupBy('store_id'); + + $stores = Store::filter(Arr::only($input, ['store_id', 'region']), StoreFilter::class) + ->leftJoinSub($storeLedgerStats, 'store_ledger_stats', fn ($join) => $join->on('stores.id', '=', 'store_ledger_stats.store_id')) + ->when($sorts, function ($query, $sorts) { + foreach ($sorts as $sort) { + $query->orderBy($sort[0], $sort[1]); + } + }) + ->get(); + + return $stores->map(function (Store $store, $key) { + return [ + 'ranking' => $key + 1, + 'store' => [ + 'id' => $store->id, + 'title' => $store->title, + ], + 'sales' => trim_zeros($store->sales ?: 0), + 'expenditure' => trim_zeros($store->expenditure ?: 0), + ]; + })->all(); + } +}