根据前面的分析,前端业务逻辑主要实现以下内容:
一是实现教师领取教学任务的操作,即教师能够根据开设课程,自行领取教学课程;二是实现学生选课的操作,学生选课时,系统应能将可供选择的课程(系统中已有的、教师已经领取教学任务的课程)列出,学生从中选取感兴趣的课程;三是支持学生取消选课;四是支持教师取消教学任务(取消时,应注意应同时取消学生选课信息)。
与上小节类似,我们通过一个类来实现前端业务逻辑,并通过php服务提供操作接口,供前端界面调用。
(1)教师领取教学任务。若实现该操作,首先应提供未分配教学任务(课程),以供教师选取;之后是教师领取教学任务(课程)的实现,事实上,教师领取教学任务,即是对教学表进行插入数据的操作,其实现如下:
// 1.教师领取教学任务
function Teaching($t_id,$c_id){
// 查询是否有相同数据,防止重复插入
$sql = "SELECT * FROM teaching WHERE t_id=$t_id AND c_id=$c_id";
if($this->query($sql)!==false){
$this->error("数据库错误:向教学表中插入重复数据");
return false;
}
// ͨ依据$t_id,$c_id插入数据
$sql = "INSERT INTO teaching(t_id,c_id) values($t_id,$c_id)";
return $this->query($sql);
}
以上仅实现了领取教学任务的功能,至于查看未分配教学任务的课程,与学生选课时查看已分配教学任务课程类似,我们将其写成一个函数进行实现。
(2)学生选课
学生选课时,学生应能看到所有能够选取的课程(这里能够选取的课程,我们定义为:课程在课程表中,且已有教师领取了该课程的教学任务);然后是学生的实际选课的实现,学生实际选课,与教师领取教学任务类似,即向选课表中插入数据。具体实现如下:
首先是根据条件列出课程的实现:
// 2.列出课程
// 参数[type]:
// 1 : 列出全部课程
// 2 : 列出没有教师领取任务的课程,以便教师领取教学任务
// 3 : 列出已有教师领取任务的课程,以便学生选课
// 其他值暂时无效,程序不返回结果
function LoadCourse($type = 1) {
// 根据$type构建不同的查询语句
$sql = "";
if($type == 1) {
$sql = "SELECT * FROM course ";
}
else if($type == 2 ) {
// $type = 2 时,查询所有教学表中不存在的课程编号
// 注:教学表中没有该课程编号,表明没有教师领取该课程教学任务
$sql = "SELECT * FROM course WHERE c_id not in (SELECT c_id FROM teaching) ";
}
else if($type == 3) {
// $type = 3 时,查询所有教学表中已存在的课程编号
// 注:教学表中已存在该课程编号,表明有教师领取了该课程任务
$sql = "SELECT * FROM course WHERE c_id in (SELECT c_id FROM teaching)";
}
$course_list = array();
$query = $this->query($sql);
// 将查询结果转化为数组列表
while ($row = $this->fetch_array($query)) {
$course_list[] = array(
"c_name" => $row['c_name'],
"c_id" => $row['ID'],
"c_credit" => $row['c_creadit']
);
}
// 返回结果列表
return $course_list;
}
之后是学生选课的具体实现:
// 3.学生选课
function selection($s_id,$c_id) {
// 与教师领取教学任务类似==
// 查询是否有相同数据,防止重复插入
$sql = "SELECT * FROM selection WHERE s_id=$s_id AND c_id=$c_id";
if($this->query($sql)!==false){
$this->error("数据库错误:向选课表中插入重复数据");
return false;
}
// ͨ依据$s_id,$c_id插入数据
$sql = "INSERT INTO selection(s_id,c_id) values($s_id,$c_id)";
return $this->query($sql);
}
(3)学生取消选课
这个比较简单,只要删除选课表中对应的数据即可,具体实现如下:
// 4.取消选课
function de_selection($s_id,$c_id) {
// 删除时不必判断,直接删除
// ͨ依据$s_id,$c_id删除数据
$sql = "DELETE FROM selection WHERE s_id = $s_id AND c_id = $c_id)";
return $this->query($sql);
}
(4)教师取消教学任务
这个与学生取消选课类似,但是考虑到,学生选课时,必须选取已被教师领取教学任务的课程,因此,在教师取消教学任务时,必须同时取消该课程学生的选课数据。为了保持数据的一致性,这里,我们将这个操作通过MySQL的存储过程进行实现,而PHP通过调用该存储过程完成这个操作,具体为:
MySQL中的存储过程:
delimiter $
CREATE PROCEDURE de_teaching(IN tid int,IN cid int)
-- 声明删除教学任务的存储过程(函数)参数为教师ID和课程ID
BEGIN
DECLARE i_error integer; -- 定义一个变量,用于接收出错信息
DECLARE CONTINUE handler FOR SQLEXCEPTION SET i_error = 1; -- 一旦出错则将变量设置为1
START TRANSACTION ; -- 发起事务
DELETE FROM teaching WHERE t_ID=tid AND c_ID=cid; -- 删除教学表中有关该课程数据
DELETE FROM selection WHERE c_ID=cid; -- 删除选课表中有关该课程数据
IF i_error = 1 THEN -- 判断是否出错
ROLLBACK; -- 回滚事务
ELSE
COMMIT; -- 提交事务
END IF;
END $
调用该存储过程的PHP实现(即教师取消教学任务的实现):
// 5.取消教学任务
function de_teaching($t_id,$c_id) {
// ͨ依据$t_id,$c_id调用存储过程
$sql = "CALL de_teaching($t_id,$c_id)";
return $this->query($sql);
}
本节最后,我们需要说明的是,为了重复使用上一小节的数据库操作类DbMysql,我们使用了一个面向对象编程时经常用的“继承”定义,即,我们定义的新类(命名为:frontAction)集成于DbMysql,也就是说,frontAction类完全具有DbMysql的所有开放功能,同时还有我们新实现的该类所独有的功能,
示意图如下
具体写法如下:
// frontAction前端操作类继承DbMysql
class frontAction extends DbMysql {
… … // 此处为frontAction类特有的功能,即本小结实现的功能
}
本文实现的类文件(front.class.php和frontInterface.php)由本书所对应的网址另行发布。