CaiWuXiTong/modules/EcommerceFinance/Http/Controllers/StoreReceivingBalanceOverview.php
qiuxiang 59485b99f2 fix: period balance reconciliation performance
Separate trend loading, aggregate summary from store balances, and cap trend queries to five representative dates.
2026-11-11 19:57:36 +08:00

158 lines
5.4 KiB
PHP

<?php
namespace Modules\EcommerceFinance\Http\Controllers;
use App\Utilities\SidebarPermissions;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Modules\EcommerceFinance\Services\PeriodBalanceReconciliationService;
use Modules\EcommerceFinance\Services\StoreReceivingBalanceOverviewService;
use Throwable;
class StoreReceivingBalanceOverview extends Controller
{
public function index(Request $request, StoreReceivingBalanceOverviewService $service)
{
$this->authorizeStoreReceivingBills();
try {
return response()->json($service->overview(...$this->requestedPeriod($request)));
} catch (Throwable $exception) {
report($exception);
return response()->json([
'message' => '账户余额总览暂时无法读取,请稍后重试。',
], 503);
}
}
public function incomeDetail(Request $request, StoreReceivingBalanceOverviewService $service)
{
$this->authorizeStoreReceivingBills();
try {
return response()->json($service->incomeDetail(...$this->requestedPeriod($request)));
} catch (Throwable $exception) {
report($exception);
return response()->json([
'message' => '收入明细暂时无法读取,请稍后重试。',
], 503);
}
}
public function expenseDetail(Request $request, StoreReceivingBalanceOverviewService $service)
{
$this->authorizeStoreReceivingBills();
try {
return response()->json($service->expenseDetail(...$this->requestedPeriod($request)));
} catch (Throwable $exception) {
report($exception);
return response()->json([
'message' => '支出明细暂时无法读取,请稍后重试。',
], 503);
}
}
public function reconciliation(Request $request, PeriodBalanceReconciliationService $service)
{
$this->authorizePeriodBalanceReconciliation();
try {
return response()->json($service->build(...$this->requestedPeriod($request)));
} catch (Throwable $exception) {
report($exception);
return response()->json([
'message' => '期末余额双源核对数据暂时无法读取,请稍后重试。',
], 503);
}
}
public function reconciliationTrend(Request $request, PeriodBalanceReconciliationService $service)
{
$this->authorizePeriodBalanceReconciliation();
try {
return response()->json($service->buildTrend(...$this->requestedPeriod($request)));
} catch (Throwable $exception) {
report($exception);
return response()->json([
'message' => '期末余额双源趋势暂时无法读取,请稍后重试。',
], 503);
}
}
public function balanceDetail(Request $request, StoreReceivingBalanceOverviewService $service)
{
$this->authorizeStoreReceivingBills();
try {
return response()->json($service->balanceDetail(...$this->requestedPeriod($request)));
} catch (Throwable $exception) {
report($exception);
return response()->json([
'message' => '期末余额明细暂时无法读取,请稍后重试。',
], 503);
}
}
public function balanceStoreDetail(Request $request, StoreReceivingBalanceOverviewService $service)
{
$this->authorizeStoreReceivingBills();
try {
return response()->json($service->balanceStoreDetail(...$this->requestedPeriod($request)));
} catch (Throwable $exception) {
report($exception);
return response()->json([
'message' => '店铺期末余额明细暂时无法读取,请稍后重试。',
], 503);
}
}
/** @return array{0:string,1?:string} */
private function requestedPeriod(Request $request): array
{
$validated = $request->validate([
'month' => ['nullable', 'date_format:Y-m'],
'start' => ['nullable', 'date_format:Y-m-d', 'required_with:end'],
'end' => ['nullable', 'date_format:Y-m-d', 'required_with:start', 'after_or_equal:start'],
]);
if (! empty($validated['start']) && ! empty($validated['end'])) {
return [(string) $validated['start'], (string) $validated['end']];
}
return [(string) ($validated['month'] ?? now('Asia/Shanghai')->format('Y-m'))];
}
private function authorizeStoreReceivingBills(): void
{
$section = collect(SidebarPermissions::navigationFor(user()))
->firstWhere('slug', 'billing-transactions');
$page = collect($section['pages'] ?? [])
->firstWhere('slug', 'store-receiving-bills');
abort_if(empty($page), 403, '当前账号没有店铺收款账户账单权限。');
}
private function authorizePeriodBalanceReconciliation(): void
{
$section = collect(SidebarPermissions::navigationFor(user()))
->firstWhere('slug', 'billing-transactions');
$pages = collect($section['pages'] ?? []);
$authorized = $pages->whereIn('slug', [
'store-receiving-bills',
'period-balance-reconciliation',
])->isNotEmpty();
abort_if(! $authorized, 403, '当前账号没有期末余额双源核对权限。');
}
}