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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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()