# -*- coding: utf-8 -*- from odoo import models, fields, api class GameRule(models.Model): _name = 'game.rule' _description = '规则 / 等级制度 / 货币' _rec_name = 'name' _order = 'category_id, level' category_id = fields.Many2one( 'game.rule.category', string='类别', required=True, index=True, ondelete='restrict', ) level = fields.Integer( string='等级', index=True, aggregator=False, # 分组时不累计 ) name = fields.Char(string='名称', required=True) desc = fields.Html(string='说明') rate = fields.Integer( string='兑换比例', default=1, help='多少单位本货币可兑换 1 单位下一等级货币。例如 100 墟铢 = 1 灵币,则墟铢的 rate 为 100。仅货币类有效。', ) note = fields.Text( string='备注', help='额外说明,仅后台可见(如发行背景、流通范围等)。', ) @api.model def convert(self, amount, from_level, to_level, category_key='currency'): """按等级汇率将 amount 从 from_level 换算为 to_level 货币。 默认只在「货币」类别内换算。汇率方向:低等级 → 高等级 为除以 rate, 高等级 → 低等级 为乘以 rate。最高等级货币(元玺)的 rate 固定为 1。 """ if from_level == to_level: return amount category = self.env['game.rule.category'].sudo().search( [('key', '=', category_key)], limit=1 ) if not category: return amount recs = self.search( [('category_id', '=', category.id)], order='level asc', ) rate_map = {r.level: r.rate or 1 for r in recs} if from_level < to_level: result = amount for lv in range(from_level, to_level): result = result / rate_map.get(lv, 1) return result else: result = amount for lv in range(to_level, from_level): result = result * rate_map.get(lv, 1) return result