项目:
项目名称:点餐系统
项目描述:使用户可以通过浏览器访问服务器获取菜品信息并点餐;
以及可以使管理员通过浏览器访问服务器实现订单以及菜品的管理;
技术调研:线程、socket、http、json、mysql、stl;
概要设计:框架的设计–不太严谨的MVC框架
model:数据管理模块——管理数据(菜品、订单),外界想要访问数据必须通过这个模块来访问,不能直接访问;
view:视图界面模块——浏览器前端界面,用户和管理员的操作都是通过前段界面完成的;
controller:业务控制模块——搭建服务器针对前端的请求
详细设计:
数据管理模块:
1.数据的存储:mysql数据库(免费,换台机子也可以)
2.数据库表的设计
菜品信息表:菜品id、菜品名称、菜品单价、添加时间
订单信息表:订单ID、订单菜品、订单状态、修改时间
3、数据管理模块代码的设计
菜品数据类:添加菜品、删除菜品、修改菜品、获取菜品(所有、单个)
订单数据类:添加订单、删除订单、修改订单(菜品、状态)、获取订单(所有,指定ID)
.
业务控制模块:
1.搭建服务器:HTTP服务器(采用httplib库)
2.通信接口设计:什么样的请求对应什么样的业务处理与响应
1.静态页面请求:html页面(以及依赖的css/js文件);
index.html——菜品信息的展示以及下单界面
GET /index.html HTTP/1.1 HTTP/1.1 200 OK
Content-Type:text/html
Content-Length:文件长度
..
..
/index.html文件数据
2.动态数据请求:菜品数据,订单数据;
通信接口采用restful风格接口设计
基于http协议,使用xml或者json格式定义正文序列化方式
定义操作类型:新增-POST;删除-DELETE;修改-PUT;获取-GET
method url version
......
\r\n
菜品名称,菜品单价
新增菜品:
POST /dish HTTP/1.1 HTTP/1.1 200 OK
... ...
\r\n HTTP/1.1 500
{"name":"红烧肉",”price“:180} {result:false,reason:""}
删除菜品
DELETE /dish/1 HTTP/1.1 HTTP/1.1 200 OK
...
\r\n
修改菜品:
PUT /dish/1 HTTP/1.1 HTTP/1.1 200 OK
...
\r\n
{name:"蚂蚁上树","price":22}
获取所有所有菜品:
GET /dish HTTP/1.1 HTTP/1.1 200 OK
... ...
\r\n \r\n
[{id:1,name:"红烧肉",price:23}
{id:2,name:"盐煎肉",price:24}]
获取单个菜品:
GET /dish/1 HTTP/1.1 HTTP/1.1 200 OK
... ...
\r\n \r\n
{id:1,name:"红烧肉",price:23}
.
前端界面模块:html的编写渲染
实现:html+css+js
vue.js
环境搭建:
1.mysql服务安装:按照博客一步步;
https://zhuanlan.zhihu.com/p/49046496
2.gcc/g++升级
sudo yum -y install epel-release
sudo yum install centos-release-scl-rh centos-release-scl
sudo yum install devtoolset-7-gcc devtoolset-7-gcc-c++
source /opt/rh/devtoolset-7/enable
#最好将source加载配置这句指令,写到 ~/.bashrc 这个文件中
3.安装jsoncpp开发包
sudo yum install jsoncpp-devel
**jsoncpp基本应用认识:**
Json::Value类:json与外界进行数据中转的一个类对象
重载了大量的操作符:赋值运算符
包含了大量的类型转换函数;
Json::Reader类:实现反系列化,
将json格式字符串转换为多个数据对象,存储在json::Value对象中
.parse(std::string &buf,Json::Value &val)
Json::Write类:实现序列化
基类——子类:Json::FastWriter / Json::StyledWriter
将Json::Value对象中的数据序列化成为json格式的字符串
std::string write(Json::Value &val)
mysql数据库的基本操作:SQL
客户端操作:mysql -uroot -p(带密码)
注意事项:
1.sql语句中,都已“;"结尾;
2.sql语句中,不分大小写;
3.sql语句中,数据库名称,表名称,字段名称不能直接使用sql关键字;——``
库的操作:
创建数据库:create database dbname;/ create database if not exists dbname;
查看数据库:show databases;
选择所使用的数据库:use dbname; 查看所使用的: select database();
删除数据库:drop database dbname;
.
表的操作:
常用数据类型:
int-整形; decimal(m,d)-浮点数; varchar(可变字符长度);char(固定字符长度)
create table if not exists tbname();
查看表:desc tbname;
删除指定表:drop table tbname;
修改表结构:alter关键字;--课后
**表中字段约束**:
primary key 主键约束 约定指定字段的值-非空且唯一
unique key 唯一约束 约束指定字段必须唯一
not null 非空约束-约束指定字段的值不能为NULL
auto_increment 自增属性(只能用于整形的主键字段)
`create table if not exists tbname(id int primary key auto_increment,name varchar(32) not null unique,sex bit,score decimal(4,2),birth datetime);`
表中数据的操作:增删查改
新增:
intsert tbname(id,name,sex) values(null,"张三",0);
insert tbname values(null,"李四",1,22.33,"2021-6-10 12:00:12");
删除:
delete from tbname where id=2;
修改:
update tbname set score=66.54,birth="2021-10-2 12:20:22" where id=1;
查询:
查询表中所有数据:select * from tbname ;
指定列查询:select id, name, score from tbname;
按序查询:select id, name ,score from tbname order by id desc;降序
分页查找:select * from tbname order by id desc limit 3 offset 3;
limit count offset (page* count)
条件查询:where
导入数据库:
mysql uroot -p < db.sql
mysql 代码操作:
1.初始化做操句柄
2.通过句柄连接mysql服务器
3.设置客户端字符集(utf8)
4.选择使用的数据库
数据操作:
5.执行语句:
增删改:执行语句–执行语句成功即可
查询:执行语句-
将查询结果获取到本地
获取结果中数据条数、列数
遍历结果集获取每一条数据的每一列
释放本地结果集
6.关闭句柄释放资源
7.获取接口执行失败原因
接口介绍:
MYSQL *mysql=NULL;
MYSQL *mysql_init(MYSQL *mysql);
。
int mysql_real_connect(MYSQL *mysql,char *host,char *username,
char *passwd,char *dbname, int port(默认3306),char *sock,int flag);
mysql:初始化完成句柄;
host:mysql服务器ip地址
username:用户名
passwd:密码
dbname:默认所选择使用的数据库名称
port:mysql服务端口-0-默认3306;
sock:
flag:客户端标志--通常置0
返回值:成功返回句柄,失败返回NULL
.
int mysql_set_character_set(MYSQL *mysql,char *name);
mysql:句柄
name:字符集名称-utf8
返回值:成功返回0,失败返回非0;
.
int mysql_select_db(MYSQL* mysql,char* dbname)
mysql:句柄;dbname:要切换的数据库名称;
返回值:成功返回0,失败返回非0;
.
int mysql_query(MYSQL *mysql,char *sql);
mysql: 句柄 sql:要执行的sql语句
返回值:成功返回0,失败返回非0;
MYSQL_RES *mysql_store_result(MYSQL *mysql);
mysql:句柄
特殊说明:mysql_query与mysql_store_result存在线程安全问题
返回值:成功返回结果集的地址,失败返回NULL;
int mysql_num_rows(MYSQL_RES *res); ---获取行数;
int mysql_num_fields(MYSQL_RES *res); ---获取列数;
MYSQL_ROW mysql_fetch_row(MYSQL_RES *res);
MYSQL_RES res中会记录当前获取的位置,逐条取出
MYSQL_ROW:就是一个char**
int mysql _free_result(MYSQL_RES *res);--释放结果集
void mysql_close(MYSQL *mysql);---关闭客户端连接
char *mysql_error(MYSQL *mysql);——获取mysql错误原因
mysql_query与mysql_store_result存在线程安全问题
srv文件下
db.hpp
//db.hpp
#include<iostream>
#include<string>
#include<mysql/mysql.h>
#include<jsoncpp/json/json.h>
#include<mutex>
namespace order_sys{
#define MYSQL_SERVER "172.2*.***.***"
#define MYSQL_USER "root"
#define MYSQL_PASSWD "***"
#define MYSQL_DBNAME "order_system"
static MYSQL* MysqlInit(){
//初始化句柄
//mysql_init(句柄地址)
MYSQL *mysql=NULL;
mysql=mysql_init(NULL);
if(mysql==NULL){
std::cout<<"mysql init failed\n";
return NULL;
}
//连接服务器
//mysql_real_connect(句柄,服务器IP,用户名,密码,数据库名称,端口,套接字文件,客户端标志)
if(mysql_real_connect(mysql,MYSQL_SERVER,MYSQL_USER,MYSQL_PASSWD,MYSQL_DBNAME,3306,NULL,0)==NULL){
std::cout<<mysql_error(mysql)<<std::endl;
return NULL;
}
//设置字符集
//mysql_set_character_set(句柄,字符集名称)
if(mysql_set_character_set(mysql,"utf8")!=0){
std::cout<<mysql_error(mysql)<<std::endl;
return NULL;
}
//选择数据库
//mysql_select_db(句柄,数据库名称)
//if(mysql_select_db(mysql,MYSQL_DBNAME)!=0){
// std::cout<<mysql_error(mysql)<<std::endl;
// return NULL;
//}
return mysql;
}
static void MysqlRelease(MYSQL *mysql){
if(mysql!=NULL){
mysql_close(mysql);
}
return ;
}
static bool MysqlQuery(MYSQL *mysql,const std::string &sql){
//mysql_query(句柄,sql语句)
if(mysql_query(mysql,sql.c_str())!=0){
std::cout<<sql<<std::endl;
std::cout<<mysql_error(mysql)<<std::endl;
return false;
}
return true;
}
class TableDish{
private:
MYSQL *_mysql;
std::mutex _mutex;
public:
TableDish(){/*mysql 初始化*/
_mysql=MysqlInit();
if(_mysql==NULL){
exit(-1);
}
}
~TableDish(){
MysqlRelease(_mysql);
_mysql=NULL;
}
bool Insert(const Json::Value &dish){
//组织sql语句
#define DISH_INSERT "insert tb_dish values(null,'%s',%d,now());"
char str_sql[4096]={0};
sprintf(str_sql,DISH_INSERT,
dish["name"].asCString(),
dish["price"].asInt());
//insert tbname value()
//执行sql语句
return MysqlQuery(_mysql,str_sql);
}
bool Delete(int dish_id){
#define DISH_DELETE "delete from tb_dish where id=%d;"
char str_sql[4096]={0};
sprintf(str_sql,DISH_DELETE,dish_id);
return MysqlQuery(_mysql,str_sql);
}
bool Update(const Json::Value &dish){
#define DISH_UPDATE "update tb_dish set name='%s',price=%d where id=%d;"
char str_sql[4096]={0};
sprintf(str_sql,DISH_UPDATE,
dish["name"].asCString(),
dish["price"].asInt(),
dish["id"].asInt());
return MysqlQuery(_mysql,str_sql);
}
bool SelectAll(Json::Value *dishes){
#define DISH_SELECT "select * from tb_dish;"
_mutex.lock();
bool ret=MysqlQuery(_mysql,DISH_SELECT);
if(ret==false){
_mutex.unlock();
return false;
}
MYSQL_RES *res=mysql_store_result(_mysql);
_mutex.unlock();
if(res==NULL){
std::cout<<"store result failed!\n";
return false;
}
int num=mysql_num_rows(res);
for(int i=0;i<num;i++){
MYSQL_ROW row=mysql_fetch_row(res);
Json::Value dish;
dish["id"]=std::stoi(row[0]);
dish["name"]=row[1];
dish["price"]=std::stoi(row[2]);
dish["ctime"]=row[3];
dishes->append(dish);
}
mysql_free_result(res);
return true;
}
bool SelectOne(int dish_id,Json::Value *dish){
#define DISH_SELECTONE "select * from tb_dish where id=%d;"
char str_sql[4096]={0};
sprintf(str_sql,DISH_SELECTONE,dish_id);
_mutex.lock();
bool ret=MysqlQuery(_mysql,str_sql);
if(ret==false){
_mutex.unlock();
return false;
}
MYSQL_RES *res=mysql_store_result(_mysql);
_mutex.unlock();
if(res==NULL){
std::cout<<"store result failed!\n";
return false;
}
int num=mysql_num_rows(res);
if(num!=1){
std::cout<<"result error\n";
mysql_free_result(res);
return false;
}
MYSQL_ROW row=mysql_fetch_row(res);
(*dish)["id"]=dish_id;
(*dish)["name"]=row[1];
(*dish)["price"]=std::stoi(row[2]);
(*dish)["ctime"]=row[3];
mysql_free_result(res);
return true;
}
};
class TableOrder{
private:
MYSQL *_mysql;
std::mutex _mutex;
public:
TableOrder(){/*mysql 初始化*/
_mysql=MysqlInit();
if(_mysql==NULL){
exit(-1);
}
}
~TableOrder(){
if(_mysql!=NULL){
MysqlRelease(_mysql);
}
}
bool Insert(const Json::Value &order){
#define ORDER_INSERT "insert tb_order values(null,'%s',0,now());"
char str_sql[4096]={0};
Json::FastWriter writer;
std::string dishes=writer.write(order["dishes"]);
sprintf(str_sql,ORDER_INSERT,dishes.c_str());
return MysqlQuery(_mysql,str_sql);
}
bool Delete(int order_id){
#define ORDER_DELETE "delete from tb_order where id=%d;"
char str_sql[4096]={0};
sprintf(str_sql,ORDER_DELETE,order_id);
return MysqlQuery(_mysql,str_sql);
}
bool Update(const Json::Value &order){
#define ORDER_UPDATE "update tb_order set dishes='%s',status=%d where id=%d;"
Json::FastWriter writer;
int order_id=order["id"].asInt();
int status=order["status"].asInt();
std::string dishes=writer.write(order["dishes"]);
char str_sql[4096]={0};
sprintf(str_sql,ORDER_UPDATE,dishes.c_str(),status,order_id);
return MysqlQuery(_mysql,str_sql);
}
bool SelectAll(Json::Value *orders){
#define ORDER_SELECTALL "select * from tb_order;"
_mutex.lock();
bool ret=MysqlQuery(_mysql,ORDER_SELECTALL);
if(ret==false){
_mutex.unlock();
return false;
}
MYSQL_RES *res=mysql_store_result(_mysql);
_mutex.unlock();
if(res==NULL){
std::cout<<mysql_error(_mysql)<<std::endl;
return false;
}
int num=mysql_num_rows(res);
for(int i=0;i<num;i++){
MYSQL_ROW row=mysql_fetch_row(res);
Json::Value order;
order["id"]=std::stoi(row[0]);
order["dishes"]=row[1];
order["status"]=std::stoi(row[2]);
order["mtime"]=row[3];
orders->append(order);
}
mysql_free_result(res);
return true;
}
bool SelectOne(int order_id,Json::Value *order){
#define ORDER_SELECTONE "select * from tb_order where id=%d;"
char str_sql[4096]={0};
sprintf(str_sql,ORDER_SELECTONE,order_id);
_mutex.lock();
bool ret=MysqlQuery(_mysql,str_sql);
if(ret==false){
_mutex.unlock();
return false;
}
MYSQL_RES *res=mysql_store_result(_mysql);
_mutex.unlock();
if(res==NULL){
std::cout<<mysql_error(_mysql)<<std::endl;
return false;
}
int rows=mysql_num_rows(res);
if(rows!=1){
std::cout<<"one result error\n";
mysql_free_result(res);
return false;
}
MYSQL_ROW row=mysql_fetch_row(res);
(*order)["id"]=order_id;
(*order)["dishes"]=row[1];
(*order)["status"]=std::stoi(row[2]);
(*order)["mtime"]=row[3];
mysql_free_result(res);
return true;
}
};
};
db.sql
//db.sql
create database if not exists order_system;
use order_system;
create table if not exists tb_dish(
id int primary key auto_increment,
name varchar(32) unique not null,
price int not null,
ctime datetime
);
create table if not exists tb_order(
id int primary key auto_increment,
dishes varchar(255) comment '[1,2]',
status int comment '0-未完成,1-完成',
mtime datetime
);
insert tb_dish values(null,"刀削面",900,now()),
(null,"油泼面",1200,now());
insert tb_order values(null,"[1,2]",0,now(),null,"[1]",0,now());
mian.cpp
//main.cpp
/*************************************************************************
> File Name: main.cpp
> Author: Black_K
> Mail: xzp01@foxmail.com
> Created Time: Thu 21 Oct 2021 12:38:16 PM CST
************************************************************************/
//#include<regex>
#include"db.hpp"
#include"httplib.h"
#include <regex>
#define WWWROOT "./wwwroot"
using namespace httplib;
order_sys::TableDish *tb_dish=NULL;
order_sys::TableOrder *tb_order=NULL;
void DishInsert(const Request &req,Response &rsp){
//1.业务处理
//1.解析正文 (json反序列化),得到菜品信息
Json::Value dish;
Json::Reader reader;
bool ret=reader.parse(req.body,dish);
if(ret==false){
rsp.status=400;
Json::Value reason;
Json::FastWriter writer;
reason["result"]=false;
reason["reason"]="dish info parse failed!";
rsp.body=writer.write(reason);
rsp.set_header("Content-Type","application/json");
return ;
}
//2.将菜品信息插入数据库
ret=tb_dish->Insert(dish);
if(ret==false){
Json::Value reason;
Json::FastWriter writer;
reason["result"]=false;
reason["reason"]="mysql insert failed!";
rsp.status=500;
rsp.body=writer.write(reason);
rsp.set_header("Content-Type","application/json");
std::cout<<"mysql insert dish error!"<<std::endl;
return ;
}
//3.设置响应信息
//rsp.status=200;
return ;
}
void DishDelete(const Request &req,Response &rsp){
//1.获取要删除的菜品id /dish/id
int dish_id=std::stoi(req.matches[1]);
//2.数据库删除操作
bool ret=tb_dish->Delete(dish_id);
if(ret==false){
std::cout<<"mysql delete dish error!"<<std::endl;
rsp.status=500;
return ;
}
return ;
}
void DishUpdate(const Request &req,Response &rsp){
int dish_id=std::stoi(req.matches[1]);
Json::Value dish;
Json::Reader reader;
bool ret=reader.parse(req.body,dish);
if(ret==false){
rsp.status=400;
std::cout<<"update -parse dish info error!\n";
return ;
}
dish["id"]=dish_id;
ret=tb_dish->Update(dish);
if(ret==false){
std::cout<<"mysql update dish error!"<<std::endl;
rsp.status=500;
return ;
}
return ;
}
W>void DishGetAll(const Request &req,Response &rsp){
Json::Value dishes;
bool ret=tb_dish->SelectAll(&dishes);
if(ret==false){
std::cout<<"mysql getALl dish error!"<<std::endl;
rsp.status=500;
return ;
}
Json::FastWriter writer;
rsp.body=writer.write(dishes);
return ;
}
void DishGetOne(const Request &req,Response &rsp){
int dish_id=std::stoi(req.matches[1]);
Json::Value dish;
bool ret=tb_dish->SelectOne(dish_id,&dish);
if(ret==false){
std::cout<<"mysql getOne dish error!"<<std::endl;
rsp.status=500;
return ;
}
Json::FastWriter writer;
rsp.body=writer.write(dish);
return ;
}
void OrderInsert(const Request &req,Response &rsp){
Json::Value order;
Json::Reader reader;
bool ret=reader.parse(req.body,order);
if(ret==false){
std::cout<<"insert parse order info error!"<<std::endl;
rsp.status=400;
return ;
}
ret=tb_order->Insert(order);
if(ret==false){
std::cout<<"insert mysql order error!"<<std::endl;
rsp.status=500;
return ;
}
return ;
}
void OrderDelete(const Request &req,Response &rsp){
int order_id=std::stoi(req.matches[1]);
bool ret=tb_order->Delete(order_id);
if(ret==false){
std::cout<<"mysql delete order error!"<<std::endl;
rsp.status=500;
return ;
}
return ;
}
void OrderUpdate(const Request &req,Response &rsp){
int order_id=std::stoi(req.matches[1]);
Json::Value order;
Json::Reader reader;
bool ret=reader.parse(req.body,order);
if(ret==false){
std::cout<<"update parse order info error!"<<std::endl;
rsp.status=400;
return ;
}
order["id"]=order_id;
ret=tb_order->Update(order);
if(ret==false){
std::cout<<"mysql update order error!"<<std::endl;
rsp.status=500;
return ;
}
return ;
}
W>void OrderGetAll(const Request &req,Response &rsp){
Json::Value orders;
bool ret=tb_order->SelectAll(&orders);
if(ret==false){
std::cout<<"mysql getall order error!"<<std::endl;
rsp.status=500;
return ;
}
Json::FastWriter writer;
rsp.body=writer.write(orders);
return ;
}
void OrderGetOne(const Request &req,Response &rsp){
int order_id=std::stoi(req.matches[1]);
Json::Value order;
bool ret=tb_order->SelectOne(order_id,&order);
if(ret==false){
std::cout<<"mysql getone order error!"<<std::endl;
rsp.status=500;
return ;
}
Json::FastWriter writer;
rsp.body=writer.write(order);
return ;
}
int main(){
tb_dish=new order_sys::TableDish();
tb_order=new order_sys::TableOrder();
//dish_test();
//order_test();
Server server;
server.set_base_dir(WWWROOT);
//正则表达式:(\d+)标识匹配一个数字字符一次或多次
//正则表达式:()表示捕捉匹配括号中规则的文本
//R"()" 表示括号中的字符串去除特殊字符的特殊含义
server.Post("/dish",DishInsert);
server.Delete(R"(/dish/(\d+))",DishDelete);
server.Put(R"(/dish/(\d+))",DishUpdate);
server.Get(R"(/dish)",DishGetAll);
server.Get(R"(/dish/(\d+))",DishGetOne);
server.Post("/order",OrderInsert);
server.Delete(R"(/order/(\d+))",OrderDelete);
server.Put(R"(/order/(\d+))",OrderUpdate);
server.Get(R"(/order)",OrderGetAll);
server.Get(R"(/order/(\d+))",OrderGetOne);
server.listen("0.0.0.0",9000);
return 0;
}
void dish_test(){
order_sys::TableDish dish;
//增删改
/*
Json::Value val;
val["id"]=1;
val["name"]="麻婆豆";
val["price"]=2300;
//dish.Insert(val);
dish.Update(val);
dish.Delete(1);
*/
//查
Json::Value val;
Json::StyledWriter writer;
//dish.SelectAll(&val);
dish.SelectOne(2,&val);
std::cout<<writer.write(val)<<std::endl;
}
void order_test(){
order_sys::TableOrder order;
//增删改
/*
Json::Value val;
val["id"]=3;
val["dishes"].append(2);
val["dishes"].append(3);
val["status"]=1;
//order.Insert(val);
//order.Update(val);
order.Delete(3);
*/
//查
Json::Value val;
Json::StyledWriter writer;
//order.SelectAll(&val);
order.SelectOne(1,&val);
std::cout<<writer.write(val)<<std::endl;
}
Makefile
//Makefile
LFLAG=-L/usr/lib64/mysql -lmysqlclient -ljsoncpp
main:main.cpp db.hpp
g++ -std=c++11 $^ -o $@ $(LFLAG
test 文件下
httplib.h是github上下载的
http_server.cpp
//http_server.cpp
/*************************************************************************
> File Name: test.c
> Author: Black_K
> Mail: xzp01@foxmail.com
> Created Time: Thu 21 Oct 2021 08:25:14 PM CST
************************************************************************/
#include"httplib.h"
void hello(const httplib::Request &req,httplib::Response &rsp){
std::cout<<req.method<<std::endl;
std::cout<<req.path<<std::endl;
std::cout<<req.body<<std::endl;
auto it=req.headers.begin();
for(;it!=req.headers.end();++it){
std::cout<<it->first<<"="<<it->second<<std::endl;
}
it=req.params.begin();
for(;it!=req.params.end();++it){
std::cout<<it->first<<"="<<it->second<<std::endl;
}
rsp.status=200;
rsp.body="<html><body><h1>Hello Black_K</h1></body></html>";
rsp.set_header("Content-Type","text/html");
return ;
}
W>int main(int argc,char* argv[]){
//"start coding K:"
httplib::Server srv;
srv.Get("/hello",hello);
srv.listen("0.0.0.0",8080);
return 0;
}
注册路由成员函数
Server.Get()/Post()/Put()/Delete()
设置静态资源默认路径接口:设置了这个路径之后,当前端在请求静态资源的时候/index.html,就会自动的先到这个路径下查找有没有对应静态资源文件,如果有则自动读取文件数据进行回复
Server.set base_ dir(char *path)
httplib库主要是搭建http服务器或者客户端-实现http协议网络通信
而使用库的目的就是把重心放到了业务处理上而不是服务器搭建上前端界面模块: html+css+js
html:完成页面的布局
css: 样式语言-对标签容器进行样式修饰,让简单的html页面更加好看
js: javascript脚本语言,让页面动态渲染展示
项目总结:
项目名称:点餐系统
项目描述:这个点餐系统实现用户通过浏览器与后台服务器进行交互,实现用户查看菜品信息以及下单功能,以及管理员对菜品和订单的管理功能。
项目实现:这个项目在实现的时候采用了一个不太严谨的mvc框架实现,将项目实现总体分为三个模块:数据管理,业务处理,前端页面
其中数据管理模块:基于mysq|数据库实现数据存储管理,并且封装数据库
访问类向外提供与业务分离的数据信息
其中业务处理模块:基于http协议使用httplib库搭建http服务器与前端进行交互进行菜品以及订单的数据业务处理功能
其中前端界面模块:基于简单的htm|与css和vue,js以及 ajax实现前端界面的静态页面展示以及动态数据获取渲染功能