From 18e8b386f2c2d302296cccdab10b85c8278d2299 Mon Sep 17 00:00:00 2001 From: Jing Li Date: Fri, 29 Mar 2024 12:39:22 +0800 Subject: [PATCH] =?UTF-8?q?=E9=97=A8=E5=BA=97=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Finance/StoreStatisticController.php | 86 +++++++++++++++++++ app/Admin/Filters/LedgerFilter.php | 26 +++++- app/Admin/routes.php | 3 + database/seeders/AdminPermissionSeeder.php | 9 ++ 4 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 app/Admin/Controllers/Finance/StoreStatisticController.php diff --git a/app/Admin/Controllers/Finance/StoreStatisticController.php b/app/Admin/Controllers/Finance/StoreStatisticController.php new file mode 100644 index 0000000..9861b0e --- /dev/null +++ b/app/Admin/Controllers/Finance/StoreStatisticController.php @@ -0,0 +1,86 @@ +actionOfGetData()) { + return $this->response()->success([ + 'items' => $this->getStoreStatistics(request()), + ]); + } + + return $this->response()->success( + $this->baseList( + $this->baseCRUD() + ->headerToolbar([ + amis('filter-toggler')->align('right'), + ]) + ->footerToolbar([]) + ->bulkActions([]) + ->filter($this->baseFilter()->body([ + amis()->GroupControl()->mode('horizontal')->body([ + amis()->DateRangeControl('date_range', '日期') + ->valueFormat('YYYY-MM-DD') + ->columnRatio(6), + amis()->InputCityControl('region', '区域') + ->allowDistrict(false) + ->extractValue(false), + ]), + ])) + ->columns([ + amis()->TableColumn('ranking', '排序'), + amis()->TableColumn('title', '门店'), + amis()->TableColumn('sales', '收入')->sortable(), + amis()->TableColumn('expenditure', '支出')->sortable(), + ]) + ) + ); + } + + protected function getStoreStatistics(Request $request): array + { + $stores = Store::filter($request->only(['region']), StoreFilter::class) + ->get(['id', 'title']); + + /** @var \Illuminate\Database\Eloquent\Collection */ + $statistics = Ledger::select([ + 'store_id', + DB::raw('SUM(sales) as sales'), + DB::raw('SUM(expenditure) as expenditure'), + ]) + ->filter($request->input(), LedgerItemFilter::class) + ->groupBy('store_id') + ->get() + ->keyBy('store_id'); + + // 排序规则 + $sortBy = [ + [$request->input('orderBy') ?: 'sales', $request->input('orderDir') ?: 'desc'], + ]; + + return $stores->map(function ($store) use ($statistics) { + $statistic = $statistics->get($store->id); + return [ + 'title' => $store->title, + 'sales' => trim_zeros($statistic->sales ?? '0'), + 'expenditure' => trim_zeros($statistic->expenditure ?? '0'), + ]; + }) + ->sortBy($sortBy) + ->values() + ->map(fn ($statistic, $key) => array_merge($statistic, ['ranking' => $key + 1])) + ->all(); + } +} diff --git a/app/Admin/Filters/LedgerFilter.php b/app/Admin/Filters/LedgerFilter.php index e17881b..5a80b70 100644 --- a/app/Admin/Filters/LedgerFilter.php +++ b/app/Admin/Filters/LedgerFilter.php @@ -3,21 +3,41 @@ namespace App\Admin\Filters; use EloquentFilter\ModelFilter; +use Illuminate\Support\Arr; class LedgerFilter extends ModelFilter { public function store($id) { - $this->query->where('store_id', $id); + $this->where('store_id', $id); } public function dateRange($dateRange) { - $this->query->whereBetween('date', explode(',', $dateRange)); + $this->whereBetween('date', explode(',', $dateRange)); } public function status($status) { - $this->query->whereIn('ledger_status', explode(',', $status)); + $this->whereIn('ledger_status', explode(',', $status)); + } + + public function region($region) + { + if (! is_array($region)) { + return; + } + + $provinceCode = Arr::get($region, 'provinceCode'); + $cityCode = Arr::get($region, 'cityCode'); + + if (empty($provinceCode) && empty($cityCode)) { + return; + } + + $this->related('store', function($query) use ($provinceCode, $cityCode) { + $query->when($provinceCode, fn ($query) => $query->where('region->provinceCode', $provinceCode)) + ->when($cityCode, fn ($query) => $query->where('region->cityCode', $cityCode)); + }); } } diff --git a/app/Admin/routes.php b/app/Admin/routes.php index c59dd6b..7c0b993 100644 --- a/app/Admin/routes.php +++ b/app/Admin/routes.php @@ -3,6 +3,7 @@ use App\Admin\Controllers\BaseKeywordController; use App\Admin\Controllers\Finance\LedgerController; use App\Admin\Controllers\Finance\SalesStatisticController; +use App\Admin\Controllers\Finance\StoreStatisticController; use App\Admin\Controllers\Hr\EmployeeController; use App\Admin\Controllers\Hr\RestController; use App\Admin\Controllers\Hr\SignController; @@ -88,6 +89,8 @@ Route::group([ $router->post('ledgers/{ledger}/approval', [LedgerController::class, 'approval'])->name('ledgers.approval'); // 销售统计 $router->get('sales-statistics', [SalesStatisticController::class, 'index'])->name('sales_statistics.index'); + // 门店统计 + $router->get('store-statistics', [StoreStatisticController::class, 'index'])->name('store_statistics.index'); }); /* diff --git a/database/seeders/AdminPermissionSeeder.php b/database/seeders/AdminPermissionSeeder.php index fe75d8c..297e135 100644 --- a/database/seeders/AdminPermissionSeeder.php +++ b/database/seeders/AdminPermissionSeeder.php @@ -151,6 +151,15 @@ class AdminPermissionSeeder extends Seeder 'index' => '销售统计', ], ], + 'store_statistics' => [ + 'name' => '门店统计', + 'icon' => 'material-symbols:store-rounded', + 'uri' => '/finance/store-statistics', + 'resource' => false, + 'children' => [ + 'index' => '门店统计', + ], + ], ], ],