Big Update: 40% complete

This commit is contained in:
Kirigaya Kazuto 2017-12-08 22:37:18 +08:00
parent ec42d7db08
commit f792c9bc19
41 changed files with 2469 additions and 490 deletions

View File

@ -31,99 +31,37 @@
<Compiler>
<Add option="-Wall" />
<Add option="-fexceptions" />
<Add option="-D_HTTPWRAPPER_WITH_SESSION" />
<Add option="-D_HTTPWRAPPER_WITH_MYSQL" />
<Add directory="MySQLWrapper" />
<Add directory="mysql_include" />
<Add directory="HTTPWrapper" />
<Add directory="WinUtil" />
<Add directory="D:/CodeBlocks_Codes/DBHomework/" />
</Compiler>
<Linker>
<Add library="mysql_lib/libmysql.lib" />
</Linker>
<Unit filename="HTTPWrapper/CookieVec.cpp" />
<Unit filename="HTTPWrapper/CookieVec.h" />
<Unit filename="HTTPWrapper/Readme.md" />
<Unit filename="HTTPWrapper/Request.cpp" />
<Unit filename="HTTPWrapper/Request.h" />
<Unit filename="HTTPWrapper/Response.cpp" />
<Unit filename="HTTPWrapper/Response.h" />
<Unit filename="HTTPWrapper/Session.cpp" />
<Unit filename="HTTPWrapper/Session.h" />
<Unit filename="HTTPWrapper/Session_MySQL.cpp" />
<Unit filename="HTTPWrapper/Singleton.hpp" />
<Unit filename="HTTPWrapper/Util.cpp" />
<Unit filename="HTTPWrapper/Util.h" />
<Unit filename="MySQLTransaction.cpp" />
<Unit filename="MySQLTransaction.h" />
<Unit filename="MySQLWrapper/MySQLInclude.h" />
<Unit filename="MySQLWrapper/MySQLTransaction.cpp" />
<Unit filename="MySQLWrapper/MySQLTransaction.h" />
<Unit filename="MySQLWrapper/MySQLWrapper.cpp" />
<Unit filename="MySQLWrapper/MySQLWrapper.h" />
<Unit filename="json.hpp" />
<Unit filename="bs_util.cpp" />
<Unit filename="bs_util.h" />
<Unit filename="jsonfail.cpp" />
<Unit filename="jsonfail.h" />
<Unit filename="mysql_include/big_endian.h" />
<Unit filename="mysql_include/binary_log_types.h" />
<Unit filename="mysql_include/byte_order_generic.h" />
<Unit filename="mysql_include/byte_order_generic_x86.h" />
<Unit filename="mysql_include/decimal.h" />
<Unit filename="mysql_include/errmsg.h" />
<Unit filename="mysql_include/keycache.h" />
<Unit filename="mysql_include/little_endian.h" />
<Unit filename="mysql_include/m_ctype.h" />
<Unit filename="mysql_include/m_string.h" />
<Unit filename="mysql_include/my_alloc.h" />
<Unit filename="mysql_include/my_byteorder.h" />
<Unit filename="mysql_include/my_command.h" />
<Unit filename="mysql_include/my_compiler.h" />
<Unit filename="mysql_include/my_config.h" />
<Unit filename="mysql_include/my_dbug.h" />
<Unit filename="mysql_include/my_dir.h" />
<Unit filename="mysql_include/my_getopt.h" />
<Unit filename="mysql_include/my_global.h" />
<Unit filename="mysql_include/my_list.h" />
<Unit filename="mysql_include/my_sys.h" />
<Unit filename="mysql_include/my_thread.h" />
<Unit filename="mysql_include/my_thread_local.h" />
<Unit filename="mysql_include/my_xml.h" />
<Unit filename="mysql_include/mysql.h" />
<Unit filename="mysql_include/mysql/client_authentication.h" />
<Unit filename="mysql_include/mysql/client_plugin.h" />
<Unit filename="mysql_include/mysql/get_password.h" />
<Unit filename="mysql_include/mysql/mysql_lex_string.h" />
<Unit filename="mysql_include/mysql/plugin_auth_common.h" />
<Unit filename="mysql_include/mysql/plugin_trace.h" />
<Unit filename="mysql_include/mysql/psi/mysql_file.h" />
<Unit filename="mysql_include/mysql/psi/mysql_idle.h" />
<Unit filename="mysql_include/mysql/psi/mysql_mdl.h" />
<Unit filename="mysql_include/mysql/psi/mysql_memory.h" />
<Unit filename="mysql_include/mysql/psi/mysql_ps.h" />
<Unit filename="mysql_include/mysql/psi/mysql_socket.h" />
<Unit filename="mysql_include/mysql/psi/mysql_sp.h" />
<Unit filename="mysql_include/mysql/psi/mysql_stage.h" />
<Unit filename="mysql_include/mysql/psi/mysql_statement.h" />
<Unit filename="mysql_include/mysql/psi/mysql_table.h" />
<Unit filename="mysql_include/mysql/psi/mysql_thread.h" />
<Unit filename="mysql_include/mysql/psi/mysql_transaction.h" />
<Unit filename="mysql_include/mysql/psi/psi.h" />
<Unit filename="mysql_include/mysql/psi/psi_base.h" />
<Unit filename="mysql_include/mysql/psi/psi_memory.h" />
<Unit filename="mysql_include/mysql/service_my_snprintf.h" />
<Unit filename="mysql_include/mysql/service_mysql_alloc.h" />
<Unit filename="mysql_include/mysql_com.h" />
<Unit filename="mysql_include/mysql_com_server.h" />
<Unit filename="mysql_include/mysql_embed.h" />
<Unit filename="mysql_include/mysql_time.h" />
<Unit filename="mysql_include/mysql_version.h" />
<Unit filename="mysql_include/mysqld_ername.h" />
<Unit filename="mysql_include/mysqld_error.h" />
<Unit filename="mysql_include/sql_common.h" />
<Unit filename="mysql_include/sql_state.h" />
<Unit filename="mysql_include/sslopt-case.h" />
<Unit filename="mysql_include/sslopt-longopts.h" />
<Unit filename="mysql_include/sslopt-vars.h" />
<Unit filename="mysql_include/thr_cond.h" />
<Unit filename="mysql_include/thr_mutex.h" />
<Unit filename="mysql_include/thr_rwlock.h" />
<Unit filename="mysql_include/typelib.h" />
<Unit filename="removebook.cpp" />
<Extensions>
<code_completion />
<envvars />

View File

@ -1,24 +1,16 @@
# depslib dependency file v1.0
1510706148 source:d:\codeblocks_codes\dbhomework\main.cpp
<cstdio>
<cstdlib>
<cstring>
<string>
<sstream>
<fstream>
<iostream>
<vector>
"Request.h"
"Response.h"
1511504972 source:d:\codeblocks_codes\dbhomework\main.cpp
"Session.h"
"Util.h"
"MySQLWrapper.h"
"jsonfail.h"
"json.hpp"
"MySQLTransaction.h"
1511076615 d:\codeblocks_codes\dbhomework\mysqlwrapper\mysqlwrapper.h
<functional>
<string>
1511076563 source:d:\codeblocks_codes\dbhomework\mysqlwrapper\mysqlwrapper.cpp
1511877230 source:d:\codeblocks_codes\dbhomework\mysqlwrapper\mysqlwrapper.cpp
"MySQLWrapper.h"
"MySQLInclude.h"
<string>
@ -96,38 +88,39 @@
"Util.h"
<fstream>
1510899241 source:d:\codeblocks_codes\dbhomework\httpwrapper\request.cpp
1511792433 source:d:\codeblocks_codes\dbhomework\httpwrapper\request.cpp
"Request.h"
"Util.h"
<cstdlib>
<cstring>
<sstream>
<algorithm>
1510899188 d:\codeblocks_codes\dbhomework\httpwrapper\request.h
1511686368 d:\codeblocks_codes\dbhomework\httpwrapper\request.h
<string>
<map>
"Session.h"
1511136347 source:d:\codeblocks_codes\dbhomework\httpwrapper\response.cpp
1511686368 source:d:\codeblocks_codes\dbhomework\httpwrapper\response.cpp
"Response.h"
<sstream>
<iostream>
1511136341 d:\codeblocks_codes\dbhomework\httpwrapper\response.h
1511686368 d:\codeblocks_codes\dbhomework\httpwrapper\response.h
<string>
"CookieVec.h"
1511153903 source:d:\codeblocks_codes\dbhomework\httpwrapper\util.cpp
1511686368 source:d:\codeblocks_codes\dbhomework\httpwrapper\util.cpp
"Util.h"
<fstream>
<sstream>
<cstdio>
1511153929 d:\codeblocks_codes\dbhomework\httpwrapper\util.h
1511689007 d:\codeblocks_codes\dbhomework\httpwrapper\util.h
<string>
<sstream>
"MySQLWrapper.h"
"Response.h"
"MySQLWrapper.h"
1510704940 d:\codeblocks_codes\dbhomework\json.hpp
<algorithm>
@ -163,7 +156,7 @@
"Util.h"
<sstream>
1510973351 d:\codeblocks_codes\dbhomework\httpwrapper\cookievec.h
1511791095 d:\codeblocks_codes\dbhomework\httpwrapper\cookievec.h
<map>
<string>
@ -201,7 +194,7 @@
<cstdlib>
<cstring>
1511147480 d:\codeblocks_codes\dbhomework\httpwrapper\session.h
1511250624 d:\codeblocks_codes\dbhomework\httpwrapper\session.h
"Request.h"
"Response.h"
<string>
@ -219,18 +212,20 @@
"Util.h"
"json.hpp"
1511149331 source:d:\codeblocks_codes\dbhomework\login.cpp
1511687998 source:d:\codeblocks_codes\dbhomework\login.cpp
"Request.h"
"Response.h"
"Session.h"
"Util.h"
"json.hpp"
"jsonfail.h"
"MySQLWrapper.h"
"MySQLTransaction.h"
1511136779 source:d:\codeblocks_codes\dbhomework\addbooktype.cpp
"Session.h"
"Util.h"
"json.hpp"
1511149002 source:d:\codeblocks_codes\dbhomework\jsonfail.cpp
1511158571 source:d:\codeblocks_codes\dbhomework\jsonfail.cpp
"jsonfail.h"
1511153994 d:\codeblocks_codes\dbhomework\jsonfail.h
@ -259,3 +254,136 @@
1511156696 d:\codeblocks_codes\dbhomework\mysqltransaction.h
"MySQLWrapper.h"
1511248736 source:d:\codeblocks_codes\dbhomework\dopaste.cpp
"Request.h"
"Response.h"
"Util.h"
"json.hpp"
<fstream>
<cstdio>
"windows.h"
1511878138 source:d:\codeblocks_codes\dbhomework\httpwrapper\session_mysql.cpp
"Session.h"
"Singleton.hpp"
"Util.h"
"MySQLWrapper.h"
"MySQLTransaction.h"
<ctime>
<cstdlib>
<cstring>
1511337863 source:d:\codeblocks_codes\dbhomework\blockuser.cpp
"Session.h"
"Util.h"
"jsonfail.h"
"json.hpp"
1511338065 source:d:\codeblocks_codes\dbhomework\allowuser.cpp
"Session.h"
"Util.h"
"jsonfail.h"
"json.hpp"
1511416570 source:d:\codeblocks_codes\dbhomework\addbookobject.cpp
"Session.h"
"Util.h"
"jsonfail.h"
"json.hpp"
"MySQLTransaction.h"
1511877177 d:\codeblocks_codes\dbhomework\mysqlwrapper\mysqltransaction.h
"MySQLWrapper.h"
1511877161 source:d:\codeblocks_codes\dbhomework\mysqlwrapper\mysqltransaction.cpp
"MySQLTransaction.h"
1511687385 source:d:\codeblocks_codes\dbhomework\install.cpp
"Request.h"
"Response.h"
"Session.h"
"Util.h"
"MySQLWrapper.h"
"MySQLTransaction.h"
1511790374 source:d:\codeblocks_codes\dbhomework\old\login.cpp
"Session.h"
"Util.h"
"json.hpp"
"jsonfail.h"
1510704940 d:\codeblocks_codes\dbhomework\\json.hpp
<algorithm>
<array>
<cassert>
<cctype>
<ciso646>
<cmath>
<cstddef>
<cstdint>
<cstdlib>
<cstring>
<forward_list>
<functional>
<initializer_list>
<iomanip>
<iostream>
<iterator>
<limits>
<locale>
<map>
<memory>
<numeric>
<sstream>
<stdexcept>
<string>
<type_traits>
<utility>
<vector>
1511153994 d:\codeblocks_codes\dbhomework\\jsonfail.h
1511940029 source:d:\codeblocks_codes\dbhomework\src\login.cpp
"bs_util.h"
<mutex>
<condition_variable>
1511939814 source:d:\codeblocks_codes\dbhomework\bs_util.cpp
"bs_util.h"
1512014783 d:\codeblocks_codes\dbhomework\\bs_util.h
"Request.h"
"Response.h"
"Session.h"
"json.hpp"
"jsonfail.h"
"Util.h"
1512014783 d:\codeblocks_codes\dbhomework\bs_util.h
"Request.h"
"Response.h"
"Session.h"
"json.hpp"
"jsonfail.h"
"Util.h"
1511941430 source:d:\codeblocks_codes\dbhomework\src\dochecklogin.cpp
"bs_util.h"
1511963515 source:d:\codeblocks_codes\dbhomework\src\dogetbookstatus.cpp
"bs_util.h"
1511947446 source:d:\codeblocks_codes\dbhomework\src\doviewbook.cpp
"bs_util.h"
1512096115 source:d:\codeblocks_codes\dbhomework\src\doborrowbook.cpp
"bs_util.h"
"MySQLTransaction.h"
1512108415 source:d:\codeblocks_codes\dbhomework\src\doaddbook.cpp
"bs_util.h"
1512703018 source:d:\codeblocks_codes\dbhomework\src\doaddbookobj.cpp
"bs_util.h"
"MySQLTransaction.h"

View File

@ -1,100 +1,95 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_layout_file>
<FileVersion major="1" minor="0" />
<ActiveTarget name="Release" />
<File name="HTTPWrapper\Response.h" open="1" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<ActiveTarget name="Debug" />
<File name="HTTPWrapper\Response.cpp" open="1" top="0" tabpos="10" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="214" topLine="0" />
<Cursor1 position="858" topLine="27" />
</Cursor>
</File>
<File name="HTTPWrapper\Util.cpp" open="1" top="0" tabpos="9" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="MySQLWrapper\MySQLWrapper.cpp" open="1" top="0" tabpos="14" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="102" topLine="3" />
<Cursor1 position="1894" topLine="81" />
</Cursor>
</File>
<File name="HTTPWrapper\Util.h" open="1" top="0" tabpos="8" split="0" active="1" splitpos="0" zoom_1="1" zoom_2="0">
<File name="HTTPWrapper\Session_MySQL.cpp" open="1" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="1" zoom_2="0">
<Cursor>
<Cursor1 position="158" topLine="30" />
<Cursor1 position="2533" topLine="95" />
</Cursor>
</File>
<File name="removebook.cpp" open="1" top="1" tabpos="17" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="jsonfail.h" open="1" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2103" topLine="63" />
<Cursor1 position="366" topLine="0" />
</Cursor>
</File>
<File name="MySQLTransaction.cpp" open="1" top="0" tabpos="15" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="HTTPWrapper\Singleton.hpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="726" topLine="31" />
<Cursor1 position="217" topLine="27" />
</Cursor>
</File>
<File name="MySQLWrapper\MySQLInclude.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="MySQLWrapper\MySQLTransaction.cpp" open="1" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="66" topLine="0" />
<Cursor1 position="536" topLine="19" />
</Cursor>
</File>
<File name="MySQLWrapper\MySQLWrapper.cpp" open="1" top="0" tabpos="12" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="bs_util.cpp" open="1" top="0" tabpos="15" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2643" topLine="96" />
<Cursor1 position="1534" topLine="54" />
</Cursor>
</File>
<File name="MySQLWrapper\MySQLWrapper.h" open="0" top="0" tabpos="12" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="HTTPWrapper\CookieVec.h" open="1" top="0" tabpos="11" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="655" topLine="26" />
<Cursor1 position="2194" topLine="0" />
</Cursor>
</File>
<File name="HTTPWrapper\CookieVec.h" open="1" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="MySQLWrapper\MySQLWrapper.h" open="1" top="0" tabpos="13" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2013" topLine="10" />
<Cursor1 position="556" topLine="26" />
</Cursor>
</File>
<File name="HTTPWrapper\CookieVec.cpp" open="1" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="MySQLWrapper\MySQLTransaction.h" open="1" top="0" tabpos="12" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="960" topLine="0" />
<Cursor1 position="506" topLine="0" />
</Cursor>
</File>
<File name="MySQLTransaction.h" open="1" top="0" tabpos="14" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="HTTPWrapper\Util.cpp" open="1" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="137" topLine="0" />
<Cursor1 position="2712" topLine="118" />
</Cursor>
</File>
<File name="HTTPWrapper\Request.h" open="1" top="0" tabpos="10" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="HTTPWrapper\Request.cpp" open="1" top="0" tabpos="9" split="0" active="1" splitpos="0" zoom_1="3" zoom_2="0">
<Cursor>
<Cursor1 position="159" topLine="0" />
<Cursor1 position="369" topLine="0" />
</Cursor>
</File>
<File name="jsonfail.cpp" open="1" top="0" tabpos="16" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="HTTPWrapper\Request.h" open="1" top="1" tabpos="8" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="592" topLine="7" />
<Cursor1 position="472" topLine="0" />
</Cursor>
</File>
<File name="HTTPWrapper\Request.cpp" open="1" top="0" tabpos="11" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="HTTPWrapper\Response.h" open="1" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="3128" topLine="47" />
<Cursor1 position="292" topLine="0" />
</Cursor>
</File>
<File name="HTTPWrapper\Response.cpp" open="1" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="HTTPWrapper\Session.h" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="294" topLine="3" />
<Cursor1 position="745" topLine="3" />
</Cursor>
</File>
<File name="jsonfail.h" open="1" top="0" tabpos="13" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="HTTPWrapper\Util.h" open="1" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="251" topLine="0" />
<Cursor1 position="1586" topLine="0" />
</Cursor>
</File>
<File name="HTTPWrapper\Session.cpp" open="1" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="bs_util.h" open="1" top="0" tabpos="16" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2516" topLine="162" />
<Cursor1 position="29" topLine="0" />
</Cursor>
</File>
<File name="HTTPWrapper\Session.h" open="1" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="jsonfail.cpp" open="1" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="541" topLine="0" />
</Cursor>
</File>
<File name="HTTPWrapper\Singleton.hpp" open="1" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="21" topLine="27" />
<Cursor1 position="559" topLine="0" />
</Cursor>
</File>
</CodeBlocks_layout_file>

View File

@ -19,4 +19,4 @@ int getPermissionLevel(const std::string& Username,Response& res);
std::function<void(MySQLResult&)> SQLParseInt(int& nval);
#define postval(NAME) if(req.post[#NAME].empty()){jsonfail(err_missing_parameter);break;}string NAME=req.post[#NAME]
#define startdb() DBInfo db;if(db.readConfig()<0){jsonfail(err_config);break;} MySQLConn conn;if(db.connectProxy(conn)<0){jsonfail(err_connect);break;}
#define startdb() DBInfo db;if(db.readConfig()<0){jsonfail(err_config);break;} MySQLConn conn;if(db.connectProxy(conn)<0){jsonfail(err_connect);break;}if(conn.exec("set names utf8",nullptr)<0){jsonfail(err_sql,"Failed to set names");break;}

5
dbconfig.txt Normal file
View File

@ -0,0 +1,5 @@
127.0.0.1
root
ilovelgj
abc
3306

View File

@ -1,118 +1,146 @@
数据库作业:
语言
数据库作业:
语言
JavaScript,HTML,C++
数据库:
数据库:
MySQL
===================
数据库表设计
数据库表设计
===================
表前缀: bs_
用户表(bs_user)
登录账号 varchar 主键
登录密码 varchar (hashed)
昵称 varchar
用户级别 integer (0 超级管理员 1 管理员 2 图书馆借阅处 3 读者)
3级用户必须有对应的用户信息!
账户状态 integer (0 隐藏 1 禁止登陆 2 需要验证才能激活 3 允许登陆)
隐藏状态: 以该登陆账号登陆时会提示账户不存在,但注册时会提示不能不注册
禁止登陆: 以该登陆账号登陆时会提示账户已被禁用
待验证: 刚注册完的用户需要经过验证,登陆时会提示待验证. 验证后状态变为3
允许登陆: 一切正常
表前缀: bs_
用户表(bs_user)
登录账号 varchar 主键
登录密码 varchar (hashed)
昵称 varchar
用户级别 integer (0 超级管理员 1 管理员 2 图书馆借阅处 3 读者)
3级用户必须有对应的用户信息!
账户状态 integer (0 隐藏 1 禁止登陆 2 需要验证才能激活 3 允许登陆)
隐藏状态: 以该登陆账号登陆时会提示账户不存在,但注册时会提示不能不注册
禁止登陆: 以该登陆账号登陆时会提示账户已被禁用
待验证: 刚注册完的用户需要经过验证,登陆时会提示待验证. 验证后状态变为3
允许登陆: 一切正常
级别表(bs_level)
等级 integer 主键
默认最低借阅限额 integer
默认最高借阅限额 integer
默认最低借阅时间 integer
默认最高借阅时间 integer
可接受的最小余额额度 money
级别表(bs_level)
等级 integer 主键
默认最低借阅限额 integer
默认最高借阅限额 integer
默认最低借阅时间 integer
默认最高借阅时间 integer
可接受的最小余额额度 money
读者表(bs_reader)
登录账号 外键到bs_user
姓名 varchar
身份证号 varchar
联系电话 varchar
等级 integer (触发器->升级->改变限额等信息) 外键到bs_level
成长值(经验值) integer (签到送经验值等等)
借阅限额 integer (可以与级别表中的默认值不一致,但升级时会受到影响进而重新评估)
已使用借阅额度 integer 冗余
借阅时间限额 integer (天)
积分 integer (签到,奖励,活动)
余额 money
读者表(bs_reader)
登录账号 外键到bs_user
姓名 varchar
身份证号 varchar
联系电话 varchar
等级 integer (触发器->升级->改变限额等信息) 外键到bs_level
成长值(经验值) integer (签到送经验值等等)
借阅限额 integer (可以与级别表中的默认值不一致,但升级时会受到影响进而重新评估)
已使用借阅额度 integer 冗余
借阅时间限额 integer (天)
积分 integer (签到,奖励,活动)
余额 money
图书类别表(bs_booktype)
类别名称 varchar 主键
图书类别表(bs_booktype)
类别名称 varchar 主键
图书表(bs_book)
图书定义序号 integer 主键 (考虑到有些书没有ISBN号)
ISBN号 varchar 主键
名称 varchar
类别 外键到bs_booktype
作者 varchar
出版社 varchar
出版日期 date
状态 integer (0 隐藏 1 禁用 2 正常)
隐藏: 不在图书搜索中显示这本书的信息
禁用: 禁止借阅这本书
图书表(bs_book)
图书定义序号 integer 主键 (考虑到有些书没有ISBN号)
ISBN号 varchar 主键
名称 varchar
类别 外键到bs_booktype
作者 varchar
出版社 varchar
出版日期 date
状态 integer (0 隐藏 1 禁用 2 正常)
隐藏: 不在图书搜索中显示这本书的信息
禁用: 禁止借阅这本书
图书状态表(bs_bookstatus)
图书实体序号 integer 主键 (一本书可能在图书馆里有多本藏书)
图书类别序号 外键到bs_book
位置 varchar (用来提示图书所在位置)
状态 integer (0 借出 1 丢失 2 在馆)
借出: 书籍已借出,可以在bs_borrow中查找到
丢失: 书籍已丢失,且无法从其他表中查找到有关信息.(用于报告丢失)
在馆: 书籍在馆,可以借出
图书状态表(bs_bookstatus)
图书实体序号 integer 主键 (一本书可能在图书馆里有多本藏书)
图书类别序号 外键到bs_book
位置 varchar (用来提示图书所在位置)
状态 integer (0 借出 1 丢失 2 在馆)
借出: 书籍已借出,可以在bs_borrow中查找到
丢失: 书籍已丢失,且无法从其他表中查找到有关信息.(用于报告丢失)
在馆: 书籍在馆,可以借出
借阅关系表(bs_borrow)
借阅者账号 外键到bs_user
图书实体序号 外键到bs_bookstatus
借阅日期 date
最迟还书日期 date (即使用户在借阅图书后升级,这个日期也不会改动. 此日期是在借阅书籍的时候计算的)
还书日期 date 可以为空 如果没还书就是null否则表示书已归还此条数据留存为历史数据
借阅关系表(bs_borrow)
借阅者账号 外键到bs_user
图书实体序号 外键到bs_bookstatus
借阅日期 date
最迟还书日期 date (即使用户在借阅图书后升级,这个日期也不会改动. 此日期是在借阅书籍的时候计算的)
还书日期 date 可以为空 如果没还书就是null否则表示书已归还此条数据留存为历史数据
===================
特性设计
特性设计
===================
5分钟安装(在线安装,类似Wordpress Install)
超级管理员账号 可以修改所有账户的密码,此账户只能有一个,可以添加管理员账号,其他功能同管理员账号
管理员账号 可以修改自己和所有普通用户的密码,添加/修改图书类别表,其他功能同图书馆借阅处账号
图书馆借阅处账号 可以修改自己的密码,添加/修改借阅关系表
5分钟安装(在线安装,类似Wordpress Install)
超级管理员账号 可以修改所有账户的密码,此账户只能有一个,可以添加管理员账号,其他功能同管理员账号
管理员账号 可以修改自己和所有普通用户的密码,添加/修改图书类别表,其他功能同图书馆借阅处账号
图书馆借阅处账号 可以修改自己的密码,添加/修改借阅关系表
===================
具体设计
具体设计
===================
5分钟安装需要的信息:
数据库服务器地址 dbaddr
数据库端口 dbport
数据库账户 dbuser
数据库口令 dbpass
数据库名称 dbname
超级管理员口令 supass (超级管理员账户锁定为root)
5分钟安装需要的信息:
数据库服务器地址 dbaddr
数据库端口 dbport
数据库账户 dbuser
数据库口令 dbpass
数据库名称 dbname
超级管理员口令 supass (超级管理员账户锁定为root)
新建账号:
新建账号:
session
增删改查 图书类别,图书,账户
http://localhost/cgi-bin/booksys/admin/install
安装页面. 安装成功后再访问本页面将重定向到login.
http://localhost/cgi-bin/booksys/login
登录页面
http://localhost/cgi-bin/booksys/mainpage
主页(搜索框)
http://localhost/cgi-bin/booksys/dashboard
个人页面(borrowed book那些)
http://localhost/cgi-bin/booksys/info
http://localhost/cgi-bin/booksys/admin/workbench
http://localhost/cgi-bin/booksys/admin/booktype
http://localhost/cgi-bin/booksys/admin/newbook
http://localhost/cgi-bin/booksys/viewbook?
http://localhost/cgi-bin/booksys/
增删改查 图书类别,图书,账户
http://booksys.com/api/v1/install POST (install.cpp)
POST:
dbaddr,dbport,dbuser,dbpass,dbname,supass
http://booksys.com/api/v1/search?type=...&name=... GET (search.cpp)
GET:
type= 0 用户 1 书籍
name= 用户名,书籍名称
typename= 书籍种类名称,仅当type为1时有效
type= 0 用户 1 书籍
name= 用户名,书籍名称
typename= 书籍种类名称,仅当type为1时有效
http://booksys.com/api/v1/explore GET
GET:
没有参数
没有参数
http://booksys.com/api/v1/addbook POST (addbook.cpp)
POST:
(图书定义序号自动生成)
(图书定义序号自动生成)
isbn
bookname
booktype
@ -121,14 +149,14 @@
pubdate
status
错误:
权限不足,添加失败
错误:
权限不足,添加失败
http://booksys.com/api/v1/editbook POST (editbook.cpp)
POST:
book_key (唯一图书定义序号)
book_key (唯一图书定义序号)
以下所有列均为可选: 当任一列存在时将引起数据的修改
以下所有列均为可选: 当任一列存在时将引起数据的修改
isbn
bookname
booktype
@ -137,40 +165,40 @@
pubdate
status
错误:
权限不足,修改失败
错误:
权限不足,修改失败
http://booksys.com/api/v1/removebook POST (removebook.cpp)
POST:
book_key (唯一图书定义序号)
book_key (唯一图书定义序号)
错误:
当图书的任一实体处于借出状态时将不能删除图书定义.
错误:
当图书的任一实体处于借出状态时将不能删除图书定义.
http://booksys.com/api/v1/addbooktype POST (addbooktype.cpp)
POST:
booktype
错误:
当新的类型名称发生冲突
错误:
当新的类型名称发生冲突
http://booksys.com/api/v1/editbooktype POST (editbooktype.cpp)
POST:
booktype_old
booktype_new
错误:
当新的类型名称发生冲突
错误:
当新的类型名称发生冲突
副作用:
改变图书种类会引起所有与原种类相关图书的信息变更(未实现)
副作用:
改变图书种类会引起所有与原种类相关图书的信息变更(未实现)
http://booksys.com/api/v1/removebooktype POST (removebooktype.cpp)
POST:
booktype
错误:
当任一图书定义使用此定义时将不能删除图书种类
错误:
当任一图书定义使用此定义时将不能删除图书种类
http://booksys.com/api/v1/join POST (join.cpp)
POST:
@ -178,10 +206,10 @@
pass
nickname
提示:通过此API注册的用户等级锁定为3. 且注册后账户处于状态2
提示:通过此API注册的用户等级锁定为3. 且注册后账户处于状态2
错误:
账户名称重复时
错误:
账户名称重复时
http://booksys.com/api/v1/enableuser POST (enableuser.cpp)
POST:
@ -190,122 +218,122 @@
realid
realphone
提示:通过此API激活的用户等级必须为3.(更高等级的用户不需要经此激活) 激活后账户状态将自动变更为3.
提示:通过此API激活的用户等级必须为3.(更高等级的用户不需要经此激活) 激活后账户状态将自动变更为3.
错误:
内容填充错误或禁止激活.
错误:
内容填充错误或禁止激活.
http://booksys.com/api/v1/login POST (login.cpp)
POST:
account
pass
提示:通过此API可登陆的用户等级为0,1,2,3,账户状态为3才能登陆成功,账户状态为2时返回提示信息前往激活,账户状态为1时返回禁止登陆,账户状态为0时返回需要联系管理员激活信息.
提示:通过此API可登陆的用户等级为0,1,2,3,账户状态为3才能登陆成功,账户状态为2时返回提示信息前往激活,账户状态为1时返回禁止登陆,账户状态为0时返回需要联系管理员激活信息.
错误:
账户或密码错误(包括账户错误)
错误:
账户或密码错误(包括账户错误)
返回:
当登陆成功时绑定User到Session.
返回:
当登陆成功时绑定User到Session.
http://booksys.com/api/v1/logout GET/POST (logout.cpp)
提示:退出登陆. 会立刻注销Session.
提示:退出登陆. 会立刻注销Session.
http://booksys.com/api/v1/addbookobject POST (addbookobject.cpp)
POST:
class_id 图书定义序号
book_id 图书实体序号(可选,当有此参数时将尝试以此参数新建书籍)
position 藏书位置
status 图书状态
class_id 图书定义序号
book_id 图书实体序号(可选,当有此参数时将尝试以此参数新建书籍)
position 藏书位置
status 图书状态
错误:
权限不足
图书实体序号冲突
错误:
权限不足
图书实体序号冲突
http://booksys.com/api/v1/editbookobject POST
POST:
book_id_old 旧图书实体序号
book_id_new 新图书实体序号 (可选)
position_new 新藏书位置 (可选)
status 图书新状态
book_id_old 旧图书实体序号
book_id_new 新图书实体序号 (可选)
position_new 新藏书位置 (可选)
status 图书新状态
错误:
权限不足
图书实体不存在
图书实体序号冲突
错误:
权限不足
图书实体不存在
图书实体序号冲突
http://booksys.com/api/v1/removebookobject POST
POST:
book_id 图书实体序号
book_id 图书实体序号
错误:
权限不足
图书实体序号不存在
图书已借出,不能删除实体
错误:
权限不足
图书实体序号不存在
图书已借出,不能删除实体
http://booksys.com/api/v1/borrowbook POST
POST:
account 借阅者账户
book_id 图书实体序号
account 借阅者账户
book_id 图书实体序号
错误:
权限不足(此API只能由图书管理员以上(等级<=2)调用)
图书不可借阅
实体不存在
错误:
权限不足(此API只能由图书管理员以上(等级<=2)调用)
图书不可借阅
实体不存在
http://booksys.com/api/v1/returnbook POST
POST:
book_id 图书实体序号
book_id 图书实体序号
错误:
图书状态不允许还书(未借出等等)
实体不存在
错误:
图书状态不允许还书(未借出等等)
实体不存在
http://booksys.com/api/v1/blockuser POST (blockuser.cpp)
POST:
account 被操作用户
account 被操作用户
提示:
本操作将修改用户的状态为1(禁止登陆)
提示:
本操作将修改用户的状态为1(禁止登陆)
错误:
权限不足. 只有级别<=1的用户可以使用本API. 其中管理员只能修改自己和等级>=2的用户. 超级管理员可以修改全部账户.
错误:
权限不足. 只有级别<=1的用户可以使用本API. 其中管理员只能修改自己和等级>=2的用户. 超级管理员可以修改全部账户.
http://booksys.com/api/v1/allowuser POST (allowuser.cpp)
POST:
account 被操作用户
account 被操作用户
提示:
本操作将修改用户的状态为3(正常). 注意: 若用户尚未完成身份验证,将忽视身份验证步骤.
提示:
本操作将修改用户的状态为3(正常). 注意: 若用户尚未完成身份验证,将忽视身份验证步骤.
错误:
权限不足. 只有级别<=1的用户可以使用本API.其中管理员只能修改自己和等级>=2的用户. 超级管理员可以修改全部账户.
错误:
权限不足. 只有级别<=1的用户可以使用本API.其中管理员只能修改自己和等级>=2的用户. 超级管理员可以修改全部账户.
http://booksys.com/api/v1/dashboard GET
GET:
无参数
无参数
返回:
返回关于当前用户的全部信息. (Session关联)
返回:
返回关于当前用户的全部信息. (Session关联)
错误:
未登录
错误:
未登录
http://booksys.com/api/v1/adminsearch POST
POST:
提示:
管理员专用搜索
提示:
管理员专用搜索
错误:
权限不足. 只有管理员<=1能使用本API
错误:
权限不足. 只有管理员<=1能使用本API
http://booksys.com/api/v1/advancedsearch POST
POST:
提示:
提示:
错误:
权限不足,只有<=2的用户能使用本API
错误:
权限不足,只有<=2的用户能使用本API

View File

@ -94,3 +94,41 @@ create table bs_session
last_time integer,
username varchar(10) references bs_user(username)
);
DROP PROCEDURE IF EXISTS newbook;
DELIMITER //
create procedure newbook(
IN isbn varchar(13),
IN name varchar(20),
IN book_type varchar(10),
IN author varchar(10),
IN publisher varchar(20),
IN publish_time date,
IN status integer
)
begin
declare maxid integer;
declare idcnt integer;
declare result_code integer default 0;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET result_code = 1;
start transaction;
select count(class_id) into idcnt from bs_book ;
select max(class_id) into maxid from bs_book;
if (idcnt=0) then
set maxid=1;
else
set maxid=maxid+1;
end if;
insert into bs_book values (maxid,isbn,name,book_type,author,publisher,publish_time,status);
if result_code=1 then
rollback;
else
commit;
end if;
select result_code;
end
//
DELIMITER ;

5
sql_log.txt Normal file
View File

@ -0,0 +1,5 @@
start transaction
select count(id) from bs_session where id='0284A830DCADD84758B2F1E945C744FA'
insert into bs_session values ('0284A830DCADD84758B2F1E945C744FA',1512108423,null)
commit
select username from bs_session where id='0284A830DCADD84758B2F1E945C744FA'

121
src/doAddBook.cpp Normal file
View File

@ -0,0 +1,121 @@
#include "bs_util.h"
using namespace std;
int main()
{
Request req;
Session se(req);
Response res;
json j;
auto jsonfail=[&](int errcode,const std::string& dtl="")
{
jsonfail_func(j,errcode,dtl);
};
do
{
if(!se.isReady())
{
jsonfail(err_session);
break;
}
if(se.getUser().empty())
{
jsonfail(err_need_login);
break;
}
if(req.requestMethod!="POST")
{
jsonfail(err_method_not_supported);
break;
}
postval(book_isbn);
postval(book_type);
postval(book_name);
postval(book_author);
postval(book_publish);
postval(book_pubdate);
postval(book_status);
int book_status_real=ParseInt(book_status);
if(book_status_real<0)
{
jsonfail(err_parameter,"Failed to parse status");
break;
}
if(book_status_real<0||book_status_real>2)
{
jsonfail(err_parameter,"Invalid Status");
break;
}
startdb();
/// Check Permission
int permission_level=-1;
if(conn.exec(make_str("select permission_level from bs_user where username='",
se.getUser(),
"'"),
SQLParseInt(permission_level))<0)
{
jsonfail(err_sql,"Step 1");
break;
}
if(permission_level<0)
{
jsonfail(err_data,"Failed to get permission level");
break;
}
if(permission_level>2)
{
jsonfail(err_permission_denied,"Permission Not Reach Required Level");
break;
}
int result_code=-1;
if(conn.exec(make_str("call newbook('",
book_isbn,
"','",
book_name,
"','",
book_type,
"','",
book_author,
"','",
book_publish,
"','",
book_pubdate,
"',",
book_status_real,
")"),
SQLParseInt(result_code))<0)
{
jsonfail(err_sql,"Procedure 1");
break;
}
if(result_code==1)
{
/// Failed
jsonfail(err_sql_logic,"SQL Operation Failed");
break;
}
j["success"]=1;
}
while(0);
se.writeToResponse(res);
res.content.append(j.dump());
return 0;
}

141
src/doAddBookObj.cpp Normal file
View File

@ -0,0 +1,141 @@
#include "bs_util.h"
#include "MySQLTransaction.h"
using namespace std;
int main()
{
Request req;
Session se(req);
Response res;
json j;
auto jsonfail=[&](int errcode,const std::string& dtl="")
{
jsonfail_func(j,errcode,dtl);
};
do
{
if(!se.isReady())
{
jsonfail(err_session);
break;
}
if(se.getUser().empty())
{
jsonfail(err_need_login);
break;
}
if(req.requestMethod!="POST")
{
jsonfail(err_method_not_supported);
break;
}
postval(id);
postval(book_pos);
postval(bookobj_status);
int id_real=ParseInt(id);
if(id_real<0)
{
jsonfail(err_data,"Failed to parse id.");
break;
}
int bookobj_status_real=ParseInt(bookobj_status);
if(bookobj_status_real<0)
{
jsonfail(err_data,"Failed to parse obj status");
break;
}
startdb();
Transaction ts(conn);
/// Check Permission
int permission_level=-1;
if(conn.exec(make_str("select permission_level from bs_user where username='",
se.getUser(),
"'"),
SQLParseInt(permission_level))<0)
{
jsonfail(err_sql,"Step 1");
break;
}
if(permission_level<0 || permission_level>=3)
{
jsonfail(err_permission_denied);
break;
}
/// Check If this is the first book object
int count_val=-1;
if(conn.exec("select count(book_id) from bs_bookstatus",
SQLParseInt(count_val))<0)
{
jsonfail(err_sql,"Step 2");
break;
}
if(count_val<0)
{
jsonfail(err_general,"This error should not exist.");
break;
}
int current_maxbook_id=-1;
if(count_val==0)
{
current_maxbook_id=0;
}
else
{
/// Get Available BookObjID
if(conn.exec("select max(book_id) from bs_bookstatus",
SQLParseInt(current_maxbook_id))<0)
{
jsonfail(err_sql,"Step 3");
break;
}
if(current_maxbook_id<0)
{
jsonfail(err_data,"Failed to generate book id.");
break;
}
}
int nextbook_id=current_maxbook_id+1;
/// Insert the book.(TODO)
if(conn.exec(make_str("insert into bs_bookstatus values (",
nextbook_id,
",",
id_real,
",'",
book_pos,
"',",
bookobj_status_real,
")"),
nullptr)<0)
{
jsonfail(err_sql,"Step 4");
break;
}
ts.commit();
j["success"]=1;
}
while(0);
se.writeToResponse(res);
res.content.append(j.dump());
return 0;
}

167
src/doBorrowBook.cpp Normal file
View File

@ -0,0 +1,167 @@
#include "bs_util.h"
#include "MySQLTransaction.h"
using namespace std;
int main()
{
Request req;
Session se(req);
Response res;
json j;
auto jsonfail=[&](int errcode,const std::string& dtl="")
{
jsonfail_func(j,errcode,dtl);
};
do
{
if(!se.isReady())
{
jsonfail(err_session);
break;
}
if(se.getUser().empty())
{
jsonfail(err_need_login);
break;
}
if(req.requestMethod!="POST")
{
jsonfail(err_method_not_supported);
break;
}
postval(bid);
int bid_real=ParseInt(bid);
if(bid_real<0)
{
jsonfail(err_parameter,"Failed to parse bid");
break;
}
startdb();
/// Start transaction
Transaction ts(conn);
if(!ts.isReady())
{
jsonfail(err_sql_logic,"Failed to start transaction.");
break;
}
/// Check if user can borrow...
int cntval;
if(conn.exec(make_str("select count(username) from bs_reader where username='",
se.getUser(),
"'"),
SQLParseInt(cntval))<0)
{
jsonfail(err_sql,"Step 1");
break;
}
if(cntval!=1)
{
jsonfail(err_permission_denied,"You are not in reader list!");
break;
}
int borrow_limit,borrow_used,borrow_time_limit;
if(conn.exec(make_str("select borrow_limit,borrow_used,borrow_time_limit from bs_reader where username='",
se.getUser(),
"'"),
[&](MySQLResult& res)
{
res.stepRow([&](char** val,unsigned long* len)
{
borrow_limit=ParseInt(val[0]);
borrow_used=ParseInt(val[1]);
borrow_time_limit=ParseInt(val[2]);
});
})<0)
{
jsonfail(err_sql,"Step 2");
break;
}
if(borrow_limit-borrow_used<=0)
{
jsonfail(err_general,"Reach Borrow Limit");
break;
}
/// Verify bid
if(conn.exec(make_str("select count(book_id) from bs_bookstatus where book_id=",
bid_real),
SQLParseInt(cntval))<0)
{
jsonfail(err_sql,"Step 3");
break;
}
if(cntval!=1)
{
jsonfail(err_parameter,"Failed to verify bid");
break;
}
/// Check if bid is allowed to be borrowed.
int book_status;
if(conn.exec(make_str("select status from bs_bookstatus where book_id=",bid_real),
SQLParseInt(book_status))<0)
{
jsonfail(err_sql,"Step 4");
break;
}
if(book_status!=2)
{
jsonfail(err_data,"Book is not allowed to borrow");
break;
}
/// DO UPDATE
if(conn.exec(make_str("update bs_reader set borrow_used=borrow_used+1 where username='",
se.getUser(),
"'"),nullptr)<0)
{
jsonfail(err_sql,"Update 1");
break;
}
if(conn.exec(make_str("update bs_bookstatus set status=0 where book_id=",bid_real),nullptr)<0)
{
jsonfail(err_sql,"Update 2");
break;
}
if(conn.exec(make_str("insert into bs_borrow values ('",
se.getUser(),
"',",
bid_real,
",curdate(),date_add(curdate(),interval ",
borrow_time_limit,
" day),null)"),nullptr)<0)
{
jsonfail(err_sql,"Update 3");
break;
}
/// Commit it
ts.commit();
j["success"]=1;
}
while(0);
se.writeToResponse(res);
res.content.append(j.dump());
return 0;
}

47
src/doCheckLogin.cpp Normal file
View File

@ -0,0 +1,47 @@
#include "bs_util.h"
using namespace std;
int main()
{
Request req;
Session se(req);
Response res;
json j;
auto jsonfail=[&](int errcode,const std::string& dtl="")
{
jsonfail_func(j,errcode,dtl);
};
do
{
if(!se.isReady())
{
jsonfail(err_session);
break;
}
if(req.requestMethod!="POST")
{
jsonfail(err_method_not_supported);
break;
}
if(se.getUser().empty())
{
jsonfail(err_need_login);
break;
}
j["success"]=1;
j["next_url"]="/booksys/mainpage.html";
}
while(0);
se.writeToResponse(res);
res.content.append(j.dump());
return 0;
}

79
src/doCheckPermission.cpp Normal file
View File

@ -0,0 +1,79 @@
#include "bs_util.h"
using namespace std;
int main()
{
Request req;
Session se(req);
Response res;
json j;
auto jsonfail=[&](int errcode,const std::string& dtl="")
{
jsonfail_func(j,errcode,dtl);
};
do
{
if(!se.isReady())
{
jsonfail(err_session);
break;
}
if(se.getUser().empty())
{
jsonfail(err_need_login);
break;
}
if(req.requestMethod!="POST")
{
jsonfail(err_method_not_supported);
break;
}
postval(required);
int required_real=ParseInt(required);
if(required_real<0)
{
jsonfail(err_parameter,"Failed to parse permission level");
break;
}
startdb();
/// Get Permission
int xval=-1;
if(conn.exec(make_str("select permission_level from bs_user where username='",
se.getUser(),
"'"),
SQLParseInt(xval))<0)
{
jsonfail(err_sql,"Step 1");
break;
}
if(xval<0)
{
jsonfail(err_data,"Failed to parse X-Val");
break;
}
if(xval>required_real)
{
jsonfail(err_permission_denied,"Permission Not Reach Required Level");
break;
}
j["success"]=1;
}
while(0);
se.writeToResponse(res);
res.content.append(j.dump());
return 0;
}

70
src/doGetBookByObj.cpp Normal file
View File

@ -0,0 +1,70 @@
#include "bs_util.h"
using namespace std;
int main()
{
Request req;
Session se(req);
Response res;
json j;
auto jsonfail=[&](int errcode,const std::string& dtl="")
{
jsonfail_func(j,errcode,dtl);
};
do
{
if(!se.isReady())
{
jsonfail(err_session);
break;
}
if(se.getUser().empty())
{
jsonfail(err_need_login);
break;
}
if(req.requestMethod!="POST")
{
jsonfail(err_method_not_supported);
break;
}
postval(bid);
int bid_real=ParseInt(bid);
if(bid_real<0)
{
jsonfail(err_parameter,"Failed to parse BID");
break;
}
startdb();
string book_name;
if(conn.exec(make_str("select name from bs_book where class_id in (select class_id from bs_bookstatus where book_id=",bid_real,")"),
[&](MySQLResult& res)
{
res.stepRow([&](char** val,unsigned long* len)
{
j["book_name"]=string(len[0]>0?val[0]:"(NULL)");
});
})<0)
{
jsonfail(err_sql,"Step 1");
break;
}
j["success"]=1;
}
while(0);
se.writeToResponse(res);
res.content.append(j.dump());
return 0;
}

81
src/doGetBookStatus.cpp Normal file
View File

@ -0,0 +1,81 @@
#include "bs_util.h"
using namespace std;
int main()
{
Request req;
Session se(req);
Response res;
json j;
auto jsonfail=[&](int errcode,const std::string& dtl="")
{
jsonfail_func(j,errcode,dtl);
};
do
{
if(!se.isReady())
{
jsonfail(err_session);
break;
}
if(se.getUser().empty())
{
jsonfail(err_need_login);
break;
}
if(req.requestMethod!="POST")
{
jsonfail(err_method_not_supported);
break;
}
postval(id);
int id_real=ParseInt(id);
if(id_real<0)
{
jsonfail(err_parameter,"Failed to Parse ID");
break;
}
startdb();
if(conn.exec("set names utf8",nullptr)<0)
{
jsonfail(err_sql,"Failed to set names");
break;
}
if(conn.exec(make_str("select book_id,position,status from bs_bookstatus where class_id=",id_real),
[&](MySQLResult& res)
{
res.stepRow([&](char** val,unsigned long* len)
{
json x;
x["obj_id"]=string(val[0]);
x["book_pos"]=string(len[1]>0?val[1]:"");
x["book_status"]=string(val[2]);
j["result"].push_back(x);
});
})<0)
{
jsonfail(err_sql,"Step 1");
break;
}
j["success"]=1;
}
while(0);
se.writeToResponse(res);
res.content.append(j.dump());
return 0;
}

63
src/doGetBookTypes.cpp Normal file
View File

@ -0,0 +1,63 @@
#include "bs_util.h"
#include <vector>
using namespace std;
int main()
{
Request req;
Session se(req);
Response res;
json j;
auto jsonfail=[&](int errcode,const std::string& dtl="")
{
jsonfail_func(j,errcode,dtl);
};
do
{
if(!se.isReady())
{
jsonfail(err_session);
break;
}
if(se.getUser().empty())
{
jsonfail(err_need_login);
break;
}
if(req.requestMethod!="POST")
{
jsonfail(err_method_not_supported);
break;
}
startdb();
if(conn.exec("select book_type from bs_booktype",
[&](MySQLResult& res)
{
res.stepRow([&](char** val,unsigned long* len)
{
j["result"].push_back(string(len[0]>0?val[0]:""));
});
})<0)
{
jsonfail(err_sql,"Step 1");
break;
}
j["success"]=1;
}
while(0);
se.writeToResponse(res);
res.content.append(j.dump());
return 0;
}

88
src/doListBook.cpp Normal file
View File

@ -0,0 +1,88 @@
#include "bs_util.h"
using namespace std;
int main()
{
Request req;
Session se(req);
Response res;
json j;
auto jsonfail=[&](int errcode,const std::string& dtl="")
{
jsonfail_func(j,errcode,dtl);
};
do
{
if(!se.isReady())
{
jsonfail(err_session);
break;
}
if(se.getUser().empty())
{
jsonfail(err_need_login);
break;
}
if(req.requestMethod!="POST")
{
jsonfail(err_method_not_supported);
break;
}
postval(startid);
postval(amount);
int startid_real=ParseInt(startid);
if(startid_real<0)
{
jsonfail(err_parameter,"Failed to parse startid");
break;
}
int amount_real=ParseInt(amount);
if(amount_real<0)
{
jsonfail(err_parameter,"Failed to parse amount");
break;
}
/// Limit to 50.
if(amount_real>50) amount_real=50;
startdb();
if(conn.exec(make_str("select class_id,name,book_type from bs_book where class_id>=",
startid_real,
" order by class_id limit ",
amount_real),
[&](MySQLResult& res)
{
res.stepRow([&](char** val,unsigned long* len)
{
json s;
s["class_id"]=string(val[0]);
s["book_name"]=string(val[1]);
s["book_type"]=string(val[2]);
j["result"].push_back(s);
});
})<0)
{
jsonfail(err_sql,"Step 1");
break;
}
j["success"]=1;
}
while(0);
se.writeToResponse(res);
res.content.append(j.dump());
return 0;
}

View File

@ -1,6 +1,4 @@
#include "bs_util.h"
#include <mutex>
#include <condition_variable>
using namespace std;
int main()
@ -27,7 +25,7 @@ int main()
{
/// Logged in...
j["success"]=2;
j["next_url"]="/booksys/dashboard.html";
j["next_url"]="/booksys/mainpage.html";
break;
}
@ -102,7 +100,7 @@ int main()
else
{
j["success"]=1;
j["next_url"]="/booksys/dashboard.html";
j["next_url"]="/booksys/mainpage.html";
}
}
while(0);

48
src/doLogout.cpp Normal file
View File

@ -0,0 +1,48 @@
#include "bs_util.h"
using namespace std;
int main()
{
Request req;
Session se(req);
Response res;
json j;
auto jsonfail=[&](int errcode,const std::string& dtl="")
{
jsonfail_func(j,errcode,dtl);
};
do
{
if(!se.isReady())
{
jsonfail(err_session);
break;
}
if(se.getUser().empty())
{
/// Not logged in
jsonfail(err_need_login);
break;
}
int ret;
if((ret=se.setUser(""))<0)
{
jsonfail(err_session,make_str("Failed to reset session, SessionModule returns: ",ret));
break;
}
j["success"]=1;
}
while(0);
se.writeToResponse(res);
res.content.append(j.dump());
return 0;
}

124
src/doRemoveBook.cpp Normal file
View File

@ -0,0 +1,124 @@
#include "bs_util.h"
#include "MySQLTransaction.h"
using namespace std;
int main()
{
Request req;
Session se(req);
Response res;
json j;
auto jsonfail=[&](int errcode,const std::string& dtl="")
{
jsonfail_func(j,errcode,dtl);
};
do
{
if(!se.isReady())
{
jsonfail(err_session);
break;
}
if(se.getUser().empty())
{
jsonfail(err_need_login);
break;
}
if(req.requestMethod!="POST")
{
jsonfail(err_method_not_supported);
break;
}
postval(id);
int id_real=ParseInt(id);
if(id_real<0)
{
jsonfail(err_parameter,"Failed to parse id");
break;
}
startdb();
Transaction ts(conn);
/// Check Permission
int permission_level=-1;
if(conn.exec(make_str("select permission_level from bs_user where username='",
se.getUser(),
"'"),
SQLParseInt(permission_level))<0)
{
jsonfail(err_sql,"Step 1");
break;
}
if(permission_level<0)
{
jsonfail(err_general,"Failed to check Permission");
break;
}
if(permission_level>=3)
{
jsonfail(err_permission_denied);
break;
}
/// Check if the book info can be removed.
/// count_val: Count of books with class_id={ID} and status is borrowed (0)
int count_val=-1;
if(conn.exec(make_str("select count(book_id) from bs_bookstatus where class_id=",
id_real,
" and status=0"),
SQLParseInt(count_val))<0)
{
jsonfail(err_sql,"Step 2");
break;
}
if(count_val<0)
{
jsonfail(err_data,"Failed to get book id data");
break;
}
if(count_val!=0)
{
jsonfail(err_data,make_str("Cannot remove book. Still ",count_val," books borrowed."));
break;
}
if(conn.exec(make_str("delete from bs_borrow where book_id in (select book_id from bs_bookstatus where class_id=",id_real),nullptr)<0)
{
jsonfail(err_sql,"Step 3");
}
if(conn.exec(make_str("delete from bs_bookstatus where class_id=",id_real),nullptr)<0)
{
jsonfail(err_sql,"Step 4");
break;
}
if(conn.exec(make_str("delete from bs_book where class_id=",id_real),nullptr)<0)
{
jsonfail(err_sql,"Step 5");
break;
}
ts.commit();
j["success"]=1;
}
while(0);
se.writeToResponse(res);
res.content.append(j.dump());
return 0;
}

73
src/doSearch.cpp Normal file
View File

@ -0,0 +1,73 @@
#include "bs_util.h"
using namespace std;
int main()
{
Request req;
Session se(req);
Response res;
json j;
auto jsonfail=[&](int errcode,const std::string& dtl="")
{
jsonfail_func(j,errcode,dtl);
};
do
{
if(!se.isReady())
{
jsonfail(err_session);
break;
}
if(se.getUser().empty())
{
jsonfail(err_need_login);
break;
}
if(req.requestMethod!="POST")
{
jsonfail(err_method_not_supported);
break;
}
postval(name);
startdb();
if(conn.exec("set names utf8",nullptr)<0)
{
jsonfail(err_sql,"Failed to set names");
break;
}
if(conn.exec(make_str("select class_id,name,book_type from bs_book where name like '%",
name,
"%'"),
[&](MySQLResult& res)
{
res.stepRow([&](char** val,unsigned long* len)
{
json s;
s["class_id"]=string(val[0]);
s["book_name"]=string(val[1]);
s["book_type"]=string(val[2]);
j["result"].push_back(s);
});
})<0)
{
jsonfail(err_sql,"Step 1");
break;
}
j["success"]=1;
}
while(0);
se.writeToResponse(res);
res.content.append(j.dump());
return 0;
}

80
src/doViewBook.cpp Normal file
View File

@ -0,0 +1,80 @@
#include "bs_util.h"
using namespace std;
int main()
{
Request req;
Session se(req);
Response res;
json j;
auto jsonfail=[&](int errcode,const std::string& dtl="")
{
jsonfail_func(j,errcode,dtl);
};
do
{
if(!se.isReady())
{
jsonfail(err_session);
break;
}
if(se.getUser().empty())
{
jsonfail(err_need_login);
break;
}
if(req.requestMethod!="POST")
{
jsonfail(err_method_not_supported);
break;
}
postval(id);
int id_real=ParseInt(id);
if(id_real<0)
{
jsonfail(err_parameter,"Failed to Parse ID");
break;
}
startdb();
if(conn.exec(make_str("select name,isbn,book_type,author,publisher,publish_time,status from bs_book where class_id=",
id),
[&](MySQLResult& res)
{
res.stepRow([&](char** val,unsigned long* len)
{
/// define ref
json& x=j;
x["book_name"]=string(val[0]);
x["book_isbn"]=string(val[1]);
x["book_type"]=string(val[2]);
x["book_author"]=string(val[3]);
x["book_publisher"]=string(val[4]);
x["book_pubdate"]=string(val[5]);
x["book_status"]=ParseInt(val[6]);
});
})<0)
{
jsonfail(err_sql,"Step 1");
break;
}
j["success"]=1;
}
while(0);
se.writeToResponse(res);
res.content.append(j.dump());
return 0;
}

View File

@ -1,147 +0,0 @@
#include "Request.h"
#include "Response.h"
#include "Util.h"
#include "json.hpp"
using namespace std;
using json=nlohmann::json;
int main()
{
Request req;
Response res;
json j;
auto jsonfail=[&](int errcode,const std::string& errmsg)
{
j["success"]=0;
j["errcode"]=errcode;
j["errmsg"]=errmsg;
};
if(req.requestMethod=="GET")
{
if(req.get["type"].empty())
{
jsonfail(2,"Missing Parameter: type");
}
else
{
string searchType=req.get["type"];
if(searchType=="0")
{
/// Search User
if(req.get["name"].empty())
{
jsonfail(3,"Missing Parameter: name");
}
else
{
/// Search User by ONLY nickname.
string nickname=req.get["name"];
DBInfo db;
if(db.readConfig()<0)
{
/// Failed to read config. May be not installed.
jsonfail(4,"Failed to read configure.");
}
else
{
MySQLConn conn;
if(db.connectProxy(conn)<0)
{
jsonfail(5,"Failed to connect DB");
}
else
{
vector<pair<string,string>> vec;
if(conn.exec(make_str("select name from bs_user where nickname like '%",nickname,"%'"),[&](MySQLResult& res)
{
res.stepRow([&](char** val,unsigned long* len)
{
vec.push_back(make_pair(val[0],val[1]));
});
})<0)
{
jsonfail(6,"Failed to execute SQL.");
}
else
{
j["success"]=1;
int sz=vec.size();
for(int i=0;i<sz;i++)
{
j["result"][i]["uname"]=vec[i].first;
j["result"][i]["nickname"]=vec[i].second;
}
}
}
}
}
}
else if(searchType=="1")
{
/// Search Book
if(req.get["name"].empty())
{
jsonfail(13,"Missing parameter: name");
}
else
{
/// Search book by name
string bookname=req.get["name"];
DBInfo db;
if(db.readConfig()<0)
{
jsonfail(14,"Failed to read configure.");
}
else
{
MySQLConn conn;
if(db.connectProxy(conn)<0)
{
jsonfail(15,"Failed to connect DB");
}
else
{
vector<pair<string,string>> vec;
if(conn.exec(make_str("select class_id,name from bs_book where name like '%",bookname,"%'"),[&](MySQLResult& res)
{
res.stepRow([&](char** val,unsigned long* len)
{
vec.push_back(make_pair(val[0],val[1]));
});
})<0)
{
jsonfail(16,"Failed to execute SQL.");
}
else
{
j["success"]=1;
int sz=vec.size();
for(int i=0;i<sz;i++)
{
j["result"][i]["class_id"]=vec[i].first;
j["result"][i]["name"]=vec[i].second;
}
}
}
}
}
}
else
{
jsonfail(90,"Unknown Type");
}
}
}
else
{
j["success"]=0;
j["errcode"]=1;
j["errmsg"]=make_str("Request Method Not Supported");
}
res.content.append(j.dump());
res.show();
return 0;
}

119
web/booksys/addbook.html Normal file
View File

@ -0,0 +1,119 @@
<!DOCTYPE>
<html>
<head>
<title>BookSystem 添加图书</title>
{{Header}}
{{navcss}}
</head>
<body>
{{nav}}
<div>
<div id="error_panel" hidden></div>
<p>添加图书</p>
<p>ISBN: <input type="text" id="book_isbn" /></p>
<p>图书种类: <select id="book_type_select"></select> <a href="changebooktype.html">添加或删除图书种类</a></p>
<p>图书名称: <input type="text" id="book_name" /></p>
<p>作者: <input type="text" id="book_author" /></p>
<p>出版商: <input type="text" id="book_publish" /></p>
<p>出版日期: <input type="date" id="book_pubdate" /></p>
<p>状态:
<select id="book_status_select">
<option value=2>正常</option>
<option value=0>隐藏</option>
<option value=1>禁用</option>
</select>
</p>
<button id="b_confirm">添加图书</button>
<button id="b_cancel">取消</button>
</div>
<script>
$("button").button();
$("#error_panel").click(function(){
$("#error_panel").hide("");
});
mustLogin();
checkPermission(2,function() { GoBack(); } );
/// Fetch BookTypes
$.post("/cgi-bin/booksys/doGetBookTypes",function(data){
console.log("BookType Fetch Success");
if(data.success!=1) {
console.log("BookType Fetch not success.");
$("#book_type_select").append("<option>获取图书种类失败(服务错误)</option>");
} else {
$.each(data.result,function(n,val){
$("#book_type_select").append(
"<option>"+val+"</option>"
);
});
}
},"json").fail(function(err){
console.log("BookType Fetch Failed");
$("#book_type_select").append("<option>获取图书种类失败(一般错误)</option>");
});
/// Submit Data
$("#b_confirm").click(function(){
var error_panel=$("#error_panel");
error_panel.hide("",function(){
error_panel.text("正在提交...").removeClass();
createHighlight(error_panel);
error_panel.show("");
});
$.post("/cgi-bin/booksys/doAddBook",
{
book_isbn:$("#book_isbn").val(),
book_type:$("#book_type_select").find("option:selected").text(),
book_name:$("#book_name").val(),
book_author:$("#book_author").val(),
book_publish:$("#book_publish").val(),
book_pubdate:$("#book_pubdate").val(),
book_status:$("#book_status_select").val()
},
function(data) {
console.log("Confirm Ajax Success");
if(data.success==1) {
console.log("AddBook Success");
error_panel.hide("",function(){
error_panel.text("操作成功").removeClass();
createHighlight(error_panel);
error_panel.show("");
});
/// Reload Page
location.reload();
} else {
console.log("Failed to addbook.");
error_panel.hide("",function(){
error_panel.text("添加图书失败(服务错误)").removeClass();
createError(error_panel);
error_panel.show("");
});
}
},
"json").fail(function(err){
console.log("Confirm Ajax Failed");
error_panel.hide("",function(){
error_panel.text("添加图书失败(一般错误)").removeClass();
createError(error_panel);
error_panel.show("");
});
});
});
/// Cancel
$("#b_cancel").click(function(){
location.href="listbook.html";
});
</script>
</body>
</html>

104
web/booksys/addbookobj.html Normal file
View File

@ -0,0 +1,104 @@
<!DOCTYPE>
<html>
<head>
<title>BookSystem 添加图书实体</title>
{{Header}}
{{navcss}}
</head>
<body>
{{nav}}
<div>
<div id="info_panel"></div>
<div id="control_panel">
<p>添加图书实体</p>
<p>图书标题:【<span id="book_name">正在获取图书信息...</span>】么?</p>
<p>存放位置:<input type="text" id="book_position" /></p>
<p>状态:
<select id="book_status">
<option value=2>在馆</option>
</select>
</p>
<button id="b_confirm">添加图书实体</button>
<button id="b_cancel">取消</button>
</div>
</div>
<script>
$("button").button();
$("#info_panel").hide(0).click(function(){
$("#info_panel").hide(100,function(){
$("#control_panel").show(100);
});
});
var id=GetRequest()["id"];
console.log("ClassID is ",id);
if(isNaN(parseInt(id))) {
console.log("Cannot Parse");
GoBack();
}
var lastLocation="viewbook.html?id="+id;
mustLogin();
checkPermission(2,function() { location.href=lastLocation; } );
/// Fetch Book name
$.post("/cgi-bin/booksys/doViewBook",{id:id},function(data){
console.log("Fetch Ajax Success");
if(data.success==1) {
console.log("Fetch Success");
$("#book_name").text(data.book_name);
} else {
console.log("Fetch Failed.");
}
},"json").fail(function(err){
console.log("Fetch Ajax Error: ",err);
});
$("#b_cancel").click(function(){
console.log("Operation Canceled.");
location.href=lastLocation;
});
$("#b_confirm").click(function(){
console.log("Operation Confirmed");
$.post("/cgi-bin/booksys/doAddBookObj",
{
id:id,
book_pos:$("#book_position").val(),
bookobj_status:$("#book_status").val()
},
function(data){
console.log("AddBook Ajax Success");
if(data.success==1) {
$("#control_panel").hide(100,function(){
$("#info_panel").text("操作成功");
createHighlight($("#info_panel"));
$("#info_panel").show(100,function(){
location.href=lastLocation;
});
});
} else {
$("#control_panel").hide(100,function(){
$("#info_panel").text("操作失败(服务错误)");
createError($("#info_panel"));
$("#info_panel").show(100);
});
}
},"json").fail(function(err){
$("#control_panel").hide(100,function(){
$("#info_panel").text("操作失败(一般错误)");
createError($("#info_panel"));
$("#info_panel").show(100);
});
});
});
</script>
</body>
</html>

View File

@ -0,0 +1,27 @@
<!DOCTYPE>
<html>
<head>
<title>BookSystem 图书借阅成功</title>
{{Header}}
{{navcss}}
</head>
<body>
{{nav}}
<div>
<p>借阅成功!请及时到线下图书馆取走书籍</p>
<button id="b_confirm">返回主页</button>
</div>
<script>
$("button").button();
mustLogin();
$("#b_confirm").click(function(){
location.href="mainpage.html";
});
</script>
</body>
</html>

View File

@ -0,0 +1,71 @@
<!DOCTYPE>
<html>
<head>
<title>BookSystem 图书借阅</title>
{{Header}}
{{navcss}}
</head>
<body>
{{nav}}
<div>
<p>确认借阅: 【<span id="book_name">正在获取图书信息</span>】 么?</p>
<button id="b_confirm" hidden>确定</button>
<button id="b_cancel" hidden>取消</button>
</div>
<script>
$("button").button();
function goBack() {
history.back();
location.reload(true);
}
var bid=GetRequest()["bid"];
console.log("BID is ",bid);
if(isNaN(parseInt(bid))){
console.log("Cannot Parse.");
GoBack();
}
mustLogin();
/// Fetch Info
$.post("/cgi-bin/booksys/doGetBookByObj",{bid:bid},function(data){
console.log("POST OK");
if(data.success==1) {
console.log("Result OK");
$("#book_name").text(data.book_name);
} else {
console.log("Result Failed.");
$("#book_name").text("无法获取图书名称,请刷新重试");
}
},"json").fail(function(err){
console.log("POST Failed");
$("#book_name").text("无法获取图书名称,请刷新重试");
});
$("#b_cancel").click(function(){
console.log("Operation Cancelled.");
goBack();
});
$("#b_confirm").click(function(){
console.log("Operation Confirmed");
$.post("/cgi-bin/booksys/doBorrowBook",{bid:bid},function(data){
console.log("Post OK");
if(data.success==1) {
location.href="borrow-success.html";
} else {
console.log("Failed.");
}
},"json").fail(function(err){
console.log("Post Failed");
});
});
</script>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,7 @@
nav ul {
list-style: none;
}
nav li {
display: inline;
line-height: 50px;
}

View File

@ -2,12 +2,7 @@
<html>
<head>
<title>安装成功</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="jquery-ui.css">
<link rel="stylesheet" href="jquery-ui.structure.css">
<link rel="stylesheet" href="jquery-ui.theme.css">
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery-ui.js"></script>
{{Header}}
</head>
<body>

View File

@ -2,12 +2,7 @@
<html>
<head>
<title>BookSystem 安装</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="jquery-ui.css">
<link rel="stylesheet" href="jquery-ui.structure.css">
<link rel="stylesheet" href="jquery-ui.theme.css">
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery-ui.js"></script>
{{Header}}
<style>
div.login_panel

69
web/booksys/listbook.html Normal file
View File

@ -0,0 +1,69 @@
<!DOCTYPE>
<html>
<head>
<title>BookSystem 图书浏览</title>
{{Header}}
{{navcss}}
</head>
<body>
{{nav}}
<div>
<table border="1" id="result_table">
<tr>
<th>图书序号</th>
<th>图书名称</th>
<th>图书种类</th>
<th>操作</th>
</tr>
</table>
<button id="b_lastpage">上一页</button>
<button id="b_nextpage">下一页</button>
</div>
<script>
var Request=GetRequest();
$("button").button().hide(0);
mustLogin();
if( Request["id"]==undefined || isNaN(parseInt(Request["id"])) ) {
console.log("ID is undefined. Changed to 1");
Request["id"]=1;
} else {
console.log("ID is ",Request["id"]," Parsed: ",parseInt(Request["id"]));
}
$.post("/cgi-bin/booksys/doListBook",
{
startid:parseInt(Request["id"]),
amount:10
},
function(data){
console.log("BookList Ajax Success");
if(data.success==1) {
console.log("List Success");
$.each(data.result,function(n,val){
$("#result_table").append(
"<tr><td>"+
val.class_id+
"</td><td>"+
val.book_name+
"</td><td>"+
val.book_type+
"</td><td>"+
"<a href='viewbook.html?id="+val.class_id+"'>查看</a>"+
"</td></tr>"
);
});
} else {
console.log("List Failed");
}
},"json").fail(function(err){
console.log("BookList Ajax Failed");
});
</script>
</body>
</html>

View File

@ -2,12 +2,7 @@
<html>
<head>
<title>BookSystem 登录</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="jquery-ui.css">
<link rel="stylesheet" href="jquery-ui.structure.css">
<link rel="stylesheet" href="jquery-ui.theme.css">
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery-ui.js"></script>
{{Header}}
</head>
<body>
@ -30,7 +25,7 @@
$("button").button();
/// Check Login
$.post("/cgi-bin/booksys/checkLogin",{},function(data){
$.post("/cgi-bin/booksys/doCheckLogin",{},function(data){
console.log("CheckLogin Ajax Success");
if(data.success==1)
{
@ -41,7 +36,7 @@
{
console.log("Check Failed, need login");
}
}).fail(function(err){
},"json").fail(function(err){
console.log("Failed to check login. err:",err);
});
@ -77,6 +72,10 @@
if(data.success==1||data.success==2) {
// Success
location.href=data.next_url;
} else if(data.success==3) {
// Not really success, goto url
console.log("Need Redirect");
location.href=data.next_url;
} else {
// Fail
console.log("Login Failure.");

View File

@ -0,0 +1,25 @@
<!DOCTYPE>
<html>
<head>
<title>BookSystem 登出</title>
{{Header}}
</head>
<body>
<div>
正在退出登录...
</div>
<script>
/// Check Login
$.post("/cgi-bin/booksys/doLogout",{},function(data){
console.log("Logout Ajax Success");
location.href="login.html";
},"json").fail(function(err){
console.log("Logout Ajax Failed. err:",err);
location.href="login.html";
});
</script>
</body>
</html>

View File

@ -2,26 +2,24 @@
<html>
<head>
<title>BookSystem 主页</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="jquery-ui.css">
<link rel="stylesheet" href="jquery-ui.structure.css">
<link rel="stylesheet" href="jquery-ui.theme.css">
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery-ui.js"></script>
{{Header}}
{{navcss}}
</head>
<body>
<nav>
<a href=mainpage.html><img src="img/booksys_icon.png" alt="booksys_icon"/></a>
<input type="text" placeholder="Search BookSys" id="search_box"/>
<a href="explore.html"><b>Explore</b></a>
<a href="notice.html"><img src="img/notice_icon.png" alt="Notice"/></a>
<a href="profile.html"><img src="img/default_user.png" alt="default_user"/></a>
</nav>
{{nav}}
<div>
BookSystem
BookSystem Search
<input type="text" placeholder="What's your favorite book?" id="search_box_main"/>
<p><img src="img/search_icon.png" alt="Search It!" id="search_box_icon"/></p>
</div>
<script>
mustLogin();
$("#search_box_icon").click(function(){
location.href="search.html?name="+$("#search_box_main").val();
});
</script>
</body>
</html>

102
web/booksys/removebook.html Normal file
View File

@ -0,0 +1,102 @@
<!DOCTYPE>
<html>
<head>
<title>BookSystem 删除图书信息</title>
{{Header}}
{{navcss}}
</head>
<body>
{{nav}}
<div id="info_panel"></div>
<div id="control_panel">
<p>删除图书信息</p>
<p>确认要删除【<span id="book_name">正在获取图书信息...</span>】么?</p>
<button id="b_confirm">确认</button>
<button id="b_cancel">取消</button>
</div>
<script>
$("#info_panel").hide(0).click(function(){
$("#info_panel").hide(100,function(){
$("#control_panel").show(100);
});
});
$("button").button();
mustLogin();
var id=GetRequest()["id"];
/// Check Permission
$.post("/cgi-bin/booksys/doCheckPermission",{required:2},function(data){
console.log("Permission Check Success");
if(data.success!=1) {
console.log("Permission Denied.");
location.href="mainpage.html";
} else {
console.log("Permission Check Pass");
}
},"json").fail(function(err){
console.log("Failed to check permission");
});
/// Fetch Book Data
$.post("/cgi-bin/booksys/doViewBook",{id:id},function(data){
console.log("Fetch Ajax Done.");
if(data.success==1) {
console.log("Success!");
$("#book_name").html("<b>"+data.book_name+"</b>");
} else {
console.log("Fetch Failed");
}
},"json").fail(function(err){
console.log("Fetch Ajax Error: ",err);
});
$("#b_cancel").click(function(){
console.log("Operation Cancelled");
$("#control_panel").hide(100,function(){
$("#info_panel").text("操作取消");
createHighlight($("#info_panel"));
$("#info_panel").show(100,function(){
GoBack();
});
});
});
$("#b_confirm").click(function(){
console.log("Operation Confirmed");
$.post("/cgi-bin/booksys/doRemoveBook",{id:id},function(data){
console.log("RemoveBook Ajax Success");
if(data.success==1) {
console.log("RemoveBook Success");
$("#control_panel").hide(100,function(){
$("#info_panel").text("删除成功!");
createHighlight($("#info_panel"));
$("#info_panel").show(100,function(){
GoBackWith(2);
});
});
} else {
console.log("RemoveBook Failed");
$("#control_panel").hide(100,function(){
$("#info_panel").text("操作失败(服务错误)");
createError($("#info_panel"));
$("#info_panel").show(100);
});
}
},"json").fail(function(err){
$("#control_panel").hide(100,function(){
$("#info_panel").text("操作失败(一般错误)");
createError($("#info_panel"));
$("#info_panel").show(100);
});
});
});
</script>
</body>
</html>

View File

@ -0,0 +1,30 @@
{{Header}}
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="jquery-ui.css">
<link rel="stylesheet" href="jquery-ui.structure.css">
<link rel="stylesheet" href="jquery-ui.theme.css">
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery-ui.js"></script>
<script type="text/javascript" src="util.js"></script>
{{navcss}}
<link rel="stylesheet" href="include/nav.css">
{{nav}}
<nav>
<ul>
<li><a href="mainpage.html"><img src="img/booksys_icon.png" alt="booksys_icon" width=50px height=50px/></a></li>
<li><input type="text" placeholder="Search BookSys" id="search_box"/></li>
<li><a href="explore.html"><b>Explore</b></a></li>
<li><a href="notice.html"><img src="img/notice_icon.png" alt="Notice" width=50px height=50px/></a></li>
<li><a href="profile.html"><img src="img/default_user.png" alt="default_user" width=50px height=50px/></a></li>
</ul>
</nav>
<script>
/// Nav Search Box
$("#search_box").keydown(function(e){
if(e.keyCode==13) {
location.href="search.html?name="+$("#search_box").val();
}
});
</script>

57
web/booksys/search.html Normal file
View File

@ -0,0 +1,57 @@
<!DOCTYPE>
<html>
<head>
<title>BookSystem 搜索</title>
{{Header}}
{{navcss}}
</head>
<body>
{{nav}}
<div>
<p>图书系统搜索</p>
<p>关键词: <input type="text" placeholder="What's the request?" id="search_box_main" /></p>
<table border="1" id="result_table">
<tr>
<th>图书序号</th>
<th>图书名称</th>
<th>图书种类</th>
<th>操作</th>
</tr>
</table>
</div>
<script>
var Request=GetRequest();
$("#search_box_main").attr("value",Request["name"]);
console.log("BookSearch: ",Request["name"]);
mustLogin();
/// Do Search
$.post("/cgi-bin/booksys/doSearch",{name:Request["name"]},function(data){
console.log("BookQuery Success");
if(data.success==1) {
console.log("Query Success");
$.each(data.result,function(n,val){
$("#result_table").append(
"<tr><td>"+
val.class_id+
"</td><td>"+
val.book_name+
"</td><td>"+
val.book_type+
"</td><td>"+
"<a href='viewbook.html?id="+val.class_id+"'>查看</a>"+
"</td></tr>"
);
});
} else {
console.log("Failed to Query");
}
},"json").fail(function(err){
console.log("Failed to query. "+err);
});
</script>
</body>
</html>

81
web/booksys/util.js Normal file
View File

@ -0,0 +1,81 @@
/// BookSystem JavaScript Utility Library.
/// HC TECH 2017 Kiritow.
/// Under MIT License
/// Check Login
function mustLogin() {
$.post("/cgi-bin/booksys/doCheckLogin",{},function(data){
console.log("CheckLogin Ajax Success");
if(data.success!=1)
{
console.log("Not Logged in.");
location.href="login.html";
}
else
{
console.log("Logged in.");
}
},"json").fail(function(err){
console.log("Failed to check login. err:",err);
});
}
/// Check Permission
/// If level does not matches required_level, callback will be called.
function checkPermission(required_level,callback_failure,callback_success) {
$.post("/cgi-bin/booksys/doCheckPermission",{required:required_level},function(data){
console.log("CheckPermission: Ajax Success");
if(data.success!=1) {
console.log("CheckPermission: Permission Denied.")
if(callback_failure!=null) callback_failure();
} else {
console.log("CheckPermission: Permission OK.");
if(callback_success!=null) callback_success();
}
},"json").fail(function(err){
console.log("CheckPermission Ajax Failed.");
});
}
/// jQueryUI Wrapper
function createHighlight(obj){
obj.removeClass('ui-state-highlight ui-state-error ui-corner-all');
obj.addClass('ui-state-highlight ui-corner-all');
obj.html('<p><span class="ui-icon ui-icon-alert" style="float: left; margin-right:.3em;"></span>'+obj.html()+'</p>');
}
function createError(obj){
obj.removeClass('ui-state-highlight ui-state-error ui-corner-all');
obj.addClass('ui-state-error ui-corner-all');
obj.html('<p><span class="ui-icon ui-icon-alert" style="float: left; margin-right:.3em;"></span>'+obj.html()+'</p>');
}
/// URI Resolver
function GetRequest() {
var url = decodeURI(location.search);
var theRequest = new Object();
if (url.indexOf("?") != -1) {
var str = url.substr(1);
strs = str.split("&");
for(var i = 0; i < strs.length; i ++) {
theRequest[strs[i].split("=")[0]]=unescape(strs[i].split("=")[1]);
}
}
return theRequest;
}
/// Route back in browser
function GoBack() {
window.history.back();
window.location.reload();
/// Chrome?
return false;
}
function GoBackWith(n) {
window.history.go(-(n));
window.location.reload();
/// Chrome?
return false;
}

130
web/booksys/viewbook.html Normal file
View File

@ -0,0 +1,130 @@
<!DOCTYPE>
<html>
<head>
<title>BookSystem 图书详情页</title>
{{Header}}
{{navcss}}
</head>
<body>
{{nav}}
<div>
<div>
<p>图书名称: <b id="book_name"></b> </p>
<p>ISBN号: <b id="book_isbn"></b> </p>
<p>类别: <b id="book_type"></b> </p>
<p>作者: <b id="book_author"></b> </p>
<p>出版社: <b id="book_publisher"></b> </p>
<p>出版日期: <b id="book_pubdate"></b> </p>
</div>
<div id="admin_op_panel" class='admin_op' hidden>
<table border="1">
<tr>
<th>管理员操作列表</th>
</tr>
<tr><td><p><a id="admin_op_panel_edit">修改图书信息</a></p></td></tr>
<tr><td><p><a id="admin_op_panel_remove">删除图书信息</a></p></td></tr>
</table>
</div>
<div>
<table border="1" id="result_table">
<tr>
<th>图书实体号</th>
<th>存放位置</th>
<th>状态</th>
<th>操作</th>
</tr>
</table>
</div>
</div>
<div id="js_event_box"></div>
<script>
var id=window.location.href.split("=")[1];
console.log("ID is ",id);
if(isNaN(parseInt(id))){
console.log("Cannot Parse.");
history.go(-1);
location.reload();
}
/// Fix Link
$("#admin_op_panel_edit").attr("href","editbook.html?id="+id);
$("#admin_op_panel_remove").attr("href","removebook.html?id="+id);
mustLogin();
/// Check Permission (ViewControl)
$.post("/cgi-bin/booksys/doCheckPermission",{required:2},function(data){
console.log("Check Permission Ajax Success");
if(data.success==1) {
console.log("ViewControl: Permission Fit");
$(".admin_op").removeAttr("hidden");
}
},"json").fail(function(err){
console.log("Failed to fetch permission. Ajax Failed.");
});
/// Fetch Book Data
$.post("/cgi-bin/booksys/doViewBook",{id:id},function(data){
console.log("Fetch Done.");
if(data.success==1) {
console.log("Success!");
$("#book_name").text(data.book_name);
$("#book_isbn").text(data.book_isbn);
$("#book_type").text(data.book_type);
$("#book_author").text(data.book_author);
$("#book_publisher").text(data.book_publisher);
$("#book_pubdate").text(data.book_pubdate);
} else {
console.log("Failed");
}
},"json").fail(function(err){
console.log("Fetch Error: ",err);
});
/// Fetch Book Obj Data
$.post("/cgi-bin/booksys/doGetBookStatus",{id:id},function(data){
console.log("Fetch Status Done.");
if(data.success==1) {
console.log("Fetch Status Success");
var cnt_val=0;
$.each(data.result,function(n,val) {
cnt_val++;
$("#result_table").append(
"<tr><td>"+
val.obj_id+
"</td><td>"+
val.book_pos+
"</td><td>"+
(val.book_status==0?"已借出":val.book_status==1?"丢失":val.book_status==2?"在馆":"未知")+
"</td><td>"+
(val.book_status==2?"<p><a href='borrowbook.html?bid="+val.obj_id+"'>借阅</a></p>":" ")+
"<p><a href='editbookobj.html?bid="+val.obj_id+"' class='admin_op' hidden>修改图书实体信息</a></p> "+
"<p><a href='removebookobj.html?bid="+val.obj_id+"' class='admin_op' hidden>删除图书实体</a></p> "+
"</td></tr>"
);
});
if(cnt_val==0) {
$("#result_table").append("<tr><td colspan='4'>无图书实体信息</tr>");
}
$("#result_table").append("<tr><td colspan='4'><a href='addbookobj.html?id="+id+"'>添加图书实体</a></tr>");
} else {
console.log("Fetch Status Failed");
$("#result_table").append("<tr><td colspan='4'>查找图书失败(标准错误)</tr>");
}
},"json").fail(function(err){
console.log("Fetch Status Failed, error:",err);
$("#result_table").append("<tr><td colspan='4'>查找图书失败(服务器错误)</tr>");
});
</script>
</body>
</html>