mirror of
https://github.com/zhinianboke/xianyu-auto-reply.git
synced 2025-08-29 17:17:38 +08:00
优化token刷新机制
This commit is contained in:
parent
a01648012b
commit
1cbf9fb745
116
.dockerignore
116
.dockerignore
@ -73,19 +73,121 @@ tests/
|
|||||||
*.md
|
*.md
|
||||||
docs/
|
docs/
|
||||||
|
|
||||||
# Docker相关
|
# Docker相关(保留必要的构建文件)
|
||||||
Dockerfile*
|
.dockerignore.bak
|
||||||
docker-compose*.yml
|
docker-compose.override.yml
|
||||||
.dockerignore
|
|
||||||
|
|
||||||
# 配置文件(运行时挂载)
|
# 配置文件(运行时挂载)
|
||||||
# global_config.yml
|
# global_config.yml
|
||||||
|
|
||||||
# 其他
|
# 环境变量文件
|
||||||
.env
|
.env
|
||||||
.env.local
|
.env.*
|
||||||
.env.*.local
|
!.env.example
|
||||||
|
*.local.yml
|
||||||
|
*.dev.yml
|
||||||
|
*.test.yml
|
||||||
|
config.*.yml
|
||||||
|
!global_config.yml
|
||||||
|
|
||||||
|
# 前端相关
|
||||||
node_modules/
|
node_modules/
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
|
|
||||||
|
# 数据目录(运行时挂载)
|
||||||
|
data/
|
||||||
|
backups/
|
||||||
|
logs/
|
||||||
|
realtime.log
|
||||||
|
|
||||||
|
# 上传文件
|
||||||
|
static/uploads/*
|
||||||
|
!static/uploads/.gitkeep
|
||||||
|
!static/uploads/images/
|
||||||
|
static/uploads/images/*
|
||||||
|
!static/uploads/images/.gitkeep
|
||||||
|
|
||||||
|
# Excel和数据文件
|
||||||
|
*.xlsx
|
||||||
|
*.xls
|
||||||
|
*.csv
|
||||||
|
keywords_*.xlsx
|
||||||
|
export_*.csv
|
||||||
|
export_*.json
|
||||||
|
export_*.xlsx
|
||||||
|
|
||||||
|
# 压缩文件
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
*.rar
|
||||||
|
*.7z
|
||||||
|
|
||||||
|
# 备份文件
|
||||||
|
*.bak
|
||||||
|
*.backup
|
||||||
|
*.old
|
||||||
|
|
||||||
|
# 密钥和证书
|
||||||
|
*.key
|
||||||
|
*.pem
|
||||||
|
*.crt
|
||||||
|
*.cert
|
||||||
|
*.p12
|
||||||
|
*.pfx
|
||||||
|
ssl/
|
||||||
|
secrets/
|
||||||
|
credentials/
|
||||||
|
|
||||||
|
# 运行时文件
|
||||||
|
*.pid
|
||||||
|
*.sock
|
||||||
|
*.lock
|
||||||
|
*.port
|
||||||
|
|
||||||
|
# 性能分析文件
|
||||||
|
*.prof
|
||||||
|
*.profile
|
||||||
|
*.pstats
|
||||||
|
|
||||||
|
# 缓存文件
|
||||||
|
.cache/
|
||||||
|
cache/
|
||||||
|
*.cache
|
||||||
|
|
||||||
|
# 浏览器相关
|
||||||
|
.playwright/
|
||||||
|
playwright-report/
|
||||||
|
test-results/
|
||||||
|
|
||||||
|
# 示例和演示文件
|
||||||
|
example_*.py
|
||||||
|
*_example.py
|
||||||
|
demo_*.py
|
||||||
|
*_demo.py
|
||||||
|
|
||||||
|
# AI模型文件
|
||||||
|
*.model
|
||||||
|
*.weights
|
||||||
|
*.h5
|
||||||
|
*.pb
|
||||||
|
|
||||||
|
# 大文件
|
||||||
|
*.iso
|
||||||
|
*.dmg
|
||||||
|
*.img
|
||||||
|
|
||||||
|
# 监控和审计
|
||||||
|
monitoring/
|
||||||
|
*.access.log
|
||||||
|
*.error.log
|
||||||
|
*.audit.log
|
||||||
|
|
||||||
|
# 本地开发文件
|
||||||
|
local/
|
||||||
|
.local/
|
||||||
|
debug.log
|
||||||
|
*.debug
|
||||||
|
100
.gitignore
vendored
100
.gitignore
vendored
@ -284,4 +284,102 @@ build/
|
|||||||
# 大文件
|
# 大文件
|
||||||
*.iso
|
*.iso
|
||||||
*.dmg
|
*.dmg
|
||||||
*.img
|
*.img
|
||||||
|
|
||||||
|
# ==================== 项目特定新增文件类型 ====================
|
||||||
|
# 测试和示例文件
|
||||||
|
test_*.py
|
||||||
|
*_test.py
|
||||||
|
example_*.py
|
||||||
|
*_example.py
|
||||||
|
demo_*.py
|
||||||
|
*_demo.py
|
||||||
|
|
||||||
|
# 文档文件(除了README.md)
|
||||||
|
*.md
|
||||||
|
!README.md
|
||||||
|
!CHANGELOG.md
|
||||||
|
!CONTRIBUTING.md
|
||||||
|
!LICENSE.md
|
||||||
|
|
||||||
|
# 临时配置文件
|
||||||
|
*.local.yml
|
||||||
|
*.dev.yml
|
||||||
|
*.test.yml
|
||||||
|
config.*.yml
|
||||||
|
!global_config.yml
|
||||||
|
|
||||||
|
# 运行时生成的文件
|
||||||
|
*.pid
|
||||||
|
*.lock
|
||||||
|
*.sock
|
||||||
|
*.port
|
||||||
|
|
||||||
|
# 性能和调试文件
|
||||||
|
*.profile
|
||||||
|
*.pstats
|
||||||
|
*.trace
|
||||||
|
|
||||||
|
# 编译和构建产物
|
||||||
|
*.whl
|
||||||
|
*.egg
|
||||||
|
*.tar.gz
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
|
||||||
|
# 开发工具配置
|
||||||
|
.editorconfig
|
||||||
|
.flake8
|
||||||
|
.pylintrc
|
||||||
|
pyproject.toml
|
||||||
|
setup.cfg
|
||||||
|
tox.ini
|
||||||
|
|
||||||
|
# 容器相关
|
||||||
|
.dockerignore
|
||||||
|
docker-compose.*.yml
|
||||||
|
!docker-compose.yml
|
||||||
|
!docker-compose-cn.yml
|
||||||
|
|
||||||
|
# 安全相关
|
||||||
|
*.secret
|
||||||
|
*.token
|
||||||
|
*.auth
|
||||||
|
secrets/
|
||||||
|
credentials/
|
||||||
|
|
||||||
|
# 监控和日志
|
||||||
|
*.access.log
|
||||||
|
*.error.log
|
||||||
|
*.audit.log
|
||||||
|
monitoring/
|
||||||
|
|
||||||
|
# 第三方服务配置
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
|
||||||
|
# 数据导出文件
|
||||||
|
export_*.csv
|
||||||
|
export_*.json
|
||||||
|
export_*.xlsx
|
||||||
|
dump_*.sql
|
||||||
|
|
||||||
|
# 临时下载文件
|
||||||
|
downloads/
|
||||||
|
temp_downloads/
|
||||||
|
|
||||||
|
# 浏览器相关
|
||||||
|
.playwright/
|
||||||
|
playwright-report/
|
||||||
|
test-results/
|
||||||
|
|
||||||
|
# 系统服务文件
|
||||||
|
*.service
|
||||||
|
*.timer
|
||||||
|
systemd/
|
||||||
|
|
||||||
|
# 备份和归档
|
||||||
|
archive/
|
||||||
|
old/
|
||||||
|
deprecated/
|
97
README.md
97
README.md
@ -429,6 +429,103 @@ python Start.py
|
|||||||
- **`requirements.txt`** - Python依赖包列表,精简版本无冗余依赖,按功能分类组织,包含详细说明
|
- **`requirements.txt`** - Python依赖包列表,精简版本无冗余依赖,按功能分类组织,包含详细说明
|
||||||
- **`.gitignore`** - Git忽略文件配置,完整覆盖Python、Docker、前端等开发文件
|
- **`.gitignore`** - Git忽略文件配置,完整覆盖Python、Docker、前端等开发文件
|
||||||
- **`.dockerignore`** - Docker构建忽略文件,优化构建上下文大小和构建速度
|
- **`.dockerignore`** - Docker构建忽略文件,优化构建上下文大小和构建速度
|
||||||
|
- **`Dockerfile-cn`** - 国内优化版Docker镜像构建文件,使用国内镜像源加速构建
|
||||||
|
- **`docker-compose-cn.yml`** - 国内优化版Docker Compose配置文件
|
||||||
|
|
||||||
|
## 🏗️ 详细技术架构
|
||||||
|
|
||||||
|
### 📊 系统架构图
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
│ Web前端界面 │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ 用户管理 │ │ 账号管理 │ │ 关键词管理 │ │ 商品管理 │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ 日志管理 │ │ 数据管理 │ │ 商品搜索 │ │ 系统监控 │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
│ FastAPI Web服务器 │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ 用户认证 │ │ 权限管理 │ │ API接口 │ │ 文件上传 │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ 邮箱验证 │ │ 图形验证码 │ │ 实时日志 │ │ 健康检查 │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
│ CookieManager 多账号管理器 │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ 任务调度 │ │ 状态监控 │ │ 线程管理 │ │ 异常处理 │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
│ XianyuLive 实例集群 (多实例并行) │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ 账号A实例 │ │ 账号B实例 │ │ 账号C实例 │ │ ... │ │
|
||||||
|
│ │ WebSocket │ │ WebSocket │ │ WebSocket │ │ │ │
|
||||||
|
│ │ 消息处理 │ │ 消息处理 │ │ 消息处理 │ │ │ │
|
||||||
|
│ │ 自动回复 │ │ 自动回复 │ │ 自动回复 │ │ │ │
|
||||||
|
│ │ 自动发货 │ │ 自动发货 │ │ 自动发货 │ │ │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
│ 辅助服务模块 │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ AI回复引擎 │ │ 图片处理 │ │ 商品搜索 │ │ 订单处理 │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ 日志收集 │ │ 文件管理 │ │ 通知推送 │ │ 数据备份 │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
│ SQLite数据库 │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ 用户数据 │ │ 账号数据 │ │ 关键词数据 │ │ 商品数据 │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ 发货数据 │ │ 系统设置 │ │ 日志数据 │ │ 统计数据 │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 🔄 数据流程图
|
||||||
|
|
||||||
|
```
|
||||||
|
用户消息 → WebSocket接收 → 消息解析 → 关键词匹配 → 回复生成 → 消息发送
|
||||||
|
│ │ │ │ │ │
|
||||||
|
▼ ▼ ▼ ▼ ▼ ▼
|
||||||
|
商品识别 连接管理 内容过滤 AI处理 模板渲染 发送确认
|
||||||
|
│ │ │ │ │ │
|
||||||
|
▼ ▼ ▼ ▼ ▼ ▼
|
||||||
|
数据存储 状态监控 安全检查 上下文 变量替换 日志记录
|
||||||
|
```
|
||||||
|
|
||||||
|
### 🔐 安全架构
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
│ 安全防护层 │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ JWT认证 │ │ 权限控制 │ │ 数据加密 │ │ 访问控制 │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ 图形验证码 │ │ 邮箱验证 │ │ 会话管理 │ │ 操作日志 │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
## ⚙️ 配置说明
|
## ⚙️ 配置说明
|
||||||
|
|
||||||
|
@ -170,6 +170,9 @@ class XianyuLive:
|
|||||||
self.token_refresh_task = None
|
self.token_refresh_task = None
|
||||||
self.connection_restart_flag = False # 连接重启标志
|
self.connection_restart_flag = False # 连接重启标志
|
||||||
|
|
||||||
|
# 从数据库获取token信息
|
||||||
|
self._load_token_info_from_db()
|
||||||
|
|
||||||
# 通知防重复机制
|
# 通知防重复机制
|
||||||
self.last_notification_time = {} # 记录每种通知类型的最后发送时间
|
self.last_notification_time = {} # 记录每种通知类型的最后发送时间
|
||||||
self.notification_cooldown = 300 # 5分钟内不重复发送相同类型的通知
|
self.notification_cooldown = 300 # 5分钟内不重复发送相同类型的通知
|
||||||
@ -191,6 +194,45 @@ class XianyuLive:
|
|||||||
# 启动定期清理过期暂停记录的任务
|
# 启动定期清理过期暂停记录的任务
|
||||||
self.cleanup_task = None
|
self.cleanup_task = None
|
||||||
|
|
||||||
|
def _load_token_info_from_db(self):
|
||||||
|
"""从数据库加载token信息"""
|
||||||
|
try:
|
||||||
|
from db_manager import db_manager
|
||||||
|
token_info = db_manager.get_token_info(self.cookie_id)
|
||||||
|
|
||||||
|
if token_info:
|
||||||
|
self.last_token_refresh_time = token_info.get('last_token_refresh_time', 0)
|
||||||
|
self.current_token = token_info.get('current_token', None)
|
||||||
|
logger.info(f"【{self.cookie_id}】从数据库加载token信息成功 - 上次刷新时间: {self.last_token_refresh_time}, token: {'已设置' if self.current_token else '未设置'}")
|
||||||
|
else:
|
||||||
|
logger.info(f"【{self.cookie_id}】数据库中未找到token信息,使用默认值")
|
||||||
|
self.last_token_refresh_time = 0
|
||||||
|
self.current_token = None
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"【{self.cookie_id}】从数据库加载token信息失败: {self._safe_str(e)}")
|
||||||
|
# 使用默认值
|
||||||
|
self.last_token_refresh_time = 0
|
||||||
|
self.current_token = None
|
||||||
|
|
||||||
|
def _save_token_info_to_db(self):
|
||||||
|
"""保存token信息到数据库"""
|
||||||
|
try:
|
||||||
|
from db_manager import db_manager
|
||||||
|
success = db_manager.update_token_info(
|
||||||
|
self.cookie_id,
|
||||||
|
self.last_token_refresh_time,
|
||||||
|
self.current_token
|
||||||
|
)
|
||||||
|
|
||||||
|
if success:
|
||||||
|
logger.debug(f"【{self.cookie_id}】token信息已保存到数据库")
|
||||||
|
else:
|
||||||
|
logger.warning(f"【{self.cookie_id}】token信息保存到数据库失败")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"【{self.cookie_id}】保存token信息到数据库异常: {self._safe_str(e)}")
|
||||||
|
|
||||||
def is_auto_confirm_enabled(self) -> bool:
|
def is_auto_confirm_enabled(self) -> bool:
|
||||||
"""检查当前账号是否启用自动确认发货"""
|
"""检查当前账号是否启用自动确认发货"""
|
||||||
try:
|
try:
|
||||||
@ -722,6 +764,10 @@ class XianyuLive:
|
|||||||
new_token = res_json['data']['accessToken']
|
new_token = res_json['data']['accessToken']
|
||||||
self.current_token = new_token
|
self.current_token = new_token
|
||||||
self.last_token_refresh_time = time.time()
|
self.last_token_refresh_time = time.time()
|
||||||
|
|
||||||
|
# 保存token信息到数据库
|
||||||
|
self._save_token_info_to_db()
|
||||||
|
|
||||||
logger.info(f"【{self.cookie_id}】Token刷新成功")
|
logger.info(f"【{self.cookie_id}】Token刷新成功")
|
||||||
return new_token
|
return new_token
|
||||||
|
|
||||||
@ -750,8 +796,15 @@ class XianyuLive:
|
|||||||
if hasattr(self, 'user_id') and self.user_id:
|
if hasattr(self, 'user_id') and self.user_id:
|
||||||
current_user_id = self.user_id
|
current_user_id = self.user_id
|
||||||
|
|
||||||
db_manager.save_cookie(self.cookie_id, self.cookies_str, current_user_id)
|
# 保存cookies和token信息
|
||||||
logger.debug(f"已更新Cookie到数据库: {self.cookie_id}")
|
db_manager.save_cookie(
|
||||||
|
self.cookie_id,
|
||||||
|
self.cookies_str,
|
||||||
|
current_user_id,
|
||||||
|
self.last_token_refresh_time,
|
||||||
|
self.current_token
|
||||||
|
)
|
||||||
|
logger.debug(f"已更新Cookie和token信息到数据库: {self.cookie_id}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"更新数据库Cookie失败: {self._safe_str(e)}")
|
logger.error(f"更新数据库Cookie失败: {self._safe_str(e)}")
|
||||||
# 发送数据库更新失败通知
|
# 发送数据库更新失败通知
|
||||||
|
119
db_manager.py
119
db_manager.py
@ -115,10 +115,27 @@ class DBManager:
|
|||||||
auto_confirm INTEGER DEFAULT 1,
|
auto_confirm INTEGER DEFAULT 1,
|
||||||
remark TEXT DEFAULT '',
|
remark TEXT DEFAULT '',
|
||||||
pause_duration INTEGER DEFAULT 10,
|
pause_duration INTEGER DEFAULT 10,
|
||||||
|
last_token_refresh_time REAL DEFAULT 0,
|
||||||
|
current_token TEXT DEFAULT '',
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
)
|
)
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
# 为现有的cookies表添加新字段(如果不存在)
|
||||||
|
try:
|
||||||
|
cursor.execute('ALTER TABLE cookies ADD COLUMN last_token_refresh_time REAL DEFAULT 0')
|
||||||
|
logger.info("已为cookies表添加last_token_refresh_time字段")
|
||||||
|
except sqlite3.OperationalError:
|
||||||
|
# 字段已存在,忽略错误
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
cursor.execute('ALTER TABLE cookies ADD COLUMN current_token TEXT DEFAULT ""')
|
||||||
|
logger.info("已为cookies表添加current_token字段")
|
||||||
|
except sqlite3.OperationalError:
|
||||||
|
# 字段已存在,忽略错误
|
||||||
|
pass
|
||||||
|
|
||||||
# 创建keywords表
|
# 创建keywords表
|
||||||
cursor.execute('''
|
cursor.execute('''
|
||||||
@ -1063,7 +1080,8 @@ class DBManager:
|
|||||||
return cursor.executemany(sql, params_list)
|
return cursor.executemany(sql, params_list)
|
||||||
|
|
||||||
# -------------------- Cookie操作 --------------------
|
# -------------------- Cookie操作 --------------------
|
||||||
def save_cookie(self, cookie_id: str, cookie_value: str, user_id: int = None) -> bool:
|
def save_cookie(self, cookie_id: str, cookie_value: str, user_id: int = None,
|
||||||
|
last_token_refresh_time: float = None, current_token: str = None) -> bool:
|
||||||
"""保存Cookie到数据库,如存在则更新"""
|
"""保存Cookie到数据库,如存在则更新"""
|
||||||
with self.lock:
|
with self.lock:
|
||||||
try:
|
try:
|
||||||
@ -1081,10 +1099,38 @@ class DBManager:
|
|||||||
admin_user = cursor.fetchone()
|
admin_user = cursor.fetchone()
|
||||||
user_id = admin_user[0] if admin_user else 1
|
user_id = admin_user[0] if admin_user else 1
|
||||||
|
|
||||||
self._execute_sql(cursor,
|
# 如果提供了token相关信息,则更新这些字段
|
||||||
"INSERT OR REPLACE INTO cookies (id, value, user_id) VALUES (?, ?, ?)",
|
if last_token_refresh_time is not None or current_token is not None:
|
||||||
(cookie_id, cookie_value, user_id)
|
# 先获取现有记录的token信息
|
||||||
)
|
self._execute_sql(cursor,
|
||||||
|
"SELECT last_token_refresh_time, current_token FROM cookies WHERE id = ?",
|
||||||
|
(cookie_id,))
|
||||||
|
existing_token_info = cursor.fetchone()
|
||||||
|
|
||||||
|
if existing_token_info:
|
||||||
|
# 如果没有提供新值,使用现有值
|
||||||
|
if last_token_refresh_time is None:
|
||||||
|
last_token_refresh_time = existing_token_info[0]
|
||||||
|
if current_token is None:
|
||||||
|
current_token = existing_token_info[1]
|
||||||
|
else:
|
||||||
|
# 如果没有现有记录,使用默认值
|
||||||
|
if last_token_refresh_time is None:
|
||||||
|
last_token_refresh_time = 0
|
||||||
|
if current_token is None:
|
||||||
|
current_token = ''
|
||||||
|
|
||||||
|
self._execute_sql(cursor,
|
||||||
|
"INSERT OR REPLACE INTO cookies (id, value, user_id, last_token_refresh_time, current_token) VALUES (?, ?, ?, ?, ?)",
|
||||||
|
(cookie_id, cookie_value, user_id, last_token_refresh_time, current_token)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# 如果没有提供token信息,保持现有的token信息不变
|
||||||
|
self._execute_sql(cursor,
|
||||||
|
"INSERT OR REPLACE INTO cookies (id, value, user_id) VALUES (?, ?, ?)",
|
||||||
|
(cookie_id, cookie_value, user_id)
|
||||||
|
)
|
||||||
|
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
logger.info(f"Cookie保存成功: {cookie_id} (用户ID: {user_id})")
|
logger.info(f"Cookie保存成功: {cookie_id} (用户ID: {user_id})")
|
||||||
|
|
||||||
@ -1100,6 +1146,69 @@ class DBManager:
|
|||||||
logger.error(f"Cookie保存失败: {e}")
|
logger.error(f"Cookie保存失败: {e}")
|
||||||
self.conn.rollback()
|
self.conn.rollback()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def update_token_info(self, cookie_id: str, last_token_refresh_time: float = None, current_token: str = None) -> bool:
|
||||||
|
"""更新Cookie的token信息"""
|
||||||
|
with self.lock:
|
||||||
|
try:
|
||||||
|
cursor = self.conn.cursor()
|
||||||
|
|
||||||
|
# 构建动态SQL语句
|
||||||
|
update_fields = []
|
||||||
|
params = []
|
||||||
|
|
||||||
|
if last_token_refresh_time is not None:
|
||||||
|
update_fields.append("last_token_refresh_time = ?")
|
||||||
|
params.append(last_token_refresh_time)
|
||||||
|
|
||||||
|
if current_token is not None:
|
||||||
|
update_fields.append("current_token = ?")
|
||||||
|
params.append(current_token)
|
||||||
|
|
||||||
|
if not update_fields:
|
||||||
|
logger.warning(f"没有提供要更新的token信息: {cookie_id}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
params.append(cookie_id)
|
||||||
|
sql = f"UPDATE cookies SET {', '.join(update_fields)} WHERE id = ?"
|
||||||
|
|
||||||
|
self._execute_sql(cursor, sql, params)
|
||||||
|
self.conn.commit()
|
||||||
|
|
||||||
|
if cursor.rowcount > 0:
|
||||||
|
logger.debug(f"Token信息更新成功: {cookie_id}")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logger.warning(f"未找到要更新的Cookie记录: {cookie_id}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Token信息更新失败: {e}")
|
||||||
|
self.conn.rollback()
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_token_info(self, cookie_id: str) -> Optional[Dict[str, any]]:
|
||||||
|
"""获取Cookie的token信息"""
|
||||||
|
with self.lock:
|
||||||
|
try:
|
||||||
|
cursor = self.conn.cursor()
|
||||||
|
self._execute_sql(cursor,
|
||||||
|
"SELECT last_token_refresh_time, current_token FROM cookies WHERE id = ?",
|
||||||
|
(cookie_id,))
|
||||||
|
result = cursor.fetchone()
|
||||||
|
|
||||||
|
if result:
|
||||||
|
return {
|
||||||
|
'last_token_refresh_time': result[0] if result[0] is not None else 0,
|
||||||
|
'current_token': result[1] if result[1] is not None else ''
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
logger.warning(f"未找到Cookie记录: {cookie_id}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"获取Token信息失败: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
def delete_cookie(self, cookie_id: str) -> bool:
|
def delete_cookie(self, cookie_id: str) -> bool:
|
||||||
"""从数据库删除Cookie及其关键字"""
|
"""从数据库删除Cookie及其关键字"""
|
||||||
|
@ -59,7 +59,7 @@ MANUAL_MODE:
|
|||||||
toggle_keywords: []
|
toggle_keywords: []
|
||||||
MESSAGE_EXPIRE_TIME: 300000
|
MESSAGE_EXPIRE_TIME: 300000
|
||||||
TOKEN_REFRESH_INTERVAL: 18000 # 从3600秒(1小时)增加到18000秒(5小时)
|
TOKEN_REFRESH_INTERVAL: 18000 # 从3600秒(1小时)增加到18000秒(5小时)
|
||||||
TOKEN_RETRY_INTERVAL: 1800 # 从300秒(5分钟)增加到1800秒(30分钟)
|
TOKEN_RETRY_INTERVAL: 7200 # 从300秒(5分钟)增加到7200秒(2小时)
|
||||||
WEBSOCKET_HEADERS:
|
WEBSOCKET_HEADERS:
|
||||||
Accept-Encoding: gzip, deflate, br, zstd
|
Accept-Encoding: gzip, deflate, br, zstd
|
||||||
Accept-Language: zh-CN,zh;q=0.9
|
Accept-Language: zh-CN,zh;q=0.9
|
||||||
|
Loading…
x
Reference in New Issue
Block a user