authorizeStoreReceivingBills(); $billType = (string) $request->get('bill_type', ''); if (! AccountBillColumns::has($billType)) { abort(404, '未知的账户类型。'); } $query = AccountBill::query() ->where('company_id', company_id()) ->where('bill_type', $billType); if ($store = $request->get('store_name')) { $query->where('store_name', $store); } if ($item = $request->get('bill_item')) { $query->where('bill_item', $item); } if ($start = $request->get('start')) { $query->where('occurred_at', '>=', $start); } if ($end = $request->get('end')) { $query->where('occurred_at', '<=', $end . ' 23:59:59'); } if ($keyword = $request->get('keyword')) { $query->where(function ($q) use ($keyword) { $like = '%' . $keyword . '%'; $q->where('record_code', 'like', $like) ->orWhere('order_no', 'like', $like) ->orWhere('remark', 'like', $like) ->orWhere('bill_item', 'like', $like); }); } $sortable = ['occurred_at', 'income', 'expense', 'balance', 'record_code']; $sort = in_array($request->get('sort'), $sortable, true) ? $request->get('sort') : 'occurred_at'; $dir = $request->get('dir') === 'asc' ? 'asc' : 'desc'; $query->orderBy($sort, $dir); $perPage = min(max((int) $request->get('limit', 10), 1), 100); $rows = $query->paginate($perPage); // 汇总(分页前) $summaryRow = (clone $query)->selectRaw( 'COALESCE(SUM(income), 0) as income, ' . 'COALESCE(SUM(expense), 0) as expense, ' . 'COUNT(*) as count' )->first(); $latestBalance = (clone $query) ->orderByDesc('occurred_at') ->orderByDesc('id') ->value('balance'); $data = $rows->toArray(); $data['summary'] = [ 'income' => (float) ($summaryRow->income ?? 0), 'expense' => (float) ($summaryRow->expense ?? 0), 'count' => (int) ($summaryRow->count ?? 0), 'balance' => $latestBalance !== null ? (float) $latestBalance : 0, ]; $data['columns'] = AccountBillColumns::for($billType); return response()->json($data); } public function show(AccountBill $bill) { $this->authorizeStoreReceivingBills(); return response()->json($bill); } protected 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, '当前账号没有店铺收款账户账单权限。'); } }