main
Jing Li 2024-04-16 15:05:32 +08:00
parent e94c349a3e
commit 9878a1fc5c
2 changed files with 119 additions and 111 deletions

View File

@ -3,12 +3,8 @@
namespace App\Http\Controllers\Api; namespace App\Http\Controllers\Api;
use App\Admin\Filters\LedgerFilter; use App\Admin\Filters\LedgerFilter;
use App\Admin\Filters\LedgerItemFilter;
use App\Models\Keyword;
use App\Models\Ledger; use App\Models\Ledger;
use App\Models\LedgerItem;
use App\Services\StatisticService; use App\Services\StatisticService;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Carbon; use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
@ -18,7 +14,7 @@ class StatisticsController extends Controller
/** /**
* 首页统计 * 首页统计
*/ */
public function dashboard(Request $request): array public function dashboard(Request $request, StatisticService $statisticService): array
{ {
$query = Ledger::filter( $query = Ledger::filter(
$this->defaultFilterInput($request), LedgerFilter::class $this->defaultFilterInput($request), LedgerFilter::class
@ -40,34 +36,6 @@ class StatisticsController extends Controller
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
$yesterdayLedger = (clone $query)->where('date', $yesterday->format('Y-m-d'))->first(); $yesterdayLedger = (clone $query)->where('date', $yesterday->format('Y-m-d'))->first();
//--------------------------------------------------------------------------
// 近 30 天趋势数据
//--------------------------------------------------------------------------
$startAt = $yesterday->copy()->subDays(29);
$endAt = $yesterday->copy();
/** @var \Illuminate\Database\Eloquent\Collection */
$ledgers30days = (clone $query)
->whereBetween('date', [$startAt, $endAt])
->get(['date', 'sales', 'expenditure'])
->keyBy('date');
$trend = collect();
while ($startAt->lte($endAt)) {
$ledger = $ledgers30days->get(
$date = $startAt->format('Y-m-d')
);
$trend->push([
'date' => $date,
'sales' => trim_zeros($ledger->sales ?? 0),
'expenditure' => trim_zeros($ledger->expenditure ?? 0),
]);
$startAt->addDay();
}
return [ return [
// 本月总账录入 // 本月总账录入
'current_month_ledger' => [ 'current_month_ledger' => [
@ -83,7 +51,9 @@ class StatisticsController extends Controller
'expenditure' => trim_zeros($yesterdayLedger->expenditure ?? 0), 'expenditure' => trim_zeros($yesterdayLedger->expenditure ?? 0),
], ],
// 近30天趋势数据 // 近30天趋势数据
'trend_data_of_30days' => $trend, 'trend_data_of_30days' => $statisticService->ledgerTrends(
$yesterday->copy()->subDays(29), $yesterday->copy()
),
]; ];
} }
@ -116,7 +86,7 @@ class StatisticsController extends Controller
/** /**
* 销售统计 * 销售统计
*/ */
public function sales(Request $request): array public function sales(Request $request, StatisticService $statisticService): array
{ {
$request->validate( $request->validate(
rules: [ rules: [
@ -129,82 +99,11 @@ class StatisticsController extends Controller
], ],
); );
// 开始日期 return $statisticService->sales(
$startAt = Carbon::parse($request->input('start_at')); Carbon::parse($request->input('start_at')),
// 结束日期 Carbon::parse($request->input('end_at')),
$endAt = Carbon::parse($request->input('end_at')); $this->defaultFilterInput($request),
);
$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();
} }
/** /**

View File

@ -3,14 +3,47 @@
namespace App\Services; namespace App\Services;
use App\Admin\Filters\LedgerFilter; use App\Admin\Filters\LedgerFilter;
use App\Admin\Filters\LedgerItemFilter;
use App\Admin\Filters\StoreFilter; use App\Admin\Filters\StoreFilter;
use App\Models\Keyword;
use App\Models\Ledger; use App\Models\Ledger;
use App\Models\LedgerItem;
use App\Models\Store; use App\Models\Store;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
class StatisticService class StatisticService
{ {
/**
* 总账趋势
*/
public function ledgerTrends(Carbon $start, Carbon $end, array $input = []): array
{
$ledgers = Ledger::filter($input, LedgerFilter::class)
->whereBetween('date', [$start->format('Y-m-d'), $end->format('Y-m-d')])
->get(['date', 'sales', 'expenditure'])
->keyBy('date');
$data = collect();
while ($start->lte($end)) {
$ledger = $ledgers->get(
$date = $start->format('Y-m-d')
);
$data->push([
'date' => $date,
'sales' => trim_zeros($ledger->sales ?? 0),
'expenditure' => trim_zeros($ledger->expenditure ?? 0),
]);
$start->addDay();
}
return $data->all();
}
/** /**
* 门店统计 * 门店统计
*/ */
@ -41,4 +74,80 @@ class StatisticService
]; ];
})->all(); })->all();
} }
/**
* 销售统计
*/
public function sales(Carbon $start, Carbon $end, array $input = []): array
{
/** @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', [$start->format('Y-m-d'), $end->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', [$start->format('Y-m-d'), $end->format('Y-m-d')])
->groupBy(['date', 'ledger_item_type_id'])
->get()
->groupBy('date');
$data = collect();
while ($end->gte($start)) {
$date = $end->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),
];
}),
]);
$end->subDay();
}
return $data->all();
}
} }