153 lines
5.0 KiB
Python
153 lines
5.0 KiB
Python
from flask import Flask, render_template, request, redirect, url_for, flash, session
|
|
from flask_bcrypt import Bcrypt
|
|
from functools import wraps
|
|
import mysql.connector
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = 'secret_key'
|
|
bcrypt = Bcrypt(app)
|
|
|
|
db = mysql.connector.connect(
|
|
host="sql_ip",
|
|
user="user",
|
|
password="password",
|
|
database="database_name"
|
|
)
|
|
|
|
# 登錄裝飾器
|
|
def login_required(f):
|
|
@wraps(f)
|
|
def decorated_function(*args, **kwargs):
|
|
if 'user_id' not in session:
|
|
flash('請先登錄', 'danger')
|
|
return redirect(url_for('login'))
|
|
return f(*args, **kwargs)
|
|
|
|
return decorated_function
|
|
|
|
|
|
@app.route('/register', methods=['GET', 'POST'])
|
|
def register():
|
|
if request.method == 'POST':
|
|
username = request.form['username']
|
|
password = request.form['password']
|
|
cursor = db.cursor()
|
|
|
|
# 檢查帳號是否已存在
|
|
cursor.execute("SELECT * FROM users WHERE username = %s", (username,))
|
|
if cursor.fetchone():
|
|
flash('帳號已存在', 'danger')
|
|
else:
|
|
hashed_password = bcrypt.generate_password_hash(password).decode('utf-8')
|
|
cursor.execute("INSERT INTO users (username, password) VALUES (%s, %s)", (username, hashed_password))
|
|
db.commit()
|
|
flash('註冊成功,請登錄', 'success')
|
|
return redirect(url_for('login'))
|
|
|
|
return render_template('register.html')
|
|
|
|
|
|
@app.route('/login', methods=['GET', 'POST'])
|
|
def login():
|
|
if request.method == 'POST':
|
|
username = request.form['username']
|
|
password = request.form['password']
|
|
cursor = db.cursor(dictionary=True)
|
|
cursor.execute("SELECT * FROM users WHERE username = %s", (username,))
|
|
user = cursor.fetchone()
|
|
|
|
if user and bcrypt.check_password_hash(user['password'], password):
|
|
session['user_id'] = user['id']
|
|
flash('登錄成功', 'success')
|
|
return redirect(url_for('index'))
|
|
else:
|
|
flash('登錄失敗,請檢查帳號和密碼', 'danger')
|
|
|
|
return render_template('login.html')
|
|
|
|
|
|
@app.route('/logout')
|
|
def logout():
|
|
session.pop('user_id', None)
|
|
flash('已登出', 'info')
|
|
return redirect(url_for('login'))
|
|
|
|
|
|
@app.route('/')
|
|
@login_required
|
|
def index():
|
|
cursor = db.cursor(dictionary=True)
|
|
search = request.args.get('search', '')
|
|
if search:
|
|
cursor.execute("SELECT * FROM tasks WHERE user_id = %s AND (title LIKE %s OR description LIKE %s)",
|
|
(session['user_id'], f'%{search}%', f'%{search}%'))
|
|
else:
|
|
cursor.execute("SELECT * FROM tasks WHERE user_id = %s ORDER BY priority DESC, created_at DESC",
|
|
(session['user_id'],))
|
|
tasks = cursor.fetchall()
|
|
return render_template('index.html', tasks=tasks, search=search)
|
|
|
|
|
|
@app.route('/add_task', methods=['POST'])
|
|
@login_required
|
|
def add_task():
|
|
title = request.form['title']
|
|
description = request.form['description']
|
|
priority = request.form['priority']
|
|
cursor = db.cursor()
|
|
sql = "INSERT INTO tasks (title, description, priority, user_id) VALUES (%s, %s, %s, %s)"
|
|
cursor.execute(sql, (title, description, priority, session['user_id']))
|
|
db.commit()
|
|
flash('任務已添加', 'success')
|
|
return redirect(url_for('index'))
|
|
|
|
|
|
@app.route('/edit_task/<int:task_id>', methods=['GET', 'POST'])
|
|
@login_required
|
|
def edit_task(task_id):
|
|
cursor = db.cursor(dictionary=True)
|
|
if request.method == 'POST':
|
|
title = request.form['title']
|
|
description = request.form['description']
|
|
status = request.form['status']
|
|
priority = request.form['priority']
|
|
sql = "UPDATE tasks SET title=%s, description=%s, status=%s, priority=%s WHERE id=%s AND user_id=%s"
|
|
cursor.execute(sql, (title, description, status, priority, task_id, session['user_id']))
|
|
db.commit()
|
|
flash('任務已更新', 'success')
|
|
return redirect(url_for('index'))
|
|
else:
|
|
cursor.execute("SELECT * FROM tasks WHERE id = %s AND user_id = %s", (task_id, session['user_id']))
|
|
task = cursor.fetchone()
|
|
if task:
|
|
return render_template('edit_task.html', task=task)
|
|
else:
|
|
flash('未找到任務', 'danger')
|
|
return redirect(url_for('index'))
|
|
|
|
|
|
@app.route('/delete_task/<int:task_id>')
|
|
@login_required
|
|
def delete_task(task_id):
|
|
cursor = db.cursor()
|
|
sql = "DELETE FROM tasks WHERE id = %s AND user_id = %s"
|
|
cursor.execute(sql, (task_id, session['user_id']))
|
|
db.commit()
|
|
flash('任務已刪除', 'success')
|
|
return redirect(url_for('index'))
|
|
|
|
|
|
@app.route('/update_status/<int:task_id>/<string:new_status>')
|
|
@login_required
|
|
def update_status(task_id, new_status):
|
|
cursor = db.cursor()
|
|
sql = "UPDATE tasks SET status = %s WHERE id = %s AND user_id = %s"
|
|
cursor.execute(sql, (new_status, task_id, session['user_id']))
|
|
db.commit()
|
|
flash('任務狀態已更新', 'success')
|
|
return redirect(url_for('index'))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
app.run(debug=True)
|