validate( rules: ['date' => ['filled', 'date_format:Y-m-d']], attributes: ['date' => '日期'], ); $input = Arr::except($this->filterInput($request), 'date'); $date = Carbon::yesterday(); if ($request->filled('date')) { $date = Carbon::parse($request->input('date')); } // 本月上报数据统计 $monthLedger = array_merge( ['deadline' => $date->format('Y-m-d')], $statisticService->ledger( array_merge($input, [ 'start_at' => $date->copy()->startOfMonth()->toDateString(), 'end_at' => $date->copy()->toDateString(), ]) ), ); // 昨日总账录入 $yesdayLedger = array_merge( ['date' => $date->format('Y-m-d')], $statisticService->ledger( array_merge($input, [ 'start_at' => $date->copy()->toDateString(), 'end_at' => $date->copy()->toDateString(), ]) ), ); // 近30天趋势数据 $trendsOf30days = $statisticService->dailyLedgerTrend( $date->copy()->subDays(29), $date->copy(), $input, ); return [ // 本月总账录入 'current_month_ledger' => $monthLedger, // 昨日累计金额 'yesday_ledger' => $yesdayLedger, // 近30天趋势数据 'trends_of_30days' => $trendsOf30days, ]; } /** * 总账统计 */ public function ledger(Request $request, StatisticService $statisticService) { $request->validate( rules: [ 'start_at' => ['bail', 'required', 'date_format:Y-m-d'], 'end_at' => ['bail', 'required', 'date_format:Y-m-d'], 'before_start_at' => ['bail', 'required', 'date_format:Y-m-d'], 'before_end_at' => ['bail', 'required', 'date_format:Y-m-d'], ], attributes: [ 'start_at' => '开始日期', 'end_at' => '结束日期', 'before_start_at' => '对比开始日期', 'before_end_at' => '对比结束日期', ], ); $input = $this->filterInput($request); $dateRange1 = $request->input('start_at').','.$request->input('end_at'); $dateRange2 = $request->input('before_start_at').','.$request->input('before_end_at'); $ledger = $statisticService->ledger( array_merge($input, ['date_range' => $dateRange1]) ); $beforeLedger = $statisticService->ledger( array_merge($input, ['date_range' => $dateRange2]) ); // 销售涨幅 $salesGrowthRate = 0; if (bccomp($beforeLedger['sales'], '0', 2) === 0) { $salesGrowthRate = '-'; } else { $diff = bcsub($ledger['sales'], $beforeLedger['sales'], 2); $salesGrowthRate = bcdiv(bcmul($diff, '100'), $beforeLedger['sales'], 2); } /** @var \Illuminate\Database\Eloquent\Collection */ $lotteryTypes = Keyword::where('parent_key', 'lottery_type')->oldest('sort')->get(); /** @var \Illuminate\Support\Collection */ $lotteryTypeStatistics = LedgerItem::select([ 'ledger_item_type_id', DB::raw('SUM(sales) as sales'), DB::raw('SUM(expenditure) as expenditure'), ]) ->filter(array_merge($input, ['date_range' => $dateRange1]), LedgerItemFilter::class) ->whereIn('ledger_item_type_id', $lotteryTypes->pluck('key')) ->groupBy(['ledger_item_type_id']) ->get() ->keyBy('ledger_item_type_id'); return array_merge($ledger, [ 'sales_growth_rate' => $salesGrowthRate, 'lottery_types' => $lotteryTypes->map(function ($lotteryType) use ($lotteryTypeStatistics) { $aggregate = $lotteryTypeStatistics->get($lotteryType->key); return [ 'name' => $lotteryType->name, 'sales' => trim_zeros($aggregate->sales ?? 0), 'expenditure' => trim_zeros($aggregate->expenditure ?? 0), ]; }), ]); } /** * 门店统计 */ public function stores(Request $request, StatisticService $statisticService) { $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' => '结束日期', ], ); $input = array_merge( $this->filterInput($request), $request->only(['start_at', 'end_at']), ); return $statisticService->storeRanking($input); } /** * 销售统计 */ public function sales(Request $request, StatisticService $statisticService): 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' => '结束日期', ], ); return $statisticService->sales( Carbon::parse($request->input('start_at')), Carbon::parse($request->input('end_at')), $this->filterInput($request), ); } /** * 处理区域和门店过滤条件 */ protected function filterInput(Request $request): array { $input = Arr::except($request->input(), ['store_id', 'province_code', 'city_code']); if ($request->filled('store_id')) { $input['store_id'] = $request->input('store_id'); } elseif ($request->anyFilled(['province_code', 'city_code'])) { $region = []; $provinceCode = (string) $request->input('province_code'); if ($provinceCode !== '') { $region['provinceCode'] = $provinceCode; } $cityCode = (string) $request->input('city_code'); if ($cityCode !== '') { $region['cityCode'] = $provinceCode; } $input['region'] = $region; } return $input; } }