fuck lining, from sqlite to mysql
This commit is contained in:
parent
018499d722
commit
9f93aa854b
@ -3,4 +3,7 @@ cd src
|
||||
python -m venv venv
|
||||
pip install flask
|
||||
flask --app main run
|
||||
```
|
||||
```
|
||||
|
||||
使用之前,需要新整一个mysql服务器,然后在里面建立一个数据库bigwork并保证该数据库被授权给了指定的用户。
|
||||
在config里面修改对应的用户、密码、服务器地址
|
||||
@ -1,111 +1,134 @@
|
||||
drop database if exists bigwork;
|
||||
create database bigwork;
|
||||
|
||||
use bigwork;
|
||||
drop table if exists `admin`;
|
||||
drop table if exists user_stat;
|
||||
drop table if exists book_type;
|
||||
drop table if exists book_author;
|
||||
drop table if exists author;
|
||||
drop table if exists typetable;
|
||||
drop table if exists record;
|
||||
drop table if exists note;
|
||||
drop table if exists document;
|
||||
drop table if exists book;
|
||||
drop table if exists user;
|
||||
create table `admin`
|
||||
(
|
||||
passwd varchar(100) NOT NULL
|
||||
passwd varchar(200) NOT NULL
|
||||
);
|
||||
|
||||
insert into `admin` (`passwd`) values('');
|
||||
-- insert into `admin` (`passwd`) values('');
|
||||
|
||||
create table user
|
||||
(
|
||||
user_id int PRIMARY KEY AUTO_INCREMENT,
|
||||
user_name varchar(100) NOT NULL,
|
||||
user_mail varchar(100) NOT NULL,
|
||||
user_passwd varchar(100) NOT NULL,
|
||||
user_limit int NOT NULL,
|
||||
user_regtime datetime NOT NULL
|
||||
user_id int PRIMARY KEY AUTO_INCREMENT,
|
||||
user_name varchar(100) NOT NULL UNIQUE,
|
||||
user_mail varchar(100) NOT NULL UNIQUE,
|
||||
user_passwd varchar(200) NOT NULL,
|
||||
user_limit int NOT NULL,
|
||||
user_regtime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
create table book
|
||||
(
|
||||
book_id int PRIMARY KEY AUTO_INCREMENT,
|
||||
book_name varchar(100) NOT NULL,
|
||||
book_isbn varchar(100) DEFAULT NULL,
|
||||
book_publisher varchar(100) DEFAULT NULL,
|
||||
book_pubdate datetime DEFAULT NULL,
|
||||
book_lang varchar(100) DEFAULT NULL,
|
||||
user_id int NOT NULL,
|
||||
CONSTRAINT `fk_book_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`)
|
||||
book_id int PRIMARY KEY AUTO_INCREMENT,
|
||||
book_name varchar(100) NOT NULL,
|
||||
book_isbn varchar(100) DEFAULT NULL,
|
||||
book_publisher varchar(100) DEFAULT NULL,
|
||||
book_pubdate datetime DEFAULT NULL,
|
||||
book_lang varchar(100) DEFAULT NULL,
|
||||
book_author varchar(100) DEFAULT NULL,
|
||||
user_id int NOT NULL,
|
||||
CONSTRAINT `fk_book_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
create table document
|
||||
(
|
||||
doc_id int PRIMARY KEY AUTO_INCREMENT,
|
||||
doc_name varchar(100) NOT NULL,
|
||||
doc_url varchar(100) NOT NULL,
|
||||
doc_size int NOT NULL,
|
||||
doc_date datetime NOT NULL,
|
||||
doc_type varchar(100) NOT NULL,
|
||||
book_id int NOT NULL,
|
||||
user_id int NOT NULL,
|
||||
CONSTRAINT `fk_document_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`),
|
||||
CONSTRAINT `fk_document_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`),
|
||||
INDEX (doc_name(10)),
|
||||
INDEX (doc_date)
|
||||
doc_id int PRIMARY KEY AUTO_INCREMENT,
|
||||
doc_name varchar(100) NOT NULL,
|
||||
doc_url varchar(100) NOT NULL,
|
||||
doc_size int NOT NULL,
|
||||
doc_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
doc_type varchar(100) NOT NULL,
|
||||
book_id int NOT NULL,
|
||||
user_id int NOT NULL,
|
||||
CONSTRAINT `fk_document_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `fk_document_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
create index `idx_doc_name` on document(doc_name);
|
||||
create table note
|
||||
(
|
||||
note_id int PRIMARY KEY AUTO_INCREMENT,
|
||||
note_name varchar(100) NOT NULL,
|
||||
note_date datetime NOT NULL,
|
||||
note_content mediumtext NOT NULL DEFAULT '',
|
||||
book_id int NOT NULL,
|
||||
user_id int NOT NULL,
|
||||
CONSTRAINT `fk_note_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`),
|
||||
CONSTRAINT `fk_note_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`),
|
||||
INDEX (note_name(10))
|
||||
note_id int PRIMARY KEY AUTO_INCREMENT,
|
||||
note_name varchar(100) NOT NULL,
|
||||
note_date datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
note_content text NOT NULL,
|
||||
book_id int NOT NULL,
|
||||
user_id int NOT NULL,
|
||||
CONSTRAINT `fk_note_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `fk_note_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
create index `idx_note_name` on note(note_name);
|
||||
create table record
|
||||
(
|
||||
record_time timestamp PRIMARY KEY,
|
||||
record_type varchar(10) NOT NULL,
|
||||
doc_URL varchar(100) NOT NULL,
|
||||
user_id int NOT NULL,
|
||||
INDEX (record_type)
|
||||
record_time timestamp PRIMARY KEY DEFAULT CURRENT_TIMESTAMP,
|
||||
record_type varchar(10) NOT NULL,
|
||||
doc_URL varchar(100) NOT NULL,
|
||||
user_id int NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
create table typetable
|
||||
(
|
||||
type_id int PRIMARY KEY AUTO_INCREMENT,
|
||||
type_name varchar(20) NOT NULL,
|
||||
UNIQUE (type_name)
|
||||
type_id int PRIMARY KEY AUTO_INCREMENT,
|
||||
type_name varchar(20) NOT NULL UNIQUE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
create table author
|
||||
(
|
||||
author_id int PRIMARY KEY AUTO_INCREMENT,
|
||||
author_name varchar(50) NOT NULL,
|
||||
INDEX (author_name(10))
|
||||
author_id int PRIMARY KEY AUTO_INCREMENT,
|
||||
author_name varchar(50) NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
create index `idx_author_name` on author(author_name);
|
||||
|
||||
create table book_author
|
||||
(
|
||||
author_id int NOT NULL,
|
||||
book_id int NOT NULL,
|
||||
PRIMARY KEY (`author_id`, `book_id`),
|
||||
CONSTRAINT `fk_ba_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`),
|
||||
CONSTRAINT `fk_ba_author_id` FOREIGN KEY (`author_id`) REFERENCES author(`author_id`)
|
||||
author_id int NOT NULL,
|
||||
book_id int NOT NULL,
|
||||
PRIMARY KEY (`author_id`, `book_id`),
|
||||
CONSTRAINT `fk_ba_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`) ON DELETE RESTRICT,
|
||||
CONSTRAINT `fk_ba_author_id` FOREIGN KEY (`author_id`) REFERENCES author(`author_id`) ON DELETE RESTRICT
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
create table book_type
|
||||
(
|
||||
type_id int NOT NULL,
|
||||
book_id int NOT NULL,
|
||||
PRIMARY KEY (`type_id`, `book_id`),
|
||||
CONSTRAINT `fk_bt_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`),
|
||||
CONSTRAINT `fk_bt_type_id` FOREIGN KEY (`type_id`) REFERENCES typetable(`type_id`)
|
||||
type_id int NOT NULL,
|
||||
book_id int NOT NULL,
|
||||
PRIMARY KEY (`type_id`, `book_id`),
|
||||
CONSTRAINT `fk_bt_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `fk_bt_type_id` FOREIGN KEY (`type_id`) REFERENCES typetable(`type_id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
create table user_stat
|
||||
(
|
||||
user_id int PRIMARY KEY,
|
||||
user_usedspace int NOT NULL DEFAULT 0,
|
||||
user_bookcount int NOT NULL DEFAULT 0,
|
||||
user_doccount int NOT NULL DEFAULT 0,
|
||||
user_typecount int NOT NULL DEFAULT 0,
|
||||
CONSTRAINT `fk_user_stat_user` FOREIGN KEY REFERENCES user(`user_id`)
|
||||
user_id int PRIMARY KEY,
|
||||
user_limit int NOT NULL,
|
||||
user_usedspace int NOT NULL DEFAULT 0,
|
||||
user_bookcount int NOT NULL DEFAULT 0,
|
||||
user_doccount int NOT NULL DEFAULT 0,
|
||||
user_notecount int NOT NULL DEFAULT 0,
|
||||
CONSTRAINT `fk_user_stat_user` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `ck_usedspace` CHECK (user_usedspace <= user_limit)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
drop view if exists `v_book_to_types`;
|
||||
create view `v_book_to_types` as
|
||||
select book_id, typetable.type_id as type_id, type_name from book_type natural join typetable;
|
||||
|
||||
drop view if exists `v_type_to_book`;
|
||||
create view `v_type_to_book` as
|
||||
select book_id,
|
||||
book_name,
|
||||
book_isbn,
|
||||
book_publisher,
|
||||
book_lang,
|
||||
book_author,
|
||||
user_id,
|
||||
type_id,
|
||||
type_name
|
||||
from book natural join book_type natural join typetable;
|
||||
@ -1,3 +1,22 @@
|
||||
use bigwork;
|
||||
DELIMITER ##
|
||||
drop trigger if exists `trig_create_user_stat`;
|
||||
create trigger `trig_create_user_stat`
|
||||
after insert on user
|
||||
for each row begin
|
||||
insert into user_stat (`user_id`, `user_limit`) values(NEW.user_id, NEW.user_limit);
|
||||
end ##
|
||||
DELIMITER ;
|
||||
|
||||
DELIMITER ##
|
||||
drop trigger if exists `trig_delete_user_stat`;
|
||||
create trigger `trig_delete_user_stat`
|
||||
after delete on user
|
||||
for each row begin
|
||||
delete from user_stat where user_id=OLD.user_id;
|
||||
end ##
|
||||
DELIMITER ;
|
||||
|
||||
drop trigger if exists `trig_update_stat_book_ins`;
|
||||
DELIMITER ##
|
||||
create trigger `trig_update_stat_book_ins`
|
||||
@ -36,20 +55,20 @@ create trigger `trig_update_stat_doc_del`
|
||||
end ##
|
||||
DELIMITER ;
|
||||
|
||||
drop trigger if exists `trig_update_stat_type_ins`;
|
||||
drop trigger if exists `trig_update_stat_note_ins`;
|
||||
DELIMITER ##
|
||||
create trigger `trig_update_stat_type_ins`
|
||||
after insert on typetable
|
||||
create trigger `trig_update_stat_note_ins`
|
||||
after insert on note
|
||||
for each row begin
|
||||
update user_stat set user_typecount=user_typecount+1 where user_stat.user_id=NEW.user_id;
|
||||
update user_stat set user_notecount=user_notecount+1 where user_stat.user_id=NEW.user_id;
|
||||
end ##
|
||||
DELIMITER ;
|
||||
|
||||
drop trigger if exists `trig_update_stat_type_del`;
|
||||
drop trigger if exists `trig_update_stat_note_del`;
|
||||
DELIMITER ##
|
||||
create trigger `trig_update_stat_type_del`
|
||||
after delete on typetable
|
||||
create trigger `trig_update_stat_note_del`
|
||||
after delete on note
|
||||
for each row begin
|
||||
update user_stat set user_typecount=user_typecount-1 where user_stat.user_id=OLD.user_id;
|
||||
update user_stat set user_notecount=user_notecount-1 where user_stat.user_id=OLD.user_id;
|
||||
end ##
|
||||
DELIMITER ;
|
||||
@ -8,7 +8,11 @@ def create_app(test_config=None):
|
||||
app = Flask(__name__, instance_relative_config=True)
|
||||
app.config.from_mapping(
|
||||
SECRET_KEY='dev',
|
||||
DATABASE=os.path.join(app.instance_path, 'dbproj.db'),
|
||||
# DATABASE=os.path.join(app.instance_path, 'dbproj.db'),
|
||||
DATABASE='bigwork',
|
||||
DATABASE_USER='root',
|
||||
DATABASE_HOST='localhost',
|
||||
DATABASE_PASS='lil0,.lil0',
|
||||
)
|
||||
|
||||
if test_config is None:
|
||||
|
||||
38
src/admin.py
38
src/admin.py
@ -7,7 +7,7 @@ from werkzeug.security import generate_password_hash
|
||||
|
||||
from src.auth import admin_login_required
|
||||
from src.db import get_db
|
||||
import sqlite3
|
||||
import pymysql
|
||||
|
||||
bp = Blueprint('admin', __name__, url_prefix='/admin')
|
||||
|
||||
@ -20,10 +20,12 @@ def validateEmail(email):
|
||||
@bp.route('/')
|
||||
@admin_login_required
|
||||
def index():
|
||||
db = get_db()
|
||||
users = db.execute(
|
||||
cur = get_db().cursor()
|
||||
cur.execute(
|
||||
'select * from user'
|
||||
).fetchall()
|
||||
)
|
||||
users = cur.fetchall()
|
||||
cur.close()
|
||||
return render_template("admin/index.html", users=users)
|
||||
|
||||
@bp.route('/adduser', methods=("GET", "POST"))
|
||||
@ -39,22 +41,27 @@ def adduser():
|
||||
error = '用户空间必须是整数GB'
|
||||
elif not validateEmail(usermail):
|
||||
error = 'email格式不合法'
|
||||
userlimi = int(userlimi)
|
||||
userlimi = float(userlimi)
|
||||
userlimi *= 1024 * 1024 # userlimit is stored and measured by KB
|
||||
userlimi = int(userlimi)
|
||||
if error is None:
|
||||
db = get_db()
|
||||
cur = db.cursor()
|
||||
try:
|
||||
db.execute(
|
||||
'insert into user(`user_name`, `user_mail`, `user_passwd`, `user_limit`) values (?,?,?,?)',
|
||||
cur.execute(
|
||||
'insert into user(`user_name`, `user_mail`, `user_passwd`, `user_limit`) values (%s,%s,%s,%s)',
|
||||
(username, usermail, generate_password_hash(password), userlimi,)
|
||||
)
|
||||
db.commit()
|
||||
except sqlite3.IntegrityError as _e:
|
||||
|
||||
except pymysql.IntegrityError as _e:
|
||||
error = "用户名或邮箱已经存在 %s" % (_e)
|
||||
db.rollback()
|
||||
except sqlite3.Error as _e:
|
||||
except pymysql.Error as _e:
|
||||
error = "未知错误 %s" % (_e)
|
||||
db.rollback()
|
||||
finally:
|
||||
cur.close()
|
||||
if error is None:
|
||||
return redirect(url_for('admin.index'))
|
||||
flash(error)
|
||||
@ -69,18 +76,21 @@ def removeuser():
|
||||
uid_to_del = request.args.get("uid")
|
||||
if uid_to_del is not None and uid_to_del.isdecimal:
|
||||
db = get_db()
|
||||
cur = db.cursor()
|
||||
rowcnt = 0
|
||||
try:
|
||||
rowcnt = db.execute(
|
||||
"delete from user where user.user_id=?", (uid_to_del, )
|
||||
).rowcount
|
||||
rowcnt = cur.execute(
|
||||
"delete from user where user.user_id=%s", (uid_to_del, )
|
||||
)
|
||||
db.commit()
|
||||
except sqlite3.IntegrityError as _e:
|
||||
except pymysql.IntegrityError as _e:
|
||||
error = "用户未做好被删除的准备:%s" % (_e)
|
||||
db.rollback()
|
||||
except sqlite3.Error as _e:
|
||||
except pymysql.Error as _e:
|
||||
error = "删除发生未知错误: %s" %(_e)
|
||||
db.rollback()
|
||||
finally:
|
||||
cur.close()
|
||||
if error is None:
|
||||
if rowcnt != 0:
|
||||
error = "删除uid为%s的用户成功!" % uid_to_del
|
||||
|
||||
26
src/auth.py
26
src/auth.py
@ -11,20 +11,22 @@ def loginuser():
|
||||
username = request.form['username']
|
||||
password = request.form['password']
|
||||
db = get_db()
|
||||
cur = db.cursor()
|
||||
error = None
|
||||
user = db.execute(
|
||||
'SELECT * FROM user WHERE user_name = ?', (username,)
|
||||
).fetchone()
|
||||
|
||||
cur.execute(
|
||||
'SELECT * FROM user WHERE user_name = %s', (username,)
|
||||
)
|
||||
user = cur.fetchone()
|
||||
cur.close()
|
||||
if user is None:
|
||||
error = '用户名不存在'
|
||||
elif not check_password_hash(user['user_passwd'], password):
|
||||
error = '密码错误'
|
||||
|
||||
if error is None:
|
||||
if error is None and user is not None:
|
||||
session.clear()
|
||||
session['user_id'] = user['user_id']
|
||||
return redirect(url_for('home'))
|
||||
return redirect(url_for('user.home'))
|
||||
|
||||
flash(error)
|
||||
|
||||
@ -35,8 +37,10 @@ def loginadmin():
|
||||
if request.method == 'POST':
|
||||
password = request.form['password']
|
||||
db = get_db()
|
||||
cur = db.cursor()
|
||||
error = None
|
||||
admin = db.execute('SELECT * FROM admin limit 1').fetchone()
|
||||
cur.execute('SELECT * FROM admin limit 1')
|
||||
admin = cur.fetchone()
|
||||
|
||||
if admin is None:
|
||||
error = '用户名不存在'
|
||||
@ -64,9 +68,9 @@ def load_logged_in_user():
|
||||
g.user = {'user_id':0, 'user_name': 'admin'}
|
||||
# use id=0 to refer to admin
|
||||
else:
|
||||
g.user = get_db().execute(
|
||||
'SELECT * FROM user WHERE user_id = ?', (user_id,)
|
||||
).fetchone()
|
||||
cur = get_db().cursor()
|
||||
cur.execute('SELECT * FROM user WHERE user_id = %s', (user_id,))
|
||||
g.user = cur.fetchone()
|
||||
|
||||
@bp.route('/logout')
|
||||
def logout():
|
||||
@ -91,7 +95,7 @@ def admin_login_required(view):
|
||||
if g.user is None:
|
||||
return redirect(url_for('auth.login'))
|
||||
elif g.user['user_id'] != 0:
|
||||
return redirect(url_for('home'))
|
||||
return redirect(url_for('user.home'))
|
||||
return view(**kwargs)
|
||||
|
||||
return wrapped_view
|
||||
36
src/db.py
36
src/db.py
@ -1,16 +1,22 @@
|
||||
import sqlite3
|
||||
# import sqlite3
|
||||
import pymysql
|
||||
import click
|
||||
from flask import current_app, g
|
||||
from werkzeug.security import generate_password_hash
|
||||
|
||||
def get_db():
|
||||
if 'db' not in g:
|
||||
g.db = sqlite3.connect(
|
||||
current_app.config['DATABASE'],
|
||||
detect_types=sqlite3.PARSE_DECLTYPES
|
||||
)
|
||||
g.db.row_factory = sqlite3.Row
|
||||
|
||||
# g.db = sqlite3.connect(
|
||||
# current_app.config['DATABASE'],
|
||||
# detect_types=sqlite3.PARSE_DECLTYPES
|
||||
# )
|
||||
# g.db.row_factory = sqlite3.Row
|
||||
g.db = pymysql.connect(
|
||||
host=current_app.config['DATABASE_HOST'],
|
||||
user=current_app.config['DATABASE_USER'],
|
||||
password=current_app.config['DATABASE_PASS'],
|
||||
database=current_app.config['DATABASE'], cursorclass=pymysql.cursors.DictCursor)
|
||||
|
||||
return g.db
|
||||
|
||||
|
||||
@ -23,14 +29,16 @@ def close_db(e=None):
|
||||
@click.command('init-db')
|
||||
def init_db():
|
||||
db = get_db()
|
||||
click.echo("Initializing database schema...")
|
||||
with current_app.open_resource('sql/db_create_sqlite.sql') as f:
|
||||
db.executescript(f.read().decode('utf8'))
|
||||
click.echo("Initializing database triggers...")
|
||||
with current_app.open_resource('sql/trigger_sqlite.sql') as f:
|
||||
db.executescript(f.read().decode('utf8'))
|
||||
click.echo("PyMySQL do not support script execution...")
|
||||
# click.echo("Initializing database schema...")
|
||||
# with current_app.open_resource('sql/db_create_sqlite.sql') as f:
|
||||
# db.executescript(f.read().decode('utf8'))
|
||||
# click.echo("Initializing database triggers...")
|
||||
# with current_app.open_resource('sql/trigger_sqlite.sql') as f:
|
||||
# db.executescript(f.read().decode('utf8'))
|
||||
click.echo("Initializing admin passwd...")
|
||||
db.execute("insert into admin (passwd) values (?)", (generate_password_hash("lolicon"),))
|
||||
print(len(generate_password_hash("lolicon")))
|
||||
db.cursor().execute("insert into admin (passwd) values (%s)", (generate_password_hash("lolicon")))
|
||||
db.commit()
|
||||
click.echo("Initialized database.")
|
||||
|
||||
|
||||
@ -1,111 +0,0 @@
|
||||
drop database if exists bigwork;
|
||||
create database bigwork;
|
||||
|
||||
create table `admin`
|
||||
(
|
||||
passwd varchar(100) NOT NULL
|
||||
);
|
||||
|
||||
insert into `admin` (`passwd`) values('');
|
||||
|
||||
create table user
|
||||
(
|
||||
user_id int PRIMARY KEY AUTO_INCREMENT,
|
||||
user_name varchar(100) NOT NULL,
|
||||
user_mail varchar(100) NOT NULL,
|
||||
user_passwd varchar(100) NOT NULL,
|
||||
user_limit int NOT NULL,
|
||||
user_regtime datetime NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
create table book
|
||||
(
|
||||
book_id int PRIMARY KEY AUTO_INCREMENT,
|
||||
book_name varchar(100) NOT NULL,
|
||||
book_isbn varchar(100) DEFAULT NULL,
|
||||
book_publisher varchar(100) DEFAULT NULL,
|
||||
book_pubdate datetime DEFAULT NULL,
|
||||
book_lang varchar(100) DEFAULT NULL,
|
||||
user_id int NOT NULL,
|
||||
CONSTRAINT `fk_book_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
create table document
|
||||
(
|
||||
doc_id int PRIMARY KEY AUTO_INCREMENT,
|
||||
doc_name varchar(100) NOT NULL,
|
||||
doc_url varchar(100) NOT NULL,
|
||||
doc_size int NOT NULL,
|
||||
doc_date datetime NOT NULL,
|
||||
doc_type varchar(100) NOT NULL,
|
||||
book_id int NOT NULL,
|
||||
user_id int NOT NULL,
|
||||
CONSTRAINT `fk_document_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`),
|
||||
CONSTRAINT `fk_document_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`),
|
||||
INDEX (doc_name(10)),
|
||||
INDEX (doc_date)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
create table note
|
||||
(
|
||||
note_id int PRIMARY KEY AUTO_INCREMENT,
|
||||
note_name varchar(100) NOT NULL,
|
||||
note_date datetime NOT NULL,
|
||||
note_content mediumtext NOT NULL DEFAULT '',
|
||||
book_id int NOT NULL,
|
||||
user_id int NOT NULL,
|
||||
CONSTRAINT `fk_note_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`),
|
||||
CONSTRAINT `fk_note_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`),
|
||||
INDEX (note_name(10))
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
create table record
|
||||
(
|
||||
record_time timestamp PRIMARY KEY,
|
||||
record_type varchar(10) NOT NULL,
|
||||
doc_URL varchar(100) NOT NULL,
|
||||
user_id int NOT NULL,
|
||||
INDEX (record_type)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
create table typetable
|
||||
(
|
||||
type_id int PRIMARY KEY AUTO_INCREMENT,
|
||||
type_name varchar(20) NOT NULL,
|
||||
UNIQUE (type_name)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
create table author
|
||||
(
|
||||
author_id int PRIMARY KEY AUTO_INCREMENT,
|
||||
author_name varchar(50) NOT NULL,
|
||||
INDEX (author_name(10))
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
create table book_author
|
||||
(
|
||||
author_id int NOT NULL,
|
||||
book_id int NOT NULL,
|
||||
PRIMARY KEY (`author_id`, `book_id`),
|
||||
CONSTRAINT `fk_ba_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`),
|
||||
CONSTRAINT `fk_ba_author_id` FOREIGN KEY (`author_id`) REFERENCES author(`author_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
create table book_type
|
||||
(
|
||||
type_id int NOT NULL,
|
||||
book_id int NOT NULL,
|
||||
PRIMARY KEY (`type_id`, `book_id`),
|
||||
CONSTRAINT `fk_bt_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`),
|
||||
CONSTRAINT `fk_bt_type_id` FOREIGN KEY (`type_id`) REFERENCES typetable(`type_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
create table user_stat
|
||||
(
|
||||
user_id int PRIMARY KEY,
|
||||
user_usedspace int NOT NULL DEFAULT 0,
|
||||
user_bookcount int NOT NULL DEFAULT 0,
|
||||
user_doccount int NOT NULL DEFAULT 0,
|
||||
user_typecount int NOT NULL DEFAULT 0,
|
||||
CONSTRAINT `fk_user_stat_user` FOREIGN KEY REFERENCES user(`user_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
@ -1,55 +0,0 @@
|
||||
drop trigger if exists `trig_update_stat_book_ins`;
|
||||
DELIMITER ##
|
||||
create trigger `trig_update_stat_book_ins`
|
||||
after insert on book
|
||||
for each row begin
|
||||
update user_stat set user_bookcount=user_bookcount+1 where user_stat.user_id=NEW.user_id;
|
||||
end ##
|
||||
DELIMITER ;
|
||||
|
||||
drop trigger if exists `trig_update_stat_book_del`;
|
||||
DELIMITER ##
|
||||
create trigger `trig_update_stat_book_del`
|
||||
after delete on book
|
||||
for each row begin
|
||||
update user_stat set user_bookcount=user_bookcount-1 where user_stat.user_id=OLD.user_id;
|
||||
end ##
|
||||
DELIMITER ;
|
||||
|
||||
drop trigger if exists `trig_update_stat_doc_ins`;
|
||||
DELIMITER ##
|
||||
create trigger `trig_update_stat_doc_ins`
|
||||
after insert on document
|
||||
for each row begin
|
||||
update user_stat set user_doccount=user_doccount+1 where user_stat.user_id=NEW.user_id;
|
||||
update user_stat set user_usedspace=user_usedspace+NEW.doc_size where user_stat.user_id=NEW.user_id;
|
||||
end ##
|
||||
DELIMITER ;
|
||||
|
||||
drop trigger if exists `trig_update_stat_doc_del`;
|
||||
DELIMITER ##
|
||||
create trigger `trig_update_stat_doc_del`
|
||||
after delete on document
|
||||
for each row begin
|
||||
update user_stat set user_doccount=user_doccount-1 where user_stat.user_id=OLD.user_id;
|
||||
update user_stat set user_usedspace=user_usedspace-OLD.doc_size where user_stat.user_id=OLD.user_id;
|
||||
end ##
|
||||
DELIMITER ;
|
||||
|
||||
drop trigger if exists `trig_update_stat_type_ins`;
|
||||
DELIMITER ##
|
||||
create trigger `trig_update_stat_type_ins`
|
||||
after insert on typetable
|
||||
for each row begin
|
||||
update user_stat set user_typecount=user_typecount+1 where user_stat.user_id=NEW.user_id;
|
||||
end ##
|
||||
DELIMITER ;
|
||||
|
||||
drop trigger if exists `trig_update_stat_type_del`;
|
||||
DELIMITER ##
|
||||
create trigger `trig_update_stat_type_del`
|
||||
after delete on typetable
|
||||
for each row begin
|
||||
update user_stat set user_typecount=user_typecount-1 where user_stat.user_id=OLD.user_id;
|
||||
end ##
|
||||
DELIMITER ;
|
||||
@ -9,7 +9,7 @@
|
||||
z-index: 1;
|
||||
top: 20;
|
||||
left: 0;
|
||||
overflow-x: hidden;
|
||||
|
||||
padding-left: 1.2rem;
|
||||
padding-right: 2rem;
|
||||
}
|
||||
@ -17,7 +17,7 @@
|
||||
height: 100%;
|
||||
max-width: 160px;
|
||||
z-index: 1;
|
||||
overflow-x: hidden;
|
||||
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
@ -42,7 +42,7 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container maindiv">
|
||||
<div class="container">
|
||||
<div class="columns">
|
||||
<div class="column col-3">
|
||||
<ul class="nav">
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
z-index: 1;
|
||||
top: 20;
|
||||
left: 0;
|
||||
overflow-x: hidden;
|
||||
|
||||
padding-left: 1.2rem;
|
||||
padding-right: 2rem;
|
||||
}
|
||||
@ -17,13 +17,13 @@
|
||||
height: 100%;
|
||||
max-width: 160px;
|
||||
z-index: 1;
|
||||
overflow-x: hidden;
|
||||
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container maindiv">
|
||||
<div class="container">
|
||||
<div class="columns">
|
||||
<div class="column col-3">
|
||||
<ul class="nav">
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
z-index: 1;
|
||||
top: 20;
|
||||
left: 0;
|
||||
overflow-x: hidden;
|
||||
padding-left: 1.2rem;
|
||||
padding-right: 2rem;
|
||||
}
|
||||
@ -17,13 +16,12 @@
|
||||
height: 100%;
|
||||
max-width: 160px;
|
||||
z-index: 1;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container maindiv">
|
||||
<div class="container">
|
||||
<div class="columns">
|
||||
<div class="column col-3">
|
||||
<ul class="nav">
|
||||
@ -43,12 +41,57 @@
|
||||
</div>
|
||||
<div class="column col-9 panel">
|
||||
<div class="panel-header">
|
||||
<div class="panel-title h4">{{book['book_name']}}</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="panel-title h3">{{book['book_name']}}</div>
|
||||
{%if booktype|length > 0 %}
|
||||
<div>
|
||||
<mark>分类标签:</mark>
|
||||
{% for atype in booktype %}
|
||||
<span class="chip"> {{atype['type_name']}}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{%endif%}
|
||||
{%if book['book_author']%}
|
||||
<div class="py-1">
|
||||
<mark>作者:</mark><span class="px-2">{{book['book_author']}}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{%if book['book_publisher']%}
|
||||
<div class="py-1">
|
||||
<mark>出版社:</mark><span class="px-2">{{book['book_publisher']}}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{%if book['book_isbn']%}
|
||||
<div class="py-1">
|
||||
<mark>ISBN:</mark><span class="px-2">{{book['book_isbn']}}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{%if book['book_lang']%}
|
||||
<div class="py-1">
|
||||
<mark>语言:</mark><span class="px-2">{{book['book_lang']}}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div>
|
||||
<a href="/book/update/{{book['book_id']}}/" class="btn btn-primary">编辑图书信息</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div id="book-docs" class="card">
|
||||
<div class="card-header">
|
||||
<div class="card-title h5">文档1</div>
|
||||
<div class="card-subtitle">
|
||||
<span>大小:</span>
|
||||
<span>日期:</span>
|
||||
<div class="float-right">
|
||||
<button class="btn btn-primary">下载</button>
|
||||
<button class="btn">删除</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="divider"></div>
|
||||
<div id = "book-notes" class="card">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
Rendered @ {{cur_time}}
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
z-index: 1;
|
||||
top: 20;
|
||||
left: 0;
|
||||
overflow-x: hidden;
|
||||
|
||||
padding-left: 1.2rem;
|
||||
padding-right: 2rem;
|
||||
}
|
||||
@ -17,13 +17,13 @@
|
||||
height: 100%;
|
||||
max-width: 160px;
|
||||
z-index: 1;
|
||||
overflow-x: hidden;
|
||||
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container maindiv">
|
||||
<div class="container">
|
||||
<div class="columns">
|
||||
<div class="column col-3">
|
||||
<ul class="nav">
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
z-index: 1;
|
||||
top: 20;
|
||||
left: 0;
|
||||
overflow-x: hidden;
|
||||
padding-left: 1.2rem;
|
||||
padding-right: 2rem;
|
||||
}
|
||||
@ -17,13 +16,12 @@
|
||||
height: 100%;
|
||||
max-width: 160px;
|
||||
z-index: 1;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container maindiv">
|
||||
<div class="container">
|
||||
<div class="columns">
|
||||
<div class="column col-3">
|
||||
<ul class="nav">
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
z-index: 1;
|
||||
top: 20;
|
||||
left: 0;
|
||||
overflow-x: hidden;
|
||||
padding-left: 1.2rem;
|
||||
padding-right: 2rem;
|
||||
}
|
||||
@ -17,13 +16,12 @@
|
||||
height: 100%;
|
||||
max-width: 160px;
|
||||
z-index: 1;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container maindiv">
|
||||
<div class="container">
|
||||
<div class="columns">
|
||||
<div class="column col-3">
|
||||
<ul class="nav">
|
||||
|
||||
85
src/templates/user/updatebook.html
Normal file
85
src/templates/user/updatebook.html
Normal file
@ -0,0 +1,85 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block header %}
|
||||
<script>
|
||||
var typelist = {};
|
||||
function switch_type(typename) {
|
||||
if (typelist.hasOwnProperty(typename)) {
|
||||
delete typelist[typename];
|
||||
} else {
|
||||
typelist[typename] = 1;
|
||||
}
|
||||
let typeinput = document.getElementById("booktype");
|
||||
let typestr = "";
|
||||
for (let typekey in typelist) {
|
||||
typestr += typekey + ";";
|
||||
}
|
||||
typeinput.value = typestr;
|
||||
}
|
||||
function create_type_button(typename) {
|
||||
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="columns">
|
||||
<div class="column col-3">
|
||||
<ul class="nav">
|
||||
<li class="nav-item">
|
||||
<a href="/home">主页</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/search">搜索</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/addbook">增加</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="/tags">分类</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="column col-9 panel">
|
||||
<div class="panel-header">
|
||||
<h2>编辑图书</h2>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{%if error%}
|
||||
<div class="toast">
|
||||
{{error}}
|
||||
</div>
|
||||
{% endif %}
|
||||
<form method="post" class="form-group">
|
||||
<label class="form-label" for="bookname">书名</label>
|
||||
<input class="form-input" name="bookname" id="bookname" value="{{book['book_name']}}" required>
|
||||
<label class="form-label" for="bookisbn">ISBN</label>
|
||||
<input class="form-input" name="bookisbn" id="bookisbn" value="{{book['book_isbn']}}">
|
||||
<label class="form-label" for="bookpublisher">出版社</label>
|
||||
<input class="form-input" name="bookpublisher" id="bookpublisher" value="{{book['book_publisher']}}">
|
||||
<label class="form-label" for="bookauthor">作者</label>
|
||||
<input class="form-input" name="bookauthor" id="bookauthor" value="{{book['book_author']}}">
|
||||
<label class="form-label" for="booklang">语言</label>
|
||||
<select class="form-select" name="booklang" id="booklang">
|
||||
<option selected>CN</option>
|
||||
<option>EN</option>
|
||||
<option>Other</option>
|
||||
</select>
|
||||
<label class="form-label" for="booktype">分类</label>
|
||||
<input class="form-input" name="booktype" id="booktype" value="{{booktype}}">
|
||||
<div>
|
||||
{% for atype in typelist%}
|
||||
<span class="chip btn" onclick="switch_type('{{atype['type_name']}}')">{{atype['type_name']}}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<input class="btn btn-primary input-group-btn p-centered" type="submit" value="提交">
|
||||
</form>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
Rendered @ {{cur_time}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
161
src/user.py
161
src/user.py
@ -7,7 +7,7 @@ from werkzeug.security import generate_password_hash
|
||||
|
||||
from src.auth import login_required
|
||||
from src.db import get_db
|
||||
import sqlite3
|
||||
import pymysql
|
||||
import datetime
|
||||
|
||||
bp = Blueprint('user', __name__)
|
||||
@ -15,16 +15,20 @@ bp = Blueprint('user', __name__)
|
||||
@bp.route("/home")
|
||||
@login_required
|
||||
def home():
|
||||
db = get_db()
|
||||
user_stat = db.execute(
|
||||
"select * from user_stat where user_id = ?", (g.user['user_id'],)
|
||||
).fetchone()
|
||||
cur = get_db().cursor()
|
||||
cur.execute(
|
||||
"select * from user_stat where user_id = %s", (g.user['user_id'],)
|
||||
)
|
||||
user_stat = cur.fetchone()
|
||||
print(user_stat)
|
||||
cur.close()
|
||||
return render_template("user/home.html", user_stat=user_stat, cur_time=datetime.datetime.now())
|
||||
|
||||
@bp.route("/addbook", methods=('GET', 'POST'))
|
||||
@login_required
|
||||
def addbook():
|
||||
db = get_db()
|
||||
cur = db.cursor()
|
||||
error = None
|
||||
if request.method == 'POST':
|
||||
bookname = request.form['bookname']
|
||||
@ -46,40 +50,43 @@ def addbook():
|
||||
booklang = None
|
||||
if len(booktype) == 0:
|
||||
booktype = None
|
||||
db.execute(
|
||||
cur.execute(
|
||||
"insert into book (`book_name`, `book_isbn`"
|
||||
", `book_publisher`, `book_lang`, `book_author`, `user_id`) "
|
||||
"values (?,?,?,?,?,?)",
|
||||
"values (%s,%s,%s,%s,%s,%s)",
|
||||
(bookname, bookisbn, bookpublisher, booklang, bookauthor, g.user['user_id'],))
|
||||
db.commit()
|
||||
bookid = db.execute("select max(book_id) from book").fetchone()
|
||||
cur.execute("select max(book_id) from book")
|
||||
bookid = cur.fetchone()
|
||||
bookid = bookid['max(book_id)']
|
||||
error = None
|
||||
if booktype is not None:
|
||||
booktype = booktype.strip()
|
||||
if booktype[-1] != ';':
|
||||
booktype += ';'
|
||||
booktypes = booktype.split(";")
|
||||
booktypes.remove("")
|
||||
print(booktypes)
|
||||
for booktype in booktypes:
|
||||
typeid = db.execute("select type_id from typetable where type_name=?",
|
||||
(booktype,)).fetchone()
|
||||
cur.execute("select type_id from typetable where type_name=%s", (booktype,))
|
||||
typeid = cur.fetchone()
|
||||
if typeid is None:
|
||||
db.execute("insert into typetable(`type_name`) values (?)",
|
||||
(booktype,))
|
||||
typeid = db.execute("select type_id from typetable where type_name=?",
|
||||
(booktype,)).fetchone()
|
||||
cur.execute("insert into typetable(`type_name`) values (%s)", (booktype,))
|
||||
cur.execute("select type_id from typetable where type_name=%s", (booktype,))
|
||||
typeid = cur.fetchone()
|
||||
typeid = typeid['type_id']
|
||||
try:
|
||||
db.execute("insert into book_type values(?,?)",
|
||||
(typeid, bookid))
|
||||
cur.execute("insert into book_type values(%s,%s)",(typeid, bookid))
|
||||
db.commit()
|
||||
except sqlite3.Error as _e:
|
||||
except pymysql.Error as _e:
|
||||
error = "未知错误: %s" % (_e)
|
||||
db.rollback()
|
||||
if error is None:
|
||||
error = "新建图书《%s》完成" % (bookname)
|
||||
# else:
|
||||
# return render_template("user/addbook.html", success=True)
|
||||
typelist = db.execute("select type_name from typetable").fetchall()
|
||||
cur.execute("select type_name from typetable")
|
||||
typelist = cur.fetchall()
|
||||
return render_template("user/addbook.html", typelist=typelist, error=error,
|
||||
cur_time=datetime.datetime.now())
|
||||
|
||||
@ -87,6 +94,7 @@ def addbook():
|
||||
@login_required
|
||||
def tags():
|
||||
db = get_db()
|
||||
cur = db.cursor()
|
||||
error = None
|
||||
if request.method == 'POST':
|
||||
typename = request.form['typename']
|
||||
@ -95,13 +103,12 @@ def tags():
|
||||
rowcount = 0
|
||||
if error is None:
|
||||
try:
|
||||
rowcount = db.execute("insert into typetable(`type_name`) values(?)",
|
||||
(typename,)).rowcount
|
||||
rowcount = cur.execute("insert into typetable(`type_name`) values(%s)", (typename,))
|
||||
db.commit()
|
||||
except sqlite3.IntegrityError:
|
||||
except pymysql.IntegrityError:
|
||||
error = "类型名称已经存在: %s" % (typename)
|
||||
db.rollback()
|
||||
except sqlite3.Error as _e:
|
||||
except pymysql.Error as _e:
|
||||
error = "未知错误: %s" % (_e)
|
||||
db.rollback()
|
||||
if error is None:
|
||||
@ -109,7 +116,8 @@ def tags():
|
||||
error = "新建可能失败,再次检查是否完成"
|
||||
else:
|
||||
error = "新建类型\"%s\"完成" % (typename)
|
||||
typelist = db.execute("select * from typetable").fetchall()
|
||||
cur.execute("select * from typetable")
|
||||
typelist = cur.fetchall()
|
||||
return render_template("user/addtype.html", typelist=typelist, error=error,
|
||||
cur_time=datetime.datetime.now())
|
||||
|
||||
@ -117,6 +125,7 @@ def tags():
|
||||
@login_required
|
||||
def removetype():
|
||||
db = get_db()
|
||||
cur = db.cursor()
|
||||
tid_to_del = request.args.get("tid")
|
||||
error = None
|
||||
if tid_to_del is None or not tid_to_del.isnumeric():
|
||||
@ -124,9 +133,9 @@ def removetype():
|
||||
rowcnt = 0
|
||||
if error is None:
|
||||
try:
|
||||
rowcnt = db.execute("delete from typetable where type_id=?", (tid_to_del,)).rowcount
|
||||
rowcnt = cur.execute("delete from typetable where type_id=%s", (tid_to_del,))
|
||||
db.commit()
|
||||
except sqlite3.Error as _e:
|
||||
except pymysql.Error as _e:
|
||||
error = "删除失败:%s" % (_e)
|
||||
db.rollback()
|
||||
if error is None:
|
||||
@ -134,6 +143,7 @@ def removetype():
|
||||
error = "删除可能失败,再次检查是否完成"
|
||||
else:
|
||||
error = "删除(type_id=%s)完成" % tid_to_del
|
||||
cur.close()
|
||||
return render_template("user/result.html", opname="删除分类",
|
||||
opresult=error, cur_time=datetime.datetime.now())
|
||||
|
||||
@ -143,6 +153,7 @@ def search():
|
||||
attr_dict = {"书名":"book_name", "ISBN":"book_isbn",
|
||||
"作者": "book_author", "出版社":"book_publisher", "分类": "specail1"}
|
||||
db = get_db()
|
||||
cur = db.cursor()
|
||||
page = request.args.get('page')
|
||||
page_lim = 10
|
||||
page_off = 0
|
||||
@ -169,20 +180,22 @@ def search():
|
||||
bookattr=""
|
||||
if error is None:
|
||||
if queryval is None or len(queryval) == 0:
|
||||
querystring = "select * from book where user_id=%d" % (g.user['user_id'])
|
||||
querystring = "select * from book where user_id=%s" % (g.user['user_id'])
|
||||
queryval = ""
|
||||
elif bookattr == "分类":
|
||||
querystring = "SELECT * from v_type_to_book WHERE user_id=%d AND type_name LIKE \'%%%s%%\'" % (g.user['user_id'], queryval)
|
||||
querystring = "SELECT * from v_type_to_book WHERE user_id=%s AND type_name LIKE \'%%%s%%\'" % (g.user['user_id'], queryval)
|
||||
else:
|
||||
querystring = "select * from book where user_id=%d and %s like \'%%%s%%\'" % (g.user['user_id'], queryattr, queryval)
|
||||
querystring = "select * from book where user_id=%s and %s like \'%%%s%%\'" % (g.user['user_id'], queryattr, queryval)
|
||||
querystring += " limit %d offset %d" % (page_lim, page_off)
|
||||
# print(querystring)
|
||||
queryresult = db.execute(querystring).fetchall()
|
||||
cur.execute(querystring)
|
||||
queryresult = cur.fetchall()
|
||||
|
||||
page_last = False
|
||||
if len(queryresult) < page_lim:
|
||||
page_last = True
|
||||
next_page_link = "/search?bookname=%s&bookattr=%s&page=%d" %(queryval, bookattr, page + 1)
|
||||
prev_page_link = "/search?bookname=%s&bookattr=%s&page=%d" %(queryval, bookattr, page - 1)
|
||||
next_page_link = "/search?bookname=%s&bookattr=%s&page=%s" %(queryval, bookattr, page + 1)
|
||||
prev_page_link = "/search?bookname=%s&bookattr=%s&page=%s" %(queryval, bookattr, page - 1)
|
||||
# print(prev_page_link, next_page_link)
|
||||
return render_template("user/search.html",
|
||||
cur_time=datetime.datetime.now(), error=error, queryresult=queryresult,
|
||||
@ -193,8 +206,90 @@ def search():
|
||||
@login_required
|
||||
def book(id):
|
||||
db = get_db()
|
||||
book = db.execute("select * from book where book_id=?", (id,)).fetchone()
|
||||
booktype = db.execute("select * from v_book_to_types where book_id=?", (book['book_id'], )).fetchall()
|
||||
cur = db.cursor()
|
||||
cur.execute("select * from book where book_id=%s", (id,))
|
||||
book = cur.fetchone()
|
||||
cur.execute("select * from v_book_to_types where book_id=%s", (book['book_id'], ))
|
||||
booktype = cur.fetchall()
|
||||
return render_template("/user/book.html",
|
||||
book=book, booktype=booktype,
|
||||
cur_time=datetime.datetime.now())
|
||||
|
||||
@bp.route("/book/update/<int:id>/", methods=("GET", "POST"))
|
||||
@login_required
|
||||
def book_update(id):
|
||||
db = get_db()
|
||||
cur = db.cursor()
|
||||
error = None
|
||||
if request.method == 'POST':
|
||||
bookname = request.form['bookname']
|
||||
bookisbn = request.form['bookisbn']
|
||||
bookpublisher = request.form['bookpublisher']
|
||||
booklang = request.form['booklang']
|
||||
bookauthor = request.form['bookauthor']
|
||||
booktype = request.form['booktype']
|
||||
error = None
|
||||
if len(bookname) == 0:
|
||||
error = "书名不能为空"
|
||||
if len(bookisbn) == 0:
|
||||
bookisbn = None
|
||||
if len(bookpublisher) == 0:
|
||||
bookpublisher = None
|
||||
if len(booklang) == 0:
|
||||
booklang = None
|
||||
if len(bookauthor) == 0:
|
||||
booklang = None
|
||||
if len(booktype) == 0:
|
||||
booktype = None
|
||||
cur.execute('update book set `book_name`=%s where `book_id`=%s', (bookname, id))
|
||||
cur.execute('update book set `book_isbn`=%s where `book_id`=%s', (bookisbn, id))
|
||||
cur.execute('update book set `book_publisher`=%s where `book_id`=%s', (bookpublisher, id))
|
||||
cur.execute('update book set `book_lang`=%s where `book_id`=%s', (booklang, id))
|
||||
cur.execute('update book set `book_author`=%s where `book_id`=%s', (bookauthor, id))
|
||||
db.commit()
|
||||
error = None
|
||||
if booktype is not None:
|
||||
booktype = booktype.strip()
|
||||
if booktype[-1] != ';':
|
||||
booktype += ';'
|
||||
booktypes = booktype.split(";")
|
||||
booktypes.remove("")
|
||||
print(booktypes)
|
||||
for booktype in booktypes:
|
||||
cur.execute("select type_id from typetable where type_name=%s", (booktype,))
|
||||
typeid = cur.fetchone()
|
||||
if typeid is None:
|
||||
cur.execute("insert into typetable(`type_name`) values (%s)", (booktype,))
|
||||
cur.execute("select type_id from typetable where type_name=%s", (booktype,))
|
||||
typeid = cur.fetchone()
|
||||
typeid = typeid['type_id']
|
||||
try:
|
||||
cur.execute("insert into book_type values(%s,%s)",(typeid, id))
|
||||
db.commit()
|
||||
except pymysql.IntegrityError:
|
||||
db.rollback()
|
||||
except pymysql.Error as _e:
|
||||
error = "未知错误: %s" % (_e)
|
||||
db.rollback()
|
||||
if error is None:
|
||||
cur.close()
|
||||
return redirect(url_for("user.book", id=id))
|
||||
|
||||
cur.execute("select * from book where book_id=%s", (id,))
|
||||
bookinfo = cur.fetchone()
|
||||
assert(bookinfo is not None)
|
||||
cur.execute("select * from v_book_to_types where book_id=%s", (bookinfo['book_id'], ))
|
||||
booktype = cur.fetchall()
|
||||
cur.execute("select type_name from typetable")
|
||||
typelist = cur.fetchall()
|
||||
cur.close()
|
||||
for k in bookinfo:
|
||||
if bookinfo[k] is None:
|
||||
bookinfo[k] = ''
|
||||
booktypestr = ""
|
||||
print(booktype)
|
||||
for k in booktype:
|
||||
booktypestr += k['type_name'] + ';'
|
||||
return render_template("/user/updatebook.html",
|
||||
book=bookinfo, booktype=booktypestr, typelist=typelist,
|
||||
cur_time=datetime.datetime.now())
|
||||
Loading…
Reference in New Issue
Block a user