后端 game_base: - 货币并入 game.rule(rate/note 字段),新增可配置规则类别 game.rule.category(world/faction/character/currency) - 新增「配置」菜单与规则类别配置子项 - /game/api/rules 按类别分组返回,/game/api/currencies 保持兼容 - 列表分组取消等级累计(aggregator=False,适配 Odoo18) - 1.2 pre-migrate 清理旧 game.currency 记录,避免外部ID冲突 前端/官网: - 世界数据大报表(index.html + .wd-* 样式) - 背景 5 板块同步、论坛汉化、过渡资源与 views 拆分(announcement/codex/forum/page/rule/story)
65 lines
2.1 KiB
Python
65 lines
2.1 KiB
Python
# -*- 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
|