From 446743677fe680382d4dcc477414bc9773f4c030 Mon Sep 17 00:00:00 2001 From: hubian <908234780@qq.com> Date: Sun, 12 Apr 2026 16:56:50 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0PROJECTS.md=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=8A=80=E6=9C=AF=E8=AE=BA=E5=9D=9B=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MEMORY.md | 54 +++ PROJECTS.md | 259 ++++++++++++- memory/2026-04-08.md | 30 +- memory/2026-04-10.md | 79 ++++ memory/2026-04-11.md | 72 ++++ memory/2026-04-12.md | 87 +++++ skills/email | 1 + skills/email-sender/SKILL.md | 168 -------- skills/email-sender/scripts/.gitignore | 2 - skills/email-sender/scripts/send_email.py | 293 -------------- works/ai-chat | 1 + works/board-monitor | 1 + works/disk-scanner | 1 + works/llm-index-rag | 2 +- works/mailbox/README.md | 77 ++++ .../mailbox_manager.cpython-310.pyc | Bin 0 -> 8621 bytes works/mailbox/emails/1/body.txt | 27 ++ works/mailbox/emails/1/meta.json | 11 + works/mailbox/inbox.json | 14 + works/mailbox/mailbox_manager.py | 362 ++++++++++++++++++ works/multi-agent-bidding | 1 + works/param-hub | 2 +- works/param-hub-python | 1 + works/pdf-translate-web-v2 | 2 +- works/project-panel | 1 + works/service-monitor | 1 + works/snippet-notes | 1 + works/xian-favor | 1 + 28 files changed, 1071 insertions(+), 480 deletions(-) create mode 100644 memory/2026-04-10.md create mode 100644 memory/2026-04-11.md create mode 100644 memory/2026-04-12.md create mode 160000 skills/email delete mode 100644 skills/email-sender/SKILL.md delete mode 100644 skills/email-sender/scripts/.gitignore delete mode 100644 skills/email-sender/scripts/send_email.py create mode 160000 works/ai-chat create mode 160000 works/board-monitor create mode 160000 works/disk-scanner create mode 100644 works/mailbox/README.md create mode 100644 works/mailbox/__pycache__/mailbox_manager.cpython-310.pyc create mode 100644 works/mailbox/emails/1/body.txt create mode 100644 works/mailbox/emails/1/meta.json create mode 100644 works/mailbox/inbox.json create mode 100644 works/mailbox/mailbox_manager.py create mode 160000 works/multi-agent-bidding create mode 160000 works/param-hub-python create mode 160000 works/project-panel create mode 160000 works/service-monitor create mode 160000 works/snippet-notes create mode 160000 works/xian-favor diff --git a/MEMORY.md b/MEMORY.md index f5d3644..ee61ad1 100644 --- a/MEMORY.md +++ b/MEMORY.md @@ -93,12 +93,66 @@ git push origin v1.0.0 | PDF翻译助手 V2 | 本地 | 19000 | ✅ 运行中 | | 碎片信息记录 | 本地 | 19009 | ✅ 运行中 | | ParamHub Python | 本地 | 19010 | ✅ 运行中 | +| 项目服务管理面板 | 本地 | 19013 | ✅ 运行中 | | 网页助手插件 | /coder/web-context-extension | - | 📦 已完成 | +| 磁盘大文件扫描 | 本地 | - | 📦 已完成 | --- ## 更新日志 +### 2026-04-12 +- 磁盘大文件扫描工具 v1.0.0:智能扫描找出大文件和大目录 + - 自动跳过零碎目录(node_modules, .git, venv等) + - 文件数量阈值判断(超过阈值视为程序包) + - 大小阈值过滤(小目录不深入) + - 按大小排序,树形展示 + - 跨平台:Windows/Linux/macOS + - Git仓库: http://192.168.2.8:12007/coder/disk-scanner +- AI对话系统 v2.0.0:架构重构 + - 端口: 19020 + - 大模型池管理:多LLM Provider配置 + - Agent管理:系统设定、思考功能开关 + - 渠道独立:网页端/Matrix独立绑定Agent + - 思考功能:支持原生思考模型,兼容无思考功能模型 + - Git仓库: http://192.168.2.8:12007/coder/ai-chat-system v2.0.0 +- 多智能体竞标调度系统 v1.0.0:基于邮件方案实现 + - 端口: 19015 + - 核心组件:Orchestrator(规划Agent)、Worker(执行Agent)、TaskBoard(任务公告板) + - 功能:竞标机制、动态调度、智能容错、质量保证 + - 默认Agent:代码专家、搜索专家、写作专家、分析专家 + - Web界面:首页、请求列表、任务列表、Agent管理 + - Git仓库: http://192.168.2.8:12007/coder/multi-agent-bidding +- Xian Favor 收藏系统 v1.0.0:支持命令行、API、Web三种操作模式 + - 端口: 19014 + - 功能:文本笔记、链接收藏、专栏订阅、待办事项管理 + - 标签系统:灵活分类,支持多标签 + - 状态管理:待办支持待处理/进行中/已完成 + - 优先级:低/中/高/紧急 + - 截止日期:待办支持设置截止日期 + - 快速搜索:全文搜索标题、内容、备注 + - Git仓库: http://192.168.2.8:12007/coder/xian-favor + +### 2026-04-11 +- PDF翻译助手 V2 v2.1.0:系统配置支持动态增删用户类型和会员套餐 + - 新增 UserTypeConfig 模型:用户类型配置支持动态增删 + - 新增 MembershipPlanConfig 模型:会员套餐配置支持动态增删 + - 用户类型管理页面:添加、编辑、删除、启用/禁用用户类型 + - 会员套餐管理页面:添加、编辑、删除、上架/下架、推荐套餐 + - 功能权限配置:支持选择功能列表 +- 项目服务管理面板 v1.0.0:统一管理所有项目和服务 + - 端口: 19013 + - 功能: 项目列表、状态检测、启动/停止/重启控制、日志查看 + - 配置文件: projects.json 便于扩展新项目 + - Git仓库: http://192.168.2.8:12007/coder/project-panel + +### 2026-04-10 +- 创建 Web服务监控系统(每20分钟检查8个服务,邮件通知) +- 配置 Cron 定时任务 +- 扩展邮件技能:新增 IMAP 接收邮件功能,支持查看未读邮件和文本附件 +- 创建 A股板块监控系统(东方财富API,异动检测,邮件通知) +- 创建邮件收件箱管理系统 (`works/mailbox/`):同步、存储、状态追踪、归档 + ### 2026-04-09 - 创建 PROJECTS.md 项目记录文件 - 创建邮件发送技能 email-sender diff --git a/PROJECTS.md b/PROJECTS.md index 0ed63a5..f1d292d 100644 --- a/PROJECTS.md +++ b/PROJECTS.md @@ -14,9 +14,14 @@ | 4 | 碎片信息记录 | Web | 19009 | ✅ 运行中 | 2026-04-09 | | 5 | ParamHub Python版 | Web | 19010 | ✅ 运行中 | 2026-04-09 | | 6 | LLM Proxy | Web | 19007/19008 | ✅ 运行中 | 2026-04-10 | -| 7 | 网页助手插件 | Extension | - | 📦 已完成 | 2026-04-08 | -| 8 | A股历史数据系统 | CLI | - | 🔄 优化中 | 2026-04-09 | -| 9 | Web服务监控 | Cron | - | ✅ 运行中 | 2026-04-10 | +| 7 | 项目服务管理面板 | Web | 19013 | ✅ 运行中 | 2026-04-11 | +| 8 | 网页助手插件 | Extension | - | 📦 已完成 | 2026-04-08 | +| 9 | A股历史数据系统 | CLI | - | 🔄 优化中 | 2026-04-09 | +| 10 | Web服务监控 | Cron | - | ✅ 运行中 | 2026-04-10 | +| 11 | A股板块监控 | Cron | - | ✅ 运行中 | 2026-04-10 | +| 12 | AI对话系统 V2 | Web | 19020 | ✅ 运行中 | 2026-04-12 | +| 13 | 磁盘大文件扫描 | CLI | - | 📦 已完成 | 2026-04-12 | +| 14 | 技术论坛 | Web | 19004/19005 | ✅ 已修复 | 2026-04-12 | --- @@ -169,12 +174,23 @@ curl -s http://localhost:19010/api/categories **Git仓库**: http://192.168.2.8:12007/coder/param-hub-python -**版本**: v0.3.1 +**版本**: v1.2.0 + +**v1.2.0 新功能**: +- 网站配置管理:后台可修改网站名称、备案号、页脚文字等 +- 配置前台自动读取并显示 + +**v1.1.0 新功能**: +- 智能添加:粘贴文本自动解析为结构化数据(大模型API) +- 展示开关:各分类和产品支持显示/隐藏控制 +- 原始数据保留:智能添加的产品保留raw_text字段 +- 价格显示优化:支持多币种、价格区间、单位 **依赖**: - Python 3 + Flask - Tailwind CSS (CDN) - JSON文件存储 +- LLM Proxy (http://192.168.2.17:19007/v1) --- @@ -256,7 +272,47 @@ print(response.choices[0].message.content) --- -### 7. PDF翻译助手 V1 (pdf-translate-web) +### 7. 项目服务管理面板 (project-panel) + +**简介**: 统一管理所有项目和服务,显示运行状态,支持启动、停止、重启控制。 + +**目录**: `works/project-panel` + +**启动命令**: +```bash +cd ~/.openclaw/workspace-coder/works/project-panel +python3 app.py +``` + +**访问地址**: http://localhost:19013 + +**检查服务状态**: +```bash +curl -s http://localhost:19013/api/projects +``` + +**Git仓库**: http://192.168.2.8:12007/coder/project-panel + +**版本**: v1.0.0 + +**功能特点**: +- 项目列表展示(Web服务、Cron任务、CLI工具、插件) +- 实时状态检测(端口检测、健康检查) +- 服务控制(启动、停止、重启) +- 日志查看 +- 类型筛选 +- 动态添加新项目(API) + +**项目配置**: `projects.json` 文件存储所有项目信息,便于扩展 + +**依赖**: +- Python 3 + Flask +- Tailwind CSS (CDN) +- RemixIcon + +--- + +### 8. PDF翻译助手 V1 (pdf-translate-web) **简介**: 英文PDF翻译中文网站第一版,支持翻译、缓存、用户系统。 @@ -266,7 +322,7 @@ print(response.choices[0].message.content) --- -### 8. PDF翻译脚本 (pdf-translator) +### 9. PDF翻译脚本 (pdf-translator) **简介**: 基于本地LLM的英文PDF翻译命令行工具,支持Markdown/TXT/JSON输出。 @@ -284,7 +340,7 @@ python3 translate_pdf.py input.pdf output.md --- -### 9. A股历史数据系统 (stock_system) +### 10. A股历史数据系统 (stock_system) **简介**: 获取所有A股从2010年至今的历史行情数据,支持断点续传。V2版本优化了CPU和磁盘占用。 @@ -324,7 +380,7 @@ ls -lh /home/xian/.openclaw/common/stock_system/data/stock_daily_data.parquet --- -### 10. Web服务监控 (service-monitor) +### 11. Web服务监控 (service-monitor) **简介**: 自动监控所有Web服务状态,每20分钟检查一次,如有服务停止则发送邮件通知。 @@ -369,16 +425,146 @@ cat ~/.openclaw/workspace-coder/works/service-monitor/monitor.log --- +### 12. A股板块监控 (board-monitor) + +**简介**: 自动获取东方财富板块数据,监控异动并发送邮件通知。 + +**目录**: `works/board-monitor` + +**功能特点**: +- 行业板块涨跌幅排行 +- 概念板块涨跌幅排行 +- 主力资金流入/流出监控 +- 异动检测(涨跌幅≥3%、资金≥10亿) +- HTML格式邮件通知 + +**使用命令**: +```bash +# 测试API连接 +python3 board_monitor.py test + +# 获取板块数据 +python3 board_monitor.py get industry --limit 20 + +# 执行监控检查 +python3 board_monitor.py monitor -v +``` + +**Cron配置**: 交易日盘中每小时检查(10:00-15:00) +``` +0 10,11,13,14,15 * * 1-5 python3 board_monitor.py monitor +``` + +**Git仓库**: http://192.168.2.8:12007/coder/board-monitor + +**版本**: v1.0.0 + +**依赖**: +- Python 3 + urllib +- 东方财富HTTP API +- 邮件发送技能 (email) + +--- + +### 12. AI对话系统 V2 (ai-chat-system) + +**简介**: 支持网页端和Matrix端实时同步对话的AI聊天系统,v2.0重构支持大模型池、Agent管理、渠道独立绑定。 + +**目录**: `works/ai-chat` + +**启动命令**: +```bash +cd ~/.openclaw/workspace-coder/works/ai-chat +./start_v2.sh +``` + +**访问地址**: +- 网页端: http://localhost:19020 +- 后台管理: http://localhost:19020/admin + +**检查服务状态**: +```bash +curl -s http://localhost:19020/api/v2/providers +curl -s http://localhost:19020/api/admin/stats +``` + +**Git仓库**: http://192.168.2.8:12007/coder/ai-chat-system + +**版本**: v2.0.0 + +**v2.0.0 新功能**: +- **大模型池管理**: 配置多个LLM Provider,Agent可选择使用 +- **Agent管理**: 每个Agent独立配置系统设定、思考功能开关 +- **渠道独立绑定**: 网页端和Matrix可绑定不同Agent +- **思考功能**: 支持原生思考模型,兼容无思考功能的模型 + +**技术栈**: +- FastAPI + WebSocket +- SQLite (新v2模型: LLMProvider, Agent, Channel) +- Matrix Bot (matrix-nio, 支持加密) + +**依赖**: +- Python 3 + FastAPI +- matrix-nio +- 大模型API (可配置多个) + +--- + +### 13. 磁盘大文件扫描 (disk-scanner) + +**简介**: 智能扫描Windows/Linux目录,快速定位大文件和大目录,自动跳过零碎文件目录。 + +**目录**: `works/disk-scanner` + +**使用命令**: +```bash +# Windows +disk_scanner.bat C:\Users -d 3 + +# Linux/macOS +python3 disk_scanner.py /home/user -d 3 -s 50M +``` + +**功能特点**: +- 智能跳过零碎目录(node_modules, .git, venv等) +- 文件数量阈值判断(超过100文件视为程序包) +- 大小阈值过滤(默认10MB以下不深入) +- 按大小排序展示 +- 树形结构清晰展示 +- 跨平台支持 + +**参数**: +- `-d/--depth`: 最大扫描深度 +- `-f/--file-threshold`: 文件数阈值(默认100) +- `-s/--size-threshold`: 大小阈值(默认10M) + +**Git仓库**: http://192.168.2.8:12007/coder/disk-scanner + +**版本**: v1.0.0 + +**依赖**: +- Python 3.6+(仅标准库,无需额外安装) + +--- + ## 端口分配表 | 端口 | 项目 | 说明 | |------|------|------| | 19000 | PDF翻译助手 V2 | 主服务 + 后台 | | 19001 | LLM Index RAG | API服务 | +| 19002-19006 | 预留 | 待分配 | +| 19007 | LLM Proxy | API服务 | +| 19008 | LLM Proxy | 后台管理 | | 19009 | 碎片信息记录 | Web服务 | | 19010 | ParamHub Python | Web服务 | -| 19002-19008 | 预留 | 待分配 | -| 19011-19100 | 预留 | 待分配 | +| 19011 | 产品参数爬取 | API服务 | +| 19012 | 产品参数爬取 | 后台管理 | +| 19013 | 项目服务管理面板 | Web服务 | +| 19014 | Xian Favor | 收藏系统 | +| 19015 | 多智能体竞标调度 | Web服务 | +| 19020 | AI对话系统 V2 | 主服务 + Matrix Bot | +| 19021-19100 | 预留 | 待分配 | **端口规范**: 所有Web服务必须使用 19000-19100 范围内的端口! @@ -393,9 +579,14 @@ cat ~/.openclaw/workspace-coder/works/service-monitor/monitor.log | LLM Index RAG | http://192.168.2.8:12007/coder/llm-index-rag | v1.2.0 | | LLM Proxy | http://192.168.2.8:12007/coder/llm-proxy | v0.5.1 | | 产品参数爬取系统 | http://192.168.2.8:12007/coder/product-crawler | v1.0.0 | +| 项目服务管理面板 | http://192.168.2.8:12007/coder/project-panel | v1.0.0 | | 网页助手插件 | http://192.168.2.8:12007/coder/web-context-extension | v0.1.0 | | A股历史数据系统 | http://192.168.2.8:12007/coder/stock_system | v0.2.0 | | Web服务监控 | http://192.168.2.8:12007/coder/service-monitor | v1.0.0 | +| 邮件收发技能 | http://192.168.2.8:12007/coder/skill-email | v1.1.0 | +| A股板块监控 | http://192.168.2.8:12007/coder/board-monitor | v1.0.0 | +| AI对话系统 V2 | http://192.168.2.8:12007/coder/ai-chat-system | v2.0.0 | +| 磁盘大文件扫描 | http://192.168.2.8:12007/coder/disk-scanner | v1.0.0 | **Git服务器**: http://192.168.2.8:12007/ **账号**: coder / Hps123@! @@ -440,6 +631,54 @@ pkill -f "app.py.*port=19010" - 配置 Cron 定时任务(每20分钟检查) - 邮件通知功能(发送到 zuitoushang@tphai.com) +### 2026-04-11 +- 创建项目服务管理面板 (project-panel) +- 端口: 19013 +- 功能: 项目列表、状态检测、启动/停止/重启控制、日志查看 +- Git仓库: http://192.168.2.8:12007/coder/project-panel v1.0.0 + +### 2026-04-09 +- 创建 PROJECTS.md 项目记录文件 +- 记录现有8个项目详情 +- 整理端口分配表和快速操作命令 +- 优化 stock_system 获取脚本 V2(分文件+批量合并+SQLite) + +### 待办 +- [ ] 为每个项目创建 Git 仓库和版本 tag +- [ ] 配置 systemd 服务实现开机自启动 + +### 2026-04-12 +- 技术论坛 v1.1.0 安全重构 + - 后台添加登录验证(Session + JWT) + - JSON存储改为SQLite数据库 + - API密钥移至配置文件(支持环境变量) + - SECRET_KEY改为随机生成 + - 新增管理员登录页面 + - Git仓库: http://192.168.2.8:12007/coder/tech-forumclaw/workspace-coder/works/param-hub-python && nohup python3 app.py > /tmp/paramhub.log 2>&1 & +``` + +### 停止所有Web服务 +```bash +pkill -f "app.py.*port=19000" +pkill -f "app.py.*port=19009" +pkill -f "app.py.*port=19010" +``` + +--- + +## 更新日志 + +### 2026-04-10 +- 创建 Web服务监控系统 +- 配置 Cron 定时任务(每20分钟检查) +- 邮件通知功能(发送到 zuitoushang@tphai.com) + +### 2026-04-11 +- 创建项目服务管理面板 (project-panel) +- 端口: 19013 +- 功能: 项目列表、状态检测、启动/停止/重启控制、日志查看 +- Git仓库: http://192.168.2.8:12007/coder/project-panel v1.0.0 + ### 2026-04-09 - 创建 PROJECTS.md 项目记录文件 - 记录现有8个项目详情 diff --git a/memory/2026-04-08.md b/memory/2026-04-08.md index b005c4b..7fe455c 100644 --- a/memory/2026-04-08.md +++ b/memory/2026-04-08.md @@ -74,7 +74,13 @@ curl -X POST "http://coder:Hps123%40%21@192.168.2.8:12007/api/v1/user/repos" \ | 项目 | 端口 | |------|------| | 文章工作流后台 | 19001 | -| (预留) | 19002-19100 | +| 方言AI主服务 | 19002 | +| 方言AI后台管理 | 19003 | +| 技术论坛 | 19004 | +| 参数百科前台 | 3000 | +| 参数百科后台 | 19006 | +| 大模型API中转 | /coder/llm-proxy | 19007/19008 | v0.2.0 | +| 预留 | 19008-19100 | --- @@ -99,11 +105,18 @@ curl -X POST "http://coder:Hps123%40%21@192.168.2.8:12007/api/v1/user/repos" \ ### 4. 方言版AI对话助手 (dialect-chat) - 仓库: http://192.168.2.8:12007/coder/dialect-chat -- 版本: v0.1.0 +- 版本: v0.2.0 - 技术: Python + Flask + 原生JS -- 访问地址: http://localhost:19002 +- 访问地址: http://localhost:19002 (主服务) / http://localhost:19003 (后台) - 功能: 8种方言、语音识别、用户系统 +### 5. 技术论坛与技术分享网站 (tech-forum) +- 仓库: http://192.168.2.8:12007/coder/tech-forum +- 版本: v0.1.0 +- 技术: Python + Flask + Tailwind CSS +- 访问地址: http://localhost:19004 +- 功能: 技术交流帖子、工具分享主题、用户系统 + --- ## 待办事项 @@ -111,4 +124,13 @@ curl -X POST "http://coder:Hps123%40%21@192.168.2.8:12007/api/v1/user/repos" \ - [ ] param-hub 后续功能迭代 - [ ] 添加更多模型数据 - [ ] 添加更多GPU数据 -- [ ] 实现数据库持久化 \ No newline at end of file +- [ ] 实现数据库持久化��数据库持久化��迭代 +- [ ] 添加更多模型数据 +- [ ] 添加更多GPU数据 +- [ ] 实现数据库持久化��数据库持久化续功能迭代 +- [ ] 添加更多模型数据 +- [ ] 添加更多GPU数据 +- [ ] 实现数据库持久化��数据库持久化��迭代 +- [ ] 添加更多模型数据 +- [ ] 添加更多GPU数据 +- [ ] 实现数据库持久化��数据库持久化 \ No newline at end of file diff --git a/memory/2026-04-10.md b/memory/2026-04-10.md new file mode 100644 index 0000000..d691844 --- /dev/null +++ b/memory/2026-04-10.md @@ -0,0 +1,79 @@ +# 2026-04-10 + +## 完成的工作 + +### 邮件收件箱管理 + +- 创建 `works/mailbox/` 邮件管理系统 +- 支持:同步、存储、状态追踪、归档 +- 状态流转:unread → read → pending → processing → done → archived +- 同步邮件 [1]:A股板块分析方案汇总 → 已完成(board_monitor已实现) + +### A股板块监控系统 + +- 创建 `works/board-monitor/board_monitor.py` +- 东方财富HTTP API数据获取(解决代理问题) +- **改为盘后报告模式**:每个交易日17:00发送 +- **邮件结构**:正文分析总结 + 附件详细CSV数据 +- **历史数据分析**(v1.3.0新增): + - SQLite数据库存储每日数据 + - 连续上涨/下跌板块统计 + - 板块轮动分析 + - 近5日资金流向趋势 +- 收件人: wlq@tphai.com +- 推送到仓库: http://192.168.2.8:12007/coder/board-monitor v1.3.0 + +### 邮件技能扩展 + +- 新增 IMAP 邮件接收功能 (`scripts/receive_email.py`) +- 支持查看未读邮件列表 +- 支持读取邮件详情和正文 +- 支持自动保存附件 +- 支持读取文本附件内容(.txt, .md, .json, .csv, .py 等) +- 重命名技能目录: email-sender → email +- 推送到仓库: http://192.168.2.8:12007/coder/skill-email v1.1.0 + +### 命令示例 + +```bash +# 查看未读邮件 +python3 receive_email.py unread + +# 读取邮件详情 +python3 receive_email.py read <邮件ID> + +# 查看附件内容 +python3 receive_email.py attachment <邮件ID> +``` + +### Web服务监控系统 + +- 创建 `works/service-monitor/monitor.py` +- 监控8个Web服务端口: + - PDF翻译助手 V2 (19000) + - LLM Index RAG (19001) + - 碎片信息记录 (19009) + - ParamHub Python (19010) + - 产品参数爬取 API/后台 (19011/19012) + - LLM Proxy API/后台 (19007/19008) +- Cron定时任务:每20分钟检查一次 +- 邮件通知:zuitoushang@tphai.com +- 发现停止服务时自动发送HTML格式邮件,包含启动命令 + +### Cron配置 + +``` +*/20 * * * * /usr/bin/python3 /home/xian/.openclaw/workspace-coder/works/service-monitor/monitor.py +``` + +## 服务状态 + +当前运行中: +- ✅ LLM Index RAG (19001) +- ✅ 碎片信息记录 (19009) +- ✅ ParamHub Python (19010) +- ✅ 产品参数爬取 API/后台 (19011/19012) +- ✅ LLM Proxy API/后台 (19007/19008) + +已停止: +- ❌ PDF翻译助手 V2 (19000) \ No newline at end of file diff --git a/memory/2026-04-11.md b/memory/2026-04-11.md new file mode 100644 index 0000000..5e0707d --- /dev/null +++ b/memory/2026-04-11.md @@ -0,0 +1,72 @@ +# 2026-04-11 + +## 完成的工作 + +### PDF翻译助手 V2 v2.1.0 + +**新功能:系统配置动态管理** + +- **用户类型配置**: + - 支持添加新的用户类型(自定义标识、显示名称) + - 支持编辑权限:每日翻译次数、最大页数、文件大小 + - 支持选择功能权限列表 + - 支持删除自定义类型(系统类型不可删除) + - 支持启用/禁用用户类型 + +- **会员套餐配置**: + - 支持添加新的会员套餐(自定义标识、显示名称) + - 支持编辑价格、原价、周期 + - 支持设置购买后升级的用户类型 + - 支持上架/下架套餐 + - 支持设置推荐套餐 + - 支持删除自定义套餐(系统套餐不可删除) + +- **新增数据模型**: + - `UserTypeConfig`:用户类型配置表 + - `MembershipPlanConfig`:会员套餐配置表 + +- **新增页面**: + - `user_types.html`:用户类型配置列表 + - `user_type_form.html`:添加/编辑用户类型表单 + - `membership_plans.html`:会员套餐配置列表 + - `membership_plan_form.html`:添加/编辑会员套餐表单 + +- **改进settings页面**:提供配置入口链接 + +**Git仓库**: http://192.168.2.8:12007/coder/pdf-translate-web +**版本**: v2.1.0 + +### ParamHub Python v1.1.0 + +**新功能:** +- 智能添加:粘贴文本自动解析为结构化数据(大模型API) +- 展示开关:各分类和产品支持显示/隐藏控制(默认显示) +- 原始数据保留:智能添加的产品保留raw_text字段 + +**优化:** +- 价格显示优化:支持多币种(USD/CNY/EUR)、价格区间、单位 +- CPU图标修复:改为ri-cpu-line +- favicon添加:所有页面增加浏览器标签图标 + +**Git仓库**: http://192.168.2.8:12007/coder/param-hub-python +**版本**: v1.1.0 + +### 碎片信息记录项目优化 + +- 更换大模型接口:改用LLM Proxy (http://192.168.2.17:19007/v1) +- 添加Ctrl+S快捷键保存功能(阻止浏览器默认保存) +- 添加favicon浏览器标签图标 + +### 项目服务管理面板 v1.0.0 + +- 创建 `works/project-panel/` 目录结构 +- 端口: 19013 +- 功能: + - 项目列表展示(Web服务、Cron任务、CLI工具、插件) + - 实时状态检测(端口检测、健康检查) + - 服务控制(启动、停止、重启) + - 日志查看 + - 类型筛选 + - 动态添加新项目(API) +- 配置文件: `projects.json` 存储项目信息,便于扩展 +- Git仓库: http://192.168.2.8:12007/coder/project-panel v1.0.0 \ No newline at end of file diff --git a/memory/2026-04-12.md b/memory/2026-04-12.md new file mode 100644 index 0000000..47018c3 --- /dev/null +++ b/memory/2026-04-12.md @@ -0,0 +1,87 @@ +# 2026-04-12 + +## 完成的工作 + +### Xian Favor 收藏系统 v1.0.0 + +创建了一个完整的收藏管理系统,支持三种操作模式: + +**功能特性:** +- 多种内容类型:文本笔记、链接收藏、专栏订阅、待办事项 +- 标签系统:灵活分类,支持多标签关联 +- 状态管理:待办支持待处理/进行中/已完成三种状态 +- 优先级:低/中/高/紧急四个级别 +- 截止日期:待办事项支持设置截止日期 +- 快速搜索:全文搜索标题、内容、备注 +- 统计面板:实时统计各类型、状态数量 + +**三种操作模式:** + +1. **命令行 (CLI)** + - `xian_favor add text/link/column/todo` - 添加各类内容 + - `xian_favor list` - 列出条目(支持类型、状态、标签筛选) + - `xian_favor show` - 查看详情 + - `xian_favor edit` - 编辑条目 + - `xian_favor done` - 完成待办(快捷命令) + - `xian_favor delete` - 删除条目 + - `xian_favor search` - 搜索关键词 + - `xian_favor tags` - 标签管理 + - `xian_favor stats` - 统计信息 + - `xian_favor serve` - 启动API服务 + +2. **API服务 (端口 19014)** + - `/api/items` - CRUD操作 + - `/api/items//done` - 完成待办 + - `/api/tags` - 标签管理 + - `/api/stats` - 统计信息 + - `/api/search` - 搜索 + +3. **Web界面** + - 侧边栏快速筛选(类型、状态) + - 实时搜索 + - 统计卡片 + - 添加/编辑/删除操作 + - 一键完成待办 + +**技术实现:** +- 数据库:SQLite + WAL模式(提高并发性能) +- 存储:`~/.xian_favor/xian_favor.db` +- 后端:Flask + Flask-CORS +- 前端:Bootstrap 5 + 原生JavaScript + +**解决的问题:** +- SQLite并发锁问题:WAL模式 + busy_timeout + 惰性初始化 +- 嵌套连接问题:_add_tags_to_item使用同一个连接而非调用create_tag +- 路径问题:使用Path.home()而非~字符串 + +**Git仓库**: http://192.168.2.8:12007/coder/xian-favor +**版本**: v1.0.0 + +--- + +### AI对话系统 - 后台大模型配置优化 + +优化了ai-chat-system项目的后台管理界面,增加专门的AI模型配置功能: + +**新增功能:** +- 🧠 AI配置专用标签页(默认显示) +- API地址输入框 +- API密钥输入框 +- 模型选择:支持下拉选择和手动输入两种方式(datalist + input) +- 保存配置按钮 +- 测试连接按钮(验证API是否正常) +- 刷新模型列表按钮(从API获取可用模型) +- 实时状态显示(连接状态、Mock模式指示) + +**新增API端点:** +- `/api/admin/ai-config` GET/POST - 获取/更新AI配置 +- `/api/admin/models` GET - 获取可用模型列表(从API或默认列表) +- `/api/admin/test-ai` POST - 测试AI连接 + +**修复的Bug:** +- 测试连接显示"undefined"错误:改为从数据库读取最新配置,而非依赖ai_service属性 +- 添加详细错误提示:连接失败、超时、无法连接等具体原因 + +**项目目录**: `works/ai-chat` +**端口**: 19020 +**后台管理**: http://localhost:19020/admin \ No newline at end of file diff --git a/skills/email b/skills/email new file mode 160000 index 0000000..3c0cb21 --- /dev/null +++ b/skills/email @@ -0,0 +1 @@ +Subproject commit 3c0cb213c9627a2475dbba7f6d679a58aa0f8c29 diff --git a/skills/email-sender/SKILL.md b/skills/email-sender/SKILL.md deleted file mode 100644 index d263b21..0000000 --- a/skills/email-sender/SKILL.md +++ /dev/null @@ -1,168 +0,0 @@ ---- -name: email-sender -description: Send emails via SMTP with support for attachments, CC/BCC, HTML content, and multiple SMTP accounts. Use when user wants to send emails through Python/SMTP, configure email settings, or send emails with attachments. ---- - -# Email Sender / 邮件发送工具 - -通过 SMTP 发送邮件,支持附件、抄送/密送、HTML 格式和多账号管理。 - -## 快速开始 - -### 1. 配置 SMTP - -```bash -cd ~/.openclaw/workspace-coder/skills/email-sender/scripts -python3 send_email.py config my-email \ - --server mail.tphai.com \ - --port 587 \ - --email guwen@tphai.com \ - --password "your-password" \ - --no-tls -``` - -参数说明: -- `my-email`: 配置名称(可自定义) -- `--server`: SMTP 服务器地址 -- `--port`: SMTP 端口 -- `--email`: 邮箱地址 -- `--password`: 邮箱密码 -- `--no-tls`: 不使用 TLS 加密(默认使用 TLS) - -### 2. 查看配置 - -```bash -python3 send_email.py list -``` - -### 3. 发送邮件 - -**简单邮件:** -```bash -python3 send_email.py send \ - --to wlq@tphai.com \ - --subject "测试邮件" \ - --body "这是一封测试邮件" -``` - -**带附件的邮件:** -```bash -python3 send_email.py send \ - --to wlq@tphai.com \ - --subject "带附件的邮件" \ - --body "请查收附件" \ - --attach /path/to/file1.pdf \ - --attach /path/to/file2.jpg -``` - -**HTML 邮件:** -```bash -python3 send_email.py send \ - --to wlq@tphai.com \ - --subject "HTML 邮件" \ - --body "

标题

内容

" \ - --html -``` - -**抄送和密送:** -```bash -python3 send_email.py send \ - --to wlq@tphai.com \ - --cc "cc1@example.com,cc2@example.com" \ - --bcc "bcc@example.com" \ - --subject "抄送测试" \ - --body "这是一封抄送测试邮件" -``` - -## Python API 使用 - -```python -from send_email import send_email, setup_account - -# 配置 SMTP -setup_account( - name="work", - smtp_server="mail.tphai.com", - smtp_port=587, - email="guwen@tphai.com", - password="your-password", - use_tls=False -) - -# 发送简单邮件 -send_email( - to="wlq@tphai.com", - subject="测试", - body="内容" -) - -# 发送带附件的邮件 -send_email( - to="wlq@tphai.com", - subject="附件测试", - body="请查收附件", - attachments=["/path/to/file.pdf", "/path/to/image.jpg"], - verbose=True -) - -# 发送 HTML 邮件 -send_email( - to="wlq@tphai.com", - subject="HTML 测试", - body="

Hello

World

", - html=True -) - -# 使用特定账号 -send_email( - to="wlq@tphai.com", - subject="使用指定账号", - body="内容", - account_name="work" -) -``` - -## 配置文件 - -配置保存在 `scripts/smtp_config.json` 中: - -```json -{ - "accounts": [ - { - "name": "my-email", - "smtp_server": "mail.tphai.com", - "smtp_port": 587, - "email": "guwen@tphai.com", - "password": "your-password", - "use_tls": false - } - ] -} -``` - -## 常用 SMTP 设置 - -| 服务商 | SMTP 服务器 | 端口 | TLS | -|--------|-------------|------|-----| -| Gmail | smtp.gmail.com | 587 | 是 | -| Outlook | smtp.office365.com | 587 | 是 | -| QQ邮箱 | smtp.qq.com | 587 | 是 | -| 163邮箱 | smtp.163.com | 465 | 是 | -| 企业邮箱 | mail.tphai.com | 587 | 否 | - -## 故障排除 - -**认证失败:** -- 检查邮箱密码是否正确 -- Gmail 需要使用「应用专用密码」而非登录密码 -- QQ邮箱需要使用授权码而非登录密码 - -**连接失败:** -- 检查 SMTP 服务器地址和端口 -- 检查防火墙设置 -- 尝试切换 TLS/SSL 模式 - -**邮件被退回:** -- 检查收件人地址是否正确 -- 检查邮件头是否完整(本工具自动添加 Date 和 Message-Id) \ No newline at end of file diff --git a/skills/email-sender/scripts/.gitignore b/skills/email-sender/scripts/.gitignore deleted file mode 100644 index feedb23..0000000 --- a/skills/email-sender/scripts/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# SMTP配置文件(包含密码) -smtp_config.json \ No newline at end of file diff --git a/skills/email-sender/scripts/send_email.py b/skills/email-sender/scripts/send_email.py deleted file mode 100644 index fa36aa4..0000000 --- a/skills/email-sender/scripts/send_email.py +++ /dev/null @@ -1,293 +0,0 @@ -#!/usr/bin/env python3 -""" -邮件发送脚本 -支持纯文字/HTML 邮件、抄送/密送、附件和批量发送 -""" - -import smtplib -import os -import sys -import json -from email.mime.text import MIMEText -from email.mime.multipart import MIMEMultipart -from email.mime.application import MIMEApplication -from email.utils import formatdate, make_msgid -from typing import List, Optional - -# 配置文件路径 -SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) -CONFIG_FILE = os.path.join(SCRIPT_DIR, "smtp_config.json") - - -def load_config() -> dict: - """加载 SMTP 配置""" - if not os.path.exists(CONFIG_FILE): - return {"accounts": []} - - with open(CONFIG_FILE, 'r', encoding='utf-8') as f: - return json.load(f) - - -def save_config(config: dict): - """保存 SMTP 配置""" - with open(CONFIG_FILE, 'w', encoding='utf-8') as f: - json.dump(config, f, indent=2, ensure_ascii=False) - - -def setup_account( - name: str, - smtp_server: str, - smtp_port: int, - email: str, - password: str, - use_tls: bool = True -): - """配置 SMTP 账号""" - config = load_config() - - # 检查是否已存在同名配置 - for i, acc in enumerate(config["accounts"]): - if acc["name"] == name: - print(f"配置 '{name}' 已存在,正在更新...") - config["accounts"][i] = { - "name": name, - "smtp_server": smtp_server, - "smtp_port": smtp_port, - "email": email, - "password": password, # 明文存储,仅用于本地 - "use_tls": use_tls - } - save_config(config) - return - - # 添加新配置 - config["accounts"].append({ - "name": name, - "smtp_server": smtp_server, - "smtp_port": smtp_port, - "email": email, - "password": password, - "use_tls": use_tls - }) - save_config(config) - print(f"✅ 配置 '{name}' 已保存") - - -def list_accounts(): - """列出所有 SMTP 配置""" - config = load_config() - - if not config["accounts"]: - print("暂无 SMTP 配置") - return - - print("\n=== SMTP 配置列表 ===") - for i, acc in enumerate(config["accounts"], 1): - print(f"\n{i}. {acc['name']}") - print(f" 服务器: {acc['smtp_server']}:{acc['smtp_port']}") - print(f" 邮箱: {acc['email']}") - print(f" TLS: {'是' if acc['use_tls'] else '否'}") - - -def get_account(name: Optional[str] = None) -> Optional[dict]: - """获取 SMTP 配置""" - config = load_config() - - if not config["accounts"]: - return None - - if name is None: - return config["accounts"][0] - - for acc in config["accounts"]: - if acc["name"] == name: - return acc - - return None - - -def send_email( - to: str, - subject: str, - body: str, - account_name: Optional[str] = None, - html: bool = False, - cc: Optional[str] = None, - bcc: Optional[str] = None, - from_name: Optional[str] = None, - attachments: Optional[List[str]] = None, - verbose: bool = False -) -> bool: - """ - 发送邮件 - - 参数: - to: 收件人邮箱地址 - subject: 邮件主题 - body: 邮件内容 - account_name: SMTP 配置名称(可选,默认使用第一个) - html: 是否为 HTML 邮件(默认 False) - cc: 抄送邮箱地址,多个用逗号分隔(可选) - bcc: 密送邮箱地址,多个用逗号分隔(可选) - from_name: 发件人显示名称(可选) - attachments: 附件文件路径列表(可选) - verbose: 是否显示详细日志(默认 False) - - 返回: - bool: 发送成功返回 True,失败返回 False - """ - try: - # 获取 SMTP 配置 - account = get_account(account_name) - if account is None: - print("❌ 错误:未找到 SMTP 配置,请先运行配置") - return False - - # 创建邮件 - if attachments: - msg = MIMEMultipart() - msg.attach(MIMEText(body, "html" if html else "plain", "utf-8")) - else: - msg = MIMEText(body, "html" if html else "plain", "utf-8") - - # 设置邮件头 - msg["Subject"] = subject - msg["From"] = f"{from_name} <{account['email']}>" if from_name else account["email"] - msg["To"] = to - msg["Date"] = formatdate(localtime=True) - msg["Message-Id"] = make_msgid(domain=account["email"].split("@")[1]) - - if cc: - msg["Cc"] = cc - - # 添加附件 - if attachments: - for file_path in attachments: - if not os.path.exists(file_path): - print(f"⚠️ 附件不存在,已跳过: {file_path}") - continue - - with open(file_path, "rb") as f: - part = MIMEApplication(f.read()) - - filename = os.path.basename(file_path) - part.add_header( - "Content-Disposition", - "attachment", - filename=filename - ) - msg.attach(part) - if verbose: - print(f"📎 已添加附件: {filename}") - - # 连接 SMTP 服务器 - if verbose: - print(f"📡 正在连接 {account['smtp_server']}:{account['smtp_port']}...") - - if account["use_tls"]: - server = smtplib.SMTP(account["smtp_server"], account["smtp_port"]) - server.starttls() - else: - server = smtplib.SMTP(account["smtp_server"], account["smtp_port"]) - - # 登录 - if verbose: - print(f"🔑 正在登录 {account['email']}...") - server.login(account["email"], account["password"]) - - # 准备收件人列表 - recipients = [to] - if cc: - recipients.extend([addr.strip() for addr in cc.split(",")]) - if bcc: - recipients.extend([addr.strip() for addr in bcc.split(",")]) - - # 发送邮件 - if verbose: - print(f"📤 正在发送邮件...") - server.sendmail(account["email"], recipients, msg.as_string()) - server.quit() - - print(f"✅ 邮件发送成功") - print(f" 收件人: {to}") - if cc: - print(f" 抄送: {cc}") - if attachments: - valid_attachments = [a for a in attachments if os.path.exists(a)] - print(f" 附件: {len(valid_attachments)} 个") - - return True - - except Exception as e: - print(f"❌ 邮件发送失败: {e}") - return False - - -def main(): - """命令行入口""" - import argparse - - parser = argparse.ArgumentParser(description="邮件发送工具") - subparsers = parser.add_subparsers(dest="command", help="可用命令") - - # 配置命令 - config_parser = subparsers.add_parser("config", help="配置 SMTP") - config_parser.add_argument("name", help="配置名称") - config_parser.add_argument("--server", required=True, help="SMTP 服务器地址") - config_parser.add_argument("--port", type=int, required=True, help="SMTP 端口") - config_parser.add_argument("--email", required=True, help="邮箱地址") - config_parser.add_argument("--password", required=True, help="邮箱密码") - config_parser.add_argument("--no-tls", action="store_true", help="不使用 TLS(默认使用)") - - # 列出配置命令 - subparsers.add_parser("list", help="列出所有配置") - - # 发送命令 - send_parser = subparsers.add_parser("send", help="发送邮件") - send_parser.add_argument("--to", "-t", required=True, help="收件人邮箱") - send_parser.add_argument("--subject", "-s", required=True, help="邮件主题") - send_parser.add_argument("--body", "-b", required=True, help="邮件内容") - send_parser.add_argument("--account", "-a", help="使用指定配置") - send_parser.add_argument("--html", action="store_true", help="HTML 格式") - send_parser.add_argument("--cc", help="抄送邮箱(多个用逗号分隔)") - send_parser.add_argument("--bcc", help="密送邮箱(多个用逗号分隔)") - send_parser.add_argument("--from-name", help="发件人显示名称") - send_parser.add_argument("--attach", "-f", action="append", help="附件文件路径(可多次使用)") - send_parser.add_argument("-v", "--verbose", action="store_true", help="显示详细日志") - - args = parser.parse_args() - - if args.command == "config": - setup_account( - name=args.name, - smtp_server=args.server, - smtp_port=args.port, - email=args.email, - password=args.password, - use_tls=not args.no_tls - ) - - elif args.command == "list": - list_accounts() - - elif args.command == "send": - success = send_email( - to=args.to, - subject=args.subject, - body=args.body, - account_name=args.account, - html=args.html, - cc=args.cc, - bcc=args.bcc, - from_name=args.from_name, - attachments=args.attach, - verbose=args.verbose - ) - sys.exit(0 if success else 1) - - else: - parser.print_help() - - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/works/ai-chat b/works/ai-chat new file mode 160000 index 0000000..90d31db --- /dev/null +++ b/works/ai-chat @@ -0,0 +1 @@ +Subproject commit 90d31dba69eee48af55153c0cd827fd05213a90e diff --git a/works/board-monitor b/works/board-monitor new file mode 160000 index 0000000..8d77c4a --- /dev/null +++ b/works/board-monitor @@ -0,0 +1 @@ +Subproject commit 8d77c4a852e2182880e9098c57dc328795969a47 diff --git a/works/disk-scanner b/works/disk-scanner new file mode 160000 index 0000000..4ce1c93 --- /dev/null +++ b/works/disk-scanner @@ -0,0 +1 @@ +Subproject commit 4ce1c93ad3b15cf7b5f48e4d6d3c438c24bc4d04 diff --git a/works/llm-index-rag b/works/llm-index-rag index 4fb4d61..ab6469b 160000 --- a/works/llm-index-rag +++ b/works/llm-index-rag @@ -1 +1 @@ -Subproject commit 4fb4d6187785f6c61c52209ec6f85418593dcecd +Subproject commit ab6469b9dda23fe1ab195df5ba26a8ad9dd68308 diff --git a/works/mailbox/README.md b/works/mailbox/README.md new file mode 100644 index 0000000..1de5c21 --- /dev/null +++ b/works/mailbox/README.md @@ -0,0 +1,77 @@ +# 邮件收件箱管理 + +管理已读邮件内容和处理状态。 + +## 目录结构 + +``` +mailbox/ +├── inbox.json # 收件箱状态索引 +├── mailbox_manager.py # 管理脚本 +├── emails/ # 邮件存储目录 +│ └── <邮件ID>/ +│ ├── meta.json # 邮件元数据(主题、发件人、状态等) +│ ├── body.txt # 邮件正文 +│ └── attachments/ # 附件目录 +└── archive/ # 已归档邮件 +``` + +## 邮件状态 + +| 状态 | 说明 | 命令 | +|------|------|------| +| unread | 未读 | sync | +| read | 已读 | read | +| pending | 待处理 | pending | +| processing | 处理中 | processing | +| done | 已完成 | done | +| archived | 已归档 | archive | + +## 使用方法 + +```bash +cd /home/xian/.openclaw/workspace-coder/works/mailbox + +# 从 IMAP 同步未读邮件 +python3 mailbox_manager.py sync + +# 列出所有邮件 +python3 mailbox_manager.py list + +# 按状态筛选 +python3 mailbox_manager.py list pending +python3 mailbox_manager.py list done + +# 显示邮件详情 +python3 mailbox_manager.py show 42 + +# 更新状态 +python3 mailbox_manager.py read 42 # 标记已读 +python3 mailbox_manager.py pending 42 # 待处理 +python3 mailbox_manager.py processing 42 # 处理中 +python3 mailbox_manager.py done 42 完成任务 # 已完成(可加备注) + +# 归档邮件 +python3 mailbox_manager.py archive 42 +``` + +## 工作流建议 + +1. **同步邮件**: `python3 mailbox_manager.py sync` +2. **查看列表**: `python3 mailbox_manager.py list` +3. **查看详情**: `python3 mailbox_manager.py show ` +4. **处理邮件**: + - 标记为 `pending` 等待处理 + - 处理时标记为 `processing` + - 完成后标记为 `done`(可加备注) +5. **归档**: 定期归档已完成的邮件 + +## AI 使用说明 + +扣德在处理邮件时应: +1. 先同步邮件:`sync` +2. 查看未处理邮件:`list pending` 或 `list unread` +3. 读取邮件详情:`show ` +4. 根据邮件内容执行任务 +5. 完成后更新状态:`done 处理说明` +6. 定期归档旧邮件 \ No newline at end of file diff --git a/works/mailbox/__pycache__/mailbox_manager.cpython-310.pyc b/works/mailbox/__pycache__/mailbox_manager.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3cf08f50164f64715116f3ebf45435c332030ccc GIT binary patch literal 8621 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 Ww6pd%t^2HRTFa~ltpQs#?)*OisOYf( literal 0 HcmV?d00001 diff --git a/works/mailbox/emails/1/body.txt b/works/mailbox/emails/1/body.txt new file mode 100644 index 0000000..e164c9d --- /dev/null +++ b/works/mailbox/emails/1/body.txt @@ -0,0 +1,27 @@ +你按照下面的方案,开发一下 + +A股板块分析方案汇总 + +一、方案对比 +东方财富API ★★★★★ 推荐 + +二、推荐方案:东方财富HTTP API +- 行业/概念板块涨跌幅排行 +- 主力资金净流入/流出 +- 领涨股/领跌股 + +三、代码示例(已验证可用) + +四、需要解决的问题 +1. 代理问题 - 已解决 +2. 数据更新时机 +3. API稳定性 + +五、后续可扩展功能 +1. 板块监控脚本 +2. 个股-板块关联 +3. 数据存储 +4. AI增强 + +六、实施建议 +七、今日测试数据示例 \ No newline at end of file diff --git a/works/mailbox/emails/1/meta.json b/works/mailbox/emails/1/meta.json new file mode 100644 index 0000000..3501aad --- /dev/null +++ b/works/mailbox/emails/1/meta.json @@ -0,0 +1,11 @@ +{ + "id": "1", + "subject": "Fw: A股板块分析方案汇总", + "sender": "wlq@tphai.com", + "date": "Fri, 10 Apr 2026 16:38:39 +0800", + "has_attachment": false, + "status": "done", + "created_at": "2026-04-10T23:41:34.414741", + "updated_at": "2026-04-10T23:41:34.415832", + "notes": "board_monitor项目已实现全部功能:东方财富API、代理问题已解决、历史数据存储、每日盘后报告" +} \ No newline at end of file diff --git a/works/mailbox/inbox.json b/works/mailbox/inbox.json new file mode 100644 index 0000000..e7a4cc0 --- /dev/null +++ b/works/mailbox/inbox.json @@ -0,0 +1,14 @@ +{ + "description": "邮件收件箱状态追踪", + "last_check": null, + "emails": { + "1": { + "subject": "Fw: A股板块分析方案汇总", + "sender": "wlq@tphai.com", + "date": "Fri, 10 Apr 2026 16:38:39 +0800", + "status": "done", + "has_attachment": false, + "path": "/home/xian/.openclaw/workspace-coder/works/mailbox/emails/1" + } + } +} \ No newline at end of file diff --git a/works/mailbox/mailbox_manager.py b/works/mailbox/mailbox_manager.py new file mode 100644 index 0000000..9e7d5a3 --- /dev/null +++ b/works/mailbox/mailbox_manager.py @@ -0,0 +1,362 @@ +#!/usr/bin/env python3 +""" +邮件收件箱管理工具 +管理已读邮件内容和处理状态 +""" + +import json +import os +import sys +from datetime import datetime +from pathlib import Path + +# 路径配置 +SCRIPT_DIR = Path(__file__).parent +MAILBOX_DIR = SCRIPT_DIR +INBOX_FILE = MAILBOX_DIR / "inbox.json" +EMAILS_DIR = MAILBOX_DIR / "emails" +ARCHIVE_DIR = MAILBOX_DIR / "archive" + +# 状态定义 +STATUS_UNREAD = "unread" +STATUS_READ = "read" +STATUS_PENDING = "pending" # 待处理 +STATUS_PROCESSING = "processing" # 处理中 +STATUS_DONE = "done" # 已完成 +STATUS_ARCHIVED = "archived" # 已归档 + + +def load_inbox(): + """加载收件箱状态""" + if not INBOX_FILE.exists(): + return {"description": "邮件收件箱状态追踪", "last_check": None, "emails": {}} + with open(INBOX_FILE, "r", encoding="utf-8") as f: + return json.load(f) + + +def save_inbox(data): + """保存收件箱状态""" + with open(INBOX_FILE, "w", encoding="utf-8") as f: + json.dump(data, f, ensure_ascii=False, indent=2) + + +def add_email(email_id, subject, sender, date, has_attachment=False, body="", status=STATUS_UNREAD): + """添加或更新邮件记录""" + inbox = load_inbox() + + email_dir = EMAILS_DIR / str(email_id) + email_dir.mkdir(parents=True, exist_ok=True) + + # 保存邮件内容 + meta = { + "id": email_id, + "subject": subject, + "sender": sender, + "date": date, + "has_attachment": has_attachment, + "status": status, + "created_at": datetime.now().isoformat(), + "updated_at": datetime.now().isoformat(), + "notes": "" + } + + with open(email_dir / "meta.json", "w", encoding="utf-8") as f: + json.dump(meta, f, ensure_ascii=False, indent=2) + + if body: + with open(email_dir / "body.txt", "w", encoding="utf-8") as f: + f.write(body) + + # 更新收件箱索引 + inbox["emails"][str(email_id)] = { + "subject": subject, + "sender": sender, + "date": date, + "status": status, + "has_attachment": has_attachment, + "path": str(email_dir) + } + + save_inbox(inbox) + print(f"✅ 邮件 [{email_id}] 已添加到收件箱") + + +def update_status(email_id, status, notes=None): + """更新邮件状态""" + inbox = load_inbox() + email_key = str(email_id) + + if email_key not in inbox["emails"]: + print(f"❌ 邮件 [{email_id}] 不存在") + return False + + # 更新索引 + inbox["emails"][email_key]["status"] = status + + # 更新邮件详情 + email_dir = Path(inbox["emails"][email_key]["path"]) + meta_file = email_dir / "meta.json" + + if meta_file.exists(): + with open(meta_file, "r", encoding="utf-8") as f: + meta = json.load(f) + + meta["status"] = status + meta["updated_at"] = datetime.now().isoformat() + + if notes: + meta["notes"] = notes + + with open(meta_file, "w", encoding="utf-8") as f: + json.dump(meta, f, ensure_ascii=False, indent=2) + + save_inbox(inbox) + + status_emoji = { + STATUS_UNREAD: "📬", + STATUS_READ: "📖", + STATUS_PENDING: "⏳", + STATUS_PROCESSING: "🔄", + STATUS_DONE: "✅", + STATUS_ARCHIVED: "📦" + } + + print(f"{status_emoji.get(status, '📧')} 邮件 [{email_id}] 状态更新为: {status}") + return True + + +def list_emails(status_filter=None): + """列出邮件""" + inbox = load_inbox() + + if not inbox["emails"]: + print("📭 收件箱为空") + return + + status_emoji = { + STATUS_UNREAD: "📬", + STATUS_READ: "📖", + STATUS_PENDING: "⏳", + STATUS_PROCESSING: "🔄", + STATUS_DONE: "✅", + STATUS_ARCHIVED: "📦" + } + + print("📬 邮件收件箱") + print("=" * 60) + + count = 0 + for email_id, info in sorted(inbox["emails"].items(), key=lambda x: x[0], reverse=True): + if status_filter and info["status"] != status_filter: + continue + + emoji = status_emoji.get(info["status"], "📧") + attach = "📎" if info.get("has_attachment") else "" + + print(f"\n[{email_id}] {emoji} {attach}") + print(f" 主题: {info['subject']}") + print(f" 发件人: {info['sender']}") + print(f" 时间: {info['date']}") + print(f" 状态: {info['status']}") + count += 1 + + print("\n" + "=" * 60) + print(f"共 {count} 封邮件") + + +def show_email(email_id): + """显示邮件详情""" + inbox = load_inbox() + email_key = str(email_id) + + if email_key not in inbox["emails"]: + print(f"❌ 邮件 [{email_id}] 不存在") + return + + email_dir = Path(inbox["emails"][email_key]["path"]) + meta_file = email_dir / "meta.json" + body_file = email_dir / "body.txt" + + print(f"📧 邮件详情 [{email_id}]") + print("=" * 60) + + if meta_file.exists(): + with open(meta_file, "r", encoding="utf-8") as f: + meta = json.load(f) + + print(f"主题: {meta.get('subject', 'N/A')}") + print(f"发件人: {meta.get('sender', 'N/A')}") + print(f"时间: {meta.get('date', 'N/A')}") + print(f"状态: {meta.get('status', 'N/A')}") + print(f"更新时间: {meta.get('updated_at', 'N/A')}") + + if meta.get('notes'): + print(f"\n备注: {meta['notes']}") + + if body_file.exists(): + print("\n正文:") + print("-" * 40) + with open(body_file, "r", encoding="utf-8") as f: + print(f.read()) + + # 列出附件 + attach_dir = email_dir / "attachments" + if attach_dir.exists() and list(attach_dir.iterdir()): + print("\n附件:") + print("-" * 40) + for f in attach_dir.iterdir(): + print(f" 📎 {f.name}") + + +def archive_email(email_id): + """归档邮件""" + inbox = load_inbox() + email_key = str(email_id) + + if email_key not in inbox["emails"]: + print(f"❌ 邮件 [{email_id}] 不存在") + return False + + email_dir = Path(inbox["emails"][email_key]["path"]) + + # 移动到归档目录 + archive_path = ARCHIVE_DIR / str(email_id) + if email_dir.exists(): + import shutil + shutil.move(str(email_dir), str(archive_path)) + + # 更新索引 + inbox["emails"][email_key]["status"] = STATUS_ARCHIVED + inbox["emails"][email_key]["path"] = str(archive_path) + save_inbox(inbox) + + print(f"📦 邮件 [{email_id}] 已归档") + return True + + +def sync_from_imap(): + """从 IMAP 同步未读邮件""" + try: + # 导入 receive_email 模块 + email_scripts_dir = Path(__file__).parent.parent.parent / "skills" / "email" / "scripts" + sys.path.insert(0, str(email_scripts_dir)) + from receive_email import list_unread, read_email + + print("🔄 正在同步邮件...") + + emails = list_unread(limit=20, verbose=False) + + if not emails: + print("📭 没有新邮件") + return + + inbox = load_inbox() + new_count = 0 + + for e in emails: + email_id = str(e['id']) + + # 跳过已存在的邮件 + if email_id in inbox["emails"]: + continue + + # 读取邮件详情 + detail = read_email(email_id=email_id, save_attachments=True, verbose=False) + + if detail: + add_email( + email_id=email_id, + subject=detail.get('subject', ''), + sender=detail.get('from', ''), + date=detail.get('date', ''), + has_attachment=len(detail.get('attachments', [])) > 0, + body=detail.get('body', ''), + status=STATUS_UNREAD + ) + new_count += 1 + + # 更新最后检查时间 + inbox["last_check"] = datetime.now().isoformat() + save_inbox(inbox) + + print(f"\n✅ 同步完成,新增 {new_count} 封邮件") + + except Exception as e: + print(f"❌ 同步失败: {e}") + + +def main(): + if len(sys.argv) < 2: + print("邮件收件箱管理工具") + print() + print("用法:") + print(" python3 mailbox_manager.py sync # 从IMAP同步未读邮件") + print(" python3 mailbox_manager.py list [status] # 列出邮件(可按状态筛选)") + print(" python3 mailbox_manager.py show # 显示邮件详情") + print(" python3 mailbox_manager.py read # 标记为已读") + print(" python3 mailbox_manager.py pending # 标记为待处理") + print(" python3 mailbox_manager.py processing # 标记为处理中") + print(" python3 mailbox_manager.py done [notes] # 标记为已完成") + print(" python3 mailbox_manager.py archive # 归档邮件") + print() + print("状态说明:") + print(" unread - 未读") + print(" read - 已读") + print(" pending - 待处理") + print(" processing - 处理中") + print(" done - 已完成") + print(" archived - 已归档") + return + + command = sys.argv[1] + + if command == "sync": + sync_from_imap() + + elif command == "list": + status = sys.argv[2] if len(sys.argv) > 2 else None + list_emails(status) + + elif command == "show": + if len(sys.argv) < 3: + print("❌ 请指定邮件ID") + return + show_email(sys.argv[2]) + + elif command == "read": + if len(sys.argv) < 3: + print("❌ 请指定邮件ID") + return + update_status(sys.argv[2], STATUS_READ) + + elif command == "pending": + if len(sys.argv) < 3: + print("❌ 请指定邮件ID") + return + update_status(sys.argv[2], STATUS_PENDING) + + elif command == "processing": + if len(sys.argv) < 3: + print("❌ 请指定邮件ID") + return + update_status(sys.argv[2], STATUS_PROCESSING) + + elif command == "done": + if len(sys.argv) < 3: + print("❌ 请指定邮件ID") + return + notes = " ".join(sys.argv[3:]) if len(sys.argv) > 3 else None + update_status(sys.argv[2], STATUS_DONE, notes) + + elif command == "archive": + if len(sys.argv) < 3: + print("❌ 请指定邮件ID") + return + archive_email(sys.argv[2]) + + else: + print(f"❌ 未知命令: {command}") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/works/multi-agent-bidding b/works/multi-agent-bidding new file mode 160000 index 0000000..43f7588 --- /dev/null +++ b/works/multi-agent-bidding @@ -0,0 +1 @@ +Subproject commit 43f758807e37815bcb6e60a088f35016aa8a0d33 diff --git a/works/param-hub b/works/param-hub index 0561c6d..f249f28 160000 --- a/works/param-hub +++ b/works/param-hub @@ -1 +1 @@ -Subproject commit 0561c6da6f2e58d0a0c2534b924e52db07ee8f82 +Subproject commit f249f28eb7ab7715a345d9c90494d96bcde47361 diff --git a/works/param-hub-python b/works/param-hub-python new file mode 160000 index 0000000..627148a --- /dev/null +++ b/works/param-hub-python @@ -0,0 +1 @@ +Subproject commit 627148a87fe0feedf056d7f53edbb21a27850518 diff --git a/works/pdf-translate-web-v2 b/works/pdf-translate-web-v2 index 2ef5e6d..d338522 160000 --- a/works/pdf-translate-web-v2 +++ b/works/pdf-translate-web-v2 @@ -1 +1 @@ -Subproject commit 2ef5e6da872e2fd94f5fc837444f88d0555b8a26 +Subproject commit d338522692de1756d4457e0b982e0bbf415d4f15 diff --git a/works/project-panel b/works/project-panel new file mode 160000 index 0000000..c73196d --- /dev/null +++ b/works/project-panel @@ -0,0 +1 @@ +Subproject commit c73196dad37aa418ccb488653d90e189268e81a4 diff --git a/works/service-monitor b/works/service-monitor new file mode 160000 index 0000000..a7cc605 --- /dev/null +++ b/works/service-monitor @@ -0,0 +1 @@ +Subproject commit a7cc60596e2f62956c9bd32a38cdafa178227ed2 diff --git a/works/snippet-notes b/works/snippet-notes new file mode 160000 index 0000000..8c4c0af --- /dev/null +++ b/works/snippet-notes @@ -0,0 +1 @@ +Subproject commit 8c4c0af053704e82987e030222c20fdf87b6b6d9 diff --git a/works/xian-favor b/works/xian-favor new file mode 160000 index 0000000..184cc5b --- /dev/null +++ b/works/xian-favor @@ -0,0 +1 @@ +Subproject commit 184cc5b56b270d02d52feb179675986b4527007e