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》就已经很好了。

所以还需要⾃动从教务系统获取课程表,学校⽤的新教务系统是:

第1页

Golang实战——微信公众号课程提醒系统

嗯,我研究了⼀下,他这个web端反爬⾍还是做的不错的,可以爬,但不好爬!那我们怎么搞到课表?

还好我发现了这个项⽬:/。这位⼤佬爬了强智的 App,抓出了这公司的 API。可以直接调⽤这个接⼝获取课表了:

第2页

Golang实战——微信公众号课程提醒系统

这个 API ⽂档做的挺好,⽆可挑剔;但这个 API 着实很恶⼼,看看他返回的课表:

Golang实战——微信公众号课程提醒系统

这就是我们“领先的教学⼀体化平台”——强(ruo)智教务系统!

我找不到⼀个合适的、不带个⼈感情⾊彩的词语来客观公正地评价这个设计。不管了,也只能将就着⽤了。肿的来说,我们的系统有两⽅⾯:

⼀个是输⼊(I):⾃动从教务系统获取课表;

还有是输出(O):⾃动提醒学⽣上课。

接下来我们就⼀步⼀步把这个系统实现:

设计与实现

第3页

数据库

⾸先是数据库设计。

本来写这东西 MongoDB ⽤挺⽅便的,但这学期有数据库课嘛,肯定不学这些 NoSQL,所以还是复习⼀下 SQL,⽤⼀下关系型数据库。其实这个东西挺传统啊,就是数据库书上的例⼦嘛,主要就三个表:

⼀个 Student 表,存学号、微信号(公众号⾥的openid)还有教务密码(这个可以不存的,存了还不安全,我不知道我设计的时候是怎么想的,后悔了,但懒得改 )

⼀个 Course 表,存课程名、上课时间、教室地点、授课⽼师…(就是强智API返回的那些)

还有就是 S-C 选课关系表。

最后,还有⼀个储存当前是那个学期之类的信息的表。

来看最后设计好的表结构:

Golang实战——微信公众号课程提醒系统

数据模型

有了数据库,我们还要在程序⾥使⽤数据库。也就要把数据库⾥的记录对应到程序⾥的结构体(Models)中。

为了⽅便(懒),我们直接把数据库⾥的东西对应过来,弄成这⼏个模型,⾥⾯的属性和数据库的属性⼀⼀对应(那个current太简单了,就是⼀个时间嘛, time.Time直接就可以⽤了,不⽤再去封装了):·Student

Course

Relationship

第4页

Golang实战——微信公众号课程提醒系统

蓝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。

这⼏个东西实现数据库与模型的转化,提供增删改查操作。

第5页