diff --git a/README.md b/README.md index 65e31ba..a73e82e 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,18 @@ └─────────────┴──────────────┴──────────────┴──────────────┘ ``` +### 仪表盘 +![仪表盘](img/仪表盘.png) + +### 邮箱管理界面 +![邮箱界面](img/邮箱界面.png) + +### 验证码提取功能 +![提取验证码](img/提取验证码.png) + +### 系统设置 +![设置界面](img/设置界面.png) + ## 🚀 快速开始 ### 使用 Docker(推荐) diff --git a/docs/CN/CN-00001-2026-03-01-project-overview-read.md b/docs/CN/CN-00001-2026-03-01-project-overview-read.md new file mode 100644 index 0000000..a7409b8 --- /dev/null +++ b/docs/CN/CN-00001-2026-03-01-project-overview-read.md @@ -0,0 +1,72 @@ +# Readable Summary + + +1. 用户希望我先充分阅读整个项目的前端与后端代码,并在后续只接受命令式指令,所以我首先梳理了 README 以掌握项目简介与目录布局。 +2. 之后深入查看了后端入口 `web_outlook_app.py` 及核心工厂 `outlook_web/app.py`,确认使用 Flask 工厂模式、Blueprint 注册、调度器控制与错误处理中间件的配置。 +3. 为完成“前端代码”阅读要求,我又审阅了 `static/js/main.js`、`static/js/features/emails.js` 以及 `static/css/main.css`,了解状态管理、邮件渲染、主题切换等关键逻辑与配色体系。 + + + +# Session Handoff Plan + +## 1. Primary Request and Intent +- 浏览项目前后端代码,提前准备好接收命令式指令。当前需求尚未指定具体修改/功能,只需掌握项目结构与核心逻辑。 + +## 2. Key Technical Concepts +- Flask 应用工厂+Blueprint; +- 自定义中间件(Trace ID、异常捕获)与 CSRF 初始化; +- 定时任务调度自动启动逻辑; +- 前端全局状态管理、页面导航、邮件列表渲染、轮询/缓存; +- 自定义国风主题 CSS 变量与布局; +- API 依赖 `/api/*` 路径(groups, accounts, emails, temp-emails, settings)。 + +## 3. Files and Code Sections +### README.md +- **Why important**: 介绍技术栈、部署方式、项目结构和核心特性,确认后端模块位于 `outlook_web/`,前端资源在 `static/` 与 `templates/`。 +- **Changes made**: 无修改,仅参考。 + +### outlook_web/app.py +- **Why important**: 提供 Flask 工厂实现并按需初始化数据库、CSRF、错误处理与 Blueprint。它是后端模块化的核心集成点。 +- **Code snippet**: +```python + app.register_blueprint(pages.create_blueprint(csrf_exempt=csrf_exempt)) + app.register_blueprint(groups.create_blueprint()) + app.register_blueprint(tags.create_blueprint()) + ... + app.register_error_handler(Exception, handle_exception) +``` + +### web_outlook_app.py +- **Why important**: 兼容旧入口,导出常用 helper,控制调度器在 debug 自动重载下的启动,并保持 `app` 变量可用。 + +### static/js/main.js +- **Why important**: 管理主题、导航、不同页面的数据加载、登录/登出流程以及顶部操作栏,直接驱动 Web UI 页面切换。 +- **Code snippet**: +```javascript + function navigate(page) { + currentPage = page; + document.querySelectorAll('.page').forEach(p => p.classList.add('page-hidden')); + const target = document.getElementById('page-' + page); + if (target) target.classList.remove('page-hidden'); + if (page === 'mailbox') { ... } + } +``` + +### static/js/features/emails.js +- **Why important**: 控制邮件列表与批量操作、根据方法(Graph/IMAP)缓存结果并在 UI 中显示详细错误信息。 + +### static/css/main.css +- **Why important**: 定义国风调色、深色模式变量、登录页、侧边栏与按钮样式,是前端主题与可访问性基础。 + +## 4. Problem Solving +- 通过多个工具(glob、view)逐步确认目录结构并读取关键文件,未遇到技术问题,仅需适当缩减超大文件的展示范围。 + +## 5. Pending Tasks +- 等待用户逐条下达命令;当前仅完成代码预览与总结。 + +## 6. Current Work +- 正在响应“充分阅读前后端代码”的要求,重点查看后端工厂/入口、静态 JS 管理逻辑与配色文件。 + +## 7. Optional Next Step +- 若下一步指令仍是“研究/阅读”类内容,可继续深入 controllers/services 或 templates;如需具体改动,则等待用户提供任务描述。 + diff --git a/img/全局搜索.png b/img/全局搜索.png deleted file mode 100644 index d2337c9..0000000 Binary files a/img/全局搜索.png and /dev/null differ diff --git a/img/全量刷新token.png b/img/全量刷新token.png deleted file mode 100644 index 2a0a2c9..0000000 Binary files a/img/全量刷新token.png and /dev/null differ diff --git a/img/导入邮箱账号.png b/img/导入邮箱账号.png deleted file mode 100644 index 01ee3a3..0000000 Binary files a/img/导入邮箱账号.png and /dev/null differ diff --git a/img/应用注册.png b/img/应用注册.png deleted file mode 100644 index c604d72..0000000 Binary files a/img/应用注册.png and /dev/null differ diff --git a/img/换取token.png b/img/换取token.png deleted file mode 100644 index 9b59963..0000000 Binary files a/img/换取token.png and /dev/null differ diff --git a/img/标签管理.png b/img/标签管理.png deleted file mode 100644 index 7d0e41d..0000000 Binary files a/img/标签管理.png and /dev/null differ diff --git a/img/注册应用程序.png b/img/注册应用程序.png deleted file mode 100644 index 41eb8af..0000000 Binary files a/img/注册应用程序.png and /dev/null differ diff --git a/img/登录失败强制间隔.png b/img/登录失败强制间隔.png deleted file mode 100644 index ce1e92f..0000000 Binary files a/img/登录失败强制间隔.png and /dev/null differ diff --git a/img/获取应用程序ID.png b/img/获取应用程序ID.png deleted file mode 100644 index 016efac..0000000 Binary files a/img/获取应用程序ID.png and /dev/null differ diff --git a/img/设置-按corn定时刷新.png b/img/设置-按corn定时刷新.png deleted file mode 100644 index 1a97158..0000000 Binary files a/img/设置-按corn定时刷新.png and /dev/null differ diff --git a/img/设置-按天数定时刷新.png b/img/设置-按天数定时刷新.png deleted file mode 100644 index a5ea35c..0000000 Binary files a/img/设置-按天数定时刷新.png and /dev/null differ diff --git a/img/邮箱列表.png b/img/邮箱列表.png deleted file mode 100644 index ca93dd6..0000000 Binary files a/img/邮箱列表.png and /dev/null differ diff --git a/start.py b/start.py index 2c9a09a..180229e 100644 --- a/start.py +++ b/start.py @@ -1,19 +1,80 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ -启动脚本 - 加载环境变量并启动 Flask 应用 +启动脚本 - 智能初始化环境变量并启动 Flask 应用 """ import os +import secrets +import shutil import sys from dotenv import load_dotenv + +def ensure_env_file(): + """确保 .env 文件存在且 SECRET_KEY 已正确配置""" + env_file = ".env" + env_example = ".env.example" + + # 1. 如果 .env 不存在,从 .env.example 复制 + if not os.path.exists(env_file): + if os.path.exists(env_example): + print(f"⚠️ 未找到 {env_file},从 {env_example} 复制...") + shutil.copy(env_example, env_file) + else: + print(f"❌ 错误:{env_example} 文件不存在") + sys.exit(1) + + # 2. 读取 .env 文件内容 + with open(env_file, "r", encoding="utf-8") as f: + lines = f.readlines() + + # 3. 检查 SECRET_KEY 是否需要生成 + secret_key_line_index = -1 + current_secret_key = None + + for i, line in enumerate(lines): + if line.strip().startswith("SECRET_KEY="): + secret_key_line_index = i + current_secret_key = line.split("=", 1)[1].strip() + break + + # 4. 如果 SECRET_KEY 是占位符或为空,生成新的 + if current_secret_key in [None, "", "your-secret-key-here"]: + new_secret_key = secrets.token_hex(32) + + if secret_key_line_index >= 0: + lines[secret_key_line_index] = f"SECRET_KEY={new_secret_key}\n" + else: + # 如果没有找到 SECRET_KEY 行,添加到文件开头 + lines.insert(0, f"SECRET_KEY={new_secret_key}\n") + + # 写回文件 + with open(env_file, "w", encoding="utf-8") as f: + f.writelines(lines) + + print("=" * 60) + print("✅ 已自动生成新的 SECRET_KEY") + print(f"🔑 SECRET_KEY: {new_secret_key}") + print("=" * 60) + print("⚠️ 重要提醒:") + print(" 1. SECRET_KEY 用于加密数据库中的敏感信息") + print(" 2. 请务必备份 .env 文件,丢失后将无法解密旧数据") + print(" 3. 不要将 .env 文件提交到 Git 仓库") + print("=" * 60) + else: + print(f"✅ 使用现有的 SECRET_KEY(已保护数据安全)") + + +# 初始化环境文件 +ensure_env_file() + # 加载 .env 文件中的环境变量 load_dotenv() # 确保环境变量已加载 if not os.getenv("SECRET_KEY"): - print("错误:SECRET_KEY 环境变量未设置") + print("❌ 错误:SECRET_KEY 环境变量未设置") sys.exit(1) # 直接运行 web_outlook_app.py