# MgrSystem **Repository Path**: wkhgit/mgr-system ## Basic Information - **Project Name**: MgrSystem - **Description**: 小型超市管理系统 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 1 - **Created**: 2021-09-10 - **Last Updated**: 2021-12-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 文件系统 > 用于管理HTML,script,image等静态资源 ``` enum FileType { BINARY, TXT }; class File { public: using FileBody = std::shared_ptr; using ptr = std::shared_ptr; FileBody getBody(); FileType getType() const {return type_;} size_t getSize() const { return size_;} const std::string& getContentType() const { return content_type_;} File(const std::string &path,FileType type,const std::string &content_type); private: void ReadFile(); private: uint64_t modify_time_; size_t size_; std::string path_; FileBody body_; FileType type_; std::string content_type_; RWlock lock_; }; class FileSystem { public: File::ptr getFile(const std::string &path); void ReadAllFile(const std::string &path,const std::string &save_path,const std::string &content_type,FileType type); private: RWlock lock_; std::unordered_map files_; }; ``` # 注册业务 ## 协议设计 前端将用户名,性别,电话号码,密码,职位,年龄序列化成json格式存放至http协议中的body进行请求 ``` struct RegisterReq { std::string name; std::string sex; std::string phone; std::string pwd; std::string post; int age; }; REFLECTION(RegisterReq,name,sex,phone,pwd,post,age); struct RegisterRsp { enum Code { OK = 2, EXIST = 3, ArgError = 4 }; int code; }; REFLECTION(RegisterRsp,code); ``` ## 流程图 ![image](https://img-blog.csdnimg.cn/3ba94e26a5c740ef80afb96978343aae.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQEtI,size_20,color_FFFFFF,t_70,g_se,x_16) ## 后端响应接口设计 ``` int32_t RegisterServlet::handle(HttpRequest::ptr &request, HttpResponse::ptr &response, HttpSession::ptr &session) { if(request->getMethod() != HttpMethod::POST) { response->setStatus(HttpStatus::METHOD_NOT_ALLOWED); return 0; } auto ReqBody = checkBody(request); RegisterRsp RspBody; co_defer [&RspBody,&response]() { response->setHeader("Content-type", "application/json"); response->setBody(std::make_shared(to_json(RspBody))); }; if(!ReqBody) { RspBody.code = RegisterRsp::ArgError; return 0; } auto MysqlPcon = App.getMysqlPcon(); worker_info_::WorkerInfo table; try{ MysqlPcon->run(insert_into(table).set(table.name = ReqBody->name, table.sex = ReqBody->sex, table.phone = ReqBody->phone, table.post = ReqBody->post, table.pwd = ReqBody->pwd, table.age = ReqBody->age)); RspBody.code = RegisterRsp::OK; }catch(sqlpp::exception &e) { LOG_INFO(e.what()); RspBody.code = RegisterRsp::EXIST; } } ``` # 购买商品 ## 协议设计 前端将session信息,商品id,购买数量序列化为json数据,通过HTTP请求发送至后端服务器 ``` struct addSellInfoReq { std::string session; int64_t mid; uint32_t num; }; REFLECTION(addSellInfoReq,session,mid,num); struct addMerchandiseInfoReq { std::string session; std::string name; double price; uint32_t inventory; }; REFLECTION(addMerchandiseInfoReq,session,name,price,inventory) ``` ## 流程图 ![image](https://img-blog.csdnimg.cn/61a0e9f13221469392f62b10d057af6c.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQEtI,size_20,color_FFFFFF,t_70,g_se,x_16) ## 后端响应接口 > 购买商品servlet ``` int32_t SellServlet::addSellInfoSlt(HttpRequest::ptr &req,HttpResponse::ptr &rsp,HttpSession::ptr &session) { LOG_DEBUG("addSellInfo handle"); UtilRsp RspBody; co_defer MakeSetBodyFunc(RspBody,rsp); auto ReqBody = checkBody()(req); if(!ReqBody) { RspBody.code = UtilRsp::SessionError; return 0; } if(!checkSession()(ReqBody->session,rsp)) { RspBody.code = UtilRsp::SessionError; return 0; } auto MysqlPcon = PconMgr::getMysqlPcon(rsp); if(!MysqlPcon) return 0; Merchandise_t merchandise; if(!checkStock(MysqlPcon,ReqBody->mid,ReqBody->num,merchandise)) { RspBody.code = UtilRsp::Failed; return 0; } auto RedisPcon = PconMgr::getRedisPcon(rsp); if(!RedisPcon) return 0; std::unordered_map map; auto phone = RedisPcon->get(ReqBody->session); if(!phone) { RspBody.code = UtilRsp::Failed; return 0; } RedisPcon->hgetall(phone->data(), std::inserter(map, map.begin())); if(!purchase(MysqlPcon, merchandise,ReqBody->num,map["name"],atoi(map["id"].c_str()))) { RspBody.code = UtilRsp::Failed; return 0; } RspBody.code = UtilRsp::OK; return 0; } ``` > 检验商品库存 ``` bool SellServlet::checkStock(MysqlPool::MysqlPcon &pcon,int64_t id,uint32_t num,Merchandise_t &merchandise) { using namespace sqlpp; merchandise_info_::MerchandiseInfo table; auto row = pcon->run(select(all_of(table)).from(table).where(table.mid == id)); if(row.empty()) return false; if(row.front().inventory < num) return false; try { pcon->run(update(table).set(table.inventory = table.inventory - num).where(table.mid == id)); }catch(sqlpp::exception &e) { LOG_INFO(e.what()); return false; } auto &info = row.front(); std::get<0>(merchandise) = info.mid; std::get<1>(merchandise) = info.name; std::get<2>(merchandise) = info.price; std::get<3>(merchandise) = info.inventory; return true; } ``` > 购买商品 ``` bool SellServlet::purchase(MysqlPool::MysqlPcon &pcon,Merchandise_t &merchandise,uint32_t num,const std::string &ename,uint64_t eid) { using namespace sqlpp; sell_info_::SellInfo table; auto now_time = std::chrono::system_clock::now() + std::chrono::hours(16); try{ pcon->run(insert_into(table).set(table.id = default_value,table.time = now_time, table.num = num, table.money = num * std::get<2>(merchandise), table.mid = std::get<0>(merchandise), table.mname = std::get<1>(merchandise), table.eid = eid, table.ename = ename)); }catch(sqlpp::exception &e) { LOG_INFO(e.what()); } return true; } ``` # 添加商品 ## 协议设计 ``` struct addMerchandiseInfoReq { std::string session; std::string name; double price; uint32_t inventory; }; REFLECTION(addMerchandiseInfoReq,session,name,price,inventory); struct UtilRsp { enum Code { OK = 2, SessionError = 3, Failed = 4 }; int code; }; REFLECTION(UtilRsp,code); ``` ## 流程图 ![image](https://img-blog.csdnimg.cn/11ec31cf65a147da85a1e2fdeece0556.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQEtI,size_20,color_FFFFFF,t_70,g_se,x_16) ## 后端响应接口 ``` int32_t MerchandisServlet::addMerchandiseInfo(HttpRequest::ptr &req, HttpResponse::ptr &rsp, HttpSession::ptr &session) { UtilRsp RspBody; co_defer MakeSetBodyFunc(RspBody, rsp); auto ReqBody = checkBody()(req); if (!ReqBody) { RspBody.code = UtilRsp::SessionError; return 0; } if (!checkSession()(ReqBody->session, rsp)) { RspBody.code = getAllMerchandiseInfoRsp::SessionError; return 0; } auto MysqlPcon = PconMgr::getMysqlPcon(rsp); if (!MysqlPcon) return 0; merchandise_info_::MerchandiseInfo table; using namespace sqlpp; try { MysqlPcon->run(insert_into(table).set(table.mid = default_value, table.name = ReqBody->name, table.price = ReqBody->price, table.inventory = ReqBody->inventory)); RspBody.code = UtilRsp::OK; } catch (sqlpp::exception &e) { LOG_INFO(e.what()); RspBody.code = UtilRsp::Failed; } return 0; } ``` # 修改商品信息 ## 协议设计 ``` struct updateMerchandiseInfoReq { std::string session; int64_t id; std::string name; double price; uint32_t inventory; }; REFLECTION(updateMerchandiseInfoReq,session,id,name,price,inventory); ``` ## 流程图 ![image](https://img-blog.csdnimg.cn/11ec31cf65a147da85a1e2fdeece0556.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQEtI,size_20,color_FFFFFF,t_70,g_se,x_16) ## 后端响应接口 ``` int32_t MerchandisServlet::updateMerchandiseInfo(HttpRequest::ptr &req, HttpResponse::ptr &rsp, HttpSession::ptr &session) { UtilRsp RspBody; co_defer MakeSetBodyFunc(RspBody, rsp); LOG_DEBUG((req->toString())); auto ReqBody = checkBody()(req); if (!ReqBody) { RspBody.code = UtilRsp::SessionError; return 0; } if (!checkSession()(ReqBody->session, rsp)) { RspBody.code = getAllMerchandiseInfoRsp::SessionError; return 0; } auto MysqlPcon = PconMgr::getMysqlPcon(rsp); if (!MysqlPcon) return 0; merchandise_info_::MerchandiseInfo table; using namespace sqlpp; try { MysqlPcon->run(update(table).set(table.name = ReqBody->name, table.price = ReqBody->price, table.inventory = ReqBody->inventory) .where(table.mid == ReqBody->id)); RspBody.code = UtilRsp::OK; LOG_INFO("update merchandise id = {1} success ", ReqBody->id); } catch (sqlpp::exception &e) { LOG_INFO(e.what()); RspBody.code = UtilRsp::Failed; } } ```