Files
2026-08-05 19:20:15 +08:00

70 lines
3.0 KiB
Python

from odoo import fields, models, api
class SchoolProgress(models.Model):
"""学习进展——记录每位学员在每门课程中的学习情况。"""
_name = 'yuthon.school.progress'
_description = '学习进展'
_order = 'course_id, student_id'
_rec_name = 'name'
name = fields.Char(string='名称', compute='_compute_name', store=True)
course_id = fields.Many2one(
'yuthon.school.course', string='课程', required=True, ondelete='cascade')
student_id = fields.Many2one(
'yuthon.school.student', string='学员', required=True, ondelete='cascade')
teacher_id = fields.Many2one(
'res.users', string='任课教师',
related='course_id.teacher_id', readonly=True, store=True)
# 章节进度(基于课程章节完成情况动态计算,仅用于展示,不入库)
chapter_total = fields.Integer(string='章节总数', compute='_compute_chapter_progress')
chapter_done = fields.Integer(string='已完成章节', compute='_compute_chapter_progress')
progress_rate = fields.Float(string='学习进度(%)', compute='_compute_chapter_progress')
# 状态:普通可写字段(搜索/过滤需用 stored 字段),由章节完成情况触发更新
status = fields.Selection(
[('not_started', '未开始'), ('in_progress', '进行中'), ('completed', '已完成')],
string='状态', default='not_started', index=True, required=True)
last_study_date = fields.Date(string='最近学习日期')
score = fields.Float(string='综合得分')
note = fields.Text(string='备注')
active = fields.Boolean(string='启用', default=True)
def _compute_chapter_progress(self):
"""根据课程章节的「已完成学员」计算该学员的进度(展示用)。"""
for r in self:
chapters = r.course_id.chapter_ids if r.course_id else self.env['yuthon.school.course.chapter']
total = len(chapters)
done = sum(1 for c in chapters if r.student_id in c.completed_student_ids)
r.chapter_total = total
r.chapter_done = done
r.progress_rate = (done / total * 100.0) if total else 0.0
def recompute_status(self):
"""依据章节完成情况刷新状态(在章节完成状态变化时调用)。"""
for r in self:
total = r.chapter_total
done = r.chapter_done
if total == 0 or done == 0:
new_status = 'not_started'
elif done >= total:
new_status = 'completed'
else:
new_status = 'in_progress'
if r.status != new_status:
r.write({'status': new_status})
@api.model_create_multi
def create(self, vals_list):
recs = super().create(vals_list)
recs.recompute_status()
return recs
@api.depends('course_id', 'student_id')
def _compute_name(self):
for r in self:
r.name = '%s · %s' % (r.course_id.name or '', r.student_id.name or '')