文章目录
- 需求
- 系统简介
- 身份介绍
- 机房介绍
- 申请简介
- 系统具体需求
- 实现
- 菜单与退出功能
- 实现
- 功能测试
- 创建身份类
- 创建角色基类
- 创建学生类
- 创建教师类
- 创建管理员类
- 登录模块
- 功能描述
- 登录函数封装
- 各个校色具体登录验证
- 管理员操作界面调用流程
- 管理员模块
- 构造函数实现
- 管理员子菜单显示
- 添加账号功能实现
- 初始化、加载文件、添加校验操作
- 查看账号
- 查看机房信息
- 新建机房管理类
- 添加加载机房信息功能
- 添加展示机房信息功能
- 清空预约记录
- 预约模块
- 构造函数
- 更新预约记录功能
- 学生模块
- 构造函数
- 学生菜单模块
- 申请预约功能
- 查看自身预约
- 查看所有预约
- 取消预约
- 教师模块
- 构造函数实现
- 菜单功能实现
- 查看所有预约
- 审核预约
需求
系统简介
- 解决多用户使用多机房需求
身份介绍
-
学生代表:申请使用机房
-
教师:审核学生的预约申请
-
管理员:给学生、教师创建账号
机房介绍
-
1号机房,最多容纳20人
-
2号机房,最多容纳50人
-
3号机房,最多容纳100人
申请简介
-
申请的订单每周由管理员负责清空
-
学生可以预约未来一周机房的使用,预约周期为周一至周五,预约时段为(上午、下午)
-
教师来审批预约,依据实际情况来审批通过或者不通过
系统具体需求
实现
菜单与退出功能
- 与用户交流界面
实现
- 新建
machineRoomManager.hpp
,添加展示菜单和退出声明
#pragma once#include <iostream>using namespace std;class MachineRoomManager {
public:// 构造函数MachineRoomManager();// 菜单展示void showMenu();// 退出void logout();// 析构函数~MachineRoomManager();
};
- 新建
machineRoomManager.cpp
,实现展示菜单功能
// 菜单展示
void MachineRoomManager::showMenu() {cout << "欢迎使用机房管理系统" << endl;cout << "请输入你的身份" << endl;cout << "1.学生代表" << endl;cout << "2.老师" << endl;cout << "3.管理员" << endl;cout << "4.退出" << endl;cout << "请输入你的选择:";
}
// 退出
void MachineRoomManager::logout() {cout << "即将退出系统..." << endl;exit(0);
}
功能测试
- 新建
main.cpp
,提供主页面用户交互流程
#include "machineRoomManager.hpp"int main() {int choice;MachineRoomManager mrm;while (true) {mrm.showMenu();cin >> choice;switch (choice) {case 1:// 1.学生代表break;case 2:// 2.老师break;case 3:// 3.管理员break;case 4:// 4.退出mrm.logout();break;default:cout << "输入非法,请重新输入" << endl;break;}}
}
- 结果展示
创建身份类
- 系统总共有三种身份,有共性也有特性,因此抽象出一个角色基类
创建角色基类
- 新建
role.hpp
,创建抽象类,可以用户名密码是公共属性
#pragma once#include <iostream>using namespace std;class Role {
public:// 操作界面virtual void operatorMenue()=0;// 姓名string name;// 密码string password;
};s
创建学生类
- 新建
student.hpp
,继承自Role类,提供学生具有的成员函数和属性
#pragma once#include "role.hpp"class Student : public Role {
public:// 构造函数Student();Student(int id, string name, string password);// 操作界面void operatorMenue();// 申请预约void applyOrder();// 查看自身预约void showSelfOrder();// 查看所有的预约void showAllOrder();// 取消预约void cancelOrder();// 析构函数~Student();// 学号int studentId;
};
- 新建
student.cpp
实现类,先给出各种功能的空实现
#include "student.hpp"// 构造函数
Student::Student() {}Student::Student(int id, string name, string password) {this->studentId = id;this->name = name;this->password = password;
}// 操作界面
void Student::operatorMenue() {}// 申请预约
void Student::applyOrder() {}// 查看自身预约
void Student::showSelfOrder() {}// 查看所有的预约
void Student::showAllOrder() {}// 取消预约
void Student::cancelOrder() {}Student::~Student() {}
创建教师类
- 新建
teacher.hpp
,继承自Role类,提供老师具有的成员函数和属性
#pragma once#include "role.hpp"class Teacher : public Role {
public:// 操作界面void operatorMenue();Teacher();Teacher(int id, string name, string password);// 查看所有预约void showAllOreder();// 审核预约void checkOrder();// 退出登录void logout();// 职工号int teacheId;
};
- 新建
teacher.cpp
实现类,先给出各种功能的空实现
#include "teacher.hpp"Teacher::Teacher() {}Teacher::Teacher(int id, string name, string password) {this->teacheId = id;this->name = name;this->password = password;
}// 操作界面
void Teacher::operatorMenue() {}// 查看所有预约
void Teacher::showAllOreder() {}// 审核预约
void Teacher::checkOrder() {}// 退出登录
void Teacher::logout() {}
创建管理员类
- 新建
manager.hpp
,继承自Role类,提供管理员具有的成员函数和属性
#pragma once#include "role.hpp"class Manager : public Role {
public:Manager();Manager(string name, string password);// 操作界面void operatorMenue();// 添加账号void addAccount();// 查看账号void showAccount();// 查看所有机房信息void showComputer();// 清空预约记录void cleanFile();~Manager();
};
- 新建
manager.cpp
实现类,先给出各种功能的空实现
#include "manager.hpp"Manager::Manager() {}Manager::Manager(string name, string password) {this->name = name;this->password = password;
}// 操作界面
void Manager::operatorMenue() {}// 添加账号
void Manager::addAccount() {}// 查看账号
void Manager::showAccount() {}// 查看所有机房信息
void Manager::showComputer() {}// 清空预约记录
void Manager::cleanFile() {}Manager::~Manager() {}
登录模块
功能描述
-
不同的身份可能会用到不同的文件操作,我们将所有文件名定义到同一个全局文件中
-
新建
globalFile.hpp
文件
#pragma once// 管理员文件
#define ADMIN_FILE "admin.txt"
// 教师文件
#define TEACHER_FILE "teacher.txt"
// 学生文件
#define STUDENT_FILE "student.txt"
// 机房信息文件
#define MACHINE_FILE "machine.txt"
// 订单文件
#define ORDER_FILE "order.txt"
登录函数封装
- 在
machineRoomManager.hpp
,添加登录声明
// 登录void login(string fileName, int type);
- 在
machineRoomManager.cpp
,实现登录
// 登录
void MachineRoomManager::login(string fileName, int type) {// 父指针 用于指向子类的对象Role *r = NULL;// 读文件ifstream ifs;ifs.open(fileName, ios::in);if (!ifs.is_open()) {cout << "文件不存在" << endl;ifs.close();return;}char ch;ifs >> ch;if (ch == EOF) {cout << "文件为空" << endl;return;}ifs.putback(ch);// 准备接收输入int id = 0;string name;string pwd;// 身份判断if (type == 1) {cout << "请输入学号:" << endl;cin >> id;} else if (type == 2) {cout << "请输入职工编号:" << endl;cin >> id;}cout << "请输入姓名:" << endl;cin >> name;cout << "请输入密码:" << endl;cin >> pwd;switch (type) {case 1: // 学生身份验证break;case 2: // 老师身份验证break;case 3: // 管理员身份验证break;}cout << "登录验证失败" << endl;
}
- 在用户交互入口添加登录调用
int main() {int choice;MachineRoomManager mrm;while (true) {mrm.showMenu();cin >> choice;switch (choice) {case 1:// 1.学生mrm.login(STUDENT_FILE, 1);break;case 2:// 2.老师mrm.login(TEACHER_FILE, 2);break;case 3:// 3.管理员mrm.login(ADMIN_FILE, 3);break;case 4:// 4.退出mrm.logout();break;default:cout << "输入非法,请重新输入" << endl;break;}}
}
各个校色具体登录验证
- 读取文件中的数据和用户登录的信息进行比对校验,比对成功用户登录成功,否则登录失败
int fId;string fName;string fPwd;switch (type) {case 1: // 学生身份验证while (ifs >> fId && ifs >> fName && ifs >> fPwd) {if (id == fId && fName == name && pwd == fPwd) {cout << "学生登录验证成功" << endl;role = new Student(id, name, pwd);return;}}break;case 2: // 老师身份验证while (ifs >> fId && ifs >> fName && ifs >> fPwd) {if (id == fId && fName == name && pwd == fPwd) {cout << "老师登录验证成功" << endl;role = new Teacher(id, name, pwd);return;}}break;case 3: // 管理员身份验证while (ifs >> fName && ifs >> fPwd) {if (fName == name && pwd == fPwd) {cout << "管理员登录验证成功" << endl;role = new Manager(name, pwd);return;}}break;}
管理员操作界面调用流程
- 在
role.hpp
中添加纯虚函数操作子界面声明
virtual void operatorMenue() = 0;
- 在
manager.hpp
中添加操作子界面声明
// 操作界面void operatorMenue();
- 在
manager.cpp
中实现操作子界面功能
// 操作界面
void Manager::operatorMenue() {int choice;while (true) {this->showMenu();cout << "请选择你要执行的操作" << endl;cin >> choice;switch (choice) {case 1: //1.添加账号this->addAccount();break;case 2: //2.查看账号this->showAccount();break;case 3: //3.查看所有机房信息this->showComputer();break;case 4: //4.清空预约记录this->cleanFile();break;case 5: //5.退出this->logout();return;default:cout << "请重新选择" << endl;break;}}
}
- 当用户登录成功之后,在
machineRoomManager.hpp
中添加调用不同角色声明,这里使用多态的方式用父类的对象去指向具体登录的子类函数
// 子菜单展示void showRoleMenu(Role *role);
- 在
machineRoomManager.cpp
中实现调用不同角色
// 子菜单展示
void MachineRoomManager::showRoleMenu(Role *role) {role->operatorMenue();
}
管理员模块
构造函数实现
Manager::Manager(string name, string password) {this->name = name;this->password = password;
}
管理员子菜单显示
-
功能描述:当用户选择为管理员登录成功后显示管理员可以操作的菜单
-
在
manager.hpp
中添加查看管理员菜单声明
// 查看角色菜单void showMenu();
- 在
manager.cpp
中实现查看管理员菜单功能
// 查看角色菜单
void Manager::showMenu() {cout << "1.添加账号" << endl;cout << "2.查看账号" << endl;cout << "3.查看所有机房信息" << endl;cout << "4.清空预约记录" << endl;cout << "5.退出" << endl;
}
添加账号功能实现
-
流程
-
提示选择添加账号的类型
-
根据不同的角色类型,让提示输入不同的添加值
-
将添加角色,加入到不同的角色文件中
-
// 添加账号
void Manager::addAccount() {cout << "请选择你要添加的账号类型" << endl;cout << "1.学生" << endl;cout << "2.老师" << endl;int choice;string filename;string tip;ofstream ofs;if (choice == 1) {filename = STUDENT_FILE;tip = "请输入学号";} else if (choice == 2) {filename = TEACHER_FILE;tip = "请输入职工号";} else {cout << "输入有误" << endl;return;}ofs.open(filename, ios::out | ios::app);int id;string name;string pwd;cout << tip << endl;cin >> id;cout << "请输入姓名:" << endl;cin >> name;cout << "请输入密码:" << endl;cin >> pwd;ofs << id << " " << name << " " << pwd << " " << endl;cout << "添加角色成功" << endl;ofs.close();
}
初始化、加载文件、添加校验操作
-
功能描述:
-
添加时如果学号或者职工编号重复提示错误
-
新加学生和教师容器用于存储当前已有账户
-
-
在
manager.hpp
中-
添加学生和教师容器:用于存放学生和教师账号
-
初始化容器方法声明:在构造函数中调用
-
加载文件内容方法声明:在初始化容器时调用
-
去重方法声明:在添加账户时,当输入添加id后调用该方法进行校验
-
// 初始化容器void initVector();// 加载文件内容void loadFile(string fileName, int type);// 去重检查bool checkAccount(int type, int id);// 学生容器vector <Student> vecStudent;// 教师容器vector <Teacher> vecTeacher;
- 在
manager.cpp
中实现各种功能
// 初始化容器
void Manager::initVector() {// 初始化时确保两个容器都为空this->vecStudent.clear();this->vecTeacher.clear();// 加载文件内容this->loadFile(STUDENT_FILE, 1);this->loadFile(TEACHER_FILE, 2);
}// 加载文件内容
void Manager::loadFile(string fileName, int type) {ifstream ifs(fileName, ios::in);if (!ifs.is_open()) {cout << STUDENT_FILE << "不存在" << endl;ifs.close();return;}char ch;ifs >> ch;if (ch == EOF) {cout << STUDENT_FILE << "为空" << endl;ifs.close();return;}ifs.putback(ch);int id;string name;string pwd;while (ifs >> id && ifs >> name && ifs >> pwd) {if (type == 1) {this->vecStudent.push_back(Student(id, name, pwd));} else {this->vecTeacher.push_back(Teacher(id, name, pwd));}}ifs.close();
}// 去重检查
bool Manager::checkAccount(int type, int id) {if (type == 1) {for (vector<Student>::iterator it = this->vecStudent.begin();it != this->vecStudent.end(); it++) {if (id == it->studentId) {return false;}}return true;}for (vector<Teacher>::iterator it = this->vecTeacher.begin();it != this->vecTeacher.end(); it++) {if (id == it->teacheId) {return false;}}return true;
}// 在添加账号中添加账号写容器操作if (choice == 1) {this->vecStudent.push_back(Student(id, name, pwd));} else {this->vecTeacher.push_back(Teacher(id, name, pwd));}
查看账号
- 在
manager.cpp
中完成查看账号实现,主要操作就是遍历学生和教师容器展示内容
// 查看账号
void Manager::showAccount() {cout << "student info: " << endl;for (vector<Student>::iterator it = this->vecStudent.begin();it != this->vecStudent.end(); it++) {cout << "id: " << it->studentId <<" name: " << it->name <<" pwd: " << it->password << endl;}cout << "teacher info: " << endl;for (vector<Teacher>::iterator it = this->vecTeacher.begin();it != this->vecTeacher.end(); it++) {cout << "id: " << it->teacheId <<" name: " << it->name <<" pwd: " << it->password << endl;}
}
查看机房信息
新建机房管理类
- 新建
computerRoom.hpp
#pragma once#include <iostream>using namespace std;class ComputerRoom {
public:// 构造函数ComputerRoom();ComputerRoom(int roomId, int maxNum);// 机房号int computerRoomId;// 机房最大容器int computerRoomMaxNum;
};
- 新建
computerRoom.cpp
,实现对应的构造函数
#include "computerRoom.hpp"// 构造函数
ComputerRoom::ComputerRoom() {}ComputerRoom::ComputerRoom(int roomId, int maxNum) {this->computerRoomId = roomId;this->computerRoomMaxNum = maxNum;
}
添加加载机房信息功能
- 在
manager.hpp
中,添加接口成员
// 加载机房信息void loadComputerRoom();// 查看所有机房信息void showComputer();// 机房信息容器vector <ComputerRoom> vecComputerRoom;
- 在
manager.cpp
中,实现加载机房信息功能
// 加载机房信息
void Manager::loadComputerRoom() {ifstream ifs;ifs.open(MACHINE_FILE, ios::in);if (!ifs.is_open()) {cout << MACHINE_FILE << "文件不存在" << endl;ifs.close();return;}char ch;ifs >> ch;if (ch == EOF) {cout << "文件为空" << endl;ifs.close();return;}ifs.putback(ch);ComputerRoom computerRoom;while (ifs >> computerRoom.computerRoomId && ifs >> computerRoom.computerRoomMaxNum) {this->vecComputerRoom.push_back(computerRoom);}ifs.close();
}
添加展示机房信息功能
- 在
manager.cpp
中,实现展示机房信息功能
// 查看所有机房信息
void Manager::showComputer() {for (vector<ComputerRoom>::iterator it = this->vecComputerRoom.begin();it != this->vecComputerRoom.end(); it++) {cout << it->computerRoomId << "号机房,最大容量为" << it->computerRoomMaxNum << endl;}
}
清空预约记录
// 清空预约记录
void Manager::cleanFile() {ofstream ofs(ORDER_FILE, ios::out | ios::trunc);ofs.close();
}
预约模块
构造函数
- 新建
oreder.hpp
#pragma once#include <iostream>
#include <fstream>
#include <map>
#include "globalFile.hpp"using namespace std;class Order {
public:Order();// 更新预约状态void updateOrder();// 获取属性键值void getMap(map <string, string> &mTmp, string data);// 预约记录容器 key记录条数,val记录具体记录键值对信息map<int, map<string, string> > mapOrderData;// 预约条数int size;
};
- 新建
order.cpp
实现构造函数
#include "order.hpp"Order::Order() {ifstream ifs(ORDER_FILE, ios::in);if (!ifs.is_open()) {cout << "文件不存在" << endl;return;}string day;string interval;string stuId;string stuName;string roomId;string status;// 预约记录个数this->size = 0;while (ifs >> day &&ifs >> interval &&ifs >> stuId &&ifs >> stuName &&ifs >> roomId &&ifs >> status) {map <string, string> mTmp;this->getMap(mTmp, day);this->getMap(mTmp, interval);this->getMap(mTmp, stuId);this->getMap(mTmp, stuName);this->getMap(mTmp, roomId);this->getMap(mTmp, status);this->mapOrderData.insert(make_pair(this->size, mTmp));this->size++;}
}void Order::getMap(map <string, string> &mTmp, string data) {int pos = data.find(":");string key;string val;if (pos != -1) {key = data.substr(0, pos);val = data.substr(pos + 1, data.size() - pos);mTmp.insert(make_pair(key, val));}
}
更新预约记录功能
- 在
order.cpp
中实现更新预约
void Order::updateOrder() {ofstream ofs(ORDER_FILE, ios::out | ios::trunc);for (int i = 0; i < this->size; i++) {ofs << "day:" << this->mapOrderData[i]["day"] << " ";ofs << "interval:" << this->mapOrderData[i]["interval"] << " ";ofs << "stuId:" << this->mapOrderData[i]["stuId"] << " ";ofs << "stuName:" << this->mapOrderData[i]["stuName"] << " ";ofs << "roomId:" << this->mapOrderData[i]["roomId"] << " ";ofs << "status:" << this->mapOrderData[i]["status"] << endl;}ofs.close();
}
学生模块
构造函数
- 在
student.cpp
中实现构造函数
// 构造函数
Student::Student() {}Student::Student(int id, string name, string password) {this->studentId = id;this->name = name;this->password = password;
}
学生菜单模块
- 菜单继承role类的纯虚函数,在
student.hpp
中声明查看菜单和操作界面
// 操作界面void operatorMenue();// 查看角色菜单void showMenu();
- 在
student.cpp
中实现相应功能
// 查看角色菜单
void Student::showMenu() {cout << "1.申请预约" << endl;cout << "2.查看自身预约" << endl;cout << "3.查看所有的预约" << endl;cout << "4.取消预约" << endl;cout << "5.登出" << endl;
}// 操作界面
void Student::operatorMenue() {int choice;while (true) {cout << "请选择你要执行的操作" << endl;this->showMenu();cin >> choice;switch (choice) {case 1: //1.申请预约this->applyOrder();break;case 2: //2.查看自身预约this->showSelfOrder();break;case 3: //3.查看所有的预约this->showAllOrder();break;case 4: //4.取消预约this->cancelOrder();break;case 5: //5.退出this->logout();return;default:cout << "请重新选择" << endl;break;}}
}
申请预约功能
- 现在
student.cpp
中完成申请预约写预约文件操作
// 申请预约
void Student::applyOrder() {int choice;cout << "请选择你要预约的时间" << endl;cout << "1.周一" << endl;cout << "2.周二" << endl;cout << "3.周三" << endl;cout << "4.周四" << endl;cout << "5.周五" << endl;int day;int interval;int comNum;while (true) {cin >> day;if (day >= 1 || day <= 5) {break;}cout << "预约的时间输入错误,请重新输入" << endl;}cout << "请选择你要预约的时间段" << endl;cout << "1.上午" << endl;cout << "2.下午" << endl;while (true) {cin >> interval;if (interval == 1 || interval == 2) {break;}cout << "预约时间段错误,请重新输入" << endl;}cout << "请选择你要预约的机房" << endl;cout << "1机房容量:" << this->vecComputerRoom[0].computerRoomMaxNum << endl;cout << "2机房容量:" << this->vecComputerRoom[1].computerRoomMaxNum << endl;cout << "3机房容量:" << this->vecComputerRoom[2].computerRoomMaxNum << endl;while (true) {cin >> comNum;if (comNum >= 1 || comNum <= 3) {break;}cout << "预约的机房不存在,请重新输入" << endl;}cout << "预约成功,审核中..." << endl;// 将预约信息写入预约文件ofstream ofs(ORDER_FILE, ios::out | ios::app);ofs << "day:" << day << " ";ofs << "interval:" << interval << " ";ofs << "stuId:" << this->studentId << " ";ofs << "stuName:" << this->name << " ";ofs << "roomId:" << comNum << " ";ofs << "status:" << 1 << " ";ofs << endl;ofs.close();this->vecOrder.push_back(Order(day, interval, this->studentId, this->name, comNum, 1));
}
查看自身预约
- 遍历order对象,找学号是自己的输出
// 查看自身预约
void Student::showSelfOrder() {Order order;for (int i = 0; i < order.size; i++) {if (order.mapOrderData[i]["stuId"] == to_string(this->studentId)) {cout << "day:" << order.mapOrderData[i]["day"] << " "<< "interval:" << order.mapOrderData[i]["interval"] << " "<< "stuId:" << order.mapOrderData[i]["stuId"] << " "<< "stuName:" << order.mapOrderData[i]["stuName"] << " "<< "roomId:" << order.mapOrderData[i]["roomId"] << " "<< "status:" << order.mapOrderData[i]["status"] << endl;}}
}
查看所有预约
- 遍历order对象,直接打印
// 查看所有的预约
void Student::showAllOrder() {Order order;for (int i = 0; i < order.size; i++) {cout << "day:" << order.mapOrderData[i]["day"] << " "<< "interval:" << order.mapOrderData[i]["interval"] << " "<< "stuId:" << order.mapOrderData[i]["stuId"] << " "<< "stuName:" << order.mapOrderData[i]["stuName"] << " "<< "roomId:" << order.mapOrderData[i]["roomId"] << " "<< "status:" << order.mapOrderData[i]["status"] << endl;}
}
取消预约
- 遍历order对象找学号是自己的,将状态是审核中和已预约的改为取消
// 取消预约
void Student::cancelOrder() {Order order;for (int i = 0; i < order.size; i++) {if (order.mapOrderData[i]["stuId"] == to_string(this->studentId)) {if (atoi(order.mapOrderData[i]["status"].c_str()) == 1 ||atoi(order.mapOrderData[i]["status"].c_str()) == 2) {order.mapOrderData[i]["status"] = "0";}}}order.updateOrder();
}
教师模块
构造函数实现
Teacher::Teacher(int id, string name, string password) {this->teacheId = id;this->name = name;this->password = password;
}
菜单功能实现
// 查看角色菜单
void Teacher::showMenu() {cout << "1.查看所有预约" << endl;cout << "2.审核预约" << endl;cout << "3.退出登录" << endl;
}// 操作界面
void Teacher::operatorMenue() {int choice;while (true) {this->showMenu();cout << "请选择你要执行的操作" << endl;cin >> choice;switch (choice) {case 1: //1.查看所有预约this->showAllOreder();break;case 2: //2.审核预约this->checkOrder();break;case 3: //3.退出登录this->logout();return;default:cout << "请重新选择" << endl;break;}}
}
查看所有预约
// 查看所有预约
void Teacher::showAllOreder() {Order order;for (int i = 0; i < order.size; i++) {// 老师这块只看到正在申请的预约 if (to_string(order.mapOrderData[i]["status"]) == "1") {cout << "day:" << order.mapOrderData[i]["day"] << " "<< "interval:" << order.mapOrderData[i]["interval"] << " "<< "stuId:" << order.mapOrderData[i]["stuId"] << " "<< "stuName:" << order.mapOrderData[i]["stuName"] << " "<< "roomId:" << order.mapOrderData[i]["roomId"] << " "<< "status:" << order.mapOrderData[i]["status"] << endl;}}
}
审核预约
// 审核预约
void Teacher::checkOrder() {Order order;for (int i = 0; i < order.size; i++) {if (atoi(order.mapOrderData[i]["status"]) == 1) {order.mapOrderData[i]["status"] = "2";}}order.updateOrder();
}