diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/.DS_Store differ diff --git a/README.md b/README.md index 17e0f0d..cb3fdac 100644 --- a/README.md +++ b/README.md @@ -1 +1,75 @@ -# Notes +# 网页版备忘录应用 + +这是一个使用Flask框架开发的网页版备忘录应用,支持添加、删除、修改备忘录,并具有优先级排序和完成状态管理功能。 + +## 功能特点 + +- ✅ 备忘录包含标题、详情、创建时间和预计完成时间 +- ✅ 支持添加、删除、修改备忘录 +- ✅ 可查看备忘录详情页面 +- ✅ 自动获取创建时的本地时间 +- ✅ 支持设置优先级(P0、P1、P2),并按优先级排序 +- ✅ 支持标记完成状态,完成和未完成备忘录分组显示 +- ✅ 响应式设计,适配不同设备屏幕 +- ✅ 现代化UI设计,使用渐变色彩和卡片布局 + +## 技术栈 + +- **后端**: Python 3.x + Flask +- **数据库**: SQLite (使用SQLAlchemy ORM) +- **前端**: HTML5 + CSS3 + JavaScript +- **时区处理**: pytz + +## 快速开始 + +### 1. 安装依赖 + +```bash +pip install -r requirements.txt +``` + +### 2. 运行应用 + +```bash +python app.py +``` + +### 3. 访问应用 + +在浏览器中打开:http://127.0.0.1:5000 + +## 项目结构 + +``` +. +├── app.py # Flask应用主文件 +├── requirements.txt # 项目依赖 +├── templates/ # HTML模板文件夹 +│ ├── base.html # 基础模板 +│ ├── index.html # 首页 - 备忘录列表 +│ ├── add_note.html # 添加备忘录页面 +│ ├── view_note.html # 查看备忘录详情页面 +│ └── edit_note.html # 编辑备忘录页面 +└── README.md # 项目说明文档 +``` + +## 优先级说明 + +- **P0**: 紧急重要 - 红色标签 +- **P1**: 一般重要 - 橙色标签 +- **P2**: 不太紧急 - 绿色标签 + +## 注意事项 + +1. 应用使用SQLite数据库,数据存储在项目根目录的notes.db文件中 +2. 应用默认使用上海时区(Asia/Shanghai),可在app.py中修改local_tz变量 +3. 开发环境中debug模式已开启,生产环境部署时请关闭 +4. 表单提交时会进行简单的错误处理和消息提示 + +## 扩展建议 + +1. 添加用户认证功能,支持多用户使用 +2. 添加备忘录搜索和过滤功能 +3. 添加导出和导入功能 +4. 实现数据备份和恢复功能 +5. 集成提醒功能,在截止时间前发送通知 \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000..fd873c0 --- /dev/null +++ b/app.py @@ -0,0 +1,162 @@ +from flask import Flask, render_template, request, redirect, url_for, flash +from flask_sqlalchemy import SQLAlchemy +from datetime import datetime +import pytz + +app = Flask(__name__) +app.config['SECRET_KEY'] = 'your-secret-key' +app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///notes.db' +app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False + +db = SQLAlchemy(app) + +# 获取本地时间 +local_tz = pytz.timezone('Asia/Shanghai') + +def get_local_time(): + return datetime.now(local_tz) + +# 备忘录模型 +class Note(db.Model): + id = db.Column(db.Integer, primary_key=True) + title = db.Column(db.String(100), nullable=False) + content = db.Column(db.Text, nullable=False) + created_at = db.Column(db.DateTime, default=get_local_time) + due_time = db.Column(db.DateTime, nullable=True) + priority = db.Column(db.String(2), default='P1') # P0, P1, P2 + is_completed = db.Column(db.Boolean, default=False) + + def __repr__(self): + return f'' + +# 初始化数据库 +with app.app_context(): + db.create_all() + +# 首页 - 显示备忘录列表 +@app.route('/') +def index(): + # 按优先级和完成状态排序 + # 未完成的按优先级排序,已完成的按完成时间排序 + completed_notes = Note.query.filter_by(is_completed=True).order_by(Note.created_at.desc()).all() + incomplete_notes = Note.query.filter_by(is_completed=False).order_by( + db.case( + (Note.priority == 'P0', 0), + (Note.priority == 'P1', 1), + (Note.priority == 'P2', 2), + else_=3 + ) + ).all() + + return render_template('index.html', incomplete_notes=incomplete_notes, completed_notes=completed_notes) + +# 添加备忘录 +@app.route('/add', methods=['GET', 'POST']) +def add_note(): + if request.method == 'POST': + title = request.form['title'] + content = request.form['content'] + priority = request.form['priority'] + + # 处理预计完成时间 + due_time_str = request.form['due_time'] + due_time = None + if due_time_str: + try: + due_time = datetime.strptime(due_time_str, '%Y-%m-%dT%H:%M') + due_time = local_tz.localize(due_time) + except ValueError: + flash('预计完成时间格式不正确') + return redirect(url_for('add_note')) + + new_note = Note( + title=title, + content=content, + due_time=due_time, + priority=priority + ) + + try: + db.session.add(new_note) + db.session.commit() + flash('备忘录添加成功!') + return redirect(url_for('index')) + except Exception as e: + db.session.rollback() + flash(f'添加备忘录失败: {str(e)}') + + return render_template('add_note.html') + +# 查看备忘录详情 +@app.route('/note/') +def view_note(note_id): + note = Note.query.get_or_404(note_id) + return render_template('view_note.html', note=note) + +# 编辑备忘录 +@app.route('/edit/', methods=['GET', 'POST']) +def edit_note(note_id): + note = Note.query.get_or_404(note_id) + + if request.method == 'POST': + note.title = request.form['title'] + note.content = request.form['content'] + note.priority = request.form['priority'] + note.is_completed = 'is_completed' in request.form + + # 处理预计完成时间 + due_time_str = request.form['due_time'] + if due_time_str: + try: + due_time = datetime.strptime(due_time_str, '%Y-%m-%dT%H:%M') + note.due_time = local_tz.localize(due_time) + except ValueError: + flash('预计完成时间格式不正确') + return redirect(url_for('edit_note', note_id=note_id)) + else: + note.due_time = None + + try: + db.session.commit() + flash('备忘录更新成功!') + return redirect(url_for('view_note', note_id=note_id)) + except Exception as e: + db.session.rollback() + flash(f'更新备忘录失败: {str(e)}') + + # 为表单准备时间格式 + due_time_formatted = note.due_time.strftime('%Y-%m-%dT%H:%M') if note.due_time else '' + + return render_template('edit_note.html', note=note, due_time_formatted=due_time_formatted) + +# 删除备忘录 +@app.route('/delete/') +def delete_note(note_id): + note = Note.query.get_or_404(note_id) + + try: + db.session.delete(note) + db.session.commit() + flash('备忘录删除成功!') + except Exception as e: + db.session.rollback() + flash(f'删除备忘录失败: {str(e)}') + + return redirect(url_for('index')) + +# 标记备忘录完成状态 +@app.route('/toggle_completed/') +def toggle_completed(note_id): + note = Note.query.get_or_404(note_id) + note.is_completed = not note.is_completed + + try: + db.session.commit() + except Exception as e: + db.session.rollback() + flash(f'更新状态失败: {str(e)}') + + return redirect(url_for('index')) + +if __name__ == '__main__': + app.run(debug=True) \ No newline at end of file diff --git a/instance/notes.db b/instance/notes.db new file mode 100644 index 0000000..384a201 Binary files /dev/null and b/instance/notes.db differ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..eccead5 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +flask==3.0.0 +flask-sqlalchemy==3.1.1 +pytz==2023.3.post1 \ No newline at end of file diff --git a/templates/add_note.html b/templates/add_note.html new file mode 100644 index 0000000..733b9f2 --- /dev/null +++ b/templates/add_note.html @@ -0,0 +1,45 @@ +{% extends 'base.html' %} + +{% block content %} +
+

添加新备忘录

+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + + + 设置备忘录的预计完成时间,留空表示不设置截止时间 + +
+ +
+ + + 取消 + +
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..95b057b --- /dev/null +++ b/templates/base.html @@ -0,0 +1,344 @@ + + + + + + 备忘录应用 + + + +
+
+

个人备忘录

+

记录生活和工作中的每一个重要时刻

+
+
+ +
+ + {% with messages = get_flashed_messages() %} + {% if messages %} + {% for message in messages %} +
+ {{ message }} +
+ {% endfor %} + {% endif %} + {% endwith %} + + + {% block content %} + {% endblock %} +
+ + \ No newline at end of file diff --git a/templates/edit_note.html b/templates/edit_note.html new file mode 100644 index 0000000..488bec7 --- /dev/null +++ b/templates/edit_note.html @@ -0,0 +1,49 @@ +{% extends 'base.html' %} + +{% block content %} +
+

编辑备忘录

+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+
+ + +
+
+ +
+ + + 取消 + +
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..fa89e63 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,121 @@ +{% extends 'base.html' %} + +{% block content %} + + + + +
+

📝 待办事项

+ + {% if incomplete_notes %} + {% for note in incomplete_notes %} +
+
+
+

+ + {{ note.title }} + +

+
+ + {{ note.priority }} + + + {% if note.due_time %} + + 🕒 截止: {{ note.due_time.strftime('%Y-%m-%d %H:%M') }} + + {% endif %} +
+
+
+ +

+ {{ note.content[:150] }}{% if note.content|length > 150 %}...{% endif %} +

+ + +
+ {% endfor %} + {% else %} +
+

暂无待办事项

+

添加一个新的备忘录开始记录吧!

+
+ {% endif %} +
+ + + {% if completed_notes %} +
+

✅ 已完成事项

+ + {% for note in completed_notes %} +
+
+
+

+ + {{ note.title }} + +

+
+ + {{ note.priority }} + + + + 已完成 + +
+
+
+ +

+ {{ note.content[:150] }}{% if note.content|length > 150 %}...{% endif %} +

+ + +
+ {% endfor %} +
+ {% endif %} +{% endblock %} \ No newline at end of file diff --git a/templates/view_note.html b/templates/view_note.html new file mode 100644 index 0000000..7eadc73 --- /dev/null +++ b/templates/view_note.html @@ -0,0 +1,84 @@ +{% extends 'base.html' %} + +{% block content %} +
+
+
+

{{ note.title }}

+
+ + {{ note.priority }} + + + + {{ '已完成' if note.is_completed else '未完成' }} + +
+
+ + +
+ +
+

详情

+
+ {{ note.content }} +
+
+ +
+

备忘录信息

+ +
+
+ 创建时间: {{ note.created_at.strftime('%Y-%m-%d %H:%M:%S') }} +
+ + {% if note.due_time %} +
+ 预计完成时间: {{ note.due_time.strftime('%Y-%m-%d %H:%M:%S') }} +
+ {% else %} +
+ 预计完成时间: 未设置 +
+ {% endif %} + +
+ 优先级: + {% if note.priority == 'P0' %}紧急重要 + {% elif note.priority == 'P1' %}一般重要 + {% elif note.priority == 'P2' %}不太紧急 + {% endif %} +
+ +
+ 状态: {{ '已完成' if note.is_completed else '未完成' }} +
+
+
+ +
+ + 返回列表 + + + {% if not note.is_completed %} + + 标记为完成 + + {% else %} + + 标记为未完成 + + {% endif %} +
+
+{% endblock %} \ No newline at end of file