feat: 计划任务支持发送邮件(固定内容/大模型生成),设置页新增 SMTP 邮件配置与测试发送;'定时计划'更名为'计划任务'

This commit is contained in:
xianrenge
2026-08-17 13:13:37 +08:00
parent 6eb197a91a
commit 0f942182be
14 changed files with 673 additions and 30 deletions
+15 -3
View File
@@ -12,7 +12,7 @@
```
xianren_studio/
├── apps/desktop/ Tauri 桌面壳(Rust 命令层、tauri.conf.json、推荐模型/预制智能体/预制工作流默认 JSON、工作流执行引擎 workflow.rs
├── apps/desktop/ Tauri 桌面壳(Rust 命令层、tauri.conf.json、推荐模型/预制智能体/预制工作流默认 JSON、工作流执行引擎 workflow.rs、邮件发送 mail.rs
├── crates/core/ 领域核心:SQLite(模型注册表、智能体、工作流、定时计划、会话、消息、设置)
├── crates/engine/ llama-server 生命周期 + 流式/非流式聊天(本地与远程 OpenAI 兼容)
├── crates/download/ 分片断点续传下载器
@@ -108,6 +108,7 @@ ui/src/
| 智能体 | `list_agents``add_agent``update_agent``remove_agent``set_agent_enabled``restore_preset_agents` |
| 工作流 | `list_workflows``add_workflow``update_workflow``remove_workflow``set_workflow_enabled``restore_preset_workflows``run_workflow` |
| 定时计划 | `list_scheduled_tasks``add_scheduled_task``update_scheduled_task``remove_scheduled_task``set_scheduled_task_enabled``run_scheduled_task_now` |
| 邮件 | `mail_test`(用当前 SMTP 配置发送测试邮件) |
| 应用/设置 | `app_info``autostart_status``autostart_set``settings_get``settings_set` |
| 模型 | `list_models``import_model``remove_model``set_model_enabled``scan_models``add_remote_model` |
| 模型广场 | `search_models``list_model_files``list_recommended_models``import_recommendations``fetch_model_page` |
@@ -136,6 +137,12 @@ ui/src/
- `auto_load_models`:应用启动时读取设置键 `auto_load_models`(JSON 数组,本地模型 id 按序排列),逐个调用 `start_engine_and_wait` 部署,非最后一个模型加载完即停止,最后一个保持运行。
- `start_engine_and_wait`:本地模型引擎启动的公共实现(构造 `EngineConfig`、推送 `engine://deploy` / `engine://deploy-progress` 事件、轮询加载进度、更新 `engine_base`);`deploy_model` 命令与 `auto_load_models` 共用。
- `autostart_status` / `autostart_set`:查询 / 设置开机启动(`tauri-plugin-autostart``ManagerExt`)。
- `run_scheduled_task_once`:大模型执行完成后,若任务开启邮件,按内容模式发送——固定模式用填写的主题/正文,LLM 模式用智能体回答作正文(主题留空取回答首行);邮件发送失败时任务标记失败但保留回答内容。
- `send_task_email` / `load_smtp_config` / `split_recipients`:读取设置页「邮件」SMTP 配置、拆分多收件人并调用 `mail.rs` 发送。
**邮件发送模块(`apps/desktop/src/mail.rs`):**
- `send_email`:用 lettre 通过 SMTP 发送纯文本邮件;加密方式按设置分支——隐式 SSL 用 `relay`465)、STARTTLS 用 `starttls_relay`587)、无加密用 `builder_dangerous`25),均可自定义端口与超时。
**工作流执行引擎(`apps/desktop/src/workflow.rs`):**
@@ -168,7 +175,7 @@ ui/src/
| `conversations` | `title``model_id``system_prompt``agent_id``pinned``favorite``tools_json` | 会话;`agent_id` 为空表示普通对话,否则属于对应智能体 |
| `agents` | `kind`preset/custom)、`name``icon``description``system_prompt``model_id``enabled` | 智能体(预制 + 自定义) |
| `workflows` | `kind`preset/custom)、`name``icon``description``nodes_json``edges_json``model_id``enabled` | 工作流(节点/连线以 JSON 存储,节点含 type/label/position/data |
| `scheduled_tasks` | `name``agent_id``prompt``interval_minutes``enabled``next_run_at``last_run_at``last_status`idle/running/success/error)、`last_result``last_error` | 定时计划`next_run_at` 由 SQLite `datetime('now', '+N minutes')` 计算(UTC),每次执行完成后推进 |
| `scheduled_tasks` | `name``agent_id``prompt``interval_minutes``enabled``next_run_at``last_run_at``last_status`idle/running/success/error)、`last_result``last_error``email_enabled``email_to``email_mode`fixed/llm)、`email_subject``email_body` | 计划任务`next_run_at` 由 SQLite `datetime('now', '+N minutes')` 计算(UTC),每次执行完成后推进 |
| `messages` | `role``model_id``content``tokens_in/out``elapsed_ms``first_token_ms``images_json` | 消息;`model_id` 记录该回答所用模型(回答下方展示模型名) |
| `message_versions` | `content``tokens_out``seq` | 重新生成前的旧版本 |
| `skills` | `name``description``content``enabled` | 技能工具库 |
@@ -176,6 +183,8 @@ ui/src/
迁移清单(`ensure_column`):`models.kind/base_url/api_key/api_model/enabled``messages.elapsed_ms/first_token_ms/images_json/model_id``conversations.pinned/favorite/tools_json/agent_id`
新增列迁移:`scheduled_tasks.email_enabled / email_to / email_mode / email_subject / email_body``ensure_column` 幂等补齐)。
### 5.3 `models.rs`
模型 CRUD、`set_enabled`(启用/停用)、`scan_directory`(扫描 GGUF 目录)、量化猜测 `guess_quant`
@@ -198,7 +207,7 @@ ui/src/
### 5.8 `scheduled_tasks.rs`
定时计划 CRUD 与运行状态落库:`list/get/insert/update/delete/set_enabled`(停用时清空 `next_run_at`,启用时重新计算)、`mark_running` / `finish_run`(写执行结果并推进下次执行时间)、`list_due`(到点且未运行中的启用计划)、`reset_stale_running`(应用重启后把中断的「运行中」标记为失败)。
计划任务 CRUD 与运行状态落库:`list/get/insert/update/delete/set_enabled`(停用时清空 `next_run_at`,启用时重新计算)、`mark_running` / `finish_run`(写执行结果并推进下次执行时间)、`list_due`(到点且未运行中的启用计划)、`reset_stale_running`(应用重启后把中断的「运行中」标记为失败);任务行含邮件配置字段(`email_enabled/email_to/email_mode/email_subject/email_body`
---
@@ -266,6 +275,9 @@ ui/src/
| `tavily_api_key` | (内置演示值) | 联网搜索 API Key |
| `tool_web_search_enabled` | true | 联网搜索工具开关 |
| `auto_load_models` | `[]` | 启动时自动加载的本地模型 id 列表(JSON 数组,顺序即加载顺序) |
| `smtp_host` / `smtp_port` / `smtp_tls` | 空 / 465 / wrapper | SMTP 发件服务器、端口、加密方式(wrapper/starttls/none |
| `smtp_user` / `smtp_password` | 空 / 空 | SMTP 用户名(通常为发件邮箱)与授权码/密码 |
| `smtp_from` / `smtp_from_name` | 空 / 仙人工作室 | 发件人地址(留空用用户名)与显示名称 |
| `recommend_dir` | 数据目录/recommendations | 推荐列表目录 |
| `preset_agents_seeded` | 首次启动后为 `1` | 预制智能体是否已写入(内部标记,避免覆盖用户删除) |
| `preset_workflows_seeded` | 首次启动后为 `1` | 预制工作流是否已写入(内部标记,避免覆盖用户删除) |