文章目录
前言
- Author: 浅若清风cyf
- Date: 2021/1/4-2021/1/11
- 本文来源大三上学期《软件方向综合课程设计》
一、课程设计题目及内容
1.基本事实
(1)学生只属于一个班级(如计科181)
(2)计科18级有6个班级,一个班有一个班主任,一个老师可能当多个班班主任
(3)学生上专业课有专业必修课,专业选修课两种(选修课不是所有人都选的,为简化同个班选修须一起上)
(4)不同班可能一起上课(如181,182合班上数据库)
(5)一个老师可以属于多个课程组,一个课程组包括多个老师,其中一个是课程负责人
(6)一个老师可以教多门课,一门课可能多个老师教(例如计算机导论是多个老师上)
(7)同一个班同一门课可能有多个老师教(如导论)
(8)一个老师可能教同一个班多门课
(9)必修课必开;选修课不够人数就不开
2.时间
(1)1-16周,周一到周五,1-9节; 课程安排的时间长度必须和课程学分一致
(2)同个班同个小节不能上多门课,不同班同门课可能一起上
(3为减少工作量,不考虑全校必修课,全校选修课;只考虑本学院学生,只考虑本学院老师开课
3.用户
(1)学生:自己个人选选修课,查自己个人课表,查自己个人分数,查自己绩点;
(2)任课教师(属于老师,只可以给任教的课程分数查询和修改)
(3)系主任(也是老师之一),可以查看所有学生、课程、老师,但是只能修改自己任教课程的分数
二、实验环境(技术选型)
1、语言:C++
2、开发框架:Qt5.9 (64bit)
3、开发环境:Qt Creator 4.3.0
4、编译器:MSVC 2017 64bit
5、数据库:mysql5.7
注:【可能遇到的问题】
- ①mysql连接问题:需要将mysql的驱动放置到使用的编译器目录下,注意与编译器版本适配,可自行编译!参考:Qt客户端开发——与mysql数据库连接的驱动加载问题
②项目打包方法:Qt多版本共存情况下打包程序注意事项与数据库连接问题- ②项目打包之后,可能出现驱动丢失问题,解决方法参考:Qt多版本共存情况下打包程序注意事项与数据库连接问题
④MSVC编译器中文字符报错问题,解决方法:pro文件加入QMAKE_CXXFLAGS += /utf-8
三、需求分析设计
1、基本数据表
2、系统基本设计
3、E-R图
四、业务需求考虑
1.学生选专业选修课
(1)不可与已有课程冲突
(2)不可超过选修学分上限
(3)人数超过课程最大容量不可选
2.排课需求
(1)学生上专业课有专业必修课,专业选修课两种
(2)不同班可能一起上课
(3)一个老师可以属于多个课程组,一个课程组包括多个老师,其中一个是课程负责人
(4)一个老师可以教多门课,一门课可能多个老师教
(5)同一个班同一门课可能有多个老师教
(6)一个老师可能教同一个班多门课
(7)必修课必开
3.排课算法
(1)优先排多个班级上课的课程。
(2)遍历上课班级的课表,找出几个班级共同的空闲时间安排课程。
(3)根据课时对不同的课程有不同的安排,每学期16周,则48课时优先安排在1-16周的晚课时间;32课时优先安排在1-16周的白天时间;16课时多为实验课,实验课需要在理论课之后开启,因而优先安排在9-16周的白天。
4.学生个人课表查询
学生个人课表包括上课时间、对应时间上课科目、教师、上课地点、课程类型、考试类型。
5.班级课表查询
一个班级存在一个基本课表,这个班级的学生课表大致雏形即为班级课表,包括专业必修课、专业选修课、通识类必修课等专业安排课程。
6.教师个人课表查询
教师个人课表包括上课时间、对应时间上课科目、教师、上课地点、课程类型、考试类型。
7.教师查询选课学生表
教师可以查询到自己教授科目的学生选课情况,包括学号、姓名等基本信息。
8.教师登分
教师可输入已选自己教授科目的学生的成绩,进行登分,分数范围为0-100。
9.学生绩点排名
系统内部计算当前登录账号学生的绩点
五、系统功能与逻辑设计
1、教师系统、学生系统
2、管理员系统
六、UI设计及功能展示
1、登录界面
- 用户根据自己的身份选择登陆身份,输入账号和密码完成登陆操作【不同身份系统会分别去admin表、teacher表、student表中查询用户账号信息】
2、找回密码
- 用户可以根据验证用户信息中预留的邮箱来找回密码。用户输入账号和邮箱,系统会自动根据邮箱与用户预留邮箱进行匹配。若匹配成功,系统将向邮箱发送6位数的随机数验证码,用户接收到验证码后,输入到验证码一栏,并设置新密码,提交系统修改。若验证码正确,则修改成功,否则,拒绝修改。
3、管理员功能面板
- 管理员系统包含三个主要功能:学生信息维护、课程信息维护以及修改密码。
4、学生信息维护界面
- 管理员能够按照专业和班级获取班级学生的信息,能够对表格中学生信息进行修改并提交到数据库中,能够在提交到数据库之前撤销对表格数据的修改,能够选择表格中对应学生所在的单元格,从数据库中删除学生记录,并更新班级学生信息。能够增加新增学生记录空白行,并录入新增学生信息,提交到数据库并刷新班级学生信息。
5、管理员查询教师课表、手动排课界面
- 管理员能够为教师添加课程:点击添加课程对应时间的起始单元格,选择课程,设置授课班级,上课周次,小节数,上课地点信息,然后点击添加按钮,添加到数据库并刷新课表。
- 管理员能够删除教师课表上的课程:点击课表中的课程,点击删除按钮,系统会从数据库的课程池中删除相应的记录,并刷新课表。
6、管理员查询班级课表、为班级安排必修课界面
- 管理员能够在班级列表中选择相应的班级,查看到班级的课表信息【只显示必修课程】。能够为班级添加、删除必修课程。添加课程操作方式:选择课程名->选课教学班->点击添加课程按钮。删除课程方式与教师排课系统相同。
7、为班级安排必修课程时间
- 智能排课系统:点击智能排课按钮,系统将自动为专业的各个班级安排所有的必修课程的时间,更新数据库课程池表相关自动的Time字段。刷新课表可以看到添加到课表中的课程。(由于计科班级原本已经有数据,而软件班级的班级课表为空,为了方便测试,将计科的必修课程添加到软件班级的课表中)
8、管理员修改密码
- 管理员登录成功后,点击修改密码之后,在修改密码的弹窗中两次输入新密码即可完成修改密码操作。
9、教师功能面板
- 教师系统包含四个主要功能:教师个人课表查询、选课/成绩管理、、修改密码、以及系主任特有的年级所有学生信息查询。
- 系主任非系主任
10、教师课表查询
- 教师可以手动选课要开设的课程,操作与管理员端的教师排课系统相同。
11、教师查询课程选课学生信息和修改/录入成绩
-
教师可以选择自己上课的教学班,查到教学班选课学生的信息,并且可以在成绩一列输入或修改成绩,并提交到数据库更新数据。
12、教师修改密码
13、系主任查询学院学生信息(按班级)
- 系主任拥有查询全年级班级学生信息的权限,能够按班级显示学生信息,但没有修改数据的权限。
14、学生功能面板
- 学生系统包含四个主要功能:学生选课、课表查询、课程成绩及绩点查询、修改密码。
15、学生选课系统
- 学生能够退选已选上的课程,能够选课(一门课程仅能选择一个教学班)。
- 学生能够选中相应的教学班,查看对应教师的基本信息。
- 系统能够对学生选课信息与学生个人课表进行比较,检测新增课程时间是否与现有课程冲突,若冲突,则拒绝选课操作。
- 系统能判断选课人数是否操作教学班课程的最大容量上限,如选课人数已满,则拒绝选课操作。
16、学生查询个人课表
- 学生点击查询课表按钮可以获得个人专业必修和专业选修课程的信息,显示在课表中。
17、学生成绩查询
- 学生能够查询到自己选课课程的基本信息以及成绩,点击绩点查询按钮能够弹窗显示绩点信息。
18、学生修改密码
七、实验结果分析,实验收获和体会
1.实验结果分析:
(1)本实验通过业务需求分析,设计了各个基本表及其属性,并考虑各表存在的关系,完成了关系数据库的设计。
(2)实验GUI使用Qt5.9进行设计,并通过与数据库进行连接,对数据执行增删改查,完成用户交互设计,基本满足了用户的需求。
(3)本实验中选课、调课等业务逻辑进行了一定的简化,与实际应用还有一些差距,需要考虑的因素有很多。
2.实验收获和体会:
(1)熟练使用SQL语言操作MySQL数据库,对数据进行增删改查
(2)对使用Power Designer进行建表及数据结构构造等有了更深层次的理解。
(3)提高了根据给定的题目进行业务分析与业务逻辑设计的能力
(4)学习使用Qt进行数据库连接,以及使用QSqlTableModel类对查询数据库、插入、更新数据。
(5)提高了根据业务需求设计用户交互界面的能力,进一步熟悉Qt开发框架中各个控件的使用,学会设计简洁合理的交互界面。
(6)提高了对系统全局功能合理布局、拆分、复用的能力。
八、下载地址
- 由于数据库数据涉及个人信息,以及考虑到邮箱找回密码涉及博主本人密钥的安全性,只提供核心源码,同时提供打包软件以及SQL基本表的sql脚本。
注:数据库配置需要与后文数据库源码的设置相同才能连接上数据库!
-
使用方法:运行sql脚本在主机创建相应的数据库,自行添加用户信息,解压软件,双击运行exe文件理论上即可使用。
-
编辑打包文件:JWXT_GZHU_v1.0
-
2021.12.19更新:
-
公开完整源码(已删除敏感数据):
JWXT_GZHU_public
九、文件目录及核心源码
1、文件目录
2、数据库连接
QSqlDatabase db=QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setUserName("root");
db.setPassword("123456");
db.setDatabaseName("jwxt_gzhu");
bool bRet=db.open();
if(bRet==false)
{
qDebug()<<"error open database"<<db.lastError().text();
QMessageBox::warning(this,"数据库连接失败","数据库无法连接,请联系管理员处理!");
exit(0);
}
qDebug()<<"open database success";
3、登录窗口
- 系统根据身份选择查询数据库在对应的数据库中验证账号信息,登录成功后创建对应身份的用户的功能面板窗口。
- 身份设定:管理员:identity=0,教师:identity=1,学生:identity=2
//登录按钮
connect(ui->login,&QPushButton::clicked,this,[=](){
if(indentity==0){
qDebug()<<"管理员登录 ";
//获取输入的账号密码
QString id = ui->id_input->text();
QString pwd=ui->pwd_input->text();
//查询admin表
QSqlTableModel model;
model.setTable("admin");
model.select();
int rowCount=model.rowCount();
bool loginSuccess=false;
for(int i=0;i<rowCount;++i)
{
QSqlRecord record=model.record(i);
if(record.value(0)==id&&record.value(1)==pwd)
{
qDebug()<<"账号密码与数据库匹配成功!";
adminWin=new AdminWin(id);
this->hide();
adminWin->show();
loginSuccess=true;
break;
}
}
if (loginSuccess==false)
QMessageBox::warning(this,"登录失败","账号或密码错误!请重新输入!");
}
else if(indentity==1){
qDebug()<<"教师登录 ";
//获取输入的账号密码
QString id = ui->id_input->text();
QString pwd=ui->pwd_input->text();
qDebug()<<"获取到的账号:"<<id<<"密码:"<<pwd;
//查询teacher表
QSqlTableModel model;
model.setTable("teacher");
model.select();
int rowCount=model.rowCount();
bool loginSuccess=false;
for(int i=0;i<rowCount;++i)
{
QSqlRecord record=model.record(i);
if(record.value(0)==id&&record.value(4)==pwd)
{
qDebug()<<"账号密码与数据库匹配成功!";
teacherWin=new TeacherWin(id);
this->hide();
teacherWin->show();
loginSuccess=true;
break;
}
}
if (loginSuccess==false)
QMessageBox::warning(this,"登录失败","账号或密码错误!请重新输入!");
}
else{
qDebug()<<"学生登录 ";
//获取输入的账号密码
QString id = ui->id_input->text();
QString pwd=ui->pwd_input->text();
qDebug()<<"获取到的账号:"<<id<<"密码:"<<pwd;
//查询teacher表
QSqlTableModel model;
model.setTable("student");
model.select();
int rowCount=model.rowCount();
bool loginSuccess=false;
for(int i=0;i<rowCount;++i)
{
QSqlRecord record=model.record(i);
if(record.value(0)==id&&record.value(5)==pwd)
{
qDebug()<<"账号密码与数据库匹配成功!";
studentWin=new StudentWin(id);
this->hide();
studentWin->show();
loginSuccess=true;
break;
}
}
if (loginSuccess==false)
QMessageBox::warning(this,"登录失败","账号或密码错误!请重新输入!");
}
});
4、定义的与数据库访问相关的函数
class SqlTools
{
public:
SqlTools();
//根据身份和id、需要的字段名获取对应字段
QVariant getPersonalInfo(int identity,QString id,QString infoNeed);
//查询course表获取所有课程id //type:查询课程类别:0:all,1:必修,2:选修
QVariantList getCourseIds(int type);
//查询course表获取课程的基本信息
QSqlRecord getCourseInfo(QString id);
//查询coursePool表,获取开课信息
QList<QSqlRecord> getCourseOpenInfo(QString courID);
//查询sc表,获取某门课的选课学生人数
int getCourseSelectCount(QString CPID);
//查询sc表,判断一门课程是否有选择
bool isSelectCourse(QString stuID,QString CPID);
//查询sc表,获取学生个人选课情况
QList<QSqlRecord> getStuSelectCourses(QString stuID);
//查询coursePool表,获取教师选课情况
QList<QSqlRecord> getTeaSelectCourses(QString teaID);
//向sc表添加选课记录
bool addCourseRecord(QString stuID,QString CPID);
//从sc表中删除选课记录
bool removeCourseRecord(QString stuID,QString CPID);
//查询coursepool表获取信息
QSqlRecord coursePoolInfo(QString CPID);
//弹窗显示指定教师信息
void showTeacherInfo(QString TeaName);
//根据查询条件获取课程信息
QList<QSqlRecord> getCourses(QString filter,QString value);
//获取指定表某个字段的值
QList<QVariant> getTableColumnList(QString tableName,QString fieldName);
//根据教师姓名获取教师id
QString getPersonalIDbyName(int identity,QString name);
//从coursepool删除课程
bool removeCourseFromCoursepool(QString CPID);
//根据条件获取表中满足条件的所有记录
QList<QSqlRecord> getFilterRecords(QString tableName,QString filter,QString value);
private:
QSqlTableModel* model;
};
5、课表系统定义的函数(课表查询、排课、增删课程等)
class CourseTable;
}
class CourseTable : public QWidget
{
Q_OBJECT
public:
explicit CourseTable(int identity,QString id,QWidget *parent = 0);
~CourseTable();
private:
Ui::CourseTable *ui;
int identity;
QString id;
SqlTools * sqlTool;
//查询数据库获取课表信息
public slots:
void getCourseToTable();
void getCourse();
void addCourse();
void removeCourse();
void getClassCourse();
void getCoursepoolList();
void addCourseForClass(); //为班级添加课程【修改coursePool表中的开课班级字段】
void removeCourseForClass(); //为班级移出课程【修改coursePool表中的开课班级字段】
void autoScheduleCourse(); //智能排课
QString getDay(int column); //数字转周数,如:1->星期一
QString getSection(int section); //第几大节转小节,如:1->1-2节
};
6、学生信息管理系统定义的函数
class studentInfoManage : public QWidget
{
Q_OBJECT
public:
explicit studentInfoManage(QWidget *parent = 0);
~studentInfoManage();
private:
Ui::studentInfoManage *ui;
QSqlTableModel* model;
QTableView* view;
QVBoxLayout* lay;
QStandardItemModel* addRecordTable;
// QSqlTableModel* modelAdd;
// QTableView* viewAdd;
// QVBoxLayout* layAdd;
public slots:
void addClassName(); //添加班级名称(根据专业从数据库读取)
void selectClassAndShowTable(); //选择班级并刷新班级学生信息
void addRecord(); //向表中添加新的记录
void addCommit(); //提交新增数据
void modifyComfirm(); //确认修改数据(提交数据库)
void modifyRestore(); //撤销修改
void removeRecords(); //删除选择的记录
void hideModifyTools();
void setTitle(QString title);
};
7、学生选课系统定义的函数
class Course_Selection;
}
class Course_Selection : public QWidget
{
Q_OBJECT
public:
explicit Course_Selection(QWidget *parent = 0);
explicit Course_Selection(QString id,QWidget *parent = 0);
~Course_Selection();
void getID(QString id);
void welcome();
private:
Ui::Course_Selection *ui;
QString userId;
QSqlTableModel* model;
SqlTools* sqlTool;
QTreeWidgetItem* currentItem;
public slots:
void getCourses(int courseType); //查询数据库可选的课程,添加到窗体树形控件
void selectCourse(); //学生选课,sc表增加记录
void cancelSelectCourse(); //退课,从sc表删除记录
void showCourseTeacherInfo(); //获取教师信息
};