你好,这篇文章记录了我的一次课程设计的全过程,如果能够帮助到你,我将十分荣幸。
如果你有不同的见解,欢迎在讨论区与我交流。

先展示部分系统界面。设计流程及业务测试详情见后文

文章目录

  • 0. 系统界面截图
  • 1. 选题背景与意义
  • 2. 需求分析
    • 2.1各角色需求分析
    • 2.2完整性约束
    • 2.3运行环境
    • 2.4图形操作界面要求
    • 2.5泳道图
  • 3. 系统概要设计
    • 3.1 E-R图
    • 3.2数据库逻辑结构设计
    • 3.3完整性约束设计与实现
  • 4. 系统详细设计
    • 4.1功能模块图
    • 4.2开发模块所用的数据库物理结构设计以及存储过程和触发器设计
  • 5. 系统实现
    • 5.1系统每个模块的功能描述和工作流程
    • 5.2系统类图
    • 5.3系统主要功能模块代码以及核心算法对应的关键函数定义代码,包括输入参数的含义、函数输出结果等
    • 5.4核心函数的实现代码段及注解等
  • 6. 运行测试与分析
    • 6.1访问数据库配置:
    • 6.2完整性约束测试(部分):
    • 6.3标准流程测试:
  • 7. 附录:遇到的问题与参考资料

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]);//idui->lineEdit_2->setText(dataList[2]);//pswui->lineEdit_3->setText(dataList[3]);//nameui->lineEdit_4->setText(dataList[4]);//numberif(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->lineEdit_2->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 ;}if(price_test.toDouble()<0||price_test.toDouble()>100000){ui->label_tips->setText("wrong input: price");return ;}//---------------------------------------connect_server();QString name=ui->lineEdit->text();QString price=ui->lineEdit_2->text();QString messa="add_dish/";messa+=id;messa+="/";messa+=name;messa+="/";messa+=price;clientSck->write(messa.toStdString().c_str());
}void Dialog_saler::on_pushButton_5_clicked()//删除菜品
{ui->label_tips->clear();connect_server();if(ui->listWidget->currentItem()!=Q_NULLPTR){QListWidgetItem * item = ui->listWidget->currentItem();QString strData=item->text();QStringList dataList=strData.split(SEPARATOR);QString messa="del dish/";messa+=id;messa+="/";messa+=dataList[0];clientSck->write(messa.toStdString().c_str());qDebug()<<messa;}
}void Dialog_saler::readData(){//收到服务器返回的数据QString strData=clientSck->readAll();QStringList dataList=strData.split("/");if(strData=="no connection"){ui->label_tips->setText("no connection with database");}else if(dataList[0]=="delete success")close();else if(dataList[0]=="error"){ui->label_tips->setText("error");}else if(dataList[0]=="have order now"){ui->label_tips->setText("have order now");}else if(dataList[0]=="dish exist"){ui->label_tips->setText("dish exist");}else if(dataList[0]=="add success"){QString add="";add+=ui->lineEdit->text();add+=SEPARATOR;add+=ui->lineEdit_2->text();ui->listWidget->addItem(add);ui->label_tips->setText("success");}else if(dataList[0]=="dish"){QString add="";add+=dataList[1];add+=SEPARATOR;add+=dataList[2];ui->listWidget->addItem(add);}else if(dataList[0]=="order_s"){QString add="";add+=dataList[1];add+=SEPARATOR;add+=dataList[2];add+=SEPARATOR;add+=dataList[3];add+=SEPARATOR;add+=dataList[4];add+=SEPARATOR;add+=dataList[5];add+=SEPARATOR;add+=dataList[6];add+=SEPARATOR;add+=dataList[7];ui->listWidget_2->addItem(add);}else if(dataList[0]=="del dish"){load_saler();}else if(dataList[0]=="change dish"){load_saler();qDebug()<<strData;qDebug()<<dataList[0];}return ;
}

3)买家:

void Dialog_user::on_pushButton_clicked()//确认商家
{ui->label_tips->clear();if(ui->listWidget->currentItem()!=Q_NULLPTR){connect_server();QListWidgetItem * item = ui->listWidget->currentItem();QString strData=item->text();QStringList dataList=strData.split(SEPARATOR);salerID=dataList[0];ui->label_salerID->setText(salerID);ui->listWidget_2->clear();ui->listWidget_3->clear();QString messa="load_dish/";messa+=salerID;clientSck->write(messa.toStdString().c_str());}
}void Dialog_user::on_pushButton_2_clicked()//确认添加进购物车
{ui->label_tips->clear();if(ui->listWidget_2->currentItem()!=Q_NULLPTR){QListWidgetItem * item = ui->listWidget_2->currentItem();ui->listWidget_3->addItem(item->text());}
}void Dialog_user::on_pushButton_3_clicked()//下单
{ui->label_tips->clear();if(ui->listWidget_3->item(0)==Q_NULLPTR) return ;connect_server();QString foods="";int row=0;while(ui->listWidget_3->item(row)!=Q_NULLPTR){QStringList list=ui->listWidget_3->item(row)->text().split(SEPARATOR);foods+=list[0];foods+=";";row++;}QString messa="make a order/";messa+=id;messa+="/";messa+=salerID;messa+="/";QDateTime current_date_time =QDateTime::currentDateTime();QString current_date =current_date_time.toString("yyyy.MM.dd hh:mm:ss");messa+=current_date;messa+="/";messa+=foods;clientSck->write(messa.toStdString().c_str());
}void Dialog_user::on_pushButton_5_clicked()//彻底删除订单
{ui->label_tips->clear();connect_server();if(ui->listWidget_4->currentItem()!=Q_NULLPTR){QStringList list=ui->listWidget_4->currentItem()->text().split(SEPARATOR);QString messa="del order/";messa+=list[0];clientSck->write(messa.toStdString().c_str());}
}void Dialog_user::on_pushButton_10_clicked()//取消订单
{ui->label_tips->clear();connect_server();if(ui->listWidget_4->currentItem()!=Q_NULLPTR){QStringList list=ui->listWidget_4->currentItem()->text().split(SEPARATOR);QString messa="cancel order/";messa+=list[0];clientSck->write(messa.toStdString().c_str());}
}
void Dialog_user::readData(){//收到服务器返回的数据QString strData=clientSck->readAll();//qDebug()<<strData;QStringList dataList=strData.split("/");if(strData=="no connection"){ui->label_tips->setText("no connection with database");}else if(dataList[0]=="delete success")close();else if(dataList[0]=="error"){ui->label_tips->setText("error");}else if(dataList[0]=="have order now"){ui->label_tips->setText("have order now");}else if(dataList[0]=="order_b"){QString add=dataList[1];//id_oadd+=SEPARATOR;add+=dataList[2];//id_badd+=SEPARATOR;add+=dataList[3];//id_sadd+=SEPARATOR;add+=dataList[4];//id_radd+=SEPARATOR;add+=dataList[5];//statusadd+=SEPARATOR;add+=dataList[6];//timeadd+=SEPARATOR;add+=dataList[7];//foodsui->listWidget_4->addItem(add);}else if(dataList[0]=="saler"){QString add=dataList[1];//idadd+=SEPARATOR;add+=dataList[2];//nameadd+=SEPARATOR;add+=dataList[3];//phoneadd+=SEPARATOR;add+=dataList[4];//xadd+=SEPARATOR;add+=dataList[5];//yui->listWidget->addItem(add);}else if(dataList[0]=="dish"){QString add="";add+=dataList[1];add+=SEPARATOR;add+=dataList[2];ui->listWidget_2->addItem(add);}else if(dataList[0]=="make a order"){load_buyer();}else if(dataList[0]=="del order"){load_buyer();}else if(dataList[0]=="cancel order"){load_buyer();}return ;
}

4)骑手:

void Dialog_rider::on_pushButton_4_clicked()//规划路线
{ui->label_tips->clear();//输入检测--------------------------------------//位置QString x=ui->lineEdit_X->text();QString y=ui->lineEdit_Y->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();QString now_x=ui->lineEdit_X->text();QString now_y=ui->lineEdit_Y->text();QString messa="plan/";messa+=id;messa+="/";messa+=now_x;messa+="/";messa+=now_y;clientSck->write(messa.toStdString().c_str());ui->listWidget_2->clear();
}void Dialog_rider::on_pushButton_6_clicked()//确认完成
{ui->label_tips->clear();connect_server();if(ui->listWidget->currentItem()!=Q_NULLPTR){QStringList list=ui->listWidget->currentItem()->text().split(SEPARATOR);QString messa="finish order/";messa+=list[0];clientSck->write(messa.toStdString().c_str());}
}void Dialog_rider::on_pushButton_7_clicked()//接单
{ui->label_tips->clear();connect_server();if(ui->listWidget_3->currentItem()!=Q_NULLPTR){QStringList list=ui->listWidget_3->currentItem()->text().split(SEPARATOR);QString messa="take order/";messa+=list[0];messa+="/";messa+=id;clientSck->write(messa.toStdString().c_str());}
}void Dialog_rider::readData(){//收到服务器返回的数据QString strData=clientSck->readAll();//qDebug()<<strData;QStringList dataList=strData.split("/");if(strData=="no connection"){ui->label_tips->setText("no connection with database");}else if(dataList[0]=="delete success")close();else if(dataList[0]=="error"){ui->label_tips->setText("error");}else if(dataList[0]=="have order now"){ui->label_tips->setText("have order now");}else if(dataList[0]=="order_r"){QString add=dataList[1];//id_oadd+=SEPARATOR;add+=dataList[2];//id_badd+=SEPARATOR;add+=dataList[3];//id_sadd+=SEPARATOR;add+=dataList[4];//id_radd+=SEPARATOR;add+=dataList[5];//statusadd+=SEPARATOR;add+=dataList[6];//timeadd+=SEPARATOR;add+=dataList[7];//foodsui->listWidget->addItem(add);}else if(dataList[0]=="order_waiting"){QString add=dataList[1];//id_oadd+=SEPARATOR;add+=dataList[2];//id_badd+=SEPARATOR;add+=dataList[3];//id_sadd+=SEPARATOR;add+=dataList[4];//id_radd+=SEPARATOR;add+=dataList[5];//statusadd+=SEPARATOR;add+=dataList[6];//timeadd+=SEPARATOR;add+=dataList[7];//foodsui->listWidget_3->addItem(add);}else if(dataList[0]=="plan"){QString add=dataList[1];//id_oadd+=SEPARATOR;add+=dataList[2];//saler or buyeradd+=SEPARATOR;add+=dataList[3];//id_s or id_radd+=SEPARATOR;add+=dataList[4];//xadd+=SEPARATOR;add+=dataList[5];//yui->listWidget_2->addItem(add);}else if(dataList[0]=="finish"){load_rider();}else if(dataList[0]=="take order"){load_rider();}return ;
}

5)服务器:

void Dialog::readData(){//接收客户端的信息,调用功能函数并返回结果QString strData = serverSck->readAll();QString ans="";ui->textBrowser->append("receive:"+strData);if(d.isOpen()==false){//未连接数据库则报错serverSck->write("no connection");serverSck->waitForBytesWritten();Sleep(200);serverSck->close();return ;}QStringList dataList=strData.split('/');if(dataList[0]=="login")//登陆ans=login(dataList[1],dataList[2],dataList[3]);else if(dataList[0]=="register"){//注册ans=regist(strData);}else if(dataList[0]=="delete"){//删除账户ans=delet(dataList[1],dataList[2]);}else if(dataList[0]=="change"){//修改账户ans=change(strData);}else if(dataList[0]=="search"){//查找账户信息ans=search_info(dataList[1],dataList[2]);}else if(dataList[0]=="add_dish"){//添加菜品ans=add_dish(dataList[1],dataList[2],dataList[3]);}else if(dataList[0]=="load_dish_order"){//商家初始化load_dish(dataList[1]);load_order_s(dataList[1]);}else if(dataList[0]=="del dish"){//删除菜品if(del_dish(dataList[1],dataList[2])==1){ans="del dish";}elseans="error";}else if(dataList[0]=="change dish"){//修改菜品if(change_dish(dataList[1],dataList[2],dataList[3],dataList[4])==1){ans="change dish";}elseans="error";}else if(dataList[0]=="load_saler_order"){//买家初始化load_saler();load_order_b(dataList[1]);}else if(dataList[0]=="load_dish"){//加载菜单load_dish(dataList[1]);}else if(dataList[0]=="load_order_r"){//加载骑手订单load_order_r(dataList[1]);}else if(dataList[0]=="make a order"){//生成订单ans=make_a_order(strData);}else if(dataList[0]=="del order"){//删除订单ans=del_order(dataList[1]);}else if(dataList[0]=="cancel order"){//取消订单ans=cancel_order(dataList[1]);}else if(dataList[0]=="plan"){//规划路线plan(dataList[1],dataList[2],dataList[3]);}else if(dataList[0]=="finish order"){//完成订单ans=finish_order(dataList[1]);}else if(dataList[0]=="take order"){//接单ans=take_order(dataList[1],dataList[2]);}serverSck->write(ans.toStdString().c_str());ui->textBrowser->append(ans);serverSck->waitForBytesWritten();Sleep(200);serverSck->close();return ;
}QString Dialog::login(QString profe,QString id,QString psw){//登陆QSqlQuery query(d);QString ans="";QString strLogin;if(profe=="saler")strLogin=QString("select psw_saler from saler where id_saler='%1'").arg(id);else if(profe=="buyer")strLogin=QString("select psw_buyer from buyer where id_buyer='%1'").arg(id);else if(profe=="rider")strLogin=QString("select psw_rider from rider where id_rider='%1'").arg(id);if(!query.exec(strLogin)){ans="error";return ans;}if(query.size()==0){ans="wrong id";return ans;}query.first();if(query.value(0)==psw)ans=profe+"/"+id;elseans="wrong psw";return ans;
}QString Dialog::delet(QString profe,QString id){//删除账户QString ans="delete success";//先检查是否有未完成的订单QSqlQuery query(d);QString strCheck;if(profe=="saler")strCheck=QString("select * from orderr where id_saler='%1' and (status='waiting' or status='sending')").arg(id);else if(profe=="buyer")strCheck=QString("select * from orderr where id_buyer='%1' and (status='waiting' or status='sending')").arg(id);else if(profe=="rider")strCheck=QString("select * from orderr where id_rider='%1' and (status='waiting' or status='sending')").arg(id);if(!query.exec(strCheck))ans="error";if(query.size()!=0){ans="have order now";return ans;}QSqlQuery query_2(d);QString strDelete;if(profe=="saler")strDelete=QString("delete from saler where id_saler='%1'").arg(id);else if(profe=="buyer")strDelete=QString("delete from buyer where id_buyer='%1'").arg(id);else if(profe=="rider")strDelete=QString("delete from rider where id_rider='%1'").arg(id);if(!query_2.exec(strDelete))ans="error";//删除与之相关的订单QSqlQuery query_3(d);QString strDeleteOrder;if(profe=="saler")strDeleteOrder=QString("delete from orderr where id_saler='%1'").arg(id);else if(profe=="buyer")strDeleteOrder=QString("delete from orderr where id_buyer='%1'").arg(id);else if(profe=="rider")strDeleteOrder=QString("delete from orderr where id_rider='%1'").arg(id);if(!query_3.exec(strDeleteOrder))ans="error";//若是商家,删除有关菜品if(profe=="saler"){QSqlQuery query_4(d);QString strDeleteDish;strDeleteDish=QString("delete from dish where id_saler='%1'").arg(id);if(!query_4.exec(strDeleteDish))ans="error";}return ans;
}void Dialog::load_order_s(QString id){//加载商家订单QSqlQuery query(d);QString strLoadOrder=QString("select * from orderr where id_saler='%1' and (status='sending' or status='waiting')").arg(id);if(!query.exec(strLoadOrder)){serverSck->write("error");}while(query.next()){QString ans="order_s/";ans+=query.value(0).toString();ans+="/";ans+=query.value(1).toString();ans+="/";ans+=query.value(2).toString();ans+="/";ans+=query.value(3).toString();ans+="/";ans+=query.value(4).toString();ans+="/";ans+=query.value(5).toString();ans+="/";ans+=query.value(6).toString();serverSck->write(ans.toStdString().c_str());serverSck->waitForBytesWritten();Sleep(200);}QSqlQuery query_2(d);QString strLoadOrder_2=QString("select * from orderr where id_saler='%1' and (status='finish' or status='cancel')").arg(id);if(!query_2.exec(strLoadOrder_2)){serverSck->write("error");qDebug()<<serverSck->error();}while(query_2.next()){QString ans="order_s/";ans+=query_2.value(0).toString();ans+="/";ans+=query_2.value(1).toString();ans+="/";ans+=query_2.value(2).toString();ans+="/";ans+=query_2.value(3).toString();ans+="/";ans+=query_2.value(4).toString();ans+="/";ans+=query_2.value(5).toString();ans+="/";ans+=query_2.value(6).toString();serverSck->write(ans.toStdString().c_str());serverSck->waitForBytesWritten();Sleep(200);}return ;
}QString Dialog::make_a_order(QString strData){//生成订单QString ans="error";QString id_order;QStringList dataList=strData.split("/");for(long long int num=1;num<LLONG_MAX;num++){id_order="o";id_order+=QString::number(num);QSqlQuery query(d);QString strId=QString("select id_order from orderr where id_order='%1'").arg(id_order);if(!query.exec(strId)){ans="error";return ans;}if(query.size()==0){break;}}QSqlQuery query_2(d);QString id_buyer=dataList[1];QString id_saler=dataList[2];QString id_rider="NULL";QString time_order=dataList[3];QString foods=dataList[4];QString strOrder=QString("insert into orderr values('%1','%2','%3','%4','%5','%6','%7')").arg(id_order).arg(id_buyer).arg(id_saler).arg(id_rider).arg(QString("waiting")).arg(time_order).arg(foods);if(query_2.exec(strOrder)){ans="make a order";}return ans;
}void Dialog::plan(QString id,QString now_x,QString now_y){//规划最优路线QSqlQuery query(d);QString strOrder=QString("select * from orderr where id_rider='%1' and status='sending'").arg(id);if(!query.exec(strOrder)){serverSck->write("error");return;}int k=query.size()*2;//共有k个要去的地点(包括重复的)pos[0][0]=now_x.toDouble();pos[0][1]=now_y.toDouble();int n=1;//向pos存数据时的下标QMap<int,QString> map;//序号与订单号/商家或买家/id/位置的对应关系for(int i=0;i<=k;++i) limit[i]=0;//清空买家-商家对应关系while(query.next()){QString id_order=query.value(0).toString();QString id_buyer=query.value(1).toString();QString id_saler=query.value(2).toString();//处理买家QSqlQuery query_2(d);QString strBuyer=QString("select location_x_buyer,location_y_buyer from buyer where id_buyer='%1'").arg(id_buyer);if(!query_2.exec(strBuyer)){serverSck->write("error");return;}query_2.first();double x=query_2.value(0).toString().toDouble();double y=query_2.value(1).toString().toDouble();pos[n][0]=x;pos[n][1]=y;QString temp=id_order;temp+="/buyer/";temp+=id_buyer;temp+="/";temp+=query_2.value(0).toString();temp+="/";temp+=query_2.value(1).toString();map[n]=temp;n++;//处理商家QSqlQuery query_3(d);QString strSaler=QString("select location_x_saler,location_y_saler from saler where id_saler='%1'").arg(id_saler);if(!query_3.exec(strSaler)){serverSck->write("error");return;}query_3.first();double x_2=query_3.value(0).toString().toDouble();double y_2=query_3.value(1).toString().toDouble();pos[n][0]=x_2;pos[n][1]=y_2;QString temp_2=id_order;temp_2+="/saler/";temp_2+=id_saler;temp_2+="/";temp_2+=query_3.value(0).toString();temp_2+="/";temp_2+=query_3.value(1).toString();map[n]=temp_2;n++;limit[n-2]=n-1;//商家的前置节点默认0,即出发点}//初始化各点间的距离for(int i=0;i<n;++i){for(int j=i;j<n;++j){dis[i][j]=abs(pos[i][0]-pos[j][0])+abs(pos[i][1]-pos[j][1]);dis[j][i]=dis[i][j];}}//qDebug()<<min;min=LONG_MAX;//最小长度long_now=0;//当前长度search(0,k);for(int i=2;i<=k+1;++i){QString ans="plan/";ans+=map[seq_min[i]];//qDebug()<<ans;serverSck->write(ans.toStdString().c_str());serverSck->waitForBytesWritten();Sleep(200);}//qDebug()<<min;return ;
}void Dialog::on_pushButton_clicked()
{//链接数据库ui->textBrowser->append("connecting.........");d.setHostName("127.0.0.1");d.setDatabaseName("database1");d.setPort(3306);d.setUserName("root");d.setPassword("");if(d.open()){ui->textBrowser->append("success!\n");}else{ui->textBrowser->append("cannot open");ui->textBrowser->append(d.lastError().text()+"\n");}
}

6. 运行测试与分析

6.1访问数据库配置:

服务器中:

头文件:

#include <QtSql>
#include <QSqlDatabase>
#include <QSqlError>

6.2完整性约束测试(部分):

1)注册/修改信息:
账号不合法:

位置不合法:

2)商家:
菜名不合法:

价格不合法:

3)骑手:
位置不合法:

4)存在未完成的订单时,账号不能删除:

6.3标准流程测试:

1)注册商家:

2)添加菜品:


3)添加购物车:

4)骑手接单:

5)规划路线:

7. 附录:遇到的问题与参考资料

[1]https://blog.csdn.net/ruthywei/article/details/78433074
mysql安装全过程

[2]qt(5版本以上)连接MySQL的两种方式
https://blog.csdn.net/weixin_41752376/article/details/86155912

[3]QSqlQuery::value: not positioned on a valid record 的错误的解决方法
https://blog.csdn.net/shomy_liu/article/details/39118889

[4]C++:实现socket通信(TCP/IP)实例
https://blog.csdn.net/qq_27923041/article/details/83857964

[5]Socket详解
https://blog.csdn.net/sight_/article/details/8138802

[6]windows环境下用c++实现socket编程
https://blog.csdn.net/xiaoquantouer/article/details/58001960

[7]socket中accept函数与qdialog自带的accept冲突
改为::accept

[8]error:LNK2005 已经在*.obj中定义的一种情况及解决办法
https://blog.csdn.net/zhaoyong26/article/details/84635383

[9]Qt中网络编程(C/S架构)Tcp
https://blog.csdn.net/weixin_42443025/article/details/84572940

[10]QT网络编程Tcp下C/S架构的即时通信
https://blog.csdn.net/weixin_30377461/article/details/94808924

[11]mysql无法存汉字
将字符集改为GKB

[12]QSqlQuery 学习
https://blog.csdn.net/zhouzhouasishuijiao/article/details/84310512

[13]QT之 QTimer使用方法
https://blog.csdn.net/liang19890820/article/details/51789796

[14]Qt中数据库基本操作–QSqlQuery
https://blog.csdn.net/yuanzhangmei1/article/details/7709620

[15]Qt的QTcpSocket的readyRead信号使用体会
https://blog.csdn.net/Dengdew/article/details/79065608

[16]多个write()无法分别read()
serverSck->waitForBytesWritten();

Sleep(200)

[17]表名为order时会莫名报错
未知原因,只能换名字

[18]Qt 获取当前时间
https://blog.csdn.net/lusirking/article/details/51460716

[19]正则表达式(Regular Expression)基本语法
https://blog.csdn.net/scgaliguodong123_/article/details/45363409

具有路线规划功能的外卖平台(Qt,C++,C/S架构,MySql)相关推荐

  1. 百度地图API制作类似 百度地图的路线导航界面并实现简单的路线规划功能

    之前我们讲了怎么在百度地图上设置Marker(如A点..) 和弹出框(跟随Marker的,Marker移动的时候也是会跟着移动的),接着又觉得百度地图自带的放大缩小不(fei)是(chang)很(de ...

  2. 百度地图多点路线规划_自驾游必备,多地点路线规划功能已经出炉了!!!

    对于喜欢自驾游的小伙伴们,元旦节假就快要开始啦.大家打算怎么计划自己的旅行呢? 身为一个拖延患者,我通常会拖到出发前的最后一个晚上,花上半小时,在网上搜索当地感兴趣的景点 (POI), 然后在百度地图 ...

  3. android 通过scheme唤起百度、高德、腾讯地图路线规划功能,唤起滴滴出行打车功能

    import android.content.Context; import android.content.Intent; import android.net.Uri;import java.ut ...

  4. JAVA毕设项目我饿了外卖平台(java+VUE+Mybatis+Maven+Mysql)

    JAVA毕设项目我饿了外卖平台(java+VUE+Mybatis+Maven+Mysql) 项目运行 环境配置: Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webs ...

  5. 后台:nodejs 前台:vue 全栈开发 完整功能的外卖平台系统

    关于 一直考虑写一个功能齐全的完整Nodejs项目,但苦于没有找到合适的类型,而且后台系统无法直观的感受到,需要有一个前台项目配合,因此迟迟没有动笔.恰好前一段时间开源了一个vue前端项目,便以此为契 ...

  6. 基于Qt框架实现的 C/S架构的外卖平台软件系统

    资源下载地址:https://download.csdn.net/download/sheziqiong/85628215 基于Qt框架实现的 C_S架构的外卖平台软件系统 演示视频 C/S 架构的外 ...

  7. BaiduMap---百度地图官方Demo之路径规划功能(介绍公交,驾车和步行三种线路规划方法和自设路线方法)

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  8. 外卖平台的设计与实现

    1.1 问题描述 近年来,在我国大力扶持互联网+的发展,互联网也已基本入户人名群众,成为现代人日常生活不可或缺的一部分.与此同时,网络订餐也借此政策不断蓬勃发展.外卖平台是近年来快速发展的一种新型电商 ...

  9. 百度API之路线规划

    近期参加一个课题,聊到路线规划问题,需要搜索两地点的最短线路距离以及最短用时等情况,然后就想着用借用百度API,做个参考 环境: python 3.6 主要问题: 1. 分析百度官方路线规划API了解 ...

最新文章

  1. AI时代的中层支柱:统计学
  2. 漫画:为什么程序员喜欢使用 0 ≤ i 10 左闭右开形式写 for 循环?
  3. html怎么给框格加背景图,怎么给word 2013表格添加漂亮的背景图片
  4. Java入门算法(暴力篇)丨蓄力计划
  5. java基础之java内存模型
  6. 测试工程师不懂AI,还有未来吗?
  7. plsql初始错误sql.net未正确安装_ANSYS | ansys18.0完整安装过程及常见问题解决方案[图文]...
  8. TensorFlow2.0学习使用笔记
  9. Android-多线程AsyncTask
  10. 数据结构课程设计——通讯录制作
  11. 简易版百度换肤之background属性
  12. 数据成功插入数据库,前端页面却实现404错误 POST http://127.0.0.1:8080/user/register 404 ()
  13. KISS保持简单:纪念丹尼斯·里奇
  14. 芯鼎盛LED恒流驱动芯片TX6128设计的DC-DC开关电源降压恒流DEMO说明
  15. MPB:南农韦中组-​根系分泌物调控土壤微生物群落结构和功能的研究方法
  16. php多层if函数,if函数嵌套计算公式用法
  17. 网页版怎么连接tcp服务器,请教怎么做一个tcp客户端访问网页
  18. excel表格合并程序
  19. LightOJ 1336 Sigma Function
  20. 软件开发外包:你有什么选择

热门文章

  1. Meta Cambria手柄曝光,主动追踪+多触觉回馈方案
  2. 关于手机设置高对比度文字对app的影响及解决方案
  3. 2023年美赛C题Wordle预测问题二建模及Python代码详细讲解
  4. 电镀废水的来源以及常见的处理方式,各种工艺的讲解
  5. 【NLP】第8章 将 Transformer 应用于法律和财务文件以进行 AI 文本摘要
  6. Dreamweaver 无法粘贴的解决方法
  7. gitlab复制project新建项目
  8. App内购项目的App Store推广
  9. 前端搬运工:零基础的前端开发初学者应如何系统地学习?前端掌握技能的学习路线
  10. ActivityManagerService解读之Activity启动初探