diff --git a/.env b/.env deleted file mode 100644 index de78e8a..0000000 --- a/.env +++ /dev/null @@ -1,103 +0,0 @@ -# 闲鱼自动回复系统 Docker 环境变量配置文件 -# 这是默认配置,您可以根据需要修改 - -# ================================ -# 基础配置 -# ================================ - -# 时区设置 -TZ=Asia/Shanghai - -# Python配置 -PYTHONUNBUFFERED=1 -PYTHONDONTWRITEBYTECODE=1 - -# 日志级别 (DEBUG, INFO, WARNING, ERROR) -LOG_LEVEL=INFO - -# ================================ -# 数据库配置 -# ================================ - -# 数据库文件路径 -DB_PATH=/app/data/xianyu_data.db - -# ================================ -# 服务配置 -# ================================ - -# API服务配置 -API_HOST=0.0.0.0 # 绑定所有网络接口,支持IP访问 -API_PORT=8080 # Web服务端口 - -# Web服务端口 (Docker端口映射) -WEB_PORT=8080 - -# ================================ -# 安全配置 -# ================================ - -# 管理员账号密码 (建议修改) -ADMIN_USERNAME=admin -ADMIN_PASSWORD=admin123 - -# JWT密钥 (建议修改为随机字符串) -JWT_SECRET_KEY=xianyu-auto-reply-secret-key-2024 - -# Session超时时间 (秒) -SESSION_TIMEOUT=3600 - -# ================================ -# 闲鱼API配置 -# ================================ - -# WebSocket连接URL -WEBSOCKET_URL=wss://wss-goofish.dingtalk.com/ - -# 心跳间隔 (秒) -HEARTBEAT_INTERVAL=15 - -# 心跳超时 (秒) -HEARTBEAT_TIMEOUT=5 - -# Token刷新间隔 (秒) -TOKEN_REFRESH_INTERVAL=3600 - -# Token重试间隔 (秒) -TOKEN_RETRY_INTERVAL=300 - -# 消息过期时间 (毫秒) -MESSAGE_EXPIRE_TIME=300000 - -# ================================ -# 自动回复配置 -# ================================ - -# 是否启用自动回复 -AUTO_REPLY_ENABLED=true - -# ================================ -# 资源限制 -# ================================ - -# 内存限制 (MB) -MEMORY_LIMIT=512 - -# CPU限制 (核心数) -CPU_LIMIT=0.5 - -# 内存预留 (MB) -MEMORY_RESERVATION=256 - -# CPU预留 (核心数) -CPU_RESERVATION=0.25 - -# ================================ -# 开发配置 -# ================================ - -# 开发模式 (true/false) -DEBUG=false - -# 热重载 (true/false) -RELOAD=false diff --git a/.gitignore b/.gitignore index 444c9a3..292795c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,9 @@ dist/ downloads/ eggs/ .eggs/ +# Python lib directories (but not static/lib) lib/ +!static/lib/ lib64/ parts/ sdist/ @@ -20,6 +22,11 @@ MANIFEST .cache *.log local_settings.py + +# Database files +*.db +*.sqlite +*.sqlite3 db.sqlite3 __pypackages__/ .venv @@ -28,4 +35,30 @@ venv/ ENV/ env.bak/ venv.bak/ -*.db \ No newline at end of file + +# Temporary files +*.tmp +*.temp +temp/ +tmp/ + +# OS generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# IDE files +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# Local environment files +.env +.env.local +.env.*.local \ No newline at end of file diff --git a/AI_REPLY_GUIDE.md b/AI_REPLY_GUIDE.md index b89de42..f700fd7 100644 --- a/AI_REPLY_GUIDE.md +++ b/AI_REPLY_GUIDE.md @@ -113,16 +113,14 @@ AI分析消息内容,识别用户意图: ## 📊 优先级说明 -系统回复优先级为: +当账号启用AI回复后,系统回复优先级为: 1. **🔥 API回复** (最高优先级) -2. **📝 关键词匹配** (优先匹配精确关键词) -3. **🤖 AI回复** (AI启用时的智能回复) +2. **🤖 AI回复** (AI启用时) +3. **📝 关键词匹配** (AI禁用时) 4. **💬 默认回复** (最低优先级) -> ✨ **优化**: 关键词回复优先于AI回复,确保重要关键词能够精确匹配! -> -> 💡 **说明**: 即使启用AI回复,关键词匹配仍然有效,只有在没有匹配的关键词时才会使用AI回复。 +> ⚠️ **重要**: 启用AI回复后,关键词匹配和默认回复将自动失效! ## 🧪 功能测试 diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 16a7a8a..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,178 +0,0 @@ -# 📋 更新日志 - -本文档记录了闲鱼自动回复管理系统的所有重要更新和变更。 - -## [v2.0.2] - 2024-07-24 - -### 🔧 功能改进 -- **日志系统优化**:完善统一日志记录系统 - - 所有日志统一记录到文件中,界面读取日志文件显示 - - 添加智能日志过滤器,过滤掉不必要的API请求日志 - - 优化日志格式,便于解析和展示 - - 提高日志收集的实时性和准确性 - - 过滤掉频繁的健康检查、静态资源请求等日志 - -### 🚀 性能优化 -- **日志性能提升**:减少不必要的日志记录,提高系统性能 -- **文件监控优化**:优化日志文件监控频率,更及时地收集日志 -- **内存使用优化**:智能过滤减少内存中的日志数量 - -### 📚 文档更新 -- 新增日志过滤器说明文档 -- 更新日志管理功能说明 - -## [v2.0.1] - 2024-07-24 - -### 🔧 功能改进 -- **回复优先级优化**:调整自动回复逻辑,关键词回复优先于AI回复 - - 新的优先级顺序:API回复 → 关键词回复 → AI回复 → 默认回复 - - 确保重要关键词能够精确匹配,AI回复作为智能补充 - - 提高回复的准确性和用户体验 - -### 📚 文档更新 -- 更新AI回复功能指南中的优先级说明 -- 更新使用说明中的回复逻辑描述 -- 更新README.md中的功能特性说明 - -## [v2.0.0] - 2024-07-24 - -### 🎉 重大更新 -- **AI智能回复系统**:集成多种AI模型,支持智能对话和议价 -- **商品管理功能**:自动收集和管理商品信息 -- **实时日志系统**:完整的日志收集、查看和分析功能 -- **Docker容器化**:完整的Docker部署支持 - -### ✨ 新增功能 -- **多AI模型支持**:支持通义千问、GPT等主流AI模型 -- **智能意图识别**:自动识别价格咨询、技术问题、通用咨询 -- **智能议价系统**:阶梯式降价策略,可设置最大优惠幅度 -- **商品信息自动收集**:消息触发时自动提取并保存商品信息 -- **批量商品获取**:一键获取账号下所有商品信息 -- **实时日志查看**:Web界面实时查看系统运行日志 -- **日志过滤和搜索**:支持按级别、来源、关键词过滤日志 -- **系统健康监控**:完整的系统健康检查和监控 -- **数据备份恢复**:支持完整的数据备份和恢复功能 - -### 🔧 功能改进 -- **用户界面优化**:现代化的Web界面设计 -- **性能优化**:异步处理,提高系统并发能力 -- **安全增强**:JWT认证,数据加密存储 -- **错误处理**:完善的错误处理和重试机制 -- **配置管理**:灵活的配置文件管理系统 - -### 🐛 问题修复 -- 修复WebSocket连接不稳定的问题 -- 修复Cookie失效时的自动刷新机制 -- 修复数据库并发访问的问题 -- 修复文件上传的安全问题 -- 修复日志文件过大的问题 - -### 📚 文档更新 -- 完整的README.md文档 -- 详细的功能使用说明 -- Docker部署指南 -- API接口文档 -- 故障排除指南 - -## [v1.5.0] - 2024-06-15 - -### ✨ 新增功能 -- **自动发货增强**:支持API接口类型卡券 -- **批量数据管理**:支持批量导入和管理卡券 -- **发货规则优化**:更智能的商品匹配算法 -- **消息通知格式化**:美化消息通知格式 - -### 🔧 功能改进 -- 优化自动发货匹配逻辑 -- 改进卡券管理界面 -- 增强错误处理机制 -- 提升系统稳定性 - -### 🐛 问题修复 -- 修复发货规则匹配不准确的问题 -- 修复批量数据消耗过快的问题 -- 修复API接口调用失败的问题 - -## [v1.4.0] - 2024-05-20 - -### ✨ 新增功能 -- **多账号管理**:支持同时管理多个闲鱼账号 -- **关键词回复**:每个账号独立的关键词回复设置 -- **用户认证系统**:安全的登录认证机制 -- **数据持久化**:SQLite数据库存储 - -### 🔧 功能改进 -- 重构代码架构,提高可维护性 -- 优化数据库设计 -- 改进用户界面体验 -- 增强系统安全性 - -## [v1.3.0] - 2024-04-25 - -### ✨ 新增功能 -- **自动发货功能**:支持自动发送卡券和虚拟商品 -- **发货规则配置**:灵活的发货规则设置 -- **卡券管理**:支持多种卡券类型管理 - -### 🔧 功能改进 -- 优化消息处理逻辑 -- 改进WebSocket连接稳定性 -- 增强日志记录功能 - -## [v1.2.0] - 2024-03-30 - -### ✨ 新增功能 -- **Web管理界面**:现代化的Web管理界面 -- **实时状态监控**:实时查看系统运行状态 -- **配置文件管理**:可视化配置文件编辑 - -### 🔧 功能改进 -- 优化自动回复逻辑 -- 改进错误处理机制 -- 增强系统稳定性 - -## [v1.1.0] - 2024-02-28 - -### ✨ 新增功能 -- **关键词匹配**:支持关键词自动回复 -- **变量替换**:支持消息中的变量替换 -- **日志系统**:完整的日志记录功能 - -### 🔧 功能改进 -- 优化WebSocket连接处理 -- 改进消息解析逻辑 -- 增强系统容错能力 - -## [v1.0.0] - 2024-01-15 - -### 🎉 首次发布 -- **基础自动回复**:支持闲鱼消息自动回复 -- **WebSocket连接**:稳定的WebSocket连接机制 -- **Token管理**:自动Token刷新和管理 -- **消息处理**:完整的消息接收和处理流程 - ---- - -## 📝 版本说明 - -### 版本号规则 -- **主版本号**:重大功能更新或架构变更 -- **次版本号**:新功能添加或重要改进 -- **修订版本号**:问题修复和小幅改进 - -### 更新类型说明 -- 🎉 **重大更新**:重要的新功能或架构变更 -- ✨ **新增功能**:新增的功能特性 -- 🔧 **功能改进**:现有功能的优化和改进 -- 🐛 **问题修复**:Bug修复和问题解决 -- 📚 **文档更新**:文档和说明的更新 -- 🔒 **安全更新**:安全相关的更新和修复 - -### 兼容性说明 -- **向后兼容**:新版本保持与旧版本的兼容性 -- **配置迁移**:提供配置文件自动迁移功能 -- **数据迁移**:提供数据库自动升级功能 - ---- - -**注意**:建议在升级前备份重要数据,详细的升级指南请参考相关文档。 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index c897ef4..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,220 +0,0 @@ -# 🤝 贡献指南 - -感谢您对闲鱼自动回复管理系统的关注!我们欢迎任何形式的贡献,包括但不限于代码、文档、问题反馈和功能建议。 - -## 📋 贡献方式 - -### 🐛 报告问题 -如果您发现了bug或有改进建议,请: -1. 检查 [Issues](https://github.com/your-repo/xianyu-auto-reply/issues) 确认问题未被报告 -2. 创建新的Issue,详细描述问题 -3. 提供复现步骤和环境信息 -4. 如果可能,提供错误日志和截图 - -### 💡 功能建议 -如果您有新功能的想法: -1. 在Issues中创建功能请求 -2. 详细描述功能需求和使用场景 -3. 说明功能的预期效果 -4. 讨论实现方案的可行性 - -### 🔧 代码贡献 -我们欢迎代码贡献,请遵循以下流程: - -#### 开发环境搭建 -1. **Fork项目**到您的GitHub账号 -2. **克隆项目**到本地: - ```bash - git clone https://github.com/your-username/xianyu-auto-reply.git - cd xianyu-auto-reply - ``` -3. **创建虚拟环境**: - ```bash - python -m venv venv - source venv/bin/activate # Linux/Mac - # 或 - venv\Scripts\activate # Windows - ``` -4. **安装依赖**: - ```bash - pip install -r requirements.txt - ``` -5. **运行测试**确保环境正常: - ```bash - python Start.py - ``` - -#### 开发流程 -1. **创建分支**: - ```bash - git checkout -b feature/your-feature-name - ``` -2. **编写代码**,遵循项目的代码规范 -3. **编写测试**,确保新功能有相应的测试用例 -4. **运行测试**,确保所有测试通过 -5. **提交代码**: - ```bash - git add . - git commit -m "feat: 添加新功能描述" - ``` -6. **推送分支**: - ```bash - git push origin feature/your-feature-name - ``` -7. **创建Pull Request** - -## 📝 代码规范 - -### Python代码规范 -- 遵循 [PEP 8](https://www.python.org/dev/peps/pep-0008/) 代码风格 -- 使用有意义的变量和函数名 -- 添加必要的注释和文档字符串 -- 保持函数简洁,单一职责原则 - -### 提交信息规范 -使用 [Conventional Commits](https://www.conventionalcommits.org/) 规范: - -``` -[optional scope]: - -[optional body] - -[optional footer(s)] -``` - -#### 提交类型 -- `feat`: 新功能 -- `fix`: 问题修复 -- `docs`: 文档更新 -- `style`: 代码格式调整 -- `refactor`: 代码重构 -- `test`: 测试相关 -- `chore`: 构建过程或辅助工具的变动 - -#### 示例 -``` -feat(ai): 添加智能议价功能 - -- 实现阶梯式降价策略 -- 支持最大优惠限制 -- 添加议价轮数统计 - -Closes #123 -``` - -### 文档规范 -- 使用Markdown格式 -- 保持文档结构清晰 -- 添加必要的代码示例 -- 及时更新相关文档 - -## 🧪 测试指南 - -### 运行测试 -```bash -# 运行所有测试 -python -m pytest - -# 运行特定测试文件 -python -m pytest tests/test_ai_reply.py - -# 运行带覆盖率的测试 -python -m pytest --cov=. -``` - -### 编写测试 -- 为新功能编写单元测试 -- 确保测试覆盖率不低于80% -- 使用有意义的测试名称 -- 测试边界条件和异常情况 - -### 测试示例 -```python -def test_ai_reply_with_valid_input(): - """测试AI回复功能的正常输入""" - # 准备测试数据 - message = "这个商品能便宜点吗?" - - # 执行测试 - result = ai_reply_engine.process_message(message) - - # 验证结果 - assert result is not None - assert "优惠" in result -``` - -## 📚 文档贡献 - -### 文档类型 -- **用户文档**:使用说明、配置指南 -- **开发文档**:API文档、架构说明 -- **部署文档**:安装部署指南 - -### 文档更新 -- 新功能需要更新相关文档 -- 修复文档中的错误和过时信息 -- 改进文档的可读性和准确性 - -## 🔍 代码审查 - -### 审查标准 -- **功能正确性**:代码是否实现了预期功能 -- **代码质量**:是否遵循代码规范 -- **性能考虑**:是否有性能问题 -- **安全性**:是否存在安全隐患 -- **测试覆盖**:是否有足够的测试 - -### 审查流程 -1. 提交Pull Request -2. 自动化测试运行 -3. 代码审查和讨论 -4. 修改和完善 -5. 合并到主分支 - -## 🎯 贡献建议 - -### 适合新手的任务 -- 修复文档中的错误 -- 改进错误信息和提示 -- 添加单元测试 -- 优化用户界面 - -### 高级贡献 -- 新功能开发 -- 性能优化 -- 架构改进 -- 安全增强 - -## 📞 联系方式 - -### 获取帮助 -- **GitHub Issues**:报告问题和讨论 -- **GitHub Discussions**:一般性讨论和问答 -- **Email**:紧急问题联系 - -### 社区参与 -- 参与Issue讨论 -- 帮助其他用户解决问题 -- 分享使用经验和技巧 -- 推广项目 - -## 🏆 贡献者认可 - -### 贡献者列表 -我们会在项目中维护贡献者列表,感谢每一位贡献者的付出。 - -### 贡献统计 -- 代码贡献 -- 文档贡献 -- 问题报告 -- 功能建议 - -## 📄 许可证 - -通过贡献代码,您同意您的贡献将在 [MIT License](LICENSE) 下发布。 - ---- - -**再次感谢您的贡献!** 🙏 - -每一个贡献都让这个项目变得更好,无论大小,我们都非常感激。让我们一起构建一个更好的闲鱼自动回复管理系统! diff --git a/LICENSE b/LICENSE index 19a5768..4501f64 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 Xianyu Auto Reply System +Copyright (c) 2025 肥极喵 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 30ec1c6..ce4260f 100644 --- a/README.md +++ b/README.md @@ -1,510 +1,173 @@ -# 🚀 闲鱼自动回复管理系统 +# 🐟 XianYuAutoDeliveryX - 闲鱼虚拟商品商自动发货&聊天对接大模型 -
+[![Python Version](https://img.shields.io/badge/python-3.7%2B-blue)](https://www.python.org/) +[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE) -![Python](https://img.shields.io/badge/Python-3.11+-blue.svg) -![FastAPI](https://img.shields.io/badge/FastAPI-0.111+-green.svg) -![Docker](https://img.shields.io/badge/Docker-支持-blue.svg) -![License](https://img.shields.io/badge/License-MIT-yellow.svg) -![Version](https://img.shields.io/badge/Version-v2.0.0-brightgreen.svg) -![Platform](https://img.shields.io/badge/Platform-Linux%20%7C%20Windows%20%7C%20macOS-lightgrey.svg) +**✨ 基于闲鱼API的自动发货系统,支持虚拟商品商品聊天窗口自动发货、消息自动回复等功能。** +**⚠️ 注意:本项目仅供学习交流使用,请勿用于商业用途。** -**一个功能强大的闲鱼自动回复管理系统,支持多账号管理、AI智能回复、自动发货等功能** +## 🌟 核心特性 -[功能特性](#-功能特性) • [快速开始](#-快速开始) • [部署方式](#-部署方式) • [使用文档](#-使用文档) • [API文档](#-api文档) • [贡献指南](#-贡献指南) +- 🔐 **用户认证系统** - 安全的登录认证,保护管理界面 +- 👥 **多账号管理** - 支持同时管理多个闲鱼账号 +- 🎯 **智能关键词回复** - 每个账号独立的关键词回复设置 +- 💾 **数据持久化** - SQLite数据库存储账号和关键词数据 +- 🌐 **美观Web界面** - 响应式设计,操作简单直观 +- 📡 **API接口** - 完整的RESTful API支持 +- 🔄 **实时消息处理** - 基于WebSocket的实时消息监控 +- 📊 **订单状态监控** - 实时跟踪订单状态变化 +- 📝 **完善的日志系统** - 详细的操作日志记录 -
+## 🛠️ 快速开始 -## 📋 项目概述 - -闲鱼自动回复管理系统是一个基于 Python + FastAPI 开发的自动化客服系统,专为闲鱼平台设计。系统通过 WebSocket 连接闲鱼服务器,实时接收和处理消息,提供智能化的自动回复服务。 - -### 🎯 核心优势 - -- **🤖 AI智能回复**:集成多种AI模型,支持意图识别和智能议价 -- **🔄 多账号管理**:同时管理多个闲鱼账号,独立配置和监控 -- **📦 商品管理**:自动收集和管理商品信息,支持批量操作 -- **🚚 自动发货**:智能匹配发货规则,自动发送卡券信息 -- **📊 实时监控**:完整的日志系统和状态监控 -- **🐳 容器化部署**:支持Docker一键部署,简化运维 - -## ✨ 功能特性 - -### 🤖 AI智能回复 -- **多模型支持**:支持通义千问、GPT等主流AI模型 -- **意图识别**:自动识别价格咨询、技术问题、通用咨询 -- **智能议价**:阶梯式降价策略,可设置最大优惠幅度 -- **上下文感知**:记住完整对话历史,提供连贯回复 -- **自定义提示词**:支持针对不同场景自定义AI提示词 -- **智能优先级**:关键词回复优先,AI回复作为智能补充 - -### 👥 多账号管理 -- **账号隔离**:每个账号独立配置和管理 -- **批量操作**:支持批量添加、删除、配置账号 -- **状态监控**:实时监控账号连接状态和消息处理情况 -- **权限控制**:基于JWT的安全认证系统 - -### 📦 商品管理 -- **自动收集**:消息触发时自动收集商品信息 -- **详情获取**:通过API获取完整商品详情 -- **批量管理**:支持查看、编辑、删除商品信息 -- **智能匹配**:基于商品信息进行关键词匹配 - -### 🚚 自动发货 -- **规则配置**:灵活的发货规则配置系统 -- **卡券管理**:支持多种卡券类型和批量导入 -- **智能匹配**:根据商品信息自动匹配发货规则 -- **发货记录**:完整的发货历史记录和统计 - -### 📊 监控与日志 -- **实时日志**:多级别日志记录和实时查看 -- **性能监控**:系统资源使用情况监控 -- **消息统计**:消息处理统计和分析 -- **健康检查**:完整的系统健康检查机制 - -## 🛠️ 技术栈 - -### 后端技术 -- **Python 3.11+**:主要开发语言 -- **FastAPI**:现代化的Web框架 -- **SQLite**:轻量级数据库 -- **WebSocket**:实时通信 -- **AsyncIO**:异步编程 - -### 前端技术 -- **HTML5 + CSS3**:现代化界面设计 -- **JavaScript (ES6+)**:交互逻辑 -- **Bootstrap**:响应式布局 -- **Chart.js**:数据可视化 - -### 部署技术 -- **Docker**:容器化部署 -- **Docker Compose**:多容器编排 -- **Nginx**:反向代理和负载均衡 -- **SSL/TLS**:安全传输 - -## 🚀 快速开始 - -> 💡 **推荐使用Docker镜像部署,无需配置环境,一键启动!** - -### 🐳 方式一:Docker 镜像部署(推荐) - -**使用预构建的Docker镜像,一键启动:** +### ⛳ 运行环境 +- Python 3.7+ +### 🎯 安装依赖 ```bash -docker run -d -p 8080:8080 --name xianyu-auto-reply --privileged=true registry.cn-shanghai.aliyuncs.com/zhinian-software/xianyu-auto-reply:1.0 +pip install -r requirements.txt ``` -**特点:** -- ✅ **零配置**:无需安装Python环境和依赖 -- ✅ **即开即用**:一条命令启动完整系统 -- ✅ **稳定可靠**:经过测试的稳定版本 -- ✅ **自动更新**:支持数据持久化和版本升级 +### 🎨 配置说明 +1. 在 `global_config.yml` 中配置基本参数 +2. 系统支持多账号管理,可通过Web界面添加多个闲鱼账号Cookie -**访问系统:** -- 🌐 Web界面:http://localhost:8080 -- 👤 默认账号:admin / admin123 -- 📖 API文档:http://localhost:8080/docs - -**常用管理命令:** +### 🚀 运行项目 ```bash -# 查看容器状态 -docker ps - -# 查看容器日志 -docker logs xianyu-auto-reply - -# 重启容器 -docker restart xianyu-auto-reply - -# 停止容器 -docker stop xianyu-auto-reply - -# 删除容器 -docker rm xianyu-auto-reply +python Start.py ``` -### 方式二:Docker 源码部署 +### 🔐 登录系统 +1. 启动后访问 `http://localhost:8080` +2. 默认登录账号: + - 用户名:`admin` + - 密码:`admin123` +3. 登录后可进入管理界面进行操作 -1. **克隆项目** - ```bash - git clone https://github.com/your-repo/xianyu-auto-reply.git - cd xianyu-auto-reply - ``` - -2. **一键部署** - ```bash - ./deploy.sh - ``` - -3. **访问系统** - - 打开浏览器访问:http://localhost:8080 - - 默认账号:admin / admin123 - -### 方式三:本地部署 - -1. **安装依赖** - ```bash - pip install -r requirements.txt - ``` - -2. **启动系统** - ```bash - python Start.py - ``` - -3. **访问系统** - - 打开浏览器访问:http://localhost:8080 - -## 📚 使用文档 - -### 基础使用 -1. **[使用说明](./使用说明.md)** - 系统基础使用指南 -2. **[Docker部署说明](./Docker部署说明.md)** - Docker部署详细说明 - -### 功能文档 -1. **[AI回复功能指南](./AI_REPLY_GUIDE.md)** - AI回复功能详细说明 -2. **[商品管理功能说明](./商品管理功能说明.md)** - 商品管理功能使用 -3. **[自动发货功能说明](./自动发货功能说明.md)** - 自动发货配置和使用 -4. **[日志管理功能说明](./日志管理功能说明.md)** - 日志查看和管理 -5. **[获取所有商品功能说明](./获取所有商品功能说明.md)** - 商品批量获取功能 - -## 🔧 配置说明 - -### 环境变量配置 -```bash -# 基础配置 -TZ=Asia/Shanghai -WEB_PORT=8080 - -# 管理员账号 -ADMIN_USERNAME=admin -ADMIN_PASSWORD=admin123 - -# AI回复配置 -AI_REPLY_ENABLED=true -DEFAULT_AI_MODEL=qwen-plus -DEFAULT_AI_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1 +## 📁 项目结构 +``` +├── Start.py # 项目启动入口 +├── XianyuAutoAsync.py # 核心业务逻辑 +├── config.py # 配置管理 +├── cookie_manager.py # Cookie管理器 +├── db_manager.py # 数据库管理 +├── reply_server.py # FastAPI服务器 +├── utils/ # 工具函数目录 +│ ├── xianyu_utils.py # 闲鱼相关工具 +│ ├── message_utils.py # 消息处理工具 +│ └── ws_utils.py # WebSocket工具 +├── static/ # 静态资源 +│ ├── index.html # 管理界面 +│ └── login.html # 登录页面 +├── logs/ # 日志文件 +├── global_config.yml # 全局配置文件 +├── xianyu_data.db # SQLite数据库 +└── requirements.txt # Python依赖 ``` -### 全局配置文件 -主要配置文件为 `global_config.yml`,包含: -- API端点配置 -- WebSocket连接配置 -- 自动回复配置 -- 日志配置 -- 商品详情获取配置 +## 🎯 主要功能 -## 📡 API文档 +### 1. 用户认证系统 +- 安全的登录认证机制 +- Session token管理 +- 自动登录状态检查 +- 登出功能 -### 认证接口 -- `POST /login` - 用户登录 -- `POST /logout` - 用户登出 +### 2. 多账号管理 +- 支持添加多个闲鱼账号 +- 每个账号独立管理 +- Cookie安全存储 +- 账号状态监控 -### 账号管理 -- `GET /cookies` - 获取所有账号 -- `POST /cookies` - 添加新账号 -- `DELETE /cookies/{cookie_id}` - 删除账号 +### 3. 智能关键词回复 +- 每个账号独立的关键词设置 +- 支持变量替换:`{send_user_name}`, `{send_user_id}`, `{send_message}` +- 实时关键词匹配 +- 默认回复机制 -### AI回复管理 -- `GET /ai-reply/{cookie_id}` - 获取AI配置 -- `POST /ai-reply/{cookie_id}` - 保存AI配置 -- `POST /ai-reply/{cookie_id}/test` - 测试AI回复 +### 4. Web管理界面 +- 响应式设计,支持移动端 +- 直观的操作界面 +- 实时数据更新 +- 操作反馈提示 -### 商品管理 -- `GET /items` - 获取所有商品 -- `GET /items/cookie/{cookie_id}` - 获取指定账号商品 -- `PUT /items/{cookie_id}/{item_id}` - 更新商品详情 +## 🔌 API 接口说明 -### 系统监控 -- `GET /health` - 健康检查 -- `GET /logs` - 获取系统日志 -- `GET /logs/stats` - 日志统计信息 +### 智能回复接口 +`POST http://localhost:8080/xianyu/reply` -完整API文档访问:http://localhost:8080/docs +#### 接口说明 +你需要实现这个接口,本项目会调用这个接口获取自动回复的内容并发送给客户 +不实现这个接口也没关系,系统会默认回复,你也可以配置默认回复的内容 +用于处理闲鱼消息的自动回复,支持对接大语言模型进行智能回复。 -## 🏗️ 项目结构 - -``` -xianyu-auto-reply/ -├── Start.py # 项目启动入口 -├── XianyuAutoAsync.py # 闲鱼WebSocket客户端 -├── reply_server.py # FastAPI Web服务器 -├── config.py # 配置管理 -├── cookie_manager.py # Cookie账号管理 -├── db_manager.py # 数据库管理 -├── ai_reply_engine.py # AI回复引擎 -├── file_log_collector.py # 文件日志收集器 -├── bargain_demo.py # 议价功能演示 -├── global_config.yml # 全局配置文件 -├── requirements.txt # Python依赖 -├── Dockerfile # Docker镜像构建 -├── docker-compose.yml # Docker编排配置 -├── deploy.sh # 部署脚本 -├── static/ # 前端静态文件 -│ ├── index.html # 主页面 -│ ├── login.html # 登录页面 -│ └── xianyu_js_version_2.js # 前端逻辑 -├── utils/ # 工具模块 -│ ├── xianyu_utils.py # 闲鱼工具函数 -│ ├── message_utils.py # 消息处理工具 -│ └── ws_utils.py # WebSocket工具 -├── nginx/ # Nginx配置 -├── docs/ # 文档目录 -└── backups/ # 备份目录 +**通过这个接口可以检测到用户是否已付款,然后回复虚拟资料内容即可** +#### 请求参数 +```json +{ + "msg_time": "消息时间", + "user_url": "用户主页URL", + "send_user_id": "发送者ID", + "send_user_name": "发送者昵称", + "item_id": "商品ID", + "send_message": "发送的消息内容", + "chat_id": "会话ID" +} ``` -## 🤝 贡献指南 - -我们欢迎任何形式的贡献!请查看 [CONTRIBUTING.md](CONTRIBUTING.md) 了解详细的贡献指南。 - -### 快速开始贡献 -1. **Fork** 项目到你的GitHub账号 -2. **克隆**项目到本地开发环境 -3. **创建分支**进行功能开发或问题修复 -4. **提交代码**并创建Pull Request - -### 贡献类型 -- 🐛 **问题报告**:发现bug或提出改进建议 -- 💡 **功能建议**:提出新功能想法 -- 🔧 **代码贡献**:修复问题或开发新功能 -- 📚 **文档改进**:完善文档和说明 -- 🧪 **测试用例**:添加或改进测试 - -详细信息请参考:[贡献指南](CONTRIBUTING.md) - -## 💬 社区交流 - -### 加入我们的交流群 - -
- -| 微信交流群 | QQ交流群 | -|:---:|:---:| -| 微信群二维码 | QQ群二维码 | -| 扫码加入微信群 | 扫码加入QQ群 | - -
- -### 交流内容 -- 💡 **功能讨论**:新功能建议和讨论 -- 🐛 **问题求助**:使用过程中遇到的问题 -- 📚 **经验分享**:使用技巧和最佳实践 -- 🔄 **版本更新**:最新版本发布通知 -- 🤝 **合作交流**:开发合作和技术交流 - -### 群规说明 -- 请保持友善和尊重的交流氛围 -- 优先使用搜索功能查找已有答案 -- 提问时请提供详细的问题描述和环境信息 -- 欢迎分享使用经验和改进建议 - -## 📄 许可证 - -本项目采用 MIT 许可证,详情请查看 [LICENSE](LICENSE) 文件。 - -## 📋 更新日志 - -查看 [CHANGELOG.md](CHANGELOG.md) 了解详细的版本更新历史。 - -## 🙏 致谢 - -感谢所有为这个项目做出贡献的开发者和用户! - -### 特别感谢 -- 所有提交代码的贡献者 -- 提供问题反馈的用户 -- 完善文档的志愿者 -- 推广项目的支持者 - -### 技术支持 -- [FastAPI](https://fastapi.tiangolo.com/) - 现代化的Web框架 -- [SQLite](https://www.sqlite.org/) - 轻量级数据库 -- [Docker](https://www.docker.com/) - 容器化技术 -- [Loguru](https://github.com/Delgan/loguru) - 优秀的日志库 - ---- - -
- -**如果这个项目对你有帮助,请给个 ⭐ Star 支持一下!** - -[📋 报告问题](https://github.com/your-repo/xianyu-auto-reply/issues) • [💡 功能建议](https://github.com/your-repo/xianyu-auto-reply/issues) • [🤝 参与贡献](https://github.com/your-repo/xianyu-auto-reply/pulls) • [📖 查看文档](https://github.com/your-repo/xianyu-auto-reply/wiki) - -**让我们一起构建更好的闲鱼自动化工具!** 🚀 - -
- -## 🔧 核心模块说明 - -### Start.py - 项目启动入口 -- 初始化文件日志收集器 -- 创建和管理 CookieManager -- 启动 FastAPI Web服务器 -- 加载配置文件和环境变量中的账号 - -### XianyuAutoAsync.py - 闲鱼WebSocket客户端 -- 维持与闲鱼服务器的WebSocket连接 -- 处理消息接收和发送 -- 自动刷新token和维持心跳 -- 商品信息获取和处理 -- 自动回复逻辑处理 - -### reply_server.py - FastAPI Web服务器 -- 提供Web管理界面 -- RESTful API接口 -- 用户认证和权限控制 -- 文件上传和下载 -- 健康检查和监控 - -### ai_reply_engine.py - AI回复引擎 -- 多AI模型支持(通义千问、GPT等) -- 意图识别和分类 -- 智能议价逻辑 -- 对话历史管理 -- 自定义提示词处理 - -### db_manager.py - 数据库管理 -- SQLite数据库操作 -- 数据表结构管理 -- 数据备份和恢复 -- 事务处理和连接池 - -## 🎮 使用场景 - -### 个人卖家 -- **自动客服**:24小时自动回复买家咨询 -- **智能议价**:自动处理价格谈判,提高成交率 -- **快速发货**:自动发送卡券和虚拟商品 - -### 商家店铺 -- **多账号管理**:统一管理多个闲鱼账号 -- **批量操作**:批量设置关键词和回复规则 -- **数据分析**:查看消息统计和销售数据 - -### 代运营服务 -- **客户隔离**:为不同客户提供独立的账号管理 -- **定制化配置**:根据客户需求定制回复策略 -- **监控报告**:提供详细的运营数据报告 - -## 🔒 安全特性 - -### 数据安全 -- **本地存储**:所有数据存储在本地,不上传到第三方 -- **加密传输**:支持HTTPS和WSS加密传输 -- **权限控制**:基于JWT的用户认证系统 - -### 隐私保护 -- **Cookie加密**:敏感信息加密存储 -- **日志脱敏**:自动过滤敏感信息 -- **访问控制**:IP白名单和访问频率限制 - -## 📈 性能优化 - -### 系统性能 -- **异步处理**:全异步架构,高并发处理能力 -- **连接池**:数据库连接池,提高数据库操作效率 -- **缓存机制**:智能缓存,减少重复请求 - -### 资源优化 -- **内存管理**:自动清理过期数据和缓存 -- **日志轮转**:自动清理过期日志文件 -- **资源限制**:Docker资源限制,防止资源滥用 - -## 🚨 故障排除 - -### 常见问题 - -**Q: 系统启动失败?** -A: 检查以下项目: -- Python版本是否为3.11+ -- 依赖包是否正确安装 -- 端口8080是否被占用 -- 配置文件是否存在 - -**Q: WebSocket连接失败?** -A: 检查以下方面: -- 网络连接是否正常 -- Cookie是否有效 -- 防火墙设置 -- 代理配置 - -**Q: AI回复不工作?** -A: 检查以下配置: -- AI API密钥是否正确 -- API地址是否可访问 -- 账户余额是否充足 -- 网络连接是否稳定 - -### 日志查看 -```bash -# 查看实时日志 -docker-compose logs -f - -# 查看特定服务日志 -docker-compose logs xianyu-app - -# 查看系统日志文件 -tail -f logs/xianyu_$(date +%Y-%m-%d).log +#### 响应格式 +```json +{ + "code": 200, + "data": { + "send_msg": "回复的消息内容" + } +} ``` -## 🤝 贡献指南 +#### 配置示例 +```yaml +AUTO_REPLY: + api: + enabled: true # 是否启用API回复 + timeout: 10 # 超时时间(秒) + url: http://localhost:8080/xianyu/reply +``` -我们欢迎任何形式的贡献!请查看 [CONTRIBUTING.md](CONTRIBUTING.md) 了解详细的贡献指南。 +#### 使用场景 +- 当收到买家消息时,系统会自动调用此接口 +- 支持接入 ChatGPT、文心一言等大语言模型 +- 支持自定义回复规则和模板 +- 支持消息变量替换(如 `{send_user_name}`) -### 快速开始贡献 -1. **Fork** 项目到你的GitHub账号 -2. **克隆**项目到本地开发环境 -3. **创建分支**进行功能开发或问题修复 -4. **提交代码**并创建Pull Request +#### 注意事项 +- 接口需要返回正确的状态码(200)和消息内容 +- 建议实现错误重试机制 +- 注意处理超时情况(默认10秒) +- 可以根据需要扩展更多的参数和功能 -### 贡献类型 -- 🐛 **问题报告**:发现bug或提出改进建议 -- 💡 **功能建议**:提出新功能想法 -- 🔧 **代码贡献**:修复问题或开发新功能 -- 📚 **文档改进**:完善文档和说明 -- 🧪 **测试用例**:添加或改进测试 +## 🗝️ 注意事项 +- 请确保闲鱼账号已登录并获取有效的 Cookie +- 建议在正式环境使用前先在测试环境验证 +- 定期检查日志文件,及时处理异常情况 +- 使用大模型时注意 API 调用频率和成本控制 -### 开发规范 -- 遵循 [PEP 8](https://www.python.org/dev/peps/pep-0008/) 代码风格 -- 使用 [Conventional Commits](https://www.conventionalcommits.org/) 提交规范 -- 为新功能添加相应的测试用例 -- 更新相关文档和说明 +## 📝 效果 -详细信息请参考:[贡献指南](CONTRIBUTING.md) -## 📄 许可证 +![image-20250611004531745](https://typeropic.oss-cn-beijing.aliyuncs.com/cp/image-20250611004531745.png) -本项目采用 MIT 许可证,详情请查看 [LICENSE](LICENSE) 文件。 +![image-20250611004549662](https://typeropic.oss-cn-beijing.aliyuncs.com/cp/image-20250611004549662.png) -## � 更新日志 +## 🧸特别鸣谢 -查看 [CHANGELOG.md](CHANGELOG.md) 了解详细的版本更新历史。 +本项目参考了以下开源项目: https://github.com/cv-cat/XianYuApis -## �🙏 致谢 +感谢[@CVcat](https://github.com/cv-cat)的技术支持 -感谢所有为这个项目做出贡献的开发者和用户! +## 📞 联系方式 +如有问题或建议,欢迎提交 Issue 或 Pull Request。 -### 特别感谢 -- 所有提交代码的贡献者 -- 提供问题反馈的用户 -- 完善文档的志愿者 -- 推广项目的支持者 +## 技术交流 -### 技术支持 -- [FastAPI](https://fastapi.tiangolo.com/) - 现代化的Web框架 -- [SQLite](https://www.sqlite.org/) - 轻量级数据库 -- [Docker](https://www.docker.com/) - 容器化技术 -- [Loguru](https://github.com/Delgan/loguru) - 优秀的日志库 - ---- - -
- -**如果这个项目对你有帮助,请给个 ⭐ Star 支持一下!** - -[📋 报告问题](https://github.com/your-repo/xianyu-auto-reply/issues) • [💡 功能建议](https://github.com/your-repo/xianyu-auto-reply/issues) • [🤝 参与贡献](https://github.com/your-repo/xianyu-auto-reply/pulls) • [📖 查看文档](https://github.com/your-repo/xianyu-auto-reply/wiki) - -**让我们一起构建更好的闲鱼自动化工具!** 🚀 - -
+![image-20250611004141387](https://typeropic.oss-cn-beijing.aliyuncs.com/cp/image-20250611004141387.png) diff --git a/Start.py b/Start.py index aa8652d..228cd42 100644 --- a/Start.py +++ b/Start.py @@ -9,7 +9,6 @@ import os import asyncio import threading import uvicorn -import time from urllib.parse import urlparse from pathlib import Path from loguru import logger @@ -19,36 +18,6 @@ import cookie_manager as cm from db_manager import db_manager from file_log_collector import setup_file_logging -# 配置统一的日志系统 -log_dir = 'logs' -os.makedirs(log_dir, exist_ok=True) -log_path = os.path.join(log_dir, f"xianyu_{time.strftime('%Y-%m-%d')}.log") - -# 移除默认的日志处理器 -logger.remove() - -# 导入日志过滤器 -try: - from log_filter import filter_log_record -except ImportError: - # 如果过滤器不可用,使用默认过滤器 - def filter_log_record(record): - return True - -# 添加文件日志处理器,使用统一格式,并应用过滤器 -logger.add( - log_path, - rotation="1 day", - retention="7 days", - compression="zip", - level="INFO", - format='{time:YYYY-MM-DD HH:mm:ss.SSS} | {level} | {name}:{function}:{line} - {message}', - encoding='utf-8', - enqueue=False, # 立即写入 - buffering=1, # 行缓冲 - filter=filter_log_record # 应用日志过滤器 -) - def _start_api_server(): """后台线程启动 FastAPI 服务""" diff --git a/UI_IMPROVEMENTS.md b/UI_IMPROVEMENTS.md new file mode 100644 index 0000000..1ac59fc --- /dev/null +++ b/UI_IMPROVEMENTS.md @@ -0,0 +1,92 @@ +# 🎨 界面优化总结 + +## ✨ 主要改进 + +### 1. 🎯 Cookie显示优化 +- **❌ 修改前**: Cookie值被隐藏为星号 (`****`) +- **✅ 修改后**: 显示完整的Cookie内容,便于查看和调试 + +### 2. 🎨 视觉设计升级 +- **现代化配色方案**: 使用更现代的紫色主题 (`#4f46e5`) +- **渐变背景**: 美丽的渐变背景和卡片效果 +- **毛玻璃效果**: 卡片使用 `backdrop-filter: blur()` 实现毛玻璃效果 +- **阴影和动画**: 悬停时的阴影和位移动画效果 + +### 3. 🔧 功能增强 +- **一键复制Cookie**: 点击Cookie值或复制按钮即可复制到剪贴板 +- **改进的按钮组**: 更紧凑的按钮布局,包含复制功能 +- **更好的空状态**: 当没有账号时显示更友好的提示 + +### 4. 📱 响应式设计 +- **移动端优化**: 在小屏幕上按钮垂直排列 +- **自适应布局**: 表格和卡片在不同屏幕尺寸下的自适应 + +## 🛠️ 技术改进 + +### 新增API接口 +```javascript +GET /cookies/details +``` +返回包含Cookie ID和完整值的详细信息,而不仅仅是ID列表。 + +### CSS样式优化 +- **CSS变量**: 统一的颜色管理 +- **现代字体**: 使用 Inter 字体提升可读性 +- **代码字体**: Cookie值使用等宽字体 (JetBrains Mono) +- **流畅动画**: 所有交互都有平滑的过渡效果 + +### JavaScript功能增强 +- **复制功能**: 支持现代浏览器的 Clipboard API +- **降级方案**: 对于不支持的浏览器提供传统复制方法 +- **用户反馈**: 复制成功/失败的Toast提示 + +## 🎯 用户体验提升 + +### 1. Cookie管理 +- **完整显示**: 不再隐藏Cookie内容,便于调试 +- **一键复制**: 快速复制Cookie值到剪贴板 +- **格式化显示**: 使用等宽字体和适当的行高 + +### 2. 视觉反馈 +- **悬停效果**: 所有可交互元素都有悬停反馈 +- **状态指示**: 清晰的按钮状态和颜色区分 +- **加载动画**: 优雅的加载状态显示 + +### 3. 操作便利性 +- **按钮分组**: 相关操作按钮紧凑排列 +- **图标提示**: 每个按钮都有清晰的图标和提示 +- **确认对话框**: 危险操作有确认提示 + +## 📊 界面对比 + +| 功能 | 修改前 | 修改后 | +|------|--------|--------| +| Cookie显示 | 隐藏为星号 | 完整显示 | +| 复制功能 | 无 | 一键复制 | +| 视觉效果 | 基础Bootstrap | 现代化渐变设计 | +| 响应式 | 基本支持 | 完全优化 | +| 用户反馈 | 基础提示 | 丰富的Toast反馈 | + +## 🚀 使用说明 + +### 访问界面 +1. 启动系统: `python Start.py` +2. 打开浏览器: `http://localhost:8080` +3. 登录: `admin` / `admin123` + +### 主要功能 +- **添加账号**: 在顶部表单中输入账号ID和Cookie值 +- **查看Cookie**: 完整的Cookie值显示在表格中 +- **复制Cookie**: 点击Cookie值或复制按钮 +- **管理关键词**: 点击关键词按钮设置自动回复 +- **删除账号**: 点击删除按钮(有确认提示) + +## 🎉 总结 + +这次界面优化大幅提升了用户体验: +- ✅ **Cookie不再隐藏**,便于查看和调试 +- ✅ **现代化设计**,视觉效果更佳 +- ✅ **功能增强**,操作更便利 +- ✅ **响应式优化**,支持各种设备 + +界面现在更加美观、实用和用户友好!🎨✨ diff --git a/XianyuAutoAsync.py b/XianyuAutoAsync.py index ede8e00..ede6a00 100644 --- a/XianyuAutoAsync.py +++ b/XianyuAutoAsync.py @@ -20,34 +20,26 @@ from utils.ws_utils import WebSocketClient import sys import aiohttp -# 日志配置 - 统一日志文件 +# 日志配置 log_dir = 'logs' os.makedirs(log_dir, exist_ok=True) log_path = os.path.join(log_dir, f"xianyu_{time.strftime('%Y-%m-%d')}.log") - -# 移除所有现有的日志处理器 logger.remove() - -# 导入日志过滤器 -try: - from log_filter import filter_log_record -except ImportError: - # 如果过滤器不可用,使用默认过滤器 - def filter_log_record(record): - return True - -# 只添加文件日志处理器,使用统一格式便于解析,并应用过滤器 logger.add( log_path, rotation=LOG_CONFIG.get('rotation', '1 day'), retention=LOG_CONFIG.get('retention', '7 days'), compression=LOG_CONFIG.get('compression', 'zip'), level=LOG_CONFIG.get('level', 'INFO'), - format='{time:YYYY-MM-DD HH:mm:ss.SSS} | {level} | {name}:{function}:{line} - {message}', + format=LOG_CONFIG.get('format', '{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {name}:{function}:{line} - {message}'), encoding='utf-8', - enqueue=False, # 改为False,确保立即写入 - buffering=1, # 行缓冲,立即刷新到文件 - filter=filter_log_record # 应用日志过滤器 + enqueue=True +) +logger.add( + sys.stdout, + level=LOG_CONFIG.get('level', 'INFO'), + format=LOG_CONFIG.get('format', '{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {name}:{function}:{line} - {message}'), + enqueue=True ) class XianyuLive: @@ -205,10 +197,14 @@ class XianyuLive: return new_token logger.error(f"Token刷新失败: {res_json}") + # 发送Token刷新失败通知 + await self.send_token_refresh_notification(f"Token刷新失败: {res_json}") return None - + except Exception as e: logger.error(f"Token刷新异常: {self._safe_str(e)}") + # 发送Token刷新异常通知 + await self.send_token_refresh_notification(f"Token刷新异常: {str(e)}") return None async def update_config_cookies(self): @@ -223,11 +219,17 @@ class XianyuLive: logger.debug(f"已更新Cookie到数据库: {self.cookie_id}") except Exception as e: logger.error(f"更新数据库Cookie失败: {self._safe_str(e)}") + # 发送数据库更新失败通知 + await self.send_token_refresh_notification(f"数据库Cookie更新失败: {str(e)}") else: logger.warning("Cookie ID不存在,无法更新数据库") + # 发送Cookie ID缺失通知 + await self.send_token_refresh_notification("Cookie ID不存在,无法更新数据库") except Exception as e: logger.error(f"更新Cookie失败: {self._safe_str(e)}") + # 发送Cookie更新失败通知 + await self.send_token_refresh_notification(f"Cookie更新失败: {str(e)}") async def save_item_info_to_db(self, item_id: str, item_detail: str = None): """保存商品信息到数据库 @@ -711,11 +713,11 @@ class XianyuLive: send_message=send_message ) logger.info(f"使用默认回复: {formatted_reply}") - return f"[默认回复] {formatted_reply}" + return formatted_reply except Exception as format_error: logger.error(f"默认回复变量替换失败: {self._safe_str(format_error)}") # 如果变量替换失败,返回原始内容 - return f"[默认回复] {reply_content}" + return reply_content except Exception as e: logger.error(f"获取默认回复失败: {self._safe_str(e)}") @@ -744,11 +746,11 @@ class XianyuLive: send_message=send_message ) logger.info(f"关键词匹配成功: '{keyword}' -> {formatted_reply}") - return f"[关键词回复] {formatted_reply}" + return formatted_reply except Exception as format_error: logger.error(f"关键词回复变量替换失败: {self._safe_str(format_error)}") # 如果变量替换失败,返回原始内容 - return f"[关键词回复] {reply}" + return reply logger.debug(f"未找到匹配的关键词: {send_message}") return None @@ -799,7 +801,7 @@ class XianyuLive: if reply: logger.info(f"AI回复生成成功: {reply}") - return f"[AI回复] {reply}" + return reply else: logger.debug(f"AI回复生成失败") return None @@ -893,6 +895,49 @@ class XianyuLive: except Exception as e: logger.error(f"发送QQ通知异常: {self._safe_str(e)}") + async def send_token_refresh_notification(self, error_message: str): + """发送Token刷新异常通知""" + try: + from db_manager import db_manager + + # 获取当前账号的通知配置 + notifications = db_manager.get_account_notifications(self.cookie_id) + + if not notifications: + logger.debug("未配置消息通知,跳过Token刷新通知") + return + + # 构造通知消息 + notification_msg = f"""🔴 闲鱼账号Token刷新异常 + +账号ID: {self.cookie_id} +异常时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} +异常信息: {error_message} + +请检查账号Cookie是否过期,如有需要请及时更新Cookie配置。""" + + logger.info(f"准备发送Token刷新异常通知: {self.cookie_id}") + + # 发送通知到各个渠道 + for notification in notifications: + if not notification.get('enabled', True): + continue + + channel_type = notification.get('channel_type') + channel_config = notification.get('channel_config') + + try: + if channel_type == 'qq': + await self._send_qq_notification(channel_config, notification_msg) + else: + logger.warning(f"不支持的通知渠道类型: {channel_type}") + + except Exception as notify_error: + logger.error(f"发送Token刷新通知失败 ({notification.get('channel_name', 'Unknown')}): {self._safe_str(notify_error)}") + + except Exception as e: + logger.error(f"处理Token刷新通知失败: {self._safe_str(e)}") + async def send_delivery_failure_notification(self, send_user_name: str, send_user_id: str, item_id: str, error_message: str): """发送自动发货失败通知""" try: @@ -1188,6 +1233,8 @@ class XianyuLive: break else: logger.error("Token刷新失败,将在{}分钟后重试".format(self.token_retry_interval // 60)) + # 发送Token刷新失败通知 + await self.send_token_refresh_notification("Token定时刷新失败,将自动重试") await asyncio.sleep(self.token_retry_interval) continue await asyncio.sleep(60) @@ -1272,6 +1319,8 @@ class XianyuLive: if not self.current_token: logger.error("无法获取有效token,初始化失败") + # 发送Token获取失败通知 + await self.send_token_refresh_notification("初始化时无法获取有效Token") raise Exception("Token获取失败") msg = { @@ -1826,19 +1875,19 @@ class XianyuLive: # 记录回复来源 reply_source = 'API' # 默认假设是API回复 - # 如果API回复失败或未启用API,按优先级尝试其他回复方式 + # 如果API回复失败或未启用API,按新的优先级顺序处理 if not reply: - # 优先尝试关键词匹配回复 + # 1. 首先尝试关键词匹配 reply = await self.get_keyword_reply(send_user_name, send_user_id, send_message) if reply: reply_source = '关键词' # 标记为关键词回复 else: - # 如果关键词匹配失败,尝试AI回复 + # 2. 关键词匹配失败,如果AI开关打开,尝试AI回复 reply = await self.get_ai_reply(send_user_name, send_user_id, send_message, item_id, chat_id) if reply: reply_source = 'AI' # 标记为AI回复 else: - # 最后尝试使用默认回复 + # 3. 最后使用默认回复 reply = await self.get_default_reply(send_user_name, send_user_id, send_message) reply_source = '默认' # 标记为默认回复 @@ -1908,8 +1957,14 @@ class XianyuLive: finally: await self.close_session() # 确保关闭session - async def get_item_list_info(self, retry_count=0): - """获取商品信息,自动处理token失效的情况""" + async def get_item_list_info(self, page_number=1, page_size=20, retry_count=0): + """获取商品信息,自动处理token失效的情况 + + Args: + page_number (int): 页码,从1开始 + page_size (int): 每页数量,默认20 + retry_count (int): 重试次数,内部使用 + """ if retry_count >= 3: # 最多重试3次 logger.error("获取商品信息失败,重试次数过多") return {"error": "获取商品信息失败,重试次数过多"} @@ -1952,8 +2007,8 @@ class XianyuLive: data = { 'needGroupInfo': False, - 'pageNumber': 1, - 'pageSize': 20, + 'pageNumber': page_number, + 'pageSize': page_size, 'groupName': '在售', 'groupId': '58877261', 'defaultGroup': True, @@ -2017,7 +2072,7 @@ class XianyuLive: # 打印商品详细信息到控制台 print("\n" + "="*80) - print(f"📦 账号 {self.myid} 的商品列表 ({len(items_list)} 个商品)") + print(f"📦 账号 {self.myid} 的商品列表 (第{page_number}页,{len(items_list)} 个商品)") print("="*80) for i, item in enumerate(items_list, 1): @@ -2046,7 +2101,9 @@ class XianyuLive: return { "success": True, - "total_count": len(items_list), + "page_number": page_number, + "page_size": page_size, + "current_count": len(items_list), "items": items_list, "saved_count": saved_count if items_list else 0, "raw_data": items_data # 保留原始数据以备调试 @@ -2057,7 +2114,7 @@ class XianyuLive: if 'FAIL_SYS_TOKEN_EXOIRED' in error_msg or 'token' in error_msg.lower(): logger.warning(f"Token失效,准备重试: {error_msg}") await asyncio.sleep(0.5) - return await self.get_item_list_info(retry_count + 1) + return await self.get_item_list_info(page_number, page_size, retry_count + 1) else: logger.error(f"获取商品信息失败: {res_json}") return {"error": f"获取商品信息失败: {error_msg}"} @@ -2065,7 +2122,65 @@ class XianyuLive: except Exception as e: logger.error(f"商品信息API请求异常: {self._safe_str(e)}") await asyncio.sleep(0.5) - return await self.get_item_list_info(retry_count + 1) + return await self.get_item_list_info(page_number, page_size, retry_count + 1) + + async def get_all_items(self, page_size=20, max_pages=None): + """获取所有商品信息(自动分页) + + Args: + page_size (int): 每页数量,默认20 + max_pages (int): 最大页数限制,None表示无限制 + + Returns: + dict: 包含所有商品信息的字典 + """ + all_items = [] + page_number = 1 + total_saved = 0 + + logger.info(f"开始获取所有商品信息,每页{page_size}条") + + while True: + if max_pages and page_number > max_pages: + logger.info(f"达到最大页数限制 {max_pages},停止获取") + break + + logger.info(f"正在获取第 {page_number} 页...") + result = await self.get_item_list_info(page_number, page_size) + + if not result.get("success"): + logger.error(f"获取第 {page_number} 页失败: {result}") + break + + current_items = result.get("items", []) + if not current_items: + logger.info(f"第 {page_number} 页没有数据,获取完成") + break + + all_items.extend(current_items) + total_saved += result.get("saved_count", 0) + + logger.info(f"第 {page_number} 页获取到 {len(current_items)} 个商品") + + # 如果当前页商品数量少于页面大小,说明已经是最后一页 + if len(current_items) < page_size: + logger.info(f"第 {page_number} 页商品数量({len(current_items)})少于页面大小({page_size}),获取完成") + break + + page_number += 1 + + # 添加延迟避免请求过快 + await asyncio.sleep(1) + + logger.info(f"所有商品获取完成,共 {len(all_items)} 个商品,保存了 {total_saved} 个") + + return { + "success": True, + "total_pages": page_number, + "total_count": len(all_items), + "total_saved": total_saved, + "items": all_items + } if __name__ == '__main__': cookies_str = os.getenv('COOKIES_STR') diff --git a/backup_import_update_summary.md b/backup_import_update_summary.md new file mode 100644 index 0000000..710ae24 --- /dev/null +++ b/backup_import_update_summary.md @@ -0,0 +1,193 @@ +# 备份和导入功能更新总结 + +## 📋 更新概述 + +由于系统新增了多个AI相关的数据表,备份和导入功能需要更新以确保所有数据都能正确备份和恢复。 + +## 🔧 更新内容 + +### 1. **新增的表** + +在原有的10个表基础上,新增了3个AI相关表: + +#### 新增表列表: +- `ai_reply_settings` - AI回复配置表 +- `ai_conversations` - AI对话历史表 +- `ai_item_cache` - AI商品信息缓存表 + +### 2. **更新的备份表列表** + +#### 更新前(10个表): +```python +tables = [ + 'cookies', 'keywords', 'cookie_status', 'cards', + 'delivery_rules', 'default_replies', 'notification_channels', + 'message_notifications', 'system_settings', 'item_info' +] +``` + +#### 更新后(13个表): +```python +tables = [ + 'cookies', 'keywords', 'cookie_status', 'cards', + 'delivery_rules', 'default_replies', 'notification_channels', + 'message_notifications', 'system_settings', 'item_info', + 'ai_reply_settings', 'ai_conversations', 'ai_item_cache' +] +``` + +### 3. **更新的删除顺序** + +考虑到外键依赖关系,更新了导入时的表删除顺序: + +#### 更新前: +```python +tables = [ + 'message_notifications', 'notification_channels', 'default_replies', + 'delivery_rules', 'cards', 'item_info', 'cookie_status', 'keywords', 'cookies' +] +``` + +#### 更新后: +```python +tables = [ + 'message_notifications', 'notification_channels', 'default_replies', + 'delivery_rules', 'cards', 'item_info', 'cookie_status', 'keywords', + 'ai_conversations', 'ai_reply_settings', 'ai_item_cache', 'cookies' +] +``` + +### 4. **更新的验证列表** + +导入功能中的表验证列表也相应更新,确保新增的AI表能够正确导入。 + +## ✅ 测试验证结果 + +### 测试环境 +- 数据库表总数:13个 +- 测试数据:包含所有表类型的数据 +- 测试场景:导出、导入、文件操作 + +### 测试结果 +``` +🎉 所有测试通过!备份和导入功能正常! + +✅ 功能验证: + • 所有13个表都包含在备份中 + • 备份导出功能正常 + • 备份导入功能正常 + • 数据完整性保持 + • 文件操作正常 +``` + +### 数据完整性验证 +所有13个表的数据在备份和导入过程中保持完整: + +| 表名 | 数据一致性 | 说明 | +|------|------------|------| +| ai_conversations | ✅ 一致 | AI对话历史 | +| ai_item_cache | ✅ 一致 | AI商品缓存 | +| ai_reply_settings | ✅ 一致 | AI回复配置 | +| cards | ✅ 一致 | 卡券信息 | +| cookie_status | ✅ 一致 | 账号状态 | +| cookies | ✅ 一致 | 账号信息 | +| default_replies | ✅ 一致 | 默认回复 | +| delivery_rules | ✅ 一致 | 发货规则 | +| item_info | ✅ 一致 | 商品信息 | +| keywords | ✅ 一致 | 关键词 | +| message_notifications | ✅ 一致 | 消息通知 | +| notification_channels | ✅ 一致 | 通知渠道 | +| system_settings | ✅ 一致 | 系统设置 | + +## 🎯 功能特性 + +### 1. **完整性保证** +- 包含所有13个数据表 +- 保持外键依赖关系 +- 数据完整性验证 + +### 2. **安全性** +- 事务性操作,确保数据一致性 +- 管理员密码保护(不会被覆盖) +- 错误回滚机制 + +### 3. **兼容性** +- 向后兼容旧版本备份文件 +- 自动跳过不存在的表 +- 版本标识和时间戳 + +### 4. **易用性** +- 一键导出所有数据 +- 一键导入恢复数据 +- 详细的操作日志 + +## 📊 使用方法 + +### 导出备份 +```python +from db_manager import db_manager + +# 导出备份数据 +backup_data = db_manager.export_backup() + +# 保存到文件 +import json +with open('backup.json', 'w', encoding='utf-8') as f: + json.dump(backup_data, f, indent=2, ensure_ascii=False) +``` + +### 导入备份 +```python +from db_manager import db_manager +import json + +# 从文件读取备份 +with open('backup.json', 'r', encoding='utf-8') as f: + backup_data = json.load(f) + +# 导入备份数据 +success = db_manager.import_backup(backup_data) +``` + +## 🔄 升级说明 + +### 对现有用户的影响 +- ✅ **无影响**:现有备份文件仍然可以正常导入 +- ✅ **自动兼容**:系统会自动跳过不存在的新表 +- ✅ **数据安全**:不会丢失任何现有数据 + +### 新功能优势 +- ✅ **AI数据备份**:AI回复配置和对话历史得到保护 +- ✅ **完整备份**:所有功能数据都包含在备份中 +- ✅ **快速恢复**:可以完整恢复所有AI功能设置 + +## 💡 建议 + +### 1. **定期备份** +建议用户定期进行数据备份,特别是在: +- 重要配置更改后 +- 系统升级前 +- 大量数据操作前 + +### 2. **备份验证** +建议在重要操作前验证备份文件的完整性: +- 检查文件大小 +- 验证JSON格式 +- 确认包含所需表 + +### 3. **多重备份** +建议保留多个备份版本: +- 每日自动备份 +- 重要节点手动备份 +- 异地备份存储 + +## 🎉 总结 + +备份和导入功能已成功更新,现在能够: + +1. ✅ **完整备份**所有13个数据表 +2. ✅ **安全导入**保持数据完整性 +3. ✅ **向后兼容**旧版本备份文件 +4. ✅ **AI数据保护**包含所有AI功能数据 + +用户可以放心使用备份和导入功能,所有数据都得到了完整的保护! diff --git a/cookie_manager.py b/cookie_manager.py index f58c011..e742e6c 100644 --- a/cookie_manager.py +++ b/cookie_manager.py @@ -35,6 +35,21 @@ class CookieManager: except Exception as e: logger.error(f"从数据库加载数据失败: {e}") + def reload_from_db(self): + """重新从数据库加载所有数据(用于备份导入后刷新)""" + logger.info("重新从数据库加载数据...") + old_cookies_count = len(self.cookies) + old_keywords_count = len(self.keywords) + + # 重新加载数据 + self._load_from_db() + + new_cookies_count = len(self.cookies) + new_keywords_count = len(self.keywords) + + logger.info(f"数据重新加载完成: Cookie {old_cookies_count} -> {new_cookies_count}, 关键字组 {old_keywords_count} -> {new_keywords_count}") + return True + # ------------------------ 内部协程 ------------------------ async def _run_xianyu(self, cookie_id: str, cookie_value: str): """在事件循环中启动 XianyuLive.main""" diff --git a/db_manager.py b/db_manager.py index 2e39fbe..ac4de85 100644 --- a/db_manager.py +++ b/db_manager.py @@ -51,12 +51,39 @@ class DBManager: self.conn = sqlite3.connect(self.db_path, check_same_thread=False) cursor = self.conn.cursor() - # 创建cookies表 + # 创建用户表 + cursor.execute(''' + CREATE TABLE IF NOT EXISTS users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + username TEXT UNIQUE NOT NULL, + email TEXT UNIQUE NOT NULL, + password_hash TEXT NOT NULL, + is_active BOOLEAN DEFAULT TRUE, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) + ''') + + # 创建邮箱验证码表 + cursor.execute(''' + CREATE TABLE IF NOT EXISTS email_verifications ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + email TEXT NOT NULL, + code TEXT NOT NULL, + expires_at TIMESTAMP NOT NULL, + used BOOLEAN DEFAULT FALSE, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) + ''') + + # 创建cookies表(添加user_id字段) cursor.execute(''' CREATE TABLE IF NOT EXISTS cookies ( id TEXT PRIMARY KEY, value TEXT NOT NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + user_id INTEGER NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ) ''') @@ -234,6 +261,29 @@ class DBManager: ('theme_color', 'blue', '主题颜色') ''', (hashlib.sha256("admin123".encode()).hexdigest(),)) + # 创建默认admin用户 + cursor.execute(''' + INSERT OR IGNORE INTO users (username, email, password_hash) VALUES + ('admin', 'admin@localhost', ?) + ''', (hashlib.sha256("admin123".encode()).hexdigest(),)) + + # 获取admin用户ID,用于历史数据绑定 + cursor.execute("SELECT id FROM users WHERE username = 'admin'") + admin_user = cursor.fetchone() + if admin_user: + admin_user_id = admin_user[0] + + # 将历史cookies数据绑定到admin用户(如果user_id列不存在) + try: + cursor.execute("SELECT user_id FROM cookies LIMIT 1") + except sqlite3.OperationalError: + # user_id列不存在,需要添加并更新历史数据 + cursor.execute("ALTER TABLE cookies ADD COLUMN user_id INTEGER") + cursor.execute("UPDATE cookies SET user_id = ? WHERE user_id IS NULL", (admin_user_id,)) + else: + # user_id列存在,更新NULL值 + cursor.execute("UPDATE cookies SET user_id = ? WHERE user_id IS NULL", (admin_user_id,)) + self.conn.commit() logger.info(f"数据库初始化成功: {self.db_path}") except Exception as e: diff --git a/deploy.bat b/deploy.bat new file mode 100644 index 0000000..c10fd9d --- /dev/null +++ b/deploy.bat @@ -0,0 +1,298 @@ +@echo off +chcp 65001 >nul +setlocal enabledelayedexpansion + +:: 闲鱼自动回复系统 Docker 部署脚本 (Windows版本) +:: 作者: Xianyu Auto Reply System +:: 版本: 1.0.0 + +title 闲鱼自动回复系统 Docker 部署 + +:: 颜色定义 +set "RED=[91m" +set "GREEN=[92m" +set "YELLOW=[93m" +set "BLUE=[94m" +set "NC=[0m" + +:: 打印带颜色的消息 +:print_info +echo %BLUE%[INFO]%NC% %~1 +goto :eof + +:print_success +echo %GREEN%[SUCCESS]%NC% %~1 +goto :eof + +:print_warning +echo %YELLOW%[WARNING]%NC% %~1 +goto :eof + +:print_error +echo %RED%[ERROR]%NC% %~1 +goto :eof + +:: 检查Docker是否安装 +:check_docker +call :print_info "检查 Docker 环境..." + +docker --version >nul 2>&1 +if errorlevel 1 ( + call :print_error "Docker 未安装,请先安装 Docker Desktop" + echo. + echo 下载地址: https://www.docker.com/products/docker-desktop + pause + exit /b 1 +) + +docker-compose --version >nul 2>&1 +if errorlevel 1 ( + call :print_error "Docker Compose 未安装,请先安装 Docker Compose" + pause + exit /b 1 +) + +call :print_success "Docker 环境检查通过" +goto :eof + +:: 创建必要的目录 +:create_directories +call :print_info "创建必要的目录..." + +if not exist "data" mkdir data +if not exist "logs" mkdir logs +if not exist "backups" mkdir backups +if not exist "nginx" mkdir nginx +if not exist "nginx\ssl" mkdir nginx\ssl + +REM 检查目录是否创建成功 +if not exist "data" ( + call :print_error "data目录创建失败" + pause + exit /b 1 +) + +if not exist "logs" ( + call :print_error "logs目录创建失败" + pause + exit /b 1 +) + +call :print_success "目录创建完成" +goto :eof + +:: 生成默认配置文件 +:generate_config +REM 生成.env文件 +if not exist ".env" ( + if exist ".env.example" ( + call :print_info "从模板生成 .env 文件..." + copy ".env.example" ".env" >nul + call :print_success ".env 文件已生成" + ) else ( + call :print_warning ".env.example 文件不存在,跳过 .env 文件生成" + ) +) else ( + call :print_info ".env 文件已存在,跳过生成" +) + +REM 生成global_config.yml文件 +if exist "global_config.yml" ( + call :print_info "配置文件已存在,跳过生成" + goto :eof +) + +call :print_info "生成默认配置文件..." + +( +echo # 闲鱼自动回复系统配置文件 +echo API_ENDPOINTS: +echo login_check: https://passport.goofish.com/newlogin/hasLogin.do +echo message_headinfo: https://h5api.m.goofish.com/h5/mtop.idle.trade.pc.message.headinfo/1.0/ +echo token: https://h5api.m.goofish.com/h5/mtop.taobao.idlemessage.pc.login.token/1.0/ +echo. +echo APP_CONFIG: +echo api_version: '1.0' +echo app_key: 444e9908a51d1cb236a27862abc769c9 +echo app_version: '1.0' +echo platform: web +echo. +echo AUTO_REPLY: +echo enabled: true +echo default_message: '亲爱的"{send_user_name}" 老板你好!所有宝贝都可以拍,秒发货的哈~不满意的话可以直接申请退款哈~' +echo max_retry: 3 +echo retry_interval: 5 +echo api: +echo enabled: false +echo host: 0.0.0.0 # 绑定所有网络接口,支持IP访问 +echo port: 8080 # Web服务端口 +echo url: http://0.0.0.0:8080/xianyu/reply +echo timeout: 10 +echo. +echo COOKIES: +echo last_update_time: '' +echo value: '' +echo. +echo DEFAULT_HEADERS: +echo accept: application/json +echo accept-language: zh-CN,zh;q=0.9 +echo cache-control: no-cache +echo origin: https://www.goofish.com +echo pragma: no-cache +echo referer: https://www.goofish.com/ +echo user-agent: Mozilla/5.0 ^(Windows NT 10.0; Win64; x64^) AppleWebKit/537.36 ^(KHTML, like Gecko^) Chrome/119.0.0.0 Safari/537.36 +echo. +echo WEBSOCKET_URL: wss://wss-goofish.dingtalk.com/ +echo HEARTBEAT_INTERVAL: 15 +echo HEARTBEAT_TIMEOUT: 5 +echo TOKEN_REFRESH_INTERVAL: 3600 +echo TOKEN_RETRY_INTERVAL: 300 +echo MESSAGE_EXPIRE_TIME: 300000 +echo. +echo LOG_CONFIG: +echo level: INFO +echo format: '{time:YYYY-MM-DD HH:mm:ss.SSS} | {level} | {name}:{function}:{line} - {message}' +echo rotation: '1 day' +echo retention: '7 days' +) > global_config.yml + +call :print_success "默认配置文件已生成" +goto :eof + +:: 构建Docker镜像 +:build_image +call :print_info "构建 Docker 镜像..." + +docker build -t xianyu-auto-reply:latest . +if errorlevel 1 ( + call :print_error "Docker 镜像构建失败" + pause + exit /b 1 +) + +call :print_success "Docker 镜像构建完成" +goto :eof + +:: 启动服务 +:start_services +call :print_info "启动服务..." + +if "%~1"=="--with-nginx" ( + call :print_info "启动服务(包含 Nginx)..." + docker-compose --profile with-nginx up -d +) else ( + call :print_info "启动服务(不包含 Nginx)..." + docker-compose up -d +) + +if errorlevel 1 ( + call :print_error "服务启动失败" + pause + exit /b 1 +) + +call :print_success "服务启动完成" +goto :eof + +:: 显示服务状态 +:show_status +call :print_info "服务状态:" +docker-compose ps + +echo. +call :print_info "服务日志(最近10行):" +docker-compose logs --tail=10 +goto :eof + +:: 显示访问信息 +:show_access_info +call :print_success "部署完成!" +echo. +call :print_info "访问信息:" +echo Web界面: http://localhost:8080 +echo 默认账号: admin +echo 默认密码: admin123 +echo. +call :print_info "常用命令:" +echo 查看日志: docker-compose logs -f +echo 重启服务: docker-compose restart +echo 停止服务: docker-compose down +echo 更新服务: deploy.bat update +echo. +call :print_info "数据目录:" +echo 数据库: .\data\xianyu_data.db +echo 日志: .\logs\ +echo 配置: .\global_config.yml +echo. +goto :eof + +:: 更新服务 +:update_services +call :print_info "更新服务..." + +docker-compose down +call :build_image +call :start_services %~1 + +call :print_success "服务更新完成" +goto :eof + +:: 清理资源 +:cleanup +call :print_warning "清理 Docker 资源..." + +docker-compose down --volumes --remove-orphans +docker rmi xianyu-auto-reply:latest 2>nul + +call :print_success "清理完成" +goto :eof + +:: 显示帮助 +:show_help +echo 使用方法: +echo %~nx0 # 首次部署 +echo %~nx0 with-nginx # 部署并启动 Nginx +echo %~nx0 update # 更新服务 +echo %~nx0 update with-nginx # 更新服务并启动 Nginx +echo %~nx0 status # 查看服务状态 +echo %~nx0 cleanup # 清理所有资源 +echo %~nx0 help # 显示帮助 +goto :eof + +:: 主函数 +:main +echo ======================================== +echo 闲鱼自动回复系统 Docker 部署脚本 +echo ======================================== +echo. + +if "%~1"=="update" ( + call :print_info "更新模式" + call :check_docker + call :update_services %~2 + call :show_status + call :show_access_info +) else if "%~1"=="cleanup" ( + call :print_warning "清理模式" + call :cleanup +) else if "%~1"=="status" ( + call :show_status +) else if "%~1"=="help" ( + call :show_help +) else ( + call :print_info "首次部署模式" + call :check_docker + call :create_directories + call :generate_config + call :build_image + call :start_services %~1 + call :show_status + call :show_access_info +) + +echo. +pause +goto :eof + +:: 执行主函数 +call :main %* diff --git a/docker-deploy.bat b/docker-deploy.bat new file mode 100644 index 0000000..671acb9 --- /dev/null +++ b/docker-deploy.bat @@ -0,0 +1,301 @@ +@echo off +chcp 65001 >nul +setlocal enabledelayedexpansion + +:: 闲鱼自动回复系统 Docker 部署脚本 (Windows版本) +:: 支持快速部署和管理 + +set PROJECT_NAME=xianyu-auto-reply +set COMPOSE_FILE=docker-compose.yml +set ENV_FILE=.env + +:: 颜色定义 (Windows 10+ 支持ANSI颜色) +set "RED=[31m" +set "GREEN=[32m" +set "YELLOW=[33m" +set "BLUE=[34m" +set "NC=[0m" + +:: 打印带颜色的消息 +:print_info +echo %BLUE%ℹ️ %~1%NC% +goto :eof + +:print_success +echo %GREEN%✅ %~1%NC% +goto :eof + +:print_warning +echo %YELLOW%⚠️ %~1%NC% +goto :eof + +:print_error +echo %RED%❌ %~1%NC% +goto :eof + +:: 检查依赖 +:check_dependencies +call :print_info "检查系统依赖..." + +docker --version >nul 2>&1 +if errorlevel 1 ( + call :print_error "Docker 未安装,请先安装 Docker Desktop" + exit /b 1 +) + +docker-compose --version >nul 2>&1 +if errorlevel 1 ( + call :print_error "Docker Compose 未安装,请先安装 Docker Compose" + exit /b 1 +) + +call :print_success "系统依赖检查通过" +goto :eof + +:: 初始化配置 +:init_config +call :print_info "初始化配置文件..." + +if not exist "%ENV_FILE%" ( + if exist ".env.example" ( + copy ".env.example" "%ENV_FILE%" >nul + call :print_success "已创建 %ENV_FILE% 配置文件" + ) else ( + call :print_error ".env.example 文件不存在" + exit /b 1 + ) +) else ( + call :print_warning "%ENV_FILE% 已存在,跳过创建" +) + +:: 创建必要的目录 +if not exist "data" mkdir data +if not exist "logs" mkdir logs +if not exist "backups" mkdir backups +call :print_success "已创建必要的目录" +goto :eof + +:: 构建镜像 +:build_image +call :print_info "构建 Docker 镜像..." +docker-compose build --no-cache +if errorlevel 1 ( + call :print_error "镜像构建失败" + exit /b 1 +) +call :print_success "镜像构建完成" +goto :eof + +:: 启动服务 +:start_services +set "profile=" +if "%~1"=="with-nginx" ( + set "profile=--profile with-nginx" + call :print_info "启动服务(包含 Nginx)..." +) else ( + call :print_info "启动基础服务..." +) + +docker-compose %profile% up -d +if errorlevel 1 ( + call :print_error "服务启动失败" + exit /b 1 +) +call :print_success "服务启动完成" + +:: 等待服务就绪 +call :print_info "等待服务就绪..." +timeout /t 10 /nobreak >nul + +:: 检查服务状态 +docker-compose ps | findstr "Up" >nul +if errorlevel 1 ( + call :print_error "服务启动失败" + docker-compose logs + exit /b 1 +) else ( + call :print_success "服务运行正常" + call :show_access_info "%~1" +) +goto :eof + +:: 停止服务 +:stop_services +call :print_info "停止服务..." +docker-compose down +call :print_success "服务已停止" +goto :eof + +:: 重启服务 +:restart_services +call :print_info "重启服务..." +docker-compose restart +call :print_success "服务已重启" +goto :eof + +:: 查看日志 +:show_logs +if "%~1"=="" ( + docker-compose logs -f +) else ( + docker-compose logs -f "%~1" +) +goto :eof + +:: 查看状态 +:show_status +call :print_info "服务状态:" +docker-compose ps + +call :print_info "资源使用:" +for /f "tokens=*" %%i in ('docker-compose ps -q') do ( + docker stats --no-stream %%i +) +goto :eof + +:: 显示访问信息 +:show_access_info +echo. +call :print_success "🎉 部署完成!" +echo. + +if "%~1"=="with-nginx" ( + echo 📱 访问地址: + echo HTTP: http://localhost + echo HTTPS: https://localhost ^(如果配置了SSL^) +) else ( + echo 📱 访问地址: + echo HTTP: http://localhost:8080 +) + +echo. +echo 🔐 默认登录信息: +echo 用户名: admin +echo 密码: admin123 +echo. +echo 📊 管理命令: +echo 查看状态: %~nx0 status +echo 查看日志: %~nx0 logs +echo 重启服务: %~nx0 restart +echo 停止服务: %~nx0 stop +echo. +goto :eof + +:: 健康检查 +:health_check +call :print_info "执行健康检查..." + +set "url=http://localhost:8080/health" +set "max_attempts=30" +set "attempt=1" + +:health_loop +curl -f -s "%url%" >nul 2>&1 +if not errorlevel 1 ( + call :print_success "健康检查通过" + goto :eof +) + +call :print_info "等待服务就绪... (!attempt!/%max_attempts%)" +timeout /t 2 /nobreak >nul +set /a attempt+=1 + +if !attempt! leq %max_attempts% goto health_loop + +call :print_error "健康检查失败" +exit /b 1 + +:: 备份数据 +:backup_data +call :print_info "备份数据..." + +for /f "tokens=2 delims==" %%i in ('wmic OS Get localdatetime /value') do set datetime=%%i +set backup_dir=backups\%datetime:~0,8%_%datetime:~8,6% +mkdir "%backup_dir%" 2>nul + +:: 备份数据库 +if exist "data\xianyu_data.db" ( + copy "data\xianyu_data.db" "%backup_dir%\" >nul + call :print_success "数据库备份完成" +) + +:: 备份配置 +copy "%ENV_FILE%" "%backup_dir%\" >nul +copy "global_config.yml" "%backup_dir%\" >nul 2>&1 + +call :print_success "数据备份完成: %backup_dir%" +goto :eof + +:: 显示帮助信息 +:show_help +echo 闲鱼自动回复系统 Docker 部署脚本 ^(Windows版本^) +echo. +echo 用法: %~nx0 [命令] [选项] +echo. +echo 命令: +echo init 初始化配置文件 +echo build 构建 Docker 镜像 +echo start [with-nginx] 启动服务^(可选包含 Nginx^) +echo stop 停止服务 +echo restart 重启服务 +echo status 查看服务状态 +echo logs [service] 查看日志 +echo health 健康检查 +echo backup 备份数据 +echo help 显示帮助信息 +echo. +echo 示例: +echo %~nx0 init # 初始化配置 +echo %~nx0 start # 启动基础服务 +echo %~nx0 start with-nginx # 启动包含 Nginx 的服务 +echo %~nx0 logs xianyu-app # 查看应用日志 +echo. +goto :eof + +:: 主函数 +:main +if "%~1"=="init" ( + call :check_dependencies + call :init_config +) else if "%~1"=="build" ( + call :check_dependencies + call :build_image +) else if "%~1"=="start" ( + call :check_dependencies + call :init_config + call :build_image + call :start_services "%~2" +) else if "%~1"=="stop" ( + call :stop_services +) else if "%~1"=="restart" ( + call :restart_services +) else if "%~1"=="status" ( + call :show_status +) else if "%~1"=="logs" ( + call :show_logs "%~2" +) else if "%~1"=="health" ( + call :health_check +) else if "%~1"=="backup" ( + call :backup_data +) else if "%~1"=="help" ( + call :show_help +) else if "%~1"=="-h" ( + call :show_help +) else if "%~1"=="--help" ( + call :show_help +) else if "%~1"=="" ( + call :print_info "快速部署模式" + call :check_dependencies + call :init_config + call :build_image + call :start_services +) else ( + call :print_error "未知命令: %~1" + call :show_help + exit /b 1 +) + +goto :eof + +:: 执行主函数 +call :main %* diff --git a/docker-deploy.sh b/docker-deploy.sh new file mode 100644 index 0000000..c79458a --- /dev/null +++ b/docker-deploy.sh @@ -0,0 +1,350 @@ +#!/bin/bash + +# 闲鱼自动回复系统 Docker 部署脚本 +# 支持快速部署和管理 + +set -e + +# 颜色定义 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# 项目配置 +PROJECT_NAME="xianyu-auto-reply" +COMPOSE_FILE="docker-compose.yml" +ENV_FILE=".env" + +# 打印带颜色的消息 +print_info() { + echo -e "${BLUE}ℹ️ $1${NC}" +} + +print_success() { + echo -e "${GREEN}✅ $1${NC}" +} + +print_warning() { + echo -e "${YELLOW}⚠️ $1${NC}" +} + +print_error() { + echo -e "${RED}❌ $1${NC}" +} + +# 检查依赖 +check_dependencies() { + print_info "检查系统依赖..." + + if ! command -v docker &> /dev/null; then + print_error "Docker 未安装,请先安装 Docker" + exit 1 + fi + + if ! command -v docker-compose &> /dev/null; then + print_error "Docker Compose 未安装,请先安装 Docker Compose" + exit 1 + fi + + print_success "系统依赖检查通过" +} + +# 初始化配置 +init_config() { + print_info "初始化配置文件..." + + if [ ! -f "$ENV_FILE" ]; then + if [ -f ".env.example" ]; then + cp .env.example "$ENV_FILE" + print_success "已创建 $ENV_FILE 配置文件" + else + print_error ".env.example 文件不存在" + exit 1 + fi + else + print_warning "$ENV_FILE 已存在,跳过创建" + fi + + # 创建必要的目录 + mkdir -p data logs backups + print_success "已创建必要的目录" +} + +# 构建镜像 +build_image() { + print_info "构建 Docker 镜像..." + docker-compose build --no-cache + print_success "镜像构建完成" +} + +# 启动服务 +start_services() { + local profile="" + if [ "$1" = "with-nginx" ]; then + profile="--profile with-nginx" + print_info "启动服务(包含 Nginx)..." + else + print_info "启动基础服务..." + fi + + docker-compose $profile up -d + print_success "服务启动完成" + + # 等待服务就绪 + print_info "等待服务就绪..." + sleep 10 + + # 检查服务状态 + if docker-compose ps | grep -q "Up"; then + print_success "服务运行正常" + show_access_info "$1" + else + print_error "服务启动失败" + docker-compose logs + exit 1 + fi +} + +# 停止服务 +stop_services() { + print_info "停止服务..." + docker-compose down + print_success "服务已停止" +} + +# 重启服务 +restart_services() { + print_info "重启服务..." + docker-compose restart + print_success "服务已重启" +} + +# 查看日志 +show_logs() { + local service="$1" + if [ -z "$service" ]; then + docker-compose logs -f + else + docker-compose logs -f "$service" + fi +} + +# 查看状态 +show_status() { + print_info "服务状态:" + docker-compose ps + + print_info "资源使用:" + docker stats --no-stream $(docker-compose ps -q) +} + +# 显示访问信息 +show_access_info() { + local with_nginx="$1" + + echo "" + print_success "🎉 部署完成!" + echo "" + + if [ "$with_nginx" = "with-nginx" ]; then + echo "📱 访问地址:" + echo " HTTP: http://localhost" + echo " HTTPS: https://localhost (如果配置了SSL)" + else + echo "📱 访问地址:" + echo " HTTP: http://localhost:8080" + fi + + echo "" + echo "🔐 默认登录信息:" + echo " 用户名: admin" + echo " 密码: admin123" + echo "" + echo "📊 管理命令:" + echo " 查看状态: $0 status" + echo " 查看日志: $0 logs" + echo " 重启服务: $0 restart" + echo " 停止服务: $0 stop" + echo "" +} + +# 健康检查 +health_check() { + print_info "执行健康检查..." + + local url="http://localhost:8080/health" + local max_attempts=30 + local attempt=1 + + while [ $attempt -le $max_attempts ]; do + if curl -f -s "$url" > /dev/null 2>&1; then + print_success "健康检查通过" + return 0 + fi + + print_info "等待服务就绪... ($attempt/$max_attempts)" + sleep 2 + ((attempt++)) + done + + print_error "健康检查失败" + return 1 +} + +# 备份数据 +backup_data() { + print_info "备份数据..." + + local backup_dir="backups/$(date +%Y%m%d_%H%M%S)" + mkdir -p "$backup_dir" + + # 备份数据库 + if [ -f "data/xianyu_data.db" ]; then + cp data/xianyu_data.db "$backup_dir/" + print_success "数据库备份完成" + fi + + # 备份配置 + cp "$ENV_FILE" "$backup_dir/" + cp global_config.yml "$backup_dir/" 2>/dev/null || true + + print_success "数据备份完成: $backup_dir" +} + +# 更新部署 +update_deployment() { + print_info "更新部署..." + + # 备份数据 + backup_data + + # 停止服务 + stop_services + + # 拉取最新代码(如果是git仓库) + if [ -d ".git" ]; then + print_info "拉取最新代码..." + git pull + fi + + # 重新构建 + build_image + + # 启动服务 + start_services + + print_success "更新完成" +} + +# 清理环境 +cleanup() { + print_warning "这将删除所有容器、镜像和数据,确定要继续吗?(y/N)" + read -r response + + if [[ "$response" =~ ^[Yy]$ ]]; then + print_info "清理环境..." + + # 停止并删除容器 + docker-compose down -v --rmi all + + # 删除数据目录 + rm -rf data logs backups + + print_success "环境清理完成" + else + print_info "取消清理操作" + fi +} + +# 显示帮助信息 +show_help() { + echo "闲鱼自动回复系统 Docker 部署脚本" + echo "" + echo "用法: $0 [命令] [选项]" + echo "" + echo "命令:" + echo " init 初始化配置文件" + echo " build 构建 Docker 镜像" + echo " start [with-nginx] 启动服务(可选包含 Nginx)" + echo " stop 停止服务" + echo " restart 重启服务" + echo " status 查看服务状态" + echo " logs [service] 查看日志" + echo " health 健康检查" + echo " backup 备份数据" + echo " update 更新部署" + echo " cleanup 清理环境" + echo " help 显示帮助信息" + echo "" + echo "示例:" + echo " $0 init # 初始化配置" + echo " $0 start # 启动基础服务" + echo " $0 start with-nginx # 启动包含 Nginx 的服务" + echo " $0 logs xianyu-app # 查看应用日志" + echo "" +} + +# 主函数 +main() { + case "$1" in + "init") + check_dependencies + init_config + ;; + "build") + check_dependencies + build_image + ;; + "start") + check_dependencies + init_config + build_image + start_services "$2" + ;; + "stop") + stop_services + ;; + "restart") + restart_services + ;; + "status") + show_status + ;; + "logs") + show_logs "$2" + ;; + "health") + health_check + ;; + "backup") + backup_data + ;; + "update") + check_dependencies + update_deployment + ;; + "cleanup") + cleanup + ;; + "help"|"--help"|"-h") + show_help + ;; + "") + print_info "快速部署模式" + check_dependencies + init_config + build_image + start_services + ;; + *) + print_error "未知命令: $1" + show_help + exit 1 + ;; + esac +} + +# 执行主函数 +main "$@" diff --git a/docker_deployment_update.md b/docker_deployment_update.md new file mode 100644 index 0000000..b68877b --- /dev/null +++ b/docker_deployment_update.md @@ -0,0 +1,207 @@ +# Docker部署更新检查报告 + +## 📋 检查概述 + +对Docker部署配置进行了全面检查,评估是否需要更新以支持新增的AI回复功能和其他改进。 + +## ✅ 当前状态评估 + +### 🎯 **结论:Docker部署配置已经完善,无需重大更新** + +所有新增功能都已经在现有的Docker配置中得到支持。 + +## 📊 详细检查结果 + +### 1. **依赖包检查** ✅ +#### requirements.txt 状态:**完整** +``` +✅ openai>=1.65.5 # AI回复功能 +✅ python-dotenv>=1.0.1 # 环境变量支持 +✅ python-multipart>=0.0.6 # 文件上传支持 +✅ fastapi>=0.111 # Web框架 +✅ uvicorn[standard]>=0.29 # ASGI服务器 +✅ 其他所有必要依赖 +``` + +### 2. **环境变量配置** ✅ +#### .env.example 状态:**完整** +``` +✅ AI_REPLY_ENABLED=false +✅ DEFAULT_AI_MODEL=qwen-plus +✅ DEFAULT_AI_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1 +✅ AI_REQUEST_TIMEOUT=30 +✅ AI_MAX_TOKENS=100 +✅ 所有基础配置变量 +``` + +### 3. **Docker Compose配置** ✅ +#### docker-compose.yml 状态:**完整** +``` +✅ AI回复相关环境变量映射 +✅ 数据持久化配置 (/app/data, /app/logs, /app/backups) +✅ 健康检查配置 +✅ 资源限制配置 +✅ 网络配置 +✅ Nginx反向代理支持 +``` + +### 4. **Dockerfile配置** ✅ +#### Dockerfile 状态:**完整** +``` +✅ Python 3.11基础镜像 +✅ 所有系统依赖安装 +✅ 应用依赖安装 +✅ 工作目录配置 +✅ 端口暴露配置 +✅ 启动命令配置 +``` + +### 5. **数据持久化** ✅ +#### 挂载点配置:**完整** +``` +✅ ./data:/app/data:rw # 数据库文件 +✅ ./logs:/app/logs:rw # 日志文件 +✅ ./backups:/app/backups:rw # 备份文件 +✅ ./global_config.yml:/app/global_config.yml:ro # 配置文件 +``` + +### 6. **健康检查** ✅ +#### 健康检查配置:**完整** +``` +✅ HTTP健康检查端点 (/health) +✅ 检查间隔:30秒 +✅ 超时时间:10秒 +✅ 重试次数:3次 +✅ 启动等待:40秒 +``` + +## 🔍 新功能支持验证 + +### AI回复功能 ✅ +- **依赖支持**:openai库已包含 +- **配置支持**:所有AI相关环境变量已配置 +- **数据支持**:AI数据表会自动创建 +- **API支持**:FastAPI框架支持所有新接口 + +### 备份功能增强 ✅ +- **存储支持**:备份目录已挂载 +- **数据支持**:所有新表都包含在备份中 +- **权限支持**:容器有读写权限 + +### 商品管理功能 ✅ +- **文件上传**:python-multipart依赖已包含 +- **数据存储**:数据库挂载支持新表 +- **API支持**:FastAPI支持文件上传接口 + +## 💡 可选优化建议 + +虽然当前配置已经完善,但可以考虑以下优化: + +### 1. **添加AI服务健康检查** +```yaml +# 可选:添加AI服务连通性检查 +healthcheck: + test: ["CMD", "python", "-c", "import requests; requests.get('http://localhost:8080/api/ai/health', timeout=5)"] +``` + +### 2. **添加更多监控指标** +```yaml +# 可选:添加Prometheus监控 +environment: + - ENABLE_METRICS=true + - METRICS_PORT=9090 +``` + +### 3. **添加AI配置验证** +```yaml +# 可选:启动时验证AI配置 +environment: + - VALIDATE_AI_CONFIG=true +``` + +## 🚀 部署建议 + +### 生产环境部署 +1. **使用强密码** + ```bash + ADMIN_PASSWORD=$(openssl rand -base64 32) + JWT_SECRET_KEY=$(openssl rand -base64 32) + ``` + +2. **配置AI服务** + ```bash + AI_REPLY_ENABLED=true + # 配置真实的API密钥 + ``` + +3. **启用HTTPS** + ```bash + docker-compose --profile with-nginx up -d + ``` + +4. **配置资源限制** + ```bash + MEMORY_LIMIT=1024 # 如果使用AI功能,建议增加内存 + CPU_LIMIT=1.0 + ``` + +### 开发环境部署 +```bash +# 克隆项目 +git clone +cd xianyuapis + +# 复制环境变量 +cp .env.example .env + +# 启动服务 +docker-compose up -d + +# 查看日志 +docker-compose logs -f +``` + +## 📋 部署检查清单 + +### 部署前检查 ✅ +- [x] Docker和Docker Compose已安装 +- [x] 端口8080未被占用 +- [x] 有足够的磁盘空间(建议>2GB) +- [x] 网络连接正常 + +### 配置检查 ✅ +- [x] .env文件已配置 +- [x] global_config.yml文件存在 +- [x] data、logs、backups目录权限正确 +- [x] AI API密钥已配置(如果使用AI功能) + +### 功能验证 ✅ +- [x] Web界面可访问 +- [x] 账号管理功能正常 +- [x] 自动回复功能正常 +- [x] AI回复功能正常(如果启用) +- [x] 备份功能正常 + +## 🎉 总结 + +### ✅ **Docker部署配置完全就绪** + +1. **无需更新**:当前配置已支持所有新功能 +2. **开箱即用**:可直接部署使用 +3. **功能完整**:支持AI回复、备份、商品管理等所有功能 +4. **生产就绪**:包含安全、监控、资源限制等配置 + +### 🚀 **立即可用的部署命令** + +```bash +# 快速部署 +git clone +cd xianyuapis +cp .env.example .env +docker-compose up -d + +# 访问系统 +open http://localhost:8080 +``` + +**Docker部署配置已经完善,支持所有新功能,可以直接使用!** 🎉 diff --git a/file_log_collector.py b/file_log_collector.py index 854b8ab..7dd51e7 100644 --- a/file_log_collector.py +++ b/file_log_collector.py @@ -29,167 +29,119 @@ class FileLogCollector: def setup_file_monitoring(self): """设置文件监控""" - # 使用统一的日志文件路径 - import time - log_dir = 'logs' - os.makedirs(log_dir, exist_ok=True) - - # 使用与其他模块相同的日志文件命名规则 - today_log = os.path.join(log_dir, f"xianyu_{time.strftime('%Y-%m-%d')}.log") - - # 查找日志文件,优先使用今天的日志文件 + # 查找日志文件 possible_files = [ - today_log, - "logs/xianyu.log", "xianyu.log", - "app.log", + "app.log", "system.log", + "logs/xianyu.log", "logs/app.log" ] - + for file_path in possible_files: if os.path.exists(file_path): self.log_file = file_path break - + if not self.log_file: - # 如果没有找到现有文件,使用今天的日志文件 - self.log_file = today_log - - print(f"日志收集器监控文件: {self.log_file}") - + # 如果没有找到现有文件,创建一个新的 + self.log_file = "realtime.log" + + # 设置loguru输出到文件 + self.setup_loguru_file_output() + # 启动文件监控线程 self.monitor_thread = threading.Thread(target=self.monitor_file, daemon=True) self.monitor_thread.start() - + def setup_loguru_file_output(self): + """设置loguru输出到文件""" + try: + from loguru import logger + + # 添加文件输出 + logger.add( + self.log_file, + format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level} | {name}:{function}:{line} - {message}", + level="DEBUG", + rotation="10 MB", + retention="7 days", + enqueue=False, # 改为False,避免队列延迟 + buffering=1 # 行缓冲,立即写入 + ) + + logger.info("文件日志收集器已启动") + + except ImportError: + pass def monitor_file(self): """监控日志文件变化""" - print(f"开始监控日志文件: {self.log_file}") - while True: try: if os.path.exists(self.log_file): # 获取文件大小 file_size = os.path.getsize(self.log_file) - + if file_size > self.last_position: # 读取新增内容 - try: - with open(self.log_file, 'r', encoding='utf-8', errors='ignore') as f: - f.seek(self.last_position) - new_lines = f.readlines() - self.last_position = f.tell() - - # 解析新增的日志行 - for line in new_lines: - line = line.strip() - if line: # 只处理非空行 - self.parse_log_line(line) - except Exception as read_error: - print(f"读取日志文件失败: {read_error}") - elif file_size < self.last_position: - # 文件被截断或重新创建,重置位置 - self.last_position = 0 - print(f"检测到日志文件被重置: {self.log_file}") - else: - # 文件不存在,重置位置等待文件创建 - self.last_position = 0 - - time.sleep(0.2) # 每0.2秒检查一次,更及时 - + with open(self.log_file, 'r', encoding='utf-8') as f: + f.seek(self.last_position) + new_lines = f.readlines() + self.last_position = f.tell() + + # 解析新增的日志行 + for line in new_lines: + self.parse_log_line(line.strip()) + + time.sleep(0.5) # 每0.5秒检查一次 + except Exception as e: - print(f"监控日志文件异常: {e}") time.sleep(1) # 出错时等待1秒 def parse_log_line(self, line: str): """解析日志行""" if not line: return - + try: - # 解析统一格式的日志 - # 格式: 2024-07-24 15:46:03.430 | INFO | module_name:function_name:123 - 消息内容 + # 解析loguru格式的日志 + # 格式: 2025-07-23 15:46:03.430 | INFO | __main__:debug_collector:70 - 消息 pattern = r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}) \| (\w+) \| ([^:]+):([^:]+):(\d+) - (.*)' match = re.match(pattern, line) - + if match: timestamp_str, level, source, function, line_num, message = match.groups() - + # 转换时间格式 try: timestamp = datetime.strptime(timestamp_str, '%Y-%m-%d %H:%M:%S.%f') except: timestamp = datetime.now() - - # 清理source名称,移除路径和扩展名 - if '\\' in source or '/' in source: - source = os.path.basename(source) - if source.endswith('.py'): - source = source[:-3] - + log_entry = { "timestamp": timestamp.isoformat(), - "level": level.strip(), - "source": source.strip(), - "function": function.strip(), + "level": level, + "source": source, + "function": function, "line": int(line_num), - "message": message.strip() + "message": message } - + with self.lock: self.logs.append(log_entry) - - else: - # 尝试解析其他可能的格式 - # 简单格式: [时间] [级别] 消息 - simple_pattern = r'\[([^\]]+)\] \[(\w+)\] (.*)' - simple_match = re.match(simple_pattern, line) - - if simple_match: - timestamp_str, level, message = simple_match.groups() - try: - timestamp = datetime.strptime(timestamp_str, '%Y-%m-%d %H:%M:%S') - except: - timestamp = datetime.now() - - log_entry = { - "timestamp": timestamp.isoformat(), - "level": level.strip(), - "source": "system", - "function": "unknown", - "line": 0, - "message": message.strip() - } - - with self.lock: - self.logs.append(log_entry) - else: - # 如果都解析失败,作为普通消息处理 - log_entry = { - "timestamp": datetime.now().isoformat(), - "level": "INFO", - "source": "system", - "function": "unknown", - "line": 0, - "message": line.strip() - } - - with self.lock: - self.logs.append(log_entry) - + except Exception as e: # 如果解析失败,作为普通消息处理 log_entry = { "timestamp": datetime.now().isoformat(), - "level": "ERROR", - "source": "log_parser", - "function": "parse_log_line", + "level": "INFO", + "source": "system", + "function": "unknown", "line": 0, - "message": f"日志解析失败: {line} (错误: {str(e)})" + "message": line } - + with self.lock: self.logs.append(log_entry) diff --git a/fix-db-permissions.bat b/fix-db-permissions.bat new file mode 100644 index 0000000..fdcb358 --- /dev/null +++ b/fix-db-permissions.bat @@ -0,0 +1,156 @@ +@echo off +chcp 65001 >nul +setlocal enabledelayedexpansion + +:: 修复数据库权限问题的脚本 (Windows版本) +:: 解决Docker容器中数据库无法创建的问题 + +title 数据库权限修复脚本 + +:: 颜色定义 +set "RED=[91m" +set "GREEN=[92m" +set "YELLOW=[93m" +set "BLUE=[94m" +set "NC=[0m" + +:: 打印带颜色的消息 +:print_info +echo %BLUE%[INFO]%NC% %~1 +goto :eof + +:print_success +echo %GREEN%[SUCCESS]%NC% %~1 +goto :eof + +:print_warning +echo %YELLOW%[WARNING]%NC% %~1 +goto :eof + +:print_error +echo %RED%[ERROR]%NC% %~1 +goto :eof + +echo ======================================== +echo 数据库权限修复脚本 +echo ======================================== +echo. + +:: 1. 停止现有容器 +call :print_info "停止现有容器..." +docker-compose down >nul 2>&1 + +:: 2. 检查并创建目录 +call :print_info "检查并创建必要目录..." + +for %%d in (data logs backups) do ( + if not exist "%%d" ( + call :print_info "创建目录: %%d" + mkdir "%%d" + ) + + if not exist "%%d" ( + call :print_error "目录 %%d 创建失败" + pause + exit /b 1 + ) + + call :print_success "目录 %%d 权限正常" +) + +:: 3. 检查现有数据库文件 +if exist "data\xianyu_data.db" ( + call :print_info "检查现有数据库文件..." + call :print_success "数据库文件存在" +) else ( + call :print_info "数据库文件不存在,将在启动时创建" +) + +:: 4. 测试数据库创建 +call :print_info "测试数据库创建..." +python -c " +import sqlite3 +import os + +db_path = 'data/test_db.sqlite' +try: + conn = sqlite3.connect(db_path) + conn.execute('CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY)') + conn.commit() + conn.close() + print('✅ 数据库创建测试成功') + if os.path.exists(db_path): + os.remove(db_path) +except Exception as e: + print(f'❌ 数据库创建测试失败: {e}') + exit(1) +" + +if !errorlevel! neq 0 ( + call :print_error "数据库创建测试失败" + pause + exit /b 1 +) + +:: 5. 重新构建并启动 +call :print_info "重新构建并启动服务..." +docker-compose build --no-cache +if !errorlevel! neq 0 ( + call :print_error "Docker镜像构建失败" + pause + exit /b 1 +) + +docker-compose up -d +if !errorlevel! neq 0 ( + call :print_error "服务启动失败" + pause + exit /b 1 +) + +:: 6. 等待服务启动 +call :print_info "等待服务启动..." +timeout /t 15 /nobreak >nul + +:: 7. 检查服务状态 +call :print_info "检查服务状态..." +docker-compose ps | findstr "Up" >nul +if !errorlevel! equ 0 ( + call :print_success "服务启动成功" + + :: 检查日志 + call :print_info "检查启动日志..." + docker-compose logs --tail=20 xianyu-app + + :: 测试健康检查 + call :print_info "测试健康检查..." + timeout /t 5 /nobreak >nul + curl -f http://localhost:8080/health >nul 2>&1 + if !errorlevel! equ 0 ( + call :print_success "健康检查通过" + ) else ( + call :print_warning "健康检查失败,但服务可能仍在启动中" + ) +) else ( + call :print_error "服务启动失败" + call :print_info "查看错误日志:" + docker-compose logs xianyu-app + pause + exit /b 1 +) + +echo. +call :print_success "数据库权限修复完成!" +echo. +call :print_info "服务信息:" +echo Web界面: http://localhost:8080 +echo 健康检查: http://localhost:8080/health +echo 默认账号: admin / admin123 +echo. +call :print_info "常用命令:" +echo 查看日志: docker-compose logs -f +echo 重启服务: docker-compose restart +echo 停止服务: docker-compose down +echo. + +pause diff --git a/fix-db-permissions.sh b/fix-db-permissions.sh new file mode 100644 index 0000000..e6ea4ff --- /dev/null +++ b/fix-db-permissions.sh @@ -0,0 +1,167 @@ +#!/bin/bash + +# 修复数据库权限问题的脚本 +# 解决Docker容器中数据库无法创建的问题 + +set -e + +# 颜色定义 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +print_info() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +print_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +print_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +print_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +echo "========================================" +echo " 数据库权限修复脚本" +echo "========================================" +echo "" + +# 1. 停止现有容器 +print_info "停止现有容器..." +docker-compose down 2>/dev/null || true + +# 2. 检查并创建目录 +print_info "检查并创建必要目录..." +for dir in data logs backups; do + if [ ! -d "$dir" ]; then + print_info "创建目录: $dir" + mkdir -p "$dir" + fi + + # 设置权限 + chmod 755 "$dir" + + # 检查权限 + if [ ! -w "$dir" ]; then + print_error "目录 $dir 没有写权限" + + # 尝试修复权限 + print_info "尝试修复权限..." + sudo chmod 755 "$dir" 2>/dev/null || { + print_error "无法修复权限,请手动执行: sudo chmod 755 $dir" + exit 1 + } + fi + + print_success "目录 $dir 权限正常" +done + +# 3. 检查现有数据库文件 +if [ -f "data/xianyu_data.db" ]; then + print_info "检查现有数据库文件权限..." + if [ ! -w "data/xianyu_data.db" ]; then + print_warning "数据库文件没有写权限,尝试修复..." + chmod 644 "data/xianyu_data.db" + print_success "数据库文件权限已修复" + else + print_success "数据库文件权限正常" + fi +fi + +# 4. 检查Docker用户映射 +print_info "检查Docker用户映射..." +CURRENT_UID=$(id -u) +CURRENT_GID=$(id -g) + +print_info "当前用户 UID:GID = $CURRENT_UID:$CURRENT_GID" + +# 5. 创建测试数据库 +print_info "测试数据库创建..." +python3 -c " +import sqlite3 +import os + +db_path = 'data/test_db.sqlite' +try: + conn = sqlite3.connect(db_path) + conn.execute('CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY)') + conn.commit() + conn.close() + print('✅ 数据库创建测试成功') + os.remove(db_path) +except Exception as e: + print(f'❌ 数据库创建测试失败: {e}') + exit(1) +" || { + print_error "数据库创建测试失败" + exit 1 +} + +# 6. 更新docker-compose.yml用户映射 +print_info "检查docker-compose.yml用户映射..." +if ! grep -q "user:" docker-compose.yml; then + print_info "添加用户映射到docker-compose.yml..." + + # 备份原文件 + cp docker-compose.yml docker-compose.yml.backup + + # 在xianyu-app服务中添加user配置 + sed -i '/container_name: xianyu-auto-reply/a\ user: "'$CURRENT_UID':'$CURRENT_GID'"' docker-compose.yml + + print_success "用户映射已添加" +else + print_info "用户映射已存在" +fi + +# 7. 重新构建并启动 +print_info "重新构建并启动服务..." +docker-compose build --no-cache +docker-compose up -d + +# 8. 等待服务启动 +print_info "等待服务启动..." +sleep 10 + +# 9. 检查服务状态 +print_info "检查服务状态..." +if docker-compose ps | grep -q "Up"; then + print_success "服务启动成功" + + # 检查日志 + print_info "检查启动日志..." + docker-compose logs --tail=20 xianyu-app + + # 测试健康检查 + print_info "测试健康检查..." + sleep 5 + if curl -f http://localhost:8080/health >/dev/null 2>&1; then + print_success "健康检查通过" + else + print_warning "健康检查失败,但服务可能仍在启动中" + fi +else + print_error "服务启动失败" + print_info "查看错误日志:" + docker-compose logs xianyu-app + exit 1 +fi + +echo "" +print_success "数据库权限修复完成!" +echo "" +print_info "服务信息:" +echo " Web界面: http://localhost:8080" +echo " 健康检查: http://localhost:8080/health" +echo " 默认账号: admin / admin123" +echo "" +print_info "常用命令:" +echo " 查看日志: docker-compose logs -f" +echo " 重启服务: docker-compose restart" +echo " 停止服务: docker-compose down" diff --git a/fix-docker-warnings.bat b/fix-docker-warnings.bat new file mode 100644 index 0000000..6810784 --- /dev/null +++ b/fix-docker-warnings.bat @@ -0,0 +1,144 @@ +@echo off +chcp 65001 >nul +setlocal enabledelayedexpansion + +:: 修复Docker部署警告的快速脚本 (Windows版本) +:: 解决version过时和.env文件缺失问题 + +title Docker部署警告修复脚本 + +:: 颜色定义 +set "RED=[91m" +set "GREEN=[92m" +set "YELLOW=[93m" +set "BLUE=[94m" +set "NC=[0m" + +:: 打印带颜色的消息 +:print_info +echo %BLUE%[INFO]%NC% %~1 +goto :eof + +:print_success +echo %GREEN%[SUCCESS]%NC% %~1 +goto :eof + +:print_warning +echo %YELLOW%[WARNING]%NC% %~1 +goto :eof + +:print_error +echo %RED%[ERROR]%NC% %~1 +goto :eof + +echo ======================================== +echo Docker部署警告修复脚本 +echo ======================================== +echo. + +:: 1. 检查并创建.env文件 +call :print_info "检查 .env 文件..." +if not exist ".env" ( + if exist ".env.example" ( + call :print_info "从 .env.example 创建 .env 文件..." + copy ".env.example" ".env" >nul + call :print_success ".env 文件已创建" + ) else ( + call :print_warning ".env.example 文件不存在" + call :print_info "创建基本的 .env 文件..." + + ( + echo # 闲鱼自动回复系统 Docker 环境变量配置文件 + echo. + echo # 基础配置 + echo TZ=Asia/Shanghai + echo PYTHONUNBUFFERED=1 + echo LOG_LEVEL=INFO + echo. + echo # 数据库配置 + echo DB_PATH=/app/data/xianyu_data.db + echo. + echo # 服务配置 + echo WEB_PORT=8080 + echo. + echo # 安全配置 + echo ADMIN_USERNAME=admin + echo ADMIN_PASSWORD=admin123 + echo JWT_SECRET_KEY=xianyu-auto-reply-secret-key-2024 + echo. + echo # 资源限制 + echo MEMORY_LIMIT=512 + echo CPU_LIMIT=0.5 + echo MEMORY_RESERVATION=256 + echo CPU_RESERVATION=0.25 + echo. + echo # 自动回复配置 + echo AUTO_REPLY_ENABLED=true + echo WEBSOCKET_URL=wss://wss-goofish.dingtalk.com/ + echo HEARTBEAT_INTERVAL=15 + echo TOKEN_REFRESH_INTERVAL=3600 + ) > .env + + call :print_success "基本 .env 文件已创建" + ) +) else ( + call :print_success ".env 文件已存在" +) + +:: 2. 检查docker-compose.yml版本问题 +call :print_info "检查 docker-compose.yml 配置..." +findstr /B "version:" docker-compose.yml >nul 2>&1 +if !errorlevel! equ 0 ( + call :print_warning "发现过时的 version 字段" + call :print_info "移除 version 字段..." + + REM 备份原文件 + copy docker-compose.yml docker-compose.yml.backup >nul + + REM 创建临时文件,移除version行 + ( + for /f "tokens=*" %%a in (docker-compose.yml) do ( + echo %%a | findstr /B "version:" >nul + if !errorlevel! neq 0 ( + echo %%a + ) + ) + ) > docker-compose.yml.tmp + + REM 替换原文件 + move docker-compose.yml.tmp docker-compose.yml >nul + + call :print_success "已移除过时的 version 字段" + call :print_info "原文件已备份为 docker-compose.yml.backup" +) else ( + call :print_success "docker-compose.yml 配置正确" +) + +:: 3. 验证修复结果 +call :print_info "验证修复结果..." + +echo. +call :print_info "测试 Docker Compose 配置..." +docker-compose config >nul 2>&1 +if !errorlevel! equ 0 ( + call :print_success "Docker Compose 配置验证通过" +) else ( + call :print_error "Docker Compose 配置验证失败" + echo 请检查 docker-compose.yml 文件 + pause + exit /b 1 +) + +echo. +call :print_success "所有警告已修复!" +echo. +call :print_info "现在可以正常使用以下命令:" +echo docker-compose up -d # 启动服务 +echo docker-compose ps # 查看状态 +echo docker-compose logs -f # 查看日志 +echo. +call :print_info "如果需要恢复原配置:" +echo move docker-compose.yml.backup docker-compose.yml +echo. + +pause diff --git a/fix-docker-warnings.sh b/fix-docker-warnings.sh new file mode 100644 index 0000000..63d63e5 --- /dev/null +++ b/fix-docker-warnings.sh @@ -0,0 +1,145 @@ +#!/bin/bash + +# 修复Docker部署警告的快速脚本 +# 解决version过时和.env文件缺失问题 + +set -e + +# 颜色定义 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +print_info() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +print_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +print_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +print_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +echo "========================================" +echo " Docker部署警告修复脚本" +echo "========================================" +echo "" + +# 1. 检查并创建.env文件 +print_info "检查 .env 文件..." +if [ ! -f ".env" ]; then + if [ -f ".env.example" ]; then + print_info "从 .env.example 创建 .env 文件..." + cp .env.example .env + print_success ".env 文件已创建" + else + print_warning ".env.example 文件不存在" + print_info "创建基本的 .env 文件..." + cat > .env << 'EOF' +# 闲鱼自动回复系统 Docker 环境变量配置文件 + +# 基础配置 +TZ=Asia/Shanghai +PYTHONUNBUFFERED=1 +LOG_LEVEL=INFO + +# 数据库配置 +DB_PATH=/app/data/xianyu_data.db + +# 服务配置 +WEB_PORT=8080 + +# 安全配置 +ADMIN_USERNAME=admin +ADMIN_PASSWORD=admin123 +JWT_SECRET_KEY=xianyu-auto-reply-secret-key-2024 + +# 资源限制 +MEMORY_LIMIT=512 +CPU_LIMIT=0.5 +MEMORY_RESERVATION=256 +CPU_RESERVATION=0.25 + +# 自动回复配置 +AUTO_REPLY_ENABLED=true +WEBSOCKET_URL=wss://wss-goofish.dingtalk.com/ +HEARTBEAT_INTERVAL=15 +TOKEN_REFRESH_INTERVAL=3600 +EOF + print_success "基本 .env 文件已创建" + fi +else + print_success ".env 文件已存在" +fi + +# 2. 检查docker-compose.yml版本问题 +print_info "检查 docker-compose.yml 配置..." +if grep -q "^version:" docker-compose.yml 2>/dev/null; then + print_warning "发现过时的 version 字段" + print_info "移除 version 字段..." + + # 备份原文件 + cp docker-compose.yml docker-compose.yml.backup + + # 移除version行 + sed -i '/^version:/d' docker-compose.yml + sed -i '/^$/N;/^\n$/d' docker-compose.yml # 移除空行 + + print_success "已移除过时的 version 字段" + print_info "原文件已备份为 docker-compose.yml.backup" +else + print_success "docker-compose.yml 配置正确" +fi + +# 3. 检查env_file配置 +print_info "检查 env_file 配置..." +if grep -A1 "env_file:" docker-compose.yml | grep -q "required: false"; then + print_success "env_file 配置正确" +else + print_info "更新 env_file 配置为可选..." + + # 备份文件(如果还没备份) + if [ ! -f "docker-compose.yml.backup" ]; then + cp docker-compose.yml docker-compose.yml.backup + fi + + # 更新env_file配置 + sed -i '/env_file:/,+1c\ + env_file:\ + - path: .env\ + required: false' docker-compose.yml + + print_success "env_file 配置已更新" +fi + +# 4. 验证修复结果 +print_info "验证修复结果..." + +echo "" +print_info "测试 Docker Compose 配置..." +if docker-compose config >/dev/null 2>&1; then + print_success "Docker Compose 配置验证通过" +else + print_error "Docker Compose 配置验证失败" + echo "请检查 docker-compose.yml 文件" + exit 1 +fi + +echo "" +print_success "所有警告已修复!" +echo "" +print_info "现在可以正常使用以下命令:" +echo " docker-compose up -d # 启动服务" +echo " docker-compose ps # 查看状态" +echo " docker-compose logs -f # 查看日志" +echo "" +print_info "如果需要恢复原配置:" +echo " mv docker-compose.yml.backup docker-compose.yml" diff --git a/fix-websocket-issue.sh b/fix-websocket-issue.sh new file mode 100644 index 0000000..d874a86 --- /dev/null +++ b/fix-websocket-issue.sh @@ -0,0 +1,121 @@ +#!/bin/bash + +# 快速修复WebSocket兼容性问题 +# 解决 "extra_headers" 参数不支持的问题 + +set -e + +# 颜色定义 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +print_info() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +print_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +print_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +print_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +echo "🔧 WebSocket兼容性问题修复" +echo "================================" + +# 1. 检查当前websockets版本 +print_info "检查当前websockets版本..." +if command -v python3 &> /dev/null; then + PYTHON_CMD="python3" +elif command -v python &> /dev/null; then + PYTHON_CMD="python" +else + print_error "未找到Python解释器" + exit 1 +fi + +CURRENT_VERSION=$($PYTHON_CMD -c "import websockets; print(websockets.__version__)" 2>/dev/null || echo "未安装") +print_info "当前websockets版本: $CURRENT_VERSION" + +# 2. 测试WebSocket兼容性 +print_info "测试WebSocket兼容性..." +$PYTHON_CMD test-websocket-compatibility.py + +# 3. 停止现有服务 +print_info "停止现有Docker服务..." +docker-compose down 2>/dev/null || true + +# 4. 更新websockets版本 +print_info "更新websockets版本到兼容版本..." +if [ -f "requirements.txt" ]; then + # 备份原文件 + cp requirements.txt requirements.txt.backup + + # 更新websockets版本 + sed -i 's/websockets>=.*/websockets>=10.0,<13.0 # 兼容性版本范围/' requirements.txt + + print_success "requirements.txt已更新" +else + print_warning "requirements.txt文件不存在" +fi + +# 5. 重新构建Docker镜像 +print_info "重新构建Docker镜像..." +docker-compose build --no-cache + +# 6. 启动服务 +print_info "启动服务..." +docker-compose up -d + +# 7. 等待服务启动 +print_info "等待服务启动..." +sleep 15 + +# 8. 检查服务状态 +print_info "检查服务状态..." +if docker-compose ps | grep -q "Up"; then + print_success "✅ 服务启动成功!" + + # 检查WebSocket错误 + print_info "检查WebSocket连接状态..." + sleep 5 + + # 查看最近的日志 + echo "" + print_info "最近的服务日志:" + docker-compose logs --tail=20 xianyu-app | grep -E "(WebSocket|extra_headers|ERROR)" || echo "未发现WebSocket相关错误" + + # 测试健康检查 + if curl -f http://localhost:8080/health >/dev/null 2>&1; then + print_success "健康检查通过" + else + print_warning "健康检查失败,服务可能仍在启动中" + fi + +else + print_error "❌ 服务启动失败" + print_info "查看错误日志:" + docker-compose logs --tail=30 xianyu-app + exit 1 +fi + +echo "" +print_success "🎉 WebSocket兼容性问题修复完成!" +echo "" +print_info "服务信息:" +echo " Web界面: http://localhost:8080" +echo " 健康检查: http://localhost:8080/health" +echo " 默认账号: admin / admin123" +echo "" +print_info "如果仍有WebSocket问题,请:" +echo " 1. 查看日志: docker-compose logs -f xianyu-app" +echo " 2. 运行测试: python test-websocket-compatibility.py" +echo " 3. 检查网络连接和防火墙设置" diff --git a/gitignore_rules_explanation.md b/gitignore_rules_explanation.md new file mode 100644 index 0000000..dacf1e4 --- /dev/null +++ b/gitignore_rules_explanation.md @@ -0,0 +1,172 @@ +# .gitignore 规则说明 + +## 📋 概述 + +本项目的 `.gitignore` 文件已经过优化,包含了完整的忽略规则,确保敏感文件和不必要的文件不会被提交到版本控制中。 + +## 🔧 主要修复 + +### 1. **数据库文件忽略** ✅ +**问题**: 原来缺少 `*.db` 文件的忽略规则 +**解决**: 添加了完整的数据库文件忽略规则 + +```gitignore +# Database files +*.db +*.sqlite +*.sqlite3 +db.sqlite3 +``` + +### 2. **静态资源例外** ✅ +**问题**: `lib/` 规则会忽略 `static/lib/` 中的本地 CDN 资源 +**解决**: 添加例外规则,允许 `static/lib/` 被版本控制 + +```gitignore +# Python lib directories (but not static/lib) +lib/ +!static/lib/ +``` + +## 📂 完整规则分类 + +### Python 相关 +```gitignore +__pycache__ +*.so +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +MANIFEST +*.manifest +*.spec +__pypackages__/ +.venv +venv/ +ENV/ +env.bak/ +venv.bak/ +``` + +### 数据库文件 +```gitignore +*.db +*.sqlite +*.sqlite3 +db.sqlite3 +``` + +### 日志和缓存 +```gitignore +*.log +.cache +``` + +### 临时文件 +```gitignore +*.tmp +*.temp +temp/ +tmp/ +``` + +### 操作系统生成的文件 +```gitignore +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db +``` + +### IDE 和编辑器文件 +```gitignore +.vscode/ +.idea/ +*.swp +*.swo +*~ +``` + +### 环境配置文件 +```gitignore +.env +.env.local +.env.*.local +local_settings.py +``` + +### Node.js 相关 +```gitignore +*node_modules/* +``` + +### 静态资源例外 +```gitignore +!static/lib/ +``` + +## 🎯 特殊说明 + +### 数据库文件保护 +- **目的**: 防止敏感的用户数据和配置信息被意外提交 +- **影响**: `xianyu_data.db` 等数据库文件不会被 Git 跟踪 +- **好处**: 保护用户隐私,避免数据泄露 + +### 静态资源管理 +- **目的**: 允许本地 CDN 资源被版本控制,提升中国大陆访问速度 +- **规则**: `lib/` 被忽略,但 `static/lib/` 不被忽略 +- **包含**: Bootstrap CSS/JS、Bootstrap Icons 等本地资源 + +### 环境配置保护 +- **目的**: 防止敏感的环境变量和配置被提交 +- **影响**: `.env` 文件和本地设置不会被跟踪 +- **好处**: 保护 API 密钥、数据库连接等敏感信息 + +## 🧪 验证方法 + +可以运行以下测试脚本验证规则是否正确: + +```bash +# 测试数据库文件忽略 +python test_gitignore_db.py + +# 测试静态资源例外 +python test_gitignore.py +``` + +## 📊 当前项目状态 + +### 被忽略的文件 +- `xianyu_data.db` (139,264 bytes) - 主数据库 +- `data/xianyu_data.db` (106,496 bytes) - 数据目录中的数据库 +- 各种临时文件、日志文件、IDE 配置等 + +### 不被忽略的重要文件 +- `static/lib/` 目录下的所有本地 CDN 资源 (702 KB) +- 源代码文件 (`.py`, `.html`, `.js` 等) +- 配置模板文件 (`.yml.example`, `.env.example` 等) +- 文档文件 (`.md` 等) + +## 🎉 优势总结 + +1. **数据安全**: 数据库文件不会被意外提交,保护用户数据 +2. **配置安全**: 环境变量和敏感配置得到保护 +3. **仓库整洁**: 临时文件、缓存文件等不会污染仓库 +4. **本地资源**: CDN 资源可以正常版本控制,提升访问速度 +5. **跨平台**: 支持 Windows、macOS、Linux 的常见忽略文件 +6. **IDE 友好**: 支持 VSCode、IntelliJ IDEA 等常见 IDE + +现在的 `.gitignore` 配置既保证了项目的安全性,又确保了必要文件的正常版本控制! diff --git a/global_config.yml b/global_config.yml index 4ef32e4..9e11190 100644 --- a/global_config.yml +++ b/global_config.yml @@ -9,7 +9,7 @@ APP_CONFIG: platform: web AUTO_REPLY: api: - enabled: true # 禁用API回复,使用AI回复或关键词回复 + enabled: false # 禁用API回复,使用AI回复或关键词回复 host: 0.0.0.0 # 绑定所有网络接口,支持IP访问 port: 8080 # Web服务端口 timeout: 10 diff --git a/images/qq-group.jpg b/images/qq-group.jpg deleted file mode 100644 index f351cf1..0000000 Binary files a/images/qq-group.jpg and /dev/null differ diff --git a/images/wechat-group.jpg b/images/wechat-group.jpg deleted file mode 100644 index 12a2990..0000000 Binary files a/images/wechat-group.jpg and /dev/null differ diff --git a/log_filter.py b/log_filter.py deleted file mode 100644 index 8022ee2..0000000 --- a/log_filter.py +++ /dev/null @@ -1,161 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -日志过滤器 -用于过滤不需要记录到文件的日志 -""" - -import re -from typing import Dict, Any - -class LogFilter: - """日志过滤器类""" - - def __init__(self): - # 不需要记录的API路径模式 - self.excluded_api_patterns = [ - r'GET /logs', - r'GET /logs/stats', - r'GET /health', - r'GET /docs', - r'GET /redoc', - r'GET /openapi\.json', - r'GET /static/', - r'GET /favicon\.ico' - ] - - # 不需要记录的消息模式 - self.excluded_message_patterns = [ - r'API请求: GET /logs', - r'API响应: GET /logs', - r'API请求: GET /health', - r'API响应: GET /health', - r'API请求: GET /docs', - r'API响应: GET /docs', - r'API请求: GET /static/', - r'API响应: GET /static/', - r'.*favicon\.ico.*', - r'.*websocket.*ping.*', - r'.*websocket.*pong.*' - ] - - # 编译正则表达式以提高性能 - self.compiled_api_patterns = [re.compile(pattern, re.IGNORECASE) for pattern in self.excluded_api_patterns] - self.compiled_message_patterns = [re.compile(pattern, re.IGNORECASE) for pattern in self.excluded_message_patterns] - - def should_log(self, record: Dict[str, Any]) -> bool: - """ - 判断是否应该记录这条日志 - - Args: - record: loguru的日志记录字典 - - Returns: - bool: True表示应该记录,False表示应该过滤掉 - """ - try: - message = record.get('message', '') - - # 检查消息模式 - for pattern in self.compiled_message_patterns: - if pattern.search(message): - return False - - # 检查API路径模式 - for pattern in self.compiled_api_patterns: - if pattern.search(message): - return False - - # 过滤掉过于频繁的心跳日志 - if any(keyword in message.lower() for keyword in ['heartbeat', '心跳', 'ping', 'pong']): - return False - - # 过滤掉WebSocket连接状态的频繁日志 - if any(keyword in message.lower() for keyword in ['websocket connected', 'websocket disconnected']): - # 只记录连接和断开,不记录频繁的状态检查 - if 'status check' in message.lower(): - return False - - return True - - except Exception: - # 如果过滤器出错,默认记录日志 - return True - -# 全局日志过滤器实例 -log_filter = LogFilter() - -def filter_log_record(record): - """ - loguru的过滤器函数 - - Args: - record: loguru的日志记录对象 - - Returns: - bool: True表示应该记录,False表示应该过滤掉 - """ - return log_filter.should_log(record) - -def add_excluded_pattern(pattern: str): - """ - 添加新的排除模式 - - Args: - pattern: 正则表达式模式 - """ - log_filter.excluded_message_patterns.append(pattern) - log_filter.compiled_message_patterns.append(re.compile(pattern, re.IGNORECASE)) - -def remove_excluded_pattern(pattern: str): - """ - 移除排除模式 - - Args: - pattern: 要移除的正则表达式模式 - """ - if pattern in log_filter.excluded_message_patterns: - index = log_filter.excluded_message_patterns.index(pattern) - log_filter.excluded_message_patterns.pop(index) - log_filter.compiled_message_patterns.pop(index) - -def get_excluded_patterns(): - """ - 获取当前的排除模式列表 - - Returns: - list: 排除模式列表 - """ - return log_filter.excluded_message_patterns.copy() - -# 测试函数 -def test_filter(): - """测试过滤器功能""" - test_messages = [ - "🌐 API请求: GET /logs?lines=200", - "✅ API响应: GET /logs - 200 (0.123s)", - "🌐 API请求: GET /health", - "✅ API响应: GET /health - 200 (0.001s)", - "🌐 API请求: POST /cookies", - "✅ API响应: POST /cookies - 201 (0.456s)", - "WebSocket心跳检查", - "用户登录成功", - "数据库连接建立", - "WebSocket connected status check", - "处理消息: 你好" - ] - - print("🧪 测试日志过滤器") - print("=" * 50) - - for message in test_messages: - record = {"message": message} - should_log = log_filter.should_log(record) - status = "✅ 记录" if should_log else "❌ 过滤" - print(f"{status}: {message}") - - print("=" * 50) - print("测试完成") - -if __name__ == "__main__": - test_filter() diff --git a/quick-fix-permissions.bat b/quick-fix-permissions.bat new file mode 100644 index 0000000..762e0e5 --- /dev/null +++ b/quick-fix-permissions.bat @@ -0,0 +1,116 @@ +@echo off +chcp 65001 >nul +setlocal enabledelayedexpansion + +:: 快速修复Docker权限问题 (Windows版本) + +title 快速修复Docker权限问题 + +:: 颜色定义 +set "RED=[91m" +set "GREEN=[92m" +set "YELLOW=[93m" +set "BLUE=[94m" +set "NC=[0m" + +:print_info +echo %BLUE%[INFO]%NC% %~1 +goto :eof + +:print_success +echo %GREEN%[SUCCESS]%NC% %~1 +goto :eof + +:print_error +echo %RED%[ERROR]%NC% %~1 +goto :eof + +echo 🚀 快速修复Docker权限问题 +echo ================================ +echo. + +:: 1. 停止容器 +call :print_info "停止现有容器..." +docker-compose down >nul 2>&1 + +:: 2. 确保目录存在 +call :print_info "创建必要目录..." +if not exist "data" mkdir data +if not exist "logs" mkdir logs +if not exist "backups" mkdir backups + +:: 3. 检查并修复docker-compose.yml +call :print_info "检查docker-compose.yml配置..." +findstr /C:"user.*0:0" docker-compose.yml >nul 2>&1 +if !errorlevel! neq 0 ( + call :print_info "添加root用户配置..." + + REM 备份原文件 + copy docker-compose.yml docker-compose.yml.backup >nul + + REM 创建临时文件添加user配置 + ( + for /f "tokens=*" %%a in (docker-compose.yml) do ( + echo %%a + echo %%a | findstr /C:"container_name: xianyu-auto-reply" >nul + if !errorlevel! equ 0 ( + echo user: "0:0" + ) + ) + ) > docker-compose.yml.tmp + + REM 替换原文件 + move docker-compose.yml.tmp docker-compose.yml >nul + + call :print_success "已配置使用root用户运行" +) + +:: 4. 重新构建镜像 +call :print_info "重新构建Docker镜像..." +docker-compose build --no-cache +if !errorlevel! neq 0 ( + call :print_error "Docker镜像构建失败" + pause + exit /b 1 +) + +:: 5. 启动服务 +call :print_info "启动服务..." +docker-compose up -d +if !errorlevel! neq 0 ( + call :print_error "服务启动失败" + pause + exit /b 1 +) + +:: 6. 等待启动 +call :print_info "等待服务启动..." +timeout /t 15 /nobreak >nul + +:: 7. 检查状态 +call :print_info "检查服务状态..." +docker-compose ps | findstr "Up" >nul +if !errorlevel! equ 0 ( + call :print_success "✅ 服务启动成功!" + + echo. + call :print_info "最近的日志:" + docker-compose logs --tail=10 xianyu-app + + echo. + call :print_success "🎉 权限问题已修复!" + echo. + echo 访问信息: + echo Web界面: http://localhost:8080 + echo 健康检查: http://localhost:8080/health + echo 默认账号: admin / admin123 + +) else ( + call :print_error "❌ 服务启动失败" + echo. + call :print_info "错误日志:" + docker-compose logs xianyu-app +) + +echo. +pause diff --git a/quick-fix-permissions.sh b/quick-fix-permissions.sh new file mode 100644 index 0000000..fbe55de --- /dev/null +++ b/quick-fix-permissions.sh @@ -0,0 +1,88 @@ +#!/bin/bash + +# 快速修复Docker权限问题 +# 这个脚本会立即解决权限问题并重启服务 + +set -e + +# 颜色定义 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +print_info() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +print_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +print_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +echo "🚀 快速修复Docker权限问题" +echo "================================" + +# 1. 停止容器 +print_info "停止现有容器..." +docker-compose down + +# 2. 确保目录存在并设置权限 +print_info "设置目录权限..." +mkdir -p data logs backups +chmod 777 data logs backups + +# 3. 检查并修复docker-compose.yml +print_info "检查docker-compose.yml配置..." +if ! grep -q "user.*0:0" docker-compose.yml; then + print_info "添加root用户配置..." + + # 备份原文件 + cp docker-compose.yml docker-compose.yml.backup + + # 在container_name后添加user配置 + sed -i '/container_name: xianyu-auto-reply/a\ user: "0:0"' docker-compose.yml + + print_success "已配置使用root用户运行" +fi + +# 4. 重新构建镜像 +print_info "重新构建Docker镜像..." +docker-compose build --no-cache + +# 5. 启动服务 +print_info "启动服务..." +docker-compose up -d + +# 6. 等待启动 +print_info "等待服务启动..." +sleep 15 + +# 7. 检查状态 +print_info "检查服务状态..." +if docker-compose ps | grep -q "Up"; then + print_success "✅ 服务启动成功!" + + # 显示日志 + echo "" + print_info "最近的日志:" + docker-compose logs --tail=10 xianyu-app + + echo "" + print_success "🎉 权限问题已修复!" + echo "" + echo "访问信息:" + echo " Web界面: http://localhost:8080" + echo " 健康检查: http://localhost:8080/health" + echo " 默认账号: admin / admin123" + +else + print_error "❌ 服务启动失败" + echo "" + print_info "错误日志:" + docker-compose logs xianyu-app +fi diff --git a/reply_server.py b/reply_server.py index 44f9d90..c3a8dd3 100644 --- a/reply_server.py +++ b/reply_server.py @@ -157,84 +157,23 @@ app = FastAPI( redoc_url="/redoc" ) -# 配置统一的日志系统 -import time -from loguru import logger - -# 确保日志目录存在 -log_dir = 'logs' -os.makedirs(log_dir, exist_ok=True) -log_path = os.path.join(log_dir, f"xianyu_{time.strftime('%Y-%m-%d')}.log") - -# 移除默认的日志处理器 -logger.remove() - -# 导入日志过滤器 -try: - from log_filter import filter_log_record -except ImportError: - # 如果过滤器不可用,使用默认过滤器 - def filter_log_record(record): - return True - -# 添加文件日志处理器,使用与XianyuAutoAsync相同的格式,并应用过滤器 -logger.add( - log_path, - rotation="1 day", - retention="7 days", - compression="zip", - level="INFO", - format='{time:YYYY-MM-DD HH:mm:ss.SSS} | {level} | {name}:{function}:{line} - {message}', - encoding='utf-8', - enqueue=False, # 立即写入 - buffering=1, # 行缓冲 - filter=filter_log_record # 应用日志过滤器 -) - # 初始化文件日志收集器 setup_file_logging() # 添加一条测试日志 -logger.info("Web服务器启动,统一日志系统已初始化") - -# 不需要记录到文件的API路径 -EXCLUDED_LOG_PATHS = { - '/logs', - '/logs/stats', - '/logs/clear', - '/health', - '/docs', - '/redoc', - '/openapi.json', - '/favicon.ico' -} - -# 不需要记录的路径前缀 -EXCLUDED_LOG_PREFIXES = { - '/static/', - '/docs', - '/redoc' -} +from loguru import logger +logger.info("Web服务器启动,文件日志收集器已初始化") # 添加请求日志中间件 @app.middleware("http") async def log_requests(request, call_next): start_time = time.time() - - # 检查是否需要记录日志 - should_log = ( - request.url.path not in EXCLUDED_LOG_PATHS and - not any(request.url.path.startswith(prefix) for prefix in EXCLUDED_LOG_PREFIXES) - ) - - if should_log: - logger.info(f"🌐 API请求: {request.method} {request.url.path}") + logger.info(f"🌐 API请求: {request.method} {request.url.path}") response = await call_next(request) - if should_log: - process_time = time.time() - start_time - logger.info(f"✅ API响应: {request.method} {request.url.path} - {response.status_code} ({process_time:.3f}s)") + process_time = time.time() - start_time + logger.info(f"✅ API响应: {request.method} {request.url.path} - {response.status_code} ({process_time:.3f}s)") return response @@ -1008,6 +947,15 @@ def import_backup(file: UploadFile = File(...), _: None = Depends(require_auth)) success = db_manager.import_backup(backup_data) if success: + # 备份导入成功后,刷新 CookieManager 的内存缓存 + import cookie_manager + if cookie_manager.manager: + try: + cookie_manager.manager.reload_from_db() + logger.info("备份导入后已刷新 CookieManager 缓存") + except Exception as e: + logger.error(f"刷新 CookieManager 缓存失败: {e}") + return {"message": "备份导入成功"} else: raise HTTPException(status_code=400, detail="备份导入失败") @@ -1018,6 +966,23 @@ def import_backup(file: UploadFile = File(...), _: None = Depends(require_auth)) raise HTTPException(status_code=500, detail=f"导入备份失败: {str(e)}") +@app.post("/system/reload-cache") +def reload_cache(_: None = Depends(require_auth)): + """重新加载系统缓存(用于手动刷新数据)""" + try: + import cookie_manager + if cookie_manager.manager: + success = cookie_manager.manager.reload_from_db() + if success: + return {"message": "系统缓存已刷新", "success": True} + else: + raise HTTPException(status_code=500, detail="缓存刷新失败") + else: + raise HTTPException(status_code=500, detail="CookieManager 未初始化") + except Exception as e: + raise HTTPException(status_code=500, detail=f"刷新缓存失败: {str(e)}") + + # ==================== 商品管理 API ==================== @app.get("/items") @@ -1302,9 +1267,9 @@ async def get_all_items_from_account(request: dict, _: None = Depends(require_au from XianyuAutoAsync import XianyuLive xianyu_instance = XianyuLive(cookies_str, cookie_id) - # 调用获取商品信息的方法 + # 调用获取所有商品信息的方法(自动分页) logger.info(f"开始获取账号 {cookie_id} 的所有商品信息") - result = await xianyu_instance.get_item_list_info() + result = await xianyu_instance.get_all_items() # 关闭session await xianyu_instance.close_session() @@ -1313,11 +1278,78 @@ async def get_all_items_from_account(request: dict, _: None = Depends(require_au logger.error(f"获取商品信息失败: {result['error']}") return {"success": False, "message": result['error']} else: - logger.info(f"成功获取账号 {cookie_id} 的 {result.get('total_count', 0)} 个商品") + total_count = result.get('total_count', 0) + total_pages = result.get('total_pages', 1) + logger.info(f"成功获取账号 {cookie_id} 的 {total_count} 个商品(共{total_pages}页)") return { "success": True, - "message": f"成功获取 {result.get('total_count', 0)} 个商品,详细信息已打印到控制台", - "total_count": result.get('total_count', 0) + "message": f"成功获取 {total_count} 个商品(共{total_pages}页),详细信息已打印到控制台", + "total_count": total_count, + "total_pages": total_pages + } + + except Exception as e: + logger.error(f"获取账号商品信息异常: {str(e)}") + return {"success": False, "message": f"获取商品信息异常: {str(e)}"} + + +@app.post("/items/get-by-page") +async def get_items_by_page(request: dict, _: None = Depends(require_auth)): + """从指定账号按页获取商品信息""" + try: + # 验证参数 + cookie_id = request.get('cookie_id') + page_number = request.get('page_number', 1) + page_size = request.get('page_size', 20) + + if not cookie_id: + return {"success": False, "message": "缺少cookie_id参数"} + + # 验证分页参数 + try: + page_number = int(page_number) + page_size = int(page_size) + except (ValueError, TypeError): + return {"success": False, "message": "页码和每页数量必须是数字"} + + if page_number < 1: + return {"success": False, "message": "页码必须大于0"} + + if page_size < 1 or page_size > 100: + return {"success": False, "message": "每页数量必须在1-100之间"} + + # 获取账号信息 + account = db_manager.get_cookie_by_id(cookie_id) + if not account: + return {"success": False, "message": "账号不存在"} + + cookies_str = account['cookies_str'] + if not cookies_str: + return {"success": False, "message": "账号cookies为空"} + + # 创建XianyuLive实例,传入正确的cookie_id + from XianyuAutoAsync import XianyuLive + xianyu_instance = XianyuLive(cookies_str, cookie_id) + + # 调用获取指定页商品信息的方法 + logger.info(f"开始获取账号 {cookie_id} 第{page_number}页商品信息(每页{page_size}条)") + result = await xianyu_instance.get_item_list_info(page_number, page_size) + + # 关闭session + await xianyu_instance.close_session() + + if result.get('error'): + logger.error(f"获取商品信息失败: {result['error']}") + return {"success": False, "message": result['error']} + else: + current_count = result.get('current_count', 0) + logger.info(f"成功获取账号 {cookie_id} 第{page_number}页 {current_count} 个商品") + return { + "success": True, + "message": f"成功获取第{page_number}页 {current_count} 个商品,详细信息已打印到控制台", + "page_number": page_number, + "page_size": page_size, + "current_count": current_count } except Exception as e: diff --git a/static/index.html b/static/index.html index 61e9311..1e69091 100644 --- a/static/index.html +++ b/static/index.html @@ -4,8 +4,8 @@ 闲鱼自动回复管理系统 - - + + + + +
+

账号状态显示测试

+ +
+

修改前 vs 修改后对比

+ +
+
+
修改前(带文字)
+
+ + + + 启用 + +
+ +
+ + + + 禁用 + +
+
+ +
+
修改后(仅图标)
+
+ + + + +
+ +
+ + + + +
+
+
+
+ +
+

表格中的效果预览

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
账号ID状态默认回复AI回复操作
测试账号001 +
+ + + + +
+
启用AI启用 + +
测试账号002 +
+ + + + +
+
禁用AI禁用 + +
+
+ +
+

优势说明

+
+
+
✅ 修改后的优势
+
    +
  • ✓ 界面更简洁
  • +
  • ✓ 节省空间
  • +
  • ✓ 图标直观易懂
  • +
  • ✓ 视觉焦点更集中
  • +
  • ✓ 现代化设计风格
  • +
+
+
+
🎨 设计细节
+
    +
  • • 图标居中对齐
  • +
  • • 徽章尺寸优化
  • +
  • • 颜色保持一致
  • +
  • • 响应式设计
  • +
  • • 无障碍访问友好
  • +
+
+
+
+ +
+
说明
+

+ 状态栏现在只显示图标,不显示"启用"/"禁用"文字。 + 绿色勾号表示启用状态,红色叉号表示禁用状态。 + 鼠标悬停时可以显示提示信息。 +

+
+
+ + + + + diff --git a/使用说明.md b/使用说明.md index 826ef11..008c929 100644 --- a/使用说明.md +++ b/使用说明.md @@ -70,14 +70,7 @@ python Start.py - **精确匹配**:支持关键词精确匹配 - **变量替换**:回复内容支持动态变量 - **优先级**:账号级关键词优先于全局关键词 -- **智能回复优先级**:关键词回复 → AI回复 → 默认回复 - -### 回复优先级说明 -系统按以下优先级处理回复: -1. **🔥 API回复** - 外部API接口回复(最高优先级) -2. **📝 关键词回复** - 精确关键词匹配回复 -3. **🤖 AI智能回复** - AI模型生成的智能回复 -4. **💬 默认回复** - 兜底的默认回复内容 +- **默认回复**:未匹配关键词时使用默认回复 ### API接口 - **接口地址**:`POST http://localhost:8080/xianyu/reply` @@ -159,133 +152,27 @@ python Start.py - 备份 `global_config.yml` 配置文件 - 备份自定义的关键词文件 -## 🔧 高级功能 - -### AI回复配置 -1. 在账号列表中点击"🤖 配置AI回复" -2. 开启AI回复功能 -3. 配置API密钥和模型参数 -4. 设置议价策略和优惠限制 -5. 自定义提示词(可选) - -### 自动发货设置 -1. 进入"自动发货"页面 -2. 添加发货规则和关键词匹配 -3. 上传卡券文件或手动添加卡券 -4. 配置发货模板和通知方式 - -### 商品管理 -1. 进入"商品管理"页面 -2. 查看自动收集的商品信息 -3. 编辑商品详情和分类 -4. 批量获取账号下所有商品 - -### 日志监控 -1. 进入"日志管理"页面 -2. 实时查看系统运行日志 -3. 按级别和来源筛选日志 -4. 查看系统统计信息 - -## 📊 数据管理 - -### 数据备份 -1. 进入"系统设置"页面 -2. 点击"导出备份"按钮 -3. 下载备份文件到本地 -4. 定期备份重要数据 - -### 数据恢复 -1. 进入"系统设置"页面 -2. 点击"导入备份"按钮 -3. 选择备份文件上传 -4. 确认恢复操作 - -### 数据清理 -- 定期清理过期日志文件 -- 删除无效的商品信息 -- 清理过期的对话记录 - ## 📞 技术支持 -### 系统健康检查 -访问健康检查端点: -``` -http://localhost:8080/health -``` - -### 查看系统状态 +### 测试系统 +运行测试脚本检查系统状态: ```bash -# 查看容器状态 -docker-compose ps - -# 查看系统资源使用 -docker stats - -# 查看实时日志 -docker-compose logs -f +python test_system.py ``` -### 常见问题解决 +### 重新创建配置 +如果配置文件损坏,运行: +```bash +python create_config.py +``` -**问题1:Cookie失效** -- 重新获取Cookie并更新 -- 检查账号是否被限制 -- 确认Cookie格式正确 +## 🎯 使用建议 -**问题2:消息接收异常** -- 检查网络连接 -- 重启WebSocket连接 -- 查看错误日志 - -**问题3:AI回复失败** -- 检查API密钥是否正确 -- 确认API服务可用 -- 检查账户余额 - -## 🎯 最佳实践 - -### 安全建议 -1. **定期更换密码**:修改默认管理员密码 -2. **限制访问**:仅允许信任的IP访问 -3. **备份数据**:定期备份重要配置和数据 -4. **监控日志**:定期查看系统日志 - -### 性能优化 -1. **合理设置**:根据实际需求配置参数 -2. **定期清理**:清理过期数据和日志 -3. **监控资源**:关注系统资源使用情况 -4. **优化配置**:根据使用情况调整配置 - -### 使用技巧 1. **Cookie获取**:使用浏览器开发者工具获取完整Cookie 2. **关键词设置**:设置常用的咨询关键词和回复 -3. **AI配置**:根据商品类型调整AI提示词 -4. **发货规则**:设置精确的商品匹配规则 - -## 🔄 系统更新 - -### 更新步骤 -1. 备份当前数据 -2. 停止系统服务 -3. 拉取最新代码 -4. 重新构建镜像 -5. 启动更新后的服务 - -### Docker更新 -```bash -# 停止服务 -docker-compose down - -# 拉取最新代码 -git pull - -# 重新构建 -./deploy.sh --update - -# 检查状态 -docker-compose ps -``` +3. **定期检查**:定期查看日志确保系统正常运行 +4. **备份数据**:重要数据请及时备份 --- -**注意**:本系统仅供学习交流使用,请遵守相关法律法规和平台规则。使用前请仔细阅读相关文档,确保正确配置和使用。 +**注意**:本系统仅供学习交流使用,请遵守相关法律法规和平台规则。 diff --git a/商品管理功能说明.md b/商品管理功能说明.md index 8b2614c..9ece907 100644 --- a/商品管理功能说明.md +++ b/商品管理功能说明.md @@ -194,62 +194,6 @@ Authorization: Bearer {token} - 监控自动发货匹配情况 - 及时处理异常情况 -## 🔧 故障排除 - -### 常见问题及解决方案 - -**问题1:商品信息收集失败** -- 检查网络连接是否正常 -- 确认Cookie是否有效 -- 验证商品ID格式是否正确 -- 查看详细错误日志 - -**问题2:商品详情获取失败** -- 检查API服务是否可用 -- 确认商品是否存在 -- 验证请求参数是否正确 -- 检查API配置 - -**问题3:数据库操作失败** -- 检查数据库文件权限 -- 确认磁盘空间是否充足 -- 验证数据格式是否正确 -- 查看数据库错误日志 - -### 性能优化建议 -1. **定期清理**:清理无效的商品信息 -2. **索引优化**:为常用查询字段建立索引 -3. **批量操作**:使用批量操作提高效率 -4. **缓存机制**:缓存常用的商品信息 - -## 📊 数据统计 - -### 商品统计信息 -- **总商品数量**:系统中所有商品的总数 -- **有效商品数**:包含完整信息的商品数量 -- **账号分布**:各账号的商品数量分布 -- **分类统计**:不同分类的商品数量 - -### 使用统计 -- **收集成功率**:商品信息收集的成功率 -- **API调用次数**:商品详情API的调用统计 -- **匹配成功率**:自动发货匹配的成功率 -- **处理速度**:商品信息处理的平均速度 - -## 🚀 未来规划 - -### 即将推出的功能 -1. **商品分析**:基于商品数据的深度分析 -2. **价格监控**:监控商品价格变化趋势 -3. **库存管理**:集成库存管理功能 -4. **销量统计**:统计商品销售数据 - -### 长期发展方向 -1. **智能推荐**:基于商品数据的智能推荐 -2. **自动定价**:根据市场数据自动调整价格 -3. **竞品分析**:分析同类商品的竞争情况 -4. **数据挖掘**:深度挖掘商品数据价值 - --- -🎉 **商品管理功能为您的闲鱼自动发货提供了强大的数据支持,让自动化运营更加智能和精准!通过持续优化和功能扩展,将为您带来更好的使用体验。** +🎉 **商品管理功能让您的闲鱼自动发货更加智能和准确!** diff --git a/回复优先级优化说明.md b/回复优先级优化说明.md deleted file mode 100644 index 1258b70..0000000 --- a/回复优先级优化说明.md +++ /dev/null @@ -1,147 +0,0 @@ -# 🔄 回复优先级优化说明 - -## 📋 优化概述 - -本次更新对自动回复系统的优先级逻辑进行了重要调整,确保关键词回复优先于AI回复,提高回复的准确性和用户体验。 - -## 🔧 优化内容 - -### 原有逻辑(v2.0.0之前) -``` -API回复 → AI回复 → 关键词回复 → 默认回复 -``` - -**问题**: -- AI回复可能覆盖重要的关键词回复 -- 精确的关键词匹配被AI的通用回复替代 -- 用户设置的关键词回复优先级过低 - -### 新的逻辑(v2.0.1) -``` -API回复 → 关键词回复 → AI回复 → 默认回复 -``` - -**优势**: -- ✅ 关键词回复优先级提升,确保精确匹配 -- ✅ AI回复作为智能补充,处理无关键词匹配的情况 -- ✅ 保持API回复的最高优先级 -- ✅ 默认回复作为最后的兜底方案 - -## 🎯 使用场景 - -### 场景1:价格咨询 -**用户消息**:`"请问这个商品的价格是多少?"` - -**处理流程**: -1. 检查API回复 → 无 -2. 检查关键词匹配 → 匹配"价格"关键词 ✅ -3. 返回:`"这个商品价格是100元"` - -**结果**:精确的价格信息,而不是AI的通用回复 - -### 场景2:通用咨询 -**用户消息**:`"这个东西怎么样?质量好吗?"` - -**处理流程**: -1. 检查API回复 → 无 -2. 检查关键词匹配 → 无匹配 -3. 使用AI回复 ✅ -4. 返回:`"AI智能回复:根据您的问题,我建议..."` - -**结果**:AI提供智能化的个性回复 - -### 场景3:兜底回复 -**用户消息**:`"随便说点什么"` - -**处理流程**: -1. 检查API回复 → 无 -2. 检查关键词匹配 → 无匹配 -3. 检查AI回复 → 失败或未启用 -4. 使用默认回复 ✅ -5. 返回:`"您好,感谢咨询!"` - -**结果**:确保总是有回复内容 - -## 📊 优化效果 - -### 回复准确性提升 -- **关键词匹配率**:100%(优先级最高) -- **重要信息覆盖**:避免AI回复覆盖重要关键词 -- **用户体验**:精确回复 + 智能补充 - -### 系统稳定性 -- **回复成功率**:保持100%(多层备选机制) -- **响应速度**:关键词匹配更快 -- **资源使用**:减少不必要的AI调用 - -## 🔧 技术实现 - -### 代码修改位置 -**文件**:`XianyuAutoAsync.py` -**行数**:1821-1835 - -### 修改前代码 -```python -# 如果API回复失败或未启用API,尝试使用AI回复 -if not reply: - reply = await self.get_ai_reply(send_user_name, send_user_id, send_message, item_id, chat_id) - if reply: - reply_source = 'AI' - else: - # 如果AI回复也失败,尝试关键词匹配 - reply = await self.get_keyword_reply(send_user_name, send_user_id, send_message) - if reply: - reply_source = '关键词' - else: - # 最后尝试使用默认回复 - reply = await self.get_default_reply(send_user_name, send_user_id, send_message) - reply_source = '默认' -``` - -### 修改后代码 -```python -# 如果API回复失败或未启用API,按优先级尝试其他回复方式 -if not reply: - # 优先尝试关键词匹配回复 - reply = await self.get_keyword_reply(send_user_name, send_user_id, send_message) - if reply: - reply_source = '关键词' - else: - # 如果关键词匹配失败,尝试AI回复 - reply = await self.get_ai_reply(send_user_name, send_user_id, send_message, item_id, chat_id) - if reply: - reply_source = 'AI' - else: - # 最后尝试使用默认回复 - reply = await self.get_default_reply(send_user_name, send_user_id, send_message) - reply_source = '默认' -``` - -## 📚 相关文档更新 - -### 更新的文档 -1. **AI_REPLY_GUIDE.md** - 更新优先级说明 -2. **使用说明.md** - 添加回复优先级说明 -3. **README.md** - 更新功能特性描述 -4. **CHANGELOG.md** - 记录版本更新 - -### 新增说明 -- 关键词回复优先于AI回复的原因 -- 各种回复方式的适用场景 -- 优化后的用户体验改进 - -## 🎉 总结 - -这次优化确保了: -- **精确性**:重要关键词得到精确回复 -- **智能性**:AI回复作为智能补充 -- **稳定性**:多层备选确保回复成功 -- **用户体验**:更准确、更贴心的自动回复 - -通过合理的优先级设计,系统既保持了智能化特性,又确保了关键信息的准确传达,为用户提供更好的自动回复体验。 - ---- - -**版本**:v2.0.1 -**更新时间**:2024-07-24 -**影响范围**:自动回复逻辑核心功能 diff --git a/日志管理功能说明.md b/日志管理功能说明.md index 185aba3..5ed5981 100644 --- a/日志管理功能说明.md +++ b/日志管理功能说明.md @@ -280,91 +280,17 @@ ## 🎯 使用建议 ### 适用场景 -- ✅ **开发调试**:实时查看程序运行状态和调试信息 -- ✅ **问题排查**:快速定位错误和异常,分析问题原因 -- ✅ **性能监控**:监控系统运行情况和性能指标 -- ✅ **用户支持**:协助用户解决问题,提供技术支持 -- ✅ **运维监控**:生产环境的实时监控和告警 -- ✅ **安全审计**:监控系统安全事件和异常行为 +- ✅ **开发调试**:实时查看程序运行状态 +- ✅ **问题排查**:快速定位错误和异常 +- ✅ **性能监控**:监控系统运行情况 +- ✅ **用户支持**:协助用户解决问题 ### 最佳实践 -1. **开启自动刷新**:实时监控系统状态,及时发现问题 -2. **合理使用过滤器**:根据需要过滤特定级别或来源的日志 -3. **定期查看统计信息**:了解系统整体运行状况和趋势 -4. **适时清空内存日志**:避免内存占用过多,保持系统性能 -5. **结合文件日志**:重要日志同时查看文件日志进行备份 -6. **设置告警规则**:对ERROR级别日志设置告警通知 - -### 日志级别使用指南 -- **DEBUG**:详细的调试信息,开发阶段使用 -- **INFO**:一般信息,记录程序正常运行状态 -- **WARNING**:警告信息,需要注意但不影响运行 -- **ERROR**:错误信息,需要立即处理的问题 -- **CRITICAL**:严重错误,可能导致程序崩溃 - -## 🔧 高级功能 - -### 日志导出 -1. **实时导出**:将当前显示的日志导出为文件 -2. **批量导出**:导出指定时间范围的日志 -3. **格式选择**:支持TXT、JSON、CSV等格式 -4. **自动压缩**:大文件自动压缩处理 - -### 日志分析 -1. **趋势分析**:分析日志数量和级别的时间趋势 -2. **异常检测**:自动检测异常日志模式 -3. **性能分析**:分析系统性能相关日志 -4. **报表生成**:生成日志分析报表 - -### 告警配置 -1. **级别告警**:ERROR级别日志自动告警 -2. **频率告警**:异常日志频率过高时告警 -3. **关键词告警**:包含特定关键词的日志告警 -4. **通知方式**:支持邮件、短信、webhook等通知 - -## 🚨 故障排除 - -### 常见问题 -**Q: 日志不更新?** -A: 检查以下项目: -- 自动刷新是否开启 -- 网络连接是否正常 -- 服务器是否正常运行 -- 浏览器是否支持WebSocket - -**Q: 日志显示不完整?** -A: 可能原因: -- 内存缓冲区已满,旧日志被清理 -- 过滤器设置过于严格 -- 日志级别设置不当 - -**Q: 性能影响?** -A: 优化建议: -- 适当调整刷新频率 -- 使用过滤器减少显示数量 -- 定期清空内存日志 -- 关闭不必要的DEBUG日志 - -### 性能优化 -1. **合理设置缓冲区大小**:根据系统内存调整 -2. **优化刷新频率**:平衡实时性和性能 -3. **使用过滤器**:减少不必要的日志传输 -4. **定期清理**:避免内存泄漏 - -## 📊 监控指标 - -### 系统指标 -- **日志生成速率**:每秒生成的日志数量 -- **内存使用量**:日志缓冲区内存占用 -- **处理延迟**:日志从生成到显示的延迟 -- **错误率**:ERROR级别日志的比例 - -### 业务指标 -- **消息处理量**:处理的消息数量统计 -- **API调用次数**:各API接口的调用统计 -- **用户活动**:用户操作和访问统计 -- **系统健康度**:基于日志的系统健康评分 +1. **开启自动刷新**:实时监控系统状态 +2. **使用过滤器**:快速找到关注的日志 +3. **查看统计信息**:了解系统整体状况 +4. **定期清空**:避免内存占用过多 --- -🎉 **实时日志管理功能提供了完整的日志查看、分析和监控能力,是系统运维和问题排查的重要工具!** +🎉 **实时日志管理功能已完成,提供了真正的实时日志查看、过滤和分析能力!** diff --git a/日志系统优化说明.md b/日志系统优化说明.md deleted file mode 100644 index 774b4da..0000000 --- a/日志系统优化说明.md +++ /dev/null @@ -1,221 +0,0 @@ -# 📋 日志系统优化说明 - -## 🎯 优化目标 - -本次优化的主要目标是: -1. **统一日志记录**:所有日志都记录到文件中 -2. **界面读取文件**:Web界面从日志文件读取并显示 -3. **智能过滤**:过滤掉不必要的API请求日志 -4. **提高性能**:减少日志噪音,提高系统性能 - -## 🔧 优化内容 - -### 1. 统一日志配置 - -#### 修改前的问题 -- 不同模块的日志配置不一致 -- 部分日志只输出到控制台,不记录到文件 -- 日志格式不统一,难以解析 - -#### 修改后的改进 -- **统一日志文件**:所有模块都使用相同的日志文件 -- **统一格式**:使用标准格式便于解析 -- **文件优先**:移除控制台输出,只记录到文件 - -```python -# 统一的日志配置格式 -format='{time:YYYY-MM-DD HH:mm:ss.SSS} | {level} | {name}:{function}:{line} - {message}' -``` - -### 2. 智能日志过滤 - -#### 过滤的日志类型 -- **API请求日志**:`GET /logs`, `GET /health`, `GET /docs` 等 -- **静态资源请求**:`GET /static/`, `favicon.ico` 等 -- **心跳检查**:WebSocket心跳、健康检查等 -- **频繁状态检查**:连接状态检查等 - -#### 过滤器实现 -```python -# log_filter.py -class LogFilter: - def __init__(self): - self.excluded_patterns = [ - r'GET /logs', - r'GET /health', - r'.*favicon\.ico.*', - r'.*websocket.*ping.*' - ] - - def should_log(self, record): - # 智能判断是否应该记录日志 - return not self._matches_excluded_pattern(record['message']) -``` - -### 3. 文件监控优化 - -#### 监控改进 -- **实时监控**:从0.5秒优化到0.2秒检查频率 -- **错误处理**:增强文件读取的错误处理 -- **编码支持**:支持UTF-8编码,忽略编码错误 -- **文件重置检测**:检测日志文件被截断或重新创建 - -#### 解析优化 -- **多格式支持**:支持多种日志格式解析 -- **容错处理**:解析失败时的优雅降级 -- **性能优化**:预编译正则表达式提高解析速度 - -## 📊 优化效果 - -### 性能提升 -- **日志数量减少**:过滤掉约60%的无用日志 -- **文件大小减少**:日志文件大小减少约50% -- **界面响应更快**:减少不必要的日志传输 - -### 用户体验改善 -- **日志更清晰**:只显示有价值的日志信息 -- **加载更快**:减少日志数量,界面加载更快 -- **查找更容易**:减少噪音,更容易找到关键信息 - -### 系统稳定性 -- **内存使用优化**:减少内存中的日志缓存 -- **磁盘空间节省**:减少日志文件占用空间 -- **网络传输优化**:减少API传输的数据量 - -## 🔍 技术实现 - -### 1. 模块级配置 - -#### XianyuAutoAsync.py -```python -# 导入日志过滤器 -from log_filter import filter_log_record - -# 配置文件日志处理器 -logger.add( - log_path, - format='{time:YYYY-MM-DD HH:mm:ss.SSS} | {level} | {name}:{function}:{line} - {message}', - filter=filter_log_record # 应用过滤器 -) -``` - -#### reply_server.py -```python -# 排除不需要记录的API路径 -EXCLUDED_LOG_PATHS = { - '/logs', '/logs/stats', '/health', '/docs' -} - -# 中间件级别的过滤 -@app.middleware("http") -async def log_requests(request, call_next): - should_log = request.url.path not in EXCLUDED_LOG_PATHS - if should_log: - logger.info(f"API请求: {request.method} {request.url.path}") -``` - -### 2. 文件监控系统 - -#### FileLogCollector优化 -```python -def monitor_file(self): - while True: - if os.path.exists(self.log_file): - file_size = os.path.getsize(self.log_file) - if file_size > self.last_position: - # 读取新增内容 - with open(self.log_file, 'r', encoding='utf-8', errors='ignore') as f: - f.seek(self.last_position) - new_lines = f.readlines() - self.last_position = f.tell() - - # 解析新增日志 - for line in new_lines: - if line.strip(): - self.parse_log_line(line.strip()) - - time.sleep(0.2) # 更频繁的检查 -``` - -### 3. 日志解析增强 - -#### 多格式支持 -```python -def parse_log_line(self, line): - # 主格式:统一格式 - pattern = r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}) \| (\w+) \| ([^:]+):([^:]+):(\d+) - (.*)' - - # 备用格式:简单格式 - simple_pattern = r'\[([^\]]+)\] \[(\w+)\] (.*)' - - # 容错处理:解析失败时的处理 - if not match: - # 作为普通消息处理 - log_entry = { - "timestamp": datetime.now().isoformat(), - "level": "INFO", - "source": "system", - "message": line.strip() - } -``` - -## 📈 使用指南 - -### 1. 查看日志 -- **Web界面**:访问 http://localhost:8080,点击"日志管理" -- **实时更新**:日志会实时显示,无需手动刷新 -- **过滤功能**:可按级别、来源、关键词过滤 - -### 2. 日志文件位置 -``` -logs/ -└── xianyu_2024-07-24.log # 按日期命名的日志文件 -``` - -### 3. 自定义过滤规则 -```python -# 添加新的过滤规则 -from log_filter import add_excluded_pattern -add_excluded_pattern(r'自定义过滤模式') - -# 查看当前过滤规则 -from log_filter import get_excluded_patterns -patterns = get_excluded_patterns() -``` - -## 🚨 注意事项 - -### 1. 日志文件管理 -- **自动轮转**:日志文件按天轮转,自动压缩 -- **保留期限**:默认保留7天的日志文件 -- **磁盘空间**:注意监控磁盘空间使用情况 - -### 2. 性能考虑 -- **过滤器性能**:过滤器使用预编译正则表达式,性能较好 -- **文件监控**:监控频率为0.2秒,平衡实时性和性能 -- **内存使用**:日志缓存限制为2000条,避免内存溢出 - -### 3. 故障排除 -- **日志不显示**:检查日志文件是否存在和权限 -- **过滤过度**:检查过滤规则是否过于严格 -- **性能问题**:可以调整监控频率和缓存大小 - -## 🔮 未来规划 - -### 即将推出 -1. **日志分析**:基于日志的系统分析和报告 -2. **告警系统**:基于日志的智能告警 -3. **日志搜索**:全文搜索和高级查询 -4. **性能监控**:基于日志的性能指标 - -### 长期规划 -1. **分布式日志**:支持多实例的日志聚合 -2. **日志可视化**:图表和仪表板展示 -3. **机器学习**:基于日志的异常检测 -4. **API开放**:提供日志查询API - ---- - -**版本**:v2.0.2 -**更新时间**:2024-07-24 -**影响范围**:日志系统核心功能 diff --git a/自动发货功能说明.md b/自动发货功能说明.md index f48c3ad..059cdcb 100644 --- a/自动发货功能说明.md +++ b/自动发货功能说明.md @@ -254,92 +254,12 @@ python test-item-info-delivery.py ## 💡 最佳实践 -### 规则设计原则 -1. **关键字精确性**:关键字要具体明确,避免过于宽泛 -2. **优先级设置**:重要商品设置更长的关键字,提高匹配优先级 -3. **分类管理**:按商品类型分组管理发货规则 -4. **定期更新**:根据商品变化及时更新匹配规则 - -### 库存管理策略 -1. **实时监控**:定期检查批量数据库存状态 -2. **预警机制**:设置库存低于阈值时的告警 -3. **自动补充**:配置自动补充机制或定期手动补充 -4. **分批管理**:将卡券分批次管理,避免一次性消耗完 - -### 质量控制措施 -1. **测试验证**:新规则上线前在测试环境充分测试 -2. **灰度发布**:新规则先在部分商品上试运行 -3. **监控告警**:设置发货失败率告警,及时处理异常 -4. **人工审核**:重要商品可设置人工审核环节 - -### 数据分析优化 -1. **日志分析**:定期分析发货日志,识别问题模式 -2. **成功率统计**:监控各规则的匹配成功率 -3. **用户反馈**:收集买家反馈,优化发货内容 -4. **性能监控**:监控发货响应时间,优化处理流程 - -## 🔧 故障排除 - -### 常见问题及解决方案 - -**问题1:发货规则不匹配** -- 检查关键字是否正确 -- 确认商品信息是否完整 -- 验证匹配逻辑是否合理 -- 查看详细的匹配日志 - -**问题2:API接口调用失败** -- 检查API地址是否正确 -- 验证请求参数和格式 -- 确认网络连接状态 -- 查看API服务状态 - -**问题3:批量数据消耗过快** -- 检查匹配规则是否过于宽泛 -- 确认是否有重复发货 -- 调整匹配策略 -- 增加库存补充频率 - -**问题4:发货消息发送失败** -- 检查账号连接状态 -- 验证消息格式是否正确 -- 确认网络连接稳定 -- 查看WebSocket连接日志 - -### 调试技巧 -1. **开启详细日志**:在配置中开启DEBUG级别日志 -2. **单步测试**:使用测试功能验证单个规则 -3. **模拟环境**:在测试环境模拟真实场景 -4. **监控面板**:使用系统监控面板查看实时状态 - -## 📈 性能优化 - -### 系统性能优化 -1. **缓存机制**:缓存商品信息,减少API调用 -2. **异步处理**:使用异步处理提高并发能力 -3. **连接池**:优化数据库连接池配置 -4. **资源限制**:合理设置系统资源限制 - -### 业务流程优化 -1. **规则优化**:优化匹配算法,提高匹配效率 -2. **批量处理**:支持批量发货操作 -3. **智能调度**:根据系统负载智能调度任务 -4. **预处理**:预处理商品信息,提高匹配速度 - -## 🔐 安全考虑 - -### 数据安全 -1. **敏感信息加密**:卡券内容加密存储 -2. **访问控制**:严格的权限控制机制 -3. **审计日志**:完整的操作审计日志 -4. **备份恢复**:定期备份重要数据 - -### 业务安全 -1. **防重复发货**:严格的重复发货检测 -2. **异常监控**:实时监控异常发货行为 -3. **人工干预**:支持紧急情况下的人工干预 -4. **风险控制**:设置发货频率和数量限制 +1. **规则设计**:关键字要具体明确,避免过于宽泛 +2. **库存管理**:定期检查批量数据库存,及时补充 +3. **监控告警**:设置发货失败告警,及时处理异常 +4. **测试验证**:新规则上线前充分测试 +5. **日志分析**:定期分析发货日志,优化匹配规则 --- -🎉 **自动发货功能让您的闲鱼店铺实现真正的自动化运营!通过合理配置和优化,可以大大提高运营效率和用户体验。** +🎉 **自动发货功能让您的闲鱼店铺实现真正的自动化运营!** diff --git a/获取所有商品功能说明.md b/获取所有商品功能说明.md index ecf4dce..ca70f87 100644 --- a/获取所有商品功能说明.md +++ b/获取所有商品功能说明.md @@ -181,120 +181,22 @@ async def get_item_list_info(self, retry_count=0): - 错误信息记录 - 便于问题排查 -## 🚀 高级功能 +## 🚀 扩展可能 ### 1. 批量操作 -- **多账号批量获取**:一次性获取所有账号的商品信息 -- **定时自动获取**:设置定时任务自动更新商品信息 -- **增量更新**:只获取新增或变更的商品信息 -- **并发处理**:支持多账号并发获取,提高效率 +- 支持多个账号批量获取 +- 导出商品信息到文件 +- 商品信息对比分析 -### 2. 数据处理与分析 -- **商品信息入库**:自动将获取的商品信息存储到数据库 -- **商品状态监控**:监控商品上下架状态变化 -- **价格变化追踪**:跟踪商品价格变化趋势 -- **销量统计**:统计商品浏览量和销售数据 -- **数据导出**:支持导出为Excel、CSV等格式 +### 2. 数据处理 +- 商品信息入库存储 +- 商品状态监控 +- 价格变化追踪 ### 3. 界面优化 -- **商品信息表格**:以表格形式展示商品详细信息 -- **商品图片预览**:显示商品主图和详情图 -- **高级筛选**:按价格、分类、状态等条件筛选 -- **搜索功能**:支持商品标题、描述的全文搜索 -- **排序功能**:按时间、价格、浏览量等排序 - -### 4. 智能分析 -- **商品分类统计**:自动分析商品分类分布 -- **价格区间分析**:分析不同价格区间的商品数量 -- **热门商品识别**:基于浏览量识别热门商品 -- **库存预警**:监控商品库存状态,及时预警 - -## 📊 数据统计 - -### 获取统计信息 -- **总商品数量**:账号下所有商品的总数 -- **在售商品数**:当前在售状态的商品数量 -- **已售出商品数**:已售出的商品数量 -- **平均价格**:所有商品的平均售价 -- **价格分布**:不同价格区间的商品分布 - -### 性能指标 -- **获取速度**:每秒获取的商品数量 -- **成功率**:获取成功的商品比例 -- **错误率**:获取失败的商品比例 -- **响应时间**:API响应时间统计 - -## 🔧 故障排除 - -### 常见问题及解决方案 - -**问题1:获取失败** -- 检查账号Cookie是否有效 -- 确认网络连接是否正常 -- 验证账号是否被限制 -- 查看详细错误日志 - -**问题2:获取速度慢** -- 检查网络连接质量 -- 确认服务器负载情况 -- 优化获取策略 -- 考虑分批次获取 - -**问题3:数据不完整** -- 检查API返回数据格式 -- 确认商品状态是否正常 -- 验证解析逻辑是否正确 -- 查看控制台错误信息 - -**问题4:Token频繁失效** -- 检查Cookie有效期 -- 确认账号登录状态 -- 优化Token刷新策略 -- 考虑降低获取频率 - -### 调试技巧 -1. **开启详细日志**:查看完整的获取过程 -2. **单步测试**:先测试单个商品获取 -3. **网络监控**:监控网络请求和响应 -4. **数据验证**:验证获取数据的完整性 - -## 💡 使用建议 - -### 最佳实践 -1. **合理频率**:避免过于频繁的获取操作 -2. **错峰使用**:在网络较好的时段进行获取 -3. **数据备份**:定期备份重要的商品数据 -4. **监控告警**:设置获取失败的告警机制 - -### 性能优化 -1. **缓存机制**:缓存已获取的商品信息 -2. **增量更新**:只获取变更的商品信息 -3. **并发控制**:合理控制并发获取数量 -4. **资源管理**:及时释放不需要的资源 - -### 安全考虑 -1. **权限控制**:限制获取功能的使用权限 -2. **频率限制**:设置合理的获取频率限制 -3. **数据保护**:保护获取的商品数据安全 -4. **审计日志**:记录所有获取操作的审计日志 - -## 🔮 未来规划 - -### 即将推出的功能 -1. **商品同步**:支持与其他平台的商品信息同步 -2. **智能推荐**:基于商品数据的智能推荐算法 -3. **自动定价**:根据市场数据自动调整商品价格 -4. **竞品分析**:分析同类商品的价格和销量 - -### 长期发展方向 -1. **大数据分析**:基于海量商品数据的深度分析 -2. **机器学习**:使用AI技术优化商品运营策略 -3. **API开放**:提供开放API供第三方系统集成 -4. **移动端支持**:开发移动端应用,随时随地管理商品 - ---- - -🎉 **获取所有商品功能为商品管理提供了强大的数据获取能力,是商品分析和运营的重要工具!通过持续优化和功能扩展,将为用户提供更加完善的商品管理解决方案。** +- 商品信息表格显示 +- 商品图片预览 +- 筛选和搜索功能 ---