Compare commits

...

No commits in common. 'main' and 'master' have entirely different histories.
main ... master

8
.idea/.gitignore vendored

@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.6 (Book-Management-System-master)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TemplatesService">
<option name="TEMPLATE_CONFIGURATION" value="Jinja2" />
<option name="TEMPLATE_FOLDERS">
<list>
<option value="F:/book_management_sys\templates" />
</list>
</option>
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
</component>
</module>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="data.sqlite" uuid="41c7af7f-c53a-4e9b-b052-33423543bd76">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/data.sqlite</jdbc-url>
<driver-properties>
<property name="enable_load_extension" value="true" />
</driver-properties>
</data-source>
</component>
</project>

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.6 (Book-Management-System-master)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6 (Book-Management-System-master)" project-jdk-type="Python SDK" />
</project>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/book_management_sys.iml" filepath="$PROJECT_DIR$/.idea/book_management_sys.iml" />
</modules>
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

@ -1,2 +0,0 @@
# ysy01

Binary file not shown.

497
app.py

@ -0,0 +1,497 @@
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()

Binary file not shown.

@ -0,0 +1,56 @@
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, SelectField, PasswordField
from wtforms.validators import DataRequired, EqualTo, Length
class Login(FlaskForm):
account = StringField(u'账号', validators=[DataRequired()])
password = PasswordField(u'密码', validators=[DataRequired()])
submit = SubmitField(u'登录')
class ChangePasswordForm(FlaskForm):
old_password = PasswordField(u'原密码', validators=[DataRequired()])
password = PasswordField(u'新密码', validators=[DataRequired(), EqualTo('password2', message=u'两次密码必须一致!')])
password2 = PasswordField(u'确认新密码', validators=[DataRequired()])
submit = SubmitField(u'确认修改')
class EditInfoForm(FlaskForm):
name = StringField(u'用户名', validators=[Length(1, 32)])
submit = SubmitField(u'提交')
class SearchBookForm(FlaskForm):
methods = [('book_name', '书名'), ('author', '作者'), ('class_name', '类别'), ('isbn', 'ISBN')]
method = SelectField(choices=methods, validators=[DataRequired()], coerce=str)
content = StringField(validators=[DataRequired()])
submit = SubmitField('搜索')
class SearchStudentForm(FlaskForm):
card = StringField(validators=[DataRequired()])
submit = SubmitField('搜索')
class StoreForm(FlaskForm):
barcode = StringField(validators=[DataRequired(), Length(6)])
isbn = StringField(validators=[DataRequired(), Length(13)])
location = StringField(validators=[DataRequired(), Length(1, 32)])
submit = SubmitField(u'提交')
class NewStoreForm(FlaskForm):
isbn = StringField(validators=[DataRequired(), Length(13)])
book_name = StringField(validators=[DataRequired(), Length(1, 64)])
press = StringField(validators=[DataRequired(), Length(1, 32)])
author = StringField(validators=[DataRequired(), Length(1, 64)])
class_name = StringField(validators=[DataRequired(), Length(1, 64)])
submit = SubmitField(u'提交')
class BorrowForm(FlaskForm):
card = StringField(validators=[DataRequired()])
book_name = StringField(validators=[DataRequired()])
submit = SubmitField(u'搜索')

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,2 @@
/** layui-v2.4.5 MIT License By https://www.layui.com */
html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #e2e2e2;border-left-width:6px;background-color:#F2F2F2;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:32px;line-height:32px;border-bottom:1px solid #e2e2e2}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 5px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 701 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

@ -0,0 +1,2 @@
/** layui-v2.4.5 MIT License By https://www.layui.com */
;layui.define("jquery",function(e){"use strict";var i=layui.$,n=(layui.hint(),layui.device(),{config:{},set:function(e){var n=this;return n.config=i.extend({},n.config,e),n},on:function(e,i){return layui.onevent.call(this,t,e,i)}}),t="carousel",a="layui-this",l=">*[carousel-item]>*",o="layui-carousel-left",r="layui-carousel-right",d="layui-carousel-prev",s="layui-carousel-next",u="layui-carousel-arrow",c="layui-carousel-ind",m=function(e){var t=this;t.config=i.extend({},t.config,n.config,e),t.render()};m.prototype.config={width:"600px",height:"280px",full:!1,arrow:"hover",indicator:"inside",autoplay:!0,interval:3e3,anim:"",trigger:"click",index:0},m.prototype.render=function(){var e=this,n=e.config;n.elem=i(n.elem),n.elem[0]&&(e.elemItem=n.elem.find(l),n.index<0&&(n.index=0),n.index>=e.elemItem.length&&(n.index=e.elemItem.length-1),n.interval<800&&(n.interval=800),n.full?n.elem.css({position:"fixed",width:"100%",height:"100%",zIndex:9999}):n.elem.css({width:n.width,height:n.height}),n.elem.attr("lay-anim",n.anim),e.elemItem.eq(n.index).addClass(a),e.elemItem.length<=1||(e.indicator(),e.arrow(),e.autoplay(),e.events()))},m.prototype.reload=function(e){var n=this;clearInterval(n.timer),n.config=i.extend({},n.config,e),n.render()},m.prototype.prevIndex=function(){var e=this,i=e.config,n=i.index-1;return n<0&&(n=e.elemItem.length-1),n},m.prototype.nextIndex=function(){var e=this,i=e.config,n=i.index+1;return n>=e.elemItem.length&&(n=0),n},m.prototype.addIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index+e,n.index>=i.elemItem.length&&(n.index=0)},m.prototype.subIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index-e,n.index<0&&(n.index=i.elemItem.length-1)},m.prototype.autoplay=function(){var e=this,i=e.config;i.autoplay&&(e.timer=setInterval(function(){e.slide()},i.interval))},m.prototype.arrow=function(){var e=this,n=e.config,t=i(['<button class="layui-icon '+u+'" lay-type="sub">'+("updown"===n.anim?"&#xe619;":"&#xe603;")+"</button>",'<button class="layui-icon '+u+'" lay-type="add">'+("updown"===n.anim?"&#xe61a;":"&#xe602;")+"</button>"].join(""));n.elem.attr("lay-arrow",n.arrow),n.elem.find("."+u)[0]&&n.elem.find("."+u).remove(),n.elem.append(t),t.on("click",function(){var n=i(this),t=n.attr("lay-type");e.slide(t)})},m.prototype.indicator=function(){var e=this,n=e.config,t=e.elemInd=i(['<div class="'+c+'"><ul>',function(){var i=[];return layui.each(e.elemItem,function(e){i.push("<li"+(n.index===e?' class="layui-this"':"")+"></li>")}),i.join("")}(),"</ul></div>"].join(""));n.elem.attr("lay-indicator",n.indicator),n.elem.find("."+c)[0]&&n.elem.find("."+c).remove(),n.elem.append(t),"updown"===n.anim&&t.css("margin-top",-(t.height()/2)),t.find("li").on("hover"===n.trigger?"mouseover":n.trigger,function(){var t=i(this),a=t.index();a>n.index?e.slide("add",a-n.index):a<n.index&&e.slide("sub",n.index-a)})},m.prototype.slide=function(e,i){var n=this,l=n.elemItem,u=n.config,c=u.index,m=u.elem.attr("lay-filter");n.haveSlide||("sub"===e?(n.subIndex(i),l.eq(u.index).addClass(d),setTimeout(function(){l.eq(c).addClass(r),l.eq(u.index).addClass(r)},50)):(n.addIndex(i),l.eq(u.index).addClass(s),setTimeout(function(){l.eq(c).addClass(o),l.eq(u.index).addClass(o)},50)),setTimeout(function(){l.removeClass(a+" "+d+" "+s+" "+o+" "+r),l.eq(u.index).addClass(a),n.haveSlide=!1},300),n.elemInd.find("li").eq(u.index).addClass(a).siblings().removeClass(a),n.haveSlide=!0,layui.event.call(this,t,"change("+m+")",{index:u.index,prevIndex:c,item:l.eq(u.index)}))},m.prototype.events=function(){var e=this,i=e.config;i.elem.data("haveEvents")||(i.elem.on("mouseenter",function(){clearInterval(e.timer)}).on("mouseleave",function(){e.autoplay()}),i.elem.data("haveEvents",!0))},n.render=function(e){var i=new m(e);return i},e(t,n)});

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save