Files
gzth/yuthon_ai_agent/controllers/main.py
T
2026-06-04 19:06:05 +08:00

164 lines
6.2 KiB
Python

# -*- coding: utf-8 -*-
import json
from odoo import http
from odoo.http import request
from odoo.tools import format_datetime
class AiChatController(http.Controller):
"""AI 聊天 API"""
def _check_ai_access(self):
"""检查用户是否有 AI Agent 使用权限"""
if not request.env.user.has_group('yuthon_ai_agent.group_ai_agent_user'):
return {'error': '您没有使用 AI 助手的权限,请联系管理员开通。'}
return None
@http.route('/ai/chat/send', type='json', auth='user', methods=['POST'], csrf=False)
def chat_send(self, conversation_id, message):
"""发送消息"""
err = self._check_ai_access()
if err:
return err
conv = request.env['ai.conversation'].browse(conversation_id)
if not conv.exists():
return {'error': '对话不存在'}
reply = conv.send_message(message)
if isinstance(reply, dict) and 'error' in reply:
return reply
last_msg = conv.message_ids.filtered(lambda m: m.role == 'assistant')[-1:]
return {
'content': reply,
'message_id': last_msg.id if last_msg else False,
}
@http.route('/ai/chat/history', type='json', auth='user')
def chat_history(self, conversation_id):
"""获取对话历史"""
conv = request.env['ai.conversation'].browse(conversation_id)
if not conv.exists():
return {'error': '对话不存在'}
user_tz = request.env.user.tz or 'Asia/Shanghai'
from pytz import timezone, utc
local_tz = timezone(user_tz)
messages = []
for msg in conv.message_ids:
if msg.create_date:
utc_dt = msg.create_date.replace(tzinfo=utc)
local_dt = utc_dt.astimezone(local_tz)
time_str = local_dt.strftime('%H:%M')
else:
time_str = ''
messages.append({
'id': msg.id,
'role': msg.role,
'content': msg.content,
'date': time_str,
})
return {'messages': messages}
@http.route('/ai/chat/clear', type='json', auth='user', methods=['POST'], csrf=False)
def chat_clear(self, conversation_id):
"""清空对话"""
conv = request.env['ai.conversation'].browse(conversation_id)
if not conv.exists():
return {'error': '对话不存在'}
conv.message_ids.unlink()
return {'success': True}
@http.route('/ai/conversation/create', type='json', auth='user', methods=['POST'], csrf=False)
def conversation_create(self):
"""创建新对话并返回ID"""
provider = request.env['ai.provider'].search([('active', '=', True)], limit=1)
if not provider:
return {'error': '请先在服务商配置中设置 AI 服务'}
conv = request.env['ai.conversation'].create({
'name': '新对话',
'provider_id': provider.id,
})
return {'id': conv.id}
@http.route('/ai/conversation/get_or_create_personal', type='json', auth='user')
def get_or_create_personal(self):
"""获取或创建当前用户的个人对话(浮动聊天用)"""
err = self._check_ai_access()
if err:
return err
conv = request.env['ai.conversation'].search([
('create_uid', '=', request.env.uid),
], limit=1, order='create_date desc')
if not conv:
provider = request.env['ai.provider'].search([('active', '=', True)], limit=1)
if not provider:
return {'error': '请先在服务商配置中设置 AI 服务'}
conv = request.env['ai.conversation'].create({
'name': '个人对话',
'provider_id': provider.id,
})
return {'id': conv.id, 'name': conv.name}
@http.route('/ai/conversation/list', type='json', auth='user')
def conversation_list(self):
"""获取当前用户的所有对话列表"""
err = self._check_ai_access()
if err:
return err
convs = request.env['ai.conversation'].search([
('create_uid', '=', request.env.uid),
], order='create_date desc', limit=50)
return {
'conversations': [{
'id': c.id,
'name': c.name,
'message_count': c.message_count,
} for c in convs]
}
@http.route('/ai/conversation/new', type='json', auth='user', methods=['POST'], csrf=False)
def conversation_new(self):
"""新建对话"""
err = self._check_ai_access()
if err:
return err
provider = request.env['ai.provider'].search([('active', '=', True)], limit=1)
if not provider:
return {'error': '请先在服务商配置中设置 AI 服务'}
conv = request.env['ai.conversation'].create({
'name': '新对话',
'provider_id': provider.id,
})
return {'id': conv.id, 'name': conv.name}
@http.route('/ai/conversation/delete', type='json', auth='user', methods=['POST'], csrf=False)
def conversation_delete(self, conversation_id):
"""删除对话"""
err = self._check_ai_access()
if err:
return err
conv = request.env['ai.conversation'].browse(conversation_id)
if not conv.exists():
return {'error': '对话不存在'}
if conv.create_uid.id != request.env.uid:
return {'error': '只能删除自己的对话'}
conv.unlink()
return {'success': True}
@http.route('/ai/profile/get', type='json', auth='user')
def get_profile(self):
"""获取当前用户的 AI 画像(含记忆摘要)"""
err = self._check_ai_access()
if err:
return err
profile = request.env['ai.user.profile'].get_or_create()
return {
'id': profile.id,
'nickname': profile.nickname or '',
'role': profile.role or '',
'department': profile.department or '',
'style_preference': profile.style_preference or 'concise',
'memory_count': profile.memory_count,
}