(1)学生只属于一个班级(如计科181)
(2)计科18级有6个班级,一个班有一个班主任,一个老师可能当多个班班主任
(3)学生上专业课有专业必修课,专业选修课两种(选修课不是所有人都选的,为简化同个班选修须一起上)
(4)不同班可能一起上课(如181,182合班上数据库)
(5)一个老师可以属于多个课程组,一个课程组包括多个老师,其中一个是课程负责人
(6)一个老师可以教多门课,一门课可能多个老师教(例如计算机导论是多个老师上)
(7)同一个班同一门课可能有多个老师教(如导论)
(8)一个老师可能教同一个班多门课
(9)必修课必开;选修课不够人数就不开
(1)1-16周,周一到周五,1-9节; 课程安排的时间长度必须和课程学分一致
(2)同个班同个小节不能上多门课,不同班同门课可能一起上
(3为减少工作量,不考虑全校必修课,全校选修课;只考虑本学院学生,只考虑本学院老师开课
(1)学生:自己个人选选修课,查自己个人课表,查自己个人分数,查自己绩点;
(2)任课教师(属于老师,只可以给任教的课程分数查询和修改)
(3)系主任(也是老师之一),可以查看所有学生、课程、老师,但是只能修改自己任教课程的分数
注:【可能遇到的问题】
- ①mysql连接问题:需要将mysql的驱动放置到使用的编译器目录下,注意与编译器版本适配,可自行编译!参考:Qt客户端开发——与mysql数据库连接的驱动加载问题
②项目打包方法:Qt多版本共存情况下打包程序注意事项与数据库连接问题- ②项目打包之后,可能出现驱动丢失问题,解决方法参考:Qt多版本共存情况下打包程序注意事项与数据库连接问题
④MSVC编译器中文字符报错问题,解决方法:pro文件加入QMAKE_CXXFLAGS += /utf-8
(1)不可与已有课程冲突
(2)不可超过选修学分上限
(3)人数超过课程最大容量不可选
(1)学生上专业课有专业必修课,专业选修课两种
(2)不同班可能一起上课
(3)一个老师可以属于多个课程组,一个课程组包括多个老师,其中一个是课程负责人
(4)一个老师可以教多门课,一门课可能多个老师教
(5)同一个班同一门课可能有多个老师教
(6)一个老师可能教同一个班多门课
(7)必修课必开
(1)优先排多个班级上课的课程。
(2)遍历上课班级的课表,找出几个班级共同的空闲时间安排课程。
(3)根据课时对不同的课程有不同的安排,每学期16周,则48课时优先安排在1-16周的晚课时间;32课时优先安排在1-16周的白天时间;16课时多为实验课,实验课需要在理论课之后开启,因而优先安排在9-16周的白天。
学生个人课表包括上课时间、对应时间上课科目、教师、上课地点、课程类型、考试类型。
一个班级存在一个基本课表,这个班级的学生课表大致雏形即为班级课表,包括专业必修课、专业选修课、通识类必修课等专业安排课程。
教师个人课表包括上课时间、对应时间上课科目、教师、上课地点、课程类型、考试类型。
教师可以查询到自己教授科目的学生选课情况,包括学号、姓名等基本信息。
教师可输入已选自己教授科目的学生的成绩,进行登分,分数范围为0-100。
系统内部计算当前登录账号学生的绩点
(1)本实验通过业务需求分析,设计了各个基本表及其属性,并考虑各表存在的关系,完成了关系数据库的设计。
(2)实验GUI使用Qt5.9进行设计,并通过与数据库进行连接,对数据执行增删改查,完成用户交互设计,基本满足了用户的需求。
(3)本实验中选课、调课等业务逻辑进行了一定的简化,与实际应用还有一些差距,需要考虑的因素有很多。
(1)熟练使用SQL语言操作MySQL数据库,对数据进行增删改查
(2)对使用Power Designer进行建表及数据结构构造等有了更深层次的理解。
(3)提高了根据给定的题目进行业务分析与业务逻辑设计的能力
(4)学习使用Qt进行数据库连接,以及使用QSqlTableModel类对查询数据库、插入、更新数据。
(5)提高了根据业务需求设计用户交互界面的能力,进一步熟悉Qt开发框架中各个控件的使用,学会设计简洁合理的交互界面。
(6)提高了对系统全局功能合理布局、拆分、复用的能力。
注:数据库配置需要与后文数据库源码的设置相同才能连接上数据库!
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";
//登录按钮
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,"登录失败","账号或密码错误!请重新输入!");
}
});
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;
};
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节
};
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);
};
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(); //获取教师信息
};