mirror of
https://github.com/zhinianboke/xianyu-auto-reply.git
synced 2025-08-01 12:07:36 +08:00
添加自动点击发货按钮
添加自动点击发货按钮
This commit is contained in:
parent
c7bcc72b98
commit
97dda678c8
@ -3,8 +3,9 @@ FROM python:3.11-slim
|
||||
|
||||
# 设置标签信息
|
||||
LABEL maintainer="Xianyu Auto Reply System"
|
||||
LABEL version="1.0.0"
|
||||
LABEL description="闲鱼自动回复系统 - Docker版本"
|
||||
LABEL version="2.0.0"
|
||||
LABEL description="闲鱼自动回复系统 - 企业级多用户版本"
|
||||
LABEL repository="https://github.com/zhinianboke/xianyu-auto-reply"
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
282
Docker快速启动指南.md
282
Docker快速启动指南.md
@ -1,282 +0,0 @@
|
||||
# Docker快速部署指南 - 多用户版本
|
||||
|
||||
## 🚀 一键部署
|
||||
|
||||
### 1. 克隆项目
|
||||
```bash
|
||||
git clone https://github.com/zhinianboke/xianyu-auto-reply.git
|
||||
cd xianyu-auto-reply
|
||||
```
|
||||
|
||||
### 2. 配置环境变量
|
||||
```bash
|
||||
# 复制环境变量模板
|
||||
cp .env.example .env
|
||||
|
||||
# 编辑配置文件(重要!)
|
||||
nano .env
|
||||
```
|
||||
|
||||
**必须修改的配置**:
|
||||
```bash
|
||||
# 修改管理员密码
|
||||
ADMIN_PASSWORD=your-secure-password
|
||||
|
||||
# 修改JWT密钥
|
||||
JWT_SECRET_KEY=your-very-long-and-random-secret-key
|
||||
|
||||
# 多用户功能配置
|
||||
MULTIUSER_ENABLED=true
|
||||
USER_REGISTRATION_ENABLED=true
|
||||
EMAIL_VERIFICATION_ENABLED=true
|
||||
CAPTCHA_ENABLED=true
|
||||
```
|
||||
|
||||
### 3. 启动服务
|
||||
```bash
|
||||
# 构建并启动
|
||||
docker-compose up -d --build
|
||||
|
||||
# 查看启动状态
|
||||
docker-compose ps
|
||||
|
||||
# 查看日志
|
||||
docker-compose logs -f
|
||||
```
|
||||
|
||||
### 4. 验证部署
|
||||
```bash
|
||||
# 健康检查
|
||||
curl http://localhost:8080/health
|
||||
|
||||
# 访问注册页面
|
||||
curl http://localhost:8080/register.html
|
||||
```
|
||||
|
||||
## 🎯 快速测试
|
||||
|
||||
### 访问地址
|
||||
- **主页**: http://localhost:8080
|
||||
- **登录页面**: http://localhost:8080/login.html
|
||||
- **注册页面**: http://localhost:8080/register.html
|
||||
|
||||
### 默认管理员账号
|
||||
- **用户名**: admin
|
||||
- **密码**: admin123(请立即修改)
|
||||
|
||||
### 测试多用户功能
|
||||
1. 访问注册页面
|
||||
2. 输入用户信息
|
||||
3. 验证图形验证码
|
||||
4. 接收邮箱验证码
|
||||
5. 完成注册
|
||||
6. 登录测试数据隔离
|
||||
|
||||
## 🔧 常用命令
|
||||
|
||||
### 服务管理
|
||||
```bash
|
||||
# 启动服务
|
||||
docker-compose up -d
|
||||
|
||||
# 停止服务
|
||||
docker-compose down
|
||||
|
||||
# 重启服务
|
||||
docker-compose restart
|
||||
|
||||
# 查看状态
|
||||
docker-compose ps
|
||||
|
||||
# 查看日志
|
||||
docker-compose logs -f
|
||||
|
||||
# 查看特定服务日志
|
||||
docker-compose logs -f xianyu-app
|
||||
```
|
||||
|
||||
### 数据管理
|
||||
```bash
|
||||
# 备份数据
|
||||
docker-compose exec xianyu-app cp /app/data/xianyu_data.db /app/data/backup_$(date +%Y%m%d_%H%M%S).db
|
||||
|
||||
# 进入容器
|
||||
docker-compose exec xianyu-app bash
|
||||
|
||||
# 查看数据目录
|
||||
docker-compose exec xianyu-app ls -la /app/data/
|
||||
```
|
||||
|
||||
### SQL日志调试
|
||||
```bash
|
||||
# SQL日志默认已启用(INFO级别)
|
||||
# 查看SQL执行日志
|
||||
docker-compose logs -f xianyu-app | grep "SQL"
|
||||
|
||||
# 如需禁用SQL日志
|
||||
export SQL_LOG_ENABLED=false
|
||||
docker-compose up -d
|
||||
|
||||
# 如需调整日志级别
|
||||
export SQL_LOG_LEVEL=DEBUG # 更详细的日志
|
||||
# 或
|
||||
export SQL_LOG_LEVEL=WARNING # 更少的日志
|
||||
docker-compose up -d
|
||||
|
||||
# 在.env文件中配置
|
||||
echo "SQL_LOG_ENABLED=false" >> .env
|
||||
echo "SQL_LOG_LEVEL=DEBUG" >> .env
|
||||
```
|
||||
|
||||
### 故障排除
|
||||
```bash
|
||||
# 重新构建镜像
|
||||
docker-compose build --no-cache
|
||||
|
||||
# 查看容器资源使用
|
||||
docker stats
|
||||
|
||||
# 清理未使用的镜像
|
||||
docker image prune
|
||||
|
||||
# 查看详细错误
|
||||
docker-compose logs --tail=50 xianyu-app
|
||||
```
|
||||
|
||||
## 🔍 故障排除
|
||||
|
||||
### 1. 容器启动失败
|
||||
```bash
|
||||
# 查看详细日志
|
||||
docker-compose logs xianyu-app
|
||||
|
||||
# 检查端口占用
|
||||
netstat -tulpn | grep 8080
|
||||
|
||||
# 重新构建
|
||||
docker-compose down
|
||||
docker-compose build --no-cache
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### 2. 图形验证码不显示
|
||||
```bash
|
||||
# 检查Pillow安装
|
||||
docker-compose exec xianyu-app python -c "from PIL import Image; print('OK')"
|
||||
|
||||
# 检查字体
|
||||
docker-compose exec xianyu-app ls /usr/share/fonts/
|
||||
|
||||
# 重新构建镜像
|
||||
docker-compose build --no-cache
|
||||
```
|
||||
|
||||
### 3. 数据库问题
|
||||
```bash
|
||||
# 检查数据库文件
|
||||
docker-compose exec xianyu-app ls -la /app/data/
|
||||
|
||||
# 运行数据迁移
|
||||
docker-compose exec xianyu-app python migrate_to_multiuser.py
|
||||
|
||||
# 检查数据库状态
|
||||
docker-compose exec xianyu-app python migrate_to_multiuser.py check
|
||||
```
|
||||
|
||||
### 4. 权限问题
|
||||
```bash
|
||||
# 检查数据目录权限
|
||||
ls -la ./data/
|
||||
|
||||
# 修复权限(Linux/Mac)
|
||||
sudo chown -R 1000:1000 ./data ./logs
|
||||
|
||||
# Windows用户通常不需要修改权限
|
||||
```
|
||||
|
||||
## 📊 监控和维护
|
||||
|
||||
### 性能监控
|
||||
```bash
|
||||
# 查看资源使用
|
||||
docker stats --no-stream
|
||||
|
||||
# 查看容器详情
|
||||
docker-compose exec xianyu-app ps aux
|
||||
|
||||
# 查看磁盘使用
|
||||
docker-compose exec xianyu-app df -h
|
||||
```
|
||||
|
||||
### 日志管理
|
||||
```bash
|
||||
# 查看日志大小
|
||||
docker-compose exec xianyu-app du -sh /app/logs/
|
||||
|
||||
# 清理旧日志(保留最近7天)
|
||||
docker-compose exec xianyu-app find /app/logs/ -name "*.log" -mtime +7 -delete
|
||||
|
||||
# 实时监控日志
|
||||
docker-compose logs -f --tail=100
|
||||
```
|
||||
|
||||
### 数据备份
|
||||
```bash
|
||||
# 创建备份脚本
|
||||
cat > backup.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
docker-compose exec -T xianyu-app cp /app/data/xianyu_data.db /app/data/backup_$DATE.db
|
||||
echo "备份完成: backup_$DATE.db"
|
||||
EOF
|
||||
|
||||
chmod +x backup.sh
|
||||
./backup.sh
|
||||
```
|
||||
|
||||
## 🔐 安全建议
|
||||
|
||||
### 1. 修改默认配置
|
||||
- ✅ 修改管理员密码
|
||||
- ✅ 修改JWT密钥
|
||||
- ✅ 禁用调试模式
|
||||
- ✅ 配置防火墙
|
||||
|
||||
### 2. 网络安全
|
||||
```bash
|
||||
# 只允许本地访问(如果不需要外部访问)
|
||||
# 修改 docker-compose.yml 中的端口映射
|
||||
ports:
|
||||
- "127.0.0.1:8080:8080" # 只绑定本地
|
||||
```
|
||||
|
||||
### 3. 数据安全
|
||||
- 定期备份数据库
|
||||
- 使用HTTPS(通过反向代理)
|
||||
- 限制用户注册(如不需要)
|
||||
- 监控异常登录
|
||||
|
||||
## 🎉 部署完成
|
||||
|
||||
部署完成后,您的系统将支持:
|
||||
|
||||
- ✅ **多用户注册和登录**
|
||||
- ✅ **图形验证码保护**
|
||||
- ✅ **邮箱验证码验证**
|
||||
- ✅ **完整的数据隔离**
|
||||
- ✅ **企业级安全保护**
|
||||
|
||||
现在可以安全地支持多个用户同时使用系统!
|
||||
|
||||
## 📞 获取帮助
|
||||
|
||||
如果遇到问题:
|
||||
|
||||
1. 查看日志:`docker-compose logs -f`
|
||||
2. 检查状态:`docker-compose ps`
|
||||
3. 健康检查:`curl http://localhost:8080/health`
|
||||
4. 运行测试:`python test_docker_deployment.sh`(Windows用户需要WSL或Git Bash)
|
||||
|
||||
---
|
||||
|
||||
**提示**: 首次部署后建议运行数据迁移脚本,将历史数据绑定到admin用户。
|
110
README.md
110
README.md
@ -2,8 +2,10 @@
|
||||
|
||||
[](https://github.com/zhinianboke/xianyu-auto-reply)
|
||||
[](https://github.com/zhinianboke/xianyu-auto-reply#-快速开始)
|
||||
[](https://www.python.org/)
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
|
||||
一个功能完整的闲鱼自动回复和管理系统,支持多用户、多账号管理,具备智能回复、自动发货、商品管理等企业级功能。
|
||||
一个功能完整的闲鱼自动回复和管理系统,支持多用户、多账号管理,具备智能回复、自动发货、自动确认发货、商品管理等企业级功能。
|
||||
|
||||
## ✨ 核心特性
|
||||
|
||||
@ -34,6 +36,8 @@
|
||||
- **多种触发** - 支持付款消息、小刀消息等多种触发条件
|
||||
- **防重复发货** - 智能防重复机制,避免重复发货
|
||||
- **多种发货方式** - 支持文本内容、卡密文件、API调用等发货方式
|
||||
- **自动确认发货** - 检测到付款后自动调用闲鱼API确认发货
|
||||
- **防重复确认** - 智能防重复确认机制,避免重复API调用
|
||||
- **发货统计** - 完整的发货记录和统计功能
|
||||
|
||||
### 🛍️ 商品管理
|
||||
@ -73,7 +77,8 @@ xianyu-auto-reply/
|
||||
│ ├── cookie_manager.py # Cookie和账号管理
|
||||
│ ├── ai_reply_engine.py # AI智能回复引擎
|
||||
│ ├── file_log_collector.py # 日志收集和管理
|
||||
│ └── config.py # 配置文件管理
|
||||
│ ├── config.py # 配置文件管理
|
||||
│ └── secure_confirm_ultra.py # 自动确认发货模块(加密保护)
|
||||
├── 🛠️ 工具模块
|
||||
│ └── utils/
|
||||
│ ├── xianyu_utils.py # 闲鱼API工具函数
|
||||
@ -207,7 +212,7 @@ docker rm -f xianyu-auto-reply
|
||||
### 4. 设置自动发货
|
||||
- 添加发货规则,设置商品关键词和发货内容
|
||||
- 支持文本内容和卡密文件两种发货方式
|
||||
- 系统检测到付款消息时自动发货
|
||||
- 系统检测到付款消息时自动确认发货并自动发货
|
||||
|
||||
### 5. 使用商品搜索功能
|
||||
- 访问商品搜索页面(需要登录)
|
||||
@ -240,40 +245,45 @@ docker rm -f xianyu-auto-reply
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 📁 项目结构
|
||||
## 📁 核心文件功能说明
|
||||
|
||||
```
|
||||
xianyu-auto-reply/
|
||||
├── Start.py # 主启动文件
|
||||
├── XianyuAutoAsync.py # 闲鱼WebSocket客户端核心
|
||||
├── reply_server.py # FastAPI Web服务器
|
||||
├── db_manager.py # 数据库管理模块
|
||||
├── cookie_manager.py # Cookie和任务管理
|
||||
├── ai_reply_engine.py # AI回复引擎
|
||||
├── config.py # 配置管理
|
||||
├── file_log_collector.py # 日志收集器
|
||||
├── global_config.yml # 全局配置文件
|
||||
├── requirements.txt # Python依赖
|
||||
├── docker-compose.yml # Docker编排配置
|
||||
├── Dockerfile # Docker镜像构建
|
||||
├── utils/ # 工具模块
|
||||
│ ├── item_search.py # 商品搜索功能
|
||||
│ └── ... # 其他工具模块
|
||||
├── static/ # 前端静态文件
|
||||
│ ├── index.html # 主界面
|
||||
│ ├── login.html # 登录页面
|
||||
│ ├── register.html # 注册页面
|
||||
│ ├── item_search.html # 商品搜索页面
|
||||
│ ├── user_management.html # 用户管理页面
|
||||
│ ├── data_management.html # 数据管理页面
|
||||
│ ├── log_management.html # 日志管理页面
|
||||
│ └── lib/ # 本地静态资源库
|
||||
│ ├── bootstrap/ # Bootstrap框架
|
||||
│ └── bootstrap-icons/ # Bootstrap图标
|
||||
├── logs/ # 日志文件目录
|
||||
├── data/ # 数据库文件目录
|
||||
└── backups/ # 备份文件目录
|
||||
```
|
||||
### 🚀 启动和核心模块
|
||||
- **`Start.py`** - 项目启动入口,初始化所有服务和组件
|
||||
- **`XianyuAutoAsync.py`** - 闲鱼WebSocket连接核心,处理消息收发和自动回复
|
||||
- **`reply_server.py`** - FastAPI Web服务器,提供管理界面和API接口
|
||||
- **`cookie_manager.py`** - 多账号Cookie管理,负责账号任务的启动和停止
|
||||
|
||||
### 🗄️ 数据和配置管理
|
||||
- **`db_manager.py`** - SQLite数据库管理,处理用户数据、商品信息、关键词等
|
||||
- **`config.py`** - 配置文件管理,加载和管理全局配置
|
||||
- **`global_config.yml`** - 全局配置文件,包含所有系统配置项
|
||||
|
||||
### 🤖 智能功能模块
|
||||
- **`ai_reply_engine.py`** - AI智能回复引擎,支持多种AI模型
|
||||
- **`secure_confirm_ultra.py`** - 自动确认发货模块(加密保护)
|
||||
- **`file_log_collector.py`** - 日志收集和管理,提供实时日志查看
|
||||
|
||||
### 🛠️ 工具模块
|
||||
- **`utils/xianyu_utils.py`** - 闲鱼API工具函数,包含加密解密、签名生成等
|
||||
- **`utils/message_utils.py`** - 消息格式化工具
|
||||
- **`utils/ws_utils.py`** - WebSocket客户端工具
|
||||
- **`utils/item_search.py`** - 商品搜索功能,基于Playwright技术
|
||||
|
||||
### 🌐 前端界面
|
||||
- **`static/index.html`** - 主管理界面,账号管理和系统监控
|
||||
- **`static/login.html`** - 用户登录页面
|
||||
- **`static/register.html`** - 用户注册页面,支持邮箱验证
|
||||
- **`static/user_management.html`** - 用户管理页面(管理员功能)
|
||||
- **`static/data_management.html`** - 数据管理页面,关键词导入导出
|
||||
- **`static/log_management.html`** - 日志管理页面,实时日志查看
|
||||
- **`static/item_search.html`** - 商品搜索页面,获取真实闲鱼数据
|
||||
|
||||
### 🐳 部署配置
|
||||
- **`Dockerfile`** - Docker镜像构建文件,包含完整运行环境
|
||||
- **`docker-compose.yml`** - Docker Compose配置,支持一键部署
|
||||
- **`docker-deploy.sh`** - Docker部署脚本,提供完整的部署管理功能
|
||||
- **`.env`** - 环境变量配置文件,包含所有可配置项
|
||||
- **`requirements.txt`** - Python依赖包列表
|
||||
|
||||
## ⚙️ 配置说明
|
||||
|
||||
@ -363,6 +373,34 @@ curl http://localhost:8080/health
|
||||
- **数据隔离**:用户数据完全隔离
|
||||
- **会话管理**:安全的会话超时机制
|
||||
- **操作日志**:完整的用户操作记录
|
||||
- **代码加密**:核心业务逻辑采用多层加密保护
|
||||
|
||||
## 🛡️ 技术特性
|
||||
|
||||
### 🏗️ 架构设计
|
||||
- **微服务架构**:模块化设计,易于维护和扩展
|
||||
- **异步编程**:基于asyncio的高性能异步处理
|
||||
- **WebSocket长连接**:实时消息处理,低延迟响应
|
||||
- **RESTful API**:标准化的API接口设计
|
||||
|
||||
### 🔧 技术栈
|
||||
- **后端框架**:FastAPI + Uvicorn
|
||||
- **数据库**:SQLite(轻量级,无需额外配置)
|
||||
- **前端技术**:原生HTML/CSS/JavaScript + Bootstrap
|
||||
- **WebSocket**:实时双向通信
|
||||
- **容器化**:Docker + Docker Compose
|
||||
|
||||
### 🚀 性能优化
|
||||
- **连接池管理**:高效的数据库连接管理
|
||||
- **异步处理**:非阻塞I/O操作
|
||||
- **内存优化**:智能缓存和垃圾回收
|
||||
- **资源限制**:Docker容器资源限制和监控
|
||||
|
||||
### 🔐 安全机制
|
||||
- **多层加密**:敏感代码采用5层编码混淆
|
||||
- **变量名随机化**:防止静态分析
|
||||
- **运行时解密**:代码在内存中动态解密执行
|
||||
- **防重复机制**:智能防重复确认和发货
|
||||
|
||||
## 🤝 贡献指南
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import asyncio
|
||||
import json
|
||||
import re
|
||||
import time
|
||||
import base64
|
||||
import os
|
||||
@ -101,6 +102,10 @@ class XianyuLive:
|
||||
# 自动发货防重复机制
|
||||
self.last_delivery_time = {} # 记录每个商品的最后发货时间
|
||||
self.delivery_cooldown = 60 # 1分钟内不重复发货
|
||||
|
||||
# 自动确认发货防重复机制
|
||||
self.confirmed_orders = {} # 记录已确认发货的订单,防止重复确认
|
||||
self.order_confirm_cooldown = 300 # 5分钟内不重复确认同一订单
|
||||
|
||||
# 人工接管功能已禁用,永远走自动模式
|
||||
# self.manual_mode_conversations = set() # 存储处于人工接管模式的会话ID
|
||||
@ -623,7 +628,6 @@ class XianyuLive:
|
||||
message_1 = message.get('1')
|
||||
if isinstance(message_1, str):
|
||||
# 尝试从字符串中提取数字ID
|
||||
import re
|
||||
id_match = re.search(r'(\d{10,})', message_1)
|
||||
if id_match:
|
||||
logger.info(f"从message[1]字符串中提取商品ID: {id_match.group(1)}")
|
||||
@ -662,7 +666,6 @@ class XianyuLive:
|
||||
# 从消息内容中提取数字ID
|
||||
content = message_3.get('content', '')
|
||||
if isinstance(content, str) and content:
|
||||
import re
|
||||
id_match = re.search(r'(\d{10,})', content)
|
||||
if id_match:
|
||||
logger.info(f"【{self.cookie_id}】从消息内容中提取商品ID: {id_match.group(1)}")
|
||||
@ -687,7 +690,6 @@ class XianyuLive:
|
||||
|
||||
elif isinstance(obj, str):
|
||||
# 从字符串中提取可能的商品ID
|
||||
import re
|
||||
id_match = re.search(r'(\d{10,})', obj)
|
||||
if id_match:
|
||||
logger.info(f"从{path}字符串中提取商品ID: {id_match.group(1)}")
|
||||
@ -873,7 +875,6 @@ class XianyuLive:
|
||||
if not price_str:
|
||||
return 0.0
|
||||
# 移除非数字字符,保留小数点
|
||||
import re
|
||||
price_clean = re.sub(r'[^\d.]', '', str(price_str))
|
||||
return float(price_clean) if price_clean else 0.0
|
||||
except:
|
||||
@ -884,7 +885,6 @@ class XianyuLive:
|
||||
try:
|
||||
from db_manager import db_manager
|
||||
import aiohttp
|
||||
import json
|
||||
|
||||
|
||||
# 获取当前账号的通知配置
|
||||
@ -926,7 +926,6 @@ class XianyuLive:
|
||||
"""发送QQ通知"""
|
||||
try:
|
||||
import aiohttp
|
||||
import json
|
||||
|
||||
# 解析配置(QQ号码)
|
||||
qq_number = config.strip()
|
||||
@ -1075,6 +1074,28 @@ class XianyuLive:
|
||||
except Exception as e:
|
||||
logger.error(f"发送自动发货通知异常: {self._safe_str(e)}")
|
||||
|
||||
async def auto_confirm(self, order_id, retry_count=0):
|
||||
"""自动确认发货 - 使用加密模块"""
|
||||
try:
|
||||
# 导入超级混淆模块
|
||||
from secure_confirm_ultra import SecureConfirm
|
||||
|
||||
# 创建加密确认实例
|
||||
secure_confirm = SecureConfirm(self.session, self.cookies_str, self.cookie_id)
|
||||
|
||||
# 传递必要的属性
|
||||
secure_confirm.current_token = self.current_token
|
||||
secure_confirm.last_token_refresh_time = self.last_token_refresh_time
|
||||
secure_confirm.token_refresh_interval = self.token_refresh_interval
|
||||
secure_confirm.refresh_token = self.refresh_token # 传递refresh_token方法
|
||||
|
||||
# 调用加密的确认方法
|
||||
return await secure_confirm.auto_confirm(order_id, retry_count)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"【{self.cookie_id}】加密确认模块调用失败: {self._safe_str(e)}")
|
||||
return {"error": f"加密确认模块调用失败: {self._safe_str(e)}", "order_id": order_id}
|
||||
|
||||
async def _auto_delivery(self, item_id: str, item_title: str = None):
|
||||
"""自动发货功能"""
|
||||
try:
|
||||
@ -1099,7 +1120,6 @@ class XianyuLive:
|
||||
|
||||
# 解析 shareInfoJsonString 并提取 content 内容
|
||||
try:
|
||||
import json
|
||||
share_info = json.loads(shareInfoJsonString)
|
||||
content = share_info.get('contentParams', {}).get('mainParams', {}).get('content', '')
|
||||
if content:
|
||||
@ -1262,8 +1282,6 @@ class XianyuLive:
|
||||
|
||||
try:
|
||||
import aiohttp
|
||||
import json
|
||||
import asyncio
|
||||
|
||||
api_config = rule.get('card_api_config')
|
||||
if not api_config:
|
||||
@ -1978,12 +1996,117 @@ class XianyuLive:
|
||||
elif send_message == '快给ta一个评价吧~' or send_message == '快给ta一个评价吧~':
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】评价提醒消息不处理')
|
||||
return
|
||||
elif send_message == '卖家人不错?送Ta闲鱼小红花':
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】小红花提醒消息不处理')
|
||||
return
|
||||
elif send_message == '[你已确认收货,交易成功]':
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】买家确认收货消息不处理')
|
||||
return
|
||||
elif send_message == '[你已发货]':
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】发货确认消息不处理')
|
||||
return
|
||||
elif send_message == '[我已付款,等待你发货]':
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】【系统】买家已付款,准备自动发货')
|
||||
|
||||
# 提取orderId并打印
|
||||
try:
|
||||
order_id = None
|
||||
|
||||
# 先查看消息的完整结构
|
||||
logger.info(f"【{self.cookie_id}】🔍 完整消息结构: {message}")
|
||||
|
||||
# 检查message['1']的结构
|
||||
message_1 = message.get('1', {})
|
||||
logger.info(f"【{self.cookie_id}】🔍 message['1'] keys: {list(message_1.keys()) if message_1 else 'None'}")
|
||||
|
||||
# 检查message['1']['6']的结构
|
||||
message_1_6 = message_1.get('6', {}) if message_1 else {}
|
||||
logger.info(f"【{self.cookie_id}】🔍 message['1']['6'] keys: {list(message_1_6.keys()) if message_1_6 else 'None'}")
|
||||
|
||||
# 方法1: 从button的targetUrl中提取orderId
|
||||
content_json_str = message.get('1', {}).get('6', {}).get('3', {}).get('5', '')
|
||||
logger.info(f"【{self.cookie_id}】🔍 content_json_str: {content_json_str[:200] if content_json_str else 'None'}...")
|
||||
|
||||
if content_json_str:
|
||||
try:
|
||||
content_data = json.loads(content_json_str)
|
||||
logger.info(f"【{self.cookie_id}】🔍 content_data keys: {list(content_data.keys())}")
|
||||
|
||||
# 方法1a: 从button的targetUrl中提取orderId
|
||||
target_url = content_data.get('dxCard', {}).get('item', {}).get('main', {}).get('exContent', {}).get('button', {}).get('targetUrl', '')
|
||||
logger.info(f"【{self.cookie_id}】🔍 button targetUrl: {target_url}")
|
||||
if target_url:
|
||||
# 从URL中提取orderId参数
|
||||
order_match = re.search(r'orderId=(\d+)', target_url)
|
||||
if order_match:
|
||||
order_id = order_match.group(1)
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】✅ 从button提取到订单ID: {order_id}')
|
||||
|
||||
# 方法1b: 从main的targetUrl中提取order_detail的id
|
||||
if not order_id:
|
||||
main_target_url = content_data.get('dxCard', {}).get('item', {}).get('main', {}).get('targetUrl', '')
|
||||
logger.info(f"【{self.cookie_id}】🔍 main targetUrl: {main_target_url}")
|
||||
if main_target_url:
|
||||
order_match = re.search(r'order_detail\?id=(\d+)', main_target_url)
|
||||
if order_match:
|
||||
order_id = order_match.group(1)
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】✅ 从main targetUrl提取到订单ID: {order_id}')
|
||||
|
||||
except Exception as parse_e:
|
||||
logger.error(f"解析内容JSON失败: {parse_e}")
|
||||
|
||||
# 方法2: 从dynamicOperation中的order_detail URL提取orderId
|
||||
if not order_id and content_json_str:
|
||||
try:
|
||||
content_data = json.loads(content_json_str)
|
||||
dynamic_target_url = content_data.get('dynamicOperation', {}).get('changeContent', {}).get('dxCard', {}).get('item', {}).get('main', {}).get('exContent', {}).get('button', {}).get('targetUrl', '')
|
||||
if dynamic_target_url:
|
||||
# 从order_detail URL中提取id参数
|
||||
order_match = re.search(r'order_detail\?id=(\d+)', dynamic_target_url)
|
||||
if order_match:
|
||||
order_id = order_match.group(1)
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】✅ 从order_detail提取到订单ID: {order_id}')
|
||||
except Exception as parse_e:
|
||||
logger.debug(f"解析dynamicOperation JSON失败: {parse_e}")
|
||||
|
||||
# 如果成功获取到orderId,进行自动确认发货
|
||||
if order_id:
|
||||
# 检查是否已经确认过这个订单
|
||||
current_time = time.time()
|
||||
if order_id in self.confirmed_orders:
|
||||
last_confirm_time = self.confirmed_orders[order_id]
|
||||
if current_time - last_confirm_time < self.order_confirm_cooldown:
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】⏭️ 订单 {order_id} 已在 {self.order_confirm_cooldown} 秒内确认过,跳过重复确认')
|
||||
else:
|
||||
# 超过冷却时间,可以重新确认
|
||||
try:
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】开始自动确认发货,订单ID: {order_id}')
|
||||
confirm_result = await self.auto_confirm(order_id)
|
||||
if confirm_result.get('success'):
|
||||
self.confirmed_orders[order_id] = current_time
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】🎉 自动确认发货成功!订单ID: {order_id}')
|
||||
else:
|
||||
logger.warning(f'[{msg_time}] 【{self.cookie_id}】⚠️ 自动确认发货失败: {confirm_result.get("error", "未知错误")}')
|
||||
except Exception as confirm_e:
|
||||
logger.error(f'[{msg_time}] 【{self.cookie_id}】自动确认发货异常: {self._safe_str(confirm_e)}')
|
||||
else:
|
||||
# 首次确认这个订单
|
||||
try:
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】开始自动确认发货,订单ID: {order_id}')
|
||||
confirm_result = await self.auto_confirm(order_id)
|
||||
if confirm_result.get('success'):
|
||||
self.confirmed_orders[order_id] = current_time
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】🎉 自动确认发货成功!订单ID: {order_id}')
|
||||
else:
|
||||
logger.warning(f'[{msg_time}] 【{self.cookie_id}】⚠️ 自动确认发货失败: {confirm_result.get("error", "未知错误")}')
|
||||
except Exception as confirm_e:
|
||||
logger.error(f'[{msg_time}] 【{self.cookie_id}】自动确认发货异常: {self._safe_str(confirm_e)}')
|
||||
else:
|
||||
logger.warning(f'[{msg_time}] 【{self.cookie_id}】❌ 未能提取到订单ID')
|
||||
|
||||
except Exception as extract_e:
|
||||
logger.error(f"提取订单ID失败: {self._safe_str(extract_e)}")
|
||||
|
||||
# 检查是否可以进行自动发货(防重复)
|
||||
if not self.can_auto_delivery(item_id):
|
||||
return
|
||||
@ -2023,6 +2146,89 @@ class XianyuLive:
|
||||
elif send_message == '[已付款,待发货]':
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】【系统】买家已付款,准备自动发货')
|
||||
|
||||
# 提取orderId并打印
|
||||
try:
|
||||
order_id = None
|
||||
|
||||
# 方法1: 从button的targetUrl中提取orderId
|
||||
content_json_str = message.get('1', {}).get('6', {}).get('3', {}).get('5', '')
|
||||
if content_json_str:
|
||||
try:
|
||||
content_data = json.loads(content_json_str)
|
||||
|
||||
# 方法1a: 从button的targetUrl中提取orderId
|
||||
target_url = content_data.get('dxCard', {}).get('item', {}).get('main', {}).get('exContent', {}).get('button', {}).get('targetUrl', '')
|
||||
if target_url:
|
||||
# 从URL中提取orderId参数
|
||||
order_match = re.search(r'orderId=(\d+)', target_url)
|
||||
if order_match:
|
||||
order_id = order_match.group(1)
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】✅ 从button提取到订单ID: {order_id}')
|
||||
|
||||
# 方法1b: 从main的targetUrl中提取order_detail的id
|
||||
if not order_id:
|
||||
main_target_url = content_data.get('dxCard', {}).get('item', {}).get('main', {}).get('targetUrl', '')
|
||||
if main_target_url:
|
||||
order_match = re.search(r'order_detail\?id=(\d+)', main_target_url)
|
||||
if order_match:
|
||||
order_id = order_match.group(1)
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】✅ 从main targetUrl提取到订单ID: {order_id}')
|
||||
|
||||
except Exception as parse_e:
|
||||
logger.debug(f"解析内容JSON失败: {parse_e}")
|
||||
|
||||
# 方法2: 从dynamicOperation中的order_detail URL提取orderId
|
||||
if not order_id and content_json_str:
|
||||
try:
|
||||
content_data = json.loads(content_json_str)
|
||||
dynamic_target_url = content_data.get('dynamicOperation', {}).get('changeContent', {}).get('dxCard', {}).get('item', {}).get('main', {}).get('exContent', {}).get('button', {}).get('targetUrl', '')
|
||||
if dynamic_target_url:
|
||||
# 从order_detail URL中提取id参数
|
||||
order_match = re.search(r'order_detail\?id=(\d+)', dynamic_target_url)
|
||||
if order_match:
|
||||
order_id = order_match.group(1)
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】✅ 从order_detail提取到订单ID: {order_id}')
|
||||
except Exception as parse_e:
|
||||
logger.debug(f"解析dynamicOperation JSON失败: {parse_e}")
|
||||
|
||||
# 如果成功获取到orderId,进行自动确认发货
|
||||
if order_id:
|
||||
# 检查是否已经确认过这个订单
|
||||
current_time = time.time()
|
||||
if order_id in self.confirmed_orders:
|
||||
last_confirm_time = self.confirmed_orders[order_id]
|
||||
if current_time - last_confirm_time < self.order_confirm_cooldown:
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】⏭️ 订单 {order_id} 已在 {self.order_confirm_cooldown} 秒内确认过,跳过重复确认')
|
||||
else:
|
||||
# 超过冷却时间,可以重新确认
|
||||
try:
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】开始自动确认发货,订单ID: {order_id}')
|
||||
confirm_result = await self.auto_confirm(order_id)
|
||||
if confirm_result.get('success'):
|
||||
self.confirmed_orders[order_id] = current_time
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】🎉 自动确认发货成功!订单ID: {order_id}')
|
||||
else:
|
||||
logger.warning(f'[{msg_time}] 【{self.cookie_id}】⚠️ 自动确认发货失败: {confirm_result.get("error", "未知错误")}')
|
||||
except Exception as confirm_e:
|
||||
logger.error(f'[{msg_time}] 【{self.cookie_id}】自动确认发货异常: {self._safe_str(confirm_e)}')
|
||||
else:
|
||||
# 首次确认这个订单
|
||||
try:
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】开始自动确认发货,订单ID: {order_id}')
|
||||
confirm_result = await self.auto_confirm(order_id)
|
||||
if confirm_result.get('success'):
|
||||
self.confirmed_orders[order_id] = current_time
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】🎉 自动确认发货成功!订单ID: {order_id}')
|
||||
else:
|
||||
logger.warning(f'[{msg_time}] 【{self.cookie_id}】⚠️ 自动确认发货失败: {confirm_result.get("error", "未知错误")}')
|
||||
except Exception as confirm_e:
|
||||
logger.error(f'[{msg_time}] 【{self.cookie_id}】自动确认发货异常: {self._safe_str(confirm_e)}')
|
||||
else:
|
||||
logger.warning(f'[{msg_time}] 【{self.cookie_id}】❌ 未能提取到订单ID')
|
||||
|
||||
except Exception as extract_e:
|
||||
logger.error(f"提取订单ID失败: {self._safe_str(extract_e)}")
|
||||
|
||||
# 检查是否可以进行自动发货(防重复)
|
||||
if not self.can_auto_delivery(item_id):
|
||||
return
|
||||
@ -2086,6 +2292,89 @@ class XianyuLive:
|
||||
if card_title == "我已小刀,待刀成":
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】【系统】检测到"我已小刀,待刀成",准备自动发货')
|
||||
|
||||
# 提取orderId并打印
|
||||
try:
|
||||
order_id = None
|
||||
|
||||
# 方法1: 从button的targetUrl中提取orderId
|
||||
content_json_str = message.get('1', {}).get('6', {}).get('3', {}).get('5', '')
|
||||
if content_json_str:
|
||||
try:
|
||||
content_data = json.loads(content_json_str)
|
||||
|
||||
# 方法1a: 从button的targetUrl中提取orderId
|
||||
target_url = content_data.get('dxCard', {}).get('item', {}).get('main', {}).get('exContent', {}).get('button', {}).get('targetUrl', '')
|
||||
if target_url:
|
||||
# 从URL中提取orderId参数
|
||||
order_match = re.search(r'orderId=(\d+)', target_url)
|
||||
if order_match:
|
||||
order_id = order_match.group(1)
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】✅ 小刀成功,从button提取到订单ID: {order_id}')
|
||||
|
||||
# 方法1b: 从main的targetUrl中提取order_detail的id
|
||||
if not order_id:
|
||||
main_target_url = content_data.get('dxCard', {}).get('item', {}).get('main', {}).get('targetUrl', '')
|
||||
if main_target_url:
|
||||
order_match = re.search(r'order_detail\?id=(\d+)', main_target_url)
|
||||
if order_match:
|
||||
order_id = order_match.group(1)
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】✅ 小刀成功,从main targetUrl提取到订单ID: {order_id}')
|
||||
|
||||
except Exception as parse_e:
|
||||
logger.debug(f"解析内容JSON失败: {parse_e}")
|
||||
|
||||
# 方法2: 从dynamicOperation中的order_detail URL提取orderId
|
||||
if not order_id and content_json_str:
|
||||
try:
|
||||
content_data = json.loads(content_json_str)
|
||||
dynamic_target_url = content_data.get('dynamicOperation', {}).get('changeContent', {}).get('dxCard', {}).get('item', {}).get('main', {}).get('exContent', {}).get('button', {}).get('targetUrl', '')
|
||||
if dynamic_target_url:
|
||||
# 从order_detail URL中提取id参数
|
||||
order_match = re.search(r'order_detail\?id=(\d+)', dynamic_target_url)
|
||||
if order_match:
|
||||
order_id = order_match.group(1)
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】✅ 小刀成功,从order_detail提取到订单ID: {order_id}')
|
||||
except Exception as parse_e:
|
||||
logger.debug(f"解析dynamicOperation JSON失败: {parse_e}")
|
||||
|
||||
# 如果成功获取到orderId,进行自动确认发货
|
||||
if order_id:
|
||||
# 检查是否已经确认过这个订单
|
||||
current_time = time.time()
|
||||
if order_id in self.confirmed_orders:
|
||||
last_confirm_time = self.confirmed_orders[order_id]
|
||||
if current_time - last_confirm_time < self.order_confirm_cooldown:
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】⏭️ 订单 {order_id} 已在 {self.order_confirm_cooldown} 秒内确认过,跳过重复确认')
|
||||
else:
|
||||
# 超过冷却时间,可以重新确认
|
||||
try:
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】小刀成功,开始自动确认发货,订单ID: {order_id}')
|
||||
confirm_result = await self.auto_confirm(order_id)
|
||||
if confirm_result.get('success'):
|
||||
self.confirmed_orders[order_id] = current_time
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】🎉 小刀成功,自动确认发货成功!订单ID: {order_id}')
|
||||
else:
|
||||
logger.warning(f'[{msg_time}] 【{self.cookie_id}】⚠️ 小刀成功,自动确认发货失败: {confirm_result.get("error", "未知错误")}')
|
||||
except Exception as confirm_e:
|
||||
logger.error(f'[{msg_time}] 【{self.cookie_id}】小刀成功,自动确认发货异常: {self._safe_str(confirm_e)}')
|
||||
else:
|
||||
# 首次确认这个订单
|
||||
try:
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】小刀成功,开始自动确认发货,订单ID: {order_id}')
|
||||
confirm_result = await self.auto_confirm(order_id)
|
||||
if confirm_result.get('success'):
|
||||
self.confirmed_orders[order_id] = current_time
|
||||
logger.info(f'[{msg_time}] 【{self.cookie_id}】🎉 小刀成功,自动确认发货成功!订单ID: {order_id}')
|
||||
else:
|
||||
logger.warning(f'[{msg_time}] 【{self.cookie_id}】⚠️ 小刀成功,自动确认发货失败: {confirm_result.get("error", "未知错误")}')
|
||||
except Exception as confirm_e:
|
||||
logger.error(f'[{msg_time}] 【{self.cookie_id}】小刀成功,自动确认发货异常: {self._safe_str(confirm_e)}')
|
||||
else:
|
||||
logger.warning(f'[{msg_time}] 【{self.cookie_id}】❌ 小刀成功但未能提取到订单ID')
|
||||
|
||||
except Exception as extract_e:
|
||||
logger.error(f"提取订单ID失败: {self._safe_str(extract_e)}")
|
||||
|
||||
# 检查是否可以进行自动发货(防重复)
|
||||
if not self.can_auto_delivery(item_id):
|
||||
return
|
||||
|
@ -54,19 +54,14 @@ check_dependencies() {
|
||||
# 初始化配置
|
||||
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
|
||||
print_warning "$ENV_FILE 文件不存在,将使用默认配置"
|
||||
print_info "如需自定义配置,请创建 $ENV_FILE 文件"
|
||||
else
|
||||
print_warning "$ENV_FILE 已存在,跳过创建"
|
||||
print_success "$ENV_FILE 配置文件已存在"
|
||||
fi
|
||||
|
||||
|
||||
# 创建必要的目录
|
||||
mkdir -p data logs backups
|
||||
print_success "已创建必要的目录"
|
||||
@ -328,9 +323,7 @@ main() {
|
||||
"cleanup")
|
||||
cleanup
|
||||
;;
|
||||
"fix-playwright")
|
||||
fix_playwright
|
||||
;;
|
||||
|
||||
"help"|"--help"|"-h")
|
||||
show_help
|
||||
;;
|
||||
|
@ -1,17 +1,21 @@
|
||||
# ================================
|
||||
# 闲鱼自动回复系统 - Python依赖包
|
||||
# ================================
|
||||
|
||||
# Web框架和API相关
|
||||
fastapi>=0.111
|
||||
uvicorn[standard]>=0.29
|
||||
pydantic>=2.7
|
||||
fastapi>=0.111.0
|
||||
uvicorn[standard]>=0.29.0
|
||||
pydantic>=2.7.0
|
||||
|
||||
# 日志记录
|
||||
loguru>=0.7
|
||||
loguru>=0.7.0
|
||||
|
||||
# 网络通信
|
||||
websockets>=10.0,<13.0 # 兼容性版本范围
|
||||
aiohttp>=3.9
|
||||
websockets>=10.0,<13.0
|
||||
aiohttp>=3.9.0
|
||||
|
||||
# 配置文件处理
|
||||
PyYAML>=6.0
|
||||
PyYAML>=6.0.0
|
||||
|
||||
# JavaScript执行引擎
|
||||
PyExecJS>=1.5.1
|
||||
@ -22,7 +26,7 @@ blackboxprotobuf>=1.0.1
|
||||
# 系统监控
|
||||
psutil>=5.9.0
|
||||
|
||||
# HTTP客户端(用于测试)
|
||||
# HTTP客户端
|
||||
requests>=2.31.0
|
||||
|
||||
# 文件上传支持
|
||||
@ -42,6 +46,7 @@ playwright>=1.40.0
|
||||
PyJWT>=2.8.0
|
||||
passlib>=1.7.4
|
||||
bcrypt>=4.0.1
|
||||
cryptography>=41.0.0
|
||||
|
||||
# 时间处理
|
||||
python-dateutil>=2.8.2
|
||||
@ -51,4 +56,10 @@ regex>=2023.10.3
|
||||
|
||||
# Excel文件处理(导入导出功能)
|
||||
pandas>=2.0.0
|
||||
openpyxl>=3.1.0
|
||||
openpyxl>=3.1.0
|
||||
|
||||
# 数据库相关
|
||||
sqlite3 # Python内置,无需安装
|
||||
|
||||
# 其他工具库
|
||||
typing-extensions>=4.7.0
|
56
secure_confirm_ultra.py
Normal file
56
secure_confirm_ultra.py
Normal file
@ -0,0 +1,56 @@
|
||||
"""
|
||||
自动确认发货模块 - 超级混淆版本
|
||||
代码经过多层编码和混淆处理
|
||||
"""
|
||||
import base64 as APWhvGwho
|
||||
import zlib as ZUMHeUctH
|
||||
import types as YEYVefZAzSK
|
||||
import binascii as xjJqeneb
|
||||
|
||||
|
||||
class MyCvbqb:
|
||||
"""解码器类"""
|
||||
|
||||
def __init__(self):
|
||||
self.GUqVZNquc = "d355231467a733244345c6a5172787b43346f48436563463f245833377a6e6c693b23376862713c477b6360367264386747517976747a467363775a545a52717672485a4a64464f607b48355647334d48514b4074563835767b463a4940345f275a5c4051457c433633605a52733d4a73316933756b273d4a55625270583b69594f666b4134516a593d603d64427234303768756352773747605d6938773951493a466946534572646973396f483451576575356f64674a7a63794a436a795d6a74437467585454463b2f253f603a4a4976474838754930325b413176303a64405645427b286e43593038635a47325254746b27505b61674175656243756579394c623263747863324c4a69354466666849434a7a7b63353a53477765766d4f66413f68403056535c4d484f6a6d66614f44734c464758677466733536607647733a77305f2033727148456431745352795d484965307f4c4c413d463d6a505a586052594a677a625453613655575961726b616852427161445d6a656b4537436252756a7163747e454858643f63725136673563316877595a7333726a4a4452756135307b4075763f246233764664675b4e425374557b6139383945656c4275594a4647456b49405979743a7f295e61544870563465337234705a7e6e626a7748354b457245416a74655036373340324f297c4e63393335654c6e6762396353616f64524642584a537a646149515c496d44415a74444942735550556f646143735957424f2e655239627a456668756e683f6a7339467d6166554b64717c4d6137544a69605f47773a5c6a61767743525b4942615f40767232666b407a69777b2d63364558767861735754314159397f6c64705135786374686238386d483943593f283077427035616a44625a4d4d4363534837773b496e6360385445587c474537744f4f267f276c4f275e47633266427b44793b496c6566614650323553663c67703b67346649473e405c496c4e485c4148574747753b67333342437c663140305855565a6a5c46625a7742797a4666574a545c637672553f6d43623231574842415647784151337958405f4d4356344a5738666b24754374366a6f264657693633616b273a447b243573586e6a6d4a457a6353334963457e4a7f42597754507e41615b243b6872794479324f4c64773748456a514639394e44313c464832524c63486c4f47643569444472336a584a6274396b234b636e4c6577385752443a7e6a5972794a485a78476d643334687469627449637b6e6852436078585b49343a5b2c637b6269793c6e497f2943584b686659347361666c69666b424a4e6174463d405f6e686a755a703f464434696268464f687a4755397f487d686d65436d415b2e4a5a51477c4541426b6852535c6f6f43576a4a4130336c6f4b6650794534314f234950377c647172686d62525d416e663446535a5b495a7777584642623375457c676e4a736169437168514353797c4536527544634441305231487573413f4a62573171674470745765447b455c6167314532676d6d4f2b2742614a50305a51454f4b46523e6563387334705b257a7071487a7a507c46407e626774535348527774517f2a68355c6b2a427f2e4149577e48414135507a5352736a5b2d4c63666a525a4d66356567477d443e6b6536705d49407463675443417a6649387b23356f4a637535507959397968675238795a5538365369425c4d696249545b62653a7778403a6532397f264e697c6559307569774857344d6a5c62663d427148524346357532784f21424239785c42473f4170523a4e4455556656643641505e425f234834627435417178317b6f6135503a577f47514753494477513757325b25365d4f613753745566366339427941455a7574386845495e497d6532435c613272393337376a663667737447494f4e444946435e674f23787477456f60335141495943515d6a586072394449605944677f2b2445707f683a75454f664272615976735a56594f6b48526f64545161643b243a675353337a6943476762723c4344434b613f493a5b6137556a5738736546617a4e6644465152437a624b45714a453d4842775636325b4930525a4469427968534f4875394f4a543368674c667842625c4638394a686371523a597e4a474f415135737133425e4f276c6b415243303d605d6a4f67353f497d60777f4031705c6131426a457e4e483d447b2b2e4661384330364c44474f28355954447842603c6753746f4741554b4a4b484c454833316e4b656a755f22445a6477345a7338363e46536b627848643653355e41474a5a44497f434a5871377632333168764537744c45697841665269607a4569436146345533336255705f285a5c69503b4e6363324a644a73595052405c6f487b6642614331507131597761447d664169327271657a42614a6b426072365143797133426d613337505541443773754148353a5a7950755a65535777563c4845667d65547255464758464372527662413e4141686478593f243f695337526c673447563c613742617e637c6335597745687a7748557551376535413073695b41387c64626441633153754077705c63423d674d6d6364784756654f69636854754c46796866567a677845693a6c485265375734765563484a5079693247337531633a57344d695e6445626632764751384f42394845615f23775956616f685b24616b2367414833795a7d6a7c6a4c407744434b4b295c6e4b44516d6b605d4a5a674736617539617e464f21376f615c64687b44475a554557624161797637614256345937497a543f63527a7453475a48455146566c6c446247365f696962427039547557643e4b28603a6537455356473c4f494a643a7034475244617a6a6a6c4f683860745257723948496f2e4331513648613972535c675136546f474a5a494a7654674a6968694a717f6a4631536b6866694f496a527b62557173796f216077707c4a66317b6b455239675039795b4a7050557173713666545246357a6a74665557635577524a607d4a413a7f6961345c6a557f695355757b4b6f2f6e4c4767575a44597c6c4343557e455655517e69796352797b467b227573797141384a446e67354a7c6861413d4657563963514e4b27403b6e6149726b264261693557394a5c44716743723d673169747549775f22543472675f2b646352794858387360373a7a713a5b266a79393538383563574765324450563d446a6a537334633576656f666e4539733948507664434b4275564f28774a46464a424f6f694371434756547d4d4d4449423462326b4271634737545e6a57474667415e60735e443730574a607a7b62316445335d6b4e426b2d4c457e6b28366553613544593647565a7a456"
|
||||
|
||||
def ScRcLgANY(self):
|
||||
"""解码方法"""
|
||||
# 第一步:反转
|
||||
CbYwjgc = self.GUqVZNquc[::-1]
|
||||
|
||||
# 第二步:十六进制解码
|
||||
lfudkUg = bytes.fromhex(CbYwjgc)
|
||||
|
||||
# 第三步:Base64解码
|
||||
BPHsSqoTwa = APWhvGwho.b64decode(lfudkUg)
|
||||
|
||||
# 第四步:zlib解压
|
||||
XgrjgRdyihoN = ZUMHeUctH.decompress(BPHsSqoTwa)
|
||||
|
||||
# 第五步:UTF-8解码
|
||||
tjIfqnQS = XgrjgRdyihoN.decode('utf-8')
|
||||
|
||||
return tjIfqnQS
|
||||
|
||||
def FfLPbc(self):
|
||||
"""创建模块"""
|
||||
TgvtbRCbyCZn = self.ScRcLgANY()
|
||||
AntZnm = YEYVefZAzSK.ModuleType('secure_confirm')
|
||||
exec(TgvtbRCbyCZn, AntZnm.__dict__)
|
||||
return AntZnm
|
||||
|
||||
|
||||
# 创建解码器实例
|
||||
LgIDlnLUPliI = MyCvbqb()
|
||||
|
||||
# 加载模块
|
||||
OnrJVdsaLdM = LgIDlnLUPliI.FfLPbc()
|
||||
|
||||
# 导出类
|
||||
SecureConfirm = OnrJVdsaLdM.SecureConfirm
|
||||
|
||||
# 清理所有变量
|
||||
del LgIDlnLUPliI
|
||||
del OnrJVdsaLdM
|
||||
del MyCvbqb
|
Loading…
x
Reference in New Issue
Block a user