# weeklywork **Repository Path**: jakHall/weeklywork ## Basic Information - **Project Name**: weeklywork - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-04-24 - **Last Updated**: 2025-04-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Tauri + Vanilla This template should help get you started developing with Tauri in vanilla HTML, CSS and Javascript. ## Recommended IDE Setup - [VS Code](https://code.visualstudio.com/) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer) Okay,作为项目经理,我为你整理和完善了一份基于你提供信息和需求的 **Todo & Project Management 应用项目设计书**。我补充了一些细节,并对结构进行了整理,以确保设计的清晰度和可行性。 ```markdown # 项目设计书:Tauri Todo & Project Management 应用 **版本**: 1.0 **日期**: 2024-07-08 **负责人**: [你的名字或团队] ## 1. 项目概述 本项目旨在开发一个基于 Tauri 框架的桌面应用程序,用于个人待办事项(Todo)和项目管理。应用后端使用 Rust 语言和 `rusqlite` 操作 SQLite 数据库进行数据持久化,前端使用 HTML, CSS, 和 JavaScript 构建用户界面。核心功能包括多视图(月、周、日、项目、标签)展示待办事项,支持创建、编辑、删除、查询、排序和过滤 Todo,并关联到项目和标签。 **技术栈:** * **框架**: Tauri (Rust Backend + Webview Frontend) * **后端语言**: Rust * **数据库**: SQLite (via `rusqlite`) * **前端**: HTML, CSS, JavaScript (Vanilla JS 或可选用轻量级框架/库) * **核心库**: `rusqlite`, `chrono` (Rust), (可能需要前端日期库、Markdown 渲染库) ## 2. 项目目标 * **高效 Todo 管理**: 提供直观、快速的方式来创建、查看、更新和完成待办事项。 * **多维度视图**: 支持按日、周、月、项目、标签等多种维度组织和查看任务。 * **项目关联**: 允许将 Todo 关联到具体项目,并提供项目概览。 * **标签系统**: 支持自定义标签,方便分类和过滤。 * **持久化存储**: 使用 SQLite 本地数据库存储所有数据,确保数据安全和离线可用。 * **用户友好界面**: 提供简洁、直观的用户界面,易于上手。 * **跨平台**: 利用 Tauri 实现桌面应用程序的跨平台能力(Windows, macOS, Linux)。 ## 3. 非目标 (初步阶段) * 云同步与协作功能。 * 复杂的周期性任务规则。 * 高级报表和统计功能。 * 移动端 App。 * 用户账户系统和认证。 ## 4. 系统架构 ```mermaid graph LR A[Frontend (HTML/CSS/JS)] -- Tauri invoke() --> B(Tauri Runtime); B -- Rust Function Calls --> C{Rust Backend Logic}; C -- rusqlite API --> D[(SQLite Database)]; D -- Data --> C; C -- Result --> B; B -- Event/Promise --> A; subgraph User Interface A end subgraph Backend & Core B C D end ``` * **Frontend**: 负责用户界面展示和用户交互。通过 Tauri 提供的 `invoke` 函数调用 Rust 后端命令。 * **Tauri Runtime**: 作为前端和后端之间的桥梁,处理 `invoke` 调用、事件传递和 Webview 管理。 * **Rust Backend**: 实现核心业务逻辑,包括数据库操作、数据处理等。通过 Tauri 命令暴露接口给前端。 * **SQLite Database**: 使用 `rusqlite` 库进行本地数据持久化存储。 ## 5. 数据库设计 ### 5.1 表结构 **`projects` 表** | Column | Type | Constraints | Description | | :------------ | :------ | :--------------------------------- | :------------------ | | id | INTEGER | PRIMARY KEY AUTOINCREMENT | 项目唯一 ID | | name | TEXT | NOT NULL UNIQUE | 项目名称 | | markdown_path | TEXT | | 项目描述 Markdown 文件路径 (Nullable) | | created_at | TEXT | NOT NULL DEFAULT CURRENT_TIMESTAMP | 创建时间戳 | | updated_at | TEXT | NOT NULL DEFAULT CURRENT_TIMESTAMP | 最后更新时间戳 | **`tags` 表** | Column | Type | Constraints | Description | | :--------- | :------ | :--------------------------------- | :------------------ | | id | INTEGER | PRIMARY KEY AUTOINCREMENT | 标签唯一 ID | | name | TEXT | NOT NULL UNIQUE | 标签名称 | | created_at | TEXT | NOT NULL DEFAULT CURRENT_TIMESTAMP | 创建时间戳 | **`todos` 表** | Column | Type | Constraints | Description | | :-------------------- | :------ | :--------------------------------- | :----------------------- | | id | INTEGER | PRIMARY KEY AUTOINCREMENT | Todo 唯一 ID | | title | TEXT | NOT NULL | Todo 标题/简短描述 | | importance | TEXT | NOT NULL DEFAULT 'C' | 重要程度 (S, A, B, C, D, E, F) | | urgency | TEXT | NOT NULL DEFAULT 'C' | 紧急程度 (S, A, B, C, D, E, F) | | start_time | TEXT | | 开始时间 (ISO 8601 or similar), Nullable | | due_time | TEXT | | 截止时间 (ISO 8601 or similar), Nullable | | completion_time | TEXT | | 完成时间 (ISO 8601 or similar), Nullable | | project_id | INTEGER | REFERENCES projects(id) ON DELETE SET NULL | 关联项目 ID, Nullable | | completed | INTEGER | NOT NULL DEFAULT 0 | 是否完成 (0=否, 1=是) | | completion_percentage | INTEGER | NOT NULL DEFAULT 0 | 完成百分比 (0-100) | | markdown_path | TEXT | | Todo 详情 Markdown 文件路径 (Nullable) | | created_at | TEXT | NOT NULL DEFAULT CURRENT_TIMESTAMP | 创建时间戳 | | updated_at | TEXT | NOT NULL DEFAULT CURRENT_TIMESTAMP | 最后更新时间戳 | **`todo_tags` 表 (多对多关联)** | Column | Type | Constraints | Description | | :------- | :------ | :-------------------------------------- | :------------- | | todo_id | INTEGER | NOT NULL REFERENCES todos(id) ON DELETE CASCADE | Todo ID 外键 | | tag_id | INTEGER | NOT NULL REFERENCES tags(id) ON DELETE CASCADE | Tag ID 外键 | | | | PRIMARY KEY (todo_id, tag_id) | 联合主键 | ### 5.2 索引与触发器 * **索引**: 在 `todos` 表的 `due_time`, `start_time`, `completed`, `importance`, `urgency`, `project_id` 列上创建索引。在 `tags` 表的 `name` 列上创建索引。在 `todo_tags` 表的 `tag_id` 列上创建索引。 * **触发器**: 为 `todos` 和 `projects` 表添加 `AFTER UPDATE` 触发器,自动更新 `updated_at` 时间戳。 ### 5.3 数据库初始化与加载 * **首次启动**: 检查数据库文件是否存在。如果不存在,创建数据库文件并执行 `CREATE TABLE IF NOT EXISTS` 语句创建所有表、索引和触发器。 * **重复加载**: 应用启动时,打开数据库连接即可。`CREATE TABLE IF NOT EXISTS` 会保证表结构存在。 * **懒加载与数量限制**: * **懒加载**: 仅在需要时(如切换视图或滚动到底部)查询数据,而不是一次性加载所有数据。 * **数量限制**: 对于可能返回大量数据的查询(如按项目/标签查询),实现分页(如每页 30 条)。月视图和周视图可能需要加载对应时间范围内的所有数据以便渲染。 ## 6. 后端接口设计 (Tauri Commands - Rust) **数据结构 (Rust):** * `struct Todo { ... }` (包含 `tags: Vec`, `project_name: Option`) * `struct Project { ... }` * `struct Tag { ... }` * `struct TodoData { ... }` (用于创建/更新 Todo 的参数) * `struct PagedResult { items: Vec, total: i64, page: i32, page_size: i32 }` **命令 (Tauri `#[tauri::command]`):** | 命令名 (Fn Name) | 参数 | 返回类型 (`Result`) | 描述 | | :---------------------------- | :----------------------------------------------------------------------------------------------------------------------------------- | :-------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `create_todo` | `todo: TodoData` | `Result` | 创建一个新的 Todo 项,处理项目和标签关联。返回新 Todo 的 ID。 | | `get_todo_by_id` | `id: i64` | `Result>` | 获取指定 ID 的 Todo 详情。 | | `update_todo` | `id: i64`, `data: TodoData` | `Result<()>` | 更新指定 ID 的 Todo 信息。 | | `delete_todo` | `id: i64` | `Result<()>` | 删除指定 ID 的 Todo。 | | `update_todo_completion` | `id: i64`, `completed: bool` | `Result<()>` | 更新 Todo 的完成状态和完成时间。 | | `get_todos_by_month` | `year: i32`, `month: u32` | `Result>` | **修改**: 获取指定月份**及前后各一个月**(共三个月)的 Todo。基于 `due_time` 或 `start_time` 过滤(需明确)。默认按 `due_time` 排序,未完成在前。 | | `get_todos_by_week` | `week_start_date: String` (YYYY-MM-DD) | `Result>` | 获取指定周(从周一开始)的所有 Todo。基于 `due_time` 或 `start_time` 过滤(需明确)。 | | `get_todos_for_day` | `date: String` (YYYY-MM-DD) | `Result>` | 获取指定日期的所有 Todo。基于 `due_time` 或 `start_time` 过滤(需明确)。 | | `get_todos_by_tag` | `tag: String`, `page: i32`, `page_size: Option` (默认 30) | `Result>` | 获取包含指定标签的 Todo 列表(**修改**: 分页返回,默认每页 30 条)。排序:未完成的按 `due_time` 升序,已完成的按 `completion_time` 降序。 | | `get_all_todos_by_project` | `project_id: i64`, `page: i32`, `page_size: Option` (默认 30) | `Result>` | 获取指定项目的所有 Todo 列表,分页返回。排序:未完成的按 `due_time` 升序,已完成的按 `completion_time` 降序。 | | `get_recent_todos_by_project` | `project_id: i64` | `Result>` | 获取指定项目的**最近 30 条** Todo(**修改**: 定义“最近”,如按 `created_at` DESC?)。排序:未完成的按 `due_time` 升序排在最前,已完成的按 `completion_time` 降序排在后面。 | | `create_project` | `name: String`, `markdown_path: Option` | `Result` | 创建新项目,返回 ID。 | | `get_all_projects` | | `Result>` | 获取所有项目列表。 | | `update_project` | `id: i64`, `name: Option`, `markdown_path: Option` | `Result<()>` | 更新项目信息。 | | `get_all_tags` | | `Result>` | 获取所有标签列表(可能用于前端自动完成)。 | | `query_todos_generic` | `filter_completed: Option`, `filter_time_frame: Option`, `sort_by: Option`, `page: i32`, `page_size: Option` | `Result>` | **(新增)** 一个更通用的查询接口,支持多种过滤和排序条件,供日视图等需要灵活排序的场景使用。 `TimeFrame` (Day, Week, Month), `SortOrder` (DueDateAsc/Desc, StartDateAsc/Desc, Importance, Urgency, CreatedAtAsc/Desc) | *(注: `TodoData` 应包含所有可编辑的 Todo 字段。`TimeFrame` 和 `SortOrder` 需要定义为 Rust 枚举。)* ## 7. 前端设计 (HTML/CSS/JS) ### 7.1 通用组件 * **导航栏 (Sidebar)**: 包含切换不同视图(月、周、日、项目、标签)的按钮,高亮当前活动视图。 * **主内容区 (Main Content)**: 根据导航栏选择动态显示对应的视图。 * **Todo 添加/编辑模态框**: 包含所有 Todo 字段的表单,使用 `` 处理时间选择。 ### 7.2 视图详情 1. **月视图 (`calendar-view`)** * **UI**: 显示标准日历网格。包含上/下月切换按钮,显示当前年月。 * **数据**: 调用 `get_todos_by_month(year, month)` 获取当前月及前后月数据。 * **显示**: 在每个日期格子里简洁地列出当天到期的 Todo 标题(可能截断或用标记表示数量)。高亮显示当天。对于无数据的月份,仅绘制日历格子。 * **交互**: * 点击日期格子 -> 调用 `get_todos_for_day` 并切换到该日期的**日视图**。 * (新增) 在日期格子上提供快速添加功能:点击 "+" 或空白区域弹出简化输入框,**只输入标题**,回车调用 `create_todo` 使用默认值(截止日期为当天)创建 Todo,并刷新视图。 * (待定) 直接在格子内编辑 Todo 标题?(可能较复杂,初步可不做) 2. **周视图 (`weekly-view`)** * **UI**: 显示当前周的 7 天列。包含上/下周切换按钮,显示当前周范围和周数。 * **数据**: 调用 `get_todos_by_week(start_date)` 获取本周数据。 * **显示**: 每列显示当天的日期和星期几,下方列出当天的 Todo 标题。无数据则显示空格子。 * **交互**: 点击日期列 -> 调用 `get_todos_for_day` 并切换到该日期的**日视图**。 3. **日视图 (`daily-view`)** * **UI**: 显示当前选定日期的标题(年月日星期)。内容区分“未完成”和“已完成”两个列表区域。 * **数据**: 调用 `query_todos_generic` (或 `get_todos_for_day` 后前端排序/分组) 获取当天数据。 * **显示**: * 每个 Todo 显示为一行:`[Checkbox] [Todo 标题] [截止时间] [标签1] [标签2] ...`。 * Checkbox 表示完成状态,勾选/取消勾选调用 `update_todo_completion`。 * 已完成的 Todo 标题添加删除线。 * **颜色区分**: * 标题颜色根据 `importance` 变化(如 S/A-橙色/黄色,B/C-默认,D/E/F-灰色)。 * 标题颜色也可叠加 `urgency` (如 S/A-红色边框或图标)。需定义明确规则。 * 标签使用不同背景色的小块显示,最多显示 5 个。 * **交互**: * 点击 Checkbox 切换完成状态。 * **行内添加**: 在列表末尾(或开头)始终显示一个带下划线的输入框 `[+] Add a task...`,输入内容后按回车调用 `create_todo` (截止日期为当天),然后刷新列表。如果列表为空,则只显示此输入框。 * 双击 Todo 行 -> 弹出**Todo 编辑模态框**(或切换到 Todo 视图)。 * 点击标签 -> 切换到该标签的**标签视图**。 * 提供排序按钮/下拉菜单(按截止时间、开始时间、重要性、紧急性),点击后调用 `query_todos_generic` 刷新列表。 4. **项目视图 (`projects-view`)** * **UI**: * **动态布局**: 当项目数量少(例如 < 6-8个)时,以卡片/块形式显示;项目数量多时,切换为列表形式(仅显示项目名称)。 * **块视图**: 每个块显示项目名称,预览项目 Markdown 文件内容(需后端提供或前端读取路径后加载渲染),下方显示该项目的 Todo 列表(调用 `get_recent_todos_by_project` 获取最近 30 条,包含“查看全部”链接)。 * **列表视图**: 仅显示项目名称列表,点击项目名称展开/跳转显示其 Todo。 * **数据**: 调用 `get_all_projects` 获取项目列表。根据数量决定布局。块视图中调用 `get_recent_todos_by_project`。 * **交互**: * 点击项目(块或列表项)-> 导航到显示该项目所有 Todo 的视图(可能是复用标签视图逻辑或专门的项目 Todo 视图)。点击“查看全部”也执行此操作,并可能传入分页参数。 * 提供创建新项目的入口。 5. **Todo 视图 (`todo-view`)** (可能与模态框合并或作为独立页面) * **UI**: 显示完整的 Todo 编辑表单,包含所有字段。时间相关字段使用 HTML5 时间选择器 (``)。标签输入允许逗号分隔。 * **数据**: 如果是编辑,调用 `get_todo_by_id` 填充表单;如果是新建,显示空表单。 * **交互**: 保存按钮调用 `create_todo` 或 `update_todo`。取消按钮关闭视图/模态框。 6. **标签视图 (`tag-view`)** * **UI**: 显示当前标签名称。下方列出所有关联到该标签的 Todo。 * **数据**: 调用 `get_todos_by_tag(tag_name, page)` 获取分页数据。 * **显示**: Todo 列表显示方式同日视图(Checkbox, 标题, 标签等),但排序固定为:未完成的按截止时间升序,已完成的按完成时间降序。实现分页加载。 ## 8. 数据流与状态管理 * **Frontend -> Backend**: 所有数据操作通过 `invoke('command_name', { args })` 发起。 * **Backend -> Frontend**: Rust 函数通过 `Result` 返回数据或错误。Frontend JS 处理 Promise 的 `resolve` (成功) 或 `reject` (失败)。 * **状态管理**: * 初步可使用简单的全局变量或模块作用域变量缓存数据(如 `allTodosCache`,`currentProjects`)。 * 在数据变更操作(增删改)成功后,重新调用查询命令刷新当前视图所需的数据,并更新 UI。 * 对于更复杂的状态同步,未来可考虑引入轻量级前端状态管理库。 ## 9. 关键特性与实现要点 * **日期时间处理**: Rust 后端使用 `chrono`,前端 JS 使用 `Date` 对象。注意时区问题(建议统一使用 UTC 存储,展示时转换为本地时间)。SQLite 中使用 ISO 8601 兼容的 TEXT 格式存储。 * **数据库查询**: 精心设计 SQL 查询,利用索引优化性能。动态构建 WHERE 和 ORDER BY 子句。 * **分页**: 后端实现分页逻辑(LIMIT, OFFSET),前端实现分页控件或无限滚动加载。 * **Markdown 渲染**: * 项目视图需要渲染 Markdown。可以在 Rust 端使用 `pulldown-cmark` 等库将 Markdown 转为 HTML 字符串返回给前端。 * 或者,前端直接获取 Markdown 文件路径(如果允许访问本地文件系统)或内容,使用前端 JS Markdown 库(如 `marked.js`)渲染。Tauri 的能力允许安全的本地文件访问。 * **排序与过滤**: 后端提供灵活的查询接口,前端根据用户交互调用不同的参数。 * **UI/UX**: 保持界面简洁,交互明确。颜色、图标等辅助信息应清晰一致。 ## 10. 里程碑/开发阶段 (建议) 1. **阶段一: 基础搭建与核心 Todo 功能** * 项目初始化 (Tauri, Rust, Frontend setup)。 * 数据库 Schema 设计与实现 (Rust `rusqlite` setup)。 * 实现 Todo 的基本 CRUD 后端命令 (`create_todo`, `get_todo_by_id`, `update_todo`, `delete_todo`, `update_todo_completion`)。 * 实现基本的 Todo 添加/编辑模态框 (前端)。 * 实现简单的列表视图(如项目视图的列表模式)用于展示和测试 Todo。 2. **阶段二: 日、周、月视图实现** * 实现 `get_todos_by_month`, `get_todos_by_week`, `get_todos_for_day` 后端命令。 * 开发日历组件 (前端 JS) 用于月视图和周视图。 * 实现月、周、日视图的渲染和交互逻辑。 * 实现视图间的导航切换。 3. **阶段三: 项目与标签功能** * 实现项目和标签的数据库操作和后端命令 (`create_project`, `get_all_projects`, tag handling in `create/update_todo`)。 * 实现项目视图(包括动态布局和 Markdown 预览)。 * 实现标签视图和按标签查询的后端命令 (`get_todos_by_tag`)。 * 实现日视图中点击标签跳转的功能。 4. **阶段四: 高级功能与优化** * 实现日视图的多种排序 (`query_todos_generic`)。 * 实现分页加载。 * 完善错误处理和用户反馈。 * UI/UX 优化和细节打磨。 * 性能测试与优化。 ## 11. 开放问题与风险 * **性能**: 当 Todo 数量巨大时,查询和渲染性能可能成为瓶颈,需要关注数据库索引和前端渲染优化。 * **日期/时间处理**: 跨时区、夏令时等问题需要谨慎处理(统一 UTC 是个好策略)。 * **Markdown 安全性**: 如果允许用户输入任意 Markdown,需要防止 XSS 攻击(在前端渲染时进行净化,或后端渲染时配置安全选项)。 * **Tauri 文件系统访问**: 如果需要读写 Markdown 文件,需要正确配置 Tauri 的 `allowlist` 并处理好文件路径和权限问题。 * **排序逻辑细节**: 重要性/紧急性的具体排序权重(S>A>B...)需要在代码中明确实现。混合排序(如未完成按时间,已完成按其他)的 SQL 需要仔细构造。 * **用户体验细节**: 块视图与列表视图的切换阈值、颜色编码的具体方案、标签显示数量等需要进一步设计和测试。 ``` 目前使用tauri2和js进行开发,目前后端接口已经确认的。 | 命令名 (Fn Name) | 参数 | 返回类型 (`Result`) | 描述 | | :---------------------------- | :----------------------------------------------------------------------------------------------------------------------------------- | :-------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `create_todo` | `todo: TodoData` | `Result` | 创建一个新的 Todo 项,处理项目和标签关联。返回新 Todo 的 ID。 | | `get_todo_by_id` | `id: i64` | `Result>` | 获取指定 ID 的 Todo 详情。 | | `update_todo` | `id: i64`, `data: TodoData` | `Result<()>` | 更新指定 ID 的 Todo 信息。 | | `delete_todo` | `id: i64` | `Result<()>` | 删除指定 ID 的 Todo。 | | `update_todo_completion` | `id: i64`, `completed: bool` | `Result<()>` | 更新 Todo 的完成状态和完成时间。 | | `get_todos_by_month` | `year: i32`, `month: u32` | `Result>` | **修改**: 获取指定月份**及前后各一个月**(共三个月)的 Todo。基于 `due_time` 或 `start_time` 过滤(需明确)。默认按 `due_time` 排序,未完成在前。 | | `get_todos_by_week` | `week_start_date: String` (YYYY-MM-DD) | `Result>` | 获取指定周(从周一开始)的所有 Todo。基于 `due_time` 或 `start_time` 过滤(需明确)。 | | `get_todos_for_day` | `date: String` (YYYY-MM-DD) | `Result>` | 获取指定日期的所有 Todo。基于 `due_time` 或 `start_time` 过滤(需明确)。 | | `get_todos_by_tag` | `tag: String`, `page: i32`, `page_size: Option` (默认 30) | `Result>` | 获取包含指定标签的 Todo 列表(**修改**: 分页返回,默认每页 30 条)。排序:未完成的按 `due_time` 升序,已完成的按 `completion_time` 降序。 | | `get_all_todos_by_project` | `project_id: i64`, `page: i32`, `page_size: Option` (默认 30) | `Result>` | 获取指定项目的所有 Todo 列表,分页返回。排序:未完成的按 `due_time` 升序,已完成的按 `completion_time` 降序。 | | `get_recent_todos_by_project` | `project_id: i64` | `Result>` | 获取指定项目的**最近 30 条** Todo(**修改**: 定义“最近”,如按 `created_at` DESC?)。排序:未完成的按 `due_time` 升序排在最前,已完成的按 `completion_time` 降序排在后面。 | | `create_project` | `name: String`, `markdown_path: Option` | `Result` | 创建新项目,返回 ID。 | | `get_all_projects` | | `Result>` | 获取所有项目列表。 | | `update_project` | `id: i64`, `name: Option`, `markdown_path: Option` | `Result<()>` | 更新项目信息。 | | `get_all_tags` | | `Result>` | 获取所有标签列表(可能用于前端自动完成)。 | | `query_todos_generic` | `filter_completed: Option`, `filter_time_frame: Option`, `sort_by: Option`, `page: i32`, `page_size: Option` | `Result>` | **(新增)** 一个更通用的查询接口,支持多种过滤和排序条件,供日视图等需要灵活排序的场景使用。 `TimeFrame` (Day, Week, Month), `SortOrder` (DueDateAsc/Desc, StartDateAsc/Desc, Importance, Urgency, CreatedAtAsc/Desc) | 日视图中中的todo默认分为两个部分,一个为未完成的,一个为已经完成的部分, 日视图中需要做成类似表格的形式显示todo项,并支持其中的某一个进行排序操作。 [checkbox][title] [紧急程度] [重要程度] [开始时间] [截止时间] [设置按钮] 点击设置按钮可以跳转到todo视图中,针对todo项目进行编辑,也可以在表格中直接编辑 如果没有todo项目,则显示一个下划线的编辑框,输入完成后作为标题添加todo项目