目录

MyTools — 个人效率工具集

一个基于 React + FastAPI 的全栈个人效率管理应用,提供待办事项、日程管理、工具箱、个人中心等功能。

✨ 功能特性

模块 说明
🔐 用户认证 JWT Token 登录/登出、注册、个人资料、权限控制(admin/user)
📝 待办事项 完整 CRUD、分页、状态筛选、关键词搜索、文件附件、Markdown 富文本
📅 日程管理 日/周/月视图、事件创建编辑、颜色分类、日期范围筛选
🧰 工具箱 内置工具(JSON 格式化、Base64、URL 编码等)+ 自定义工具收藏
📊 数据统计 总待办数、完成率、本周日程数等 Dashboard 指标
📤 文件上传 统一上传接口、UUID 安全命名、物理删除

🏗 技术架构

┌─────────────────────────────────────────────────┐
│                   Nginx (80)                     │
│  ┌─────────────┐  ┌─────────────────────────┐  │
│  │  前端静态资源 │  │   /api/*  → 反向代理    │  │
│  │  (dist/)     │  │   /uploads/* → 反向代理 │  │
│  └─────────────┘  └─────────────────────────┘  │
│                        │                        │
└────────────────────────┼────────────────────────┘
                         ▼
┌─────────────────────────────────────────────────┐
│              FastAPI (uvicorn :8000)             │
│  ┌──────────┐ ┌──────────┐ ┌────────────────┐  │
│  │  CORS    │ │  JWT 鉴权 │ │  异常处理      │  │
│  └──────────┘ └──────────┘ └────────────────┘  │
│  ┌──────────────────────────────────────────┐   │
│  │  API 路由层 (auth/todos/schedules/...)  │   │
│  └──────────────────────────────────────────┘   │
│  ┌──────────────────────────────────────────┐   │
│  │  Service 层 (SQLAlchemy 2.0 async)      │   │
│  └──────────────────────────────────────────┘   │
└────────────────────────┼────────────────────────┘
                         ▼
              MySQL 8+ (aiomysql)

技术栈

前端:

  • React 18 + TypeScript
  • Vite 5 构建工具
  • Zustand 5 状态管理
  • React Router v6 路由
  • Axios HTTP 客户端
  • CSS Modules 样式隔离
  • dayjs 日期处理
  • lucide-react 图标
  • react-markdown Markdown 编辑

后端:

  • FastAPI 0.115
  • SQLAlchemy 2.0 (async)
  • aiomysql 异步 MySQL 驱动
  • Pydantic v2 数据校验
  • python-jose JWT
  • passlib[bcrypt] 密码加密
  • python-multipart 文件上传

📁 项目结构

mytools/
├── frontend/                          # 前端应用
│   ├── src/
│   │   ├── components/                # 可复用组件
│   │   │   ├── common/                # Button / Modal / Pagination / Empty / Badge / Input / ConfirmDialog
│   │   │   ├── file/                  # FileUploader / AttachmentList
│   │   │   ├── form/                  # ColorPicker / IconPicker
│   │   │   ├── layout/                # MainLayout / Navbar
│   │   │   ├── markdown/              # MarkdownEditor / MarkdownPreview
│   │   │   └── toolbox/               # ToolCard / CategoryFilter / ToolSearch / BuiltinToolsConfig
│   │   ├── pages/                     # 页面
│   │   │   ├── Login/                 # 登录页
│   │   │   ├── Dashboard/             # 工作台(待办列表)
│   │   │   ├── Schedule/              # 日程管理
│   │   │   ├── Toolbox/               # 工具箱
│   │   │   └── About/                 # 关于
│   │   ├── services/                  # API 服务层
│   │   │   ├── http.ts                # Axios 实例 + 拦截器
│   │   │   ├── authService.ts         # 认证 API
│   │   │   ├── todoService.ts         # 待办 API
│   │   │   ├── scheduleService.ts     # 日程 API
│   │   │   ├── toolService.ts         # 工具 API
│   │   │   └── uploadService.ts       # 上传 API
│   │   ├── stores/                    # Zustand 状态
│   │   │   ├── authStore.ts
│   │   │   ├── todoStore.ts
│   │   │   ├── scheduleStore.ts
│   │   │   └── toolStore.ts
│   │   ├── types/                     # TypeScript 类型
│   │   │   ├── models.ts              # 数据模型(User / Todo / ScheduleEvent / Tool / Stats / Attachment)
│   │   │   └── api.ts                 # API 类型(ApiResponse / PageParams / PageResult / LoginRequest 等)
│   │   ├── router/index.tsx           # 路由配置 + 路由守卫
│   │   ├── utils/                     # storage.ts / validators.ts
│   │   ├── styles/                    # global.css / variables.css
│   │   ├── App.tsx
│   │   └── main.tsx
│   ├── .env.development               # 开发环境变量
│   ├── .env.production                # 生产环境变量
│   ├── index.html
│   ├── vite.config.ts                 # Vite + Proxy 配置
│   ├── tsconfig.json
│   └── package.json
│
├── backend/                           # 后端应用
│   ├── app/
│   │   ├── api/                       # 路由层
│   │   │   ├── auth.py                # POST /api/auth/login,logout,register,me,profile
│   │   │   ├── todos.py               # GET/POST/PUT/DELETE /api/todos
│   │   │   ├── schedules.py           # GET/POST/PUT/DELETE /api/schedules
│   │   │   ├── tools.py               # GET/POST/PUT/DELETE /api/tools
│   │   │   ├── upload.py              # POST /api/upload
│   │   │   ├── stats.py               # GET /api/dashboard/stats
│   │   │   ├── deps.py                # 依赖注入(get_db / get_current_user)
│   │   │   └── __init__.py
│   │   ├── core/                      # 核心模块
│   │   │   ├── config.py              # 配置加载(.env → Settings)
│   │   │   ├── security.py            # JWT 创建/验证 + bcrypt 密码
│   │   │   └── exceptions.py          # 自定义异常类
│   │   ├── models/                    # SQLAlchemy 模型
│   │   │   ├── base.py                # 异步引擎 + SessionFactory
│   │   │   ├── user.py                # User 模型
│   │   │   ├── todo.py                # Todo + Attachment 模型
│   │   │   ├── schedule.py            # ScheduleEvent 模型
│   │   │   └── tool.py                # Tool 模型
│   │   ├── schemas/                   # Pydantic 校验模型
│   │   │   ├── common.py              # ApiResponse[T] / PageParams / PageResult[T]
│   │   │   ├── user.py                # LoginRequest / LoginResponse / UserResponse 等
│   │   │   ├── todo.py                # TodoCreate / TodoResponse 等
│   │   │   ├── schedule.py            # ScheduleEvent 相关 schema
│   │   │   ├── tool.py                # Tool 相关 schema
│   │   │   ├── upload.py              # UploadResponse
│   │   │   └── stats.py               # StatsResponse
│   │   ├── main.py                    # FastAPI 入口(lifespan 建表/种子)
│   │   ├── run.py                     # 启动脚本
│   │   ├── seed.py                    # 默认管理员种子数据
│   │   └── __init__.py
│   ├── .env                           # 环境变量
│   └── requirements.txt
│
└── deploy/                            # 部署配置
    ├── nginx.conf                     # Nginx 反向代理
    └── mytools-backend.service        # systemd 服务单元

🚀 快速开始

环境要求

  • Node.js ≥ 18
  • Python ≥ 3.10
  • MySQL ≥ 8.0
  • npm ≥ 9 / pnpm ≥ 8

1. 克隆项目

git clone <repo-url>
cd mytools

2. 后端配置

cd backend

# 创建虚拟环境
python -m venv venv

# Windows 激活
venv\Scripts\activate

# Linux/macOS 激活
source venv/bin/activate

# 安装依赖
pip install -r requirements.txt

编辑 .env 文件,修改数据库和密钥配置:

DATABASE_URL=mysql+aiomysql://用户名:密码@localhost:3306/mytools?charset=utf8mb4
SECRET_KEY=<使用 openssl rand -hex 32 生成>
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=10080
UPLOAD_DIR=uploads
ALLOWED_ORIGINS=http://localhost:5173

创建 MySQL 数据库:

CREATE DATABASE mytools CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

启动后端开发服务器:

uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

启动后会自动:

  • 创建所有数据表
  • 创建默认管理员账号

默认管理员: admin / admin123(⚠️ 生产环境请立即修改!)

3. 前端配置

cd frontend

# 安装依赖
npm install

开发模式启动:

npm run dev

访问 http://localhost:5173

Vite 已配置代理,/api/uploads 请求会自动转发到 localhost:8000,无需配置 CORS。

4. 生产构建

# 前端构建
cd frontend
npm run build
# 产物输出到 frontend/dist/

# 后端无需构建,直接用 uvicorn 启动

📡 API 文档

启动后端后访问:http://localhost:8000/docs(Swagger UI)或 http://localhost:8000/redoc(ReDoc)

统一响应格式

所有接口均使用以下 JSON 结构:

{
  "code": 0,
  "message": "success",
  "data": { ... }
}
  • code0 表示成功,非零表示错误
  • message:人类可读的消息
  • data:具体返回数据,类型因接口而异

认证接口

方法 路径 说明
POST /api/auth/login 登录,返回 JWT Token
POST /api/auth/logout 登出
POST /api/auth/register 注册新用户
GET /api/auth/me 获取当前用户信息
PUT /api/auth/profile 更新个人资料

登录请求示例:

POST /api/auth/login
Content-Type: application/json

{
  "username": "admin",
  "password": "admin123",
  "remember": true
}

登录响应示例:

{
  "code": 0,
  "message": "success",
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "user": {
      "id": 1,
      "username": "admin",
      "email": "admin@mytools.local",
      "avatar": null,
      "role": "admin",
      "is_active": true,
      "created_at": "2026-08-03T10:00:00Z"
    }
  }
}

认证方式: 后续请求在 Authorization 头中携带 Token:

Authorization: Bearer <token>

待办事项接口

方法 路径 说明
GET /api/todos 列表(支持分页、筛选、搜索)
POST /api/todos 创建待办
GET /api/todos/{id} 获取详情
PUT /api/todos/{id} 更新待办
DELETE /api/todos/{id} 删除待办
POST /api/todos/{id}/complete 标记完成
POST /api/todos/{id}/uncomplete 取消完成
POST /api/todos/{id}/attachments 上传附件
DELETE /api/todos/attachments/{id} 删除附件

查询参数(列表):

  • page:页码(默认 1)
  • page_size:每页数量(默认 20)
  • keyword:关键词搜索(标题/内容/简介)
  • status:状态筛选(active / expired / completed

日程管理接口

方法 路径 说明
GET /api/schedules 列表(支持日期范围筛选)
POST /api/schedules 创建事件
PUT /api/schedules/{id} 更新事件
DELETE /api/schedules/{id} 删除事件

查询参数:

  • start_date:开始日期(YYYY-MM-DD)
  • end_date:结束日期(YYYY-MM-DD)

工具箱接口

方法 路径 说明
GET /api/tools 列表(支持分类和关键词筛选)
POST /api/tools 创建自定义工具
PUT /api/tools/{id} 更新工具
DELETE /api/tools/{id} 删除工具

上传接口

方法 路径 说明
POST /api/upload 统一文件上传

请求: multipart/form-data,字段名 file

响应:

{
  "code": 0,
  "message": "上传成功",
  "data": {
    "url": "/uploads/a1b2c3d4.pdf",
    "filename": "document.pdf",
    "size": 102400
  }
}

统计接口

方法 路径 说明
GET /api/dashboard/stats 获取 Dashboard 统计数据

响应:

{
  "code": 0,
  "data": {
    "total_todos": 42,
    "completed_todos": 28,
    "week_schedules": 5,
    "completion_rate": 66.7
  }
}

健康检查

方法 路径 说明
GET /api/health 服务健康检查(无需认证)

🗄 数据模型

User(用户)

字段 类型 说明
id int 主键
username str 用户名(唯一)
email str 邮箱(唯一)
hashed_password str bcrypt 加密密码
avatar str 头像 URL
role str admin / user
is_active bool 是否启用
created_at datetime 创建时间

Todo(待办)

字段 类型 说明
id int 主键
title str 标题
brief str 简介
content str 详细内容(支持 Markdown)
start_date date 开始日期
end_date date 结束日期
status str active / expired / completed
color str todo-yellow / todo-blue / todo-green / todo-pink
user_id int 所属用户
attachments list 附件列表
created_at / updated_at datetime 时间戳

ScheduleEvent(日程事件)

字段 类型 说明
id int 主键
title str 事件标题
date date 日期
start_time / end_time time 时间段
color str 颜色标识
description str 描述
user_id int 所属用户

Tool(工具)

字段 类型 说明
id int 主键
title str 工具名称
description str 工具描述
category str text / encode / format / dev / calc
icon str 图标名
icon_color str 图标颜色
type str builtin / custom
url str 工具链接
user_id int 创建者(仅 custom 类型)

Attachment(附件)

字段 类型 说明
id int 主键
todo_id int 关联待办
filename str 原始文件名
file_path str 存储路径
file_size int 文件大小(字节)
uploaded_at datetime 上传时间

🔐 安全说明

  • 密码加密:使用 bcrypt 算法,加盐存储
  • JWT Token:HS256 签名,默认有效期 7 天
  • Token 存储:前端 localStorage,请求时自动附加到 Header
  • 路由守卫:前端 React Router 检查 Token,未登录自动跳转
  • 后端鉴权:受保护接口通过 get_current_user 依赖注入验证
  • 权限控制:区分 adminuser 角色,admin 可管理所有用户数据
  • 文件上传:UUID 重命名防止路径遍历,物理删除同步清理

📦 部署指南

生产环境目录结构

/var/www/mytools/
├── frontend/
│   └── dist/              # 前端构建产物
├── backend/
│   ├── app/
│   ├── venv/
│   ├── .env
│   ├── requirements.txt
│   └── uploads/           # 上传文件目录
├── nginx.conf             # Nginx 配置
└── mytools-backend.service

步骤一:服务器环境准备

# Ubuntu 22.04/24.04
sudo apt update && sudo apt upgrade -y
sudo apt install -y nginx mysql-server python3 python3-venv python3-pip

# 安装 Node.js 20
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs

# 安装 PM2(可选,用于前端构建等)
sudo npm install -g pm2

步骤二:MySQL 配置

sudo mysql_secure_installation

# 创建数据库和用户
sudo mysql -u root -p
CREATE DATABASE mytools CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'mytools'@'localhost' IDENTIFIED BY '<强密码>';
GRANT ALL PRIVILEGES ON mytools.* TO 'mytools'@'localhost';
FLUSH PRIVILEGES;

步骤三:部署后端

# 上传后端代码到服务器
scp -r backend/ user@server:/var/www/mytools/
ssh user@server

cd /var/www/mytools/backend

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install gunicorn

# 修改 .env
vi .env

.env 生产环境示例:

DATABASE_URL=mysql+aiomysql://mytools:<强密码>@localhost:3306/mytools?charset=utf8mb4
SECRET_KEY=<使用 openssl rand -hex 32 生成的 64 字符密钥>
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=10080
UPLOAD_DIR=uploads
ALLOWED_ORIGINS=https://your-domain.com,https://www.your-domain.com

步骤四:配置 systemd 服务

# 创建运行用户
sudo useradd -r -s /bin/false mytools
sudo mkdir -p /var/www/mytools/backend/uploads
sudo chown -R mytools:mytools /var/www/mytools

# 复制服务配置
sudo cp /var/www/mytools/deploy/mytools-backend.service /etc/systemd/system/mytools-backend.service
sudo systemctl daemon-reload
sudo systemctl enable mytools-backend
sudo systemctl start mytools-backend

# 检查状态
sudo systemctl status mytools-backend

# 查看日志
sudo journalctl -u mytools-backend -f

步骤五:部署前端

# 本地构建
cd frontend
npm run build

# 上传产物
scp -r dist/ user@server:/var/www/mytools/frontend/

步骤六:配置 Nginx

sudo cp /var/www/mytools/deploy/nginx.conf /etc/nginx/conf.d/mytools.conf

# 修改 nginx.conf 中的 server_name 和 root 路径
sudo nginx -t
sudo systemctl restart nginx

HTTPS 配置(推荐):

# 使用 Let's Encrypt
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com -d www.your-domain.com

步骤七:验证部署

# 检查后端 API
curl http://localhost:8000/api/health

# 检查 Nginx 转发
curl http://localhost/api/health

# 浏览器访问
# http://your-domain.com

常用运维命令

# 查看后端日志
sudo journalctl -u mytools-backend -f

# 重启后端
sudo systemctl restart mytools-backend

# 重新加载 Nginx 配置
sudo nginx -t && sudo systemctl reload nginx

# 数据库备份
mysqldump -u mytools -p mytools > backup_$(date +%Y%m%d).sql

# 数据库恢复
mysql -u mytools -p mytools < backup_20260803.sql

🛠 开发调试

后端调试

# 开发模式(自动重载)
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

# 查看 API 文档
# http://localhost:8000/docs
# http://localhost:8000/redoc

前端调试

# 开发模式(Vite Dev Server + Proxy)
npm run dev

# 类型检查
npx tsc --noEmit

# 构建预览
npm run build && npm run preview

环境变量

前端 .env.development

VITE_API_BASE_URL=/api
VITE_APP_TITLE=MyTools Dev

前端 .env.production

VITE_API_BASE_URL=/api
VITE_APP_TITLE=MyTools

后端 .env

变量 说明 默认值
DATABASE_URL MySQL 连接字符串 mysql+aiomysql://root:password@localhost:3306/mytools?charset=utf8mb4
SECRET_KEY JWT 签名密钥 change-me-in-production
ALGORITHM JWT 算法 HS256
ACCESS_TOKEN_EXPIRE_MINUTES Token 有效期(分钟) 10080(7天)
UPLOAD_DIR 上传文件存储目录 uploads
ALLOWED_ORIGINS CORS 允许的源(逗号分隔) http://localhost:5173

❗ 常见问题

Q: 启动时报 “Table doesn’t exist”?

首次启动时 FastAPI 会在 lifespan 阶段自动建表。如果报错,请确认:

  1. MySQL 服务已启动
  2. .env 中的 DATABASE_URL 配置正确
  3. 数据库已创建(CREATE DATABASE mytools ...

Q: 如何修改默认管理员密码?

登录后通过前端 “关于” 页面的个人资料修改,或直接操作数据库:

UPDATE users SET hashed_password='<新的bcrypt哈希>' WHERE username='admin';

Q: 前端请求 404?

开发模式下 Vite 会将 /api 代理到 localhost:8000。请确认:

  1. 后端服务已启动
  2. 前端 vite.config.ts 中代理配置正确
  3. 后端 CORS 允许的源包含前端地址

Q: 文件上传失败?

  1. 确认 uploads/ 目录存在且有写入权限
  2. 检查 Nginx 配置中 /uploads/ 路径的代理
  3. 生产环境建议使用 Nginx 直接静态服务上传目录

📄 License

Private — 仅供内部使用

关于
11.2 MB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802047560号