store-manage/app/Http/Controllers/Api/StatisticsController.php

194 lines
5.7 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Services\StatisticService;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Carbon;
class StatisticsController extends Controller
{
/**
* 首页统计
*/
public function dashboard(Request $request, StatisticService $statisticService): array
{
$request->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);
$ledger = $statisticService->ledger(
array_merge($input, [
'start_at' => $request->input('start_at'),
'end_at' => $request->input('end_at'),
])
);
$beforeLedger = $statisticService->ledger(
array_merge($input, [
'start_at' => $request->input('before_start_at'),
'end_at' => $request->input('before_end_at'),
])
);
// 销售涨幅
$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);
}
return array_merge($ledger, [
'sales_growth_rate' => $salesGrowthRate,
]);
}
/**
* 门店统计
*/
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;
}
}