项目:宅人食堂——点餐系统

目录:


项目背景:

可行性研究:

需求分析:

详细设计:

编码:

测试:

维护:(缺陷)

完整代码:https://github.com/Zzzhouxiaochen/Order


项目背景:

点菜系统是一种全新的、集无线、网络、嵌入式技术、人工智能等技术于一体的无线手持终端。适用于餐饮,酒店、咖啡厅等场所的餐台管理、点菜录单、结算、信息反馈与传递。结合传统的点菜管理系统,为餐饮、酒店、咖啡厅等行业的经营管理提供了一整套高效、稳定可靠、先进的解决方案,改变了餐饮等行业的手工经营方式,提高了服务效率和顾客满意程度,提升了店面形象,最终提升了企业竞争力与经营效益。


可行性研究:

  • 技术可行性——主要服务器、客户端——HTTP协议实现
  • 操作可行性——大众操作
  • 经济可行性——低成本

中间的数据存储部分:使用MySql数据库的操作。


需求分析:

顾客扫描餐桌上的二维码进入顾客客户端,进行点菜。订单提交到服务器上由商家客户端获取到。
商家通过商家客户端可以进行订单管理和菜品管理。

服务器部分:采用 HTTP协议实现。

客户端部分:HTTP 协议的请求对应用户的下单等,厨房接单等的相关操作。

还有客户端和服务端之间:数据存储部分——数据库,简单的MySql服务端和客户端的数据交互,完成数据存储,管理。

数据库的分析:

1.菜品表:其中包含信息:

  • 菜品id:用唯一主键,自增
  • 菜名:varchar
  • 价格:int

2.订单表:

  • 订单号:用唯一主键,自增
  • 桌号:varchar
  • 时间:time
  • 菜品:varchar;用菜品id,而非名字
  • 状态:int

详细设计:

  • 1. 服务器
  • 2. 顾客客户端
  • 3. 商家客户端
  • 4. 服务端和客户端之间——数据存储部分

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.服务器设计

项目:宅人食堂——点餐系统_第1张图片

中间数据的存储:用Json结构

响应请求的设置:

项目:宅人食堂——点餐系统_第2张图片

项目:宅人食堂——点餐系统_第3张图片

项目:宅人食堂——点餐系统_第4张图片


编码:

数据库:


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;
}

维护:(缺陷)

  1. 客户端的网页编写——客户端并没有实现
  2. 多用户支持同时实现——多线程,多进程
  3. 主要:完善性维护

完整代码:https://github.com/Zzzhouxiaochen/Order

你可能感兴趣的:(项目)