set up main structure of the UI
This commit is contained in:
63
UI/main.py
63
UI/main.py
@ -3,9 +3,12 @@ import subprocess
|
||||
import signal
|
||||
import atexit
|
||||
from flask import Flask, render_template
|
||||
from flask import request, redirect, url_for, flash
|
||||
from flask import session
|
||||
from dotenv import load_dotenv
|
||||
import time
|
||||
import socket
|
||||
import utils
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
@ -19,6 +22,7 @@ backend_log_level = os.getenv('BACKEND_LOG_LEVEL')
|
||||
backend_data_directory = os.getenv('BACKEND_DATA_DIRECTORY')
|
||||
backend_log_file = os.getenv('BACKEND_LOG_FILE')
|
||||
backend_path = os.getenv('BACKEND_PATH')
|
||||
app.secret_key = os.getenv('APP_SECRET_KEY')
|
||||
|
||||
# Command to start the backend process
|
||||
backend_command = [
|
||||
@ -34,6 +38,7 @@ backend_command = [
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.connect((backend_ip, int(backend_port)))
|
||||
def ExecCommand(command):
|
||||
print("sending command: ", command)
|
||||
command=command+'\n'
|
||||
sock.sendall(command.encode('utf-8'))
|
||||
response = sock.recv(1024*1024)
|
||||
@ -59,5 +64,63 @@ def home():
|
||||
def about():
|
||||
return render_template('about.html')
|
||||
|
||||
@app.route('/login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
if request.method == 'POST':
|
||||
username = request.form['username']
|
||||
password = request.form['password']
|
||||
|
||||
# 调用 ExecCommand 执行登录命令
|
||||
login_response = ExecCommand(f'login -u {username} -p {password}')
|
||||
|
||||
if login_response.strip() == '0':
|
||||
session['username'] = username # 在session中记录用户名
|
||||
return redirect(url_for('home'))
|
||||
elif login_response.strip() == '-1':
|
||||
error = 'Invalid username or password.'
|
||||
else:
|
||||
error = 'An unknown error occurred.'
|
||||
|
||||
return render_template('login.html', error=error)
|
||||
|
||||
return render_template('login.html')
|
||||
|
||||
@app.before_request
|
||||
def before_request():
|
||||
# Skip login check for login page, callback URL, and static files
|
||||
if request.endpoint in ['login', 'logout']:
|
||||
return
|
||||
# Check if user is logged in
|
||||
if ('username' not in session) or ('username' in session and utils.GetPrivilege(session['username'], ExecCommand) < 0):
|
||||
if 'username' in session:
|
||||
session.pop('username', None)
|
||||
return redirect(url_for('login'))
|
||||
|
||||
@app.route('/profile')
|
||||
def profile():
|
||||
username = session['username']
|
||||
dat = ExecCommand(f'query_profile -c {username} -u {username}')
|
||||
print("dat: ", dat)
|
||||
# dat is something like: <username> <name> <mail> <privilege>
|
||||
profile_data = dat.split(' ')
|
||||
|
||||
if len(profile_data) >= 4:
|
||||
user_info = {
|
||||
'username': profile_data[0],
|
||||
'name': profile_data[1],
|
||||
'email': profile_data[2],
|
||||
'privilege': profile_data[3]
|
||||
}
|
||||
return render_template('profile.html', user_info=user_info)
|
||||
else:
|
||||
# Handle the case where the response does not contain the expected number of elements
|
||||
error = "Profile data is incomplete or incorrect."
|
||||
return render_template('profile.html', error=error)
|
||||
|
||||
@app.route('/logout')
|
||||
def logout():
|
||||
ExecCommand(f'logout -u {session["username"]}')
|
||||
session.pop('username', None) # 从session中移除用户名
|
||||
return redirect(url_for('home'))
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True)
|
||||
|
@ -4,13 +4,16 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}Train Ticket Booking{% endblock %}</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<a class="navbar-brand" href="#">Train Tickets</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item {% if request.endpoint == 'home' %}active{% endif %}">
|
||||
<a class="nav-link" href="/">Home</a>
|
||||
</li>
|
||||
@ -18,10 +21,30 @@
|
||||
<a class="nav-link" href="/about">About</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="navbar-nav ml-auto">
|
||||
{% if session.get('username') %}
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
{{ session.get('username') }}
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
|
||||
<a class="dropdown-item" href="/profile">Profile</a>
|
||||
<a class="dropdown-item" href="/logout">Logout</a>
|
||||
</div>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item {% if request.endpoint == 'login' %}active{% endif %}">
|
||||
<a class="nav-link" href="/login">Login</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container mt-5">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
27
UI/templates/login.html
Normal file
27
UI/templates/login.html
Normal file
@ -0,0 +1,27 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Login{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<h2 class="text-center">Login</h2>
|
||||
{% if error %}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
{{ error }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<form method="POST" action="/login">
|
||||
<div class="form-group">
|
||||
<label for="username">Username</label>
|
||||
<input type="text" class="form-control" id="username" name="username" placeholder="Enter your username" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">Password</label>
|
||||
<input type="password" class="form-control" id="password" name="password" placeholder="Enter your password" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-block">Login</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
37
UI/templates/profile.html
Normal file
37
UI/templates/profile.html
Normal file
@ -0,0 +1,37 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Profile{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<h2 class="text-center">User Profile</h2>
|
||||
{% if error %}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
{{ error }}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="card mt-4 border-custom">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">{{ user_info.name }}</h4>
|
||||
<p class="card-text"><strong>Username:</strong> {{ user_info.username }}</p>
|
||||
<p class="card-text"><strong>Email:</strong> {{ user_info.email }}</p>
|
||||
<p class="card-text"><strong>Privilege:</strong> {{ user_info.privilege }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 添加自定义样式 -->
|
||||
<style>
|
||||
.border-custom {
|
||||
border: 2px solid #007bff; /* 蓝色边框 */
|
||||
border-radius: 15px; /* 圆角边框 */
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 添加阴影效果 */
|
||||
}
|
||||
.card-body {
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
7
UI/utils.py
Normal file
7
UI/utils.py
Normal file
@ -0,0 +1,7 @@
|
||||
def GetPrivilege(username, ExecCommand):
|
||||
dat=ExecCommand(f'query_profile -c {username} -u {username}')
|
||||
if dat=='-1':
|
||||
return -1
|
||||
# dat is something like: <username> <name> <mail> <privilege>
|
||||
dat=dat.split(' ')
|
||||
return int(dat[3])
|
@ -54,6 +54,7 @@ void handle_client(sockpp::tcp_socket client, TicketSystemEngine &engine) {
|
||||
|
||||
// 检查是否需要退出
|
||||
if (*engine.its_time_to_exit_ptr) {
|
||||
(&engine)->~TicketSystemEngine();
|
||||
exit(0);
|
||||
return;
|
||||
}
|
||||
|
Reference in New Issue
Block a user