generated from liutk/owl-admin-base
222 lines
6.9 KiB
PHP
222 lines
6.9 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Admin\Filters\LedgerItemFilter;
|
|
use App\Models\Keyword;
|
|
use App\Models\LedgerItem;
|
|
use App\Services\StatisticService;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Arr;
|
|
use Illuminate\Support\Carbon;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
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);
|
|
}
|
|
|
|
/** @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($input, 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;
|
|
}
|
|
}
|