diff --git a/app/Admin/Filters/StoreFilter.php b/app/Admin/Filters/StoreFilter.php index 6c48faf..c4c0cb6 100644 --- a/app/Admin/Filters/StoreFilter.php +++ b/app/Admin/Filters/StoreFilter.php @@ -7,6 +7,11 @@ use Illuminate\Support\Arr; class StoreFilter extends ModelFilter { + public function store($id) + { + $this->where('id', $id); + } + public function title($name) { $this->whereLike('title', $name); diff --git a/app/Http/Controllers/Api/StatsController.php b/app/Http/Controllers/Api/StatisticsController.php similarity index 65% rename from app/Http/Controllers/Api/StatsController.php rename to app/Http/Controllers/Api/StatisticsController.php index 2e8653c..f68da6e 100644 --- a/app/Http/Controllers/Api/StatsController.php +++ b/app/Http/Controllers/Api/StatisticsController.php @@ -3,22 +3,25 @@ namespace App\Http\Controllers\Api; use App\Admin\Filters\LedgerFilter; -use App\Models\Employee; +use App\Admin\Filters\StoreFilter; +use App\Http\Resources\StoreResource; use App\Models\Ledger; +use App\Models\Store; use Illuminate\Database\Eloquent\Collection; use Illuminate\Http\Request; +use Illuminate\Support\Arr; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\DB; -class StatsController extends Controller +class StatisticsController extends Controller { - public function dashboard(Request $request) + /** + * 首页统计 + */ + public function dashboard(Request $request): array { - /** @var \App\Models\Employee */ - $user = $request->user(); - $query = Ledger::filter( - $this->defaultInput($user, $request), LedgerFilter::class + $this->defaultFilterInput($request), LedgerFilter::class ); // 昨天 @@ -67,6 +70,40 @@ class StatsController extends Controller ]; } + /** + * 门店统计 + */ + public function stores(Request $request) + { + $request->validate( + rules: [ + 'start_at' => ['bail', 'required', 'date_format:Y-m-d'], + 'end_at' => ['bail', 'required', 'date_format:Y-m-d'], + ], + attributes: [ + 'start_at' => '开始日期', + 'end_at' => '结束日期', + ], + ); + + $storeLedgerStats = Ledger::select(['store_id', DB::raw('SUM(sales) as sales')]) + ->whereBetween('date', [$request->input('start_at'), $request->input('end_at')]) + ->groupBy('store_id'); + + $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(); + + return $stores->map(function (Store $store) { + return [ + 'store' => StoreResource::make($store), + 'sales' => trim_zeros($store->sales ?: 0), + ]; + }); + } + /** * 准备趋势数据 */ @@ -91,13 +128,14 @@ class StatsController extends Controller return $data->all(); } - protected function defaultInput(Employee $employee, Request $request): array + /** + * 处理区域和门店过滤条件 + */ + protected function defaultFilterInput(Request $request): array { $input = []; - if (! $employee->isAdministrator()) { - $input['store_id'] = $employee->store_id; - } elseif ($request->filled('store_id')) { + if ($request->filled('store_id')) { $input['store_id'] = $request->input('store_id'); } else { $region = []; @@ -106,8 +144,8 @@ class StatsController extends Controller $region['provinceCode'] = $request->input('province_code'); } - if ($request->filled('cityCode')) { - $region['city_code'] = $request->input('city_code'); + if ($request->filled('city_code')) { + $region['cityCode'] = $request->input('city_code'); } $input['region'] = $region; diff --git a/routes/api.php b/routes/api.php index 724af97..dc25272 100644 --- a/routes/api.php +++ b/routes/api.php @@ -8,7 +8,7 @@ use App\Http\Controllers\Api\FileUploadController; use App\Http\Controllers\Api\KeywordController; use App\Http\Controllers\Api\LedgerController; use App\Http\Controllers\Api\ReimbursementController; -use App\Http\Controllers\Api\StatsController; +use App\Http\Controllers\Api\StatisticsController; use Illuminate\Support\Facades\Route; Route::post('/auth/login', [AccessTokenController::class, 'store']); @@ -35,7 +35,10 @@ Route::group([ // 个人账户 - 佣金提成 Route::get('/account/store-master-commissions', [StoreMasterCommissionController::class, 'index']); - Route::get('/stats/dashboard', [StatsController::class, 'dashboard']); + // 统计数据 - 首页统计 + Route::get('/statistics/dashboard', [StatisticsController::class, 'dashboard']); + // 统计数据 - 门店统计 + Route::get('/statistics/stores', [StatisticsController::class, 'stores']); // 数据上报 Route::apiResource('/ledgers', LedgerController::class)->only(['store', 'show']);