error('账号未绑定工厂'); } } /** * 上传文件,AI/规则提取后返回预览,不入库 */ public function preview() { @set_time_limit(180); $type = $this->request->post('type', 'workorder'); $type = $type === 'product' ? 'product' : 'workorder'; $file = $this->request->file('file'); if (!$file) { $this->error('请选择文件'); } $dir = RUNTIME_PATH . 'import' . DS; if (!is_dir($dir)) { @mkdir($dir, 0755, true); } $info = $file->validate([ 'size' => 12 * 1024 * 1024, 'ext' => 'csv,txt,xlsx,xls,pdf,png,jpg,jpeg,webp,bmp', ])->move($dir); if (!$info) { $this->error($file->getError() ?: '上传失败'); } $path = $info->getPathname(); try { $data = BizExtractor::extract($path, $type); } catch (\Exception $e) { @unlink($path); $this->error($e->getMessage()); } @unlink($path); $this->success('已识别,请核对后确认导入', $data); } /** * 确认写入数据库 */ public function confirm() { $type = $this->request->post('type', 'workorder'); $type = $type === 'product' ? 'product' : 'workorder'; $items = $this->request->post('items/a'); if (!$items) { $raw = $this->request->post('items_json', '', null); $items = json_decode((string)$raw, true); } if (!is_array($items) || !$items) { $this->error('没有可导入的数据'); } $items = BizExtractor::normalizeItems($items, $type); $saved = []; $errors = []; foreach ($items as $i => $item) { try { if ($type === 'product') { $row = BizIngest::saveProduct($item, $this->auth->id); $saved[] = ['id' => (int)$row->id, 'code' => $row->code, 'name' => $row->name]; } else { $row = BizIngest::saveWorkorder($item, $this->auth->id); $saved[] = ['id' => (int)$row->id, 'no' => $row->no]; } } catch (\Exception $e) { $errors[] = '第' . ($i + 1) . '条:' . $e->getMessage(); } } if (!$saved) { $this->error($errors ? implode(';', $errors) : '导入失败'); } $this->success('已导入 ' . count($saved) . ' 条', [ 'saved' => $saved, 'errors' => $errors, ]); } }