filters($request); $page = max((int) $request->query('page', 1), 1); $perPage = ProcessDetailsPageData::normalizePerPage($request->query('per_page')); try { $result = $this->repository->paginate($filters, $page, $perPage); $options = $this->repository->filterOptions(); return view('business.pages.financial-operations.process-details', [ 'section' => ['slug' => 'process-data', 'title' => '流程数据'], 'page' => ['slug' => 'oa-process', 'title' => 'OA流程'], 'processRows' => new LengthAwarePaginator( $result['data'], $result['total'], $perPage, $page, ['path' => $request->url(), 'query' => $request->except('page')], ), 'filters' => $filters, 'summary' => $result['summary'], 'documentTypes' => $options['document_types'], 'statuses' => $options['statuses'], 'paymentStates' => $options['payment_states'], 'mirrorStatus' => $result['status'], 'mirrorSyncedAt' => $result['last_synced_at'], 'mirrorStale' => $result['sync_stale'] ?? false, 'mirrorStaleAfterMinutes' => $result['sync_stale_after_minutes'] ?? 15, 'scope' => $result['scope'], 'error' => null, ]); } catch (Throwable $exception) { report($exception); return view('business.pages.financial-operations.process-details', [ 'section' => ['slug' => 'process-data', 'title' => '流程数据'], 'page' => ['slug' => 'oa-process', 'title' => 'OA流程'], 'processRows' => new LengthAwarePaginator([], 0, $perPage, $page, [ 'path' => $request->url(), 'query' => $request->except('page'), ]), 'filters' => $filters, 'summary' => [ 'rows' => 0, 'approvals' => 0, 'amount_total' => 0.0, 'bank_amount_total' => 0.0, ], 'documentTypes' => [], 'statuses' => [], 'paymentStates' => [], 'mirrorStatus' => 'unavailable', 'mirrorSyncedAt' => null, 'mirrorStale' => false, 'mirrorStaleAfterMinutes' => 15, 'scope' => $this->repository->scope(), 'error' => 'OA流程镜像尚未完成导入,请稍后重试。', ]); } } public function export(Request $request): StreamedResponse|RedirectResponse { if (! $this->repository->ready()) { return redirect() ->route('business.pages.show', [ 'section' => 'process-data', 'page' => 'oa-process', ]) ->withErrors(['export' => 'OA流程镜像尚未完成导入,暂时不能导出。']); } $filters = $this->filters($request); return response()->streamDownload(function () use ($filters): void { $stream = fopen('php://output', 'wb'); fwrite($stream, "\xEF\xBB\xBF"); fputcsv($stream, [...DingProcessDetailMirrorImporter::HEADERS, '付款状态', '付款差额']); $number = 0; foreach ($this->repository->exportRows($filters) as $row) { $number++; fputcsv($stream, [ $number, (string) ($row['business_id'] ?? ''), (string) ($row['originator_name'] ?? ''), (string) ($row['status'] ?? ''), (string) ($row['document_type'] ?? ''), (string) ($row['purpose'] ?? ''), (int) ($row['line_no'] ?? 0), (string) ($row['account_code'] ?? ''), (string) ($row['account_name'] ?? ''), $row['amount'] ?? '', (string) ($row['bank_account_code'] ?? ''), (string) ($row['bank_account_name'] ?? ''), $row['bank_amount'] ?? '', (string) ($row['payment_method'] ?? ''), (string) ($row['paid_at'] ?? ''), (string) ($row['payment_state'] ?? ''), isset($row['payment_difference']) ? number_format((float) $row['payment_difference'], 2, '.', '') : '', ]); } fclose($stream); }, 'OA流程_' . now()->format('Ymd_His') . '.csv', [ 'Content-Type' => 'text/csv; charset=UTF-8', ]); } /** @return array */ private function filters(Request $request): array { $paidDate = trim((string) $request->query('paid_date', '')); $status = trim((string) $request->query('status', '')); $paidDateValid = preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $paidDate, $dateParts) === 1 && checkdate((int) $dateParts[2], (int) $dateParts[3], (int) $dateParts[1]); $paymentState = trim((string) $request->query('payment_state', '')); if (! in_array($paymentState, DingProcessDetailMirrorRepository::PAYMENT_STATES, true) && $paymentState !== DingProcessDetailMirrorRepository::LEGACY_PAYMENT_STATE) { $paymentState = ''; } return [ 'paid_date' => $paidDateValid ? $paidDate : '', 'document_type' => mb_substr(trim((string) $request->query('document_type', '')), 0, 100), 'status' => mb_substr($status, 0, 20), 'payment_state' => $paymentState, 'business_id' => mb_substr(trim((string) $request->query('business_id', '')), 0, 32), 'originator_name' => mb_substr(trim((string) $request->query('originator_name', '')), 0, 100), 'keyword' => mb_substr(trim((string) $request->query('keyword', '')), 0, 100), ]; } }