You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

498 lines
18 KiB

6 months ago
from flask import Flask, render_template, session, redirect, url_for, flash, request, jsonify
import os
from flask_sqlalchemy import SQLAlchemy
from flask_script import Manager, Shell
from forms import Login, SearchBookForm, ChangePasswordForm, EditInfoForm, SearchStudentForm, NewStoreForm, StoreForm, BorrowForm
from flask_login import UserMixin, LoginManager, login_required, login_user, logout_user, current_user
import time, datetime
basedir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
manager = Manager(app)
app.config['SECRET_KEY'] = 'hard to guess string'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
db = SQLAlchemy(app)
def make_shell_context():
return dict(app=app, db=db, Admin=Admin, Book=Book)
manager.add_command("shell", Shell(make_context=make_shell_context))
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.session_protection = 'basic'
login_manager.login_view = 'login'
login_manager.login_message = u"请先登录。"
class Admin(UserMixin, db.Model):
__tablename__ = 'admin'
admin_id = db.Column(db.String(6), primary_key=True)
admin_name = db.Column(db.String(32))
password = db.Column(db.String(24))
right = db.Column(db.String(32))
def __init__(self, admin_id, admin_name, password, right):
self.admin_id = admin_id
self.admin_name = admin_name
self.password = password
self.right = right
def get_id(self):
return self.admin_id
def verify_password(self, password):
if password == self.password:
return True
else:
return False
def __repr__(self):
return '<Admin %r>' % self.admin_name
class Book(db.Model):
__tablename__ = 'book'
isbn = db.Column(db.String(13), primary_key=True)
book_name = db.Column(db.String(64))
author = db.Column(db.String(64))
press = db.Column(db.String(32))
class_name = db.Column(db.String(64))
def __repr__(self):
return '<Book %r>' % self.book_name
class Student(db.Model):
__tablename__ = 'student'
card_id = db.Column(db.String(8), primary_key=True)
student_id = db.Column(db.String(9))
student_name = db.Column(db.String(32))
sex = db.Column(db.String(2))
telephone = db.Column(db.String(11), nullable=True)
enroll_date = db.Column(db.String(13))
valid_date = db.Column(db.String(13))
loss = db.Column(db.Boolean, default=False) # 是否挂失
debt = db.Column(db.Boolean, default=False) # 是否欠费
def __repr__(self):
return '<Student %r>' % self.student_name
class Inventory(db.Model):
__tablename__ = 'inventory'
barcode = db.Column(db.String(6), primary_key=True)
isbn = db.Column(db.ForeignKey('book.isbn'))
storage_date = db.Column(db.String(13))
location = db.Column(db.String(32))
withdraw = db.Column(db.Boolean, default=False) # 是否注销
status = db.Column(db.Boolean, default=True) # 是否在馆
admin = db.Column(db.ForeignKey('admin.admin_id')) # 入库操作员
def __repr__(self):
return '<Inventory %r>' % self.barcode
class ReadBook(db.Model):
__tablename__ = 'readbook'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
barcode = db.Column(db.ForeignKey('inventory.barcode'), index=True)
card_id = db.Column(db.ForeignKey('student.card_id'), index=True)
start_date = db.Column(db.String(13))
borrow_admin = db.Column(db.ForeignKey('admin.admin_id')) # 借书操作员
end_date = db.Column(db.String(13), nullable=True)
return_admin = db.Column(db.ForeignKey('admin.admin_id')) # 还书操作员
due_date = db.Column(db.String(13)) # 应还日期
def __repr__(self):
return '<ReadBook %r>' % self.id
@login_manager.user_loader
def load_user(admin_id):
return Admin.query.get(int(admin_id))
@app.route('/', methods=['GET', 'POST'])
def login():
form = Login()
if form.validate_on_submit():
user = Admin.query.filter_by(admin_id=form.account.data, password=form.password.data).first()
if user is None:
flash('账号或密码错误!')
return redirect(url_for('login'))
else:
login_user(user)
session['admin_id'] = user.admin_id
session['name'] = user.admin_name
return redirect(url_for('index'))
return render_template('login.html', form=form)
@app.route('/logout')
@login_required
def logout():
logout_user()
flash('您已经登出!')
return redirect(url_for('login'))
@app.route('/index')
@login_required
def index():
return render_template('index.html', name=session.get('name'))
@app.route('/echarts')
@login_required
def echarts():
days = []
num = []
today_date = datetime.date.today()
today_str = today_date.strftime("%Y-%m-%d")
today_stamp = time.mktime(time.strptime(today_str + ' 00:00:00', '%Y-%m-%d %H:%M:%S'))
ten_ago = int(today_stamp) - 9 * 86400
for i in range(0, 10):
borr = ReadBook.query.filter_by(start_date=str((ten_ago+i*86400)*1000)).count()
retu = ReadBook.query.filter_by(end_date=str((ten_ago+i*86400)*1000)).count()
num.append(borr + retu)
days.append(timeStamp((ten_ago+i*86400)*1000))
data = []
for i in range(0, 10):
item = {'name': days[i], 'num': num[i]}
data.append(item)
return jsonify(data)
@app.route('/user/<id>')
@login_required
def user_info(id):
user = Admin.query.filter_by(admin_id=id).first()
return render_template('user-info.html', user=user, name=session.get('name'))
@app.route('/change_password', methods=['GET', 'POST'])
@login_required
def change_password():
form = ChangePasswordForm()
if form.password2.data != form.password.data:
flash(u'两次密码不一致!')
if form.validate_on_submit():
if current_user.verify_password(form.old_password.data):
current_user.password = form.password.data
db.session.add(current_user)
db.session.commit()
flash(u'已成功修改密码!')
return redirect(url_for('index'))
else:
flash(u'原密码输入错误,修改失败!')
return render_template("change-password.html", form=form)
@app.route('/change_info', methods=['GET', 'POST'])
@login_required
def change_info():
form = EditInfoForm()
if form.validate_on_submit():
current_user.admin_name = form.name.data
db.session.add(current_user)
flash(u'已成功修改个人信息!')
return redirect(url_for('user_info', id=current_user.admin_id))
form.name.data = current_user.admin_name
id = current_user.admin_id
right = current_user.right
return render_template('change-info.html', form=form, id=id, right=right)
@app.route('/search_book', methods=['GET', 'POST'])
@login_required
def search_book(): # 这个函数里不再处理提交按钮使用Ajax局部刷新
form = SearchBookForm()
return render_template('search-book.html', name=session.get('name'), form=form)
@app.route('/books', methods=['POST'])
def find_book():
def find_name():
return Book.query.filter(Book.book_name.like('%'+request.form.get('content')+'%')).all()
def find_author():
return Book.query.filter(Book.author.contains(request.form.get('content'))).all()
def find_class():
return Book.query.filter(Book.class_name.contains(request.form.get('content'))).all()
def find_isbn():
return Book.query.filter(Book.isbn.contains(request.form.get('content'))).all()
methods = {
'book_name': find_name,
'author': find_author,
'class_name': find_class,
'isbn': find_isbn
}
books = methods[request.form.get('method')]()
data = []
for book in books:
count = Inventory.query.filter_by(isbn=book.isbn).count()
available = Inventory.query.filter_by(isbn=book.isbn, status=True).count()
item = {'isbn': book.isbn, 'book_name': book.book_name, 'press': book.press, 'author': book.author,
'class_name': book.class_name, 'count': count, 'available': available}
data.append(item)
return jsonify(data)
@app.route('/user/book', methods=['GET', 'POST'])
def user_book():
form = SearchBookForm()
return render_template('user-book.html', form=form)
@app.route('/search_student', methods=['GET', 'POST'])
@login_required
def search_student():
form = SearchStudentForm()
return render_template('search-student.html', name=session.get('name'), form=form)
def timeStamp(timeNum):
if timeNum is None:
return timeNum
else:
timeStamp = float(float(timeNum)/1000)
timeArray = time.localtime(timeStamp)
print(time.strftime("%Y-%m-%d", timeArray))
return time.strftime("%Y-%m-%d", timeArray)
@app.route('/student', methods=['POST'])
def find_student():
stu = Student.query.filter_by(card_id=request.form.get('card')).first()
if stu is None:
return jsonify([])
else:
valid_date = timeStamp(stu.valid_date)
return jsonify([{'name': stu.student_name, 'gender': stu.sex, 'valid_date': valid_date, 'debt': stu.debt}])
@app.route('/record', methods=['POST'])
def find_record():
records = db.session.query(ReadBook).join(Inventory).join(Book).filter(ReadBook.card_id == request.form.get('card'))\
.with_entities(ReadBook.barcode, Inventory.isbn, Book.book_name, Book.author, ReadBook.start_date,
ReadBook.end_date, ReadBook.due_date).all() # with_entities啊啊啊啊卡了好久啊
data = []
for record in records:
start_date = timeStamp(record.start_date)
due_date = timeStamp(record.due_date)
end_date = timeStamp(record.end_date)
if end_date is None:
end_date = '未归还'
item = {'barcode': record.barcode, 'book_name': record.book_name, 'author': record.author,
'start_date': start_date, 'due_date': due_date, 'end_date': end_date}
data.append(item)
return jsonify(data)
@app.route('/user/student', methods=['GET', 'POST'])
def user_student():
form = SearchStudentForm()
return render_template('user-student.html', form=form)
@app.route('/storage', methods=['GET', 'POST'])
@login_required
def storage():
form = StoreForm()
if form.validate_on_submit():
book = Book.query.filter_by(isbn=request.form.get('isbn')).first()
exist = Inventory.query.filter_by(barcode=request.form.get('barcode')).first()
if book is None:
flash(u'添加失败,请注意本书信息是否已录入,若未登记,请在‘新书入库’窗口录入信息。')
else:
if len(request.form.get('barcode')) != 6:
flash(u'图书编码长度错误')
else:
if exist is not None:
flash(u'该编号已经存在!')
else:
item = Inventory()
item.barcode = request.form.get('barcode')
item.isbn = request.form.get('isbn')
item.admin = current_user.admin_id
item.location = request.form.get('location')
item.status = True
item.withdraw = False
today_date = datetime.date.today()
today_str = today_date.strftime("%Y-%m-%d")
today_stamp = time.mktime(time.strptime(today_str + ' 00:00:00', '%Y-%m-%d %H:%M:%S'))
item.storage_date = int(today_stamp)*1000
db.session.add(item)
db.session.commit()
flash(u'入库成功!')
return redirect(url_for('storage'))
return render_template('storage.html', name=session.get('name'), form=form)
@app.route('/new_store', methods=['GET', 'POST'])
@login_required
def new_store():
form = NewStoreForm()
if form.validate_on_submit():
if len(request.form.get('isbn')) != 13:
flash(u'ISBN长度错误')
else:
exist = Book.query.filter_by(isbn=request.form.get('isbn')).first()
if exist is not None:
flash(u'该图书信息已经存在,请核对后再录入;或者填写入库表。')
else:
book = Book()
book.isbn = request.form.get('isbn')
book.book_name = request.form.get('book_name')
book.press = request.form.get('press')
book.author = request.form.get('author')
book.class_name = request.form.get('class_name')
db.session.add(book)
db.session.commit()
flash(u'图书信息添加成功!')
return redirect(url_for('new_store'))
return render_template('new-store.html', name=session.get('name'), form=form)
@app.route('/borrow', methods=['GET', 'POST'])
@login_required
def borrow():
form = BorrowForm()
return render_template('borrow.html', name=session.get('name'), form=form)
@app.route('/find_stu_book', methods=['GET', 'POST'])
def find_stu_book():
stu = Student.query.filter_by(card_id=request.form.get('card')).first()
today_date = datetime.date.today()
today_str = today_date.strftime("%Y-%m-%d")
today_stamp = time.mktime(time.strptime(today_str + ' 00:00:00', '%Y-%m-%d %H:%M:%S'))
if stu is None:
return jsonify([{'stu': 0}]) # 没找到
if stu.debt is True:
return jsonify([{'stu': 1}]) # 欠费
if int(stu.valid_date) < int(today_stamp)*1000:
return jsonify([{'stu': 2}]) # 到期
if stu.loss is True:
return jsonify([{'stu': 3}]) # 已经挂失
books = db.session.query(Book).join(Inventory).filter(Book.book_name.contains(request.form.get('book_name')),
Inventory.status == 1).with_entities(Inventory.barcode, Book.isbn, Book.book_name, Book.author, Book.press).\
all()
data = []
for book in books:
item = {'barcode': book.barcode, 'isbn': book.isbn, 'book_name': book.book_name,
'author': book.author, 'press': book.press}
data.append(item)
return jsonify(data)
@app.route('/out', methods=['GET', 'POST'])
@login_required
def out():
today_date = datetime.date.today()
today_str = today_date.strftime("%Y-%m-%d")
today_stamp = time.mktime(time.strptime(today_str + ' 00:00:00', '%Y-%m-%d %H:%M:%S'))
barcode = request.args.get('barcode')
card = request.args.get('card')
book_name = request.args.get('book_name')
readbook = ReadBook()
readbook.barcode = barcode
readbook.card_id = card
readbook.start_date = int(today_stamp)*1000
readbook.due_date = (int(today_stamp)+40*86400)*1000
readbook.borrow_admin = current_user.admin_id
db.session.add(readbook)
db.session.commit()
book = Inventory.query.filter_by(barcode=barcode).first()
book.status = False
db.session.add(book)
db.session.commit()
bks = db.session.query(Book).join(Inventory).filter(Book.book_name.contains(book_name), Inventory.status == 1).\
with_entities(Inventory.barcode, Book.isbn, Book.book_name, Book.author, Book.press).all()
data = []
for bk in bks:
item = {'barcode': bk.barcode, 'isbn': bk.isbn, 'book_name': bk.book_name,
'author': bk.author, 'press': bk.press}
data.append(item)
return jsonify(data)
@app.route('/return', methods=['GET', 'POST'])
@login_required
def return_book():
form = SearchStudentForm()
return render_template('return.html', name=session.get('name'), form=form)
@app.route('/find_not_return_book', methods=['GET', 'POST'])
def find_not_return_book():
stu = Student.query.filter_by(card_id=request.form.get('card')).first()
today_date = datetime.date.today()
today_str = today_date.strftime("%Y-%m-%d")
today_stamp = time.mktime(time.strptime(today_str + ' 00:00:00', '%Y-%m-%d %H:%M:%S'))
if stu is None:
return jsonify([{'stu': 0}]) # 没找到
if stu.debt is True:
return jsonify([{'stu': 1}]) # 欠费
if int(stu.valid_date) < int(today_stamp)*1000:
return jsonify([{'stu': 2}]) # 到期
if stu.loss is True:
return jsonify([{'stu': 3}]) # 已经挂失
books = db.session.query(ReadBook).join(Inventory).join(Book).filter(ReadBook.card_id == request.form.get('card'),
ReadBook.end_date.is_(None)).with_entities(ReadBook.barcode, Book.isbn, Book.book_name, ReadBook.start_date,
ReadBook.due_date).all()
data = []
for book in books:
start_date = timeStamp(book.start_date)
due_date = timeStamp(book.due_date)
item = {'barcode': book.barcode, 'isbn': book.isbn, 'book_name': book.book_name,
'start_date': start_date, 'due_date': due_date}
data.append(item)
return jsonify(data)
@app.route('/in', methods=['GET', 'POST'])
@login_required
def bookin():
barcode = request.args.get('barcode')
card = request.args.get('card')
record = ReadBook.query.filter(ReadBook.barcode == barcode, ReadBook.card_id == card, ReadBook.end_date.is_(None)).\
first()
today_date = datetime.date.today()
today_str = today_date.strftime("%Y-%m-%d")
today_stamp = time.mktime(time.strptime(today_str + ' 00:00:00', '%Y-%m-%d %H:%M:%S'))
record.end_date = int(today_stamp)*1000
record.return_admin = current_user.admin_id
db.session.add(record)
db.session.commit()
book = Inventory.query.filter_by(barcode=barcode).first()
book.status = True
db.session.add(book)
db.session.commit()
bks = db.session.query(ReadBook).join(Inventory).join(Book).filter(ReadBook.card_id == card,
ReadBook.end_date.is_(None)).with_entities(ReadBook.barcode, Book.isbn, Book.book_name, ReadBook.start_date,
ReadBook.due_date).all()
data = []
for bk in bks:
start_date = timeStamp(bk.start_date)
due_date = timeStamp(bk.due_date)
item = {'barcode': bk.barcode, 'isbn': bk.isbn, 'book_name': bk.book_name,
'start_date': start_date, 'due_date': due_date}
data.append(item)
return jsonify(data)
if __name__ == '__main__':
manager.run()