80 lines
3.7 KiB
Python
80 lines
3.7 KiB
Python
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 新标签页打开
|
||
} |