diff --git a/yuthon_ai_agent/controllers/main.py b/yuthon_ai_agent/controllers/main.py index 18fb9fbb9..da3e9d421 100644 --- a/yuthon_ai_agent/controllers/main.py +++ b/yuthon_ai_agent/controllers/main.py @@ -247,25 +247,42 @@ class AiChatController(http.Controller): # OCR 提取文字 ocr_text = '' ocr_error = '' + ocr_diag = {} # 诊断信息 if provider and provider.ocr_enabled: from ..models.ocr_provider import get_ocr_instance ocr, init_err = get_ocr_instance(provider) + ocr_diag['provider'] = provider.name + ocr_diag['ocr_enabled'] = True if ocr is None: ocr_error = init_err or 'OCR 实例创建失败' _logger.error('[AI-OCR] get_ocr_instance 失败: %s', ocr_error) + ocr_diag['init_error'] = ocr_error else: - result = ocr.smart_recognize(raw_bytes, mimetype) + ocr_diag['init_ok'] = True + # 直接用通用文字识别(不先走票据识别,避免不必要的 API 调用) + _logger.info('[AI-OCR] 开始识别 %s (%d bytes, %s)', filename, len(raw_bytes), mimetype) + result = ocr.recognize_general(raw_bytes, mimetype) + ocr_diag['method'] = 'GeneralBasicOCR' + ocr_diag['success'] = result.get('success') if result.get('success'): ocr_text = result.get('text') or '' + ocr_diag['text_len'] = len(ocr_text) if ocr_text: document.sudo().write({'ai_ocr_content': ocr_text}) - _logger.info('[AI-OCR] 识别成功,%d 字符', len(ocr_text)) + _logger.info('[AI-OCR] ✅ 识别成功,%d 字符: %s', len(ocr_text), ocr_text[:200]) else: ocr_error = '图片中未识别到文字' - _logger.info('[AI-OCR] 识别完成但无文字') + _logger.info('[AI-OCR] ⚠️ 识别完成但无文字 — 图片中可能确实没有印刷文字') else: ocr_error = result.get('error', 'OCR 调用失败') - _logger.error('[AI-OCR] %s', ocr_error) + ocr_diag['error'] = ocr_error + _logger.error('[AI-OCR] ❌ %s', ocr_error) + else: + ocr_diag['ocr_enabled'] = False + if not provider: + ocr_diag['reason'] = '未找到 AI 服务商(conversation_id 可能无效)' + else: + ocr_diag['reason'] = 'OCR 未启用' return request.make_json_response({ 'success': True, @@ -274,4 +291,5 @@ class AiChatController(http.Controller): 'mimetype': mimetype, 'ocr_text': ocr_text, 'ocr_error': ocr_error, + '_ocr_diag': ocr_diag, # 前端 console 可查看 }) diff --git a/yuthon_ai_agent/models/ai_agent.py b/yuthon_ai_agent/models/ai_agent.py index 999eb055a..07b2a4f54 100644 --- a/yuthon_ai_agent/models/ai_agent.py +++ b/yuthon_ai_agent/models/ai_agent.py @@ -769,6 +769,7 @@ class AiConversation(models.Model): ocr_result = '' attachment_note = '' msg_attachment_ids = [] + no_text_count = 0 # 无文字附件数量 if attachment_ids: attachments = self.env['documents.document'].sudo().browse(attachment_ids).exists() if attachments: @@ -789,6 +790,7 @@ class AiConversation(models.Model): ocr_result = '\n\n'.join(ocr_parts) + '\n\n' # 有附件但 OCR 无文字 → 告知 AI 它是文本模型,无法“看”图片 if no_text_names: + no_text_count = len(no_text_names) file_list = '、'.join(no_text_names) attachment_note = ( f'[系统提示:用户上传了附件({file_list}),' @@ -802,6 +804,15 @@ class AiConversation(models.Model): # 构建最终发送给 AI 的用户消息内容 full_content = attachment_note + ocr_result + content if (ocr_result or attachment_note) else content + _logger.info( + '[AI-MSG] send_message | attachments=%d | ocr_chars=%d | no_text=%d | ' + 'full_content_head=%s', + len(msg_attachment_ids) if msg_attachment_ids else 0, + len(ocr_result) if ocr_result else 0, + no_text_count, + (full_content or '')[:300], + ) + # 1. 保存用户消息(content 存原始用户文本,ocr_content 存 OCR 结果, # full_content 带 OCR 的版本发给 AI,前端通过 attachments 字段渲染附件预览) msg_vals = { diff --git a/yuthon_ai_agent/static/src/js/ai_chat_action.js b/yuthon_ai_agent/static/src/js/ai_chat_action.js index 673d1daf1..6e629916c 100644 --- a/yuthon_ai_agent/static/src/js/ai_chat_action.js +++ b/yuthon_ai_agent/static/src/js/ai_chat_action.js @@ -138,8 +138,12 @@ export class AiChatAction extends Component { } if (data && data.success) { + console.log("[AI] 上传成功:", data.filename, "| OCR文字:", (data.ocr_text || '(无)').substring(0, 100)); + if (data._ocr_diag) { + console.log("[AI] OCR诊断:", JSON.stringify(data._ocr_diag)); + } if (data.ocr_error) { - console.warn("[AI] OCR:", data.ocr_error); + console.warn("[AI] OCR错误:", data.ocr_error); } this.state.attachments = [ ...this.state.attachments, diff --git a/yuthon_ai_agent/static/src/js/ai_floating.js b/yuthon_ai_agent/static/src/js/ai_floating.js index 3d21abca8..ac3130207 100644 --- a/yuthon_ai_agent/static/src/js/ai_floating.js +++ b/yuthon_ai_agent/static/src/js/ai_floating.js @@ -112,8 +112,13 @@ async function uploadFile(file) { } if (data && data.success) { + // 诊断日志:查看 OCR 各环节状态 + console.log("[AI] 上传成功:", data.filename, "| OCR文字:", (data.ocr_text || '(无)').substring(0, 100)); + if (data._ocr_diag) { + console.log("[AI] OCR诊断:", JSON.stringify(data._ocr_diag)); + } if (data.ocr_error) { - console.warn("[AI] OCR:", data.ocr_error); + console.warn("[AI] OCR错误:", data.ocr_error); } pendingAttachments.push({ attachment_id: data.attachment_id,