~~未完待续,别扣我分~~ 尚未定稿的内容见《总体设计文档》 **项目名称**:BookStore **作者**:Zhuang Yumin # 程序功能概述 此项目分为前端和后端。后端即本次大作业的主体部分,接受文本格式的命令,并以文本格式返回响应;前端则以WebUI的形式向用户提供操作界面。 # 主体逻辑说明 业务流程图:![业务流程图加载中……](https://cloud.zymsite.ink/f/XauW/%E4%B8%9A%E5%8A%A1%E6%B5%81%E7%A8%8B%E5%9B%BE.png) 数据流图:![数据流图加载中……](https://cloud.zymsite.ink/f/qxfn/%E6%95%B0%E6%8D%AE%E6%B5%81%E5%9B%BE.png) 系统结构图:![系统结构图加载中……](https://cloud.zymsite.ink/f/dVFB/%E7%B3%BB%E7%BB%9F%E7%BB%93%E6%9E%84%E5%9B%BE.png) 详见[需求分析文档](需求分析文档.md)和[总体设计文档](总体设计文档.md) # 代码文件结构 - `backend/include`:后端头文件 - `backend/src`:后端实现文件 - `frontend/Web`:WebUI相关 - `frontend/client`:客户端 - `external/clipp`:第三方库,解析命令行参数 - `external/json`:第三方库,为调试器提供json支持(虽然基本没啥用) # 各个类的接口及成员说明 ## DriveArray 提供文件存储支持,有缓存等元数据,在兼容MemoryRiver的基础上提供下列接口: - `bool IsOpen()` - `void OpenFile(const std::string &__file_name)` - `void CloseFile()` - `void LoadInfoTo(int *dest)`:批量读取info - `void WriteInfoFrom(int *src)`:批量写入info - `void FetchAll(std::vector &vec)`:遍历并获取所有元素 ## key2index 提供从字符串映射到一个值的支持,有内存中的散列表等内部数据,相当于multimap,有如下接口: - `void OpenFile(const std::string __file_name)` - `void Insert(const std::string &str, int val)` - `void Delete(const std::string &str, int val)` - `std::vector Find(const std::string &str)` ## 数据库 三个数据库的声明如下,相关信息见注释: ```cpp class UserDataBase { DriveArray full_user_data; String2Index user_name2index; public: UserDataBase() = default; void Open(std::string file_name); bool PAM(const std::string &user_id, const std::string &password); // 登陆验证 int GetPrevilege(const std::string &user_id); // 获取用户权限,用户不存在时返回-1 void AddUser(const std::string &user_id, const std::string &password, const std::string &user_name, int privilege); // 新增用户 void DeleteUser(const std::string &user_id); // 删除用户 void ChangePassword(const std::string &user_id, const std::string &password); // 修改密码 }; class BookDataBase { DriveArray full_book_data; String2Index ISBN2index, name2index, author2index, keyword2index; public: void Open(std::string file_name); bool HaveISBN(const std::string &ISBN); // 判断是否有 bool HaveISBN(const std::string &ISBN, BookItemClass &ret); // 判断是否有并且获取内容 void CreateEmptyBook(const std::string &ISBN); // 新建一个书 void QueryBook(const std::string &ISBN, const std::string &name, const std::string &author, const std::string &keyword, std::vector &ret); // 查询书籍,没有的关键词直接置为空 void ModifyInfo(const std::string &ISBN, const std::string &new_ISBN, const std::string &name, const std::string &author, const std::string &keyword, double price, int quantity_remain); // 修改信息,当一个字段无需修改时,字符串设为空,数值设为-1 std::string GetISBN(int bid); // 获取某个bid(当ISBN变化后唯一确定一本书的方式)对应的图书的ISBN号 }; class LogDataBase { DriveArray finance_data; DriveArray operation_log_data; int finance_operation_count; public: ~LogDataBase() { finance_data.write_info(finance_operation_count, 1); } void Open(std::string file_name); void AddSell(int book_id, int quantity, double total_price); // 添加一笔销售记录 void AddImport(int book_id, int quantity, double total_price); // 添加一笔进货记录 std::pair QueryFinance(int count = -1); // 查询最近count次交易的资金流动概要 void QueryFinance(int count, std::vector &ret); int TotalFinanceOperationCount() noexcept { return finance_operation_count; } // 查询总交易笔数 }; ``` ## 引擎 下辖三个数据库实例,和一个登录计数器,并存储是否为服务器模式以及数据文件存放位置。 对外提供解析并执行命令的接口,返回值是一个`std::vector`,每一个`std::string`对应输出中的一行 ```cpp class BookStoreEngineClass { std::string config_dir; UserDataBase user_data_base; BookDataBase book_data_base; LogDataBase log_data_base; std::unordered_map login_count; bool is_server; public: BookStoreEngineClass() = delete; BookStoreEngineClass(std::string __config_dir, bool __is_server); std::vector Execute( const std::string &cmd, std::stack> &login_stack); std::vector ExecuteSu( const std::string &cmd, std::stack> &login_stack); std::vector ExecuteLogout( const std::string &cmd, std::stack> &login_stack); std::vector ExecuteRegister( const std::string &cmd, std::stack> &login_stack); std::vector ExecutePasswd( const std::string &cmd, std::stack> &login_stack); std::vector ExecuteUserAdd( const std::string &cmd, std::stack> &login_stack); std::vector ExecuteDelete( const std::string &cmd, std::stack> &login_stack); std::vector ExecuteShow( const std::string &cmd, std::stack> &login_stack); std::vector ExecuteBuy( const std::string &cmd, std::stack> &login_stack); std::vector ExecuteSelect( const std::string &cmd, std::stack> &login_stack); std::vector ExecuteMOdify( const std::string &cmd, std::stack> &login_stack); std::vector ExecuteImport( const std::string &cmd, std::stack> &login_stack); std::vector ExecuteShowFinance( const std::string &cmd, std::stack> &login_stack); std::vector ExecuteLog( const std::string &cmd, std::stack> &login_stack); std::vector ExecuteReport( const std::string &cmd, std::stack> &login_stack); }; ``` # 文件存储说明 默认往当前目录下存放文件,但也可以指定。 - `book.author`:书籍数据库的作者名索引 - `book.isbn`:书籍数据库的ISBN索引 - `book.keyword`:书籍数据库的关键词索引 - `book.name`:书籍数据库的书名索引 - `book.full`:书籍数据库的完整信息 - `user.n2i`:用户数据库的索引 - `user.full`:用户数据库的完整信息 - `log.finance`:交易日志 - `log.log`:完整操作日志 # 其他补充说明 主程序命令行交互方式: ``` SYNOPSIS ./code [-s] [-c ] OPTIONS -s, --server run as server -c, --config use config directory ```