Files
shcool/college/models/ir_module_module_info.py
T
2026-08-27 19:53:56 +08:00

263 lines
15 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
from pathlib import Path
from odoo import api, fields, models
from odoo.modules.module import get_module_path
class IrModuleModule(models.Model):
_inherit = 'ir.module.module'
module_origin = fields.Selection(
[('official', '系统原生'), ('local', '本地模块'), ('third_party', '第三方/其它')],
string='模块来源',
compute='_compute_module_origin',
store=True,
index=True,
help='Odoo 官方模块标记为「系统原生」;放在 school 目录下的自建模块标记为「本地模块」;其余为「第三方/其它」。',
)
@api.depends('author', 'name')
def _compute_module_origin(self):
official_authors = {'Odoo', 'Odoo S.A.', 'Odoo S.A'}
for rec in self:
# 优先按物理路径判断: addons/school/ 下的模块视为本地自建
module_path = get_module_path(rec.name)
if module_path and Path(module_path).parent.name.lower() == 'school':
rec.module_origin = 'local'
continue
author = (rec.author or '').strip()
if author in official_authors:
rec.module_origin = 'official'
else:
rec.module_origin = 'third_party'
introduction = fields.Html(
string='模块介绍',
sanitize=True,
help='在「模块信息 / 功能与介绍」页展示的模块说明(由 college 维护)',
)
features = fields.Html(
string='功能亮点',
sanitize=True,
help='在「模块信息 / 功能与介绍」页展示的功能清单(由 college 维护)',
)
knowledge_points = fields.Html(
string='知识点',
sanitize=True,
help='在「模块信息 / 知识点」页展示的核心概念与使用要点(由 college 维护)',
)
@api.model
def populate_module_info(self):
"""为 school 自建模块写入「功能亮点 / 模块介绍」文案。
由 college 的 data 文件通过 <function> 调用,每次升级幂等执行。
"""
data = {
'college': {
'introduction': (
"<p>「教育」是面向高校教学的 Odoo 18 综合管理模块,围绕<strong>老师</strong>与"
"<strong>学生</strong>双角色设计,打通从师生档案、课程建设到作业与学习进展的全流程。</p>"
"<p>它既是师生管理后台,也是学生端的学习入口,所有数据按角色自动隔离可见范围。</p>"
),
'features': (
"<ul>"
"<li><strong>师生管理</strong>:班级 / 老师 / 学生档案,支持 CSV 模板批量导入,"
"导入时自动创建登录账号;</li>"
"<li><strong>课程管理</strong>:老师创建并独立管理课程,支持理论 / 实践两种形式,"
"含视频与 PPT 课件,以及课程介绍、目标、大纲、特色;</li>"
"<li><strong>作业习题</strong>:老师布置与批改,学生在线提交;</li>"
"<li><strong>学习进展</strong>:按角色区分的进展看板,老师看全局、学生看自己;</li>"
"<li><strong>双角色权限</strong>:老师可管理,学生仅可读与提交。</li>"
"</ul>"
),
'knowledge_points': (
"<ul>"
"<li><strong>角色隔离</strong>:老师与学生看到的数据范围由权限组控制,"
"同一菜单、同一视图会根据登录角色自动过滤;</li>"
"<li><strong>CSV 导入规则</strong>:导入学生/老师时会按模板字段自动创建用户并绑定 partner,"
"确保账号与档案一一对应;</li>"
"<li><strong>课程归属</strong>:课程由创建老师负责维护,其他老师默认不可编辑;</li>"
"<li><strong>进展看板</strong>:学生的提交、成绩、学习行为会汇总到进展视图,"
"老师可查看全班统计。</li>"
"</ul>"
),
},
'edu_base': {
'introduction': (
"<p>「教育基础权限」是整套教学体系的权限基座,统一管理跨模块复用的通用角色权限组。</p>"
),
'features': (
"<ul>"
"<li>预置<strong>学生 / 教师 / 教务管理员</strong>三组权限;</li>"
"<li>作为基础依赖,供 college、learning_center 等模块直接引用;</li>"
"<li>不绑定具体业务,只负责角色与授权。</li>"
"</ul>"
),
'knowledge_points': (
"<ul>"
"<li><strong>权限组继承</strong>:edu_base 只定义基础组,业务模块通过 group_id 字段"
"或菜单 access 引用,实现权限分层;</li>"
"<li><strong>角色与用户的区别</strong>:组(Group)是权限集合,用户通过分配到组获得权限;</li>"
"<li><strong>安装顺序</strong>:依赖 edu_base 的模块会自动触发安装,通常无需单独启用。</li>"
"</ul>"
),
},
'learning_center': {
'introduction': (
"<p>「学习中心」提供课程的基础信息结构与完整教学链路,是课程内容建设的核心。</p>"
),
'features': (
"<ul>"
"<li><strong>课程 / 章节</strong>:课程下挂载章节,章节可挂资源;</li>"
"<li><strong>章节资源</strong>:视频、文档等课件管理;</li>"
"<li><strong>课程作业</strong>:布置作业与学员提交;</li>"
"<li><strong>成绩管理</strong>:成绩项定义与学员成绩;</li>"
"<li><strong>课程大纲 / 教学班</strong>:syllabus 与 teaching class 组织。</li>"
"</ul>"
),
'knowledge_points': (
"<ul>"
"<li><strong>课程 ≠ 教学班</strong>:课程是内容模板,教学班是学期/班级维度的开课实例;</li>"
"<li><strong>章节资源类型</strong>:支持视频、文档等多种资源,资源通过关系模型挂到章节下;</li>"
"<li><strong>作业与成绩联动</strong>:作业提交状态会作为成绩项的数据来源之一;</li>"
"<li><strong>大纲复用</strong>:课程大纲(syllabus)可被多个教学班引用,减少重复录入。</li>"
"</ul>"
),
},
'permission_manager': {
'introduction': (
"<p>「权限管理」提供可视化的角色与权限配置界面。</p>"
),
'features': (
"<ul>"
"<li><strong>角色(Role)</strong>定义与维护;</li>"
"<li>基于角色的权限分配视图;</li>"
"<li>与 edu_base 权限基座配合,细化授权。</li>"
"</ul>"
),
'knowledge_points': (
"<ul>"
"<li><strong>Role 模型</strong>:本模块新增独立的 Role 业务对象,可与 Odoo 原生组做映射;</li>"
"<li><strong>权限分配入口</strong>:通过表单/列表直接为角色勾选模型级 CRUD 权限;</li>"
"<li><strong>与 edu_base 的关系</strong>:edu_base 提供组定义,permission_manager 负责"
"把这些组分配给具体用户或角色。</li>"
"</ul>"
),
},
'student_organization': {
'introduction': (
"<p>「学生组织」是学生档案与年级 / 班级结构的基础模块,依赖 hr,"
"为教学体系提供组织骨架。</p>"
),
'features': (
"<ul>"
"<li><strong>学生组织</strong>:年级、班级等层级管理;</li>"
"<li><strong>学生信息</strong>:学生基本档案;</li>"
"<li><strong>基础年级</strong>:年级基础数据初始化。</li>"
"</ul>"
),
'knowledge_points': (
"<ul>"
"<li><strong>与 hr 的关系</strong>:学生档案复用 employee 模型扩展字段,"
"因此依赖 hr 模块;</li>"
"<li><strong>年级 → 班级 → 学生</strong>:组织层级自上而下引用,删除上级会受外键约束;</li>"
"<li><strong>基础数据</strong>:「基础年级」用于初始化常见年级字典,后续可在学生组织中引用。</li>"
"</ul>"
),
},
'yuthon_attendance': {
'introduction': (
"<p>「Yuthon 出勤管理」面向教职工的打卡出勤模块,自动计算工时、迟到与出勤状态。</p>"
),
'features': (
"<ul>"
"<li><strong>签到 / 签退</strong>:基于员工记录出勤;</li>"
"<li><strong>自动计算</strong>:工时、迟到分钟、出勤状态由计算字段得出;</li>"
"<li><strong>约束校验</strong>:一人一天一条,签到早于签退;</li>"
"<li><strong>出勤分析</strong>:graph / pivot 统计。</li>"
"</ul>"
),
'knowledge_points': (
"<ul>"
"<li><strong>唯一约束</strong>:同一员工同一天只能有一条出勤记录,避免重复打卡;</li>"
"<li><strong>状态计算逻辑</strong>:出勤状态由签到/签退时间与阈值比较得出,无需手动选择;</li>"
"<li><strong>工时公式</strong>:实际工时 = 签退时间 − 签到时间 − 扣除规则;</li>"
"<li><strong>与薪资联动</strong>:出勤结果会作为 yuthon_wage 计算月度工资的依据。</li>"
"</ul>"
),
},
'yuthon_employee': {
'introduction': (
"<p>「Yuthon 员工管理」是大学人事基础,管理教职工主数据,"
"是整个出勤—薪资体系的数据根。</p>"
),
'features': (
"<ul>"
"<li><strong>教职工档案</strong>:工号 / 部门 / 岗位 / 基本工资;</li>"
"<li><strong>唯一约束</strong>:工号不可重复;</li>"
"<li><strong>模块组合</strong>:被出勤、薪资模块通过 _inherit 扩展反向关联。</li>"
"</ul>"
),
'knowledge_points': (
"<ul>"
"<li><strong>工号是核心键</strong>:工号全局唯一,是出勤、薪资多条记录关联员工的基础;</li>"
"<li><strong>基本工资用途</strong>:基本工资字段写入员工档案,薪资模块每月读取并聚合;</li>"
"<li><strong>反向扩展模式</strong>:出勤、薪资模块通过 _inherit 员工模型添加字段,"
"保持主数据单一来源。</li>"
"</ul>"
),
},
'yuthon_login_theme': {
'introduction': (
"<p>「校园登录主题」是纯前端外观模块,将 Odoo 登录页美化为教育网站风格,"
"不新增任何业务数据。</p>"
),
'features': (
"<ul>"
"<li><strong>渐变背景</strong>:教育紫整页渐变;</li>"
"<li><strong>玻璃质感</strong>:登录卡片 + 品牌标题;</li>"
"<li><strong>主色统一</strong>:登录按钮与主题色一致。</li>"
"</ul>"
),
'knowledge_points': (
"<ul>"
"<li><strong>纯前端模块</strong>:只包含 SCSS / XML 视图资源,没有模型或业务逻辑;</li>"
"<li><strong>登录页覆盖</strong>:通过继承 Odoo 登录模板并覆盖样式实现;</li>"
"<li><strong>主题色变量</strong>:主色在 SCSS 变量中统一定义,修改一处即可全局生效。</li>"
"</ul>"
),
},
'yuthon_wage': {
'introduction': (
"<p>「Yuthon 薪资管理」在月底把员工基本工资与当月出勤结果聚合,"
"自动计算扣款与实发工资。</p>"
),
'features': (
"<ul>"
"<li><strong>月度工资条</strong>:基本工资 + 出勤聚合;</li>"
"<li><strong>自动扣款</strong>:迟到 / 缺勤按规则计算;</li>"
"<li><strong>批量生成</strong>:向导批量生成工资条;</li>"
"<li><strong>状态机</strong>:草稿 → 完成。</li>"
"</ul>"
),
'knowledge_points': (
"<ul>"
"<li><strong>工资条生成时机</strong>:通常每月月底运行向导,批量生成上月工资条;</li>"
"<li><strong>聚合逻辑</strong>:系统按员工汇总当月出勤记录的迟到、缺勤数据,"
"再与基本工资做扣款计算;</li>"
"<li><strong>状态流转</strong>:草稿状态可重新计算,完成后建议锁定,防止误改;</li>"
"<li><strong>与出勤模块的关系</strong>:yuthon_wage 依赖 yuthon_attendance,"
"考勤数据是薪资计算的关键输入。</li>"
"</ul>"
),
},
}
for name, vals in data.items():
rec = self.search([('name', '=', name)], limit=1)
if rec:
rec.write(vals)
# 确保来源字段对所有模块记录完成计算(覆盖历史模块记录)
self.search([])._compute_module_origin()