# -*- coding: utf-8 -*- from odoo import api, fields, models class GameAchievementTemplate(models.Model): """全局成就模板:后台定义,所有玩家共用同一套成就定义。""" _name = 'game.achievement.template' _description = '成就模板' _order = 'sequence, id' _rec_name = 'name' TIER = [ ('bronze', '铜'), ('silver', '银'), ('gold', '金'), ('platinum', '铂金'), ('legend', '传奇'), ] sequence = fields.Integer('排序', default=10, index=True) code = fields.Char('标识', index=True, help='唯一标识,用于代码引用,如 first_land') name = fields.Char('成就名称', required=True, translate=True) icon = fields.Char('图标', help='emoji 或符号,如 star / sprout / lock') tier = fields.Selection(TIER, '品质', default='bronze', index=True) desc = fields.Text('描述', help='解锁条件/说明') target = fields.Integer('目标值', default=1, help='解锁所需进度值,如 10 表示需完成 10 次') points = fields.Integer('成就点数', default=10) active = fields.Boolean('启用', default=True) player_achievement_ids = fields.One2many( 'game.player.achievement', 'template_id', '玩家解锁记录') class GamePlayerAchievement(models.Model): """玩家已解锁/进行中的成就,关联到 hr.employee。""" _name = 'game.player.achievement' _description = '玩家成就' _order = 'template_id, id' _rec_name = 'name' template_id = fields.Many2one( 'game.achievement.template', '成就模板', required=True, ondelete='cascade', index=True) employee_id = fields.Many2one( 'hr.employee', '所属玩家', required=True, ondelete='cascade', index=True) name = fields.Char('名称', related='template_id.name', store=True) icon = fields.Char('图标', related='template_id.icon') tier = fields.Selection( related='template_id.tier', store=True) desc = fields.Text('描述', related='template_id.desc') points = fields.Integer('点数', related='template_id.points') progress = fields.Integer('进度', default=0) target = fields.Integer('目标值', related='template_id.target') unlocked = fields.Boolean('已解锁', default=False) unlock_date = fields.Datetime('解锁时间') @api.model def _update_progress(self, employee_id, template_key, progress): """更新某玩家某成就的进度,达标自动解锁。""" tmpl = self.env['game.achievement.template'].search( [('id', '=', template_key)], limit=1) if not tmpl: return False rec = self.search([ ('employee_id', '=', employee_id), ('template_id', '=', tmpl.id), ], limit=1) if not rec: rec = self.create({ 'employee_id': employee_id, 'template_id': tmpl.id, 'progress': min(progress, tmpl.target), 'unlocked': progress >= tmpl.target, 'unlock_date': fields.Datetime.now() if progress >= tmpl.target else False, }) elif not rec.unlocked: rec.write({ 'progress': min(progress, tmpl.target), 'unlocked': progress >= tmpl.target, }) if rec.unlocked: rec.unlock_date = fields.Datetime.now() return True