图片识别

This commit is contained in:
李鹏宇
2026-06-12 17:09:59 +08:00
parent 3c88e17986
commit e1e590200b
4 changed files with 44 additions and 6 deletions
+22 -4
View File
@@ -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 可查看
})
+11
View File
@@ -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,
+6 -1
View File
@@ -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,