ready(), 503, '供应商资料尚未完成首次同步,暂时不能导出。'); $filters = $page->filters($request->query()); $columns = SupplierManagementPageData::columns(); $companyId = (int) (company_id() ?: 1); return response()->streamDownload(static function () use ($repository, $filters, $columns, $freeShipping, $companyId): void { $csv = fopen('php://output', 'w'); fputs($csv, "\xEF\xBB\xBF"); fputcsv($csv, array_values($columns)); foreach ($repository->exportRows($filters) as $row) { $row = $freeShipping->decorateRow($row, $companyId); $values = []; foreach (array_keys($columns) as $column) { $value = $column === SupplierManagementPageData::FREE_SHIPPING_COLUMN ? ((bool) ($row->{$column} ?? false) ? '包邮' : '') : (string) ($row->{$column} ?? ''); if ($column === 'coopersgn') $value = ['1' => '合作', '2' => '不合作'][$value] ?? '未维护'; // Excel 不能执行供应商提供的公式文本,且长编码保留为文本。 if (preg_match('/^[=+\-@\t\r\n]/', ltrim($value)) || preg_match('/^\d{12,}$/', $value)) $value = "'" . $value; $values[] = $value; } fputcsv($csv, $values); } fclose($csv); }, 'supplier_management_' . now()->format('Ymd_His') . '.csv', ['Content-Type' => 'text/csv; charset=UTF-8', 'Cache-Control' => 'private, no-store']); } public function template(SupplierFreeShippingWorkbook $workbook): StreamedResponse { return $workbook->template(); } public function import( Request $request, SupplierManagementMirrorRepository $repository, SupplierFreeShippingStore $freeShipping, SupplierFreeShippingWorkbook $workbook, ): RedirectResponse { $request->validate(['import' => ['required', 'file', 'mimes:xlsx,xls,csv', 'max:10240']]); abort_unless($repository->ready(), 503, '供应商资料尚未完成首次同步,暂时不能导入。'); $valuesByCode = $workbook->read($request->file('import')); $suppliers = $repository->suppliersByCodes(array_keys($valuesByCode)); $matched = []; foreach ($suppliers as $supplier) { $code = mb_strtolower(trim((string) ($supplier->scmcode ?? ''))); if ($code !== '') { $matched[$code][] = $supplier; } } $missing = []; $ambiguous = []; $valuesBySupplierId = []; foreach ($valuesByCode as $code => $isFreeShipping) { $key = mb_strtolower(trim((string) $code)); if (! isset($matched[$key])) { $missing[] = (string) $code; continue; } if (count($matched[$key]) !== 1) { $ambiguous[] = (string) $code; continue; } $valuesBySupplierId[(int) $matched[$key][0]->Id] = $isFreeShipping; } if ($ambiguous !== []) { throw ValidationException::withMessages([ 'import' => '以下供应商代码在供应商主档中存在多条记录,未导入:' . implode('、', array_slice($ambiguous, 0, 8)), ]); } if ($missing !== []) { throw ValidationException::withMessages([ 'import' => '以下供应商代码未找到,未导入:' . implode('、', array_slice($missing, 0, 8)) . (count($missing) > 8 ? ' 等 ' . count($missing) . ' 条' : ''), ]); } $result = $freeShipping->saveMany( $valuesBySupplierId, (int) (company_id() ?: 1), user_id() ? (int) user_id() : null, 'import', ); return $this->redirectToPage($request)->with( 'supplier_management_message', "导入完成:新增 {$result['created']} 家供应商维护记录,更新 {$result['updated']} 家供应商维护记录。", ); } public function updateFreeShipping( Request $request, int $supplier, SupplierManagementMirrorRepository $repository, SupplierFreeShippingStore $freeShipping, ): JsonResponse|RedirectResponse { $request->validate(['value' => ['nullable', 'string', 'in:,包邮']]); abort_unless($repository->ready(), 503, '供应商资料尚未完成首次同步,暂时不能编辑。'); abort_if($repository->supplierById($supplier) === null, 404, '供应商不存在。'); $isFreeShipping = $request->input('value') === '包邮'; $freeShipping->save( $supplier, $isFreeShipping, (int) (company_id() ?: 1), user_id() ? (int) user_id() : null, 'manual', ); if ($request->expectsJson()) { return response()->json([ 'ok' => true, 'value' => $isFreeShipping ? '包邮' : '', 'display' => $isFreeShipping ? '包邮' : '-', ]); } return $this->redirectToPage($request)->with('supplier_management_message', '是否包邮厂家已保存。'); } private function redirectToPage(Request $request): RedirectResponse { $query = array_filter([ ...app(SupplierManagementPageData::class)->filters($request->query()), 'page' => max((int) $request->query('page', 1), 1), ], static fn (mixed $value): bool => $value !== ''); $url = route('business.pages.show', [ 'company_id' => company_id() ?: 1, 'section' => 'supplier-payables', 'page' => 'supplier-management', ]); return redirect()->to($url . ($query === [] ? '' : '?' . http_build_query($query))); } }