from odoo import api, fields, models class LearningCourse(models.Model): _name = 'learning.course' _description = '课程' _inherit = ['mail.thread', 'mail.activity.mixin'] name = fields.Char(string='课程名称', required=True) code = fields.Char(string='课程代码', required=True, index=True) english_name = fields.Char(string='英文名称') credit = fields.Float(string='学分', required=True) exam_type = fields.Selection([ ('exam', '考试'), ('assessment', '考查'), ], string='考核方式') description = fields.Html(string='课程简介') objectives = fields.Html(string='教学目标') state = fields.Selection([ ('draft', '草稿'), ('published', '已发布'), ], default='draft', required=True) # ==================== 关联章节 ==================== chapter_ids = fields.One2many('course.chapter', 'course_id', string='章节') chapter_count = fields.Integer(string='章节数', compute='_compute_chapter_count', store=True) # ==================== 关联教学大纲/教案 ==================== syllabus_ids = fields.One2many('course.syllabus', 'course_id', string='教学大纲/教案') syllabus_count = fields.Integer(string='大纲/教案数', compute='_compute_syllabus_count', store=True) # 按类型统计 syllabus_count_total = fields.Integer(string='大纲总数', compute='_compute_syllabus_count') lesson_plan_count = fields.Integer(string='教案总数', compute='_compute_syllabus_count') # ==================== 统计资源(通过章节关联) ==================== resource_count = fields.Integer(string='资源总数', compute='_compute_resource_count', store=True) video_count = fields.Integer(string='视频数', compute='_compute_resource_count', store=True) doc_count = fields.Integer(string='文档数', compute='_compute_resource_count', store=True) # 汇总所有章节的资源 resource_all_ids = fields.One2many( comodel_name='course.chapter.resource', inverse_name=None, compute='_compute_resource_all_ids', string='资源列表', readonly=True ) @api.depends('chapter_ids', 'chapter_ids.resource_ids') def _compute_resource_all_ids(self): for record in self: # 取出所有章节下的资源记录 all_resources = record.chapter_ids.mapped('resource_ids') record.resource_all_ids = all_resources # ==================== 计算字段方法 ==================== @api.depends('chapter_ids') def _compute_chapter_count(self): for record in self: record.chapter_count = len(record.chapter_ids) @api.depends('syllabus_ids', 'syllabus_ids.syllabus_type') def _compute_syllabus_count(self): for record in self: record.syllabus_count = len(record.syllabus_ids) record.syllabus_count_total = len(record.syllabus_ids.filtered(lambda s: s.syllabus_type == 'syllabus')) record.lesson_plan_count = len(record.syllabus_ids.filtered(lambda s: s.syllabus_type == 'lesson_plan')) @api.depends('chapter_ids.resource_ids', 'chapter_ids.resource_ids.resource_type') def _compute_resource_count(self): for record in self: resources = record.chapter_ids.mapped('resource_ids') record.resource_count = len(resources) record.video_count = len(resources.filtered(lambda r: r.resource_type == 'video')) record.doc_count = len(resources.filtered(lambda r: r.resource_type in ['pdf', 'ppt'])) # ==================== 业务方法 ==================== def action_publish(self): """发布课程""" self.state = 'published' def action_draft(self): """退回草稿""" self.state = 'draft' def action_view_chapters(self): """查看章节""" return { 'type': 'ir.actions.act_window', 'name': '课程章节', 'res_model': 'course.chapter', 'view_mode': 'list,form', 'domain': [('course_id', '=', self.id)], 'context': {'default_course_id': self.id}, } def action_view_syllabus(self): """查看教学大纲/教案""" return { 'type': 'ir.actions.act_window', 'name': '教学大纲/教案', 'res_model': 'course.syllabus', 'view_mode': 'list,form', 'domain': [('course_id', '=', self.id)], 'context': {'default_course_id': self.id}, } def action_view_resources(self): """查看所有资源""" return { 'type': 'ir.actions.act_window', 'name': '教学资源', 'res_model': 'course.chapter.resource', 'view_mode': 'list,form', 'domain': [('chapter_id.course_id', '=', self.id)], }