mirror of
https://github.com/zhinianboke/xianyu-auto-reply.git
synced 2025-08-30 01:27:35 +08:00
优化结构
This commit is contained in:
parent
5b2a991f41
commit
a525675e73
202
.gitignore
vendored
202
.gitignore
vendored
@ -104,4 +104,204 @@ keywords_sample.xlsx
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
*.7z
|
||||
*.7z
|
||||
|
||||
# ==================== 新增忽略项 ====================
|
||||
# Python 字节码和缓存
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# 分发/打包
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# 单元测试/覆盖率报告
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# pipenv
|
||||
Pipfile.lock
|
||||
|
||||
# PEP 582
|
||||
__pypackages__/
|
||||
|
||||
# Celery
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# ==================== 项目特定新增 ====================
|
||||
# 环境变量文件
|
||||
.env.example
|
||||
.env.*.example
|
||||
|
||||
# 数据库文件
|
||||
*.db-journal
|
||||
*.db-wal
|
||||
*.db-shm
|
||||
|
||||
# 临时文件和缓存
|
||||
*.cache
|
||||
.cache/
|
||||
cache/
|
||||
|
||||
# 编辑器临时文件
|
||||
*.swp
|
||||
*.swo
|
||||
*.tmp
|
||||
*~
|
||||
.#*
|
||||
|
||||
# 系统文件
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
desktop.ini
|
||||
|
||||
# 文档生成
|
||||
docs/_build/
|
||||
docs/build/
|
||||
|
||||
# 密钥和证书
|
||||
*.key
|
||||
*.pem
|
||||
*.crt
|
||||
*.cert
|
||||
*.p12
|
||||
*.pfx
|
||||
|
||||
# 配置文件备份
|
||||
*.conf.bak
|
||||
*.config.bak
|
||||
|
||||
# 运行时文件
|
||||
*.pid
|
||||
*.sock
|
||||
|
||||
# 调试文件
|
||||
debug.log
|
||||
*.debug
|
||||
|
||||
# 性能分析文件
|
||||
*.prof
|
||||
|
||||
# 本地开发文件
|
||||
local/
|
||||
.local/
|
||||
|
||||
# Docker相关
|
||||
.dockerignore.bak
|
||||
docker-compose.override.yml
|
||||
|
||||
# 版本控制
|
||||
.svn/
|
||||
.hg/
|
||||
.bzr/
|
||||
|
||||
# 包管理器
|
||||
node_modules/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
|
||||
# 前端构建
|
||||
dist/
|
||||
build/
|
||||
.next/
|
||||
.nuxt/
|
||||
.vuepress/dist
|
||||
|
||||
# 移动端
|
||||
*.apk
|
||||
*.ipa
|
||||
*.app
|
||||
|
||||
# 数据文件
|
||||
*.csv.bak
|
||||
*.json.bak
|
||||
*.xml.bak
|
||||
|
||||
# 媒体文件缓存
|
||||
*.mp4.cache
|
||||
*.mp3.cache
|
||||
*.wav.cache
|
||||
*.avi.cache
|
||||
|
||||
# AI模型文件
|
||||
*.model
|
||||
*.weights
|
||||
*.h5
|
||||
*.pb
|
||||
|
||||
# 大文件
|
||||
*.iso
|
||||
*.dmg
|
||||
*.img
|
48
README.md
48
README.md
@ -25,12 +25,13 @@
|
||||
|
||||
### 🤖 智能回复系统
|
||||
- **关键词匹配** - 支持精确关键词匹配回复
|
||||
- **商品专用回复** - 支持为特定商品设置专用关键词回复
|
||||
- **指定商品回复** - 支持为特定商品设置专门的回复内容,优先级最高
|
||||
- **商品专用关键词** - 支持为特定商品设置专用关键词回复
|
||||
- **通用关键词** - 支持全局通用关键词,适用于所有商品
|
||||
- **批量导入导出** - 支持Excel格式的关键词批量导入导出
|
||||
- **AI智能回复** - 集成OpenAI API,支持上下文理解
|
||||
- **变量替换** - 回复内容支持动态变量(用户名、商品信息等)
|
||||
- **优先级策略** - 商品专用关键词 > 通用关键词 > AI回复
|
||||
- **变量替换** - 回复内容支持动态变量(用户名、商品信息、商品ID等)
|
||||
- **优先级策略** - 指定商品回复 > 商品专用关键词 > 通用关键词 > 默认回复 > AI回复
|
||||
|
||||
### 🚚 自动发货功能
|
||||
- **智能匹配** - 基于商品信息自动匹配发货规则
|
||||
@ -41,8 +42,9 @@
|
||||
- **防重复发货** - 智能防重复机制,避免重复发货
|
||||
- **多种发货方式** - 支持固定文字、批量数据、API调用、图片发货等方式
|
||||
- **图片发货** - 支持上传图片并自动发送给买家,图片自动上传到CDN
|
||||
- **自动确认发货** - 检测到付款后自动调用闲鱼API确认发货
|
||||
- **自动确认发货** - 检测到付款后自动调用闲鱼API确认发货,支持锁机制防并发
|
||||
- **防重复确认** - 智能防重复确认机制,避免重复API调用
|
||||
- **订单详情缓存** - 订单详情获取支持数据库缓存,大幅提升性能
|
||||
- **发货统计** - 完整的发货记录和统计功能
|
||||
|
||||
### 🛍️ 商品管理
|
||||
@ -359,31 +361,31 @@ python Start.py
|
||||
## 📁 核心文件功能说明
|
||||
|
||||
### 🚀 核心启动模块
|
||||
- **`Start.py`** - 项目启动入口,初始化CookieManager和FastAPI服务,从数据库加载账号任务并启动后台API服务
|
||||
- **`XianyuAutoAsync.py`** - 闲鱼WebSocket连接核心,处理消息收发、自动回复、自动发货、商品信息收集
|
||||
- **`reply_server.py`** - FastAPI Web服务器,提供完整的管理界面和RESTful API接口,支持多用户系统
|
||||
- **`cookie_manager.py`** - 多账号Cookie管理器,负责账号任务的启动、停止、状态管理和线程安全操作
|
||||
- **`Start.py`** - 项目启动入口,初始化CookieManager和FastAPI服务,从数据库加载账号任务并启动后台API服务,支持环境变量配置
|
||||
- **`XianyuAutoAsync.py`** - 闲鱼WebSocket连接核心,处理消息收发、自动回复、指定商品回复、自动发货、商品信息收集、AI回复
|
||||
- **`reply_server.py`** - FastAPI Web服务器,提供完整的管理界面和RESTful API接口,支持多用户系统、JWT认证、权限管理
|
||||
- **`cookie_manager.py`** - 多账号Cookie管理器,负责账号任务的启动、停止、状态管理和线程安全操作,支持数据库持久化
|
||||
|
||||
### 🗄️ 数据和配置管理
|
||||
- **`db_manager.py`** - SQLite数据库管理器,支持多用户数据隔离、自动迁移、版本管理、完整的CRUD操作
|
||||
- **`config.py`** - 全局配置文件管理器,加载YAML配置和环境变量,提供配置项访问接口
|
||||
- **`global_config.yml`** - 全局配置文件,包含WebSocket、API、自动回复、AI等所有系统配置项
|
||||
- **`db_manager.py`** - SQLite数据库管理器,支持多用户数据隔离、自动迁移、版本管理、完整的CRUD操作、邮箱验证、系统设置
|
||||
- **`config.py`** - 全局配置文件管理器,加载YAML配置和环境变量,提供配置项访问接口,支持动态配置更新
|
||||
- **`global_config.yml`** - 全局配置文件,包含WebSocket、API、自动回复、AI、通知等所有系统配置项
|
||||
|
||||
### 🤖 智能功能模块
|
||||
- **`ai_reply_engine.py`** - AI智能回复引擎,支持OpenAI、通义千问等多种AI模型,意图识别和上下文管理
|
||||
- **`secure_confirm_ultra.py`** - 自动确认发货模块,采用多层加密保护,调用闲鱼API确认发货状态
|
||||
- **`secure_freeshipping_ultra.py`** - 自动免拼发货模块,支持批量处理、异常恢复和智能匹配
|
||||
- **`file_log_collector.py`** - 实时日志收集器,提供Web界面日志查看、搜索和管理功能
|
||||
- **`ai_reply_engine.py`** - AI智能回复引擎,支持OpenAI、通义千问等多种AI模型,意图识别、上下文管理、个性化回复
|
||||
- **`secure_confirm_ultra.py`** - 自动确认发货模块,采用多层加密保护,调用闲鱼API确认发货状态,支持锁机制防并发
|
||||
- **`secure_freeshipping_ultra.py`** - 自动免拼发货模块,支持批量处理、异常恢复、智能匹配、规格识别
|
||||
- **`file_log_collector.py`** - 实时日志收集器,提供Web界面日志查看、搜索、过滤、下载和管理功能
|
||||
|
||||
### 🛠️ 工具模块 (`utils/`)
|
||||
- **`xianyu_utils.py`** - 闲鱼API核心工具,包含加密算法、签名生成、数据解析、Cookie处理
|
||||
- **`message_utils.py`** - 消息处理工具,格式化消息内容、变量替换、内容过滤和模板渲染
|
||||
- **`ws_utils.py`** - WebSocket客户端封装,处理连接管理、心跳检测、重连机制和消息队列
|
||||
- **`qr_login.py`** - 二维码登录功能,生成登录二维码、状态检测、Cookie获取和验证
|
||||
- **`item_search.py`** - 商品搜索功能,基于Playwright获取真实闲鱼商品数据,支持分页和过滤
|
||||
- **`order_detail_fetcher.py`** - 订单详情获取工具,解析订单信息、买家信息、SKU详情,支持缓存优化
|
||||
- **`image_utils.py`** - 图片处理工具,支持压缩、格式转换、尺寸调整、水印添加
|
||||
- **`image_uploader.py`** - 图片上传工具,支持多种CDN服务商,自动压缩和格式优化
|
||||
- **`xianyu_utils.py`** - 闲鱼API核心工具,包含加密算法、签名生成、数据解析、Cookie处理、请求封装
|
||||
- **`message_utils.py`** - 消息处理工具,格式化消息内容、变量替换、内容过滤、模板渲染、表情处理
|
||||
- **`ws_utils.py`** - WebSocket客户端封装,处理连接管理、心跳检测、重连机制、消息队列、异常恢复
|
||||
- **`qr_login.py`** - 二维码登录功能,生成登录二维码、状态检测、Cookie获取、验证、自动刷新
|
||||
- **`item_search.py`** - 商品搜索功能,基于Playwright获取真实闲鱼商品数据,支持分页、过滤、排序
|
||||
- **`order_detail_fetcher.py`** - 订单详情获取工具,解析订单信息、买家信息、SKU详情,支持缓存优化、锁机制
|
||||
- **`image_utils.py`** - 图片处理工具,支持压缩、格式转换、尺寸调整、水印添加、质量优化
|
||||
- **`image_uploader.py`** - 图片上传工具,支持多种CDN服务商、自动压缩、格式优化、批量上传
|
||||
|
||||
### 🌐 前端界面 (`static/`)
|
||||
- **`index.html`** - 主管理界面,包含账号管理、关键词管理、系统监控、实时状态显示
|
||||
|
@ -1,171 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
检查用户凭据
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import hashlib
|
||||
|
||||
# 添加项目根目录到路径
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from db_manager import db_manager
|
||||
|
||||
|
||||
def check_users():
|
||||
"""检查用户表中的用户信息"""
|
||||
print("🔍 检查用户表中的用户信息")
|
||||
print("=" * 50)
|
||||
|
||||
try:
|
||||
cursor = db_manager.conn.cursor()
|
||||
cursor.execute("SELECT id, username, password_hash, is_admin FROM users")
|
||||
users = cursor.fetchall()
|
||||
|
||||
print(f"用户表中共有 {len(users)} 个用户:")
|
||||
for user in users:
|
||||
print(f" - 用户ID: {user[0]}")
|
||||
print(f" 用户名: {user[1]}")
|
||||
print(f" 密码哈希: {user[2][:20]}..." if user[2] else " 密码哈希: None")
|
||||
print(f" 是否管理员: {user[3]}")
|
||||
print()
|
||||
|
||||
# 测试密码验证
|
||||
if users:
|
||||
test_user = users[0]
|
||||
username = test_user[1]
|
||||
stored_hash = test_user[2]
|
||||
|
||||
print(f"🔐 测试用户 '{username}' 的密码验证:")
|
||||
|
||||
# 测试常见密码
|
||||
test_passwords = ["admin123", "admin", "123456", "password"]
|
||||
|
||||
for password in test_passwords:
|
||||
# 计算密码哈希
|
||||
password_hash = hashlib.sha256(password.encode()).hexdigest()
|
||||
|
||||
if password_hash == stored_hash:
|
||||
print(f"✅ 密码 '{password}' 匹配!")
|
||||
return username, password
|
||||
else:
|
||||
print(f"❌ 密码 '{password}' 不匹配")
|
||||
print(f" 计算哈希: {password_hash[:20]}...")
|
||||
print(f" 存储哈希: {stored_hash[:20]}...")
|
||||
|
||||
print("⚠️ 没有找到匹配的密码")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 检查用户失败: {e}")
|
||||
|
||||
return None, None
|
||||
|
||||
|
||||
def test_login_with_correct_credentials():
|
||||
"""使用正确的凭据测试登录"""
|
||||
username, password = check_users()
|
||||
|
||||
if username and password:
|
||||
print(f"\n🌐 使用正确凭据测试登录")
|
||||
print("=" * 50)
|
||||
|
||||
import requests
|
||||
|
||||
try:
|
||||
login_data = {
|
||||
"username": username,
|
||||
"password": password
|
||||
}
|
||||
response = requests.post("http://localhost:8080/login", json=login_data, timeout=10)
|
||||
print(f"登录状态码: {response.status_code}")
|
||||
print(f"登录响应: {response.text}")
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get('success'):
|
||||
token = data.get('token') or data.get('access_token')
|
||||
print(f"✅ 登录成功!Token: {token[:20]}..." if token else "✅ 登录成功但没有token")
|
||||
|
||||
if token:
|
||||
# 测试cookies/details接口
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
response = requests.get("http://localhost:8080/cookies/details", headers=headers, timeout=10)
|
||||
print(f"cookies/details状态码: {response.status_code}")
|
||||
|
||||
if response.status_code == 200:
|
||||
details = response.json()
|
||||
print(f"✅ 获取到 {len(details)} 个账号详情")
|
||||
for detail in details:
|
||||
print(f" - {detail['id']}: {'启用' if detail['enabled'] else '禁用'}")
|
||||
else:
|
||||
print(f"❌ 获取账号详情失败: {response.text}")
|
||||
else:
|
||||
print(f"❌ 登录失败: {data.get('message', '未知错误')}")
|
||||
else:
|
||||
print(f"❌ 登录请求失败: {response.status_code}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 登录测试失败: {e}")
|
||||
|
||||
|
||||
def create_test_user():
|
||||
"""创建测试用户"""
|
||||
print(f"\n🔧 创建测试用户")
|
||||
print("=" * 50)
|
||||
|
||||
try:
|
||||
# 创建一个新的测试用户
|
||||
test_username = "testuser"
|
||||
test_password = "test123"
|
||||
password_hash = hashlib.sha256(test_password.encode()).hexdigest()
|
||||
|
||||
cursor = db_manager.conn.cursor()
|
||||
cursor.execute("""
|
||||
INSERT OR REPLACE INTO users (username, password_hash, is_admin)
|
||||
VALUES (?, ?, ?)
|
||||
""", (test_username, password_hash, 1))
|
||||
db_manager.conn.commit()
|
||||
|
||||
print(f"✅ 创建测试用户成功:")
|
||||
print(f" 用户名: {test_username}")
|
||||
print(f" 密码: {test_password}")
|
||||
print(f" 密码哈希: {password_hash[:20]}...")
|
||||
|
||||
return test_username, test_password
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 创建测试用户失败: {e}")
|
||||
return None, None
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("🚀 检查用户凭据和登录问题")
|
||||
print("=" * 60)
|
||||
|
||||
# 检查现有用户
|
||||
username, password = check_users()
|
||||
|
||||
if not username:
|
||||
# 如果没有找到有效用户,创建一个测试用户
|
||||
print("\n没有找到有效的用户凭据,创建测试用户...")
|
||||
username, password = create_test_user()
|
||||
|
||||
if username and password:
|
||||
# 使用正确凭据测试登录
|
||||
test_login_with_correct_credentials()
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("🎯 检查完成!")
|
||||
print("\n📋 总结:")
|
||||
print("1. 检查了用户表中的用户信息")
|
||||
print("2. 验证了密码哈希")
|
||||
print("3. 测试了登录功能")
|
||||
print("4. 测试了cookies/details接口")
|
||||
|
||||
if username and password:
|
||||
print(f"\n✅ 可用的登录凭据:")
|
||||
print(f" 用户名: {username}")
|
||||
print(f" 密码: {password}")
|
||||
print(f"\n请使用这些凭据登录管理后台测试账号下拉框功能")
|
@ -1,192 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
检查用户表结构
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import hashlib
|
||||
|
||||
# 添加项目根目录到路径
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from db_manager import db_manager
|
||||
|
||||
|
||||
def check_user_table_structure():
|
||||
"""检查用户表结构"""
|
||||
print("🔍 检查用户表结构")
|
||||
print("=" * 50)
|
||||
|
||||
try:
|
||||
cursor = db_manager.conn.cursor()
|
||||
|
||||
# 检查用户表是否存在
|
||||
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='users'")
|
||||
table_exists = cursor.fetchone()
|
||||
|
||||
if table_exists:
|
||||
print("✅ users表存在")
|
||||
|
||||
# 检查表结构
|
||||
cursor.execute("PRAGMA table_info(users)")
|
||||
columns = cursor.fetchall()
|
||||
print("users表结构:")
|
||||
for col in columns:
|
||||
print(f" - {col[1]} ({col[2]}) - {'NOT NULL' if col[3] else 'NULL'} - {'PRIMARY KEY' if col[5] else ''}")
|
||||
|
||||
# 查看表中的数据
|
||||
cursor.execute("SELECT * FROM users")
|
||||
users = cursor.fetchall()
|
||||
print(f"\nusers表中共有 {len(users)} 条记录:")
|
||||
for i, user in enumerate(users):
|
||||
print(f" 记录{i+1}: {user}")
|
||||
|
||||
else:
|
||||
print("❌ users表不存在")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 检查用户表失败: {e}")
|
||||
|
||||
|
||||
def fix_user_table():
|
||||
"""修复用户表"""
|
||||
print("\n🔧 修复用户表")
|
||||
print("=" * 50)
|
||||
|
||||
try:
|
||||
cursor = db_manager.conn.cursor()
|
||||
|
||||
# 检查是否有is_admin列
|
||||
cursor.execute("PRAGMA table_info(users)")
|
||||
columns = cursor.fetchall()
|
||||
column_names = [col[1] for col in columns]
|
||||
|
||||
if 'is_admin' not in column_names:
|
||||
print("添加is_admin列...")
|
||||
cursor.execute("ALTER TABLE users ADD COLUMN is_admin INTEGER DEFAULT 1")
|
||||
db_manager.conn.commit()
|
||||
print("✅ 添加is_admin列成功")
|
||||
|
||||
# 检查是否有用户数据
|
||||
cursor.execute("SELECT COUNT(*) FROM users")
|
||||
user_count = cursor.fetchone()[0]
|
||||
|
||||
if user_count == 0:
|
||||
print("创建默认管理员用户...")
|
||||
username = "admin"
|
||||
password = "admin123"
|
||||
password_hash = hashlib.sha256(password.encode()).hexdigest()
|
||||
|
||||
cursor.execute("""
|
||||
INSERT INTO users (username, password_hash, is_admin)
|
||||
VALUES (?, ?, ?)
|
||||
""", (username, password_hash, 1))
|
||||
db_manager.conn.commit()
|
||||
|
||||
print(f"✅ 创建默认用户成功:")
|
||||
print(f" 用户名: {username}")
|
||||
print(f" 密码: {password}")
|
||||
|
||||
return username, password
|
||||
else:
|
||||
# 获取第一个用户并重置密码
|
||||
cursor.execute("SELECT username FROM users LIMIT 1")
|
||||
username = cursor.fetchone()[0]
|
||||
password = "admin123"
|
||||
password_hash = hashlib.sha256(password.encode()).hexdigest()
|
||||
|
||||
cursor.execute("""
|
||||
UPDATE users SET password_hash = ?, is_admin = 1
|
||||
WHERE username = ?
|
||||
""", (password_hash, username))
|
||||
db_manager.conn.commit()
|
||||
|
||||
print(f"✅ 重置用户密码成功:")
|
||||
print(f" 用户名: {username}")
|
||||
print(f" 密码: {password}")
|
||||
|
||||
return username, password
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 修复用户表失败: {e}")
|
||||
return None, None
|
||||
|
||||
|
||||
def test_login_after_fix():
|
||||
"""修复后测试登录"""
|
||||
username, password = fix_user_table()
|
||||
|
||||
if username and password:
|
||||
print(f"\n🌐 测试修复后的登录")
|
||||
print("=" * 50)
|
||||
|
||||
import requests
|
||||
|
||||
try:
|
||||
login_data = {
|
||||
"username": username,
|
||||
"password": password
|
||||
}
|
||||
response = requests.post("http://localhost:8080/login", json=login_data, timeout=10)
|
||||
print(f"登录状态码: {response.status_code}")
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
print(f"登录响应: {data}")
|
||||
|
||||
if data.get('success'):
|
||||
token = data.get('token') or data.get('access_token')
|
||||
print(f"✅ 登录成功!")
|
||||
|
||||
if token:
|
||||
print(f"Token: {token[:20]}...")
|
||||
|
||||
# 测试cookies/details接口
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
response = requests.get("http://localhost:8080/cookies/details", headers=headers, timeout=10)
|
||||
print(f"cookies/details状态码: {response.status_code}")
|
||||
|
||||
if response.status_code == 200:
|
||||
details = response.json()
|
||||
print(f"✅ 获取到 {len(details)} 个账号详情")
|
||||
|
||||
if len(details) > 0:
|
||||
print("🎉 账号下拉框应该有数据了!")
|
||||
print("账号列表:")
|
||||
for detail in details:
|
||||
status = "🟢" if detail['enabled'] else "🔴"
|
||||
print(f" {status} {detail['id']}")
|
||||
else:
|
||||
print("⚠️ 账号列表为空,但API接口正常")
|
||||
else:
|
||||
print(f"❌ 获取账号详情失败: {response.text}")
|
||||
else:
|
||||
print("⚠️ 登录成功但没有获取到token")
|
||||
else:
|
||||
print(f"❌ 登录失败: {data.get('message', '未知错误')}")
|
||||
else:
|
||||
print(f"❌ 登录请求失败: {response.status_code} - {response.text}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 登录测试失败: {e}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("🚀 检查和修复用户表")
|
||||
print("=" * 60)
|
||||
|
||||
# 检查用户表结构
|
||||
check_user_table_structure()
|
||||
|
||||
# 修复用户表并测试登录
|
||||
test_login_after_fix()
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("🎯 修复完成!")
|
||||
print("\n📋 现在可以:")
|
||||
print("1. 使用 admin/admin123 登录管理后台")
|
||||
print("2. 进入指定商品回复界面")
|
||||
print("3. 检查账号下拉框是否有数据")
|
||||
print("4. 如果仍然没有数据,请检查浏览器开发者工具")
|
@ -57,10 +57,14 @@ openpyxl>=3.1.0
|
||||
# ==================== 邮件发送 ====================
|
||||
email-validator>=2.0.0
|
||||
|
||||
# ==================== 数据处理和验证 ====================
|
||||
xlsxwriter>=3.1.0
|
||||
|
||||
# ==================== 说明 ====================
|
||||
# 以下模块是Python内置模块,无需安装:
|
||||
# sqlite3, json, base64, hashlib, hmac, time, datetime, os, sys, re, urllib
|
||||
# asyncio, threading, pathlib, uuid, random, secrets, traceback, logging
|
||||
# collections, itertools, functools, copy, pickle, gzip, zipfile, shutil
|
||||
# tempfile, io, csv, xml, html, http, socket, ssl, subprocess, signal
|
||||
# inspect, ast, enum, math, decimal, array, queue, contextlib, warnings
|
||||
# inspect, ast, enum, math, decimal, array, queue, contextlib, warnings
|
||||
# typing, dataclasses, weakref, gc, platform, stat, glob, fnmatch
|
Loading…
x
Reference in New Issue
Block a user