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 { $period = $this->requestedPeriod($request); $cacheKey = $this->reconciliationCacheKey('summary', $period); return response()->json(Cache::remember( $cacheKey, now()->addMinutes(30), static fn (): array => $service->build(...$period), )); } catch (Throwable $exception) { report($exception); return response()->json([ 'message' => '期末余额双源核对数据暂时无法读取,请稍后重试。', ], 503); } } public function reconciliationTrend(Request $request, PeriodBalanceReconciliationService $service) { $this->authorizePeriodBalanceReconciliation(); try { $period = $this->requestedPeriod($request); $cacheKey = $this->reconciliationCacheKey('trend', $period); return response()->json(Cache::remember( $cacheKey, now()->addMinutes(30), static fn (): array => $service->buildTrend(...$period), )); } 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, '当前账号没有期末余额双源核对权限。'); } /** @param array{0:string,1?:string} $period */ private function reconciliationCacheKey(string $kind, array $period): string { return implode(':', [ 'ecommerce-finance', 'period-balance-reconciliation', 'v2', $kind, (string) company_id(), $period[0], $period[1] ?? '', ]); } }