你好,这篇文章记录了我的一次课程设计的全过程,如果能够帮助到你,我将十分荣幸。
如果你有不同的见解,欢迎在讨论区与我交流。
先展示部分系统界面。设计流程及业务测试详情见后文
0. 系统界面截图
1)服务器:中间窗口显示链接状况和收发数据的信息
2)注册/修改信息:
输入不合法时会在tips位置显示提示信息
3)登陆:
4)商家:
若要修改菜品,现在左边选中,点击修改按钮,右侧框中会显示相应信息,修改后点击确认修改即可
5)买家:
选择商家->选择菜品加入购物车->下单
6)骑手:
选择接单->输入位置->显示配送顺序->确认送达
1. 选题背景与意义
(描述选题的背景、所针对的具体实际问题及任务所体现的实用性价值等)
背景:近年来,经过市场的不断调整,外卖行业己经从之前的萌芽期和发展期进入成熟期,企业关注的焦点从发展时期的占领市场向降低成本提高利润和提高服务质量转变。外卖配送业务作为外卖基础的业务之一,对降低成本提高利润和提高服务质量有很大的影响,而配送路径又是外卖配送业务中最为重要的环节之一,对二者也有直接的影响。配送路径的选择往往决定着运力的规模的大小,合理高效的配送路径可以使企业在使用较小规模运力的情况下,实现相对较高的配送效率,从而直接为企业降低配送成本,使企业在现有资源约束下获得尽可能高的利润。与此同时,配送路径的选择会直接对服务质量造成影响,是否准时送达、是否保证配送外卖质量等这些服务质量的好坏,都会以客户满意度的形式直接体现出来,也随着配送路径的改变而发生不同程度的变化。
意义:通过规划合理的配送路线,节约人力和时间成本,提高外卖配送员的配送效率和服务质量,提升用户满意度。
2. 需求分析
(根据任务选题的要求,充分地分析和理解问题,明确用户要求做什么?完整性约束条件是什么?运行环境要求、图形操作界面要求,画出用户用例/泳道图等)
2.1各角色需求分析
商家的需求:增加菜品、修改菜品、删除菜品;
买家的需求:选择不同商家、将菜品加入购物车、修改购物车、下单、取消订单、确认订单状态、删除订单记录;
骑手的需求:查看可接的订单、接单、规划配送路线、确认送达;
共有的需求:注册账号、修改个人信息、查看与自己有关的订单、注销账号;
2.2完整性约束
1)功能约束:有尚未完成的订单时不能删除或修改账户、删除账户的同时要删除相关的订单、删除商家账户时要删除该商家的全部菜品。
2)输入数据约束:账号和密码必须是2-10位大小写字母+数字;电话号码是5-13位数字;用户名/菜品名不能为空且长度不能超过10个字符(不能包括“/”); 菜品价格是小于100000的正数;用户位置要在一定的经纬度范围内(以湖南省为例)。输入错误时要显示相应的提示信息。
2.3运行环境
QT+ MSVC2017+MySql+TcpSocket
2.4图形操作界面要求
不同身份的用户有不同的用户界面,有单独的登陆、注册和信息修改界面,各项功能清晰明了,每个输入框都有相应的输入提示。
2.5泳道图
3. 系统概要设计
(在该部分中分析叙述清楚系统每个模块的功能要求,并写清楚系统的数据流图和数据字典,并完成:① 数据库概念结构设计(E-R图);② 数据库逻辑结构设计;③ 完整性约束设计与实现)
3.1 E-R图
3.2数据库逻辑结构设计
关系表:
1)买家:买家id,买家密码,买家称呼,买家电话,买家位置;
2)商家:商家id,商家密码,商家名称,商家电话,商家位置;
3)骑手:骑手id,骑手密码,骑手姓名,骑手电话;
4)定单:订单号,买家id,商家id,骑手id,下单时间,订单状态,订单内容;
5)菜品:商家id,菜品名称,菜品价格;
其中带有下划线的是主码,满足3NF。
3.3完整性约束设计与实现
1)实体完整性:表的每一行在表中是惟一的实体。
2)域完整性:id和密码必须是2-10位大小写字母+数字;电话号码是5-13位数字;用户名/菜品名不能为空且长度不能超过10个字符(不能包括“/”); 菜品价格是小于100000的正数;用户位置要在一定的经纬度范围内(以湖南省为例)。
3)参照完整性:
设置订单表中商家id和买家id的外键
注:订单表中骑手id没有设置外键,因为没有骑手接单时值为“NULL”
设置菜品表中商家id的外键:
4. 系统详细设计
(系统的详细设计思路:① 系统功能模块图;② 开发模块所用的数据库物理结构设计以及存储过程和触发器设计等)
4.1功能模块图
4.2开发模块所用的数据库物理结构设计以及存储过程和触发器设计
买家表:
商家表:
骑手表:
菜品表:
订单表:
5. 系统实现
(编程语言、开发环境及支撑软件、软件系统架构;给出:① 系统每个模块的功能描述和工作流程;② 系统类图;③ 系统主要功能模块代码以及核心算法对应的关键函数定义代码,包括输入参数的含义、函数输出结果等;④ 核心函数的实现代码段及注解等;⑤ 主要功能界面截图及对应文字概述,要体现系统的主要业务)
编程语言:C++; 开发环境:Qt; 架构:C/S架构
5.1系统每个模块的功能描述和工作流程
1)注册/修改信息模块
2)商家模块
3)买家模块
4)骑手模块
5.2系统类图
5.3系统主要功能模块代码以及核心算法对应的关键函数定义代码,包括输入参数的含义、函数输出结果等
前端:
1)注册/修改信息模块:
2)商家模块:
3)买家模块:
4)骑手模块:
后端:
5.4核心函数的实现代码段及注解等
1)注册/修改信息:
void Dialog_register::on_pushButton_clicked()//确定
{
ui->label_tips->clear();
//输入检测-----------------------------------------
//账号密码
QString pattern("[0-9a-zA-Z]{2,10}");
QRegExp rx(pattern);
bool match = rx.exactMatch(ui->lineEdit->text());
bool match_2 = rx.exactMatch(ui->lineEdit_2->text());
if(match==false||match_2==false){
ui->label_tips->setText("wrong input: id or password");
return ;
}
//用户名
QString name_test=ui->lineEdit_3->text();
if(name_test.contains("/")){
ui->label_tips->setText("wrong input: you can't input \"/\" ");
return ;
}
if(name_test.length()>10||name_test.length()==0){
ui->label_tips->setText("wrong input: name too long or too short");
return ;
}
//电话号码
QString pattern_num("\\d{5,13}");
QRegExp rx_num(pattern_num);
bool match_num = rx_num.exactMatch(ui->lineEdit_4->text());
if(match_num==false){
ui->label_tips->setText("wrong input: phonenumber");
return ;
}
//位置
QString x=ui->lineEdit_5->text();
QString y=ui->lineEdit_6->text();
double xx=x.toDouble();
double yy=y.toDouble();
if(x!=QString::number(xx)||y!=QString::number(yy)||xx<108.8||xx>114.2||yy<24.7||yy>30.1){
ui->label_tips->setText("wrong input: location");
return ;
}
//----------------------------------
connect_server();
if(profe==""){
//注册
QString id=ui->lineEdit->text();
QString psw=ui->lineEdit_2->text();
QString name=ui->lineEdit_3->text();
QString phonenumber=ui->lineEdit_4->text();
QString pos_x=ui->lineEdit_5->text();
QString pos_y=ui->lineEdit_6->text();
QString messa="register/";
if(buttonGroup.checkedId()==1){
messa+="saler/";
}
else if(buttonGroup.checkedId()==2){
messa+="buyer/";
}
else if(buttonGroup.checkedId()==3){
messa+="rider/";
}
messa+=id;
messa+="/";
messa+=psw;
messa+="/";
messa+=name;
messa+="/";
messa+=phonenumber;
if(buttonGroup.checkedId()!=3){
messa+="/";
messa+=pos_x;
messa+="/";
messa+=pos_y;
}
clientSck->write(messa.toStdString().c_str());
}
else{
//修改信息
ui->lineEdit->setText(id);
QString psw=ui->lineEdit_2->text();
QString name=ui->lineEdit_3->text();
QString phonenumber=ui->lineEdit_4->text();
QString pos_x=ui->lineEdit_5->text();
QString pos_y=ui->lineEdit_6->text();
QString messa="change/";
messa+=profe;
messa+="/";
messa+=id;
messa+="/";
messa+=psw;
messa+="/";
messa+=name;
messa+="/";
messa+=phonenumber;
if(profe!="rider"){
messa+="/";
messa+=pos_x;
messa+="/";
messa+=pos_y;
}
clientSck->write(messa.toStdString().c_str());
}
}
void Dialog_register::readData(){
//收到服务器返回的数据
QString strData=clientSck->readAll();
QStringList dataList=strData.split("/");
if(strData=="no connection"){
ui->label_tips->setText("no connection with database");
}
else if(strData=="regist success"){
ui->label_tips->setText("regist success");
}
else if(strData=="exist"){
ui->label_tips->setText("this ID already exist");
}
else if(strData=="have order now"){
ui->label_tips->setText("have order now");
}
else if(strData=="change success"){
ui->label_tips->setText("change success");
}
else if(strData=="error"){
ui->label_tips->setText("error");
}
else if(dataList[0]=="info"){
ui->lineEdit->setText(dataList[1]);//id
ui->lineEdit_2->setText(dataList[2]);//psw
ui->lineEdit_3->setText(dataList[3]);//name
ui->lineEdit_4->setText(dataList[4]);//number
if(dataList[5]!=""){
ui->lineEdit_5->setText(dataList[5]);
ui->lineEdit_6->setText(dataList[6]);
}
}
return ;
}
2)商家:
void Dialog_saler::on_pushButton_2_clicked()//修改信息
{
ui->label_tips->clear();
Dialog_register r;
r.init(QString("saler"),id);
r.exec();
}
void Dialog_saler::on_pushButton_clicked()//删除账号
{
ui->label_tips->clear();
connect_server();
QString messa="delete/saler/";
messa+=id;
clientSck->write(messa.toStdString().c_str());
}
void Dialog_saler::on_pushButton_6_clicked()//添加菜品
{
ui->label_tips->clear();
//输入检测---------------------------------
QString name_test=ui->lineEdit->text();
QString price_test=ui->