新增edu_base、learning_center
This commit is contained in:
parent
a9793e3320
commit
30587b58b1
0
edu_base/__init__.py
Normal file
0
edu_base/__init__.py
Normal file
15
edu_base/__manifest__.py
Normal file
15
edu_base/__manifest__.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
{
|
||||||
|
'name': '教育基础权限',
|
||||||
|
'version': '18.0.1.0.0',
|
||||||
|
'summary': '通用权限组:学生、教师、教务管理员',
|
||||||
|
'description': '统一管理全项目通用角色权限组,供其他业务模块依赖使用',
|
||||||
|
'author': '',
|
||||||
|
'depends': ['base'], # 只依赖系统基础模块
|
||||||
|
'data': [
|
||||||
|
'security/groups.xml',
|
||||||
|
],
|
||||||
|
'installable': True,
|
||||||
|
'auto_install': False, # 不自动安装,手动安装一次即可
|
||||||
|
'application': False,
|
||||||
|
}
|
||||||
BIN
edu_base/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
edu_base/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
26
edu_base/security/groups.xml
Normal file
26
edu_base/security/groups.xml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<!-- 1. 学生组 -->
|
||||||
|
<record id="group_student" model="res.groups">
|
||||||
|
<field name="name">学生</field>
|
||||||
|
<field name="category_id" ref="base.module_category_education"/>
|
||||||
|
<!-- 可选:继承系统基础组 -->
|
||||||
|
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- 2. 教师组 -->
|
||||||
|
<record id="group_teacher" model="res.groups">
|
||||||
|
<field name="name">教师</field>
|
||||||
|
<field name="category_id" ref="base.module_category_education"/>
|
||||||
|
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- 3. 教务管理员 -->
|
||||||
|
<record id="group_edu_admin" model="res.groups">
|
||||||
|
<field name="name">教务管理员</field>
|
||||||
|
<field name="category_id" ref="base.module_category_education"/>
|
||||||
|
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
1
learning_center/__init__.py
Normal file
1
learning_center/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from . import models
|
||||||
34
learning_center/__manifest__.py
Normal file
34
learning_center/__manifest__.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
'name': 'Learning Course',
|
||||||
|
'version': '18.0.1.0.0',
|
||||||
|
'category': 'Education',
|
||||||
|
'summary': '课程管理 - 课程基础信息',
|
||||||
|
'description': """
|
||||||
|
学习中心
|
||||||
|
""",
|
||||||
|
'author': 'hrrr',
|
||||||
|
'depends': [
|
||||||
|
'base',
|
||||||
|
'mail',
|
||||||
|
'student_organization',
|
||||||
|
],
|
||||||
|
'data': [
|
||||||
|
'security/ir.model.access.csv',
|
||||||
|
'security/record_rules.xml',
|
||||||
|
'views/view_learning_course.xml',
|
||||||
|
'views/view_course_chapter.xml',
|
||||||
|
'views/view_course_chapter_resource.xml',
|
||||||
|
'views/view_course_homework.xml',
|
||||||
|
'views/view_homework_submit.xml',
|
||||||
|
'views/view_course_score_item.xml',
|
||||||
|
'views/view_course_syllabus.xml',
|
||||||
|
'views/view_course_teaching_class.xml',
|
||||||
|
'views/view_course_student_score.xml',
|
||||||
|
'views/view_course_homework_student.xml',
|
||||||
|
'views/view_teach_class.xml',
|
||||||
|
|
||||||
|
|
||||||
|
],
|
||||||
|
'installable': True,
|
||||||
|
'application': True,
|
||||||
|
}
|
||||||
BIN
learning_center/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
learning_center/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
10
learning_center/models/__init__.py
Normal file
10
learning_center/models/__init__.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from . import learning_course
|
||||||
|
from . import course_chapter
|
||||||
|
from . import course_chapter_resource
|
||||||
|
from . import course_syllabus
|
||||||
|
from . import course_homework
|
||||||
|
from . import course_homework_submit
|
||||||
|
from . import course_score_item
|
||||||
|
from . import course_student_score
|
||||||
|
from . import course_teaching_class
|
||||||
|
from . import teach_class
|
||||||
BIN
learning_center/models/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
learning_center/models/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
learning_center/models/__pycache__/teach_class.cpython-312.pyc
Normal file
BIN
learning_center/models/__pycache__/teach_class.cpython-312.pyc
Normal file
Binary file not shown.
32
learning_center/models/course_chapter.py
Normal file
32
learning_center/models/course_chapter.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
from odoo import api, fields, models
|
||||||
|
|
||||||
|
class CourseChapter(models.Model):
|
||||||
|
_name = 'course.chapter'
|
||||||
|
_description = '课程章节'
|
||||||
|
_rec_name = 'name'
|
||||||
|
_inherit = ['mail.thread']
|
||||||
|
_order = 'course_id, sequence, id'
|
||||||
|
|
||||||
|
name = fields.Char(string='章节名称', required=True)
|
||||||
|
sequence = fields.Integer(string='序号', default=10)
|
||||||
|
description = fields.Html(string='章节描述')
|
||||||
|
course_id = fields.Many2one('learning.course', string='所属课程', required=True, ondelete='cascade')
|
||||||
|
is_published = fields.Boolean(string='是否发布', default=True)
|
||||||
|
resource_count = fields.Integer(string='资源数量', compute='_compute_resource_count')
|
||||||
|
video_count = fields.Integer(string='视频数量', compute='_compute_resource_count')
|
||||||
|
doc_count = fields.Integer(string='文档数量', compute='_compute_resource_count')
|
||||||
|
resource_ids = fields.One2many('course.chapter.resource', 'chapter_id', string='章节资源')
|
||||||
|
# homework_ids = fields.One2many('course.homework', 'chapter_id', string='关联作业')
|
||||||
|
|
||||||
|
syllabus_ids = fields.One2many('course.syllabus', 'chapter_id', string='教学大纲/教案')
|
||||||
|
def _compute_resource_count(self):
|
||||||
|
for record in self:
|
||||||
|
record.resource_count = len(record.resource_ids)
|
||||||
|
record.video_count = len(record.resource_ids.filtered(lambda r: r.resource_type == 'video'))
|
||||||
|
record.doc_count = len(record.resource_ids.filtered(lambda r: r.resource_type in ['pdf', 'ppt']))
|
||||||
|
|
||||||
|
def action_publish(self):
|
||||||
|
self.is_published = True
|
||||||
|
|
||||||
|
def action_hide(self):
|
||||||
|
self.is_published = False
|
||||||
80
learning_center/models/course_chapter_resource.py
Normal file
80
learning_center/models/course_chapter_resource.py
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
from odoo import api, fields, models
|
||||||
|
|
||||||
|
class CourseChapterResource(models.Model):
|
||||||
|
_name = 'course.chapter.resource'
|
||||||
|
_description = '章节资源'
|
||||||
|
_rec_name = 'name'
|
||||||
|
_order = 'chapter_id, sequence, id'
|
||||||
|
|
||||||
|
name = fields.Char(string='资源名称', required=True)
|
||||||
|
sequence = fields.Integer(string='序号', default=10)
|
||||||
|
description = fields.Text(string='备注说明')
|
||||||
|
chapter_id = fields.Many2one('course.chapter', string='所属章节', required=True)
|
||||||
|
course_id = fields.Many2one(related="chapter_id.course_id", string='所属课程', required=True, ondelete='cascade')
|
||||||
|
chapter_name = fields.Char(related="chapter_id.name", string="章节名称", readonly=True)
|
||||||
|
chapter_sequence = fields.Integer(related="chapter_id.sequence", string="章节序号", readonly=True)
|
||||||
|
chapter_is_published = fields.Boolean(related="chapter_id.is_published", string="章节发布状态", readonly=True)
|
||||||
|
resource_type = fields.Selection([
|
||||||
|
('video', '视频'),
|
||||||
|
('pdf', 'PDF文档'),
|
||||||
|
('ppt', 'PPT演示文稿'),
|
||||||
|
('other', '其他'),
|
||||||
|
], string='资源类型', required=True)
|
||||||
|
video_file = fields.Binary(string='视频文件', attachment=True)
|
||||||
|
video_filename = fields.Char(string='视频文件名')
|
||||||
|
video_url = fields.Char(string='视频链接')
|
||||||
|
video_duration = fields.Integer(string='时长(秒)')
|
||||||
|
doc_file = fields.Binary(string='文档文件', attachment=True)
|
||||||
|
doc_filename = fields.Char(string='文档文件名')
|
||||||
|
doc_page_count = fields.Integer(string='页数')
|
||||||
|
# 添加教学班关联(可选,资源可共享给所有教学班)
|
||||||
|
teaching_class_id = fields.Many2one('course.teaching_class', string='教学班',
|
||||||
|
ondelete='cascade')
|
||||||
|
preview_url = fields.Char(string='预览链接', compute='_compute_preview_url')
|
||||||
|
is_hidden = fields.Boolean(string='是否隐藏', default=False)
|
||||||
|
|
||||||
|
course_name = fields.Char(related="chapter_id.course_id.name", string="课程名称", readonly=True)
|
||||||
|
course_code = fields.Char(related="chapter_id.course_id.code", string="课程代码", readonly=True)
|
||||||
|
course_credit = fields.Float(related="chapter_id.course_id.credit", string="学分", readonly=True)
|
||||||
|
|
||||||
|
# 新增:批量上传附件字段(核心)
|
||||||
|
resource_attachment_ids = fields.Many2many(
|
||||||
|
comodel_name='ir.attachment',
|
||||||
|
relation='course_chapter_resource_attachment_rel',
|
||||||
|
column1='resource_id',
|
||||||
|
column2='attachment_id',
|
||||||
|
string='批量上传资源附件',
|
||||||
|
)
|
||||||
|
# 新增:附件数量统计(可选,用于列表显示)
|
||||||
|
attachment_count = fields.Integer(string="附件数", compute="_compute_attachment_count")
|
||||||
|
|
||||||
|
@api.depends('resource_attachment_ids')
|
||||||
|
def _compute_attachment_count(self):
|
||||||
|
for rec in self:
|
||||||
|
rec.attachment_count = len(rec.resource_attachment_ids)
|
||||||
|
|
||||||
|
def _compute_preview_url(self):
|
||||||
|
for record in self:
|
||||||
|
# 优先使用批量附件中的第一个文件作为预览链接
|
||||||
|
if record.resource_attachment_ids:
|
||||||
|
first_attachment = record.resource_attachment_ids[0]
|
||||||
|
record.preview_url = f'/web/content/{first_attachment.id}?download=false'
|
||||||
|
elif record.resource_type == 'video' and record.video_file:
|
||||||
|
record.preview_url = f'/web/content/course.chapter.resource/{record.id}/video_file'
|
||||||
|
elif record.resource_type in ['pdf', 'ppt'] and record.doc_file:
|
||||||
|
record.preview_url = f'/web/content/course.chapter.resource/{record.id}/doc_file'
|
||||||
|
else:
|
||||||
|
record.preview_url = False
|
||||||
|
|
||||||
|
def action_toggle_hide(self):
|
||||||
|
self.is_hidden = not self.is_hidden
|
||||||
|
|
||||||
|
def action_preview(self):
|
||||||
|
self.ensure_one()
|
||||||
|
if self.preview_url:
|
||||||
|
return {
|
||||||
|
'type': 'ir.actions.act_url',
|
||||||
|
'url': self.preview_url,
|
||||||
|
'target': 'new'
|
||||||
|
}
|
||||||
|
return False
|
||||||
179
learning_center/models/course_homework.py
Normal file
179
learning_center/models/course_homework.py
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
from odoo import api, fields, models
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
|
class CourseHomework(models.Model):
|
||||||
|
_name = 'course.homework'
|
||||||
|
_description = '课程作业'
|
||||||
|
_rec_name = 'name'
|
||||||
|
_inherit = ['mail.thread']
|
||||||
|
_order = 'course_id, deadline, id'
|
||||||
|
|
||||||
|
name = fields.Char(string='作业名称', required=True)
|
||||||
|
description = fields.Html(string='作业描述')
|
||||||
|
requirement = fields.Html(string='作业要求')
|
||||||
|
course_id = fields.Many2one('learning.course', string='所属课程', required=True, ondelete='cascade')
|
||||||
|
chapter_id = fields.Many2one('course.chapter', string='关联章节')
|
||||||
|
total_score = fields.Float(string='作业总分', default=100.0, required=True)
|
||||||
|
publish_time = fields.Datetime(string='发布时间', default=fields.Datetime.now)
|
||||||
|
deadline = fields.Datetime(string='提交截止时间', required=True)
|
||||||
|
late_deadline = fields.Datetime(string='补交截止时间')
|
||||||
|
state = fields.Selection([
|
||||||
|
('draft', '草稿'),
|
||||||
|
('published', '已发布'),
|
||||||
|
('closed', '已关闭'),
|
||||||
|
], string='状态', default='draft', tracking=True)
|
||||||
|
is_submit_open = fields.Boolean(string='提交通道开启', default=True)
|
||||||
|
allow_late = fields.Boolean(string='允许补交', default=False)
|
||||||
|
total_students = fields.Integer(string='应提交人数', compute='_compute_submit_stats')
|
||||||
|
submitted_count = fields.Integer(string='已提交人数', compute='_compute_submit_stats')
|
||||||
|
late_count = fields.Integer(string='逾期提交人数', compute='_compute_submit_stats')
|
||||||
|
unsubmitted_count = fields.Integer(string='未提交人数', compute='_compute_submit_stats')
|
||||||
|
# 添加教学班关联
|
||||||
|
teaching_class_id = fields.Many2one('course.teaching_class', string='教学班',
|
||||||
|
ondelete='cascade', domain="[('course_id', '=', course_id)]")
|
||||||
|
submit_ids = fields.One2many('course.homework.submit', 'homework_id', string='提交记录')
|
||||||
|
score_item_ids = fields.One2many('course.score.item', 'homework_id', string='提交记录')
|
||||||
|
|
||||||
|
def _compute_submit_stats(self):
|
||||||
|
for record in self:
|
||||||
|
# 按教学班 + 选课状态筛选学生
|
||||||
|
domain = [('state', '=', 'enrolled')]
|
||||||
|
if record.teaching_class_id:
|
||||||
|
# 优先按当前作业所属教学班统计(核心修正)
|
||||||
|
domain.append(('teaching_class_id', '=', record.teaching_class_id.id))
|
||||||
|
else:
|
||||||
|
# 无教学班时,回退到整门课程统计
|
||||||
|
domain.append(('course_id', '=', record.course_id.id))
|
||||||
|
|
||||||
|
enrollments = self.env['course.teaching_class.enrollment'].search(domain)
|
||||||
|
student_ids = enrollments.mapped('student_id')
|
||||||
|
record.total_students = len(student_ids)
|
||||||
|
|
||||||
|
# 该作业所有提交记录
|
||||||
|
base_domain = [('homework_id', '=', record.id)]
|
||||||
|
all_submit = self.env['course.homework.submit'].search(base_domain)
|
||||||
|
total_submit = len(all_submit)
|
||||||
|
|
||||||
|
deadline_val = record.deadline
|
||||||
|
if deadline_val:
|
||||||
|
# 按时提交
|
||||||
|
on_time_submit = all_submit.filtered(lambda s: s.submit_time and s.submit_time <= deadline_val)
|
||||||
|
# 逾期提交
|
||||||
|
late_submit = all_submit.filtered(lambda s: s.submit_time and s.submit_time > deadline_val)
|
||||||
|
record.submitted_count = len(on_time_submit)
|
||||||
|
record.late_count = len(late_submit)
|
||||||
|
else:
|
||||||
|
record.submitted_count = total_submit
|
||||||
|
record.late_count = 0
|
||||||
|
|
||||||
|
# 未提交 = 班级总人数 - 所有提交人数
|
||||||
|
record.unsubmitted_count = record.total_students - total_submit
|
||||||
|
|
||||||
|
def action_publish(self):
|
||||||
|
self.state = 'published'
|
||||||
|
self.publish_time = fields.Datetime.now()
|
||||||
|
|
||||||
|
def action_draft(self):
|
||||||
|
self.state = 'draft'
|
||||||
|
|
||||||
|
def action_close(self):
|
||||||
|
self.state = 'closed'
|
||||||
|
self.is_submit_open = False
|
||||||
|
|
||||||
|
@api.constrains('deadline', 'late_deadline')
|
||||||
|
def _check_deadline(self):
|
||||||
|
for record in self:
|
||||||
|
if record.late_deadline and record.late_deadline < record.deadline:
|
||||||
|
raise ValidationError('补交截止时间必须晚于提交截止时间')
|
||||||
|
|
||||||
|
def _get_current_student(self):
|
||||||
|
"""获取当前登录的学生"""
|
||||||
|
student = self.env['student.info'].search([('user_id', '=', self.env.uid)], limit=1)
|
||||||
|
return student
|
||||||
|
|
||||||
|
# 当前学生的提交记录
|
||||||
|
my_submit_id = fields.Many2one('course.homework.submit', string='我的提交',
|
||||||
|
compute='_compute_my_submit')
|
||||||
|
my_submit_state = fields.Char(string='提交状态', compute='_compute_my_submit')
|
||||||
|
my_submit_time = fields.Datetime(string='提交时间', compute='_compute_my_submit')
|
||||||
|
my_score = fields.Float(string='我的得分', compute='_compute_my_submit')
|
||||||
|
my_grade_level = fields.Char(string='我的等级', compute='_compute_my_submit')
|
||||||
|
my_comment = fields.Html(string='我的评语', compute='_compute_my_submit')
|
||||||
|
my_submit_file = fields.Binary(string='我的提交文件', compute='_compute_my_submit')
|
||||||
|
my_submit_filename = fields.Char(string='文件名', compute='_compute_my_submit')
|
||||||
|
my_submit_content = fields.Html(string='提交内容', compute='_compute_my_submit')
|
||||||
|
|
||||||
|
# 提交状态(用于前端显示)
|
||||||
|
submit_state = fields.Selection([
|
||||||
|
('not_submitted', '未提交'),
|
||||||
|
('submitted', '已提交'),
|
||||||
|
('graded', '已批改'),
|
||||||
|
('late', '逾期提交'),
|
||||||
|
], string='提交状态', compute='_compute_my_submit')
|
||||||
|
|
||||||
|
# 是否可以提交
|
||||||
|
can_submit = fields.Boolean(string='可以提交', compute='_compute_can_submit')
|
||||||
|
|
||||||
|
@api.depends('submit_ids')
|
||||||
|
def _compute_my_submit(self):
|
||||||
|
for record in self:
|
||||||
|
student = self._get_current_student()
|
||||||
|
if student:
|
||||||
|
submit = record.submit_ids.filtered(lambda s: s.student_id == student)
|
||||||
|
if submit:
|
||||||
|
record.my_submit_id = submit.id
|
||||||
|
record.my_submit_state = submit.state
|
||||||
|
record.my_submit_time = submit.submit_time
|
||||||
|
record.my_score = submit.score
|
||||||
|
record.my_grade_level = submit.grade_level
|
||||||
|
record.my_comment = submit.comment
|
||||||
|
record.my_submit_file = submit.submit_file
|
||||||
|
record.my_submit_filename = submit.submit_filename
|
||||||
|
record.my_submit_content = submit.submit_content
|
||||||
|
|
||||||
|
# 计算提交状态
|
||||||
|
if submit.state == 'graded':
|
||||||
|
record.submit_state = 'graded'
|
||||||
|
elif submit.is_late:
|
||||||
|
record.submit_state = 'late'
|
||||||
|
else:
|
||||||
|
record.submit_state = 'submitted'
|
||||||
|
else:
|
||||||
|
record.submit_state = 'not_submitted'
|
||||||
|
else:
|
||||||
|
record.submit_state = 'not_submitted'
|
||||||
|
|
||||||
|
def _compute_can_submit(self):
|
||||||
|
for record in self:
|
||||||
|
# 作业已发布、提交通道开启、未截止、且未提交
|
||||||
|
can = (record.state == 'published' and
|
||||||
|
record.is_submit_open and
|
||||||
|
record.deadline and
|
||||||
|
record.deadline > fields.Datetime.now() and
|
||||||
|
record.my_submit_state != 'submitted' and
|
||||||
|
record.my_submit_state != 'graded')
|
||||||
|
record.can_submit = can
|
||||||
|
|
||||||
|
def action_submit_homework(self):
|
||||||
|
"""学生提交作业"""
|
||||||
|
self.ensure_one()
|
||||||
|
student = self._get_current_student()
|
||||||
|
if not student:
|
||||||
|
raise ValidationError('请先关联学生信息')
|
||||||
|
|
||||||
|
# 检查提交权限
|
||||||
|
if not self.can_submit:
|
||||||
|
raise ValidationError('当前无法提交作业')
|
||||||
|
|
||||||
|
# 打开提交表单
|
||||||
|
return {
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
'name': '提交作业',
|
||||||
|
'res_model': 'course.homework.submit',
|
||||||
|
'view_mode': 'form',
|
||||||
|
'target': 'new',
|
||||||
|
'context': {
|
||||||
|
'default_homework_id': self.id,
|
||||||
|
'default_student_id': student.id,
|
||||||
|
},
|
||||||
|
}
|
||||||
102
learning_center/models/course_homework_submit.py
Normal file
102
learning_center/models/course_homework_submit.py
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
from odoo import api, fields, models
|
||||||
|
|
||||||
|
class CourseHomeworkSubmit(models.Model):
|
||||||
|
_name = 'course.homework.submit'
|
||||||
|
_description = '作业提交记录'
|
||||||
|
_rec_name = 'display_name'
|
||||||
|
_inherit = ['mail.thread']
|
||||||
|
_order = 'homework_id, student_id'
|
||||||
|
|
||||||
|
display_name = fields.Char(string='显示名称', compute='_compute_display_name', store=True)
|
||||||
|
student_id = fields.Many2one('student.info', string='学生', required=True)
|
||||||
|
homework_id = fields.Many2one('course.homework', string='作业', required=True, ondelete='cascade')
|
||||||
|
@api.depends('homework_id.name', 'student_id.stu_name')
|
||||||
|
def _compute_display_name(self):
|
||||||
|
for record in self:
|
||||||
|
record.display_name = f"{record.student_id.stu_name} - {record.homework_id.name}"
|
||||||
|
|
||||||
|
course_name = fields.Char(related="homework_id.course_id.name", string="课程名称", readonly=True)
|
||||||
|
course_code = fields.Char(related="homework_id.course_id.code", string="课程代码", readonly=True)
|
||||||
|
course_credit = fields.Float(related="homework_id.course_id.credit", string="学分", readonly=True)
|
||||||
|
|
||||||
|
homework_name = fields.Char(related="homework_id.name", string="作业名称", readonly=True)
|
||||||
|
homework_total_score = fields.Float(related="homework_id.total_score", string="作业总分", readonly=True)
|
||||||
|
homework_deadline = fields.Datetime(related="homework_id.deadline", string="截止时间", readonly=True)
|
||||||
|
homework_late_deadline = fields.Datetime(related="homework_id.late_deadline", string="补交截止时间", readonly=True)
|
||||||
|
|
||||||
|
student_name = fields.Char(related="student_id.stu_name", string="姓名", readonly=True)
|
||||||
|
student_no = fields.Char(related="student_id.stu_num", string="学号", readonly=True)
|
||||||
|
student_class_id = fields.Many2one(related="student_id.class_id", string="班级", readonly=True)
|
||||||
|
student_major_id = fields.Many2one(related="student_id.major_id", string="专业", readonly=True)
|
||||||
|
student_phone = fields.Char(related="student_id.stu_phone", string="手机号", readonly=True)
|
||||||
|
submit_file = fields.Binary(string='提交文件', attachment=True)
|
||||||
|
submit_filename = fields.Char(string='文件名')
|
||||||
|
submit_content = fields.Html(string='提交内容')
|
||||||
|
submit_time = fields.Datetime(string='提交时间')
|
||||||
|
score = fields.Float(string='得分')
|
||||||
|
comment = fields.Html(string='批改评语')
|
||||||
|
grader_id = fields.Many2one('res.users', string='批改人')
|
||||||
|
grade_time = fields.Datetime(string='批改时间')
|
||||||
|
state = fields.Selection([
|
||||||
|
('submitted', '已提交'),
|
||||||
|
('graded', '已批改'),
|
||||||
|
], string='状态', default='submitted')
|
||||||
|
is_late = fields.Boolean(string='是否逾期', compute='_compute_is_late')
|
||||||
|
|
||||||
|
|
||||||
|
def _compute_is_late(self):
|
||||||
|
for record in self:
|
||||||
|
deadline = record.homework_id.deadline
|
||||||
|
if deadline and record.submit_time:
|
||||||
|
record.is_late = record.submit_time > deadline
|
||||||
|
else:
|
||||||
|
record.is_late = False
|
||||||
|
|
||||||
|
def action_grade(self):
|
||||||
|
self.state = 'graded'
|
||||||
|
self.grade_time = fields.Datetime.now()
|
||||||
|
|
||||||
|
def action_regrade(self):
|
||||||
|
self.state = 'submitted'
|
||||||
|
self.grade_time = False
|
||||||
|
|
||||||
|
# 在 CourseHomeworkSubmit 类中添加
|
||||||
|
grade_level = fields.Selection([
|
||||||
|
('A', '优秀(A)'),
|
||||||
|
('B', '良好(B)'),
|
||||||
|
('C', '中等(C)'),
|
||||||
|
('D', '及格(D)'),
|
||||||
|
('F', '不及格(F)'),
|
||||||
|
], string='等级', compute='_compute_grade_level', store=True)
|
||||||
|
|
||||||
|
@api.depends('score', 'homework_id.total_score')
|
||||||
|
def _compute_grade_level(self):
|
||||||
|
for record in self:
|
||||||
|
if record.score and record.homework_id.total_score:
|
||||||
|
percent = record.score / record.homework_id.total_score * 100
|
||||||
|
if percent >= 90:
|
||||||
|
record.grade_level = 'A'
|
||||||
|
elif percent >= 80:
|
||||||
|
record.grade_level = 'B'
|
||||||
|
elif percent >= 70:
|
||||||
|
record.grade_level = 'C'
|
||||||
|
elif percent >= 60:
|
||||||
|
record.grade_level = 'D'
|
||||||
|
else:
|
||||||
|
record.grade_level = 'F'
|
||||||
|
else:
|
||||||
|
record.grade_level = False
|
||||||
|
|
||||||
|
# class CourseHomeworkSubmitBatchGrade(models.TransientModel):
|
||||||
|
# _name = 'course.homework.submit.batch.grade'
|
||||||
|
# _description = '作业批量批改向导'
|
||||||
|
#
|
||||||
|
# homework_id = fields.Many2one('course.homework', string='作业')
|
||||||
|
# total_count = fields.Integer(string='待批改总数')
|
||||||
|
# score = fields.Float(string='统一分数')
|
||||||
|
# comment = fields.Text(string='统一评语')
|
||||||
|
#
|
||||||
|
# # 批量批改执行方法
|
||||||
|
# def action_batch_grade(self):
|
||||||
|
# # 自行补充批量更新分数、评语、状态的业务逻辑
|
||||||
|
# return {'type': 'ir.actions.act_window_close'}
|
||||||
54
learning_center/models/course_score_item.py
Normal file
54
learning_center/models/course_score_item.py
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
from odoo import api, fields, models
|
||||||
|
|
||||||
|
class CourseScoreItem(models.Model):
|
||||||
|
_name = 'course.score.item'
|
||||||
|
_description = '成绩项目'
|
||||||
|
_rec_name = 'name'
|
||||||
|
_order = 'course_id, weight desc, id'
|
||||||
|
_inherit = ['mail.thread']
|
||||||
|
|
||||||
|
|
||||||
|
name = fields.Char(string='项目名称', required=True)
|
||||||
|
description = fields.Char(string='项目描述')
|
||||||
|
course_id = fields.Many2one('learning.course', string='课程', required=True, ondelete='cascade')
|
||||||
|
course_name = fields.Char(related="course_id.name", string="课程名称", readonly=True)
|
||||||
|
course_code = fields.Char(related="course_id.code", string="课程代码", readonly=True)
|
||||||
|
course_credit = fields.Float(related="course_id.credit", string="学分", readonly=True)
|
||||||
|
course_exam_type = fields.Selection(related="course_id.exam_type", string="考核方式", readonly=True)
|
||||||
|
homework_id = fields.Many2one('course.homework', string='作业', required=True, ondelete='cascade')
|
||||||
|
sequence = fields.Integer(string="排序", default=10)
|
||||||
|
score_type = fields.Selection([
|
||||||
|
('homework', '作业'),
|
||||||
|
('exam', '考试'),
|
||||||
|
('experiment', '实验'),
|
||||||
|
('attendance', '考勤'),
|
||||||
|
('midterm', '期中考试'),
|
||||||
|
('final', '期末考试'),
|
||||||
|
('other', '其他'),
|
||||||
|
], string='成绩类型', required=True)
|
||||||
|
weight = fields.Float(string='权重(%)', required=True)
|
||||||
|
full_score = fields.Float(string='满分', default=100.0)
|
||||||
|
is_active = fields.Boolean(string='是否启用', default=True)
|
||||||
|
homework_ids = fields.Many2many('course.homework', string='关联作业')
|
||||||
|
|
||||||
|
# 统计字段
|
||||||
|
student_count = fields.Integer(string='学生人数', compute='_compute_stats')
|
||||||
|
avg_score = fields.Float(string='平均分', compute='_compute_stats')
|
||||||
|
max_score = fields.Float(string='最高分', compute='_compute_stats')
|
||||||
|
min_score = fields.Float(string='最低分', compute='_compute_stats')
|
||||||
|
score_detail_ids = fields.One2many('course.student.score.detail', 'score_item_id', string='成绩明细')
|
||||||
|
|
||||||
|
def action_toggle_active(self):
|
||||||
|
for record in self:
|
||||||
|
record.is_active = not record.is_active
|
||||||
|
|
||||||
|
def _compute_stats(self):
|
||||||
|
for record in self:
|
||||||
|
details = self.env['course.student.score.detail'].search([
|
||||||
|
('score_item_id', '=', record.id)
|
||||||
|
])
|
||||||
|
scores = details.mapped('score')
|
||||||
|
record.student_count = len(details)
|
||||||
|
record.avg_score = sum(scores) / len(scores) if scores else 0
|
||||||
|
record.max_score = max(scores) if scores else 0
|
||||||
|
record.min_score = min(scores) if scores else 0
|
||||||
112
learning_center/models/course_student_score.py
Normal file
112
learning_center/models/course_student_score.py
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
from odoo import api, fields, models
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
class CourseStudentScore(models.Model):
|
||||||
|
_name = 'course.student.score'
|
||||||
|
_description = '学生成绩'
|
||||||
|
_rec_name = 'display_name'
|
||||||
|
_order = 'course_id, student_id'
|
||||||
|
_inherit = ['mail.thread']
|
||||||
|
display_name = fields.Char(string='显示名称', compute='_compute_display_name', store=True)
|
||||||
|
|
||||||
|
@api.depends('course_name', 'stu_name')
|
||||||
|
def _compute_display_name(self):
|
||||||
|
for record in self:
|
||||||
|
record.display_name = f"{record.stu_name} - {record.course_name}"
|
||||||
|
|
||||||
|
course_id = fields.Many2one('learning.course', string='课程', required=True, ondelete='cascade')
|
||||||
|
# 课程扩展只读字段(替代视图嵌套写法)
|
||||||
|
course_code = fields.Char(string="课程代码", related="course_id.code", readonly=True)
|
||||||
|
course_credit = fields.Float(string="学分", related="course_id.credit", readonly=True)
|
||||||
|
course_exam_type = fields.Selection(string="考核方式", related="course_id.exam_type", readonly=True)
|
||||||
|
course_name = fields.Char(related='course_id.name', string='课程', required=True, ondelete='cascade')
|
||||||
|
student_id = fields.Many2one('student.info', string='学生', required=True)
|
||||||
|
student_no = fields.Char(string="学号", related="student_id.stu_num", readonly=True)
|
||||||
|
student_class_id = fields.Many2one( string="班级", related="student_id.class_id", readonly=True)
|
||||||
|
student_major_id = fields.Many2one( string="专业", related="student_id.major_id", readonly=True)
|
||||||
|
stu_name=fields.Char(related='student_id.stu_name',required=True, ondelete='cascade',string='学生姓名')
|
||||||
|
score_ids = fields.One2many('course.student.score.detail', 'student_score_id', string='成绩明细')
|
||||||
|
teaching_class_id=fields.Many2one('course.teaching_class',string='教学班')
|
||||||
|
# 教学班相关只读关联字段
|
||||||
|
teaching_class_name = fields.Char(string="教学班名称", related="teaching_class_id.display_name", readonly=True)
|
||||||
|
teaching_class_semester = fields.Selection(string="学期", related="teaching_class_id.semester", readonly=True)
|
||||||
|
teaching_class_main_teacher = fields.Many2one('hr.employee', string="主讲教师",
|
||||||
|
related="teaching_class_id.main_teacher_id", readonly=True)
|
||||||
|
total_score = fields.Float(string='综合成绩', compute='_compute_total_score', store=True)
|
||||||
|
|
||||||
|
grade_level = fields.Selection([
|
||||||
|
('A', '优秀(A)'),
|
||||||
|
('B', '良好(B)'),
|
||||||
|
('C', '中等(C)'),
|
||||||
|
('D', '及格(D)'),
|
||||||
|
('F', '不及格(F)'),
|
||||||
|
], string='等级', compute='_compute_total_score', store=True)
|
||||||
|
|
||||||
|
@api.depends('score_ids.score', 'score_ids.weight')
|
||||||
|
def _compute_total_score(self):
|
||||||
|
for record in self:
|
||||||
|
total = 0.0
|
||||||
|
for detail in record.score_ids:
|
||||||
|
if detail.score and detail.weight:
|
||||||
|
total += detail.score * detail.weight / 100
|
||||||
|
record.total_score = round(total, 2)
|
||||||
|
|
||||||
|
if record.total_score >= 90:
|
||||||
|
record.grade_level = 'A'
|
||||||
|
elif record.total_score >= 80:
|
||||||
|
record.grade_level = 'B'
|
||||||
|
elif record.total_score >= 70:
|
||||||
|
record.grade_level = 'C'
|
||||||
|
elif record.total_score >= 60:
|
||||||
|
record.grade_level = 'D'
|
||||||
|
else:
|
||||||
|
record.grade_level = 'F'
|
||||||
|
|
||||||
|
|
||||||
|
class CourseStudentScoreDetail(models.Model):
|
||||||
|
_name = 'course.student.score.detail'
|
||||||
|
_description = '学生成绩明细'
|
||||||
|
_rec_name = 'display_name'
|
||||||
|
_order = 'student_score_id, score_item_id'
|
||||||
|
_inherit = ['mail.thread']
|
||||||
|
display_name = fields.Char(string='显示名称', compute='_compute_display_name', store=True)
|
||||||
|
@api.depends('student_score_displayname', 'score_item_id.name')
|
||||||
|
def _compute_display_name(self):
|
||||||
|
for record in self:
|
||||||
|
record.display_name = f"{record.student_score_displayname} - {record.score_item_id.name}"
|
||||||
|
# 关联学生成绩主表
|
||||||
|
student_score_id = fields.Many2one('course.student.score', string='学生成绩', required=True, ondelete='cascade')
|
||||||
|
student_score_displayname=fields.Char(related='student_score_id.display_name',required=True, ondelete='cascade',string='显示名称')
|
||||||
|
# 关联成绩项目
|
||||||
|
score_item_id = fields.Many2one('course.score.item', string='成绩项目', required=True, ondelete='restrict')
|
||||||
|
|
||||||
|
# 得分
|
||||||
|
score = fields.Float(string='得分', help='该项目实际得分')
|
||||||
|
|
||||||
|
# 从成绩项目继承的字段(用于显示和计算)
|
||||||
|
weight = fields.Float(string='权重(%)', related='score_item_id.weight', store=True, readonly=True)
|
||||||
|
full_score = fields.Float(string='满分', related='score_item_id.full_score', store=True, readonly=True)
|
||||||
|
score_type = fields.Selection(string='成绩类型', related='score_item_id.score_type', store=True, readonly=True)
|
||||||
|
# 备注
|
||||||
|
remark = fields.Char(string='备注')
|
||||||
|
# 关联课程和学生(用于视图显示)
|
||||||
|
course_id = fields.Many2one('learning.course', string='课程', related='student_score_id.course_id', store=True,
|
||||||
|
readonly=True)
|
||||||
|
student_id = fields.Many2one('student.info', string='学生', related='student_score_id.student_id', store=True,
|
||||||
|
readonly=True)
|
||||||
|
# 完成率(得分/满分)
|
||||||
|
completion_rate = fields.Float(string='完成率(%)', compute='_compute_completion_rate', store=True)
|
||||||
|
@api.depends('score', 'full_score')
|
||||||
|
def _compute_completion_rate(self):
|
||||||
|
for record in self:
|
||||||
|
if record.full_score and record.score:
|
||||||
|
record.completion_rate = round(record.score / record.full_score * 100, 1)
|
||||||
|
else:
|
||||||
|
record.completion_rate = 0.0
|
||||||
|
|
||||||
|
@api.constrains('score', 'full_score')
|
||||||
|
def _check_score(self):
|
||||||
|
for record in self:
|
||||||
|
if record.score and record.full_score and record.score > record.full_score:
|
||||||
|
raise ValidationError(f'得分({record.score})不能超过满分({record.full_score})')
|
||||||
|
if record.score and record.score < 0:
|
||||||
|
raise ValidationError('得分不能为负数')
|
||||||
80
learning_center/models/course_syllabus.py
Normal file
80
learning_center/models/course_syllabus.py
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
from odoo import api, fields, models
|
||||||
|
from odoo.tools import human_size
|
||||||
|
import base64
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
class CourseSyllabus(models.Model):
|
||||||
|
_name = 'course.syllabus'
|
||||||
|
_description = '教学大纲/教案'
|
||||||
|
_rec_name = 'title'
|
||||||
|
_order = 'course_id, syllabus_type, version desc'
|
||||||
|
_inherit = ['mail.thread']
|
||||||
|
|
||||||
|
title = fields.Char(string='标题', required=True)
|
||||||
|
syllabus_type = fields.Selection([
|
||||||
|
('syllabus', '教学大纲'),
|
||||||
|
('lesson_plan', '教案'),
|
||||||
|
], string='类型', required=True)
|
||||||
|
course_id = fields.Many2one('learning.course', string='所属课程', required=True, ondelete='cascade')
|
||||||
|
course_name = fields.Char(related="course_id.name", string="课程名称", readonly=True)
|
||||||
|
course_code = fields.Char(related="course_id.code", string="课程代码", readonly=True)
|
||||||
|
course_credit = fields.Float(related="course_id.credit", string="学分", readonly=True)
|
||||||
|
course_exam_type = fields.Selection(related="course_id.exam_type", string="考核方式", readonly=True)
|
||||||
|
chapter_id = fields.Many2one('course.chapter', string='关联章节')
|
||||||
|
chapter_name = fields.Char(related="chapter_id.name", string="章节名称", readonly=True)
|
||||||
|
chapter_sequence = fields.Integer(related="chapter_id.sequence", string="章节序号", readonly=True)
|
||||||
|
chapter_is_published = fields.Boolean(related="chapter_id.is_published", string="发布状态", readonly=True)
|
||||||
|
|
||||||
|
# 文件核心字段
|
||||||
|
file = fields.Binary(string='文件', attachment=True, required=True)
|
||||||
|
file_name = fields.Char(string='文件名')
|
||||||
|
file_size = fields.Integer(string='文件大小(字节)', readonly=True)
|
||||||
|
file_size_str = fields.Char(string='文件大小', readonly=True) # 友好显示:KB/MB
|
||||||
|
file_suffix = fields.Char(string='文件格式', readonly=True) # 后缀:docx/pptx/pdf
|
||||||
|
|
||||||
|
version = fields.Char(string='版本号', default='1.0')
|
||||||
|
version_note = fields.Char(string='版本说明')
|
||||||
|
publish_date = fields.Date(string='发布日期', default=fields.Date.today)
|
||||||
|
is_published = fields.Boolean(string='是否发布', default=True)
|
||||||
|
download_count = fields.Integer(string='下载次数', default=0)
|
||||||
|
teaching_class_id = fields.Many2one(
|
||||||
|
'course.teaching_class',
|
||||||
|
string='教学班',
|
||||||
|
ondelete='cascade',
|
||||||
|
domain="[('course_id', '=', course_id)]"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 监听文件上传,自动赋值文件名、大小、后缀
|
||||||
|
@api.onchange('file', 'file_name')
|
||||||
|
def _onchange_file_upload(self):
|
||||||
|
for record in self:
|
||||||
|
if record.file and record.file_name:
|
||||||
|
# 计算文件大小(base64 换算)
|
||||||
|
file_data = base64.b64decode(record.file)
|
||||||
|
size_bytes = len(file_data)
|
||||||
|
record.file_size = size_bytes
|
||||||
|
record.file_size_str = human_size(size_bytes)
|
||||||
|
|
||||||
|
# 提取文件后缀
|
||||||
|
name, suffix = os.path.splitext(record.file_name)
|
||||||
|
record.file_suffix = suffix.lower().strip('.')
|
||||||
|
else:
|
||||||
|
record.file_size = 0
|
||||||
|
record.file_size_str = ''
|
||||||
|
record.file_suffix = ''
|
||||||
|
|
||||||
|
# 修复批量下载问题 + 优化下载响应
|
||||||
|
def action_download(self):
|
||||||
|
for rec in self:
|
||||||
|
rec.download_count += 1
|
||||||
|
if rec.file_name:
|
||||||
|
# 携带真实文件名,浏览器正常识别
|
||||||
|
url = f'/web/content/course.syllabus/{rec.id}/file/{rec.file_name}?download=true'
|
||||||
|
else:
|
||||||
|
url = f'/web/content/course.syllabus/{rec.id}/file?download=true'
|
||||||
|
return {
|
||||||
|
'type': 'ir.actions.act_url',
|
||||||
|
'url': url,
|
||||||
|
'target': 'self', # self 强制下载,new 新标签页打开
|
||||||
|
}
|
||||||
291
learning_center/models/course_teaching_class.py
Normal file
291
learning_center/models/course_teaching_class.py
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
from odoo import api, fields, models
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
import base64
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
|
try:
|
||||||
|
import pandas as pd
|
||||||
|
except ImportError:
|
||||||
|
pd = None
|
||||||
|
|
||||||
|
|
||||||
|
class CourseTeachingClass(models.Model):
|
||||||
|
_name = 'course.teaching_class'
|
||||||
|
_description = '教学班'
|
||||||
|
_rec_name = 'display_name'
|
||||||
|
_order = 'course_id, semester, name'
|
||||||
|
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||||||
|
|
||||||
|
# ==================== 显示名称 ====================
|
||||||
|
display_name = fields.Char(string='显示名称', compute='_compute_display_name', store=True)
|
||||||
|
name = fields.Char(string='教学班名称', required=True, help='如:1班、2班、周一班')
|
||||||
|
code = fields.Char(string='班级代码', help='如:CS101-01')
|
||||||
|
semester = fields.Selection([
|
||||||
|
('2024-2025-1', '2024-2025学年第一学期'),
|
||||||
|
('2024-2025-2', '2024-2025学年第二学期'),
|
||||||
|
('2025-2026-1', '2025-2026学年第一学期'),
|
||||||
|
('2025-2026-2', '2025-2026学年第二学期'),
|
||||||
|
], string='学期', required=True, default=lambda self: self._get_current_semester())
|
||||||
|
|
||||||
|
# ==================== 关联课程 ====================
|
||||||
|
course_id = fields.Many2one('learning.course', string='课程', required=True, ondelete='cascade')
|
||||||
|
course_name = fields.Char(related='course_id.name', string='课程名称')
|
||||||
|
|
||||||
|
@api.depends('course_name', 'name', 'semester')
|
||||||
|
def _compute_display_name(self):
|
||||||
|
for record in self:
|
||||||
|
semester_map = dict(self._fields['semester'].selection)
|
||||||
|
semester_name = semester_map.get(record.semester, '')
|
||||||
|
record.display_name = f"{record.course_name} - {record.name}({semester_name})"
|
||||||
|
|
||||||
|
# ==================== 基本信息 ====================
|
||||||
|
course_code = fields.Char(string='课程代码', related='course_id.code', store=True)
|
||||||
|
course_credit = fields.Float(string='学分', related='course_id.credit', store=True)
|
||||||
|
course_exam_type = fields.Selection(string='考核方式', related='course_id.exam_type', store=True)
|
||||||
|
|
||||||
|
# ==================== 教师信息 ====================
|
||||||
|
teacher_ids = fields.Many2many('hr.employee', string='授课教师',
|
||||||
|
relation='teaching_class_teacher_rel')
|
||||||
|
main_teacher_id = fields.Many2one('hr.employee', string='主讲教师')
|
||||||
|
assistant_ids = fields.Many2many('hr.employee', string='助教',
|
||||||
|
relation='teaching_class_assistant_rel')
|
||||||
|
|
||||||
|
# ==================== 学生信息(保留仅做展示,数据以 enrollment 为准) ====================
|
||||||
|
student_ids = fields.Many2many('student.info', string='选课学生',
|
||||||
|
relation='teaching_class_student_rel')
|
||||||
|
student_count = fields.Integer(string='选课人数', compute='_compute_student_count')
|
||||||
|
|
||||||
|
# ==================== 上课信息 ====================
|
||||||
|
schedule = fields.Text(string='上课时间地点', help='如:周一 1-2节 教学楼101')
|
||||||
|
start_date = fields.Date(string='开课日期')
|
||||||
|
end_date = fields.Date(string='结课日期')
|
||||||
|
total_weeks = fields.Integer(string='教学周数', default=16)
|
||||||
|
|
||||||
|
# ==================== 人数限制 ====================
|
||||||
|
max_students = fields.Integer(string='人数上限', default=60)
|
||||||
|
min_students = fields.Integer(string='开课人数下限', default=20)
|
||||||
|
is_full = fields.Boolean(string='是否满员', compute='_compute_is_full')
|
||||||
|
|
||||||
|
# ==================== 状态 ====================
|
||||||
|
state = fields.Selection([
|
||||||
|
('draft', '未开放'),
|
||||||
|
('open', '选课中'),
|
||||||
|
('teaching', '教学中'),
|
||||||
|
('closed', '已结课'),
|
||||||
|
('cancelled', '已取消'),
|
||||||
|
], string='状态', default='draft', tracking=True)
|
||||||
|
|
||||||
|
# ==================== 教学进度 ====================
|
||||||
|
current_chapter = fields.Integer(string='当前进度章节', help='当前教学进度')
|
||||||
|
progress_rate = fields.Float(string='教学进度(%)', compute='_compute_progress_rate')
|
||||||
|
|
||||||
|
# ==================== 统计字段 ====================
|
||||||
|
homework_count = fields.Integer(string='作业数量', compute='_compute_homework_count')
|
||||||
|
submitted_count = fields.Integer(string='已提交作业数', compute='_compute_homework_count')
|
||||||
|
resource_count = fields.Integer(string='资源数量', compute='_compute_resource_count')
|
||||||
|
|
||||||
|
# ==================== 关联子表(核心:所有业务依赖 enrollment_ids) ====================
|
||||||
|
homework_ids = fields.One2many('course.homework', 'teaching_class_id', string='班级作业')
|
||||||
|
student_score_ids = fields.One2many('course.student.score', 'teaching_class_id', string='班级成绩')
|
||||||
|
enrollment_ids = fields.One2many('course.teaching_class.enrollment', 'teaching_class_id', string='选课记录')
|
||||||
|
course_syllabus_ids = fields.One2many('course.syllabus', 'teaching_class_id', string='教案/大纲')
|
||||||
|
|
||||||
|
# ==================== 计算方法(全部走选课记录) ====================
|
||||||
|
def _compute_student_count(self):
|
||||||
|
for record in self:
|
||||||
|
valid_enroll = record.enrollment_ids.filtered(lambda e: e.state == 'enrolled')
|
||||||
|
record.student_count = len(valid_enroll)
|
||||||
|
|
||||||
|
def _compute_is_full(self):
|
||||||
|
for record in self:
|
||||||
|
record.is_full = record.max_students > 0 and record.student_count >= record.max_students
|
||||||
|
|
||||||
|
def _compute_progress_rate(self):
|
||||||
|
for record in self:
|
||||||
|
if record.total_weeks and record.current_chapter:
|
||||||
|
record.progress_rate = record.current_chapter / record.total_weeks * 100
|
||||||
|
else:
|
||||||
|
record.progress_rate = 0
|
||||||
|
|
||||||
|
def _compute_homework_count(self):
|
||||||
|
for record in self:
|
||||||
|
homeworks = self.env['course.homework'].search([('teaching_class_id', '=', record.id)])
|
||||||
|
record.homework_count = len(homeworks)
|
||||||
|
record.submitted_count = 0
|
||||||
|
|
||||||
|
def _compute_resource_count(self):
|
||||||
|
for record in self:
|
||||||
|
resources = self.env['course.chapter.resource'].search([
|
||||||
|
('teaching_class_id', '=', record.id)
|
||||||
|
])
|
||||||
|
record.resource_count = len(resources)
|
||||||
|
|
||||||
|
# ==================== 业务按钮方法 ====================
|
||||||
|
def action_open_enroll(self):
|
||||||
|
self.state = 'open'
|
||||||
|
|
||||||
|
def action_start_teaching(self):
|
||||||
|
self.state = 'teaching'
|
||||||
|
|
||||||
|
def action_close(self):
|
||||||
|
self.state = 'closed'
|
||||||
|
|
||||||
|
def action_cancel(self):
|
||||||
|
self.state = 'cancelled'
|
||||||
|
|
||||||
|
def action_add_students(self):
|
||||||
|
"""打开批量添加学生向导(底层批量生成选课记录)"""
|
||||||
|
return {
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
'name': '添加学生',
|
||||||
|
'res_model': 'course.teaching_class.enrollment.wizard',
|
||||||
|
'view_mode': 'form',
|
||||||
|
'target': 'new',
|
||||||
|
'context': {'default_teaching_class_id': self.id},
|
||||||
|
}
|
||||||
|
|
||||||
|
def action_import_students(self):
|
||||||
|
"""导入入口,复用向导"""
|
||||||
|
return self.action_add_students()
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def _get_current_semester(self):
|
||||||
|
import datetime
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
year = now.year
|
||||||
|
if now.month >= 9:
|
||||||
|
return f'{year}-{year + 1}-1'
|
||||||
|
elif now.month >= 2:
|
||||||
|
return f'{year - 1}-{year}-2'
|
||||||
|
else:
|
||||||
|
return f'{year - 1}-{year}-1'
|
||||||
|
|
||||||
|
# 可选:双向同步 student_ids 和 enrollment_ids(保证两边显示一致,后期可删除 student_ids)
|
||||||
|
@api.depends('enrollment_ids.student_id')
|
||||||
|
def _sync_student_ids(self):
|
||||||
|
for rec in self:
|
||||||
|
stu_ids = rec.enrollment_ids.mapped('student_id').ids
|
||||||
|
rec.student_ids = [(6, 0, stu_ids)]
|
||||||
|
|
||||||
|
student_ids = fields.Many2many(
|
||||||
|
'student.info',
|
||||||
|
string='选课学生',
|
||||||
|
relation='teaching_class_student_rel',
|
||||||
|
compute='_sync_student_ids',
|
||||||
|
store=True
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CourseTeachingClassEnrollment(models.Model):
|
||||||
|
_name = 'course.teaching_class.enrollment'
|
||||||
|
_description = '教学班选课记录'
|
||||||
|
_rec_name = 'display_name'
|
||||||
|
_order = 'teaching_class_id, student_id'
|
||||||
|
|
||||||
|
display_name = fields.Char(string='显示名称', compute='_compute_display_name', store=True)
|
||||||
|
course_id = fields.Many2one(related="teaching_class_id.course_id", string="课程", store=True)
|
||||||
|
teaching_class_id = fields.Many2one('course.teaching_class', string='教学班', required=True, ondelete='cascade')
|
||||||
|
student_id = fields.Many2one('student.info', string='学生', required=True, ondelete='cascade')
|
||||||
|
stu_name = fields.Char(related='student_id.stu_name', string='学生姓名')
|
||||||
|
stu_phone = fields.Char(related='student_id.stu_phone', string='学生电话')
|
||||||
|
|
||||||
|
# 选课信息
|
||||||
|
enroll_date = fields.Date(string='选课日期', default=fields.Date.today)
|
||||||
|
state = fields.Selection([
|
||||||
|
('enrolled', '已选课'),
|
||||||
|
('dropped', '已退课'),
|
||||||
|
('failed', '不及格'),
|
||||||
|
('passed', '已通过'),
|
||||||
|
], string='状态', default='enrolled', tracking=True)
|
||||||
|
|
||||||
|
# 成绩(最终成绩)
|
||||||
|
final_score = fields.Float(string='最终成绩')
|
||||||
|
grade_level = fields.Selection([
|
||||||
|
('A', '优秀'),
|
||||||
|
('B', '良好'),
|
||||||
|
('C', '中等'),
|
||||||
|
('D', '及格'),
|
||||||
|
('F', '不及格'),
|
||||||
|
], string='等级')
|
||||||
|
|
||||||
|
@api.depends('teaching_class_id.display_name', 'student_id.stu_name')
|
||||||
|
def _compute_display_name(self):
|
||||||
|
for record in self:
|
||||||
|
record.display_name = f"{record.student_id.stu_name} - {record.teaching_class_id.display_name}"
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def create(self, vals):
|
||||||
|
"""新增选课记录校验人数上限"""
|
||||||
|
res = super().create(vals)
|
||||||
|
cls = res.teaching_class_id
|
||||||
|
valid_num = len(cls.enrollment_ids.filtered(lambda e: e.state == 'enrolled'))
|
||||||
|
if cls.max_students and valid_num > cls.max_students:
|
||||||
|
raise ValidationError("该教学班人数已达上限,无法继续添加学生!")
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
# ==================== 批量添加/导入学生 向导(临时模型) ====================
|
||||||
|
class CourseTeachingClassEnrollmentWizard(models.TransientModel):
|
||||||
|
_name = 'course.teaching_class.enrollment.wizard'
|
||||||
|
_description = '批量添加&导入学生向导'
|
||||||
|
|
||||||
|
teaching_class_id = fields.Many2one(
|
||||||
|
'course.teaching_class', string='教学班', required=True
|
||||||
|
)
|
||||||
|
student_ids = fields.Many2many('student.info', string='选择学生')
|
||||||
|
file = fields.Binary(string='上传Excel文件')
|
||||||
|
filename = fields.Char(string='文件名')
|
||||||
|
|
||||||
|
def action_add_students(self):
|
||||||
|
"""手动勾选学生 → 批量生成选课记录"""
|
||||||
|
self.ensure_one()
|
||||||
|
cls = self.teaching_class_id
|
||||||
|
exist_stu_ids = set(cls.enrollment_ids.mapped('student_id').ids)
|
||||||
|
create_list = []
|
||||||
|
|
||||||
|
for stu in self.student_ids:
|
||||||
|
if stu.id not in exist_stu_ids:
|
||||||
|
create_list.append({
|
||||||
|
'teaching_class_id': cls.id,
|
||||||
|
'student_id': stu.id,
|
||||||
|
'state': 'enrolled'
|
||||||
|
})
|
||||||
|
|
||||||
|
if create_list:
|
||||||
|
self.env['course.teaching_class.enrollment'].create(create_list)
|
||||||
|
return {'type': 'ir.actions.act_window_close'}
|
||||||
|
|
||||||
|
def action_import_excel(self):
|
||||||
|
"""Excel导入 → 批量生成选课记录"""
|
||||||
|
self.ensure_one()
|
||||||
|
if not self.file:
|
||||||
|
raise ValidationError("请先选择Excel文件!")
|
||||||
|
if not pd:
|
||||||
|
raise ValidationError("缺少 pandas 库,请先安装:pip install pandas openpyxl")
|
||||||
|
|
||||||
|
cls = self.teaching_class_id
|
||||||
|
exist_stu_ids = set(cls.enrollment_ids.mapped('student_id').ids)
|
||||||
|
create_list = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
file_data = base64.b64decode(self.file)
|
||||||
|
excel_file = BytesIO(file_data)
|
||||||
|
df = pd.read_excel(excel_file, engine='openpyxl')
|
||||||
|
|
||||||
|
for _, row in df.iterrows():
|
||||||
|
stu_code = str(row.get('学号', '')).strip()
|
||||||
|
if not stu_code:
|
||||||
|
continue
|
||||||
|
student = self.env['student.info'].search([('stu_id', '=', stu_code)], limit=1)
|
||||||
|
if student and student.id not in exist_stu_ids:
|
||||||
|
create_list.append({
|
||||||
|
'teaching_class_id': cls.id,
|
||||||
|
'student_id': student.id,
|
||||||
|
'state': 'enrolled'
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
raise ValidationError(f"解析Excel失败:{str(e)}")
|
||||||
|
|
||||||
|
if create_list:
|
||||||
|
self.env['course.teaching_class.enrollment'].create(create_list)
|
||||||
|
return {'type': 'ir.actions.act_window_close'}
|
||||||
113
learning_center/models/learning_course.py
Normal file
113
learning_center/models/learning_course.py
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
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)],
|
||||||
|
}
|
||||||
13
learning_center/models/teach_class.py
Normal file
13
learning_center/models/teach_class.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from odoo import api,fields,models
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class TeachClass(models.Model):
|
||||||
|
_name = 'teach.class'
|
||||||
|
course_teaching_class=fields.Many2one('course.teaching_class',string="教学班")
|
||||||
|
student_id=fields.Many2one('student.info',string='学生')
|
||||||
|
stu_num=fields.Char(related='student_id.stu_num',string='学号')
|
||||||
|
stu_name=fields.Char(related='student_id.stu_name',string='姓名')
|
||||||
|
stu_sex = fields.Selection(related='student_id.stu_sex', string="性别")
|
||||||
|
stu_phone = fields.Char(related='student_id.stu_phone', string="手机号")
|
||||||
|
stu_grade_xx = fields.Many2one(related='student_id.stu_grade_xx', string="年级")
|
||||||
24
learning_center/security/ir.model.access.csv
Normal file
24
learning_center/security/ir.model.access.csv
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
|
access_learning_course_sys,learning.course.access.sys,model_learning_course,base.group_system,1,1,1,1
|
||||||
|
access_course_chapter_sys,course.chapter.access.sys,model_course_chapter,base.group_system,1,1,1,1
|
||||||
|
access_course_chapter_resource_sys,course.chapter.resource.access.sys,model_course_chapter_resource,base.group_system,1,1,1,1
|
||||||
|
access_course_homework_sys,course.homework.access.sys,model_course_homework,base.group_system,1,1,1,1
|
||||||
|
access_course_homework_submit_sys,course.homework.submit.access.sys,model_course_homework_submit,base.group_system,1,1,1,1
|
||||||
|
access_course_score_item_sys,course.score.item.access.sys,model_course_score_item,base.group_system,1,1,1,1
|
||||||
|
access_course_student_score_sys,course.student.score.access.sys,model_course_student_score,base.group_system,1,1,1,1
|
||||||
|
access_course_student_score_detail_sys,course.student.score.detail.access.sys,model_course_student_score_detail,base.group_system,1,1,1,1
|
||||||
|
access_course_syllabus_sys,course.syllabus.access.sys,model_course_syllabus,base.group_system,1,1,1,1
|
||||||
|
access_course_teaching_class_sys,course.teaching.class.access.sys,model_course_teaching_class,base.group_system,1,1,1,1
|
||||||
|
access_course_teaching_class_enrollment_sys,course.teaching.class.enrollment.access.sys,model_course_teaching_class_enrollment,base.group_system,1,1,1,1
|
||||||
|
access_course_teaching_class_enrollment_wizard_sys,course.teaching.class.enrollment.access.sys,model_course_teaching_class_enrollment_wizard,base.group_system,1,1,1,1
|
||||||
|
access_teach_class_teacher,teach.class.access.teacher,model_teach_class,edu_base.group_teacher,1,1,0,0
|
||||||
|
access_teach_class_sys,teach.class.access.sys,model_teach_class,base.group_system,1,1,1,1
|
||||||
|
access_course_teaching_class_teacher,course.teaching.class.access.teacher,model_course_teaching_class,edu_base.group_teacher,1,0,0,0
|
||||||
|
access_course_teaching_class_enrollment_teacher,course.teaching.class.enrollment.access.teacher,model_course_teaching_class_enrollment,edu_base.group_teacher,1,0,0,0
|
||||||
|
access_course_homework_teacher,course.homework.access.teacher,model_course_homework,edu_base.group_teacher,1,1,1,0
|
||||||
|
access_course_homework_submit_teacher,course.homework.submit.access.teacher,model_course_homework_submit,edu_base.group_teacher,1,1,1,0
|
||||||
|
access_learning_course_teacher,learning.course.access.teacher,model_learning_course,edu_base.group_teacher,1,0,0,0
|
||||||
|
access_course_chapter_teacher,course.chapter.access.teacher,model_course_chapter,edu_base.group_teacher,1,1,1,0
|
||||||
|
access_course_chapter_resource_teacher,course.chapter.resource.access.teacher,model_course_chapter_resource,edu_base.group_teacher,1,1,1,0
|
||||||
|
|
||||||
|
|
||||||
|
41
learning_center/security/record_rules.xml
Normal file
41
learning_center/security/record_rules.xml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<odoo>
|
||||||
|
<!-- 教师:仅查看自己创建的班级关联数据 -->
|
||||||
|
<record id="rule_teaching_class_teacher_own" model="ir.rule">
|
||||||
|
<field name="name">教师-仅查看自己的班级数据</field>
|
||||||
|
<field name="model_id" ref="model_course_teaching_class"/>
|
||||||
|
<!-- 仅对教师组生效 -->
|
||||||
|
<field name="groups" eval="[(6,0, [ref('edu_base.group_teacher')])]"/>
|
||||||
|
<!-- create_uid 是系统内置字段:记录创建人,uid 当前登录用户-->
|
||||||
|
<field name="domain_force">[('main_teacher_id.user_id', '=', user.id)]</field>
|
||||||
|
<field name="perm_read" eval="True"/>
|
||||||
|
<field name="perm_write" eval="True"/>
|
||||||
|
<field name="perm_create" eval="False"/>
|
||||||
|
<field name="perm_unlink" eval="False"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="rule_course_homework_teacher_own" model="ir.rule">
|
||||||
|
<field name="name">作业发布-仅查看自己发布的作业</field>
|
||||||
|
<field name="model_id" ref="model_course_homework"/>
|
||||||
|
<!-- 仅对教师组生效 -->
|
||||||
|
<field name="groups" eval="[(6,0, [ref('edu_base.group_teacher')])]"/>
|
||||||
|
<!-- create_uid 是系统内置字段:记录创建人,uid 当前登录用户-->
|
||||||
|
<field name="domain_force">[('create_uid', '=', user.id)]</field>
|
||||||
|
<field name="perm_read" eval="True"/>
|
||||||
|
<field name="perm_write" eval="True"/>
|
||||||
|
<field name="perm_create" eval="True"/>
|
||||||
|
<field name="perm_unlink" eval="False"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="rule_course_homework_submit_teacher_own" model="ir.rule">
|
||||||
|
<field name="name">作业提价-仅查看自己发布的作业的提交情况</field>
|
||||||
|
<field name="model_id" ref="model_course_homework_submit"/>
|
||||||
|
<!-- 仅对教师组生效 -->
|
||||||
|
<field name="groups" eval="[(6,0, [ref('edu_base.group_teacher')])]"/>
|
||||||
|
<!-- create_uid 是系统内置字段:记录创建人,uid 当前登录用户-->
|
||||||
|
<field name="domain_force">[('homework_id.create_uid', '=', user.id)]</field>
|
||||||
|
<field name="perm_read" eval="True"/>
|
||||||
|
<field name="perm_write" eval="True"/>
|
||||||
|
<field name="perm_create" eval="True"/>
|
||||||
|
<field name="perm_unlink" eval="False"/>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
135
learning_center/views/view_course_chapter.xml
Normal file
135
learning_center/views/view_course_chapter.xml
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
<odoo>
|
||||||
|
<record id="list_course_chapter" model="ir.ui.view">
|
||||||
|
<field name="name">course.chapter.list</field>
|
||||||
|
<field name="model">course.chapter</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list>
|
||||||
|
<field name="sequence" widget="handle"/>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="course_id"/>
|
||||||
|
<field name="resource_count" sum="合计"/>
|
||||||
|
<field name="video_count"/>
|
||||||
|
<field name="doc_count"/>
|
||||||
|
<field name="is_published" widget="boolean_toggle"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="form_course_chapter" model="ir.ui.view">
|
||||||
|
<field name="name">course.chapter.form</field>
|
||||||
|
<field name="model">course.chapter</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="章节">
|
||||||
|
<sheet>
|
||||||
|
<div class="oe_title">
|
||||||
|
<h1>
|
||||||
|
<field name="name" placeholder="章节名称"/>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="oe_button_box" name="button_box">
|
||||||
|
<button name="action_publish" type="object" string="发布" class="btn-primary"
|
||||||
|
invisible="is_published == True"/>
|
||||||
|
<button name="action_hide" type="object" string="隐藏" class="btn-secondary"
|
||||||
|
invisible="is_published == False"/>
|
||||||
|
</div>
|
||||||
|
<group name="basic_info" string="基本信息">
|
||||||
|
<group>
|
||||||
|
<field name="course_id" options="{'no_create': True}"/>
|
||||||
|
<field name="sequence"/>
|
||||||
|
<field name="is_published" widget="boolean_toggle"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="resource_count" readonly="1"/>
|
||||||
|
<field name="video_count" readonly="1"/>
|
||||||
|
<field name="doc_count" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<group name="description" string="章节描述">
|
||||||
|
<field name="description" placeholder="章节描述"/>
|
||||||
|
</group>
|
||||||
|
<notebook>
|
||||||
|
<page string="教学资源">
|
||||||
|
<field name="resource_ids" view_id="view_course_chapter_resource_sub_list"/>
|
||||||
|
</page>
|
||||||
|
<page string="关联作业">
|
||||||
|
<!-- <field name="homework_ids" view_id="view_course_chapter_homework_sub_list"-->
|
||||||
|
<!-- context="{'default_course_id': course_id}"/>-->
|
||||||
|
</page>
|
||||||
|
<page string="教学大纲/教案">
|
||||||
|
<field name="syllabus_ids" view_id="view_course_chapter_syllabus_sub_list"
|
||||||
|
context="{'default_course_id': course_id, 'default_chapter_id': id}"/>
|
||||||
|
</page>
|
||||||
|
<page string="消息">
|
||||||
|
<field name="message_ids"/>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_course_chapter_search" model="ir.ui.view">
|
||||||
|
<field name="name">course.chapter.search</field>
|
||||||
|
<field name="model">course.chapter</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<search>
|
||||||
|
<searchpanel>
|
||||||
|
<field name="course_id" string="课程" />
|
||||||
|
</searchpanel>
|
||||||
|
</search>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- <record id="view_course_chapter_resource_sub_list" model="ir.ui.view">-->
|
||||||
|
<!-- <field name="name">course.chapter.resource.sub.list</field>-->
|
||||||
|
<!-- <field name="model">course.chapter.resource</field>-->
|
||||||
|
<!-- <field name="arch" type="xml">-->
|
||||||
|
<!-- <list editable="bottom">-->
|
||||||
|
<!-- <field name="sequence" widget="handle"/>-->
|
||||||
|
<!-- <field name="name"/>-->
|
||||||
|
<!-- <field name="resource_type" widget="badge"/>-->
|
||||||
|
<!-- <field name="is_hidden" widget="boolean_toggle"/>-->
|
||||||
|
<!-- </list>-->
|
||||||
|
<!-- </field>-->
|
||||||
|
<!-- </record>-->
|
||||||
|
|
||||||
|
<!-- <record id="view_course_chapter_homework_sub_list" model="ir.ui.view">-->
|
||||||
|
<!-- <field name="name">course.chapter.homework.sub.list</field>-->
|
||||||
|
<!-- <field name="model">course.homework</field>-->
|
||||||
|
<!-- <field name="arch" type="xml">-->
|
||||||
|
<!-- <list>-->
|
||||||
|
<!-- <field name="name"/>-->
|
||||||
|
<!-- <field name="deadline"/>-->
|
||||||
|
<!-- <field name="state" widget="badge"/>-->
|
||||||
|
<!-- </list>-->
|
||||||
|
<!-- </field>-->
|
||||||
|
<!-- </record>-->
|
||||||
|
|
||||||
|
<!-- 内嵌大纲/教案列表视图(用于一对多) -->
|
||||||
|
<record id="view_course_chapter_syllabus_sub_list" model="ir.ui.view">
|
||||||
|
<field name="name">course.chapter.syllabus.sub.list</field>
|
||||||
|
<field name="model">course.syllabus</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list editable="bottom">
|
||||||
|
<field name="title"/>
|
||||||
|
<field name="syllabus_type" widget="badge"/>
|
||||||
|
<field name="version"/>
|
||||||
|
<field name="is_published" widget="boolean_toggle"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="act_course_chapter" model="ir.actions.act_window">
|
||||||
|
<field name="name">章节管理</field>
|
||||||
|
<field name="res_model">course.chapter</field>
|
||||||
|
<field name="view_mode">list,form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="menu_course_chapter" model="ir.ui.menu">
|
||||||
|
<field name="name">章节管理</field>
|
||||||
|
<field name="parent_id" ref="menu_learning_center_root"/>
|
||||||
|
<field name="action" ref="act_course_chapter"/>
|
||||||
|
<field name="groups_id" eval="[(6, 0, [ref('base.group_system'),ref('edu_base.group_teacher')])]"/>
|
||||||
|
<field name="sequence">20</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
107
learning_center/views/view_course_chapter_resource.xml
Normal file
107
learning_center/views/view_course_chapter_resource.xml
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<odoo>
|
||||||
|
<record id="list_course_chapter_resource" model="ir.ui.view">
|
||||||
|
<field name="name">course.chapter.resource.list</field>
|
||||||
|
<field name="model">course.chapter.resource</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list>
|
||||||
|
<field name="sequence" widget="handle"/>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="resource_type" widget="badge"/>
|
||||||
|
<field name="chapter_id"/>
|
||||||
|
<field name="course_id"/>
|
||||||
|
<field name="is_hidden" widget="boolean_toggle"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="form_course_chapter_resource" model="ir.ui.view">
|
||||||
|
<field name="name">course.chapter.resource.form</field>
|
||||||
|
<field name="model">course.chapter.resource</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="教学资源">
|
||||||
|
<sheet>
|
||||||
|
<div class="oe_title">
|
||||||
|
<h1>
|
||||||
|
<field name="name" placeholder="资源名称"/>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="oe_button_box" name="button_box">
|
||||||
|
<button name="action_toggle_hide" type="object" string="切换隐藏状态" class="btn-secondary"/>
|
||||||
|
<button name="action_preview" type="object" string="预览" class="btn-primary"
|
||||||
|
invisible="preview_url == False"/>
|
||||||
|
</div>
|
||||||
|
<group name="basic_info" string="基本信息">
|
||||||
|
<group>
|
||||||
|
<field name="chapter_id" options="{'no_create': True}"/>
|
||||||
|
<field name="course_id" readonly="1"/>
|
||||||
|
<field name="sequence"/>
|
||||||
|
<field name="resource_type"/>
|
||||||
|
<field name="is_hidden" widget="boolean_toggle"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="description" placeholder="备注说明" nolabel="1"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
|
||||||
|
<!-- 原有视频区域 保留不变 -->
|
||||||
|
<group name="video_info" string="视频信息" invisible="resource_type != 'video'">
|
||||||
|
<group>
|
||||||
|
<field name="video_file" filename="video_filename" widget="binary"/>
|
||||||
|
<field name="video_filename" invisible="1"/>
|
||||||
|
<field name="video_duration" help="时长(秒)"/>
|
||||||
|
<field name="video_url" placeholder="外部视频链接"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
|
||||||
|
<!-- 原有文档区域 保留不变 -->
|
||||||
|
<group name="doc_info" string="文档信息" invisible="resource_type not in ['pdf', 'ppt']">
|
||||||
|
<group>
|
||||||
|
<field name="doc_file" filename="doc_filename" widget="binary"/>
|
||||||
|
<field name="doc_filename" invisible="1"/>
|
||||||
|
<field name="doc_page_count" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
|
||||||
|
<!-- 新增:批量上传附件区域 独立分组 -->
|
||||||
|
<group string="批量上传附件">
|
||||||
|
<field name="resource_attachment_ids" widget="many2many_binary"
|
||||||
|
string="多文件上传(可Ctrl/Shift多选)"/>
|
||||||
|
<field name="attachment_count" string="附件总数" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
|
||||||
|
<notebook>
|
||||||
|
<page string="所属课程信息">
|
||||||
|
<group string="课程信息">
|
||||||
|
<field name="course_id" readonly="1"/>
|
||||||
|
<field name="course_name" string="课程名称" readonly="1"/>
|
||||||
|
<field name="course_code" string="课程代码" readonly="1"/>
|
||||||
|
<field name="course_credit" string="学分" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
<page string="关联章节信息">
|
||||||
|
<group string="章节信息">
|
||||||
|
<field name="chapter_name" string="章节名称" readonly="1"/>
|
||||||
|
<field name="chapter_sequence" string="章节序号" readonly="1"/>
|
||||||
|
<field name="chapter_is_published" string="章节发布状态" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="act_course_chapter_resource" model="ir.actions.act_window">
|
||||||
|
<field name="name">教学资源</field>
|
||||||
|
<field name="res_model">course.chapter.resource</field>
|
||||||
|
<field name="view_mode">list,form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="menu_course_chapter_resource" model="ir.ui.menu">
|
||||||
|
<field name="name">教学资源</field>
|
||||||
|
<field name="parent_id" ref="menu_learning_center_root"/>
|
||||||
|
<field name="action" ref="act_course_chapter_resource"/>
|
||||||
|
<field name="groups_id" eval="[(6, 0, [ref('base.group_system'),ref('edu_base.group_teacher')])]"/>
|
||||||
|
<field name="sequence">30</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
123
learning_center/views/view_course_homework.xml
Normal file
123
learning_center/views/view_course_homework.xml
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
<odoo>
|
||||||
|
<record id="list_course_homework" model="ir.ui.view">
|
||||||
|
<field name="name">course.homework.list</field>
|
||||||
|
<field name="model">course.homework</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="course_id"/>
|
||||||
|
<field name="chapter_id"/>
|
||||||
|
<field name="total_score"/>
|
||||||
|
<field name="deadline"/>
|
||||||
|
<field name="submitted_count" sum="合计"/>
|
||||||
|
<field name="unsubmitted_count" sum="合计"/>
|
||||||
|
<field name="state" widget="badge"/>
|
||||||
|
<field name="is_submit_open" widget="boolean_toggle"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="form_course_homework" model="ir.ui.view">
|
||||||
|
<field name="name">course.homework.form</field>
|
||||||
|
<field name="model">course.homework</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="课程作业">
|
||||||
|
<sheet>
|
||||||
|
<div class="oe_title">
|
||||||
|
<h1>
|
||||||
|
<field name="name" placeholder="作业名称"/>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="oe_button_box" name="button_box">
|
||||||
|
<button name="action_publish" type="object" string="发布" class="btn-primary"
|
||||||
|
invisible="state in ['published', 'closed']"/>
|
||||||
|
<button name="action_close" type="object" string="关闭" class="btn-danger"
|
||||||
|
invisible="state != 'published'"/>
|
||||||
|
<button name="action_draft" type="object" string="退回草稿" class="btn-secondary"
|
||||||
|
invisible="state != 'published'"/>
|
||||||
|
</div>
|
||||||
|
<group name="basic_info" string="基本信息">
|
||||||
|
<group>
|
||||||
|
<field name="teaching_class_id"/>
|
||||||
|
<field name="course_id" options="{'no_create': True}"/>
|
||||||
|
<field name="chapter_id" options="{'no_create': True}"/>
|
||||||
|
<field name="total_score"/>
|
||||||
|
<field name="state" widget="statusbar"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="publish_time" readonly="1"/>
|
||||||
|
<field name="deadline"/>
|
||||||
|
<field name="late_deadline"/>
|
||||||
|
<field name="is_submit_open" widget="boolean_toggle"/>
|
||||||
|
<field name="allow_late" widget="boolean_toggle"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<notebook>
|
||||||
|
<page string="作业内容">
|
||||||
|
<group>
|
||||||
|
<field name="description" placeholder="作业描述"/>
|
||||||
|
<field name="requirement" placeholder="作业要求"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
<page string="提交情况">
|
||||||
|
<group string="统计信息">
|
||||||
|
<group>
|
||||||
|
<field name="total_students"/>
|
||||||
|
<field name="submitted_count"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="late_count"/>
|
||||||
|
<field name="unsubmitted_count"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<!-- <field name="submit_ids" view_id="view_course_homework_submit_sub_list"/>-->
|
||||||
|
</page>
|
||||||
|
<page string="成绩关联">
|
||||||
|
<group string="关联成绩项目">
|
||||||
|
<!-- <field name="score_item_ids" context="{'default_course_id': course_id}">-->
|
||||||
|
<!-- <list>-->
|
||||||
|
<!-- <field name="name"/>-->
|
||||||
|
<!-- <field name="score_type" widget="badge"/>-->
|
||||||
|
<!-- <field name="weight"/>-->
|
||||||
|
<!-- <field name="full_score"/>-->
|
||||||
|
<!-- </list>-->
|
||||||
|
<!-- </field>-->
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
<page string="消息">
|
||||||
|
<field name="message_ids"/>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- <record id="view_course_homework_submit_sub_list" model="ir.ui.view">-->
|
||||||
|
<!-- <field name="name">course.homework.submit.sub.list</field>-->
|
||||||
|
<!-- <field name="model">course.homework.submit</field>-->
|
||||||
|
<!-- <field name="arch" type="xml">-->
|
||||||
|
<!-- <list editable="bottom">-->
|
||||||
|
<!-- <field name="student_id"/>-->
|
||||||
|
<!-- <field name="submit_time"/>-->
|
||||||
|
<!-- <field name="is_late" widget="boolean_toggle"/>-->
|
||||||
|
<!-- <field name="score"/>-->
|
||||||
|
<!-- <field name="state" widget="badge"/>-->
|
||||||
|
<!-- </list>-->
|
||||||
|
<!-- </field>-->
|
||||||
|
<!-- </record>-->
|
||||||
|
|
||||||
|
<record id="act_course_homework" model="ir.actions.act_window">
|
||||||
|
<field name="name">作业管理</field>
|
||||||
|
<field name="res_model">course.homework</field>
|
||||||
|
<field name="view_mode">list,form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="menu_course_homework" model="ir.ui.menu">
|
||||||
|
<field name="name">作业发布</field>
|
||||||
|
<field name="parent_id" ref="menu_learning_center_root"/>
|
||||||
|
<field name="action" ref="act_course_homework"/>
|
||||||
|
<field name="groups_id" eval="[(6,0,[ref('base.group_system'),ref('edu_base.group_teacher')])]"/>
|
||||||
|
<field name="sequence">40</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
103
learning_center/views/view_course_homework_student.xml
Normal file
103
learning_center/views/view_course_homework_student.xml
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<!-- ==================== 学生端作业列表视图(门户/前台) ==================== -->
|
||||||
|
<record id="view_course_homework_student_list" model="ir.ui.view">
|
||||||
|
<field name="name">course.homework.student.list</field>
|
||||||
|
<field name="model">course.homework</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="course_id"/>
|
||||||
|
<field name="teaching_class_id"/>
|
||||||
|
<field name="total_score"/>
|
||||||
|
<field name="deadline"/>
|
||||||
|
<field name="submit_state" widget="badge"/>
|
||||||
|
<field name="my_score"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- ==================== 学生端作业表单视图(门户/前台) ==================== -->
|
||||||
|
<record id="view_course_homework_student_form" model="ir.ui.view">
|
||||||
|
<field name="name">course.homework.student.form</field>
|
||||||
|
<field name="model">course.homework</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="作业详情">
|
||||||
|
<sheet>
|
||||||
|
<div class="oe_title">
|
||||||
|
<h1>
|
||||||
|
<field name="name" placeholder="作业名称"/>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<group name="basic_info" string="作业信息">
|
||||||
|
<group>
|
||||||
|
<field name="course_id"/>
|
||||||
|
<field name="teaching_class_id"/>
|
||||||
|
<field name="total_score"/>
|
||||||
|
<field name="deadline"/>
|
||||||
|
<field name="submit_state" widget="badge"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="my_score"/>
|
||||||
|
<field name="my_grade_level" widget="badge"/>
|
||||||
|
<field name="my_submit_time"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<group name="content" string="作业内容">
|
||||||
|
<field name="description" placeholder="作业描述"/>
|
||||||
|
<field name="requirement" placeholder="作业要求"/>
|
||||||
|
</group>
|
||||||
|
<notebook>
|
||||||
|
<page string="提交作业" invisible="can_submit == False">
|
||||||
|
<group string="提交内容">
|
||||||
|
<field name="my_submit_file" filename="my_submit_filename" widget="binary"/>
|
||||||
|
<field name="my_submit_content" placeholder="填写你的答案或说明"/>
|
||||||
|
<div class="oe_button_box">
|
||||||
|
<button name="action_submit_homework" type="object" string="提交作业" class="btn-primary"/>
|
||||||
|
</div>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
<page string="批改反馈" invisible="my_submit_state != 'graded'">
|
||||||
|
<group string="批改信息">
|
||||||
|
<field name="my_score"/>
|
||||||
|
<field name="my_grade_level" widget="badge"/>
|
||||||
|
<field name="my_comment" placeholder="教师评语"/>
|
||||||
|
</group>
|
||||||
|
<group string="我的提交">
|
||||||
|
<field name="my_submit_file" filename="my_submit_filename" widget="binary" readonly="1"/>
|
||||||
|
<field name="my_submit_content" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<record id="act_course_homework_student" model="ir.actions.act_window">
|
||||||
|
<field name="name">我的作业</field>
|
||||||
|
<field name="res_model">course.homework</field>
|
||||||
|
<field name="view_mode">list,form</field>
|
||||||
|
<!-- <field name="domain">[('teaching_class_id.student_ids.user_id', '=', uid)]</field>-->
|
||||||
|
<!-- <field name="context">{'default_student_id': active_id}</field>-->
|
||||||
|
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="menu_student_root" model="ir.ui.menu">
|
||||||
|
<field name="name">学生作业</field>
|
||||||
|
<field name="sequence">20</field>
|
||||||
|
<!-- <field name="groups_id" eval="[(4, ref('student_info.group_student'))]"/>-->
|
||||||
|
<field name="action" ref="act_course_homework_student"/>
|
||||||
|
</record>
|
||||||
|
<!-- 学生端作业菜单 -->
|
||||||
|
<!-- <record id="menu_student_homework" model="ir.ui.menu">-->
|
||||||
|
<!-- <field name="name">我的作业</field>-->
|
||||||
|
<!-- <field name="parent_id" ref="menu_student_root"/>-->
|
||||||
|
<!-- <field name="action" ref="act_course_homework_student"/>-->
|
||||||
|
<!-- <field name="sequence">10</field>-->
|
||||||
|
<!--<!– <field name="groups_id" eval="[(4, ref('student_info.group_student'))]"/>–>-->
|
||||||
|
<!-- </record>-->
|
||||||
|
|
||||||
|
</odoo>
|
||||||
119
learning_center/views/view_course_score_item.xml
Normal file
119
learning_center/views/view_course_score_item.xml
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
<odoo>
|
||||||
|
<record id="list_course_score_item" model="ir.ui.view">
|
||||||
|
<field name="name">course.score.item.list</field>
|
||||||
|
<field name="model">course.score.item</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list>
|
||||||
|
<field name="sequence" widget="handle"/>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="course_id"/>
|
||||||
|
<field name="score_type" widget="badge"/>
|
||||||
|
<field name="weight"/>
|
||||||
|
<field name="full_score"/>
|
||||||
|
<field name="is_active" widget="boolean_toggle"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="form_course_score_item" model="ir.ui.view">
|
||||||
|
<field name="name">course.score.item.form</field>
|
||||||
|
<field name="model">course.score.item</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="成绩项目">
|
||||||
|
<sheet>
|
||||||
|
<div class="oe_title">
|
||||||
|
<h1>
|
||||||
|
<field name="name" placeholder="项目名称"/>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="oe_button_box" name="button_box">
|
||||||
|
<button name="action_toggle_active" type="object" string="启用/禁用" class="btn-secondary"/>
|
||||||
|
</div>
|
||||||
|
<group name="basic_info" string="基本信息">
|
||||||
|
<group>
|
||||||
|
<field name="course_id" options="{'no_create': True}" required="1"/>
|
||||||
|
<field name="sequence"/>
|
||||||
|
<field name="score_type" required="1"/>
|
||||||
|
<field name="is_active" widget="boolean_toggle"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="weight" required="1"/>
|
||||||
|
<field name="full_score"/>
|
||||||
|
<field name="description" placeholder="项目描述"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<notebook>
|
||||||
|
<page string="课程信息">
|
||||||
|
<group string="课程详情">
|
||||||
|
<field name="course_name" string="课程名称" readonly="1"/>
|
||||||
|
<field name="course_code" string="课程代码" readonly="1"/>
|
||||||
|
<field name="course_credit" string="学分" readonly="1"/>
|
||||||
|
<field name="course_exam_type" string="考核方式" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
<page string="成绩统计">
|
||||||
|
<group string="统计信息">
|
||||||
|
<group>
|
||||||
|
<!-- <field name="student_count" string="学生人数" readonly="1"/>-->
|
||||||
|
<field name="student_count" string="提交人数" readonly="1"/>
|
||||||
|
<field name="avg_score" string="平均分" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="max_score" string="最高分" readonly="1"/>
|
||||||
|
<field name="min_score" string="最低分" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<field name="score_detail_ids" view_id="view_score_detail_list"/>
|
||||||
|
</page>
|
||||||
|
<page string="关联作业">
|
||||||
|
<field name="homework_ids">
|
||||||
|
<list>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="deadline"/>
|
||||||
|
<field name="state" widget="badge"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</page>
|
||||||
|
<page string="消息">
|
||||||
|
<field name="message_ids"/>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_score_detail_list" model="ir.ui.view">
|
||||||
|
<field name="name">course.student.score.detail.list</field>
|
||||||
|
<field name="model">course.student.score.detail</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list>
|
||||||
|
<field name="student_id"/>
|
||||||
|
<field name="score"/>
|
||||||
|
<field name="remark"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="act_course_score_item" model="ir.actions.act_window">
|
||||||
|
<field name="name">成绩项目</field>
|
||||||
|
<field name="res_model">course.score.item</field>
|
||||||
|
<field name="view_mode">list,form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="act_course_score_item_by_course" model="ir.actions.act_window">
|
||||||
|
<field name="name">成绩项目</field>
|
||||||
|
<field name="res_model">course.score.item</field>
|
||||||
|
<field name="view_mode">list,form</field>
|
||||||
|
<field name="view_id" ref="list_course_score_item"/>
|
||||||
|
<!-- <field name="domain">[('course_id', '=', active_id)]</field>-->
|
||||||
|
<!-- <field name="context">{'default_course_id': active_id}</field>-->
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="menu_course_score_item" model="ir.ui.menu">
|
||||||
|
<field name="name">成绩项目</field>
|
||||||
|
<field name="parent_id" ref="menu_learning_center_root"/>
|
||||||
|
<field name="action" ref="act_course_score_item"/>
|
||||||
|
<field name="sequence">50</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
204
learning_center/views/view_course_student_score.xml
Normal file
204
learning_center/views/view_course_student_score.xml
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<!-- ==================== 学生成绩列表视图 ==================== -->
|
||||||
|
<record id="list_course_student_score" model="ir.ui.view">
|
||||||
|
<field name="name">course.student.score.list</field>
|
||||||
|
<field name="model">course.student.score</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list>
|
||||||
|
<field name="student_id"/>
|
||||||
|
<field name="stu_name"/>
|
||||||
|
<field name="course_id"/>
|
||||||
|
<field name="course_name"/>
|
||||||
|
<field name="teaching_class_id"/>
|
||||||
|
<field name="total_score"/>
|
||||||
|
<field name="grade_level" widget="badge"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- ==================== 学生成绩表单视图 ==================== -->
|
||||||
|
<record id="form_course_student_score" model="ir.ui.view">
|
||||||
|
<field name="name">course.student.score.form</field>
|
||||||
|
<field name="model">course.student.score</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="学生成绩">
|
||||||
|
<sheet>
|
||||||
|
<div class="oe_title">
|
||||||
|
<h1>
|
||||||
|
<field name="display_name" placeholder="成绩记录"/>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<group name="basic_info" string="基本信息">
|
||||||
|
<group>
|
||||||
|
<field name="course_id" options="{'no_create': True}"/>
|
||||||
|
<field name="course_name" readonly="1"/>
|
||||||
|
<field name="teaching_class_id" options="{'no_create': True}"
|
||||||
|
domain="[('course_id', '=', course_id)]"/>
|
||||||
|
<field name="student_id" options="{'no_create': True}"/>
|
||||||
|
<field name="stu_name" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="total_score"/>
|
||||||
|
<field name="grade_level" widget="badge"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<notebook>
|
||||||
|
<page string="成绩明细">
|
||||||
|
<field name="score_ids">
|
||||||
|
<list editable="bottom">
|
||||||
|
<field name="score_item_id" options="{'no_create': True}"/>
|
||||||
|
<field name="score"/>
|
||||||
|
<field name="full_score" readonly="1"/>
|
||||||
|
<field name="weight" readonly="1"/>
|
||||||
|
<field name="completion_rate" widget="progressbar"/>
|
||||||
|
<field name="remark"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</page>
|
||||||
|
<page string="课程信息">
|
||||||
|
<group string="课程详情">
|
||||||
|
<field name="course_name" string="课程名称" readonly="1"/>
|
||||||
|
<field name="course_code" string="课程代码" readonly="1"/>
|
||||||
|
<field name="course_credit" string="学分" readonly="1"/>
|
||||||
|
<field name="course_exam_type" string="考核方式" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
<page string="教学班信息" invisible="not teaching_class_id">
|
||||||
|
<group string="教学班详情">
|
||||||
|
<field name="teaching_class_name" string="教学班名称" readonly="1"/>
|
||||||
|
<field name="teaching_class_semester" string="学期" readonly="1"/>
|
||||||
|
<field name="teaching_class_main_teacher" string="主讲教师" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
<page string="学生信息">
|
||||||
|
<group string="学生详情">
|
||||||
|
<field name="stu_name" string="姓名" readonly="1"/>
|
||||||
|
<field name="student_no" string="学号" readonly="1"/>
|
||||||
|
<field name="student_class_id" string="班级" readonly="1"/>
|
||||||
|
<field name="student_major_id" string="专业" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
<page string="消息">
|
||||||
|
<field name="message_ids"/>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ==================== 学生成绩明细列表视图 ==================== -->
|
||||||
|
<record id="view_course_student_score_detail_list" model="ir.ui.view">
|
||||||
|
<field name="name">course.student.score.detail.list</field>
|
||||||
|
<field name="model">course.student.score.detail</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list>
|
||||||
|
<field name="student_id"/>
|
||||||
|
<field name="student_score_displayname"/>
|
||||||
|
<field name="score_item_id"/>
|
||||||
|
<field name="score"/>
|
||||||
|
<field name="full_score"/>
|
||||||
|
<field name="weight"/>
|
||||||
|
<field name="completion_rate" widget="progressbar"/>
|
||||||
|
<field name="remark"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- ==================== 学生成绩明细表单视图 ==================== -->
|
||||||
|
<record id="view_course_student_score_detail_form" model="ir.ui.view">
|
||||||
|
<field name="name">course.student.score.detail.form</field>
|
||||||
|
<field name="model">course.student.score.detail</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="成绩明细">
|
||||||
|
<sheet>
|
||||||
|
<div class="oe_title">
|
||||||
|
<h1>
|
||||||
|
<field name="display_name" placeholder="成绩明细"/>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<group name="basic_info" string="基本信息">
|
||||||
|
<group>
|
||||||
|
<field name="student_score_id" options="{'no_create': True}"/>
|
||||||
|
<field name="student_score_displayname" readonly="1"/>
|
||||||
|
<field name="score_item_id" options="{'no_create': True}"/>
|
||||||
|
<field name="score"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="full_score" readonly="1"/>
|
||||||
|
<field name="weight" readonly="1"/>
|
||||||
|
<field name="score_type" readonly="1"/>
|
||||||
|
<field name="completion_rate" widget="progressbar" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<group name="related_info" string="关联信息">
|
||||||
|
<group>
|
||||||
|
<field name="course_id" readonly="1"/>
|
||||||
|
<field name="student_id" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="remark" placeholder="备注"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ==================== 学生成绩动作 ==================== -->
|
||||||
|
<record id="act_course_student_score" model="ir.actions.act_window">
|
||||||
|
<field name="name">学生成绩</field>
|
||||||
|
<field name="res_model">course.student.score</field>
|
||||||
|
<field name="view_mode">list,form</field>
|
||||||
|
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- ==================== 学生成绩明细动作 ==================== -->
|
||||||
|
<record id="act_course_student_score_detail" model="ir.actions.act_window">
|
||||||
|
<field name="name">成绩明细</field>
|
||||||
|
<field name="res_model">course.student.score.detail</field>
|
||||||
|
<field name="view_mode">list,form</field>
|
||||||
|
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- ==================== 按课程查看学生成绩的动作 ==================== -->
|
||||||
|
<record id="act_course_student_score_by_course" model="ir.actions.act_window">
|
||||||
|
<field name="name">学生成绩</field>
|
||||||
|
<field name="res_model">course.student.score</field>
|
||||||
|
<field name="view_mode">list,form</field>
|
||||||
|
<field name="view_id" ref="list_course_student_score"/>
|
||||||
|
<field name="domain">[('course_id', '=', active_id)]</field>
|
||||||
|
<field name="context">{'default_course_id': active_id}</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- ==================== 按教学班查看学生成绩的动作 ==================== -->
|
||||||
|
<record id="act_course_student_score_by_teaching_class" model="ir.actions.act_window">
|
||||||
|
<field name="name">学生成绩</field>
|
||||||
|
<field name="res_model">course.student.score</field>
|
||||||
|
<field name="view_mode">list,form</field>
|
||||||
|
<field name="view_id" ref="list_course_student_score"/>
|
||||||
|
<field name="domain">[('teaching_class_id', '=', active_id)]</field>
|
||||||
|
<field name="context">{'default_teaching_class_id': active_id}</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- ==================== 二级菜单 ==================== -->
|
||||||
|
<record id="menu_course_student_score" model="ir.ui.menu">
|
||||||
|
<field name="name">学生成绩</field>
|
||||||
|
<field name="parent_id" ref="menu_learning_center_root"/>
|
||||||
|
<field name="action" ref="act_course_student_score"/>
|
||||||
|
<field name="sequence">60</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- ==================== 成绩明细二级菜单 ==================== -->
|
||||||
|
<record id="menu_course_student_score_detail" model="ir.ui.menu">
|
||||||
|
<field name="name">成绩明细</field>
|
||||||
|
<field name="parent_id" ref="menu_learning_center_root"/>
|
||||||
|
<field name="action" ref="act_course_student_score_detail"/>
|
||||||
|
<field name="sequence">65</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
134
learning_center/views/view_course_syllabus.xml
Normal file
134
learning_center/views/view_course_syllabus.xml
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
<odoo>
|
||||||
|
<!-- 列表视图 -->
|
||||||
|
<record id="list_course_syllabus" model="ir.ui.view">
|
||||||
|
<field name="name">course.syllabus.list</field>
|
||||||
|
<field name="model">course.syllabus</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list decoration-muted="not is_published">
|
||||||
|
<field name="title" string="标题"/>
|
||||||
|
<field name="syllabus_type" string="类型"/>
|
||||||
|
<field name="course_id" string="所属课程"/>
|
||||||
|
<field name="teaching_class_id" string="教学班"/>
|
||||||
|
<field name="chapter_id" string="关联章节"/>
|
||||||
|
<field name="file_suffix" string="文件格式"/>
|
||||||
|
<field name="version" string="版本号"/>
|
||||||
|
<field name="publish_date" string="发布日期"/>
|
||||||
|
<field name="is_published" widget="boolean_toggle" string="已发布"/>
|
||||||
|
<field name="download_count" string="下载次数"/>
|
||||||
|
<!-- 列表快速下载按钮 -->
|
||||||
|
<button name="action_download" type="object" string="下载" icon="fa-download" class="btn-sm"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- 表单视图 -->
|
||||||
|
<record id="form_course_syllabus" model="ir.ui.view">
|
||||||
|
<field name="name">course.syllabus.form</field>
|
||||||
|
<field name="model">course.syllabus</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="教学大纲/教案">
|
||||||
|
<sheet>
|
||||||
|
<div class="oe_title">
|
||||||
|
<h1>
|
||||||
|
<field name="title" placeholder="请输入文档标题"/>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 顶部按钮区 -->
|
||||||
|
<div class="oe_button_box" name="button_box">
|
||||||
|
<button name="action_download" type="object" string="下载文件" icon="fa-download" class="btn-primary"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 基础信息分组 分两列排版 -->
|
||||||
|
<group name="basic_info" string="基础信息" col="2">
|
||||||
|
<group>
|
||||||
|
<field name="syllabus_type" string="文档类型"/>
|
||||||
|
<field name="course_id" string="所属课程" options="{'no_create': True}"/>
|
||||||
|
<field name="teaching_class_id" string="教学班" options="{'no_create': True}"/>
|
||||||
|
<field name="chapter_id" string="关联章节" options="{'no_create': True}"
|
||||||
|
context="{'default_course_id': course_id}"
|
||||||
|
domain="[('course_id', '=', course_id)]"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="version" string="版本号"/>
|
||||||
|
<field name="version_note" string="版本说明" placeholder="填写版本更新内容"/>
|
||||||
|
<field name="publish_date" string="发布日期"/>
|
||||||
|
<field name="is_published" widget="boolean_toggle" string="是否发布"/>
|
||||||
|
<field name="download_count" string="下载次数" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
|
||||||
|
<!-- 文件上传区域 增加格式限制与展示 -->
|
||||||
|
<group name="file_info" string="附件文档" class="oe_mt16">
|
||||||
|
<field name="file"
|
||||||
|
filename="file_name"
|
||||||
|
widget="binary"
|
||||||
|
required="1"
|
||||||
|
accept=".doc,.docx,.ppt,.pptx,.pdf"
|
||||||
|
string="上传文件"/>
|
||||||
|
<!-- 隐藏原始文件名字段,后台自动赋值 -->
|
||||||
|
<field name="file_name" invisible="1"/>
|
||||||
|
<!-- 友好展示:文件格式、文件大小,隐藏原始字节数 -->
|
||||||
|
<group col="3" readonly="1" class="oe_pl16">
|
||||||
|
<field name="file_suffix" string="文件格式"/>
|
||||||
|
<field name="file_size_str" string="文件大小"/>
|
||||||
|
<field name="file_size" invisible="1"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
|
||||||
|
<!-- 标签页区域 -->
|
||||||
|
<notebook class="oe_mt16">
|
||||||
|
<page string="课程信息">
|
||||||
|
<group string="课程基础资料" col="2">
|
||||||
|
<field name="course_name" string="课程名称" readonly="1"/>
|
||||||
|
<field name="course_code" string="课程代码" readonly="1"/>
|
||||||
|
<field name="course_credit" string="学分" readonly="1"/>
|
||||||
|
<field name="course_exam_type" string="考核方式" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
|
||||||
|
<!-- 章节页:无章节时自动隐藏 -->
|
||||||
|
<page string="章节信息" >
|
||||||
|
<group string="章节详情" col="2">
|
||||||
|
<field name="chapter_name" string="章节名称" readonly="1"/>
|
||||||
|
<field name="chapter_sequence" string="章节序号" readonly="1"/>
|
||||||
|
<field name="chapter_is_published" string="章节发布状态" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
|
||||||
|
<page string="沟通记录">
|
||||||
|
<field name="message_ids"/>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 主动作窗口:绑定列表、表单、搜索视图 -->
|
||||||
|
<record id="act_course_syllabus" model="ir.actions.act_window">
|
||||||
|
<field name="name">教学大纲/教案</field>
|
||||||
|
<field name="res_model">course.syllabus</field>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<!-- <field name="view_id" ref="form_course_syllabus"/>-->
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- 课程详情内嵌视图:过滤当前课程数据 -->
|
||||||
|
<!-- <record id="act_course_syllabus_by_course" model="ir.actions.act_window">-->
|
||||||
|
<!-- <field name="name">教学大纲/教案</field>-->
|
||||||
|
<!-- <field name="res_model">course.syllabus</field>-->
|
||||||
|
<!-- <field name="view_mode">list,form</field>-->
|
||||||
|
<!-- <field name="view_id" ref="list_course_syllabus"/>-->
|
||||||
|
<!-- <field name="domain">[('course_id', '=', active_id)]</field>-->
|
||||||
|
<!-- <field name="context">{'default_course_id': active_id}</field>-->
|
||||||
|
<!-- </record>-->
|
||||||
|
|
||||||
|
<!-- 二级菜单 -->
|
||||||
|
<record id="menu_course_syllabus" model="ir.ui.menu">
|
||||||
|
<field name="name">教学大纲/教案</field>
|
||||||
|
<field name="parent_id" ref="menu_learning_center_root"/>
|
||||||
|
<field name="action" ref="act_course_syllabus"/>
|
||||||
|
<field name="sequence">35</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
215
learning_center/views/view_course_teaching_class.xml
Normal file
215
learning_center/views/view_course_teaching_class.xml
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<record id="list_course_teaching_class" model="ir.ui.view">
|
||||||
|
<field name="name">course.teaching_class.list</field>
|
||||||
|
<field name="model">course.teaching_class</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="course_id"/>
|
||||||
|
<field name="semester" widget="badge"/>
|
||||||
|
<field name="main_teacher_id"/>
|
||||||
|
<field name="student_count" sum="合计"/>
|
||||||
|
<field name="max_students"/>
|
||||||
|
<field name="state" widget="badge"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="form_course_teaching_class" model="ir.ui.view">
|
||||||
|
<field name="name">course.teaching_class.form</field>
|
||||||
|
<field name="model">course.teaching_class</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="教学班">
|
||||||
|
<sheet>
|
||||||
|
<div class="oe_title">
|
||||||
|
<h1>
|
||||||
|
<field name="display_name" placeholder="教学班名称"/>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="oe_button_box" name="button_box">
|
||||||
|
<button name="action_open_enroll" type="object" string="开放选课" class="btn-primary"
|
||||||
|
invisible="state not in ['draft']"/>
|
||||||
|
<button name="action_start_teaching" type="object" string="开始教学" class="btn-success"
|
||||||
|
invisible="state not in ['open']"/>
|
||||||
|
<button name="action_close" type="object" string="结课" class="btn-danger"
|
||||||
|
invisible="state not in ['teaching']"/>
|
||||||
|
<button name="action_cancel" type="object" string="取消课程" class="btn-warning"
|
||||||
|
invisible="state in ['closed','cancelled']"/>
|
||||||
|
</div>
|
||||||
|
<group name="basic_info" string="基本信息">
|
||||||
|
<group>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="code"/>
|
||||||
|
<field name="course_id" options="{'no_create': True}"/>
|
||||||
|
<field name="semester"/>
|
||||||
|
<field name="state" widget="statusbar"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="main_teacher_id" options="{'no_create': True}"/>
|
||||||
|
<field name="teacher_ids" widget="many2many_tags"/>
|
||||||
|
<field name="assistant_ids" widget="many2many_tags"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<group name="schedule_info" string="上课安排">
|
||||||
|
<group>
|
||||||
|
<field name="schedule"/>
|
||||||
|
<field name="start_date"/>
|
||||||
|
<field name="end_date"/>
|
||||||
|
<field name="total_weeks"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="max_students"/>
|
||||||
|
<field name="min_students"/>
|
||||||
|
<field name="student_count" readonly="1"/>
|
||||||
|
<field name="is_full" widget="boolean_toggle" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<notebook>
|
||||||
|
<page string="选课学生">
|
||||||
|
<field name="student_ids" view_id="view_student_info_list_in_class"/>
|
||||||
|
<div class="oe_button_box" style="margin-top:8px;">
|
||||||
|
<button name="action_add_students" type="object" string="批量添加学生" class="btn-secondary"/>
|
||||||
|
<button name="action_import_students" type="object" string="导入学生名单" class="btn-secondary"/>
|
||||||
|
</div>
|
||||||
|
</page>
|
||||||
|
<!-- 选课记录:开启顶部行内编辑,支持连续快速新增多条 -->
|
||||||
|
<page string="选课记录">
|
||||||
|
<field name="enrollment_ids" view_id="view_enrollment_list"/>
|
||||||
|
</page>
|
||||||
|
<page string="课程作业">
|
||||||
|
<field name="homework_ids" context="{'default_course_id': course_id, 'default_teaching_class_id': id}" view_id="view_homework_list"/>
|
||||||
|
</page>
|
||||||
|
<page string="学生成绩">
|
||||||
|
<field name="student_score_ids" context="{'default_course_id': course_id, 'default_teaching_class_id': id}" view_id="view_student_score_list"/>
|
||||||
|
</page>
|
||||||
|
<page string="教学大纲/教案">
|
||||||
|
<field name="course_syllabus_ids" context="{'default_course_id': course_id}" view_id="view_course_syllabus_list_inside"/>
|
||||||
|
</page>
|
||||||
|
<page string="消息">
|
||||||
|
<field name="message_ids"/>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_student_info_list_in_class" model="ir.ui.view">
|
||||||
|
<field name="name">student.info.list.in.class</field>
|
||||||
|
<field name="model">student.info</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list editable="bottom">
|
||||||
|
<field name="stu_num"/>
|
||||||
|
<field name="stu_name"/>
|
||||||
|
<field name="class_id"/>
|
||||||
|
<field name="stu_phone"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- 重点:editable="top" 顶部快速新建,可连续添加多条选课记录 -->
|
||||||
|
<record id="view_enrollment_list" model="ir.ui.view">
|
||||||
|
<field name="name">course.teaching.class.enrollment.list</field>
|
||||||
|
<field name="model">course.teaching_class.enrollment</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list editable="top">
|
||||||
|
<field name="student_id"/>
|
||||||
|
<field name="enroll_date"/>
|
||||||
|
<field name="state" widget="badge"/>
|
||||||
|
<field name="final_score"/>
|
||||||
|
<field name="grade_level" widget="badge"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_homework_list" model="ir.ui.view">
|
||||||
|
<field name="name">course.homework.list</field>
|
||||||
|
<field name="model">course.homework</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="deadline"/>
|
||||||
|
<field name="total_score"/>
|
||||||
|
<field name="submitted_count"/>
|
||||||
|
<field name="state" widget="badge"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_course_syllabus_list_inside" model="ir.ui.view">
|
||||||
|
<field name="name">course.syllabus.list.inside</field>
|
||||||
|
<field name="model">course.syllabus</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list>
|
||||||
|
<field name="title"/>
|
||||||
|
<field name="syllabus_type" widget="badge"/>
|
||||||
|
<field name="version"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_student_score_list" model="ir.ui.view">
|
||||||
|
<field name="name">course.student.score.list</field>
|
||||||
|
<field name="model">course.student.score</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list>
|
||||||
|
<field name="student_id"/>
|
||||||
|
<field name="total_score"/>
|
||||||
|
<field name="grade_level" widget="badge"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- 批量添加/导入学生 向导弹窗视图 -->
|
||||||
|
<record id="view_teaching_class_enrollment_wizard_form" model="ir.ui.view">
|
||||||
|
<field name="name">course.teaching_class.enrollment.wizard.form</field>
|
||||||
|
<field name="model">course.teaching_class.enrollment.wizard</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="批量添加学生">
|
||||||
|
<group col="2">
|
||||||
|
<field name="teaching_class_id" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
<group string="手动选择学生">
|
||||||
|
<field name="student_ids" widget="many2many_tags" colspan="4"/>
|
||||||
|
</group>
|
||||||
|
<group string="Excel批量导入">
|
||||||
|
<field name="file" filename="filename"/>
|
||||||
|
<p style="color:gray;">Excel模板要求:首列标题为【学号】,按学号匹配学生</p>
|
||||||
|
</group>
|
||||||
|
<footer>
|
||||||
|
<button name="action_add_students" string="确认添加选中学生" type="object" class="btn-primary"/>
|
||||||
|
<button name="action_import_excel" string="执行Excel导入" type="object" class="btn-success"/>
|
||||||
|
<button string="关闭" special="cancel" class="btn-secondary"/>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- 教学班动作 -->
|
||||||
|
<record id="act_course_teaching_class" model="ir.actions.act_window">
|
||||||
|
<field name="name">教学班管理</field>
|
||||||
|
<field name="res_model">course.teaching_class</field>
|
||||||
|
<field name="view_mode">list,form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- 按课程查看教学班的动作 -->
|
||||||
|
<record id="act_course_teaching_class_by_course" model="ir.actions.act_window">
|
||||||
|
<field name="name">教学班</field>
|
||||||
|
<field name="res_model">course.teaching_class</field>
|
||||||
|
<field name="view_mode">list,form</field>
|
||||||
|
<field name="view_id" ref="list_course_teaching_class"/>
|
||||||
|
<field name="domain">[('course_id', '=', active_id)]</field>
|
||||||
|
<field name="context">{'default_course_id': active_id}</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- 二级菜单 -->
|
||||||
|
<record id="menu_course_teaching_class" model="ir.ui.menu">
|
||||||
|
<field name="name">教学班管理</field>
|
||||||
|
<field name="parent_id" ref="menu_learning_center_root"/>
|
||||||
|
<field name="action" ref="act_course_teaching_class"/>
|
||||||
|
<field name="sequence">15</field>
|
||||||
|
<field name="groups_id" eval="[(6,0,[ref('base.group_system'),ref('edu_base.group_teacher')])]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
140
learning_center/views/view_homework_submit.xml
Normal file
140
learning_center/views/view_homework_submit.xml
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
<odoo>
|
||||||
|
<record id="list_course_homework_submit" model="ir.ui.view">
|
||||||
|
<field name="name">course.homework.submit.list</field>
|
||||||
|
<field name="model">course.homework.submit</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list>
|
||||||
|
<field name="homework_id"/>
|
||||||
|
<field name="student_id"/>
|
||||||
|
<field name="submit_time"/>
|
||||||
|
<field name="is_late" widget="boolean_toggle"/>
|
||||||
|
<field name="score"/>
|
||||||
|
<field name="state" widget="badge"/>
|
||||||
|
<field name="grader_id"/>
|
||||||
|
<field name="grade_time"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="form_course_homework_submit" model="ir.ui.view">
|
||||||
|
<field name="name">course.homework.submit.form</field>
|
||||||
|
<field name="model">course.homework.submit</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="作业提交">
|
||||||
|
<sheet>
|
||||||
|
<div class="oe_title">
|
||||||
|
<h1>
|
||||||
|
<field name="display_name" placeholder="提交记录"/>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="oe_button_box" name="button_box">
|
||||||
|
<button name="action_grade" type="object" string="批改" class="btn-primary"
|
||||||
|
invisible="state == 'graded'"/>
|
||||||
|
<button name="action_regrade" type="object" string="重新批改" class="btn-secondary"
|
||||||
|
invisible="state != 'graded'"/>
|
||||||
|
</div>
|
||||||
|
<group name="basic_info" string="基本信息">
|
||||||
|
<group>
|
||||||
|
<field name="homework_id" options="{'no_create': True}"/>
|
||||||
|
<field name="student_id" options="{'no_create': True}"/>
|
||||||
|
<field name="submit_time" readonly="1"/>
|
||||||
|
<field name="is_late" widget="boolean_toggle" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="state" widget="statusbar"/>
|
||||||
|
<field name="score"/>
|
||||||
|
<field name="grader_id" readonly="1"/>
|
||||||
|
<field name="grade_time" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<notebook>
|
||||||
|
<page string="提交内容">
|
||||||
|
<group string="提交文件">
|
||||||
|
<field name="submit_file" filename="submit_filename" widget="binary"/>
|
||||||
|
<field name="submit_filename" invisible="1"/>
|
||||||
|
<field name="submit_content" placeholder="提交内容"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
<page string="批改内容">
|
||||||
|
<group string="批改信息">
|
||||||
|
<field name="comment" placeholder="批改评语"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
<page string="课程信息">
|
||||||
|
<group string="课程信息">
|
||||||
|
<field name="course_name" string="课程名称" readonly="1"/>
|
||||||
|
<field name="course_code" string="课程代码" readonly="1"/>
|
||||||
|
<field name="course_credit" string="学分" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
<page string="作业信息">
|
||||||
|
<group string="作业信息">
|
||||||
|
<field name="homework_name" string="作业名称" readonly="1"/>
|
||||||
|
<field name="homework_total_score" string="作业总分" readonly="1"/>
|
||||||
|
<field name="homework_deadline" string="截止时间" readonly="1"/>
|
||||||
|
<field name="homework_late_deadline" string="补交截止时间" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
<page string="学生信息">
|
||||||
|
<group string="学生信息">
|
||||||
|
<field name="student_name" string="姓名" readonly="1"/>
|
||||||
|
<field name="student_no" string="学号" readonly="1"/>
|
||||||
|
<field name="student_class_id" string="班级" readonly="1"/>
|
||||||
|
<field name="student_major_id" string="专业" readonly="1"/>
|
||||||
|
<field name="student_phone" string="手机号" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
<page string="消息">
|
||||||
|
<field name="message_ids"/>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- <record id="view_course_homework_submit_batch_grade_wizard" model="ir.ui.view">-->
|
||||||
|
<!-- <field name="name">course.homework.submit.batch.grade.wizard</field>-->
|
||||||
|
<!-- <field name="model">course.homework.submit.batch.grade</field>-->
|
||||||
|
<!-- <field name="arch" type="xml">-->
|
||||||
|
<!-- <form string="批量批改">-->
|
||||||
|
<!-- <group>-->
|
||||||
|
<!-- <group>-->
|
||||||
|
<!-- <field name="homework_id" readonly="1"/>-->
|
||||||
|
<!-- <field name="total_count" readonly="1"/>-->
|
||||||
|
<!-- <field name="score"/>-->
|
||||||
|
<!-- </group>-->
|
||||||
|
<!-- <group>-->
|
||||||
|
<!-- <field name="comment" placeholder="统一评语"/>-->
|
||||||
|
<!-- </group>-->
|
||||||
|
<!-- </group>-->
|
||||||
|
<!-- <footer>-->
|
||||||
|
<!-- <button name="action_batch_grade" type="object" string="确认批改" class="btn-primary"/>-->
|
||||||
|
<!-- <button string="取消" class="btn-secondary" special="cancel"/>-->
|
||||||
|
<!-- </footer>-->
|
||||||
|
<!-- </form>-->
|
||||||
|
<!-- </field>-->
|
||||||
|
<!-- </record>-->
|
||||||
|
|
||||||
|
<record id="act_course_homework_submit" model="ir.actions.act_window">
|
||||||
|
<field name="name">作业提交</field>
|
||||||
|
<field name="res_model">course.homework.submit</field>
|
||||||
|
<field name="view_mode">list,form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- <record id="act_course_homework_submit_by_homework" model="ir.actions.act_window">-->
|
||||||
|
<!-- <field name="name">作业提交情况</field>-->
|
||||||
|
<!-- <field name="res_model">course.homework.submit</field>-->
|
||||||
|
<!-- <field name="view_mode">list,form</field>-->
|
||||||
|
<!--<!– <field name="domain">[('homework_id.active_id', '=', active_id)]</field>–>-->
|
||||||
|
<!--<!– <field name="context">{'default_homework_id': active_id}</field>–>-->
|
||||||
|
<!-- </record>-->
|
||||||
|
|
||||||
|
<record id="menu_course_homework_submit" model="ir.ui.menu">
|
||||||
|
<field name="name">作业提交</field>
|
||||||
|
<field name="parent_id" ref="menu_learning_center_root"/>
|
||||||
|
<field name="action" ref="act_course_homework_submit"/>
|
||||||
|
<field name="groups_id" eval="[(6,0,[ref('base.group_system'),ref('edu_base.group_teacher')])]"/>
|
||||||
|
<field name="sequence">45</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
170
learning_center/views/view_learning_course.xml
Normal file
170
learning_center/views/view_learning_course.xml
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<!-- 课程列表视图 -->
|
||||||
|
<record id="list_learning_course" model="ir.ui.view">
|
||||||
|
<field name="name">learning.course.list</field>
|
||||||
|
<field name="model">learning.course</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list>
|
||||||
|
<field name="code"/>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="credit"/>
|
||||||
|
<field name="exam_type" widget="badge"/>
|
||||||
|
<field name="chapter_count"/>
|
||||||
|
<field name="syllabus_count"/>
|
||||||
|
<field name="state" widget="badge"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- 课程表单视图 -->
|
||||||
|
<record id="form_learning_course" model="ir.ui.view">
|
||||||
|
<field name="name">learning.course.form</field>
|
||||||
|
<field name="model">learning.course</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="课程">
|
||||||
|
<sheet>
|
||||||
|
<div class="oe_title">
|
||||||
|
<h1>
|
||||||
|
<field name="name" placeholder="课程名称"/>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="oe_button_box" name="button_box">
|
||||||
|
<button name="action_publish" type="object" string="发布" class="btn-primary"
|
||||||
|
invisible="state != 'draft'"/>
|
||||||
|
|
||||||
|
<button name="action_draft" type="object" string="退回草稿" class="btn-secondary"
|
||||||
|
invisible="state == 'draft'"/>
|
||||||
|
</div>
|
||||||
|
<group name="basic_info" string="基本信息">
|
||||||
|
<group>
|
||||||
|
<field name="code"/>
|
||||||
|
<field name="english_name"/>
|
||||||
|
<field name="credit"/>
|
||||||
|
<field name="exam_type"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="state" widget="statusbar"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
|
||||||
|
<!-- 统计卡片 -->
|
||||||
|
<group name="statistics" string="课程统计" col="3">
|
||||||
|
<field name="chapter_count" widget="statinfo" string="章节数"/>
|
||||||
|
<field name="syllabus_count" widget="statinfo" string="大纲/教案数"/>
|
||||||
|
<field name="resource_count" widget="statinfo" string="教学资源"/>
|
||||||
|
</group>
|
||||||
|
|
||||||
|
<notebook>
|
||||||
|
<page string="课程简介">
|
||||||
|
<field name="description"/>
|
||||||
|
<field name="objectives"/>
|
||||||
|
</page>
|
||||||
|
<page string="章节管理">
|
||||||
|
<field name="chapter_ids" view_id="view_course_chapter_list">
|
||||||
|
</field>
|
||||||
|
<div class="oe_button_box">
|
||||||
|
<button name="action_view_chapters" type="object" string="管理章节" class="btn-primary"/>
|
||||||
|
</div>
|
||||||
|
</page>
|
||||||
|
<page string="教学大纲/教案">
|
||||||
|
<field name="syllabus_ids" view_id="view_course_syllabus_list"/>
|
||||||
|
<div class="oe_button_box">
|
||||||
|
<button name="action_view_syllabus" type="object" string="管理大纲/教案" class="btn-primary"/>
|
||||||
|
</div>
|
||||||
|
</page>
|
||||||
|
<page string="教学资源">
|
||||||
|
<field name="resource_all_ids" string="资源列表" view_id="view_course_chapter_resource_list">
|
||||||
|
</field>
|
||||||
|
<div class="oe_button_box">
|
||||||
|
<button name="action_view_resources" type="object" string="管理资源" class="btn-primary"/>
|
||||||
|
</div>
|
||||||
|
</page>
|
||||||
|
<page string="消息">
|
||||||
|
<field name="message_ids"/>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<record id="view_course_chapter_list" model="ir.ui.view">
|
||||||
|
<field name="name">course.chapter.list</field>
|
||||||
|
<field name="model">course.chapter</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list>
|
||||||
|
<field name="sequence" widget="handle"/>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="resource_count"/>
|
||||||
|
<field name="is_published" widget="boolean_toggle"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- <record id="view_course_syllabus_list" model="ir.ui.view">-->
|
||||||
|
<!-- <field name="name">course.syllabus.list</field>-->
|
||||||
|
<!-- <field name="model">course.syllabus</field>-->
|
||||||
|
<!-- <field name="arch" type="xml">-->
|
||||||
|
<!-- <list>-->
|
||||||
|
<!-- <field name="title"/>-->
|
||||||
|
<!-- <field name="syllabus_type" widget="badge"/>-->
|
||||||
|
<!-- <field name="version"/>-->
|
||||||
|
<!-- <field name="is_published" widget="boolean_toggle"/>-->
|
||||||
|
<!-- </list>-->
|
||||||
|
<!-- </field>-->
|
||||||
|
<!-- </record>-->
|
||||||
|
|
||||||
|
<record id="view_course_chapter_resource_list" model="ir.ui.view">
|
||||||
|
<field name="name">course.chapter.resource.list</field>
|
||||||
|
<field name="model">course.chapter.resource</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list>
|
||||||
|
<field name="chapter_id"/>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="resource_type" widget="badge"/>
|
||||||
|
<field name="is_hidden" widget="boolean_toggle"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_course_chapter_resource_list" model="ir.ui.view">
|
||||||
|
<field name="name">course.chapter.resource.list</field>
|
||||||
|
<field name="model">course.chapter.resource</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list>
|
||||||
|
<field name="chapter_id"/>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="resource_type" widget="badge"/>
|
||||||
|
<field name="is_hidden" widget="boolean_toggle"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 课程动作 -->
|
||||||
|
<record id="act_learning_course" model="ir.actions.act_window">
|
||||||
|
<field name="name">课程管理</field>
|
||||||
|
<field name="res_model">learning.course</field>
|
||||||
|
<field name="view_mode">list,form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="menu_learning_center_root" model="ir.ui.menu">
|
||||||
|
<field name="name">学习中心</field>
|
||||||
|
<field name="sequence">11</field>
|
||||||
|
<field name="groups_id" eval="[(6, 0, [ref('base.group_system'),ref('edu_base.group_teacher')])]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- 二级菜单 -->
|
||||||
|
<record id="menu_learning_course" model="ir.ui.menu">
|
||||||
|
<field name="name">课程管理</field>
|
||||||
|
<field name="parent_id" ref="menu_learning_center_root"/>
|
||||||
|
<field name="action" ref="act_learning_course"/>
|
||||||
|
<field name="sequence">10</field>
|
||||||
|
<field name="groups_id" eval="[(6, 0, [ref('base.group_system')])]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
51
learning_center/views/view_teach_class.xml
Normal file
51
learning_center/views/view_teach_class.xml
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<odoo>
|
||||||
|
<record id="view_teach_class_list" model="ir.ui.view">
|
||||||
|
<field name="name">view.teach.class.list</field>
|
||||||
|
<field name="model">teach.class</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<list>
|
||||||
|
<field name="stu_num"/>
|
||||||
|
<field name="stu_name"/>
|
||||||
|
<field name="stu_sex"/>
|
||||||
|
<field name="stu_phone"/>
|
||||||
|
<field name="stu_grade_xx"/>
|
||||||
|
<field name="course_teaching_class"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_teach_class_form" model="ir.ui.view">
|
||||||
|
<field name="name">view.teach.class.form</field>
|
||||||
|
<field name="model">teach.class</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form>
|
||||||
|
<field name="course_teaching_class"/>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_teach_class_search" model="ir.ui.view">
|
||||||
|
<field name="name">teach.class.search</field>
|
||||||
|
<field name="model">teach.class</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<search>
|
||||||
|
<searchpanel>
|
||||||
|
<field name="course_teaching_class" string="我的班级" group="1"/>
|
||||||
|
</searchpanel>
|
||||||
|
</search>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="act_teach_class" model="ir.actions.act_window">
|
||||||
|
<field name="name">我的班级</field>
|
||||||
|
<field name="res_model">teach.class</field>
|
||||||
|
<field name="view_mode">list</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="menu_teach_class" model="ir.ui.menu">
|
||||||
|
<field name="name">我的班级</field>
|
||||||
|
<field name="action" ref="act_teach_class"/>
|
||||||
|
<field name="sequence">11</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
Loading…
Reference in New Issue
Block a user