基于Laravel框架下实验室管理系统的编写

00

事情起源于9月。

在我漫长而又短暂的大学生涯中,最不喜欢的事是什么呢?

焊通用版。

最最不喜欢的事情是什么呢?

调通用版。

最最最不喜欢的事情是什么呢?

画通用版。

因此,在研0开学的时候,我卑微而又谦逊的和导师请求:

能不能不要做硬件,我想做软件

导师笑了笑:正好,现在有个软件要你做。

在完成了我的第一个活之后,第二个活来了。

要求:制作一个实验室管理系统,指纹认证、指纹登录,定时开关,远程预约。

02

在这之前,我用PHP写的大多是小项目,比如说比特币仪表盘,用SQL改改人民日报1946-2003的数据库,这是第一次接触大工程。

因此,首先要考虑的就是整个系统的组成。

整个系统由服务器、客户端、指纹认证、电源开关四个部分组成。

用户在完成指纹录入后,在有预约的前提下,服务器返回登录成功的数据,并打开电源开关。

时间到了之后,服务器发送到时间命令提示用户切断电源,2分钟后如果不切断电源,则记录当前用户信息。

如果用户在预约时间之前完成实验,则出门按指纹结束使用。

第一个问题是,服务器是用Linux服务器,还是Windows?

Linux服务器优点在于占用空间小、成本低;缺点是命令行不好维护,以及驱动安装和后续的优化问题;

Windows服务器优点在于方便安装操作、软件包固定、发行版唯一;缺点是网卡需要服务器网卡、占用资源大、功耗高。

由于专业软件的问题,不可能在开发机上运行Linux,因此我采用的是折中的方法,即开发用Windows,测试用Windows Subsystem for Linux,生产环境用Linux。

第二个问题,客户端用Qt,还是用VS?

这就要说起我的第一个活了。

我的第一个活是用Qt做的厨房监控以及传感系统。众所周知,Qt里面做传感器需要用VLC,而VLC是基于FFMPEG封装的一个库,而Qt的VLC已经很长时间没有更新了。并且,Qt-Vlc没有相应的编译好的库,要从源码编译。源码编译问题可就大了,根据不同的发行版、VC++的版本决定不同的编译器、链接器、解释器。最后我还花了2毛从CSDN上下了一个预编译的库,结果还是Release版本的,没法调试,因此,我之前的调试全在黑箱下面进行。

就这样在黑暗中摸索了一个月,在调整完Demo之后,我实在是受不了了,向导师提出:既然必须要VC++,也没有必须在Linux下,为什么不能直接用VS呢?

没想到,是我说晚了,其实只要功能实现,用什么语言客户并不介意。

于是,我用了3个小时,用XAML重写了我之前半个月用QML写的GUI。一边写,一边骂Qt,我是倒了八辈子霉才用QML写这个东西!

而且VLC-Csharp维护的人可不少,全都有预编译的库,并且一个回车就能搞定!

至于通信部分,又花了1个小时用Python把之前的通讯协议写好了。

最后是C#读取文件、拉直播流,然后Python通讯,C#只是一个壳子。

用什么语言已经不用多说了吧。

第三个问题,服务器用什么语言?

Python和PHP中我肯定是选PHP,虽然都是用C++写的,但是PHP的性能可比Python高多了,Php是为服务器而生,并且与Nginx的FASTCGI链接非常方便,关键是我不是很会Python和前端交互的手段。

第四个问题,纯PHP、ThinkPHP、Laravel?

纯PHP的工作流程是这样的:写HTML文件——中间插入<?php?>代码,归类整理文件,整理mod_rewrite文件,限制权限,最后测试发布;

ThinkPHP是国产框架,据说微软好的东西没学会,抛弃旧版本学的一个比一个快;

Laravel是世界上使用人数最多的框架,更新频繁,性能强大,路由表等常见功能直接封装好功能模块,写一行代码就行,缺点是不好学习。

既然要学习了,肯定要学习最好的框架,流行的框架肯定是有过人之处的。

因此,整个系统的框架如下所示:

系统的框架图

03

从下往上说,第一个介绍指纹模块。

这个指纹模块叫Live20R,文档更新于2016年,支持的语言有C、JAVA、Active X,Android、Linux、C#等等。是不是看起来支持非常广泛?

其实事情刚好相反,上面几个语言有一个共同特点:

他们都是基于C,或者能够调用C语言的方法!

反编译了Live20R的C#库以后,我才发现,这个库所有的东西都是基于C写的,剩下的只是调用和封装了一下而已。

这也就算了,大家都是编程的,理解一下也没什么大不了。

但是文档写错就不对了吧?

这个2016年的文档,不知道是哪位程序员跑路前写的,库函数和文档没一个对的上的,至于产品宣传页里说的什么储存指纹呢,其实是把指纹存到内存里,重启软件就没了。

因此,拿到库函数以后,第一件是就是要找到存储指纹、读取指纹的两个方法,把他们储存到SQLite/MySQL,这样就能在本地进行对比了。

客户端和服务器的交互利用Json+RESTAPI,用来动态同步用户数据。

04

指纹模块是个小程序,重头戏在Laravel上。

前端

一个现代化的完整的网站必须做到前后端分离,要做到这点是要用到Laravel的。

先从前端开始介绍:

Laravel的所有前端的JS和CSS都是通过包管理程序打包成ALL.CSS以及ALL.js的。

前端用的是pjax+Bootstrap+Fontawesome,要引入这两个js包,要在Laravel目录下运行前端打包工具,Laravel-Mix,即:

npm run dev

同时,在resouce/app.scss下加入以下内容:

@import 'node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss';
@import 'node_modules/@fortawesome/fontawesome-free/scss/regular.scss';
@import 'node_modules/@fortawesome/fontawesome-free/scss/solid.scss';
@import 'node_modules/@fortawesome/fontawesome-free/scss/brands.scss';
// Variables
@import 'variables';
// Bootstrap
@import '~bootstrap/scss/bootstrap';
SCSS和CSS有什么区别呢?
简单来说,SCSS就是动态的CSS。比如红色,在CSS中是#ff0000,在SCSS中可以引用为$red了。
这样,如果后期要引入新的JS/CSS,只要在这个目录下新增库的名字后,再用NPM安装就行了。
注意!某些JS库有先后引用顺序,如果合并后功能不正常,就要把这个库单独拿出来单独引用。
引用目录在public/js下,不是resource/js下

MVC结构

配置好基本的前端后,介绍一下Laravel的MVC结构:
MVC——指的是Model(模型)——View(视图)——Controller(控制器)

MVC结构

模型(Eloquent ORM),代表着存储的数据,这个模型和普通的模型概念可能不一样,叫做依赖注入,也就是数据的抽象。

软件的维护工作,本质上都是由“变化”引起的,只要软件还活着,我们就无法对抗变化,只能顺应它。而组件之间的依赖关系决定了变化的传导范围。

一般来说,当被依赖的组件变化时,其依赖者也会随之变化。软件开发最怕的就是牵一发而动全身。所幸,并不是每次变化都必然会传导给它的依赖者们。

对于具体实现细节的修改,只要没有改变其外部契约(可简单理解为接口),其依赖者就不需要修改。对于更大规模的修改,比如更换计费策略,我们是不是就无法控制其传播了?也不见得。只要我们的设计能让两者的接口保持一致,就可以把变化控制在尽可能小的范围内。

在我们的网站上,可以理解为用户这一模型不是某个特定用户,而是用户这个整体,在需要查询数据的时候,再实例化给某类查询,并返回结果。

视图,可以理解为前端,或者返回的数据的显示内容。

控制器,即后端,核心业务逻辑处理页面,控制器实例化模型,并处理数据传给视图。

路由表

下一个介绍的是Laravel的路由表(routes):

路由表是什么?比如说https://add.where.name/this-is-a-example/example?example=1

https称为协议,add称为二级域名,where.name称为顶级域名 /this-is-a-example/example称为路径,?example=1称为参数,值为1。

路径后面的值通过路由表传递给控制器,控制器再进行相应的操作。

前面提到过,路由表的方便在于不用自己写rewrite规则,方便程序归类整理,在route/web.php下添加:

Route::prefix('admin')->namespace('Admin')->group(function () {
Route::prefix('article')->group(function () {
Route::get('index', 'ArticleController@index');
Route::get('create', 'ArticleController@create');
Route::post('store', 'ArticleController@store');
});
});

就能实现在admin/article/index的get/post方法。

其中,prefix指的是网页路径,namespace指的是服务器文件路径。

路由可以编组,上面的代码指的是在Admin文件夹下的ArticleController控制器。

控制器

大家都知道,所有网站无非就是增删查改四种操作。

重复性的操作就不用我们自己写了,打开Laravel的目录,输入:

php artisan make:controller ArticleController --resource

打开这个文件,你会发现,显示,增删查改函数全部写好了。简直是太贴心了!

之后的事情就是写逻辑部分啦。

写完逻辑部分之后,记得和上面的路由表参数一样,@后面跟的是函数名,否则是进不去方法的。

 

这里多了一个小问题,如果路径带参数呢,比如要访问admin/1/这样的文件?

路径参数只要加个{}就行了,比如:

Route::get('{id?}', 'PermisstionController@index')->where('id', '[0-9]+');

这句话的意思是{id}参数可以不带,并且在id参数下只允许数字请求。

进入PermisstionController控制器:头部函数长这样:

 public function index($id=1){

……

}

这里,id参数就传进去了。$id=1的意思是参数默认的值为1。

那么,参数值怎么传进去呢?这里要用到Laravel自带的参数了:

    public function update(Request $request, $id)
{
try{
$input = $request->all();
if ($input['operate']=='update_seats')

}

注意,Laravel会自动进行Json解码,因此直接$input['operate']拿过来就可以,是不是既简单又方便?

数据库

依赖注入废话了半天,但是还得先说数据库:

要创建数据库,不用费劲的学SQL语言,Laravel全给你封装好了。

运行以下命令:

php artisan make:migration create_articles_table

Laravel就会在database/migrations生成一个迁移文件,打开这个文件,就能直接编辑要创建的数据表了。

参考资料的代码如下:

Schema::create('articles', function (Blueprint $table) {
$table->increments('id');
$table->integer('category_id')->unsigned()->default(0)->comment('分类id');
$table->string('title')->comment('标题');
$table->text('content')->comment('内容');
$table->timestamps();
$table->softDeletes();
});

相信应该不用过多解释了,一共就那么几种数据类型,一个回车就完事了。

表结构生成之后,输入:

php artisan migrate

你就发现Laravel自动进行迁移了。

如果发现不行了,点错了,只要输入:

php artisan migrate:rollback

就能回退上一步了。

模型

最关键的模型来了:

首先在命令行输入:

php artisan make:model Article

Article指的是上一步创建的表名,注意首字母大写,名字必须要一样!

之后输入:

php artisan make:controller ModelController

并添加路由:

Route::get('index', 'ModelController@index');

在ModelController中加入index方法:

public function index(Article $articleModel)
{
$data = $articleModel->get();
dump($data);
}

这样,Article模型就创建完成了。

咋一看有点看不懂,调用的时候就方便的很多了。

在传统的MySQL+PHP引用中,要根据PHP的版本先安装插件、然后引用插件、实例化、运行SQL语句,也就是大家都喜欢的“SELECT * FROM TABLE”;

在这里,我们只要这样:

$data = Article::select('id','name', 'email', 'provider')
->WhereBetween('id',[ $id , $id + 19 ])
->orderBy('id', 'desc')
->get();

就能获取到编码好的数据啦,而且非常的安全!

业务逻辑

业务逻辑方面,先介绍基本的流程,其实逻辑代码不多,就是RestAPI的增删查改。

  1. 用户注册——输入邮箱/Github登录——注册完成
  2. 用户登录——输入用户名密码/Github登录——登录成功
  3. 更改密码——发送至预留邮箱——找回密码
  4. 预约——选择可用教室——选择可用时段——选择可用座位——预约成功
  5. 取消预约——用户确认——座位释放——取消预约成功
  6. 指纹登录——检查预约——开启成功
  7. 指纹注销——检查预约——关闭成功
  8. 管理员——修改权限
  9. 管理员——修改教室时间/座位
  10. 管理员——修改指纹/登录指纹

 

先写到这里,预约还没做完,等我寒假慢慢写~

参考资料

最适合入门的laravel初级教程(一)序言

Laravel 入门到精通教程

futa: