log = Log::channel('sync_seal'); } elseif (self::DRUG_REPORT_OPT_HISTORY == $source) { $this->log = Log::channel('sync_opt'); } else { $this->log = Log::channel('sync'); } } /** * 分批次同步数据 * @param string $source * @param bool $isFull * @param string $startTime * @param string $endTime * @param int $page * @param int $pageSize * @return int */ public function syncDrugReport(string $source, bool $isFull, string $startTime, string $endTime = '', int $page = 1, int $pageSize = 20): int { if (!$this->checkSource($source)) { $this->log->error("来源[source]不正确,无法进行同步", [ 'source' => $source, 'params' => [ 'is_full' => $isFull, 'start_time' => $startTime, 'end_time' => $endTime, 'page' => $page, 'page_size' => $pageSize, ], ]); return 0; } $this->setLog($source); $total = 0; $this->log->notice($isFull ? "开始全量同步" : "开始增量同步", [ 'source' => $source, 'params' => [ 'is_full' => $isFull, 'start_time' => $startTime, 'end_time' => $endTime, 'page' => $page, 'page_size' => $pageSize, ], ]); if (empty($endTime)) { $endTime = Carbon::parse($startTime)->copy()->endOfMonth()->toDateTimeString(); } $this->queryDrugReportService = app(QueryDrugReportService::class); do { $month = Carbon::parse($startTime)->copy()->format('Ym'); try { if (Carbon::parse($startTime)->isFuture()) { $this->log->warning("时间大于当前时间,同步终止", [ 'source' => $source, 'params' => [ 'is_full' => $isFull, 'start_time' => $startTime, 'end_time' => $endTime, 'page' => $page, 'page_size' => $pageSize, ] ]); break; } $this->log->info("批次 {$month}[{$page}] 开始处理", [ 'source' => $source, 'params' => [ 'is_full' => $isFull, 'start_time' => $startTime, 'end_time' => $endTime, 'page' => $page, 'page_size' => $pageSize, ] ]); // 分批次拉取数据 $data = $this->queryDrugReport($source, $startTime, $endTime, $page, $pageSize); if (empty($data)) { $this->log->warning("批次 {$month}[{$page}] 没有数据", [ 'source' => $source, 'params' => [ 'is_full' => $isFull, 'start_time' => $startTime, 'end_time' => $endTime, 'page' => $page, 'page_size' => $pageSize, ] ]); if ($isFull) { $next = Carbon::parse($startTime)->copy()->addMonth(); $startTime = $next->startOfMonth()->toDateTimeString(); $endTime = $next->endOfMonth()->toDateTimeString(); $page = 1; continue; } break; } // 处理并保存数据 $saveCount = $this->saveDrugReport($source, $data); $total += $saveCount; $this->log->info("批次 {$month}[{$page}] 处理完成", [ 'source' => $source, 'fetch_count' => count($data), 'save_count' => $saveCount, 'total' => $total, ]); // 检查是否还有更多数据 if (count($data) <> $pageSize) { if ($isFull) { $next = Carbon::parse($startTime)->copy()->addMonth(); $startTime = $next->startOfMonth()->toDateTimeString(); $endTime = $next->endOfMonth()->toDateTimeString(); $page = 1; continue; } break; } $page++; // 避免请求过于频繁 sleep(1); } catch (\Exception $e) { $this->log->error("批次 {$month}[{$page}] 数据获取失败", [ 'source' => $source, 'params' => [ 'is_full' => $isFull, 'start_time' => $startTime, 'end_time' => $endTime, 'page' => $page, 'page_size' => $pageSize, ], 'error' => $e->getMessage() ]); // continue; break; } } while (true); $this->log->notice($isFull ? "全量同步完成" : "增量同步完成", [ 'source' => $source, 'total' => $total ]); return $total; } /** * 查询药检报告数据 * @param string $source * @param string $startTime * @param string $endTime * @param int $page * @param int $pageSize * @return array * @throws \Exception */ protected function queryDrugReport(string $source, string $startTime, string $endTime = '', int $page = 1, int $pageSize = 20): array { if (self::QUERY_DRUG_REPORT == $source) { return $this->queryDrugReportService->queryDrugReport($startTime, $endTime, $page, $pageSize); } if (self::QUERY_SEAL_DRUG_REPORT == $source) { return $this->queryDrugReportService->querySealDrugReport($startTime, $endTime, $page, $pageSize); } if (self::DRUG_REPORT_OPT_HISTORY == $source) { $startDate = Carbon::parse($startTime)->copy()->toDateString(); $endDate = Carbon::parse($endTime)->copy()->toDateString(); return $this->queryDrugReportService->drugReportOptHistory($startDate, $endDate, $page, $pageSize); } return []; } /** * 处理并保存批次数据 * @param string $source * @param array $data * @return int */ protected function saveDrugReport(string $source, array $data): int { try { if (self::QUERY_SEAL_DRUG_REPORT == $source) { $data = $this->correctSealDrugReport($data); } elseif (self::DRUG_REPORT_OPT_HISTORY == $source) { $data = $this->correctDrugReportOptHistory($data); } else { $data = $this->correctDrugReport($data); } return DrugReportInfo::bulkUpsert($data); } catch (\Throwable $e) { $this->log->error("保存批次数据失败", [ 'data' => $data, 'error' => $e->getMessage() ]); return 0; } } /** * 处理【待签收】医药报告批次数据 * @param array $data * @return array */ protected function correctDrugReport(array $data): array { return array_map(function ($item) { return [ 'drug_report_id' => $item['drug_report_id'] ?? '', 'report_name' => $item['file_name'] ?? '', 'batch_no' => $item['produce_batch_no'] ?? '', 'drug_id' => $item['drug_id'] ?? '', 'drug_name' => $item['physic_name'] ?? '', 'pkg_spec' => $item['pkg_spec'] ?? '', 'prepn_spec' => $item['prepn_spec'] ?? '', 'prepn_type_desc' => $item['prepn_type_desc'] ?? '', 'bill_type' => $item['bill_type'] ?? 0, 'bill_id' => $item['bill_id'] ?? '', 'bill_detail_id' => $item['bill_detail_id'] ?? '', 'bill_time' => $item['bill_time'] ?? '', 'bill_code' => $item['bill_code'] ?? '', 'produce_date' => $item['produce_date'] ?? '', 'produce_ent_id' => $item['produce_ent_id'] ?? '', 'produce_ent_name' => $item['produce_ent_name'] ?? '', 'ass_ref_ent_id' => $item['ass_ref_ent_id'] ?? '', 'from_ref_ent_id' => $item['from_ref_ent_id'] ?? '', 'from_ent_name' => $item['from_ent_name'] ?? '', 'sealed_report_url' => $item['sealed_report_url'] ?? '', 'report_sign_status' => $item['drug_report_sign_status'] ?? '', 'raw_data' => json_encode($item ?? [], JSON_UNESCAPED_UNICODE), ]; }, $data); } /** * 处理【已签收】医药报告批次数据 * @param array $data * @return array */ protected function correctSealDrugReport(array $data): array { return array_map(function ($item) { return [ 'report_id' => $item['report_id'] ?? '', 'report_name' => $item['drug_report_name'] ?? '', 'report_no' => $item['report_no'] ?? '', 'report_date' => $item['report_date'] ?? '', 'batch_no' => $item['batch_no'] ?? '', 'drug_id' => $item['drug_ent_base_info_id'] ?? '', 'drug_name' => $item['drug_name'] ?? '', 'prod_code' => $item['prod_code'] ?? '', 'pkg_spec' => $item['pkg_spec'] ?? '', 'prepn_spec' => $item['prepn_spec'] ?? '', 'pkg_ratio_list' => json_encode($item['pkg_ratio_list'] ?? [], JSON_UNESCAPED_UNICODE), 'sealed_report_url' => $item['sealed_report_url'] ?? '', 'seal_raw_data' => json_encode($item ?? [], JSON_UNESCAPED_UNICODE), ]; }, $data); } /** * 处理医药报告操作批次数据 * @param array $data * @return array */ protected function correctDrugReportOptHistory(array $data): array { return array_map(function ($item) { return [ 'batch_no' => $item['batch_no'] ?? '', 'drug_id' => $item['drug_id'] ?? '', 'opt_raw_data' => json_encode($item ?? [], JSON_UNESCAPED_UNICODE), ]; }, $data); } }