# -*- coding: utf-8 -*- from odoo import models, fields, api class AiTokenUsage(models.Model): """Token 使用量记录""" _name = 'ai.token.usage' _description = 'AI Token 使用记录' _order = 'create_date desc' user_id = fields.Many2one( 'res.users', string='用户', required=True, default=lambda self: self.env.uid, index=True, ) conversation_id = fields.Many2one( 'ai.conversation', string='对话', ondelete='set null', index=True, ) provider_id = fields.Many2one( 'ai.provider', string='服务商', ondelete='set null', ) model_name = fields.Char(string='模型') prompt_tokens = fields.Integer(string='输入 Token', default=0) completion_tokens = fields.Integer(string='输出 Token', default=0) total_tokens = fields.Integer(string='总 Token', default=0) create_date = fields.Datetime(string='时间', readonly=True) # 汇总统计(SQL视图替代方案:直接在列表中分组展示即可) class AiTokenUsageSummary(models.Model): """用户 Token 汇总(数据库视图)""" _name = 'ai.token.usage.summary' _description = 'AI Token 使用汇总' _auto = False _order = 'total_tokens desc' user_id = fields.Many2one('res.users', string='用户', readonly=True) provider_id = fields.Many2one('ai.provider', string='服务商', readonly=True) model_name = fields.Char(string='模型', readonly=True) call_count = fields.Integer(string='调用次数', readonly=True) prompt_tokens = fields.Integer(string='输入 Token', readonly=True) completion_tokens = fields.Integer(string='输出 Token', readonly=True) total_tokens = fields.Integer(string='总 Token', readonly=True) def init(self): from odoo.tools import table_exists # 依赖表 ai_token_usage 可能尚未创建,跳过 if not table_exists(self.env.cr, 'ai_token_usage'): return self.env.cr.execute(""" DROP VIEW IF EXISTS ai_token_usage_summary; CREATE OR REPLACE VIEW ai_token_usage_summary AS ( SELECT row_number() OVER () AS id, user_id, provider_id, model_name, COUNT(*) AS call_count, SUM(prompt_tokens) AS prompt_tokens, SUM(completion_tokens) AS completion_tokens, SUM(total_tokens) AS total_tokens FROM ai_token_usage GROUP BY user_id, provider_id, model_name ); """)