Golang实战——微信公众号课程提醒系统
Golang 实战——微信公众号课程提醒系统
起因
最早开始学 Golang 已经是整整⼀年前了,当时就把基础语法那⼀块学完了,然后拿 Golang 写了点 leetcode 题。之后由于项⽬⾥⼀直⽤Python 和 Java,Golang 这⼀块就搁置下来没学了。
之前寒假本来是打算学 iOS、Mac 开发这⼀块的,搞了两个星期,感觉暂时不想学下去了。(我想学 SwiftUI,我觉得这才够酷,但我不想拿赖以⽣存的⽼ Macbook 尝试 Catalina,Mojave 写 SwiftUI 没有及时预览,感觉没有灵魂了。)
所以就搬出 Golang 来接着学了。看完了函数、接⼝、并发这⼀块,然后就学了⼀些 Web 开发⽅⾯的。(这才实在,不然语⾔学完就只能刷 leetcode。)
学完了差不多就开学了,刚好我⼀直憎恶超级课程表⼴告的烦扰,所以就打算写⼀个可以⾃动从教务系统获取课程表、在上课前提醒的课程表项⽬。这个照理来说是个前端项⽬,但 iOS 开发这⼀块还没学完。本来 Android 也⾏,但我⽤ iPhone 啊。所以想了个曲线救国的⽅法——微信公众号开发,纯后端,拿来练习 Golang 再好不过。
我在这个项⽬中的很多地⽅尝试了 Golang 的“⾯向对象”。Go 不是⼀个⾯向对象的语⾔,这给写惯了 Java、Python 的我们还是带来了⼀些不适应的。但没关系,正如它的发明者们所说,Go 是⽤来构建系统的实⽤语⾔。⾯向对象不可否认是构建系统的强有⼒⼯具,Golang 当然会有所⽀持。当然,也只是有所⽀持,⽽不是真正的⾯向对象,我在 coding 的时候,就在⼀个需要多态的地⽅碰到了困难,最后不得不更改设计,稍微没那么优雅了。
在这篇⽂章中,我尝试记录我开发这个系统的整个过程、解释尽可能多的代码设计。但因为毕竟整个项⽬有接近3000⾏代码,我不可能逐⼀解释到位。如果你想看懂所有东西,请去 GitHub 打开这个项⽬的源码对照来看,我也是个初学者,写出的代码应该还是很简单的。
另外,这篇⽂章不是 Golang 的⼊门,在开始阅读前请确保你掌握了(起码是有所了解)以下技能:
Go语⾔基础: :全部内容;
Go语⾔Web开发基础: :1~7章;
微信公众号开发基础: :1、2、4节;
⽬标
我的⽬的很明确,就是做⼀个微信公众号系统,在上课前发个通知提醒快上课了。但我不想⼿动输⼊课程信息,不然 iDaily Corp 开发的《课程表·ClassTable》就已经很好了。
所以还需要⾃动从教务系统获取课程表,学校⽤的新教务系统是:
嗯,我研究了⼀下,他这个web端反爬⾍还是做的不错的,可以爬,但不好爬!那我们怎么搞到课表?
还好我发现了这个项⽬:/。这位⼤佬爬了强智的 App,抓出了这公司的 API。可以直接调⽤这个接⼝获取课表了:
这个 API ⽂档做的挺好,⽆可挑剔;但这个 API 着实很恶⼼,看看他返回的课表:
这就是我们“领先的教学⼀体化平台”——强(ruo)智教务系统!
我找不到⼀个合适的、不带个⼈感情⾊彩的词语来客观公正地评价这个设计。不管了,也只能将就着⽤了。肿的来说,我们的系统有两⽅⾯:
⼀个是输⼊(I):⾃动从教务系统获取课表;
还有是输出(O):⾃动提醒学⽣上课。
接下来我们就⼀步⼀步把这个系统实现:
设计与实现
数据库
⾸先是数据库设计。
本来写这东西 MongoDB ⽤挺⽅便的,但这学期有数据库课嘛,肯定不学这些 NoSQL,所以还是复习⼀下 SQL,⽤⼀下关系型数据库。其实这个东西挺传统啊,就是数据库书上的例⼦嘛,主要就三个表:
⼀个 Student 表,存学号、微信号(公众号⾥的openid)还有教务密码(这个可以不存的,存了还不安全,我不知道我设计的时候是怎么想的,后悔了,但懒得改 )
⼀个 Course 表,存课程名、上课时间、教室地点、授课⽼师…(就是强智API返回的那些)
还有就是 S-C 选课关系表。
最后,还有⼀个储存当前是那个学期之类的信息的表。
来看最后设计好的表结构:
数据模型
有了数据库,我们还要在程序⾥使⽤数据库。也就要把数据库⾥的记录对应到程序⾥的结构体(Models)中。
为了⽅便(懒),我们直接把数据库⾥的东西对应过来,弄成这⼏个模型,⾥⾯的属性和数据库的属性⼀⼀对应(那个current太简单了,就是⼀个时间嘛, time.Time直接就可以⽤了,不⽤再去封装了):·Student
Course
Relationship
蓝T是结构体,下⾯的黄f是属性,红f是函数/⽅法
(这些图都是从 IDEA 截图出来⾃⼰随⼿拼的,没时间好好调,所以有点丑)
(对,没错,我⽤ IDEA 写 Golang,MacBook 硬盘⼩鸭,没办法,咱坚强的 IDEA 带上⼏个插件就肩负起了我家 Java、Android、Python、Go 的所有“⼤型“项⽬开发)
注意这⾥强智系统API请求来的课程是没有 cid 的,但我们为了唯⼀识别⼀个课程,所以在构造函数 NewCourse ⾥⾃动通过计算Name,Teacher,Location,Begin,End,Week,When 的 md5 和得出。
有了模型,我们再实现数据操作(Data) :StudentDatabase、CourseDatabase、StudentCourseRelationshipDatabase。
这⼏个东西实现数据库与模型的转化,提供增删改查操作。