From 170267740ac3cff5bf6d87779d247c67bfddcfd4 Mon Sep 17 00:00:00 2001 From: Jing Li Date: Tue, 16 Apr 2024 13:28:29 +0800 Subject: [PATCH] =?UTF-8?q?=E9=94=80=E5=94=AE=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Admin/Filters/LedgerItemFilter.php | 9 +- .../Controllers/Api/StatisticsController.php | 97 +++++++++++++++++++ app/Models/LedgerItem.php | 1 - routes/api.php | 4 +- 4 files changed, 106 insertions(+), 5 deletions(-) diff --git a/app/Admin/Filters/LedgerItemFilter.php b/app/Admin/Filters/LedgerItemFilter.php index 1afb388..2825a3b 100644 --- a/app/Admin/Filters/LedgerItemFilter.php +++ b/app/Admin/Filters/LedgerItemFilter.php @@ -18,9 +18,12 @@ class LedgerItemFilter extends ModelFilter return; } - $provinceCode = Arr::get($region, 'provinceCode'); - $cityCode = Arr::get($region, 'cityCode'); - if (empty($provinceCode) && empty($cityCode)) { + // 区划代码 - 省份 + $provinceCode = (string) Arr::get($region, 'provinceCode'); + // 区划代码 - 城市 + $cityCode = (string) Arr::get($region, 'cityCode'); + + if ($provinceCode === '' && $cityCode === '') { return; } diff --git a/app/Http/Controllers/Api/StatisticsController.php b/app/Http/Controllers/Api/StatisticsController.php index 2ab7562..b7853b1 100644 --- a/app/Http/Controllers/Api/StatisticsController.php +++ b/app/Http/Controllers/Api/StatisticsController.php @@ -3,7 +3,10 @@ namespace App\Http\Controllers\Api; use App\Admin\Filters\LedgerFilter; +use App\Admin\Filters\LedgerItemFilter; +use App\Models\Keyword; use App\Models\Ledger; +use App\Models\LedgerItem; use App\Services\StatisticService; use Illuminate\Database\Eloquent\Collection; use Illuminate\Http\Request; @@ -93,6 +96,100 @@ class StatisticsController extends Controller return $statisticService->stores($input, $sorts); } + /** + * 销售统计 + */ + public function sales(Request $request): array + { + $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' => '结束日期', + ], + ); + + // 开始日期 + $startAt = Carbon::parse($request->input('start_at')); + // 结束日期 + $endAt = Carbon::parse($request->input('end_at')); + + $input = $this->defaultFilterInput($request); + + /** @var \Illuminate\Database\Eloquent\Collection */ + $lotteryTypes = Keyword::where('parent_key', 'lottery_type')->get(); + + /** @var \Illuminate\Support\Collection */ + $ledgerStatistics = Ledger::select([ + 'date', + DB::raw('SUM(new_customers) as new_customers'), + DB::raw('SUM(sales) as sales'), + DB::raw('SUM(expenditure) as expenditure') + ]) + ->filter($input, LedgerFilter::class) + ->whereBetween('date', [$startAt->format('Y-m-d'), $endAt->format('Y-m-d')]) + ->groupBy(['date']) + ->get() + ->keyBy('date'); + + /** @var \Illuminate\Support\Collection */ + $ledgerItemStatistics = LedgerItem::select([ + 'date', + 'ledger_item_type_id', + DB::raw('SUM(sales) as sales'), + DB::raw('SUM(expenditure) as expenditure'), + ]) + ->filter($input, LedgerItemFilter::class) + ->whereIn('ledger_item_type_id', $lotteryTypes->pluck('key')) + ->whereBetween('date', [$startAt->format('Y-m-d'), $endAt->format('Y-m-d')]) + ->groupBy(['date', 'ledger_item_type_id']) + ->get() + ->groupBy('date'); + + $data = collect(); + $date = $endAt->copy(); + + while ($date->gte($startAt)) { + $_date = $date->format('Y-m-d'); + $ledgerStatistic = $ledgerStatistics->get($_date); + /** @var \Illuminate\Support\Collection */ + $lotteryTypeStatistics = $ledgerItemStatistics->get($_date, collect())->keyBy('ledger_item_type_id'); + + $lotteryTypes->map(function ($lotteryType) use ($lotteryTypeStatistics) { + $lotteryTypeStatistic = $lotteryTypeStatistics->get($lotteryType->key); + return [ + 'name' => $lotteryType->name, + 'sales' => trim_zeros($lotteryTypeStatistic->sales ?? 0), + 'expenditure' => trim_zeros($lotteryTypeStatistic->expenditure ?? 0), + ]; + }); + + $data->push([ + 'date' => $_date, + 'ledger' => [ + 'new_customers' => $ledgerStatistic->new_customers ?? 0, + 'sales' => trim_zeros($ledgerStatistic->sales ?? 0), + 'expenditure' => trim_zeros($ledgerStatistic->expenditure ?? 0), + ], + 'lottery_types' => $lotteryTypes->map(function ($lotteryType) use ($lotteryTypeStatistics) { + $lotteryTypeStatistic = $lotteryTypeStatistics->get($lotteryType->key); + return [ + 'name' => $lotteryType->name, + 'sales' => trim_zeros($lotteryTypeStatistic->sales ?? 0), + 'expenditure' => trim_zeros($lotteryTypeStatistic->expenditure ?? 0), + ]; + }), + ]); + + $date->subDay(); + } + + return $data->all(); + } + /** * 准备趋势数据 */ diff --git a/app/Models/LedgerItem.php b/app/Models/LedgerItem.php index d00de50..fdb5dfd 100644 --- a/app/Models/LedgerItem.php +++ b/app/Models/LedgerItem.php @@ -13,7 +13,6 @@ class LedgerItem extends Model use Filterable, HasDateTimeFormatter, HasFactory; protected $casts = [ - 'date' => 'date', 'approved' => 'bool', ]; diff --git a/routes/api.php b/routes/api.php index 31b262d..62764cf 100644 --- a/routes/api.php +++ b/routes/api.php @@ -39,6 +39,8 @@ Route::group([ Route::get('/statistics/dashboard', [StatisticsController::class, 'dashboard']); // 统计数据 - 门店统计 Route::get('/statistics/stores', [StatisticsController::class, 'stores']); + // 统计数据 - 销售统计 + Route::get('/statistics/sales', [StatisticsController::class, 'sales']); // 数据上报 Route::apiResource('/ledgers', LedgerController::class)->only(['store', 'show']); @@ -67,7 +69,7 @@ Route::group([ // 报销管理 Route::apiResource('reimbursements', \App\Http\Controllers\Api\ReimbursementController::class); - + // 审核流程 Route::get('workflow', [\App\Http\Controllers\Api\WorkflowController::class, 'index']); Route::get('workflow/{id}', [\App\Http\Controllers\Api\WorkflowController::class, 'show']);