diff --git a/app/Admin/Controllers/CockpitController.php b/app/Admin/Controllers/CockpitController.php index ae6da9e..1bf5618 100644 --- a/app/Admin/Controllers/CockpitController.php +++ b/app/Admin/Controllers/CockpitController.php @@ -11,6 +11,7 @@ use App\Models\LedgerItem; use App\Models\Store; use App\Models\TaskPerformance; use Illuminate\Http\Request; +use Illuminate\Support\Arr; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Storage; @@ -378,4 +379,62 @@ class CockpitController extends Controller ]); })->all(); } + + public function storeCategory(Request $request): array + { + $request->validate( + rules: [ + 'category_id' => ['filled'], + ], + ); + + $categoryId = $request->input('category_id', 'store_category'); + + $categories = collect(); + + if ($parent = Keyword::where('key', $categoryId)->first()) { + /** @var \Illuminate\Database\Eloquent\Collection */ + $descendants = Keyword::where('path', 'like', "%-{$parent->id}-%")->get(); + + $categories = $descendants->where('parent_id', $parent->id) + ->map(function ($category) use ($descendants) { + return [ + 'id' => $category->key, + 'name' => $category->name, + 'descendants' => $descendants->filter(function ($descendant) use ($category) { + return preg_match("/-{$category->id}-/", $descendant->path); + })->map(function ($descendant) { + return [ + 'id' => $descendant->key, + 'name' => $descendant->name, + ]; + })->all(), + ]; + }); + } + + $aggregates = Store::select(['category_id', DB::raw('count(1) as stores_count')]) + ->onlyOpen() + ->groupBy('category_id') + ->get() + ->keyBy('category_id'); + + return $categories->map(function ($category) use ($aggregates) { + $storesCount = 0; + + $descendants = collect( + Arr::pull($category, 'descendants') + )->push($category); + + foreach ($descendants as $item) { + if ($aggregate = $aggregates->get($item['id'])) { + $storesCount += $aggregate->stores_count; + } + } + + return array_merge($category, [ + 'stores_count' => $storesCount, + ]); + })->values()->all(); + } } diff --git a/app/Admin/routes.php b/app/Admin/routes.php index bafb6dc..eec4c0e 100644 --- a/app/Admin/routes.php +++ b/app/Admin/routes.php @@ -254,6 +254,8 @@ Route::group([ $router->get('cockpit/store-number-distribution', [CockpitController::class, 'storeNumberDistribution']); // 门店分布(按城市) $router->get('cockpit/store-distribution', [CockpitController::class, 'storeDistribution']); + // 门店分类 + $router->get('cockpit/store-category', [CockpitController::class, 'storeCategory']); // 年度目标 $router->get('cockpit/yearly-goals', [CockpitController::class, 'yearlyGoals']); });