目录:
项目背景:
可行性研究:
需求分析:
详细设计:
编码:
测试:
维护:(缺陷)
完整代码:https://github.com/Zzzhouxiaochen/Order
点菜系统是一种全新的、集无线、网络、嵌入式技术、人工智能等技术于一体的无线手持终端。适用于餐饮,酒店、咖啡厅等场所的餐台管理、点菜录单、结算、信息反馈与传递。结合传统的点菜管理系统,为餐饮、酒店、咖啡厅等行业的经营管理提供了一整套高效、稳定可靠、先进的解决方案,改变了餐饮等行业的手工经营方式,提高了服务效率和顾客满意程度,提升了店面形象,最终提升了企业竞争力与经营效益。
中间的数据存储部分:使用MySql数据库的操作。
顾客扫描餐桌上的二维码进入顾客客户端,进行点菜。订单提交到服务器上由商家客户端获取到。
商家通过商家客户端可以进行订单管理和菜品管理。
服务器部分:采用 HTTP协议实现。
客户端部分:HTTP 协议的请求对应用户的下单等,厨房接单等的相关操作。
还有客户端和服务端之间:数据存储部分——数据库,简单的MySql服务端和客户端的数据交互,完成数据存储,管理。
数据库的分析:
1.菜品表:其中包含信息:
2.订单表:
1.创建数据库
按照标准数据库语句创建,注:因为一条一条的语句十分麻烦,这里使用写一个文件中,进行重定向 < (标准输入)。
create database if not exists order_system;
use order_system;
create table if not exists dish_table(
dish_id int not null primary key auto_increment,
name varchar(50),
price int);
insert into dish_table values(null,'红烧肉',1200);
insert into dish_table values(null,'回锅肉',2200);
insert into dish_table values(null,'糖醋里脊肉',3200);
insert into dish_table values(null,'红烧鱼肉',4200);
insert into dish_table values(null,'干煸豆角',5200);
create table if not exists order_table(
order_id int not null primary key auto_increment,
table_id varchar(50),
time varchar(50),
dishes varchar(1024),
status int);
insert into order_table values(null,'少林','2019/08/01 12:00','1,2,3,4,5',0);
insert into order_table values(null,'武当','2019/08/01 14:00','1,',0);
insert into order_table values(null,'峨眉','2019/08/01 18:00','1,5',0);
至于数据库的服务器就用 MySql 其自身的。
2.服务器设计
中间数据的存储:用Json结构
响应请求的设置:
数据库:
create database if not exists order_system;
use order_system;
create table if not exists dish_table(
dish_id int not null primary key auto_increment,
name varchar(50),
price int);
insert into dish_table values(null,'红烧肉',1200);
insert into dish_table values(null,'回锅肉',2200);
insert into dish_table values(null,'糖醋里脊肉',3200);
insert into dish_table values(null,'红烧鱼肉',4200);
insert into dish_table values(null,'干煸豆角',5200);
create table if not exists order_table(
order_id int not null primary key auto_increment,
table_id varchar(50),
time varchar(50),
dishes varchar(1024),
status int);
insert into order_table values(null,'少林','2019/08/01 12:00','1,2,3,4,5',0);
insert into order_table values(null,'武当','2019/08/01 14:00','1,',0);
insert into order_table values(null,'峨眉','2019/08/01 18:00','1,5',0);
插入函数示例:
#incldue
#include
#include //第三方库
int main(){
//创建数据库的操作句柄(遥控器)
MYSQL* mysql=mysql_init(NULL);
//2.建立句柄和数据库之间的联系(连接服务器)
if(mysql_real_connect(mysql/*遥控器*/,"127.0.0.1","root"/*密码*/,""/*密码*/,
"order_system"/*数据库名字*/,3306/*端口号*/,NULL,0/*客户端选项*/)==NULL) {
printf("连接失败!:%s\n",mysql_error(mysql));
return 1;
}
//设置编码格式(服务器和客户端匹配)
mysql_set_character_set(mysql,"utf8");
//拼装插入数据的sql
char sql[1024]={0};
int price=2000;
sprintf(sql,"insert into caipinbiao values(null,'干煸豆角',%d)",price);
//执行sql语句
int ret=mysql_query(mysql,sql);
if(ret !=0) {
printf("sql 执行失败!\n");
mysql_close(mysql);
return 1;
}
//关闭连接
mysql_close(mysql);
return 0;
}
选择函数示例:
#include
#include
#include //第三方库
int main(){
//1.创建数据库的操作句柄(遥控器)
MYSQL* mysql=mysql_init(NULL);
//2.建立句柄和数据库之间的联系(连接服务器)
if(mysql_real_connect(mysql/*遥控器*/,"127.0.0.1"/*主机名*/,"root"/*用户名*/,""/*密码*/,
"order_system"/*数据库名字*/,3306/*端口号*/,NULL,0/*客户端选项*/)==NULL) {
printf("连接失败!:%s\n",mysql_error(mysql));
return 1;
}
//设置编码格式(服务器和客户端匹配)
mysql_set_character_set(mysql,"utf8");
//3.拼装数据的sql
char sql[1024]={0};
sprintf(sql,"select* from dish_table");
//4.执行sql语句
int ret=mysql_query(mysql,sql);
if(ret !=0) {
printf("sql 执行失败!\n");
mysql_close(mysql);
return 1;
}
//5.获取结果进行遍历
//获取集合
MYSQL_RES* result=mysql_store_result(mysql);
int rows=mysql_num_rows(result); //行
int cols=mysql_num_fields(result); //列
//行列遍历得到结果
for(int row=0;row
服务器:(封装)
#include"httplib.h"
#include
#include
#include"db.hpp"
const char* CONTENT_TYPE = "application/json";
MYSQL* mysql=mysql;
int main(){
using namespase httplib;
mysql=order_system::MySQLInit();
signal(SIGINT,[](int){order_system::MySQLRelease(mysql);exit(0);});
order_system::DishTable dish_table(mysql);
order_system::OrderTable order_table(mysql);
Server server;
server.Post("/dish",[&dish_table](const Request& req,Response& resp)){ //新增菜品
Json::Value req_json;
Json::Value resp_json;
Json::Reader reader;
Json::FastWriter writer;
printf("新增菜品!\n");
//1.获取数据解析成Json格式
bool ret =readr.parse(req.body,req_json);
if(!ret) {
printf("parse body failed!");
resp_json["ok"]=false;
resp_json["reason"]="parse body failed!";
resp.status=400;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
return;
}
//2.校验JSON信息
if(rep_json["name"].empty()||req_json["price"].empty()) {
printf("格式错误!");
resp_json["ok"]=false;
resp_json["reason"]="格式错误!\n";
resp.status=400;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
return;
}
//3.调用数据库操作插入数据
ret = dish_table.Insert(req_json);
if(!ret) {
printf("数据库插入数据失败!");
resp_json["ok"]=false;
resp_json["reason"]="数据库插入数据失败";
resp.status=500;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
return;
}
//正确的响应
resp_json["ok"]=true;
resp.status=200;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
});
server.Get("/dish",[dish_table](const Request& req,Response& resp
(void)req;
Json::Value req_json;
Json::Value resp_json;
Json::Reader reader;
Json::FastWriter writer;
printf("看全部菜品!\n");
//1.直接数据库操作
bool ret = dish_table.Selectall(resq_json);
if(!ret) {
printf("查看所有菜品失败!");
resp_json["ok"]=false;
resp_json["reason"]="查看所有菜品失败";
resp.status=500;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
return;
}
//2.正确的响应
resp_json["ok"]=true;
resp.status=200;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
return;
});
server.Get(R"(/dish/(\d+))",[dish_table](const Request& req,Response& resp)){
//1.获取id
int32_t dish_id=std::stoi(req.matches[1]); //stoi string ->整数 //std::to_string 数字->string
printf("获取到编号是%d的菜品\n",auto dish_id);
(void)req;
Json::Value resp_json;
Json::FastWriter writer;
printf("看指定菜品!\n");
//2.直接数据库操作
bool ret = dish_table.SelectOnce(resq_json);
if(!ret) {
printf("查看指定菜品失败!");
resp_json["ok"]=false;
resp_json["reason"]="查看指定菜品失败";
resp.status=500;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
return;
}
//3.正确的响应
resp_json["ok"]=true;
resp.status=200;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
});
server.Put(R"(/dish/(\d+))",[&dish_table](const Request& req,Response& resp)){
Json::Value req_json;
Json::Value resp_json;
Json::Reader reader;
Json::FastWriter writer;
printf("修改菜品!\n");
//1.获取id
int32_t dish_id=std::stoi(req.matches[1]); //stoi string ->整数 //std::to_string 数字->string
printf("获取到编号是%d的菜品\n",auto dish_id);
//2.获取数据解析成Json格式
bool ret =readr.parse(req.body,req_json);
if(!ret) {
printf("parse body failed!");
resp_json["ok"]=false;
resp_json["reason"]="parse body failed!";
resp.status=400;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
return;
}
//3.校验JSON信息
if(rep_json["name"].empty()||req_json["price"].empty()) {
printf("格式错误!");
resp_json["ok"]=false;
resp_json["reason"]="格式错误!";
resp.status=400;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
return;
}
//4.调用数据库操作插入数据
resp_json["dish_id"]=dish_id; //dish_id加入到Json中
ret = dish_table.Update(req_json);
if(!ret) {
printf("数据库更新数据失败!");
resp_json["ok"]=false;
resp_json["reason"]="数据库更新数据失败";
resp.status=500;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
return;
}
//正确的响应
resp_json["ok"]=true;
resp.status=200;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
});
server.Delete(R"(/dish/(\d+))",[&dish_table](const Request& req,Response& resp)){
Json::Value resp_json;
Json::FastWriter writer;
//1.获取id
int32_t dish_id=std::stoi(req.matches[1]); //stoi string ->整数 //std::to_string 数字->string
printf("删除编号是%d的菜品\n",auto dish_id);
//2.直接数据库操作
bool ret = dish_table.Delete(req_json);
if(!ret) {
printf("删除指定菜品失败!");
resp_json["ok"]=false;
resp_json["reason"]="删除指定菜品失败";
resp.status=500;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
return;
}
//3.正确的响应
resp_json["ok"]=true;
resp.status=200;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
});
server.Post("/order",[&order_table](const Request& req,Response& resp)) {
Json::Value req_json;
Json::Value resp_json;
Json::Reader reader;
Json::FastWriter writer;
printf("新增订单!\n");
//1.获取数据解析成Json格式
bool ret =readr.parse(req.body,req_json);
if(!ret) {
printf("新增订单失败!");
resp_json["ok"]=false;
resp_json["reason"]="新增订单失败!";
resp.status=400;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
return;
}
//2.校验JSON信息
if(rep_json["table_id"].empty()||req_json["time"].empty()||req_json["dish_ids"].empty()) {
printf("格式错误!");
resp_json["ok"]=false;
resp_json["reason"]="格式错误!";
resp.status=400;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
return;
}
//3.构造其他需要的字段
req_json["status"]=1; //1进行中 0关闭
//把dish_ids转换成dishes
const Json::Value& dish_ids=req_json["dish_ids"];
req_json["dishes"]=writer.write(dish_ids);
//4.调用数据库操作插入数据
ret = order_table.Insert(req_json);
if(!ret) {
printf("数据库插入数据失败!");
resp_json["ok"]=false;
resp_json["reason"]="数据库插入数据失败";
resp.status=500;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
return;
}
//正确的响应
resp_json["ok"]=true;
resp.status=200;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
});
server.Get("/order",[order_table](const Request& req,Response& resp)) {
(void)req;
Json::Value resp_json;
Json::FastWriter writer;
printf("看全部订单!\n");
//1.直接数据库操作
bool ret = order_table.Selectall(resq_json);
if(!ret) {
printf("查看所有菜品失败!");
resp_json["ok"]=false;
resp_json["reason"]="查看所有菜品失败";
resp.status=500;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
return;
}
//2.正确的响应
resp_json["ok"]=true;
resp.status=200;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
});
server.Put(R"(/order/(\d+))",[](const Request& req,Response& resp)) {
Json::Value req_json;
Json::Value resp_json;
Json::Reader reader;
Json::FastWriter writer;
printf("修改菜品!\n");
//1.获取id
int32_t dish_id=std::stoi(req.matches[1]); //stoi string ->整数 //std::to_string 数字->string
printf("获取到订单编号是%d的订单章台\n",auto dish_id);
//2.获取数据解析成Json格式
bool ret =readr.parse(req.body,req_json);
if(!ret) {
printf("parse body failed!");
resp_json["ok"]=false;
resp_json["reason"]="parse body failed!";
resp.status=400;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
return;
}
//3.校验JSON信息
if(rep_json["status"].empty()) {
printf("格式错误!");
resp_json["ok"]=false;
resp_json["reason"]="格式错误!";
resp.status=400;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
return;
}
//4.调用数据库操作插入数据
resp_json["dish_id"]=dish_id; //dish_id加入到Json中
ret = order_table.ChangeState(req_json);
if(!ret) {
printf("数据库更新数据失败!");
resp_json["ok"]=false;
resp_json["reason"]="数据库更新数据失败";
resp.status=500;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
return;
}
//正确的响应
resp_json["ok"]=true;
resp.status=200;
resp.set_content(writer.write(resp_json),CONTENT_TYPE);
});
server.set_base_dir("./wwwroot");
server.listen("0.0.0.0",9094);
}
主函数:
#include "httplib.h"
int main() {
using namespace httplib;
Server server;
server.Get("/", [](const Request& req, Response& resp)
{ (void)req;
resp.set_content("hello", "text/html");
});
server.set_base_dir("./wwwroot");
server.listen("0.0.0.0", 9092);
return 0;
}
Makefile:
FLAGS=-std=c++11 -L/usr/lib64/mysql -lmysqlclient -ljsoncpp -lpthread -g
.PHONY:all all:db_test
db_test:db_test.cc db.hpp
g++ db_test.cc -o db_test $(FLAGS)
main:main.cc
g++ main.cc -lpthread -std=c++11
.PHONY:clean
clean:
rm db_test
测试方式:单元测试;测试方法:白盒测试
每个功能的逐个实现,根据数据库的查看情况进行测试评价。
测试代码:
#include"db.hpp"
//单元测试
// void TestDishTable() {
// MYSQL* mysql=order_system::MySQLInit();
// order_system::DishTable dish_table(mysql);
// //插入数据 //成功
// Json::Value dish;
// dish["name"]="干煸豆角";
// dish["price"]=1000;
// bool ret = dish_table.Insert(dish);
// printf("ret = %d\n",ret);
// //查找所有数据 //成功
// Json::Value dishes;
// int ret = dish_table.Selectall(&dishes);
// printf("ret = %d\n",ret);
// Json::StyledWriter writer;
// printf("%s\n",writer.write(dishes).c_str());
// //查找指定数据 //成功
// Json::Value dish;
// int ret = dish_table.Selectall(9,&dish);
// printf("ret = %d\n",ret);
// Json::StyledWriter writer;
// printf("%s\n",writer.write(dish).c_str());
//修改指定数据 //成功
// Json::Value dish;
// dish["dish_id"]=9;
// dish["name"]="肥宅快乐水";
// dish["price"]=999;
// int ret = dish_table.Update(dish);
// printf("ret = %d\n",ret);
// //删除指定数据 //成功
// int ret = dish_table.Delete(9);
// printf("ret = %d\n",ret);
// order_system::MySQLRelease(mysql);
// }
void TestOrderTable() {
MYSQL* mysql=order_system::MySQLInit();
order_system::OrderTable order_table(mysql);
//插入订单 //成功
// Json::Value orderes;
// dish["table_id"]="明教";
// dish["time"]="2019/08/11 12:00";
// dish["dishes"]="[1,2,3]";
// dish["status"]=1;
// bool ret = order_table.Insert(order);
// printf("ret = %d\n",ret);
//查找所有订单 //成功
// Json::Value orders;
// int ret = order_table.Selectall(&orders);
// printf("ret = %d\n",ret);
// Json::StyledWriter writer;
// printf("%s\n",writer.write(orders).c_str());
//修改状态 //成功
Json::Value order;
order["order_id"]=1;
order["status"]=1;
int ret = dish_table.ChangeState(order);
printf("ret = %d\n",ret);
//修改指定数据 //成功
// Json::Value dish;
// dish["dish_id"]=9;
// dish["name"]="肥宅快乐水";
// dish["price"]=999;
// int ret = dish_table.Update(dish);
// printf("ret = %d\n",ret);
//删除指定数据 //成功
// int ret = dish_table.Delete(9);
// printf("ret = %d\n",ret);
order_system::MySQLRelease(mysql);
}
int main() {
//TestDishTable();
TestOrderTable();
return 0;
}