图片识别
This commit is contained in:
@@ -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 可查看
|
||||
})
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user