├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── app ├── __init__.py ├── config.py ├── forms.py ├── models.py ├── models_new.py ├── static │ ├── .DS_Store │ ├── bootstrap │ │ ├── css │ │ │ ├── bootstrap-grid.css │ │ │ ├── bootstrap-grid.css.map │ │ │ ├── bootstrap-grid.min.css │ │ │ ├── bootstrap-grid.min.css.map │ │ │ ├── bootstrap-reboot.css │ │ │ ├── bootstrap-reboot.css.map │ │ │ ├── bootstrap-reboot.min.css │ │ │ ├── bootstrap-reboot.min.css.map │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ └── js │ │ │ ├── bootstrap.js │ │ │ └── bootstrap.min.js │ ├── css │ │ └── stisla.css │ ├── img │ │ ├── .DS_Store │ │ ├── head.gif │ │ ├── hero.jpeg │ │ ├── logo.png │ │ └── spinner.svg │ ├── ionicons │ │ ├── css │ │ │ ├── ionicons.css │ │ │ └── ionicons.min.css │ │ └── fonts │ │ │ ├── ionicons.eot │ │ │ ├── ionicons.svg │ │ │ ├── ionicons.ttf │ │ │ └── ionicons.woff │ └── js │ │ ├── jquery.easeScroll.js │ │ ├── jquery.min.js │ │ └── stisla.js ├── templates │ ├── .DS_Store │ ├── admin.html │ ├── admin │ │ ├── course_manage.html │ │ ├── course_select_manage.html │ │ ├── manager.html │ │ ├── student_manage.html │ │ └── teacher_manage.html │ ├── base.html │ ├── index.html │ ├── login.html │ ├── student │ │ ├── course.html │ │ ├── course_select_table.html │ │ ├── course_teachers.html │ │ ├── dept_info.html │ │ ├── grade_query.html │ │ ├── major_info.html │ │ ├── student.html │ │ ├── student_info.html │ │ └── voluntary_selection.html │ └── teacher │ │ ├── course_grade_input.html │ │ ├── course_select_detail.html │ │ ├── teacher.html │ │ └── teacher_info.html └── view.py ├── course_select_system.sql ├── image ├── AllCourse.png ├── CourseManage.png ├── CourseManage2.png ├── GradeInput.png ├── GradeInquiry.png ├── Login.png ├── SelectManage.png ├── SelectedCourse.png ├── StuManage.png ├── Student.png ├── Teacher.png ├── TeacherCourse.png └── TeacherManage.png ├── main.py ├── migrations ├── README ├── alembic.ini ├── env.py ├── script.py.mako └── versions │ └── ddcf6d407079_.py └── requirements.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .nox/ 42 | .coverage 43 | .coverage.* 44 | .cache 45 | nosetests.xml 46 | coverage.xml 47 | *.cover 48 | .hypothesis/ 49 | .pytest_cache/ 50 | 51 | # Translations 52 | *.mo 53 | *.pot 54 | 55 | # Django stuff: 56 | *.log 57 | local_settings.py 58 | db.sqlite3 59 | 60 | # Flask stuff: 61 | instance/ 62 | .webassets-cache 63 | 64 | # Scrapy stuff: 65 | .scrapy 66 | 67 | # Sphinx documentation 68 | docs/_build/ 69 | 70 | # PyBuilder 71 | target/ 72 | 73 | # Jupyter Notebook 74 | .ipynb_checkpoints 75 | 76 | # IPython 77 | profile_default/ 78 | ipython_config.py 79 | 80 | # pyenv 81 | .python-version 82 | 83 | # celery beat schedule file 84 | celerybeat-schedule 85 | 86 | # SageMath parsed files 87 | *.sage.py 88 | 89 | # Environments 90 | .env 91 | .venv 92 | env/ 93 | venv/ 94 | ENV/ 95 | env.bak/ 96 | venv.bak/ 97 | 98 | # Spyder project settings 99 | .spyderproject 100 | .spyproject 101 | 102 | # Rope project settings 103 | .ropeproject 104 | 105 | # mkdocs documentation 106 | /site 107 | 108 | # mypy 109 | .mypy_cache/ 110 | .dmypy.json 111 | dmypy.json 112 | 113 | # Pyre type checker 114 | .pyre/ 115 | 116 | .DS_Store 117 | *.out 118 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > 展示网站: 2 | > 3 | > 首先用管理员账户登陆(帐号000,密码admin) 4 | > 5 | > 创建自己的8位学号,默认密码admin。 6 | > 7 | > 再用自己学号登陆选课系统进行体验。 8 | 9 | ## 一、Python_Flask的初始化(Bootstrap框架、SQLalchemy的ORM框架、数据库迁移工具) 10 | 11 | 12 | ## 二、选课系统关系模型的定义 13 | 14 | 在基础的属性定义外,还定义了各类之间的一对多关系,多对多关系,包括: 15 | 16 | - 学院:教师 = 1:n 17 | - 学院:专业 = 1:n 18 | - 学院:课程 = 1:n 19 | - 专业:学生 = 1:n 20 | - 教师:课程 = m:n 21 | - 学生:课程 = m:n 22 | 23 | 在教师与课程的多对多关系中,额外建立一张表,用于存储老师开设课程的具体属性:上课时间、课程容量等。 24 | 25 | 在教师、课程、学生这个三方多对多关系中,额外建立一张结联表。 26 | 27 | 28 | ## 三、登陆、登出模块 29 | 30 | 登陆验证时,首先从学生表中查找输入的学号,若无,再从教师表中去查找。管理员采用单独的登陆界面,用于区分。 31 | 32 | 密码验证采用flask的加盐哈希加密算法,无SQL注入风险,保证用户的信息安全。 33 | 34 | 在此基础上,添加了"记住我"的登陆选项。 35 | 36 | ![image](https://github.com/WolfMy/course_select_system/blob/master/image/Login.png) 37 | 38 | 39 | ## 四、学生界面的功能简述 40 | 41 | 1. 信息查询:学生个人信息(可修改密码)、专业信息、学院信息 42 | 43 | 2. 查询已选课程信息,更换已选课程授课教师,退课 44 | 45 | 3. 查询所有开设课程的信息 46 | 47 | 4. 查询已选课程的成绩 48 | 49 | ![image](https://github.com/WolfMy/course_select_system/blob/master/image/Student.png) 50 | 51 | ![image](https://github.com/WolfMy/course_select_system/blob/master/image/SelectedCourse.png) 52 | 53 | ![image](https://github.com/WolfMy/course_select_system/blob/master/image/AllCourse.png) 54 | 55 | ![image](https://github.com/WolfMy/course_select_system/blob/master/image/GradeInquiry.png) 56 | 57 | 58 | ## 五、教师界面功能简述 59 | 60 | 1. 信息查询:教师个人信息(可修改密码) 61 | 62 | 2. 查看学生选此教师开设课程的详情,包括各个学生的个人信息,以及已选学生人数等 63 | 64 | 3. 为此教师开设课程中的学生,录入此门课程的成绩,支持录入后修改成绩的功能 65 | 66 | ![image](https://github.com/WolfMy/course_select_system/blob/master/image/Teacher.png) 67 | 68 | ![image](https://github.com/WolfMy/course_select_system/blob/master/image/TeacherCourse.png) 69 | 70 | ![image](https://github.com/WolfMy/course_select_system/blob/master/image/GradeInput.png) 71 | 72 | 73 | ## 六、管理员界面简述 74 | 75 | 1. 学生管理: 76 | - 录入学生:先检测学生表中是否存在学号冲突的学生,若无则插入此学生信息。 77 | - 删除学生:先查询出此学生所有已选课程,系统将其全部退选后,再删除此学生。 78 | 79 | 2. 教师管理: 80 | - 录入教师:同"录入学生"。 81 | 82 | 3. 课程管理: 83 | - 创建课程 84 | - 教师开设课程 85 | - 删除课程 86 | 87 | 4. 学生选课管理: 88 | - 手动签课 89 | - 手动退课 90 | - 修改课程容量 91 | - 删除此开设课程 92 | 93 | ![image](https://github.com/WolfMy/course_select_system/blob/master/image/StuManage.png) 94 | 95 | ![image](https://github.com/WolfMy/course_select_system/blob/master/image/TeacherManage.png) 96 | 97 | ![image](https://github.com/WolfMy/course_select_system/blob/master/image/CourseManage.png) 98 | 99 | ![image](https://github.com/WolfMy/course_select_system/blob/master/image/CourseManage2.png) 100 | 101 | ![image](https://github.com/WolfMy/course_select_system/blob/master/image/SelectManage.png) 102 | -------------------------------------------------------------------------------- /app/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from flask_sqlalchemy import SQLAlchemy 3 | from flask_migrate import Migrate 4 | from flask_login import LoginManager 5 | from flask_bootstrap import Bootstrap 6 | 7 | from .config import Config 8 | 9 | # create and configure the app 10 | app = Flask(__name__) 11 | app.config.from_object(Config) 12 | 13 | db = SQLAlchemy(app) 14 | bootstrap = Bootstrap(app) 15 | migrate = Migrate(app, db) 16 | login = LoginManager(app) 17 | login.login_view = 'login' 18 | 19 | from app import view, models_new -------------------------------------------------------------------------------- /app/config.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | class Config(object): 4 | SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess!' 5 | SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:root@localhost:3306/course_select_system?charset=utf8' 6 | SQLALCHEMY_TRACK_MODIFICATIONS = False -------------------------------------------------------------------------------- /app/forms.py: -------------------------------------------------------------------------------- 1 | from flask_wtf import FlaskForm 2 | from wtforms import StringField, PasswordField, BooleanField, SubmitField 3 | from wtforms.validators import DataRequired, EqualTo 4 | 5 | class LoginForm(FlaskForm): 6 | username = StringField('Username', validators=[DataRequired()]) 7 | password = PasswordField('Password', validators=[DataRequired()]) 8 | submit = SubmitField('Sign In') 9 | 10 | class EditProfileForm(FlaskForm): 11 | old_password = PasswordField('Old Password', validators=[DataRequired()]) 12 | new_password = PasswordField('New Password', validators=[DataRequired()]) 13 | new_password2 = PasswordField('Repeat New Password', validators=[DataRequired()]) 14 | submit = SubmitField('修改密码') -------------------------------------------------------------------------------- /app/models.py: -------------------------------------------------------------------------------- 1 | from werkzeug.security import generate_password_hash, check_password_hash 2 | from flask_login import UserMixin 3 | from app import db 4 | from app import login 5 | 6 | @login.user_loader 7 | def load_user(Num): 8 | if len(Num) == 8: 9 | return Student.query.get(int(Num)) 10 | elif len(Num) == 5: 11 | return Teacher.query.get(int(Num)) 12 | elif len(Num) == 3: 13 | return Manager.query.get(int(Num)) 14 | else: 15 | pass 16 | 17 | class Dept(db.Model): 18 | # 学院 19 | DeptNum = db.Column(db.String(4), primary_key=True) 20 | DeptName = db.Column(db.String(10), nullable=False) 21 | DeptChairman = db.Column(db.String(10), nullable=False) 22 | DeptTel = db.Column(db.String(11)) 23 | DeptDesc = db.Column(db.Text) 24 | teacher = db.relationship('Teacher', backref='dept', lazy='dynamic') 25 | Majors = db.relationship('Major', backref='dept', lazy='dynamic') 26 | 27 | class Teacher(UserMixin, db.Model): 28 | # 教师 29 | TeacherNum = db.Column(db.String(8), primary_key=True) 30 | DeptNum = db.Column(db.String(4), db.ForeignKey('dept.DeptNum'), nullable=False) 31 | TeacherName = db.Column(db.String(10), nullable=False) 32 | TeacherSex = db.Column(db.String(2), nullable=False) 33 | TeacherBirthday = db.Column(db.DateTime) 34 | TeacherTitle = db.Column(db.String(10)) 35 | TeacherPassword = db.Column(db.Text, nullable=False) 36 | CourseNum = db.Column(db.String(8), db.ForeignKey('course.CourseNum')) 37 | 38 | # override 39 | def get_id(self): 40 | return self.TeacherNum 41 | def set_password(self, password): 42 | self.TeacherNum = generate_password_hash(password) 43 | def check_password(self, password): 44 | return check_password_hash(self.TeacherPassword, password) 45 | 46 | class Manager(UserMixin, db.Model): 47 | # 管理员 48 | ManagerNum = db.Column(db.String(8), primary_key=True) 49 | ManagerName = db.Column(db.String(10), nullable=False) 50 | ManagerSex = db.Column(db.String(2), nullable=False) 51 | ManagerBirthday = db.Column(db.DateTime) 52 | ManagerPassword = db.Column(db.Text, nullable=False) 53 | ManagerPermission = db.Column(db.Integer, nullable=False) 54 | 55 | # override 56 | def get_id(self): 57 | return self.ManagerNum 58 | def set_password(self, password): 59 | self.ManagerPassword = generate_password_hash(password) 60 | def check_password(self, password): 61 | return check_password_hash(self.ManagerPassword, password) 62 | 63 | class Major(db.Model): 64 | # 专业 65 | MajorNum = db.Column(db.String(6), primary_key=True) 66 | DeptNum = db.Column(db.String(4), db.ForeignKey('dept.DeptNum'), nullable=False) 67 | MajorName = db.Column(db.String(10), nullable=False) 68 | MajorAssistant = db.Column(db.String(10), nullable=False) 69 | MajorTel = db.Column(db.String(11)) 70 | MajorDesc = db.Column(db.Text) 71 | Students = db.relationship('Student', backref='major', lazy='dynamic') 72 | 73 | # 选课表 74 | Course_select_table = db.Table('course_select_table', 75 | db.Column('StudentNum', db.String(8), db.ForeignKey('student.StudentNum'), nullable=False), 76 | db.Column('CourseNum', db.String(10), db.ForeignKey('course.CourseNum'), nullable=False), 77 | db.Column('TeacherNum', db.String(8), db.ForeignKey('teacher.TeacherNum'), nullable=False), 78 | db.Column('Grade', db.Integer) 79 | ) 80 | 81 | class Student(UserMixin, db.Model): 82 | # 学生 83 | StudentNum = db.Column(db.String(8), primary_key=True) 84 | MajorNum = db.Column(db.String(16), db.ForeignKey('major.MajorNum'), nullable=False) 85 | StudentName = db.Column(db.String(10), nullable=False) 86 | StudentSex = db.Column(db.String(10), nullable=False) 87 | StudentBirthday = db.Column(db.DateTime) 88 | StudengtPassword = db.Column(db.Text, nullable=False) 89 | Course = db.relationship('Course', secondary=Course_select_table, backref=db.backref('student', lazy='dynamic')) 90 | 91 | # override 92 | def get_id(self): 93 | return self.StudentNum 94 | def set_password(self, password): 95 | self.StudengtPassword = generate_password_hash(password) 96 | def check_password(self, password): 97 | return check_password_hash(self.StudengtPassword, password) 98 | 99 | class Course(db.Model): 100 | # 课程 101 | CourseNum = db.Column(db.String(8), primary_key=True) 102 | CourseName = db.Column(db.String(10), nullable=False) 103 | CourseCredit = db.Column(db.Integer, nullable=False) 104 | CourseTime = db.Column(db.Integer, nullable=False) 105 | TeacherNum = db.relationship('Teacher', backref='course', lazy='dynamic') 106 | CourseDesc = db.Column(db.Text) 107 | 108 | class TrainingProgram(db.Model): 109 | # 培养计划 110 | TPNumber = db.Column(db.String(7), primary_key=True) -------------------------------------------------------------------------------- /app/models_new.py: -------------------------------------------------------------------------------- 1 | from werkzeug.security import generate_password_hash, check_password_hash 2 | from flask_login import UserMixin 3 | from app import db 4 | from app import login 5 | 6 | @login.user_loader 7 | def load_user(Num): 8 | if len(Num) == 8: 9 | return Student.query.get(int(Num)) 10 | elif len(Num) == 4: 11 | return Teacher.query.get(int(Num)) 12 | elif len(Num) == 3: 13 | return Manager.query.get(int(Num)) 14 | else: 15 | pass 16 | 17 | class Dept(db.Model): 18 | # 学院 19 | DeptNum = db.Column(db.String(4), primary_key=True) 20 | DeptName = db.Column(db.String(10), nullable=False) 21 | DeptChairman = db.Column(db.String(10), nullable=False) 22 | DeptTel = db.Column(db.String(11)) 23 | DeptDesc = db.Column(db.Text) 24 | Teachers = db.relationship('Teacher', backref='dept', lazy='dynamic') 25 | Majors = db.relationship('Major', backref='dept', lazy='dynamic') 26 | Courses = db.relationship('Course', backref='dept', lazy='dynamic') 27 | 28 | class Major(db.Model): 29 | # 专业 30 | MajorNum = db.Column(db.String(6), primary_key=True) 31 | DeptNum = db.Column(db.String(4), db.ForeignKey('dept.DeptNum'), nullable=False) 32 | MajorName = db.Column(db.String(10), nullable=False) 33 | MajorAssistant = db.Column(db.String(10), nullable=False) 34 | MajorTel = db.Column(db.String(11)) 35 | MajorDesc = db.Column(db.Text) 36 | Students = db.relationship('Student', backref='major', lazy='dynamic') 37 | TrainingProgram = db.Column(db.String(7)) 38 | 39 | class Course_select_table(db.Model): 40 | __tablename__ = "course_select_table" 41 | StudentNum = db.Column(db.String(8), db.ForeignKey('student.StudentNum'), primary_key=True, nullable=False) 42 | CourseNum = db.Column(db.String(10), db.ForeignKey('course.CourseNum'), primary_key=True, nullable=False) 43 | TeacherNum = db.Column(db.String(8), db.ForeignKey('teacher.TeacherNum'), primary_key=True, nullable=False) 44 | Grade = db.Column(db.Integer) 45 | 46 | def __init__(self, StudentNum, CourseNum, TeacherNum): 47 | self.StudentNum = StudentNum 48 | self.CourseNum = CourseNum 49 | self.TeacherNum = TeacherNum 50 | 51 | def input_grade(self, grade): 52 | self.Grade = grade 53 | 54 | class Course_Teacher(db.Model): 55 | __tablename__ = "course_teacher" 56 | CourseNum = db.Column(db.String(8), db.ForeignKey('course.CourseNum'), primary_key=True, nullable=False) 57 | TeacherNum = db.Column(db.String(10), db.ForeignKey('teacher.TeacherNum'), primary_key=True, nullable=False) 58 | #Time = db.Column(db.Text) 59 | CourseCapacity = db.Column(db.Integer, nullable=False) 60 | 61 | def __init__(self, CourseNum, TeacherNum, CourseCapacity): 62 | self.CourseNum = CourseNum 63 | self.TeacherNum = TeacherNum 64 | self.CourseCapacity = CourseCapacity 65 | 66 | class Teacher(UserMixin, db.Model): 67 | # 教师 68 | TeacherNum = db.Column(db.String(8), primary_key=True) 69 | DeptNum = db.Column(db.String(4), db.ForeignKey('dept.DeptNum'), nullable=False) 70 | TeacherName = db.Column(db.String(10), nullable=False) 71 | TeacherSex = db.Column(db.String(2), nullable=False) 72 | TeacherInyear = db.Column(db.String(4), nullable=False) 73 | TeacherTitle = db.Column(db.String(10)) 74 | TeacherPassword = db.Column(db.Text, nullable=False) 75 | Students = db.relationship('Student', secondary='course_select_table', backref='teacher', lazy='dynamic') 76 | Courses = db.relationship('Course', secondary='course_teacher', backref='teacher', lazy='dynamic') 77 | 78 | def __init__(self, TeacherNum, DeptNum, TeacherName, TeacherSex, TeacherInyear, TeacherTitle): 79 | self.TeacherNum = TeacherNum 80 | self.DeptNum = DeptNum 81 | self.TeacherName = TeacherName 82 | self.TeacherSex = TeacherSex 83 | self.TeacherInyear = TeacherInyear 84 | self.TeacherTitle = TeacherTitle 85 | self.set_password('admin') 86 | 87 | # override 88 | def get_id(self): 89 | return self.TeacherNum 90 | def set_password(self, password): 91 | self.TeacherPassword = generate_password_hash(password) 92 | def check_password(self, password): 93 | return check_password_hash(self.TeacherPassword, password) 94 | 95 | class Student(UserMixin, db.Model): 96 | # 学生 97 | StudentNum = db.Column(db.String(8), primary_key=True) 98 | MajorNum = db.Column(db.String(16), db.ForeignKey('major.MajorNum'), nullable=False) 99 | StudentName = db.Column(db.String(10), nullable=False) 100 | StudentSex = db.Column(db.String(10), nullable=False) 101 | StudentInyear = db.Column(db.String(4), nullable=False) 102 | StudengtPassword = db.Column(db.Text, nullable=False) 103 | Courses = db.relationship('Course', secondary='course_select_table', backref='student', lazy='dynamic') 104 | 105 | def __init__(self, StudentNum, MajorNum, StudentName, StudentSex, StudentInyear): 106 | self.StudentNum = StudentNum 107 | self.MajorNum = MajorNum 108 | self.StudentName = StudentName 109 | self.StudentSex = StudentSex 110 | self.StudentInyear = StudentInyear 111 | self.set_password('admin') 112 | 113 | # override 114 | def get_id(self): 115 | return self.StudentNum 116 | def set_password(self, password): 117 | self.StudengtPassword = generate_password_hash(password) 118 | def check_password(self, password): 119 | return check_password_hash(self.StudengtPassword, password) 120 | def drop_course(self, CourseNum): 121 | course_drop = [course for course in self.Courses if course.CourseNum==CourseNum][0] 122 | self.Courses.remove(course_drop) 123 | 124 | class Course(db.Model): 125 | # 课程 126 | CourseNum = db.Column(db.String(8), primary_key=True) 127 | CourseName = db.Column(db.String(10), nullable=False) 128 | CourseCredit = db.Column(db.Integer, nullable=False) 129 | CourseTime = db.Column(db.Integer, nullable=False) 130 | CourseDesc = db.Column(db.Text) 131 | Teachers = db.relationship('Teacher', secondary='course_teacher', backref='course', lazy='dynamic') 132 | DeptNum = db.Column(db.String(4), db.ForeignKey('dept.DeptNum'), nullable=False) 133 | 134 | def __init__(self, CourseNum, CourseName, CourseCredit, CourseTime, DeptNum, CourseDesc): 135 | self.CourseNum = CourseNum 136 | self.CourseName = CourseName 137 | self.CourseCredit = CourseCredit 138 | self.CourseTime = CourseTime 139 | self.DeptNum = DeptNum 140 | self.CourseDesc = CourseDesc 141 | 142 | 143 | class Manager(UserMixin, db.Model): 144 | # 管理员 145 | ManagerNum = db.Column(db.String(8), primary_key=True) 146 | ManagerName = db.Column(db.String(10), nullable=False) 147 | ManagerSex = db.Column(db.String(2), nullable=False) 148 | ManagerBirthday = db.Column(db.DateTime) 149 | ManagerPassword = db.Column(db.Text, nullable=False) 150 | ManagerPermission = db.Column(db.Integer, nullable=False) 151 | 152 | # override 153 | def get_id(self): 154 | return self.ManagerNum 155 | def set_password(self, password): 156 | self.ManagerPassword = generate_password_hash(password) 157 | def check_password(self, password): 158 | return check_password_hash(self.ManagerPassword, password) 159 | 160 | class TrainingProgram(db.Model): 161 | # 培养计划 162 | TPNumber = db.Column(db.String(7), primary_key=True) -------------------------------------------------------------------------------- /app/static/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/app/static/.DS_Store -------------------------------------------------------------------------------- /app/static/bootstrap/css/bootstrap-grid.min.css: -------------------------------------------------------------------------------- 1 | @-ms-viewport{width:device-width}html{box-sizing:border-box;-ms-overflow-style:scrollbar}*,::after,::before{box-sizing:inherit}.container{margin-right:auto;margin-left:auto;padding-right:15px;padding-left:15px;width:100%}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;margin-right:auto;margin-left:auto;padding-right:15px;padding-left:15px;width:100%}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}} 2 | /*# sourceMappingURL=bootstrap-grid.min.css.map */ -------------------------------------------------------------------------------- /app/static/bootstrap/css/bootstrap-reboot.css: -------------------------------------------------------------------------------- 1 | html { 2 | box-sizing: border-box; 3 | font-family: sans-serif; 4 | line-height: 1.15; 5 | -webkit-text-size-adjust: 100%; 6 | -ms-text-size-adjust: 100%; 7 | -ms-overflow-style: scrollbar; 8 | -webkit-tap-highlight-color: transparent; 9 | } 10 | 11 | *, 12 | *::before, 13 | *::after { 14 | box-sizing: inherit; 15 | } 16 | 17 | @-ms-viewport { 18 | width: device-width; 19 | } 20 | 21 | article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section { 22 | display: block; 23 | } 24 | 25 | body { 26 | margin: 0; 27 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; 28 | font-size: 1rem; 29 | font-weight: normal; 30 | line-height: 1.5; 31 | color: #212529; 32 | background-color: #fff; 33 | } 34 | 35 | [tabindex="-1"]:focus { 36 | outline: none !important; 37 | } 38 | 39 | hr { 40 | box-sizing: content-box; 41 | height: 0; 42 | overflow: visible; 43 | } 44 | 45 | h1, h2, h3, h4, h5, h6 { 46 | margin-top: 0; 47 | margin-bottom: .5rem; 48 | } 49 | 50 | p { 51 | margin-top: 0; 52 | margin-bottom: 1rem; 53 | } 54 | 55 | abbr[title], 56 | abbr[data-original-title] { 57 | text-decoration: underline; 58 | -webkit-text-decoration: underline dotted; 59 | text-decoration: underline dotted; 60 | cursor: help; 61 | border-bottom: 0; 62 | } 63 | 64 | address { 65 | margin-bottom: 1rem; 66 | font-style: normal; 67 | line-height: inherit; 68 | } 69 | 70 | ol, 71 | ul, 72 | dl { 73 | margin-top: 0; 74 | margin-bottom: 1rem; 75 | } 76 | 77 | ol ol, 78 | ul ul, 79 | ol ul, 80 | ul ol { 81 | margin-bottom: 0; 82 | } 83 | 84 | dt { 85 | font-weight: bold; 86 | } 87 | 88 | dd { 89 | margin-bottom: .5rem; 90 | margin-left: 0; 91 | } 92 | 93 | blockquote { 94 | margin: 0 0 1rem; 95 | } 96 | 97 | dfn { 98 | font-style: italic; 99 | } 100 | 101 | b, 102 | strong { 103 | font-weight: bolder; 104 | } 105 | 106 | small { 107 | font-size: 80%; 108 | } 109 | 110 | sub, 111 | sup { 112 | position: relative; 113 | font-size: 75%; 114 | line-height: 0; 115 | vertical-align: baseline; 116 | } 117 | 118 | sub { 119 | bottom: -.25em; 120 | } 121 | 122 | sup { 123 | top: -.5em; 124 | } 125 | 126 | a { 127 | color: #007bff; 128 | text-decoration: none; 129 | background-color: transparent; 130 | -webkit-text-decoration-skip: objects; 131 | } 132 | 133 | a:hover { 134 | color: #0056b3; 135 | text-decoration: underline; 136 | } 137 | 138 | a:not([href]):not([tabindex]) { 139 | color: inherit; 140 | text-decoration: none; 141 | } 142 | 143 | a:not([href]):not([tabindex]):focus, a:not([href]):not([tabindex]):hover { 144 | color: inherit; 145 | text-decoration: none; 146 | } 147 | 148 | a:not([href]):not([tabindex]):focus { 149 | outline: 0; 150 | } 151 | 152 | pre, 153 | code, 154 | kbd, 155 | samp { 156 | font-family: monospace, monospace; 157 | font-size: 1em; 158 | } 159 | 160 | pre { 161 | margin-top: 0; 162 | margin-bottom: 1rem; 163 | overflow: auto; 164 | } 165 | 166 | figure { 167 | margin: 0 0 1rem; 168 | } 169 | 170 | img { 171 | vertical-align: middle; 172 | border-style: none; 173 | } 174 | 175 | svg:not(:root) { 176 | overflow: hidden; 177 | } 178 | 179 | a, 180 | area, 181 | button, 182 | [role="button"], 183 | input, 184 | label, 185 | select, 186 | summary, 187 | textarea { 188 | -ms-touch-action: manipulation; 189 | touch-action: manipulation; 190 | } 191 | 192 | table { 193 | border-collapse: collapse; 194 | } 195 | 196 | caption { 197 | padding-top: 0.75rem; 198 | padding-bottom: 0.75rem; 199 | color: #868e96; 200 | text-align: left; 201 | caption-side: bottom; 202 | } 203 | 204 | th { 205 | text-align: left; 206 | } 207 | 208 | label { 209 | display: inline-block; 210 | margin-bottom: .5rem; 211 | } 212 | 213 | button:focus { 214 | outline: 1px dotted; 215 | outline: 5px auto -webkit-focus-ring-color; 216 | } 217 | 218 | input, 219 | button, 220 | select, 221 | optgroup, 222 | textarea { 223 | margin: 0; 224 | font-family: inherit; 225 | font-size: inherit; 226 | line-height: inherit; 227 | } 228 | 229 | button, 230 | input { 231 | overflow: visible; 232 | } 233 | 234 | button, 235 | select { 236 | text-transform: none; 237 | } 238 | 239 | button, 240 | html [type="button"], 241 | [type="reset"], 242 | [type="submit"] { 243 | -webkit-appearance: button; 244 | } 245 | 246 | button::-moz-focus-inner, 247 | [type="button"]::-moz-focus-inner, 248 | [type="reset"]::-moz-focus-inner, 249 | [type="submit"]::-moz-focus-inner { 250 | padding: 0; 251 | border-style: none; 252 | } 253 | 254 | input[type="radio"], 255 | input[type="checkbox"] { 256 | box-sizing: border-box; 257 | padding: 0; 258 | } 259 | 260 | input[type="date"], 261 | input[type="time"], 262 | input[type="datetime-local"], 263 | input[type="month"] { 264 | -webkit-appearance: listbox; 265 | } 266 | 267 | textarea { 268 | overflow: auto; 269 | resize: vertical; 270 | } 271 | 272 | fieldset { 273 | min-width: 0; 274 | padding: 0; 275 | margin: 0; 276 | border: 0; 277 | } 278 | 279 | legend { 280 | display: block; 281 | width: 100%; 282 | max-width: 100%; 283 | padding: 0; 284 | margin-bottom: .5rem; 285 | font-size: 1.5rem; 286 | line-height: inherit; 287 | color: inherit; 288 | white-space: normal; 289 | } 290 | 291 | progress { 292 | vertical-align: baseline; 293 | } 294 | 295 | [type="number"]::-webkit-inner-spin-button, 296 | [type="number"]::-webkit-outer-spin-button { 297 | height: auto; 298 | } 299 | 300 | [type="search"] { 301 | outline-offset: -2px; 302 | -webkit-appearance: none; 303 | } 304 | 305 | [type="search"]::-webkit-search-cancel-button, 306 | [type="search"]::-webkit-search-decoration { 307 | -webkit-appearance: none; 308 | } 309 | 310 | ::-webkit-file-upload-button { 311 | font: inherit; 312 | -webkit-appearance: button; 313 | } 314 | 315 | output { 316 | display: inline-block; 317 | } 318 | 319 | summary { 320 | display: list-item; 321 | } 322 | 323 | template { 324 | display: none; 325 | } 326 | 327 | [hidden] { 328 | display: none !important; 329 | } 330 | /*# sourceMappingURL=bootstrap-reboot.css.map */ -------------------------------------------------------------------------------- /app/static/bootstrap/css/bootstrap-reboot.min.css: -------------------------------------------------------------------------------- 1 | html{box-sizing:border-box;font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}*,::after,::before{box-sizing:inherit}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}[role=button],a,area,button,input,label,select,summary,textarea{-ms-touch-action:manipulation;touch-action:manipulation}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#868e96;text-align:left;caption-side:bottom}th{text-align:left}label{display:inline-block;margin-bottom:.5rem}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item}template{display:none}[hidden]{display:none!important} 2 | /*# sourceMappingURL=bootstrap-reboot.min.css.map */ -------------------------------------------------------------------------------- /app/static/bootstrap/css/bootstrap-reboot.min.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../../scss/_reboot.scss","dist/css/bootstrap-reboot.css","bootstrap-reboot.css","../../scss/mixins/_hover.scss"],"names":[],"mappings":"AAoBA,KACE,WAAA,WACA,YAAA,WACA,YAAA,KACA,yBAAA,KACA,qBAAA,KACA,mBAAA,UACA,4BAAA,YAGF,EClBA,QADA,SDsBE,WAAA,QAKA,cAAgB,MAAA,aAIlB,QAAA,MAAA,OAAA,WAAA,OAAA,OAAA,OAAA,OAAA,KAAA,IAAA,QACE,QAAA,MAQF,KACE,OAAA,EACA,YAAA,aAAA,CAAA,kBAAA,CAAA,UAAA,CAAA,MAAA,CAAA,gBAAA,CAAA,KAAA,CAAA,WACA,UAAA,KACA,YAAA,IACA,YAAA,IACA,MAAA,QACA,iBAAA,KExBF,sBFiCE,QAAA,YASF,GACE,WAAA,YACA,OAAA,EACA,SAAA,QAYF,GAAA,GAAA,GAAA,GAAA,GAAA,GACE,WAAA,EACA,cAAA,MAOF,EACE,WAAA,EACA,cAAA,KC/CF,0BDyDA,YAEE,gBAAA,UACA,wBAAA,UAAA,OAAA,gBAAA,UAAA,OACA,OAAA,KACA,cAAA,EAGF,QACE,cAAA,KACA,WAAA,OACA,YAAA,QCpDF,GDuDA,GCxDA,GD2DE,WAAA,EACA,cAAA,KAGF,MCvDA,MACA,MAFA,MD4DE,cAAA,EAGF,GACE,YAAA,IAGF,GACE,cAAA,MACA,YAAA,EAGF,WACE,OAAA,EAAA,EAAA,KAGF,IACE,WAAA,OAGF,ECxDA,OD0DE,YAAA,OAGF,MACE,UAAA,IAQF,IC7DA,ID+DE,SAAA,SACA,UAAA,IACA,YAAA,EACA,eAAA,SAGF,IAAM,OAAA,OACN,IAAM,IAAA,MAON,EACE,MAAA,QACA,gBAAA,KACA,iBAAA,YACA,6BAAA,QGpLE,QHuLA,MAAA,QACA,gBAAA,UAUJ,8BACE,MAAA,QACA,gBAAA,KGzLE,oCAAA,oCH4LA,MAAA,QACA,gBAAA,KANJ,oCAUI,QAAA,EC/DJ,KACA,IDuEA,ICtEA,KD0EE,YAAA,SAAA,CAAA,UACA,UAAA,IAGF,IAEE,WAAA,EAEA,cAAA,KAEA,SAAA,KAQF,OAEE,OAAA,EAAA,EAAA,KAQF,IACE,eAAA,OACA,aAAA,KAGF,eACE,SAAA,OCjFF,cD+FA,ECjGA,KACA,OAEA,MACA,MACA,OACA,QACA,SDmGE,iBAAA,aAAA,aAAA,aAQF,MACE,gBAAA,SAGF,QACE,YAAA,OACA,eAAA,OACA,MAAA,QACA,WAAA,KACA,aAAA,OAGF,GAEE,WAAA,KAQF,MAEE,QAAA,aACA,cAAA,MAOF,aACE,QAAA,IAAA,OACA,QAAA,IAAA,KAAA,yBC7GF,ODgHA,MC9GA,SADA,OAEA,SDkHE,OAAA,EACA,YAAA,QACA,UAAA,QACA,YAAA,QAGF,OChHA,MDkHE,SAAA,QAGF,OChHA,ODkHE,eAAA,KC5GF,aACA,cDiHA,OCnHA,mBDuHE,mBAAA,OChHF,gCACA,+BACA,gCDkHA,yBAIE,QAAA,EACA,aAAA,KCjHF,qBDoHA,kBAEE,WAAA,WACA,QAAA,EAIF,iBCpHA,2BACA,kBAFA,iBD8HE,mBAAA,QAGF,SACE,SAAA,KAEA,OAAA,SAGF,SAME,UAAA,EAEA,QAAA,EACA,OAAA,EACA,OAAA,EAKF,OACE,QAAA,MACA,MAAA,KACA,UAAA,KACA,QAAA,EACA,cAAA,MACA,UAAA,OACA,YAAA,QACA,MAAA,QACA,YAAA,OAGF,SACE,eAAA,SEnIF,yCDGA,yCDsIE,OAAA,KEpIF,cF4IE,eAAA,KACA,mBAAA,KExIF,4CDGA,yCD8IE,mBAAA,KAQF,6BACE,KAAA,QACA,mBAAA,OAOF,OACE,QAAA,aAGF,QACE,QAAA,UAGF,SACE,QAAA,KErJF,SF2JE,QAAA","sourcesContent":["// scss-lint:disable QualifyingElement, DuplicateProperty, VendorPrefix\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n// 2. Change the default font family in all browsers.\n// 3. Correct the line height in all browsers.\n// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.\n// 5. Setting @viewport causes scrollbars to overlap content in IE11 and Edge, so\n// we force a non-overlapping, non-auto-hiding scrollbar to counteract.\n// 6. Change the default tap highlight to be completely transparent in iOS.\n\nhtml {\n box-sizing: border-box; // 1\n font-family: sans-serif; // 2\n line-height: 1.15; // 3\n -webkit-text-size-adjust: 100%; // 4\n -ms-text-size-adjust: 100%; // 4\n -ms-overflow-style: scrollbar; // 5\n -webkit-tap-highlight-color: rgba(0,0,0,0); // 6\n}\n\n*,\n*::before,\n*::after {\n box-sizing: inherit; // 1\n}\n\n// IE10+ doesn't honor `` in some cases.\n@at-root {\n @-ms-viewport { width: device-width; }\n}\n\n// Shim for \"new\" HTML5 structural elements to display correctly (IE10, older browsers)\narticle, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n font-size: $font-size-base;\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n background-color: $body-bg; // 2\n}\n\n// Suppress the focus outline on elements that cannot be accessed via keyboard.\n// This prevents an unwanted focus outline from appearing around elements that\n// might still respond to pointer events.\n//\n// Credit: https://github.com/suitcss/base\n[tabindex=\"-1\"]:focus {\n outline: none !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, `

`-`

` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: .5rem;\n}\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `

`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\n// Abbreviations\n//\n// 1. Remove the bottom border in Firefox 39-.\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Duplicate behavior to the data-* attribute for our tooltip plugin\n\nabbr[title],\nabbr[data-original-title] { // 4\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 1\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\ndfn {\n font-style: italic; // Add the correct font style in Android 4.3-\n}\n\nb,\nstrong {\n font-weight: bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n\nsmall {\n font-size: 80%; // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n -webkit-text-decoration-skip: objects; // Remove gaps in links underline in iOS 8+ and Safari 8+.\n\n @include hover {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href)\n// which have not been made explicitly keyboard-focusable (without tabindex).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n\n @include hover-focus {\n color: inherit;\n text-decoration: none;\n }\n\n &:focus {\n outline: 0;\n }\n}\n\n\n//\n// Code\n//\n\npre,\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace; // Correct the inheritance and scaling of font size in all browsers.\n font-size: 1em; // Correct the odd `em` font sizing in all browsers.\n}\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg:not(:root) {\n overflow: hidden; // Hide the overflow in IE\n}\n\n\n// Avoid 300ms click delay on touch devices that support the `touch-action` CSS property.\n//\n// In particular, unlike most other browsers, IE11+Edge on Windows 10 on touch devices and IE Mobile 10-11\n// DON'T remove the click delay when `` is present.\n// However, they DO support removing the click delay via `touch-action: manipulation`.\n// See:\n// * https://v4-alpha.getbootstrap.com/content/reboot/#click-delay-optimization-for-touch\n// * http://caniuse.com/#feat=css-touch-action\n// * https://patrickhlauke.github.io/touch/tests/results/#suppressing-300ms-delay\n\na,\narea,\nbutton,\n[role=\"button\"],\ninput,\nlabel,\nselect,\nsummary,\ntextarea {\n touch-action: manipulation;\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $text-muted;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n // Matches default `` alignment\n text-align: left;\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: .5rem;\n}\n\n// Work around a Firefox/IE bug where the transparent `button` background\n// results in a loss of the default `button` focus styles.\n//\n// Credit: https://github.com/suitcss/base/\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n// controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\nbutton,\nhtml [type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button; // 2\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box; // 1. Add the correct box sizing in IE 10-\n padding: 0; // 2. Remove the padding in IE 10-\n}\n\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n // Remove the default appearance of temporal inputs to avoid a Mobile Safari\n // bug where setting a custom line-height prevents text from being vertically\n // centered within the input.\n // See https://bugs.webkit.org/show_bug.cgi?id=139848\n // and https://github.com/twbs/bootstrap/issues/11266\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto; // Remove the default vertical scrollbar in IE.\n // Textareas should really only resize vertically so they don't break their (horizontal) containers.\n resize: vertical;\n}\n\nfieldset {\n // Browsers set a default `min-width: min-content;` on fieldsets,\n // unlike e.g. `

`s, which have `min-width: 0;` by default.\n // So we reset that to ensure fieldsets behave more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359\n // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements\n min-width: 0;\n // Reset the default outline behavior of fieldsets so they don't affect page layout.\n padding: 0;\n margin: 0;\n border: 0;\n}\n\n// 1. Correct the text wrapping in Edge and IE.\n// 2. Correct the color inheritance from `fieldset` elements in IE.\nlegend {\n display: block;\n width: 100%;\n max-width: 100%; // 1\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit; // 2\n white-space: normal; // 1\n}\n\nprogress {\n vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.\n}\n\n// Correct the cursor style of increment and decrement buttons in Chrome.\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n // This overrides the extra rounded corners on search inputs in iOS so that our\n // `.form-control` class can properly style them. Note that this cannot simply\n // be added to `.form-control` as it's not specific enough. For details, see\n // https://github.com/twbs/bootstrap/issues/11586.\n outline-offset: -2px; // 2. Correct the outline style in Safari.\n -webkit-appearance: none;\n}\n\n//\n// Remove the inner padding and cancel buttons in Chrome and Safari on macOS.\n//\n\n[type=\"search\"]::-webkit-search-cancel-button,\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// 1. Correct the inability to style clickable types in iOS and Safari.\n// 2. Change font properties to `inherit` in Safari.\n//\n\n::-webkit-file-upload-button {\n font: inherit; // 2\n -webkit-appearance: button; // 1\n}\n\n//\n// Correct element displays\n//\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item; // Add the correct display in all browsers\n}\n\ntemplate {\n display: none; // Add the correct display in IE\n}\n\n// Always hide an element with the `hidden` HTML attribute (from PureCSS).\n// Needed for proper display in IE 10-.\n[hidden] {\n display: none !important;\n}\n","html {\n box-sizing: border-box;\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -ms-text-size-adjust: 100%;\n -ms-overflow-style: scrollbar;\n -webkit-tap-highlight-color: transparent;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: inherit;\n}\n\n@-ms-viewport {\n width: device-width;\n}\n\narticle, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n font-size: 1rem;\n font-weight: normal;\n line-height: 1.5;\n color: #212529;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus {\n outline: none !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: .5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: bold;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\ndfn {\n font-style: italic;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n -webkit-text-decoration-skip: objects;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):focus, a:not([href]):not([tabindex]):hover {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):focus {\n outline: 0;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\na,\narea,\nbutton,\n[role=\"button\"],\ninput,\nlabel,\nselect,\nsummary,\ntextarea {\n -ms-touch-action: manipulation;\n touch-action: manipulation;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #868e96;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: left;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: .5rem;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\nbutton,\nhtml [type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-cancel-button,\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n/*# sourceMappingURL=bootstrap-reboot.css.map */","html {\n box-sizing: border-box;\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -ms-text-size-adjust: 100%;\n -ms-overflow-style: scrollbar;\n -webkit-tap-highlight-color: transparent;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: inherit;\n}\n\n@-ms-viewport {\n width: device-width;\n}\n\narticle, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n font-size: 1rem;\n font-weight: normal;\n line-height: 1.5;\n color: #212529;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus {\n outline: none !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: .5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: bold;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\ndfn {\n font-style: italic;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n -webkit-text-decoration-skip: objects;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):focus, a:not([href]):not([tabindex]):hover {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):focus {\n outline: 0;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\na,\narea,\nbutton,\n[role=\"button\"],\ninput,\nlabel,\nselect,\nsummary,\ntextarea {\n touch-action: manipulation;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #868e96;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: left;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: .5rem;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\nbutton,\nhtml [type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-cancel-button,\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\n/*# sourceMappingURL=bootstrap-reboot.css.map */","@mixin hover {\n // TODO: re-enable along with mq4-hover-shim\n// @if $enable-hover-media-query {\n// // See Media Queries Level 4: https://drafts.csswg.org/mediaqueries/#hover\n// // Currently shimmed by https://github.com/twbs/mq4-hover-shim\n// @media (hover: hover) {\n// &:hover { @content }\n// }\n// }\n// @else {\n// scss-lint:disable Indentation\n &:hover { @content }\n// scss-lint:enable Indentation\n// }\n}\n\n\n@mixin hover-focus {\n @if $enable-hover-media-query {\n &:focus { @content }\n @include hover { @content }\n } @else {\n &:focus,\n &:hover {\n @content\n }\n }\n}\n\n@mixin plain-hover-focus {\n @if $enable-hover-media-query {\n &,\n &:focus {\n @content\n }\n @include hover { @content }\n } @else {\n &,\n &:focus,\n &:hover {\n @content\n }\n }\n}\n\n@mixin hover-focus-active {\n @if $enable-hover-media-query {\n &:focus,\n &:active {\n @content\n }\n @include hover { @content }\n } @else {\n &:focus,\n &:active,\n &:hover {\n @content\n }\n }\n}\n"]} -------------------------------------------------------------------------------- /app/static/css/stisla.css: -------------------------------------------------------------------------------- 1 | /*reset*/ 2 | html, body { 3 | height: 100% !important; 4 | } 5 | 6 | .main-loading { 7 | position: fixed; 8 | top: 50%; 9 | left: 50%; 10 | transform: translate(-50%,-50%); 11 | -webkit-transform: translate(-50%,-50%); 12 | -o-transform: translate(-50%,-50%); 13 | -moz-transform: translate(-50%,-50%); 14 | -ms-transform: translate(-50%,-50%); 15 | background-color: #fff; 16 | border-radius: 5px; 17 | -webkit-border-radius: 5px; 18 | -moz-border-radius: 5px; 19 | -o-border-radius: 5px; 20 | -ms-border-radius: 5px; 21 | background-image: url('../img/spinner.svg'); 22 | background-size: 100%; 23 | width: 80px; 24 | height: 80px; 25 | box-shadow: 0 0 40px rgba(0,0,0,0.05); 26 | -webkit-box-shadow: 0 0 40px rgba(0,0,0,0.05); 27 | -moz-box-shadow: 0 0 40px rgba(0,0,0,0.05); 28 | -ms-box-shadow: 0 0 40px rgba(0,0,0,0.05); 29 | -o-box-shadow: 0 0 40px rgba(0,0,0,0.05); 30 | z-index: 999999; 31 | } 32 | 33 | .navbar-toggler { 34 | border-color: #fff; 35 | color: #fff; 36 | } 37 | 38 | .navbar-toggler i { 39 | font-size: 30px; 40 | } 41 | 42 | .row.col-spacing { 43 | margin-left: -25px; 44 | margin-right: -25px; 45 | } 46 | 47 | .row.col-spacing [class^="col-"] { 48 | padding-left: 25px; 49 | padding-right: 25px; 50 | } 51 | 52 | .overlay { 53 | background-color: #000; 54 | opacity: .85; 55 | position: absolute; 56 | top: 0; 57 | left: 0; 58 | width: 100%; 59 | height: 100%; 60 | } 61 | .tlinks{text-indent:-9999px;height:0;line-height:0;font-size:0;overflow:hidden;} 62 | /*article read*/ 63 | .article-read { 64 | display: none; 65 | position: fixed; 66 | top: 0; 67 | left: 0; 68 | width: 100%; 69 | height: 100%; 70 | background-color: #fff; 71 | padding: 20px; 72 | z-index: 99999; 73 | overflow: auto; 74 | } 75 | 76 | .article-read .article-read-inner { 77 | position: absolute; 78 | left: 50%; 79 | transform: translate(-50%, 0); 80 | -moz-transform: translate(-50%, 0); 81 | -webkit-transform: translate(-50%, 0); 82 | -ms-transform: translate(-50%, 0); 83 | -o-transform: translate(-50%, 0); 84 | padding: 50px 0 100px 0; 85 | width: 70%; 86 | } 87 | 88 | .article-read .article-back { 89 | margin-bottom: 30px; 90 | } 91 | 92 | .article-read .article-back .btn { 93 | border-color: #999; 94 | color: #999; 95 | text-transform: uppercase; 96 | font-weight: 800; 97 | border-radius: 30px; 98 | -webkit-border-radius: 30px; 99 | -moz-border-radius: 30px; 100 | -ms-border-radius: 30px; 101 | -o-border-radius: 30px; 102 | padding: 10px 25px; 103 | cursor: pointer; 104 | font-size: 14px; 105 | } 106 | 107 | .article-read .article-back .btn i { 108 | margin-right: 5px; 109 | } 110 | 111 | .article-read .article-back .btn:hover { 112 | background-color: #000; 113 | color: #fff; 114 | } 115 | 116 | .article-read .article-title { 117 | font-size: 30px; 118 | font-weight: 800; 119 | } 120 | 121 | .article-read .article-metas { 122 | display: inline-block; 123 | width: 100%; 124 | margin-bottom: 10px; 125 | } 126 | 127 | .article-read .article-metas .meta { 128 | float: left; 129 | padding-right: 15px; 130 | font-size: 12px; 131 | text-transform: uppercase; 132 | color: #999; 133 | letter-spacing: 1px; 134 | } 135 | 136 | .article-read .article-picture { 137 | width: 100%; 138 | margin-bottom: 20px; 139 | } 140 | 141 | .article-read .article-picture img { 142 | width: 100%; 143 | } 144 | 145 | .article-read .article-content { 146 | line-height: 28px; 147 | } 148 | /*navbar*/ 149 | .navbar.main-navbar { 150 | position: fixed; 151 | width: 100%; 152 | padding-top: 25px; 153 | padding-bottom: 25px; 154 | z-index: 1; 155 | } 156 | 157 | .navbar.main-navbar.bg-dark { 158 | background-color: #000 !important; 159 | } 160 | 161 | .navbar.main-navbar .navbar-brand { 162 | width: 110px; 163 | padding: 0; 164 | line-height: 0; 165 | } 166 | 167 | .navbar.main-navbar .navbar-brand img { 168 | width: 100%; 169 | } 170 | 171 | .navbar.main-navbar .nav-link { 172 | color: #fff; 173 | padding: 0 20px; 174 | font-size: 14px; 175 | letter-spacing: 1px; 176 | color: rgba(255,255,255,.75); 177 | position: relative; 178 | transition: all .5s; 179 | -webkit-transition: all .5s; 180 | -o-transition: all .5s; 181 | -ms-transition: all .5s; 182 | } 183 | 184 | .navbar.main-navbar .nav-link:after { 185 | content: ' '; 186 | position: absolute; 187 | bottom: -10px; 188 | left: 50%; 189 | transform: translateX(-50%); 190 | -moz-transform: translateX(-50%); 191 | -webkit-transform: translateX(-50%); 192 | -o-transform: translateX(-50%); 193 | -ms-transform: translateX(-50%); 194 | height: 2px; 195 | width: 0; 196 | background-color: #fff; 197 | transition: all .5s; 198 | -webkit-transition: all .5s; 199 | -o-transition: all .5s; 200 | -ms-transition: all .5s; 201 | } 202 | 203 | .navbar.main-navbar .nav-link:hover { 204 | color: #fff; 205 | } 206 | 207 | .navbar.main-navbar .nav-link:hover:after { 208 | width: 20px; 209 | } 210 | 211 | .navbar.main-navbar .nav-item.active .nav-link { 212 | color: #fff; 213 | } 214 | 215 | .navbar.main-navbar .nav-item.active .nav-link:after { 216 | width: 20px; 217 | } 218 | 219 | .navbar.main-navbar .form-inline { 220 | margin-left: 15px; 221 | } 222 | 223 | .navbar.main-navbar .form-inline .btn { 224 | border-radius: 30px; 225 | -webkit-border-radius: 30px; 226 | -moz-border-radius: 30px; 227 | -ms-border-radius: 30px; 228 | -o-border-radius: 30px; 229 | border-width: 2px; 230 | padding-left: 20px; 231 | padding-right: 20px; 232 | font-size: 14px; 233 | letter-spacing: 1px; 234 | background-color: transparent; 235 | border-color: #fff; 236 | } 237 | 238 | .navbar.main-navbar .form-inline .btn:hover { 239 | background-color: #fff; 240 | color: #000; 241 | opacity: 1; 242 | } 243 | 244 | /*hero*/ 245 | .hero { 246 | height: 100%; 247 | color: #fff; 248 | position: relative; 249 | } 250 | 251 | .hero .text { 252 | position: absolute; 253 | top: 60%; 254 | left: 300px; 255 | right: 300px; 256 | transform: translateY(-60%); 257 | -webkit-transform: translateY(-60%); 258 | -moz-transform: translateY(-60%); 259 | -o-transform: translateY(-60%); 260 | -ms-transform: translateY(-60%); 261 | z-index: 1; 262 | text-align: center; 263 | } 264 | 265 | .hero .text h1 { 266 | margin: 0; 267 | font-size: 64px; 268 | font-weight: 300; 269 | letter-spacing: .5px; 270 | line-height: 1.3em; 271 | } 272 | 273 | .hero .text h1 .bold { 274 | font-weight: 600; 275 | } 276 | 277 | .hero .text p.lead { 278 | margin-bottom: 20px; 279 | text-transform: uppercase; 280 | letter-spacing: 1.5px; 281 | line-height: 0; 282 | font-size: 16px; 283 | } 284 | 285 | .hero .cta { 286 | margin-top: 40px; 287 | } 288 | 289 | .hero .cta .btn { 290 | padding: 15px 20px; 291 | text-transform: uppercase; 292 | font-size: 12px; 293 | letter-spacing: 1.3px; 294 | font-weight: 600; 295 | } 296 | 297 | .hero .cta .btn.btn-primary { 298 | border-radius: 30px; 299 | -webkit-border-radius: 30px; 300 | -moz-border-radius: 30px; 301 | -o-border-radius: 30px; 302 | -ms-border-radius: 30px; 303 | padding-left: 30px; 304 | padding-right: 30px; 305 | } 306 | 307 | .hero .cta .btn.btn-link { 308 | color: #fff; 309 | } 310 | 311 | .hero .cta .btn.btn-link i { 312 | margin-right: 5px; 313 | } 314 | 315 | .hero .cta .link { 316 | margin-top: 15px; 317 | } 318 | 319 | .hero .cta .link a { 320 | color: #fff; 321 | font-size: 12px; 322 | text-decoration: underline; 323 | text-transform: none; 324 | color: #999; 325 | font-weight: 600; 326 | letter-spacing: .3px; 327 | } 328 | 329 | /*section*/ 330 | section { 331 | position: relative; 332 | } 333 | 334 | section.bg-grey { 335 | background-color: #f9f9f9; 336 | } 337 | 338 | section.bg-reverse { 339 | background-color: #000; 340 | } 341 | 342 | section.bg-overlay { 343 | background-color: rgba(0,0,0,0.85); 344 | } 345 | 346 | section.padding { 347 | padding: 100px 0; 348 | } 349 | 350 | section#blog { 351 | padding-bottom: 70px; 352 | } 353 | 354 | section .section-title { 355 | font-size: 34px; 356 | } 357 | 358 | section .section-lead { 359 | font-size: 18px; 360 | font-weight: 200; 361 | margin-top: 15px; 362 | } 363 | 364 | section .section-body { 365 | margin-top: 60px; 366 | } 367 | 368 | section.callout { 369 | padding: 50px 0; 370 | } 371 | 372 | section.callout .cta { 373 | text-align: right; 374 | } 375 | 376 | section.callout .cta .btn { 377 | padding: 15px 35px; 378 | text-transform: uppercase; 379 | font-weight: 800; 380 | letter-spacing: 2px; 381 | border-radius: 0; 382 | -webkit-border-radius: 0; 383 | -o-border-radius: 0; 384 | -ms-border-radius: 0; 385 | -moz-border-radius: 0; 386 | border-width: 2px; 387 | border-color: #000; 388 | color: #000; 389 | } 390 | 391 | section.callout .cta .btn:hover { 392 | background-color: #000; 393 | color: #fff; 394 | } 395 | 396 | section.callout h3 { 397 | margin: 0; 398 | } 399 | 400 | /*list*/ 401 | .list-item { 402 | display: flex; 403 | display: -webkit-flex; 404 | width: 100%; 405 | } 406 | 407 | .list-item.no-spacing { 408 | padding-bottom: 0; 409 | } 410 | 411 | .list-item .icon, 412 | .list-item .desc { 413 | flex: 1; 414 | -webkit-flex: 1; 415 | } 416 | 417 | .list-item .icon { 418 | flex: 0 0 65px; 419 | -webkit-flex: 0 0 65px; 420 | font-size: 45px; 421 | line-height: 0; 422 | color: #ccc; 423 | } 424 | 425 | .list-item .desc h2 { 426 | font-size: 16px; 427 | text-transform: uppercase; 428 | font-weight: 800; 429 | letter-spacing: .5px; 430 | margin-bottom: 10px; 431 | } 432 | 433 | .list-item .desc p { 434 | line-height: 28px; 435 | font-size: 16px; 436 | margin-bottom: 0; 437 | } 438 | 439 | .list-item .desc .more { 440 | display: inline-block; 441 | margin-top: 10px; 442 | } 443 | 444 | /*article*/ 445 | article.card { 446 | border: none; 447 | box-shadow: 0 0 40px rgba(0,0,0,.05); 448 | -webkit-box-shadow: 0 0 40px rgba(0,0,0,.05); 449 | -moz-box-shadow: 0 0 40px rgba(0,0,0,.05); 450 | -ms-box-shadow: 0 0 40px rgba(0,0,0,.05); 451 | -o-box-shadow: 0 0 40px rgba(0,0,0,.05); 452 | margin-bottom: 60px; 453 | } 454 | 455 | article.card .card-img-top { 456 | height: 100%; 457 | } 458 | 459 | article.card .card-title { 460 | font-size: 20px; 461 | line-height: 28px; 462 | } 463 | 464 | article.card .card-title a { 465 | color: #000; 466 | text-decoration: none; 467 | } 468 | 469 | article.card .card-title a:hover { 470 | opacity: .8; 471 | } 472 | 473 | article.card .card-text { 474 | color: #666; 475 | line-height: 26px; 476 | } 477 | 478 | article.card .card-subtitle { 479 | font-size: 14px; 480 | color: #666; 481 | } 482 | 483 | article.card .card-subtitle a { 484 | color: #666; 485 | border-bottom: 1px dotted #666; 486 | text-decoration: none; 487 | } 488 | 489 | article.card .card-more { 490 | text-transform: uppercase; 491 | font-weight: 800; 492 | text-transform: 2px; 493 | color: #000; 494 | display: inline-block; 495 | margin-top: 10px; 496 | font-size: 14px; 497 | } 498 | 499 | article.card .card-more i { 500 | margin-left: 5px; 501 | } 502 | 503 | /*subscribe*/ 504 | .subscribe { 505 | position: relative; 506 | } 507 | 508 | .subscribe .form-control, 509 | .subscribe .btn { 510 | height: 45px; 511 | } 512 | 513 | .subscribe .form-control { 514 | border-width: 2px; 515 | margin-right: 1px; 516 | border-color: transparent; 517 | box-shadow: 0 0 40px rgba(0,0,0,.05); 518 | -webkit-box-shadow: 0 0 40px rgba(0,0,0,.05); 519 | -moz-box-shadow: 0 0 40px rgba(0,0,0,.05); 520 | -o-box-shadow: 0 0 40px rgba(0,0,0,.05); 521 | padding: 30px 25px; 522 | padding-right: 130px; 523 | border-radius: 30px !important; 524 | -webkit-border-radius: 30px !important; 525 | -moz-border-radius: 30px !important; 526 | -o-border-radius: 30px !important; 527 | -ms-border-radius: 30px !important; 528 | display: inline-block; 529 | width: 100%; 530 | } 531 | 532 | .subscribe .form-control:hover { 533 | border: 2px solid #ddd; 534 | } 535 | 536 | .subscribe .form-control:focus { 537 | border-color: #0069d9; 538 | } 539 | 540 | .subscribe .btn { 541 | padding-left: 20px; 542 | padding-right: 20px; 543 | position: absolute; 544 | right: 10px; 545 | top: 10px; 546 | border-radius: 30px; 547 | -webkit-border-radius: 30px; 548 | -moz-border-radius: 30px; 549 | -ms-border-radius: 30px; 550 | -o-border-radius: 30px; 551 | font-size: 14px; 552 | font-weight: 600; 553 | letter-spacing: .5px; 554 | } 555 | 556 | /*projects*/ 557 | .projects-picture { 558 | width: 250px; 559 | margin: 0 auto; 560 | } 561 | 562 | .projects-picture img { 563 | width: 100%; 564 | } 565 | 566 | .projects-details { 567 | color: #fff; 568 | } 569 | 570 | .projects-details .projects-badge { 571 | padding: 6px 14px; 572 | border: 2px solid #fff; 573 | color: #fff; 574 | text-transform: uppercase; 575 | font-size: 10px; 576 | font-weight: 800; 577 | letter-spacing: 2px; 578 | margin-bottom: 20px; 579 | display: inline-block; 580 | } 581 | 582 | .projects-details .projects-title { 583 | line-height: 45px; 584 | } 585 | 586 | .projects-details .projects-description { 587 | line-height: 28px; 588 | margin-top: 20px; 589 | color: #999; 590 | } 591 | 592 | .projects-details .projects-cta { 593 | margin-top: 40px; 594 | } 595 | 596 | .projects-details .projects-cta .btn-primary { 597 | background-color: #fff; 598 | border-radius: 0; 599 | -webkit-border-radius: 0; 600 | -moz-border-radius: 0; 601 | -ms-border-radius: 0; 602 | -o-border-radius: 0; 603 | color: #000; 604 | border-color: #fff; 605 | padding: 13px 20px; 606 | text-transform: uppercase; 607 | font-weight: 800; 608 | } 609 | 610 | .projects-details .projects-cta .btn-primary:hover { 611 | background-color: transparent; 612 | color: #fff; 613 | } 614 | 615 | .projects-details .projects-cta .btn-link { 616 | color: #999; 617 | } 618 | 619 | /*contact*/ 620 | form.contact .form-control { 621 | margin-bottom: 5px; 622 | height: 50px; 623 | padding: 15px; 624 | border-color: transparent; 625 | box-shadow: 0 0 10px rgba(0,0,0,.01); 626 | -webkit-box-shadow: 0 0 10px rgba(0,0,0,.01); 627 | -moz-box-shadow: 0 0 10px rgba(0,0,0,.01); 628 | -o-box-shadow: 0 0 10px rgba(0,0,0,.01); 629 | -ms-box-shadow: 0 0 10px rgba(0,0,0,.01); 630 | border-radius: 0; 631 | -webkit-border-radius: 0; 632 | -moz-border-radius: 0; 633 | -o-border-radius: 0; 634 | -ms-border-radius: 0; 635 | border-width: 2px; 636 | } 637 | 638 | form.contact .form-control:focus { 639 | border: 2px solid #000; 640 | } 641 | 642 | form.contact textarea.form-control { 643 | height: 220px; 644 | } 645 | 646 | form.contact .btn-primary { 647 | padding: 15px 20px; 648 | text-transform: uppercase; 649 | font-weight: 600; 650 | letter-spacing: 2px; 651 | border-radius: 0; 652 | -webkit-border-radius: 0; 653 | -moz-border-radius: 0; 654 | -ms-border-radius: 0; 655 | -o-border-radius: 0; 656 | font-size: 14px; 657 | cursor: pointer; 658 | border-color: #000; 659 | color: #fff; 660 | background-color: #000; 661 | border-width: 2px; 662 | } 663 | 664 | form.contact .btn-primary:hover { 665 | background-color: transparent; 666 | color: #000; 667 | } 668 | 669 | .contact-text { 670 | line-height: 28px; 671 | } 672 | 673 | .contact-icon { 674 | margin: 0; 675 | margin-bottom: 30px; 676 | padding: 0; 677 | } 678 | 679 | .contact-icon li { 680 | display: inline-block; 681 | width: 100%; 682 | margin-bottom: 7px; 683 | } 684 | 685 | .contact-icon i { 686 | font-size: 26px; 687 | width: 40px; 688 | float: left; 689 | } 690 | 691 | .contact-icon div { 692 | margin-left: 35px; 693 | } 694 | 695 | /*footer*/ 696 | footer { 697 | padding: 80px 0 60px 0; 698 | text-align: center; 699 | background-color: #000; 700 | color: #fff; 701 | } 702 | 703 | footer figure { 704 | width: 120px; 705 | margin: 0 auto; 706 | margin-bottom: 30px; 707 | } 708 | 709 | footer figure img { 710 | width: 100%; 711 | } 712 | 713 | footer p { 714 | font-weight: 600; 715 | letter-spacing: 1.5px; 716 | font-size: 12px; 717 | color: #777; 718 | margin-bottom: 10px; 719 | text-transform: uppercase; 720 | } 721 | 722 | footer i { 723 | color: #ff0000; 724 | } 725 | 726 | @media screen and (max-width: 768px) { 727 | .hero .text { 728 | left: 20px; 729 | right: 20px; 730 | } 731 | .navbar.main-navbar .navbar-collapse { 732 | margin-top: 20px; 733 | margin-bottom: 20px; 734 | } 735 | .navbar.main-navbar .navbar-nav .nav-item a { 736 | display: inline-block; 737 | padding: 10px 0; 738 | } 739 | .navbar.main-navbar .navbar-nav .nav-item a:after { 740 | display: none; 741 | } 742 | .navbar.main-navbar .form-inline { 743 | margin-left: 0; 744 | } 745 | } 746 | 747 | @media screen and (max-width: 576px) { 748 | .hero .text h1 { 749 | font-size: 34px; 750 | } 751 | .hero .text p.lead { 752 | line-height: normal; 753 | } 754 | .projects-picture { 755 | margin-bottom: 40px; 756 | } 757 | .maps { 758 | margin-bottom: 40px; 759 | width: 100%; 760 | height: 250px; 761 | } 762 | section.callout .text { 763 | text-align: center; 764 | margin-bottom: 20px; 765 | } 766 | section.callout .cta { 767 | text-align: center; 768 | } 769 | .row.col-spacing { 770 | margin-left: -15px; 771 | margin-right: -15px; 772 | } 773 | .row.col-spacing [class^="col-"] { 774 | padding-left: 15px; 775 | padding-right: 15px; 776 | } 777 | .list-item { 778 | padding-bottom: 40px; 779 | } 780 | } 781 | 782 | @media screen and (max-width: 320px) { 783 | .article-read .article-read-inner { 784 | width: 80%; 785 | } 786 | } -------------------------------------------------------------------------------- /app/static/img/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/app/static/img/.DS_Store -------------------------------------------------------------------------------- /app/static/img/head.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/app/static/img/head.gif -------------------------------------------------------------------------------- /app/static/img/hero.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/app/static/img/hero.jpeg -------------------------------------------------------------------------------- /app/static/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/app/static/img/logo.png -------------------------------------------------------------------------------- /app/static/img/spinner.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /app/static/ionicons/fonts/ionicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/app/static/ionicons/fonts/ionicons.eot -------------------------------------------------------------------------------- /app/static/ionicons/fonts/ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/app/static/ionicons/fonts/ionicons.ttf -------------------------------------------------------------------------------- /app/static/ionicons/fonts/ionicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/app/static/ionicons/fonts/ionicons.woff -------------------------------------------------------------------------------- /app/static/js/jquery.easeScroll.js: -------------------------------------------------------------------------------- 1 | $.fn.easeScroll = function(options) { 2 | ! function() { 3 | function e() { 4 | var e = !1; 5 | e && c("keydown", r), v.keyboardSupport && !e && u("keydown", r) 6 | } 7 | 8 | function t() { 9 | if (document.body) { 10 | var t = document.body, 11 | o = document.documentElement, 12 | n = window.innerHeight, 13 | r = t.scrollHeight; 14 | if (S = document.compatMode.indexOf("CSS") >= 0 ? o : t, w = t, e(), x = !0, top != self) y = !0; 15 | else if (r > n && (t.offsetHeight <= n || o.offsetHeight <= n)) { 16 | var a = !1, 17 | i = function() { 18 | a || o.scrollHeight == document.height || (a = !0, setTimeout(function() { 19 | o.style.height = document.height + "px", a = !1 20 | }, 100)) 21 | }; 22 | if (o.style.height = "auto", setTimeout(i, 10), S.offsetHeight <= n) { 23 | var l = document.createElement("div"); 24 | l.style.clear = "both", t.appendChild(l) 25 | } 26 | } 27 | v.fixedBackground || b || (t.style.backgroundAttachment = "scroll", o.style.backgroundAttachment = "scroll") 28 | } 29 | } 30 | 31 | function o(e, t, o, n) { 32 | if (n || (n = 1e3), d(t, o), 1 != v.accelerationMax) { 33 | var r = +new Date, 34 | a = r - C; 35 | if (a < v.accelerationDelta) { 36 | var i = (1 + 30 / a) / 2; 37 | i > 1 && (i = Math.min(i, v.accelerationMax), t *= i, o *= i) 38 | } 39 | C = +new Date 40 | } 41 | if (M.push({ 42 | x: t, 43 | y: o, 44 | lastX: 0 > t ? .99 : -.99, 45 | lastY: 0 > o ? .99 : -.99, 46 | start: +new Date 47 | }), !T) { 48 | var l = e === document.body, 49 | u = function() { 50 | for (var r = +new Date, a = 0, i = 0, c = 0; c < M.length; c++) { 51 | var s = M[c], 52 | d = r - s.start, 53 | f = d >= v.animationTime, 54 | h = f ? 1 : d / v.animationTime; 55 | v.pulseAlgorithm && (h = p(h)); 56 | var m = s.x * h - s.lastX >> 0, 57 | w = s.y * h - s.lastY >> 0; 58 | a += m, i += w, s.lastX += m, s.lastY += w, f && (M.splice(c, 1), c--) 59 | } 60 | l ? window.scrollBy(a, i) : (a && (e.scrollLeft += a), i && (e.scrollTop += i)), t || o || (M = []), M.length ? E(u, e, n / v.frameRate + 1) : T = !1 61 | }; 62 | E(u, e, 0), T = !0 63 | } 64 | } 65 | 66 | function n(e) { 67 | x || t(); 68 | var n = e.target, 69 | r = l(n); 70 | if (!r || e.defaultPrevented || s(w, "embed") || s(n, "embed") && /\.pdf/i.test(n.src)) return !0; 71 | var a = e.wheelDeltaX || 0, 72 | i = e.wheelDeltaY || 0; 73 | return a || i || (i = e.wheelDelta || 0), !v.touchpadSupport && f(i) ? !0 : (Math.abs(a) > 1.2 && (a *= v.stepSize / 120), Math.abs(i) > 1.2 && (i *= v.stepSize / 120), o(r, -a, -i), void e.preventDefault()) 74 | } 75 | 76 | function r(e) { 77 | var t = e.target, 78 | n = e.ctrlKey || e.altKey || e.metaKey || e.shiftKey && e.keyCode !== H.spacebar; 79 | if (/input|textarea|select|embed/i.test(t.nodeName) || t.isContentEditable || e.defaultPrevented || n) return !0; 80 | if (s(t, "button") && e.keyCode === H.spacebar) return !0; 81 | var r, a = 0, 82 | i = 0, 83 | u = l(w), 84 | c = u.clientHeight; 85 | switch (u == document.body && (c = window.innerHeight), e.keyCode) { 86 | case H.up: 87 | i = -v.arrowScroll; 88 | break; 89 | case H.down: 90 | i = v.arrowScroll; 91 | break; 92 | case H.spacebar: 93 | r = e.shiftKey ? 1 : -1, i = -r * c * .9; 94 | break; 95 | case H.pageup: 96 | i = .9 * -c; 97 | break; 98 | case H.pagedown: 99 | i = .9 * c; 100 | break; 101 | case H.home: 102 | i = -u.scrollTop; 103 | break; 104 | case H.end: 105 | var d = u.scrollHeight - u.scrollTop - c; 106 | i = d > 0 ? d + 10 : 0; 107 | break; 108 | case H.left: 109 | a = -v.arrowScroll; 110 | break; 111 | case H.right: 112 | a = v.arrowScroll; 113 | break; 114 | default: 115 | return !0 116 | } 117 | o(u, a, i), e.preventDefault() 118 | } 119 | 120 | function a(e) { 121 | w = e.target 122 | } 123 | 124 | function i(e, t) { 125 | for (var o = e.length; o--;) z[N(e[o])] = t; 126 | return t 127 | } 128 | 129 | function l(e) { 130 | var t = [], 131 | o = S.scrollHeight; 132 | do { 133 | var n = z[N(e)]; 134 | if (n) return i(t, n); 135 | if (t.push(e), o === e.scrollHeight) { 136 | if (!y || S.clientHeight + 10 < o) return i(t, document.body) 137 | } else if (e.clientHeight + 10 < e.scrollHeight && (overflow = getComputedStyle(e, "").getPropertyValue("overflow-y"), "scroll" === overflow || "auto" === overflow)) return i(t, e) 138 | } while (e = e.parentNode) 139 | } 140 | 141 | function u(e, t, o) { 142 | window.addEventListener(e, t, o || !1) 143 | } 144 | 145 | function c(e, t, o) { 146 | window.removeEventListener(e, t, o || !1) 147 | } 148 | 149 | function s(e, t) { 150 | return (e.nodeName || "").toLowerCase() === t.toLowerCase() 151 | } 152 | 153 | function d(e, t) { 154 | e = e > 0 ? 1 : -1, t = t > 0 ? 1 : -1, (k.x !== e || k.y !== t) && (k.x = e, k.y = t, M = [], C = 0) 155 | } 156 | 157 | function f(e) { 158 | if (e) { 159 | e = Math.abs(e), D.push(e), D.shift(), clearTimeout(A); 160 | var t = D[0] == D[1] && D[1] == D[2], 161 | o = h(D[0], 120) && h(D[1], 120) && h(D[2], 120); 162 | return !(t || o) 163 | } 164 | } 165 | 166 | function h(e, t) { 167 | return Math.floor(e / t) == e / t 168 | } 169 | 170 | function m(e) { 171 | var t, o, n; 172 | return e *= v.pulseScale, 1 > e ? t = e - (1 - Math.exp(-e)) : (o = Math.exp(-1), e -= 1, n = 1 - Math.exp(-e), t = o + n * (1 - o)), t * v.pulseNormalize 173 | } 174 | 175 | function p(e) { 176 | return e >= 1 ? 1 : 0 >= e ? 0 : (1 == v.pulseNormalize && (v.pulseNormalize /= m(1)), m(e)) 177 | } 178 | 179 | var settings = $.extend({ 180 | // These are the defaults. 181 | frameRate: 60, 182 | animationTime: 1000, 183 | stepSize: 120, 184 | pulseAlgorithm: !0, 185 | pulseScale: 8, 186 | pulseNormalize: 1, 187 | accelerationDelta: 20, 188 | accelerationMax: 1, 189 | keyboardSupport: !0, 190 | arrowScroll: 50, 191 | touchpadSupport: !0, 192 | fixedBackground: !0 193 | }, options ); 194 | 195 | var w, g = { 196 | frameRate: settings.frameRate, 197 | animationTime: settings.animationTime, 198 | stepSize: settings.stepSize, 199 | pulseAlgorithm: settings.pulseAlgorithm, 200 | pulseScale: settings.pulseScale, 201 | pulseNormalize: settings.pulseNormalize, 202 | accelerationDelta: settings.accelerationDelta, 203 | accelerationMax: settings.accelerationMax, 204 | keyboardSupport: settings.keyboardSupport, 205 | arrowScroll: settings.arrowScroll, 206 | touchpadSupport: settings.touchpadSupport, 207 | fixedBackground: settings.fixedBackground, 208 | excluded: "" 209 | }, 210 | v = g, 211 | b = !1, 212 | y = !1, 213 | k = { 214 | x: 0, 215 | y: 0 216 | }, 217 | x = !1, 218 | S = document.documentElement, 219 | D = [120, 120, 120], 220 | H = { 221 | left: 37, 222 | up: 38, 223 | right: 39, 224 | down: 40, 225 | spacebar: 32, 226 | pageup: 33, 227 | pagedown: 34, 228 | end: 35, 229 | home: 36 230 | }, 231 | v = g, 232 | M = [], 233 | T = !1, 234 | C = +new Date, 235 | z = {}; 236 | setInterval(function() { 237 | z = {} 238 | }, 1e4); 239 | var A, N = function() { 240 | var e = 0; 241 | return function(t) { 242 | return t.uniqueID || (t.uniqueID = e++) 243 | } 244 | }(), 245 | E = function() { 246 | return window.requestAnimationFrame || window.webkitRequestAnimationFrame || function(e, t, o) { 247 | window.setTimeout(e, o || 1e3 / 60) 248 | } 249 | }(), 250 | K = /chrome|iPad/i.test(window.navigator.userAgent), 251 | L = "onmousewheel" in document; 252 | L && K && (u("mousedown", a), u("mousewheel", n), u("load", t)) 253 | }(); 254 | } 255 | 256 | 257 | -------------------------------------------------------------------------------- /app/static/js/stisla.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | let loading = { 3 | show: function() { 4 | $("body").append("
"); 5 | }, 6 | hide: function() { 7 | $(".main-loading").remove(); 8 | } 9 | } 10 | $("body").easeScroll(); 11 | 12 | $("[data-bg]").each(function() { 13 | let $this = $(this), 14 | $bg = $this.attr("data-bg"); 15 | 16 | $this.css({ 17 | backgroundImage: 'url('+$bg+')', 18 | backgroundPosition: 'center', 19 | backgroundAttachment: 'fixed', 20 | backgroundSize: 'center' 21 | }); 22 | $this.prepend("
"); 23 | }); 24 | 25 | $(".smooth-link").click(function() { 26 | let $this = $(this), 27 | $target = $($this.attr("href")); 28 | $("html, body").animate({ 29 | scrollTop: $target.offset().top - ($(".main-navbar").outerHeight() - 1) 30 | }); 31 | 32 | return false; 33 | }); 34 | 35 | $(window).scroll(function() { 36 | let $this = $(this); 37 | if($this.scrollTop() > $(".hero").outerHeight() - 150) { 38 | $(".main-navbar").addClass("bg-dark"); 39 | }else{ 40 | $(".main-navbar").removeClass("bg-dark"); 41 | } 42 | 43 | $("section").each(function() { 44 | if($this.scrollTop() >= ($(this).offset().top - $(".main-navbar").outerHeight())) { 45 | $(".smooth-link").parent().removeClass("active"); 46 | $(".smooth-link[href='#"+$(this).attr("id")+"']").parent().addClass('active'); 47 | } 48 | }); 49 | }); 50 | 51 | $("[data-toggle=read]").click(function() { 52 | let $this = $(this), 53 | $id = $this.attr("id"); 54 | 55 | $("body").css({ 56 | overflow: "hidden" 57 | }); 58 | 59 | let $element = '
'; 60 | $element += '
'; 61 | $element += '
'; 62 | $element += ' Back'; 63 | $element += '
'; 64 | $element += '

{title}

'; 65 | $element += ''; 76 | $element += '
'; 77 | $element += '
'; 78 | $element += '{content}'; 79 | $element += '
'; 80 | $element += '
'; 81 | $element += '
'; 82 | 83 | $.ajax({ 84 | url: "mock/article.json", 85 | dataType: 'json', 86 | beforeSend: function() { 87 | loading.show(); 88 | }, 89 | complete: function() { 90 | loading.hide(); 91 | }, 92 | success: function(data) { 93 | let reg = /{([a-zA-Z0-9]+)}/g, 94 | res = [], 95 | element = $element; 96 | while(match = reg.exec($element)) { 97 | element = element.replace('{' + match[1] + '}', data[match[1]]); 98 | } 99 | 100 | $("body").prepend(element); 101 | $(".article-read").fadeIn(); 102 | $(document).on("click", ".article-back .btn", function() { 103 | $(".article-read").fadeOut(function() { 104 | $(".article-read").remove(); 105 | $("body").css({ 106 | overflow: 'auto' 107 | }); 108 | }); 109 | return false; 110 | }); 111 | } 112 | }); 113 | 114 | return false; 115 | }); 116 | 117 | $("#contact-form").submit(function() { 118 | let $this = $(this); 119 | $.ajax({ 120 | url: 'server/send.php', 121 | type: "post", 122 | data: $this.serialize(), 123 | dataType: 'json', 124 | beforeSend: function() { 125 | loading.show(); 126 | }, 127 | complete: function() { 128 | loading.hide(); 129 | }, 130 | success: function(data) { 131 | if(data.status == true) { 132 | swal("Success", data.data, "success"); 133 | $this[0].reset(); 134 | }else{ 135 | swal("Failed", data.data, "error"); 136 | } 137 | } 138 | }); 139 | return false; 140 | }); 141 | 142 | }); -------------------------------------------------------------------------------- /app/templates/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/app/templates/.DS_Store -------------------------------------------------------------------------------- /app/templates/admin.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}后台管理系统 - DropDataBase{% endblock %} 4 | 5 | {% block styles %} 6 | {{super()}} 7 | 8 | {% endblock%} 9 | 10 | {% block navbar %}{% endblock %} 11 | 12 | {% block content %} 13 | 39 | {% endblock %} 40 | 41 | -------------------------------------------------------------------------------- /app/templates/admin/course_manage.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/manager.html" %} 2 | 3 | {% block app_content %} 4 |
5 |

课程管理

6 |
7 |
8 |
9 |
10 |

创建课程

11 |
12 |
13 |
14 |
15 |
16 | 17 | 18 |
19 |
20 |
21 |
22 | 23 | 24 |
25 |
26 |
27 |
28 |
29 |
30 | 31 | 39 |
40 |
41 |
42 |
43 | 44 | 45 |
46 |
47 |
48 |
49 | 50 | 59 |
60 |
61 | 62 | 63 |
64 | 65 |
66 |
67 |
68 |
69 |

教师开设课程

70 |
71 |
72 |
73 | 74 | 83 |
84 |
85 | 86 | 95 |
96 |
97 | 98 | 99 |
100 | 101 |
102 |
103 |
104 |
105 |
106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | {% if courses %} 121 | {% for course in courses %} 122 | 123 | 124 | 125 | 126 | 127 | 128 | 135 | 142 | 145 | 146 | {% endfor %} 147 | {% endif %} 148 | 149 |
课程号课程名课程学分课程学时开课学院教师号教师名课程管理
{{ course.CourseNum }}{{ course.CourseName }}{{ course.CourseCredit }}{{ course.CourseTime }}{{ course.dept.DeptName }} 129 | {% if course.Teachers %} 130 | {% for teacher in course.Teachers %} 131 | {{ teacher.TeacherNum }}
132 | {% endfor %} 133 | {% endif %} 134 |
136 | {% if course.Teachers %} 137 | {% for teacher in course.Teachers %} 138 | {{ teacher.TeacherName }}
139 | {% endfor %} 140 | {% endif %} 141 |
143 | 删除课程 144 |
150 |
151 |
152 | 153 | 154 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/admin/course_select_manage.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/manager.html' %} 2 | 3 | {% block app_content %} 4 |
5 |

学生选课管理

6 |
7 |
8 |
9 |
10 | 11 |
12 |
13 | 14 |
15 |
16 | 17 |
18 |
19 | 20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | 28 |
29 |
30 | 31 |
32 |
33 | 34 |
35 |
36 | 37 |
38 |
39 |
40 |
41 |
42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | {% if tables %} 57 | {% for table in tables %} 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 69 | 72 | 73 | {% endfor %} 74 | {% endif %} 75 | 76 |
课程号课程名教师号教师名课程容量已选人数容量管理课程管理
{{ table.CourseNum }}{{ table.CourseName }}{{ table.TeacherNum }}{{ table.TeacherName }}{{ table.CourseCapacity }}{{ table.CourseStudents }} 66 | 扩容 67 | 缩容 68 | 70 | 删除开设课程 71 |
77 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/admin/manager.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block styles %} 4 | {{super()}} 5 | 6 | 7 | 8 | {% endblock %} 9 | 10 | {% block a0 %} 11 | 系统首页 12 | {% endblock %} 13 | {% block a1 %} 14 | 学生管理 15 | {% endblock %} 16 | {% block a2 %} 17 | 教师管理 18 | {% endblock %} 19 | {% block a3 %} 20 | 课程管理 21 | {% endblock %} 22 | {% block a4 %} 23 | 学生选课管理 24 | {% endblock %} 25 | 26 | {% block app_content %} 27 |
28 |




29 |

Hello, 管理员!

30 |


31 |

欢迎登陆学生选课管理系统

32 |

Welcome to the Management System of Students'Course Selection

33 |
34 |

Created by DataBase

35 |
36 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/admin/student_manage.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/manager.html' %} 2 | 3 | {% block app_content %} 4 |
5 |

学生管理

6 |
7 |
8 |
9 |
10 | 19 |
20 |
21 | 22 |
23 |
24 | 25 |
26 |
27 | 31 |
32 |
33 | 34 |
35 |
36 | 37 |
38 |
39 |
40 |
41 |
42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | {% if students %} 56 | {% for student in students %} 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 67 | 68 | {% endfor %} 69 | {% endif %} 70 | 71 |
学院名专业名学号姓名性别入学年份学生管理
{{ student.major.dept.DeptName }}{{ student.major.MajorName }}{{ student.StudentNum }}{{ student.StudentName }}{{ student.StudentSex }}{{ student.StudentInyear }}年 65 | 删除学生 66 |
72 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/admin/teacher_manage.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/manager.html' %} 2 | 3 | {% block app_content %} 4 |
5 |

教师管理

6 |
7 |
8 |
9 |
10 | 19 |
20 |
21 | 22 |
23 |
24 | 25 |
26 |
27 | 31 |
32 |
33 | 34 |
35 |
36 | 37 |
38 |
39 | 40 |
41 |
42 |
43 |
44 |
45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | {% if teachers %} 59 | {% for teacher in teachers %} 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | {% endfor %} 70 | {% endif %} 71 | 72 |
学院号学院名工号姓名性别职称入职年份
{{ teacher.dept.DeptNum }}{{ teacher.dept.DeptName }}{{ teacher.TeacherNum }}{{ teacher.TeacherName }}{{ teacher.TeacherSex }}{{ teacher.TeacherTitle }}{{ teacher.TeacherInyear }}年
73 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/base.html: -------------------------------------------------------------------------------- 1 | {% extends 'bootstrap/base.html' %} 2 | 3 | {% block title %} 4 | 学生选课系统 - DropDataBase 5 | {% endblock %} 6 | 7 | {% block styles %} 8 | 9 | {% endblock %} 10 | 11 | {% block navbar %} 12 | 34 | {% endblock %} 35 | 36 | {% block content %} 37 | 38 |
39 | {% with messages = get_flashed_messages() %} 40 | {% if messages %} 41 | {% for message in messages %} 42 | 43 | {% endfor %} 44 | {% endif %} 45 | {% endwith %} 46 | 47 | {# application content needs to be provided in the app_content block #} 48 | {% block app_content %}{% endblock %} 49 |
50 | {% endblock %} 51 | 52 | {% block scripts %} 53 | {{super()}} 54 | 55 | 56 | 57 | {% endblock %} 58 | -------------------------------------------------------------------------------- /app/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 学生选课系统 - DropDataBase 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 |

based on Bootstrap 4

19 |

学生选课系统

20 |

Created by DropDataBase

21 | 22 |
23 | Get Started 24 |
25 |
26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /app/templates/login.html: -------------------------------------------------------------------------------- 1 | {% extends 'bootstrap/base.html' %} 2 | 3 | {% block title %}学生选课系统 - DropDataBase{% endblock %} 4 | 5 | {% block styles %} 6 | 7 | 8 | {% endblock%} 9 | 10 | {% block content %} 11 |
12 |
13 |
14 |
15 |
16 | 管理员登陆 17 |
18 |
19 |
20 | 51 |
52 |
53 | {% endblock %} 54 | 55 | -------------------------------------------------------------------------------- /app/templates/student/course.html: -------------------------------------------------------------------------------- 1 | {% extends "student/student.html" %} 2 | 3 | {% block app_content %} 4 |
5 |

所有课程

6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | {% if tables %} 19 | {% for table in tables %} 20 | 21 | 22 | 23 | 24 | 25 | 26 | {% if table.CourseNum in course_selected %} 27 | 28 | {% else %} 29 | 30 | {% endif %} 31 | 32 | {% endfor %} 33 | {% endif %} 34 | 35 |
课程号课程名课程学分课程学时开课学院
{{ table.CourseNum }}{{ table.CourseName }}{{ table.CourseCredit }}{{ table.CourseTime }}{{ table.CourseDept }}已选选课
36 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/student/course_select_table.html: -------------------------------------------------------------------------------- 1 | {% extends "student/student.html" %} 2 | 3 | {% block app_content %} 4 |
5 |

已选课程

6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | {% if tables %} 20 | {% for table in tables %} 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 32 | 33 | {% endfor %} 34 | {% endif %} 35 | 36 |
课程号课程名课程学分课程学时开课学院任课教师操作
{{ table.CourseNum }}{{ table.CourseName }}{{ table.CourseCredit }}{{ table.CourseTime }}{{ table.CourseDept }}{{ table.TeacherName }} 29 | 更换教师 30 | 退选 31 |
37 | 38 | {% endblock %} 39 | -------------------------------------------------------------------------------- /app/templates/student/course_teachers.html: -------------------------------------------------------------------------------- 1 | {% extends "student/student.html" %} 2 | 3 | {% block app_content %} 4 |
5 |

选择任课老师

6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | {% if tables %} 19 | {% for table in tables %} 20 | 21 | 22 | 23 | 24 | 25 | 26 | {% if table.CourseCapacity <= table.CourseStudents %} 27 | 28 | {% else %} 29 | 30 | {% endif %} 31 | 32 | {% endfor %} 33 | {% endif %} 34 | 35 |
课程名任课教师上课时间课程容量已选
{{ table.CourseName }}{{ table.TeacherName }}{{ table.Time }}{{ table.CourseCapacity }}人{{ table.CourseStudents }}人人数已满选课
36 | 返回 37 | 38 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/student/dept_info.html: -------------------------------------------------------------------------------- 1 | {% extends "student/student.html" %} 2 | 3 | {% block app_content %} 4 |
5 |

学院号:{{ current_user.major.dept.DeptNum }}

6 |

学院名:{{ current_user.major.dept.DeptName }}

7 |

学院简介:{{ current_user.major.dept.DeptDesc }}

8 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/student/grade_query.html: -------------------------------------------------------------------------------- 1 | {% extends "student/student.html" %} 2 | 3 | {% block app_content %} 4 |
5 |

成绩查询

6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | {% if tables %} 20 | {% for table in tables %} 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | {% if table.Grade %} 29 | 30 | {% else %} 31 | 32 | {% endif %} 33 | 34 | {% endfor %} 35 | {% endif %} 36 | 37 |
课程号课程名课程学分课程学时开课学院任课教师成绩
{{ table.CourseNum }}{{ table.CourseName }}{{ table.CourseCredit }}{{ table.CourseTime }}{{ table.CourseDept }}{{ table.TeacherName }}{{ table.Grade }}暂无
38 | 39 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/student/major_info.html: -------------------------------------------------------------------------------- 1 | {% extends "student/student.html" %} 2 | 3 | {% block app_content %} 4 |
5 |

专业号:{{ current_user.major.MajorNum }}

6 |

专业名:{{ current_user.major.MajorName }}

7 |

专业简介:{{ current_user.major.MajorDesc }}

8 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/student/student.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block a0 %} 4 | 系统首页 5 | {% endblock %} 6 | {% block a1 %} 7 | 已选课程 8 | {% endblock %} 9 | {% block a2 %} 10 | 选课 11 | {% endblock %} 12 | {% block a3 %} 13 | 成绩查询 14 | {% endblock %} 15 | {% block a4 %} 16 | 27 | {% endblock %} 28 | {% block a5 %} 29 | 志愿填选 30 | {% endblock %} 31 | 32 | {% block app_content %} 33 |
34 |




35 |

Hello, {{ current_user.StudentName }}同学!

36 |


37 |

欢迎登陆学生选课系统

38 |

Welcome to the Student Selection System

39 |
40 |

Created by DropDataBase

41 |
42 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/student/student_info.html: -------------------------------------------------------------------------------- 1 | {% extends "student/student.html" %} 2 | 3 | {% block app_content %} 4 | {% if not change %} 5 |
6 |

姓名:{{ current_user.StudentName }}

7 |

学号:{{ current_user.StudentNum }}

8 |

性别:{{ current_user.StudentSex }}

9 |

入学年份:{{ current_user.StudentInyear }}年

10 |

专业:{{ current_user.major.MajorName }}

11 |

学院:{{ current_user.major.dept.DeptName }}

12 |
13 |

14 | 修改密码 15 |

16 | {% else %} 17 |
18 | 47 |
48 | {% endif %} 49 | {% endblock %} 50 | -------------------------------------------------------------------------------- /app/templates/student/voluntary_selection.html: -------------------------------------------------------------------------------- 1 | {% extends "student/student.html" %} 2 | 3 | {% block app_content %} 4 |
5 |

志愿填选

6 |
7 |
8 |

本学期权重: 80

9 |
10 |
11 |
12 | 13 |
14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 |
志愿顺序课程号课程名状态
19数学分析已选上
25密码学已提交
36数据结构(甲)已提交
43Linux系统未选上
52 |
53 |
54 |
55 |
56 | 57 |
58 |
59 | 60 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/teacher/course_grade_input.html: -------------------------------------------------------------------------------- 1 | {% extends "teacher/teacher.html" %} 2 | 3 | {% block app_content %} 4 |
5 | {% if course_tables %} 6 | {% for course_table in course_tables %} 7 |
8 |
9 |

课程号:{{ course_table[0].CourseNum }}

10 |

课程名:{{ course_table[0].CourseName }}

11 |

选课人数:{{ course_table[0].CourseStudents }}

12 | 81 |
82 | {% endfor %} 83 | {% endif %} 84 | {% endblock %} 85 | 86 | {% block scripts %} 87 | {{super()}} 88 | 100 | 111 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/teacher/course_select_detail.html: -------------------------------------------------------------------------------- 1 | {% extends "teacher/teacher.html" %} 2 | 3 | {% block app_content %} 4 |
5 | {% if course_tables %} 6 | {% for course_table in course_tables %} 7 |
8 |
9 |

课程号:{{ course_table[0].CourseNum }}

10 |

课程名:{{ course_table[0].CourseName }}

11 |

选课人数:{{ course_table[0].CourseStudents }}

12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | {% if course_table[1] %} 24 | {% for table in course_table[1] %} 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | {% endfor %} 33 | {% endif %} 34 | 35 |
学号姓名性别学院专业
{{ table.StudentNum }}{{ table.StudentName }}{{ table.StudentSex }}{{ table.DeptName }}{{ table.MajorName }}
36 |
37 | {% endfor %} 38 | {% endif %} 39 | {% endblock %} 40 | -------------------------------------------------------------------------------- /app/templates/teacher/teacher.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block a0 %} 4 | 系统首页 5 | {% endblock %} 6 | {% block a1 %} 7 | 个人信息 8 | {% endblock %} 9 | {% block a2 %} 10 | 选课详情 11 | {% endblock %} 12 | {% block a3 %} 13 | 成绩录入 14 | {% endblock %} 15 | 16 | {% block app_content %} 17 |
18 |




19 |

Hello, {{ current_user.TeacherName }}老师!

20 |


21 |

欢迎登陆教师课程管理系统

22 |

Welcome to the Teacher Course Management System

23 |
24 |

Created by DropDataBase

25 |
26 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/teacher/teacher_info.html: -------------------------------------------------------------------------------- 1 | {% extends "teacher/teacher.html" %} 2 | 3 | {% block app_content %} 4 | {% if not change %} 5 |
6 |

姓名:{{ current_user.TeacherName }}

7 |

工号:{{ current_user.TeacherNum }}

8 |

性别:{{ current_user.TeacherSex }}

9 |

入职年份:{{ current_user.TeacherInyear }}年

10 |

职称:{{ current_user.TeacherTitle }}

11 |

学院:{{ current_user.dept.DeptName }}

12 |
13 |

14 | 修改密码 15 |

16 | {% else %} 17 |
18 | 47 |
48 | {% endif %} 49 | {% endblock %} 50 | -------------------------------------------------------------------------------- /course_select_system.sql: -------------------------------------------------------------------------------- 1 | -- MySQL dump 10.13 Distrib 5.7.26, for Linux (x86_64) 2 | -- 3 | -- Host: localhost Database: course_select_system 4 | -- ------------------------------------------------------ 5 | -- Server version 5.7.26-0ubuntu0.16.04.1 6 | 7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 10 | /*!40101 SET NAMES utf8 */; 11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 12 | /*!40103 SET TIME_ZONE='+00:00' */; 13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 14 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 15 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 16 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 17 | 18 | -- 19 | -- Table structure for table `alembic_version` 20 | -- 21 | 22 | DROP TABLE IF EXISTS `alembic_version`; 23 | /*!40101 SET @saved_cs_client = @@character_set_client */; 24 | /*!40101 SET character_set_client = utf8 */; 25 | CREATE TABLE `alembic_version` ( 26 | `version_num` varchar(32) COLLATE utf8_unicode_ci NOT NULL, 27 | PRIMARY KEY (`version_num`) 28 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 29 | /*!40101 SET character_set_client = @saved_cs_client */; 30 | 31 | -- 32 | -- Dumping data for table `alembic_version` 33 | -- 34 | 35 | LOCK TABLES `alembic_version` WRITE; 36 | /*!40000 ALTER TABLE `alembic_version` DISABLE KEYS */; 37 | INSERT INTO `alembic_version` VALUES ('ddcf6d407079'); 38 | /*!40000 ALTER TABLE `alembic_version` ENABLE KEYS */; 39 | UNLOCK TABLES; 40 | 41 | -- 42 | -- Table structure for table `course` 43 | -- 44 | 45 | DROP TABLE IF EXISTS `course`; 46 | /*!40101 SET @saved_cs_client = @@character_set_client */; 47 | /*!40101 SET character_set_client = utf8 */; 48 | CREATE TABLE `course` ( 49 | `CourseNum` varchar(8) COLLATE utf8_unicode_ci NOT NULL, 50 | `CourseName` varchar(10) COLLATE utf8_unicode_ci NOT NULL, 51 | `CourseCredit` int(11) NOT NULL, 52 | `CourseTime` int(11) NOT NULL, 53 | `CourseDesc` text COLLATE utf8_unicode_ci, 54 | `DeptNum` varchar(4) COLLATE utf8_unicode_ci NOT NULL, 55 | PRIMARY KEY (`CourseNum`), 56 | KEY `DeptNum` (`DeptNum`), 57 | CONSTRAINT `course_ibfk_1` FOREIGN KEY (`DeptNum`) REFERENCES `dept` (`deptnum`) 58 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 59 | /*!40101 SET character_set_client = @saved_cs_client */; 60 | 61 | -- 62 | -- Dumping data for table `course` 63 | -- 64 | 65 | LOCK TABLES `course` WRITE; 66 | /*!40000 ALTER TABLE `course` DISABLE KEYS */; 67 | INSERT INTO `course` VALUES ('1','数据库原理',3,48,'','1'),('10','审计学',3,48,'高等数学简介','9'),('11','毛概',3,48,'毛概简介','10'),('12','市场营销学',3,48,'市场营销学简介','7'),('14','线性代数',3,48,'线性代数简介','8'),('15','形式与政策',3,48,'形式与政策简介','10'),('2','计算机组成原理',3,48,'计算机组成原理简介','1'),('20','电路与电子学',3,48,'','4'),('3','Linux系统',3,48,'Linux系统简介','1'),('4','数据库课程设计',3,48,'数据库课程设计简介','1'),('5','密码学',2,32,'','2'),('6','数据结构(甲)',3,48,'数据结构','2'),('7','编译原理',3,48,'编译原理简介','1'),('9','数学分析',3,48,'数学分析简介','8'); 68 | /*!40000 ALTER TABLE `course` ENABLE KEYS */; 69 | UNLOCK TABLES; 70 | 71 | -- 72 | -- Table structure for table `course_select_table` 73 | -- 74 | 75 | DROP TABLE IF EXISTS `course_select_table`; 76 | /*!40101 SET @saved_cs_client = @@character_set_client */; 77 | /*!40101 SET character_set_client = utf8 */; 78 | CREATE TABLE `course_select_table` ( 79 | `StudentNum` varchar(8) COLLATE utf8_unicode_ci NOT NULL, 80 | `CourseNum` varchar(10) COLLATE utf8_unicode_ci NOT NULL, 81 | `TeacherNum` varchar(8) COLLATE utf8_unicode_ci NOT NULL, 82 | `Grade` int(11) DEFAULT NULL, 83 | PRIMARY KEY (`StudentNum`,`CourseNum`,`TeacherNum`), 84 | KEY `CourseNum` (`CourseNum`), 85 | KEY `TeacherNum` (`TeacherNum`), 86 | CONSTRAINT `course_select_table_ibfk_1` FOREIGN KEY (`CourseNum`) REFERENCES `course` (`CourseNum`), 87 | CONSTRAINT `course_select_table_ibfk_2` FOREIGN KEY (`StudentNum`) REFERENCES `student` (`studentnum`), 88 | CONSTRAINT `course_select_table_ibfk_3` FOREIGN KEY (`TeacherNum`) REFERENCES `teacher` (`teachernum`) 89 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 90 | /*!40101 SET character_set_client = @saved_cs_client */; 91 | 92 | -- 93 | -- Dumping data for table `course_select_table` 94 | -- 95 | 96 | LOCK TABLES `course_select_table` WRITE; 97 | /*!40000 ALTER TABLE `course_select_table` DISABLE KEYS */; 98 | INSERT INTO `course_select_table` VALUES ('17262229','14','2002',NULL),('17272224','1','0001',100),('17272224','2','0002',NULL),('17272224','20','0038',NULL),('17272224','4','0001',99),('17282224','12','2001',NULL); 99 | /*!40000 ALTER TABLE `course_select_table` ENABLE KEYS */; 100 | UNLOCK TABLES; 101 | 102 | -- 103 | -- Table structure for table `course_teacher` 104 | -- 105 | 106 | DROP TABLE IF EXISTS `course_teacher`; 107 | /*!40101 SET @saved_cs_client = @@character_set_client */; 108 | /*!40101 SET character_set_client = utf8 */; 109 | CREATE TABLE `course_teacher` ( 110 | `CourseNum` varchar(8) COLLATE utf8_unicode_ci NOT NULL, 111 | `TeacherNum` varchar(10) COLLATE utf8_unicode_ci NOT NULL, 112 | `CourseCapacity` int(11) NOT NULL, 113 | PRIMARY KEY (`CourseNum`,`TeacherNum`), 114 | KEY `TeacherNum` (`TeacherNum`), 115 | CONSTRAINT `course_teacher_ibfk_1` FOREIGN KEY (`CourseNum`) REFERENCES `course` (`CourseNum`), 116 | CONSTRAINT `course_teacher_ibfk_2` FOREIGN KEY (`TeacherNum`) REFERENCES `teacher` (`teachernum`) 117 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 118 | /*!40101 SET character_set_client = @saved_cs_client */; 119 | 120 | -- 121 | -- Dumping data for table `course_teacher` 122 | -- 123 | 124 | LOCK TABLES `course_teacher` WRITE; 125 | /*!40000 ALTER TABLE `course_teacher` DISABLE KEYS */; 126 | INSERT INTO `course_teacher` VALUES ('1','0001',11),('12','2001',30),('14','2002',25),('2','0002',30),('2','0004',10),('20','0038',48),('3','0003',20),('4','0001',15),('5','1001',10),('6','1002',5),('7','0005',50); 127 | /*!40000 ALTER TABLE `course_teacher` ENABLE KEYS */; 128 | UNLOCK TABLES; 129 | 130 | -- 131 | -- Table structure for table `dept` 132 | -- 133 | 134 | DROP TABLE IF EXISTS `dept`; 135 | /*!40101 SET @saved_cs_client = @@character_set_client */; 136 | /*!40101 SET character_set_client = utf8 */; 137 | CREATE TABLE `dept` ( 138 | `DeptNum` varchar(4) COLLATE utf8_unicode_ci NOT NULL, 139 | `DeptName` varchar(10) COLLATE utf8_unicode_ci NOT NULL, 140 | `DeptChairman` varchar(10) COLLATE utf8_unicode_ci NOT NULL, 141 | `DeptTel` varchar(11) COLLATE utf8_unicode_ci DEFAULT NULL, 142 | `DeptDesc` text COLLATE utf8_unicode_ci, 143 | PRIMARY KEY (`DeptNum`) 144 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 145 | /*!40101 SET character_set_client = @saved_cs_client */; 146 | 147 | -- 148 | -- Dumping data for table `dept` 149 | -- 150 | 151 | LOCK TABLES `dept` WRITE; 152 | /*!40000 ALTER TABLE `dept` DISABLE KEYS */; 153 | INSERT INTO `dept` VALUES ('1','计算机学院','计算机学院党委书记',NULL,'计算机学院简介'),('10','马克思主义学院','马院党委书记',NULL,'马院简介'),('2','网络空间安全学院','网安学院党委书记',NULL,'网络空间安全学院简介'),('3','机械工程学院','李勇','13711111111','学院全日制在校大学生千余人,研究生近百人。现设有机械工程、工业设计和环境科学与工程3个系,下设机械设计制造及其自动化、车辆工程、工业设计、环境工程和环境科学5个本科专业,并拥有机械电子工程、机械制造及其自动化、机械设计及理论、精密仪器与机械4个二级学科硕士学位点,形成了学科方向稳定、培养体系完整的本科生、研究生人才培养体系。\n 学院设有机械电子工程、机械制造及其自动化、机械设计与车辆工程、工业设计、环境科学与工程等5个研究所,拥有实力雄厚的教学科研队伍。学院学术带头人为陈鹰教授、赵文礼教授、张云电教授和谢正苗教授四位博士生导师。\n 学院在机电装备技术、特种加工、测控技术等领域,特色明显。完成了一系列国家计划项目,国家、省部级基金项目和横向科研项目,一批成果获得国家和省部级科技进步奖,并拥有一批国家发明专利。在研的国家自然科学基金6项,其中国家自然科学基金重点项目1项。'),('4','电子信息学院','刘诗晨','137222222','电子信息学院是我校历史最悠久的学院之一,也是学校重点建设发展的学院。历经30余年的发展,已形成学士、硕士和博士完整的培养体系。作为国内具有较高知名度的工科学院,多个研究领域在国内外具有较强的影响力。'),('5','通信工程学院','王一鸣','13777333333','通信工程学院是学校重点建设的学院之一,历经30多年发展,已形成学士、硕士和博士完整的培养体系。\n 学院现有“通信工程”、“信息对抗技术”、“信息工程”3个本科专业以及一个中外合作办学项目“通信工程”。通信工程专业是国家重点专业、浙江省优势专业和卓越工程师教育培养计划试点专业,信息对抗技术专业是全省唯一武器类专业。拥有信息与通信工程一级学科工学硕士学位授予权和电子与通信工程领域工程硕士学位授予权。信息与通信工程一级硕士学位点包含信号与信息处理、通信与信息系统、信息安全3个二级学科硕士点。自主设置目录外二级学科智能信息处理与系统博士点。拥有1个浙江省一流学科(B类)、1个国防特色学科和1个原信息产业部重点学科。'),('6','自动化学院','王婷婷','13777444444','杭州电子科技大学自动化学院成立于2000年,其前身是1985年成立的机器人研究室和1994年成立的自动化系,是学校最富活力、发展最快的学院之一。学院现设置有2个本科专业:自动化(国防特色重点专业、卓越工程师培养计划专业、省重点及优势专业)、电气工程及其自动化(省重点及优势专业);在校本科生及研究生2000余人。'),('7','管理学院','贾向东','13777766666','学院的发展可追溯至1956年学校前身杭州航空工业财经学校的成立,1980年杭州电子工业学院成立时管理工程系为独立建制,1995年组建工商管理学院,2000年,成立管理学院。当前,学院依托学校电子信息特色与优势,致力于建设成为信息化特色明显、国际化水平一流的高水平学院,成为我国特别是浙江省信息化管理人才培养、信息化管理创新研究和社会服务的重要基地。'),('8','理学院','陈宝玉','13777777777','理学院以数学、物理两大学科为基础,依托学校电子信息优势,重基础,强特色,坚持走理工交叉融合的学科发展道路。现拥有信息与计算科学、数学与应用数学、应用物理学、光电信息科学与工程、应用统计学等五个本科专业,另有与经济学院合办的金融学(数学与应用数学复合)专业,其中信息与计算科学专业为浙江省“十二五”优势专业。现有系统优化与智能计算二级博士点(自主设置),数学、物理学和统计学(与经济学院联合)等三个一级学科硕士点。数学学科为浙江省“十二五”一级重点学科、浙江省“十三五”一流学科(A类)和学校博士单位建设支撑学科,物理学科为校一流学科(A类)。学院设有数学系、物理系,基础数学研究所、应用数学研究所、计算数学研究所、运筹与控制研究所、能源研究所和光电子物理与技术研究所'),('9','会计学院','会计学院党委书记',NULL,'会计学院简介'); 154 | /*!40000 ALTER TABLE `dept` ENABLE KEYS */; 155 | UNLOCK TABLES; 156 | 157 | -- 158 | -- Table structure for table `major` 159 | -- 160 | 161 | DROP TABLE IF EXISTS `major`; 162 | /*!40101 SET @saved_cs_client = @@character_set_client */; 163 | /*!40101 SET character_set_client = utf8 */; 164 | CREATE TABLE `major` ( 165 | `MajorNum` varchar(6) COLLATE utf8_unicode_ci NOT NULL, 166 | `DeptNum` varchar(4) COLLATE utf8_unicode_ci NOT NULL, 167 | `MajorName` varchar(10) COLLATE utf8_unicode_ci NOT NULL, 168 | `MajorAssistant` varchar(10) COLLATE utf8_unicode_ci NOT NULL, 169 | `MajorTel` varchar(11) COLLATE utf8_unicode_ci DEFAULT NULL, 170 | `MajorDesc` text COLLATE utf8_unicode_ci, 171 | `TrainingProgram` varchar(7) COLLATE utf8_unicode_ci DEFAULT NULL, 172 | PRIMARY KEY (`MajorNum`), 173 | KEY `DeptNum` (`DeptNum`), 174 | CONSTRAINT `major_ibfk_1` FOREIGN KEY (`DeptNum`) REFERENCES `dept` (`DeptNum`) 175 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 176 | /*!40101 SET character_set_client = @saved_cs_client */; 177 | 178 | -- 179 | -- Dumping data for table `major` 180 | -- 181 | 182 | LOCK TABLES `major` WRITE; 183 | /*!40000 ALTER TABLE `major` DISABLE KEYS */; 184 | INSERT INTO `major` VALUES ('1','1','计算机科学与技术','丹姐',NULL,'计算机科学与技术简介','1'),('10','1','计算机科学与技术','珊迪','14988658658','计算机科学与技术','10'),('11','1','软件工程','珍珍','14777989686','软件工程','11'),('12','1','软件工程卓越工程师','痞老板','16999856635','软件工程卓越工程师','12'),('13','1','物联网工程','图图','1447524456','物联网工程','13'),('14','7','人力资源管理专业','泡芙老师','14424744585','无','14'),('15','7','电子商务专业','FV','19981144457','无','15'),('16','7','工商管理专业','VS','4556686','无','16'),('17','8','光电信息科学与工程','JUGG','6456456','无','17'),('18','8','数学与应用数学','AM','565334','无','18'),('19','3','车辆工程','莫依琳','13466863628','车辆工程','19'),('2','2','网络工程','冯姐',NULL,'网络工程简介','2'),('20','3','海洋工程与技术','君辰煜','14574212463','海洋工程与技术','20'),('3','4','电子科学与技术','卢x伟','15585324632','电子科学与技术','3'),('4','4','电子信息工程','刘波','18898909876','电子信息工程','4'),('5','5','通信工程','牛伯伯','18815612398','通信工程','5'),('6','5','信息对抗技术','海绵宝宝','14256998659','信息对抗技术','6'),('7','6','电气工程及其自动化','派大星','19877545681','电气工程及其自动化','7'),('8','6','自动化专业','章鱼哥','13646244512','自动化专业','8'),('9','6','自动化(卓越)','蟹老板','12545525568','自动化(卓越)','9'); 185 | /*!40000 ALTER TABLE `major` ENABLE KEYS */; 186 | UNLOCK TABLES; 187 | 188 | -- 189 | -- Table structure for table `manager` 190 | -- 191 | 192 | DROP TABLE IF EXISTS `manager`; 193 | /*!40101 SET @saved_cs_client = @@character_set_client */; 194 | /*!40101 SET character_set_client = utf8 */; 195 | CREATE TABLE `manager` ( 196 | `ManagerNum` varchar(8) COLLATE utf8_unicode_ci NOT NULL, 197 | `ManagerName` varchar(10) COLLATE utf8_unicode_ci NOT NULL, 198 | `ManagerSex` varchar(2) COLLATE utf8_unicode_ci NOT NULL, 199 | `ManagerBirthday` datetime DEFAULT NULL, 200 | `ManagerPassword` text COLLATE utf8_unicode_ci NOT NULL, 201 | `ManagerPermission` int(11) NOT NULL, 202 | PRIMARY KEY (`ManagerNum`) 203 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 204 | /*!40101 SET character_set_client = @saved_cs_client */; 205 | 206 | -- 207 | -- Dumping data for table `manager` 208 | -- 209 | 210 | LOCK TABLES `manager` WRITE; 211 | /*!40000 ALTER TABLE `manager` DISABLE KEYS */; 212 | INSERT INTO `manager` VALUES ('000','管理员','男',NULL,'pbkdf2:sha256:50000$Kd1BWslr$3235dda29fc6980052b036ccff257c2f62a5653260ecd61225916fd8b2844720',1); 213 | /*!40000 ALTER TABLE `manager` ENABLE KEYS */; 214 | UNLOCK TABLES; 215 | 216 | -- 217 | -- Table structure for table `student` 218 | -- 219 | 220 | DROP TABLE IF EXISTS `student`; 221 | /*!40101 SET @saved_cs_client = @@character_set_client */; 222 | /*!40101 SET character_set_client = utf8 */; 223 | CREATE TABLE `student` ( 224 | `StudentNum` varchar(8) COLLATE utf8_unicode_ci NOT NULL, 225 | `MajorNum` varchar(16) COLLATE utf8_unicode_ci NOT NULL, 226 | `StudentName` varchar(10) COLLATE utf8_unicode_ci NOT NULL, 227 | `StudentSex` varchar(10) COLLATE utf8_unicode_ci NOT NULL, 228 | `StudentInyear` varchar(4) COLLATE utf8_unicode_ci NOT NULL, 229 | `StudengtPassword` text COLLATE utf8_unicode_ci NOT NULL, 230 | PRIMARY KEY (`StudentNum`), 231 | KEY `MajorNum` (`MajorNum`), 232 | CONSTRAINT `student_ibfk_1` FOREIGN KEY (`MajorNum`) REFERENCES `major` (`MajorNum`) 233 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 234 | /*!40101 SET character_set_client = @saved_cs_client */; 235 | 236 | -- 237 | -- Dumping data for table `student` 238 | -- 239 | 240 | LOCK TABLES `student` WRITE; 241 | /*!40000 ALTER TABLE `student` DISABLE KEYS */; 242 | INSERT INTO `student` VALUES ('17262229','5','夏俊','男','2017','pbkdf2:sha256:150000$J125habF$a8e79022bf66ab52467660edf84dbaab60d843b9f75e2a3c9ce15581eb24d862'),('17272224','1','牟宇','男','2017','pbkdf2:sha256:150000$cpVX6sre$a50066924e9d647237ee4489c59c29a4674d69cc81910028d74d98cff395249b'),('17272225','2','ray','男','2017','pbkdf2:sha256:150000$JsNLA406$46b9a76895d17825ead245f5401393c54a8bd770bbadcc9445c6446abf3f51ff'),('17272227','2','spy','男','2017','pbkdf2:sha256:150000$fE2he8Sq$e311d730f648be3df26a0634f240af7909d6b9e03fe94e4837b71e38abe469ef'),('17282224','16','汪阳','女','2017','pbkdf2:sha256:150000$JK1MBBsP$733f34e4ef9d11dd0a5b12d4f836b83e66ddd17711012477376b121d80dbf9b3'); 243 | /*!40000 ALTER TABLE `student` ENABLE KEYS */; 244 | UNLOCK TABLES; 245 | 246 | -- 247 | -- Table structure for table `teacher` 248 | -- 249 | 250 | DROP TABLE IF EXISTS `teacher`; 251 | /*!40101 SET @saved_cs_client = @@character_set_client */; 252 | /*!40101 SET character_set_client = utf8 */; 253 | CREATE TABLE `teacher` ( 254 | `TeacherNum` varchar(8) COLLATE utf8_unicode_ci NOT NULL, 255 | `DeptNum` varchar(4) COLLATE utf8_unicode_ci NOT NULL, 256 | `TeacherName` varchar(10) COLLATE utf8_unicode_ci NOT NULL, 257 | `TeacherSex` varchar(2) COLLATE utf8_unicode_ci NOT NULL, 258 | `TeacherInyear` varchar(4) COLLATE utf8_unicode_ci NOT NULL, 259 | `TeacherTitle` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL, 260 | `TeacherPassword` text COLLATE utf8_unicode_ci NOT NULL, 261 | PRIMARY KEY (`TeacherNum`), 262 | KEY `DeptNum` (`DeptNum`), 263 | CONSTRAINT `teacher_ibfk_1` FOREIGN KEY (`DeptNum`) REFERENCES `dept` (`DeptNum`) 264 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 265 | /*!40101 SET character_set_client = @saved_cs_client */; 266 | 267 | -- 268 | -- Dumping data for table `teacher` 269 | -- 270 | 271 | LOCK TABLES `teacher` WRITE; 272 | /*!40000 ALTER TABLE `teacher` DISABLE KEYS */; 273 | INSERT INTO `teacher` VALUES ('0001','1','张娟','女','1999','教授','pbkdf2:sha256:150000$yjfNLX6V$7f1425dad325dc5d24a67769cb144829a47d5ada96f11f68d685bedcf02ad275'),('0002','1','冯建','女','1997','教授','pbkdf2:sha256:150000$lfocOIrq$c08ef4894bda14e7e947b77f4f939d9b2c44be2eaed2c79d434bf50a59dda10b'),('0003','1','周旭日','男','2010','副教授','pbkdf2:sha256:150000$BRKZvQ1X$bb52920ef91c622dcdf3ad152f0d2d93b4543577a776addbf2aef11422f0f449'),('0004','1','赵准备','男','1998','副教授','pbkdf2:sha256:150000$jwqThKCt$83bed964ea9996c057a31eda1dd742b708b5e868f5a9adf473794a0ea826de18'),('0005','1','王光荣','男','1999','教授','pbkdf2:sha256:150000$k2zgGaXD$03c5c82263874603415d5b190a4b83a2e0437cfa57ddea4af05726df6a7868f1'),('0038','4','王康泰','男','1999','副教授','pbkdf2:sha256:150000$3j3Df9Bj$ca389d9c07a3a0aa90ffb209f131e9dbc09e3ba7331e7b5d68c2bb028f3f2304'),('1001','2','吴铤风','男','2000','教授','pbkdf2:sha256:150000$qKcrEw4M$e1fb31fefb289f8aa3514377b98ea1d68b7ac3746a71f2e8474a7da2dd267aa1'),('1002','2','胡胃痛','男','2001','副教授','pbkdf2:sha256:150000$jwqThKCt$83bed964ea9996c057a31eda1dd742b708b5e868f5a9adf473794a0ea826de18'),('2000','5','任飞','男','2000','教授','pbkdf2:sha256:150000$76KVi5v6$fb3a174d22738f863c8ca1677ce37d2085284b2c537c5198fa44990cfaf7709a'),('2001','7','吴晓','女','1999','副教授','pbkdf2:sha256:150000$yqHyPP7S$1e03c77b6564052c351a8fb1aea2bc45784749568823ea8aa2484ea530eb1026'),('2002','8','王建君','男','1999','教授','pbkdf2:sha256:150000$Yk18mr5E$f185ba64d82644fed19a4f8d55552154e52486320a3c7604a15e028e4f4920ff'); 274 | /*!40000 ALTER TABLE `teacher` ENABLE KEYS */; 275 | UNLOCK TABLES; 276 | 277 | -- 278 | -- Table structure for table `training_program` 279 | -- 280 | 281 | DROP TABLE IF EXISTS `training_program`; 282 | /*!40101 SET @saved_cs_client = @@character_set_client */; 283 | /*!40101 SET character_set_client = utf8 */; 284 | CREATE TABLE `training_program` ( 285 | `TPNumber` varchar(7) COLLATE utf8_unicode_ci NOT NULL, 286 | PRIMARY KEY (`TPNumber`) 287 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 288 | /*!40101 SET character_set_client = @saved_cs_client */; 289 | 290 | -- 291 | -- Dumping data for table `training_program` 292 | -- 293 | 294 | LOCK TABLES `training_program` WRITE; 295 | /*!40000 ALTER TABLE `training_program` DISABLE KEYS */; 296 | INSERT INTO `training_program` VALUES ('1'),('10'),('11'),('12'),('13'),('14'),('15'),('16'),('17'),('18'),('19'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'); 297 | /*!40000 ALTER TABLE `training_program` ENABLE KEYS */; 298 | UNLOCK TABLES; 299 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 300 | 301 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 302 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 303 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 304 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 305 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 306 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 307 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 308 | 309 | -- Dump completed on 2019-11-14 11:15:38 310 | -------------------------------------------------------------------------------- /image/AllCourse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/image/AllCourse.png -------------------------------------------------------------------------------- /image/CourseManage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/image/CourseManage.png -------------------------------------------------------------------------------- /image/CourseManage2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/image/CourseManage2.png -------------------------------------------------------------------------------- /image/GradeInput.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/image/GradeInput.png -------------------------------------------------------------------------------- /image/GradeInquiry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/image/GradeInquiry.png -------------------------------------------------------------------------------- /image/Login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/image/Login.png -------------------------------------------------------------------------------- /image/SelectManage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/image/SelectManage.png -------------------------------------------------------------------------------- /image/SelectedCourse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/image/SelectedCourse.png -------------------------------------------------------------------------------- /image/StuManage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/image/StuManage.png -------------------------------------------------------------------------------- /image/Student.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/image/Student.png -------------------------------------------------------------------------------- /image/Teacher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/image/Teacher.png -------------------------------------------------------------------------------- /image/TeacherCourse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/image/TeacherCourse.png -------------------------------------------------------------------------------- /image/TeacherManage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolfMy/course_select_system/5db3d26ac81bd410b64ce45d4ffdf512c2217dee/image/TeacherManage.png -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from app import app 2 | 3 | if __name__ == "__main__": 4 | from werkzeug.contrib.fixers import ProxyFix 5 | app.wsgi_app = ProxyFix(app.wsgi_app) 6 | app.run(host='0.0.0.0', port=4070, debug=False) 7 | -------------------------------------------------------------------------------- /migrations/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration. -------------------------------------------------------------------------------- /migrations/alembic.ini: -------------------------------------------------------------------------------- 1 | # A generic, single database configuration. 2 | 3 | [alembic] 4 | # template used to generate migration files 5 | # file_template = %%(rev)s_%%(slug)s 6 | 7 | # set to 'true' to run the environment during 8 | # the 'revision' command, regardless of autogenerate 9 | # revision_environment = false 10 | 11 | 12 | # Logging configuration 13 | [loggers] 14 | keys = root,sqlalchemy,alembic 15 | 16 | [handlers] 17 | keys = console 18 | 19 | [formatters] 20 | keys = generic 21 | 22 | [logger_root] 23 | level = WARN 24 | handlers = console 25 | qualname = 26 | 27 | [logger_sqlalchemy] 28 | level = WARN 29 | handlers = 30 | qualname = sqlalchemy.engine 31 | 32 | [logger_alembic] 33 | level = INFO 34 | handlers = 35 | qualname = alembic 36 | 37 | [handler_console] 38 | class = StreamHandler 39 | args = (sys.stderr,) 40 | level = NOTSET 41 | formatter = generic 42 | 43 | [formatter_generic] 44 | format = %(levelname)-5.5s [%(name)s] %(message)s 45 | datefmt = %H:%M:%S 46 | -------------------------------------------------------------------------------- /migrations/env.py: -------------------------------------------------------------------------------- 1 | from __future__ import with_statement 2 | 3 | import logging 4 | from logging.config import fileConfig 5 | 6 | from sqlalchemy import engine_from_config 7 | from sqlalchemy import pool 8 | 9 | from alembic import context 10 | 11 | # this is the Alembic Config object, which provides 12 | # access to the values within the .ini file in use. 13 | config = context.config 14 | 15 | # Interpret the config file for Python logging. 16 | # This line sets up loggers basically. 17 | fileConfig(config.config_file_name) 18 | logger = logging.getLogger('alembic.env') 19 | 20 | # add your model's MetaData object here 21 | # for 'autogenerate' support 22 | # from myapp import mymodel 23 | # target_metadata = mymodel.Base.metadata 24 | from flask import current_app 25 | config.set_main_option( 26 | 'sqlalchemy.url', current_app.config.get( 27 | 'SQLALCHEMY_DATABASE_URI').replace('%', '%%')) 28 | target_metadata = current_app.extensions['migrate'].db.metadata 29 | 30 | # other values from the config, defined by the needs of env.py, 31 | # can be acquired: 32 | # my_important_option = config.get_main_option("my_important_option") 33 | # ... etc. 34 | 35 | 36 | def run_migrations_offline(): 37 | """Run migrations in 'offline' mode. 38 | 39 | This configures the context with just a URL 40 | and not an Engine, though an Engine is acceptable 41 | here as well. By skipping the Engine creation 42 | we don't even need a DBAPI to be available. 43 | 44 | Calls to context.execute() here emit the given string to the 45 | script output. 46 | 47 | """ 48 | url = config.get_main_option("sqlalchemy.url") 49 | context.configure( 50 | url=url, target_metadata=target_metadata, literal_binds=True 51 | ) 52 | 53 | with context.begin_transaction(): 54 | context.run_migrations() 55 | 56 | 57 | def run_migrations_online(): 58 | """Run migrations in 'online' mode. 59 | 60 | In this scenario we need to create an Engine 61 | and associate a connection with the context. 62 | 63 | """ 64 | 65 | # this callback is used to prevent an auto-migration from being generated 66 | # when there are no changes to the schema 67 | # reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html 68 | def process_revision_directives(context, revision, directives): 69 | if getattr(config.cmd_opts, 'autogenerate', False): 70 | script = directives[0] 71 | if script.upgrade_ops.is_empty(): 72 | directives[:] = [] 73 | logger.info('No changes in schema detected.') 74 | 75 | connectable = engine_from_config( 76 | config.get_section(config.config_ini_section), 77 | prefix='sqlalchemy.', 78 | poolclass=pool.NullPool, 79 | ) 80 | 81 | with connectable.connect() as connection: 82 | context.configure( 83 | connection=connection, 84 | target_metadata=target_metadata, 85 | process_revision_directives=process_revision_directives, 86 | **current_app.extensions['migrate'].configure_args 87 | ) 88 | 89 | with context.begin_transaction(): 90 | context.run_migrations() 91 | 92 | 93 | if context.is_offline_mode(): 94 | run_migrations_offline() 95 | else: 96 | run_migrations_online() 97 | -------------------------------------------------------------------------------- /migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /migrations/versions/ddcf6d407079_.py: -------------------------------------------------------------------------------- 1 | """empty message 2 | 3 | Revision ID: ddcf6d407079 4 | Revises: 5 | Create Date: 2019-06-04 23:33:58.570814 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = 'ddcf6d407079' 14 | down_revision = None 15 | branch_labels = None 16 | depends_on = None 17 | 18 | 19 | def upgrade(): 20 | # ### commands auto generated by Alembic - please adjust! ### 21 | op.create_table('dept', 22 | sa.Column('DeptNum', sa.String(length=4), nullable=False), 23 | sa.Column('DeptName', sa.String(length=10), nullable=False), 24 | sa.Column('DeptChairman', sa.String(length=10), nullable=False), 25 | sa.Column('DeptTel', sa.String(length=11), nullable=True), 26 | sa.Column('DeptDesc', sa.Text(), nullable=True), 27 | sa.PrimaryKeyConstraint('DeptNum') 28 | ) 29 | op.create_table('manager', 30 | sa.Column('ManagerNum', sa.String(length=8), nullable=False), 31 | sa.Column('ManagerName', sa.String(length=10), nullable=False), 32 | sa.Column('ManagerSex', sa.String(length=2), nullable=False), 33 | sa.Column('ManagerBirthday', sa.DateTime(), nullable=True), 34 | sa.Column('ManagerPassword', sa.Text(), nullable=False), 35 | sa.Column('ManagerPermission', sa.Integer(), nullable=False), 36 | sa.PrimaryKeyConstraint('ManagerNum') 37 | ) 38 | op.create_table('training_program', 39 | sa.Column('TPNumber', sa.String(length=7), nullable=False), 40 | sa.PrimaryKeyConstraint('TPNumber') 41 | ) 42 | op.create_table('course', 43 | sa.Column('CourseNum', sa.String(length=8), nullable=False), 44 | sa.Column('CourseName', sa.String(length=10), nullable=False), 45 | sa.Column('CourseCredit', sa.Integer(), nullable=False), 46 | sa.Column('CourseTime', sa.Integer(), nullable=False), 47 | sa.Column('CourseDesc', sa.Text(), nullable=True), 48 | sa.Column('DeptNum', sa.String(length=4), nullable=False), 49 | sa.ForeignKeyConstraint(['DeptNum'], ['dept.DeptNum'], ), 50 | sa.PrimaryKeyConstraint('CourseNum') 51 | ) 52 | op.create_table('major', 53 | sa.Column('MajorNum', sa.String(length=6), nullable=False), 54 | sa.Column('DeptNum', sa.String(length=4), nullable=False), 55 | sa.Column('MajorName', sa.String(length=10), nullable=False), 56 | sa.Column('MajorAssistant', sa.String(length=10), nullable=False), 57 | sa.Column('MajorTel', sa.String(length=11), nullable=True), 58 | sa.Column('MajorDesc', sa.Text(), nullable=True), 59 | sa.Column('TrainingProgram', sa.String(length=7), nullable=True), 60 | sa.ForeignKeyConstraint(['DeptNum'], ['dept.DeptNum'], ), 61 | sa.PrimaryKeyConstraint('MajorNum') 62 | ) 63 | op.create_table('teacher', 64 | sa.Column('TeacherNum', sa.String(length=8), nullable=False), 65 | sa.Column('DeptNum', sa.String(length=4), nullable=False), 66 | sa.Column('TeacherName', sa.String(length=10), nullable=False), 67 | sa.Column('TeacherSex', sa.String(length=2), nullable=False), 68 | sa.Column('TeacherInyear', sa.String(length=4), nullable=False), 69 | sa.Column('TeacherTitle', sa.String(length=10), nullable=True), 70 | sa.Column('TeacherPassword', sa.Text(), nullable=False), 71 | sa.ForeignKeyConstraint(['DeptNum'], ['dept.DeptNum'], ), 72 | sa.PrimaryKeyConstraint('TeacherNum') 73 | ) 74 | op.create_table('course_teacher', 75 | sa.Column('CourseNum', sa.String(length=8), nullable=False), 76 | sa.Column('TeacherNum', sa.String(length=10), nullable=False), 77 | sa.Column('CourseCapacity', sa.Integer(), nullable=False), 78 | sa.ForeignKeyConstraint(['CourseNum'], ['course.CourseNum'], ), 79 | sa.ForeignKeyConstraint(['TeacherNum'], ['teacher.TeacherNum'], ), 80 | sa.PrimaryKeyConstraint('CourseNum', 'TeacherNum') 81 | ) 82 | op.create_table('student', 83 | sa.Column('StudentNum', sa.String(length=8), nullable=False), 84 | sa.Column('MajorNum', sa.String(length=16), nullable=False), 85 | sa.Column('StudentName', sa.String(length=10), nullable=False), 86 | sa.Column('StudentSex', sa.String(length=10), nullable=False), 87 | sa.Column('StudentInyear', sa.String(length=4), nullable=False), 88 | sa.Column('StudengtPassword', sa.Text(), nullable=False), 89 | sa.ForeignKeyConstraint(['MajorNum'], ['major.MajorNum'], ), 90 | sa.PrimaryKeyConstraint('StudentNum') 91 | ) 92 | op.create_table('course_select_table', 93 | sa.Column('StudentNum', sa.String(length=8), nullable=False), 94 | sa.Column('CourseNum', sa.String(length=10), nullable=False), 95 | sa.Column('TeacherNum', sa.String(length=8), nullable=False), 96 | sa.Column('Grade', sa.Integer(), nullable=True), 97 | sa.ForeignKeyConstraint(['CourseNum'], ['course.CourseNum'], ), 98 | sa.ForeignKeyConstraint(['StudentNum'], ['student.StudentNum'], ), 99 | sa.ForeignKeyConstraint(['TeacherNum'], ['teacher.TeacherNum'], ), 100 | sa.PrimaryKeyConstraint('StudentNum', 'CourseNum', 'TeacherNum') 101 | ) 102 | # ### end Alembic commands ### 103 | 104 | 105 | def downgrade(): 106 | # ### commands auto generated by Alembic - please adjust! ### 107 | op.drop_table('course_select_table') 108 | op.drop_table('student') 109 | op.drop_table('course_teacher') 110 | op.drop_table('teacher') 111 | op.drop_table('major') 112 | op.drop_table('course') 113 | op.drop_table('training_program') 114 | op.drop_table('manager') 115 | op.drop_table('dept') 116 | # ### end Alembic commands ### 117 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | alembic==1.0.10 2 | certifi==2019.3.9 3 | Click==7.0 4 | dominate==2.3.5 5 | Flask==1.0.3 6 | Flask-Bootstrap==3.3.7.1 7 | Flask-Login==0.4.1 8 | Flask-Migrate==2.5.2 9 | Flask-SQLAlchemy==2.4.0 10 | Flask-WTF==0.14.2 11 | itsdangerous==1.1.0 12 | Jinja2==2.10.1 13 | Mako==1.0.11 14 | MarkupSafe==1.1.1 15 | PyMySQL==0.9.3 16 | python-dateutil==2.8.0 17 | python-editor==1.0.4 18 | six==1.12.0 19 | SQLAlchemy==1.3.4 20 | visitor==0.1.3 21 | Werkzeug==0.15.2 22 | WTForms==2.2.1 23 | --------------------------------------------------------------------------------