Intro
之前挖了个坑,一直没有动力去填:
咱今天就来打造一个 XJTU 评课社区。
该以什么样的形式呈现呢?
可能的解决方案
采用 ustc 评课社区的代码
最简单的做法是,克隆一下 ustc 评课社区的代码,部署一下即可
USTC 评课社区是使用 Python 3 + Flask + SQLAlchemy 开发的 Web 系统。
优点: 开发效率高,二次开发容易。USTC 评课社区的界面看起来挺清爽的,功能很丰富,还有 培养方案查询,最受欢迎的老师和课程,统计信息可视化,社区规范 和 投诉点评的流程 都有一定的参考价值。
缺点: 闭源依赖问题,MariaDB+Python 太重型以至于性能不行/对硬件要求高 :
再次扩容到 4 核 8G,CPU 仍然是 100%,但是访问变快了很多
最重要的缺点是无法利用现有的 Discourse 的功能。不过也许可以和交大門共用一套用户系统(SSO)。
基于 Lemmy 的二次开发
目前的 交大門 L 的 UI 有一点点像 USTC 评课社区,具有二次开发的可能性。
优点:
- Rust Actix 高性能、轻量、安全性
缺点:
- Rust 学习上手较难,生命周期 Borrow Checker 使得代码无法成功编译的可能性较大
使用各种编程语言从 0 开始开发
适合网络应用的开发编程语言、各种框架多得是。缺点是造轮子很不容易,优点是很锻炼开发者。
开发 Discourse 插件
可参考 Topic Ratings Plugin - plugin - Discourse Meta
优缺点
优点:
- 可以和交大門 现有的众多功能 有机地 结合起来,利用现有的用户系统,编辑器,匿名回复/发帖功能,Wiki 功能
- 考虑到 Discourse 使用的是 Ruby on rails 的技术栈,开发插件不难
- 不会因为 UI 完全不同造成其他板块割裂
- 可以复用到 导师信息 - 交大門 板块
缺点:
- 没法一上来就直接拥有 USTC 评课社区有的拥有众多成熟评课的功能
Steps
预备知识
Discourse 有丰富的开源插件和 Theme(Component),以下是官方的指南:
https://meta.discourse.org/t/beginners-guide-to-developing-discourse-themes/93648
https://meta.discourse.org/t/developing-discourse-plugins-part-1-create-a-basic-plugin/30515
业务逻辑和组织
## Data Models:
class 课程 { @linkable
@bindAction 收藏/关注
客观属性 {
学校的编号 Str
学分 Num
学时 Num
教学单位/学院 Enum @linkable
简介 Str
class 类型 {
层次(本科 / 硕 / 博)Enum
培养方案里要求为必修的学院/专业 Enum
选修课类型(核心/通识,对于必修课为 None)Option(Enum)
}
先修课程 NeedsPrerequisite List[Self] // 例如电路对于模拟电子技术而言
是先修课程 ProvidesPrerequisiteFor List[Self] // 和上一行相反
冲突课程 ConflictsWith List[Self] // 例如高数 I 和高数 II
类似/相关课程 List[Self]
}
-> Derived {
课程*好评*度
UpdatedAt Date
所有教学班评价的总结 Str
}
}
class 教学班 extends 课程 { @linkable
客观属性 += {
class 教师 { Str @unique @linkable
简介 Str
个人主页地址(gr.xjtu)Str
交大門教师信息地址 Str
-> Derived {
平均课程*好评*度
}
}
}
List[ @sortable by 评价的优质程度 &/ 开课学期(年份 + 季节)&/ 总体的推荐度
@groupable by 开课学期(年份 + 季节) &/ 总体的推荐度
class 评价信息 { @linkable
评价人 Str @unique @linkable
开课学期(年份 + 季节)Num+Enum @linkable @nullable
难度 Enum
作业量 Enum
给分吝惜度 Enum
总体学习收获多少 Enum
详细的文字评价 Str
总体的推荐度 Enum
UpdatedAt Date
class 他人对该评价的评价 { @linkable
Upvote (Informative / Neutral / Objective) Count(Bool)
Downvote (Low-entropy / Biased / Emotional) Count(Bool)
他人对该评价的文字评价 Str
}
-> Derived {
他人认为该评价的优质程度 Num
}
},
]
-> Derived {
教学班*好评*度
set(开课学期(年份 + 季节)) set(Num+Enum)
UpdatedAt Date
所有评价的总结 Str
}
}
## Views
// Basic Views
[_ for _ in all(课程)]
// _ 课程的所有教学班
[_.children for _ in all(课程)]
[_ for _ in all(教学班)]
[_ for _ in all(评价信息)]
// XX 教师的所有课程
[_ for _ in all(课程) if 课程。教师 == XX]
// XX 学院的所有课程
[_ for _ in all(课程) if 课程.(教学单位/学院) == XX]
信息格式
Dict 课程 {
客观属性 {
学校的编号 Str
学分 Num
学时 Num
教学单位/学院 Enum
简介 Str
Dict 类型 {
层次(本科 / 硕 / 博)Enum
选修课类型(核心/通识,对于必修课为 None)Option(Enum)
}
List[Dict 教学班信息 {
教师
开课学期(年份 + 季节)
...
},
]
Optional {
先修课程 NeedsPrerequisite List[Self] // 例如电路对于模拟电子技术而言
是先修课程 ProvidesPrerequisiteFor List[Self] // 和上一行相反
冲突课程 ConflictsWith List[Self] // 例如高数 I 和高数 II
类似/相关课程 List[Self]
}
}
}
临时的解决方法
将表格中的不同课程信息上传为不同的话题。
See Also
后续建设可以看看 USTC 评课社区背后的故事,USTC 学习资料。