Сделал тестовую версию системы администрирования

This commit is contained in:
Andrei 2023-03-09 21:26:08 +05:00
parent 3617afce1b
commit e4b97e7616
8 changed files with 173 additions and 6 deletions

6
forms/encrypt_form.py Normal file
View File

@ -0,0 +1,6 @@
from flask_wtf import FlaskForm
from wtforms import SubmitField
class EncryptForm(FlaskForm):
submit = SubmitField('Сохранить')

View File

@ -4,7 +4,6 @@ import shutil
import smtplib
from json import loads
from email.message import EmailMessage
from sqlalchemy import or_
from data.answer import Answer
from data.proof_file import FileProof
@ -14,6 +13,7 @@ from data.users import User
from data.staff_projects import StaffProjects
from data.files import Files
from data import db_session
import uuid
import pymorphy2
@ -259,3 +259,9 @@ def copy_template(template, new_project, data_session, current_user):
list(map(lambda quest: copy_quests_from_template(quest, new_project, data_session, current_user),
data_session.query(Quests).filter(Quests.project == template.id).all()))
data_session.commit()
def save_admin_data(data, data_session):
user = data_session.query(User).filter(User.id == data[0][5:]).first()
if user.role != data[1]:
user.role = data[1]

29
main.py
View File

@ -1,7 +1,6 @@
import datetime
import os
import logging
import shutil
from flask import Flask, render_template, request, url_for
from flask_login import login_user, current_user, LoginManager, logout_user, login_required
@ -12,10 +11,12 @@ from werkzeug.utils import redirect
from itsdangerous import URLSafeTimedSerializer, SignatureExpired
from sqlalchemy import or_
from json import loads
from waitress import serve
from functions import check_password, mail, init_db_default, get_projects_data, get_user_data, save_project_logo, \
overdue_quest_project, save_proof_quest, find_files_answer, file_tree, delete_project_data, delete_quest_data, \
copy_template
copy_template, save_admin_data
from forms.edit_profile import EditProfileForm
from forms.login import LoginForm
from forms.find_project import FindProjectForm
@ -24,6 +25,7 @@ from forms.project import ProjectForm, AddFileProject
from forms.recovery import RecoveryForm, NewPasswordForm
from forms.conf_delete_project import DeleteProjectForm
from forms.task import Task, AnswerTask
from forms.encrypt_form import EncryptForm
from data.users import User
from data.quests import Quests
@ -32,7 +34,7 @@ from data.proof_file import FileProof
from data.files import Files
from data.projects import Projects
from data.staff_projects import StaffProjects
from waitress import serve
from data.roles import Roles
from data import db_session
app = Flask(__name__)
@ -58,6 +60,24 @@ def base():
return redirect('/projects')
@app.route('/admin', methods=['GET', 'POST'])
def admin():
if current_user.is_authenticated:
if current_user.role == 1:
data_session = db_session.create_session()
roles, users = data_session.query(Roles).all(), \
data_session.query(User).filter(User.id != current_user.id).all()
form = EncryptForm()
if request.method == 'POST':
data_form = request.form.to_dict()
del data_form['csrf_token'], data_form['submit']
data_form = list(map(lambda x: (x[0], x[1]), data_form.items()))
list(map(lambda x: save_admin_data(x, data_session), data_form))
data_session.commit()
return render_template('admin.html', title='Панель админа', roles=roles, users=users, form=form)
abort(404)
@app.route('/template/<int:id_template>/create')
def create_by_template(id_template):
if current_user.is_authenticated:
@ -533,6 +553,7 @@ def projects():
@app.route('/profile', methods=['GET', 'POST'])
def profile():
if current_user.is_authenticated:
data_session = db_session.create_session()
form = EditProfileForm(
CombinedMultiDict((request.files, request.form)),
email=current_user.email,
@ -542,7 +563,6 @@ def profile():
birthday=current_user.birthday
)
if form.del_photo.data:
data_session = db_session.create_session()
user = data_session.query(User).filter(User.id == current_user.id).first()
if not user:
return render_template('profile.html', title='Профиль', form=form,
@ -551,7 +571,6 @@ def profile():
user.photo = 'static/images/none_logo.png'
data_session.commit()
if form.validate_on_submit():
data_session = db_session.create_session()
user = data_session.query(User).filter(User.id == current_user.id).first()
if not user:
return render_template('profile.html', title='Профиль', form=form,

92
static/css/admin.css Normal file
View File

@ -0,0 +1,92 @@
.admin_page {
height: 120vw;
background-color: #dcb495;
display: flex;
flex-direction: column;
align-items: center;
}
.roles_block {
width: 90%;
height: 35vw;
background-color: #EDCBB0;
border-radius: 2vw;
overflow-y: auto;
overflow-x: hidden;
}
.roles_block::-webkit-scrollbar {
width: 0.8vw; /* ширина scrollbar */
}
.roles_block::-webkit-scrollbar-thumb {
background-color: #d49d51; /* цвет плашки */
border-radius: 5vw; /* закругления плашки */
border: 0.25vw solid #ffffff;
}
.users_block {
margin: 20px;
display: flex;
flex-direction: column;
align-items: center;
}
.user {
width: 90%;
height: 5vw;
background-color: #ffffff;
border: 2px solid #9E795A;
border-radius: 3vw;
margin-top: 5px;
display: flex;
align-items: center;
justify-content: flex-start;
flex-direction: row;
}
.user_logo {
margin-left: 3px;
width: 4vw;
height: 4vw;
border-radius: 5vw;
background-color: #000000;
}
.user_names {
margin-left: 9px;
margin-top: 10px;
overflow-x: auto;
color: #000000 !important;
font-size: 2vw;
}
.roles_title {
font-size: 3vw;
}
.link_to_user {
width: 16vw;
height: 3.5vw;
display: flex;
align-items: center;
justify-content: flex-start;
flex-direction: row;
flex-wrap: no-wrap;
text-decoration: none;
}
.link_to_user:hover {
text-decoration: none;
}
.role_div {
width: 8vw;
height: 3vw;
border-radius: 2vw;
}
.save_button {
margin-top: 15px;
width: 35vw;
height: 5vw;
background-color: #000000;
color: #ffffff;
border-radius: 5vw;
vertical-align: middle;
font-size: 1.5vw;
}
.edit_user_form {
width: 90%;
display: flex;
flex-direction: column;
align-items: center;
}

View File

@ -116,6 +116,16 @@
}
.project_title {
font-size: 3.5vw;
overflow-y: hidden;
overflow-x: auto;
}
.project_title::-webkit-scrollbar {
height: 0.8vw; /* ширина scrollbar */
}
.project_title::-webkit-scrollbar-thumb {
background-color: #d49d51; /* цвет плашки */
border-radius: 5vw; /* закругления плашки */
border: 0.25vw solid #ffffff;
}
.project_button_block_one {
width: 50%;

BIN
static/images/showcase.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

29
templates/admin.html Normal file
View File

@ -0,0 +1,29 @@
<link rel="stylesheet" href="../static/css/admin.css"/>
{% extends "base.html" %} {% block content %}
<div class="admin_page">
<h2 class="roles_title">Изменение ролей</h2>
<form action="" method="post" class="edit_user_form" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<div class="roles_block">
<div class="users_block">
{% for user in users %}
<div class="user">
<a class="link_to_user" href="/user/{{ user.login }}">
<img class="user_logo" src="{{user.photo}}">
<p class="user_names">{{user.name}}</p>
</a>
<select name="role_{{ user.id }}" class="form-select role_div" aria-label="Default select example">
{% for role in roles %}
<option class="role" value="{{ loop.index }}" {% if user.role == loop.index %}selected{%
endif %}>{{ roles[loop.index0].name }}
</option>
{% endfor %}
</select>
</div>
{% endfor %}
</div>
</div>
{{ form.submit(type="submit", class="save_button") }}
</form>
</div>
{% endblock %}

View File

@ -30,6 +30,11 @@
<a class="nav_chapter" href="/showcase">
<p class="nav_chapter_text">Витрина</p>
</a>
{% if current_user.role == 1 %}
<a class="nav_chapter" href="/admin">
<p class="nav_chapter_text">Админ</p>
</a>
{% endif %}
</div>
</nav>
{% else %}