diff --git a/XianyuAutoAsync.py b/XianyuAutoAsync.py
index 6e8c961..a879e1f 100644
--- a/XianyuAutoAsync.py
+++ b/XianyuAutoAsync.py
@@ -110,6 +110,15 @@ class XianyuLive:
self.session = None # 用于API调用的aiohttp session
+ def is_auto_confirm_enabled(self) -> bool:
+ """检查当前账号是否启用自动确认发货"""
+ try:
+ from db_manager import db_manager
+ return db_manager.get_auto_confirm(self.cookie_id)
+ except Exception as e:
+ logger.error(f"【{self.cookie_id}】获取自动确认发货设置失败: {self._safe_str(e)}")
+ return True # 出错时默认启用
+
def can_auto_delivery(self, item_id: str) -> bool:
"""检查是否可以进行自动发货(防重复发货)"""
current_time = time.time()
@@ -2017,14 +2026,30 @@ class XianyuLive:
# 如果成功获取到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} 秒内确认过,跳过重复确认')
+ # 检查是否启用自动确认发货
+ if not self.is_auto_confirm_enabled():
+ logger.info(f'[{msg_time}] 【{self.cookie_id}】自动确认发货已关闭,跳过订单 {order_id}')
+ else:
+ # 检查是否已经确认过这个订单
+ 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)
@@ -2035,18 +2060,6 @@ class XianyuLive:
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')
@@ -2139,14 +2152,30 @@ class XianyuLive:
# 如果成功获取到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} 秒内确认过,跳过重复确认')
+ # 检查是否启用自动确认发货
+ if not self.is_auto_confirm_enabled():
+ logger.info(f'[{msg_time}] 【{self.cookie_id}】自动确认发货已关闭,跳过订单 {order_id}')
+ else:
+ # 检查是否已经确认过这个订单
+ 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)
@@ -2157,18 +2186,6 @@ class XianyuLive:
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')
@@ -2285,14 +2302,30 @@ class XianyuLive:
# 如果成功获取到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} 秒内确认过,跳过重复确认')
+ # 检查是否启用自动确认发货
+ if not self.is_auto_confirm_enabled():
+ logger.info(f'[{msg_time}] 【{self.cookie_id}】自动确认发货已关闭,跳过小刀成功订单 {order_id}')
+ else:
+ # 检查是否已经确认过这个订单
+ 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)
@@ -2303,18 +2336,6 @@ class XianyuLive:
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')
diff --git a/cookie_manager.py b/cookie_manager.py
index be721fb..f61736c 100644
--- a/cookie_manager.py
+++ b/cookie_manager.py
@@ -16,6 +16,7 @@ class CookieManager:
self.tasks: Dict[str, asyncio.Task] = {}
self.keywords: Dict[str, List[Tuple[str, str]]] = {}
self.cookie_status: Dict[str, bool] = {} # 账号启用状态
+ self.auto_confirm_settings: Dict[str, bool] = {} # 自动确认发货设置
self._load_from_db()
def _load_from_db(self):
@@ -27,11 +28,15 @@ class CookieManager:
self.keywords = db_manager.get_all_keywords()
# 加载所有Cookie状态(默认启用)
self.cookie_status = db_manager.get_all_cookie_status()
- # 为没有状态记录的Cookie设置默认启用状态
+ # 加载所有auto_confirm设置
+ self.auto_confirm_settings = {}
for cookie_id in self.cookies.keys():
+ # 为没有状态记录的Cookie设置默认启用状态
if cookie_id not in self.cookie_status:
self.cookie_status[cookie_id] = True
- logger.info(f"从数据库加载了 {len(self.cookies)} 个Cookie、{len(self.keywords)} 组关键字和 {len(self.cookie_status)} 个状态记录")
+ # 加载auto_confirm设置
+ self.auto_confirm_settings[cookie_id] = db_manager.get_auto_confirm(cookie_id)
+ logger.info(f"从数据库加载了 {len(self.cookies)} 个Cookie、{len(self.keywords)} 组关键字、{len(self.cookie_status)} 个状态记录和 {len(self.auto_confirm_settings)} 个自动确认设置")
except Exception as e:
logger.error(f"从数据库加载数据失败: {e}")
@@ -273,6 +278,25 @@ class CookieManager:
except Exception as e:
logger.error(f"停止Cookie任务失败: {cookie_id}, {e}")
+ def update_auto_confirm_setting(self, cookie_id: str, auto_confirm: bool):
+ """实时更新账号的自动确认发货设置"""
+ try:
+ # 更新内存中的设置
+ self.auto_confirm_settings[cookie_id] = auto_confirm
+ logger.info(f"更新账号 {cookie_id} 自动确认发货设置: {'开启' if auto_confirm else '关闭'}")
+
+ # 如果账号正在运行,通知XianyuLive实例更新设置
+ if cookie_id in self.tasks and not self.tasks[cookie_id].done():
+ # 这里可以通过某种方式通知正在运行的XianyuLive实例
+ # 由于XianyuLive会从数据库读取设置,所以数据库已经更新就足够了
+ logger.info(f"账号 {cookie_id} 正在运行,自动确认发货设置已实时生效")
+ except Exception as e:
+ logger.error(f"更新自动确认发货设置失败: {cookie_id}, {e}")
+
+ def get_auto_confirm_setting(self, cookie_id: str) -> bool:
+ """获取账号的自动确认发货设置"""
+ return self.auto_confirm_settings.get(cookie_id, True) # 默认开启
+
# 在 Start.py 中会把此变量赋值为具体实例
manager: Optional[CookieManager] = None
\ No newline at end of file
diff --git a/db_manager.py b/db_manager.py
index 0959903..413e5d1 100644
--- a/db_manager.py
+++ b/db_manager.py
@@ -106,12 +106,13 @@ class DBManager:
)
''')
- # 创建cookies表(添加user_id字段)
+ # 创建cookies表(添加user_id字段和auto_confirm字段)
cursor.execute('''
CREATE TABLE IF NOT EXISTS cookies (
id TEXT PRIMARY KEY,
value TEXT NOT NULL,
user_id INTEGER NOT NULL,
+ auto_confirm INTEGER DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
)
@@ -367,6 +368,17 @@ class DBManager:
# user_id列存在,更新NULL值
self._execute_sql(cursor, "UPDATE cookies SET user_id = ? WHERE user_id IS NULL", (admin_user_id,))
+ # 为cookies表添加auto_confirm字段(如果不存在)
+ try:
+ self._execute_sql(cursor, "SELECT auto_confirm FROM cookies LIMIT 1")
+ except sqlite3.OperationalError:
+ # auto_confirm列不存在,需要添加并设置默认值
+ self._execute_sql(cursor, "ALTER TABLE cookies ADD COLUMN auto_confirm INTEGER DEFAULT 1")
+ self._execute_sql(cursor, "UPDATE cookies SET auto_confirm = 1 WHERE auto_confirm IS NULL")
+ else:
+ # auto_confirm列存在,更新NULL值
+ self._execute_sql(cursor, "UPDATE cookies SET auto_confirm = 1 WHERE auto_confirm IS NULL")
+
# 为delivery_rules表添加user_id字段(如果不存在)
try:
self._execute_sql(cursor, "SELECT user_id FROM delivery_rules LIMIT 1")
@@ -576,23 +588,51 @@ class DBManager:
return None
def get_cookie_details(self, cookie_id: str) -> Optional[Dict[str, any]]:
- """获取Cookie的详细信息,包括user_id"""
+ """获取Cookie的详细信息,包括user_id和auto_confirm"""
with self.lock:
try:
cursor = self.conn.cursor()
- self._execute_sql(cursor, "SELECT id, value, user_id, created_at FROM cookies WHERE id = ?", (cookie_id,))
+ self._execute_sql(cursor, "SELECT id, value, user_id, auto_confirm, created_at FROM cookies WHERE id = ?", (cookie_id,))
result = cursor.fetchone()
if result:
return {
'id': result[0],
'value': result[1],
'user_id': result[2],
- 'created_at': result[3]
+ 'auto_confirm': bool(result[3]),
+ 'created_at': result[4]
}
return None
except Exception as e:
logger.error(f"获取Cookie详细信息失败: {e}")
return None
+
+ def update_auto_confirm(self, cookie_id: str, auto_confirm: bool) -> bool:
+ """更新Cookie的自动确认发货设置"""
+ with self.lock:
+ try:
+ cursor = self.conn.cursor()
+ self._execute_sql(cursor, "UPDATE cookies SET auto_confirm = ? WHERE id = ?", (int(auto_confirm), cookie_id))
+ self.conn.commit()
+ logger.info(f"更新账号 {cookie_id} 自动确认发货设置: {'开启' if auto_confirm else '关闭'}")
+ return True
+ except Exception as e:
+ logger.error(f"更新自动确认发货设置失败: {e}")
+ return False
+
+ def get_auto_confirm(self, cookie_id: str) -> bool:
+ """获取Cookie的自动确认发货设置"""
+ with self.lock:
+ try:
+ cursor = self.conn.cursor()
+ self._execute_sql(cursor, "SELECT auto_confirm FROM cookies WHERE id = ?", (cookie_id,))
+ result = cursor.fetchone()
+ if result:
+ return bool(result[0])
+ return True # 默认开启
+ except Exception as e:
+ logger.error(f"获取自动确认发货设置失败: {e}")
+ return True # 出错时默认开启
# -------------------- 关键字操作 --------------------
def save_keywords(self, cookie_id: str, keywords: List[Tuple[str, str]]) -> bool:
diff --git a/reply_server.py b/reply_server.py
index a0b3f11..d0baa45 100644
--- a/reply_server.py
+++ b/reply_server.py
@@ -899,10 +899,12 @@ def get_cookies_details(current_user: Dict[str, Any] = Depends(get_current_user)
result = []
for cookie_id, cookie_value in user_cookies.items():
cookie_enabled = cookie_manager.manager.get_cookie_status(cookie_id)
+ auto_confirm = db_manager.get_auto_confirm(cookie_id)
result.append({
'id': cookie_id,
'value': cookie_value,
- 'enabled': cookie_enabled
+ 'enabled': cookie_enabled,
+ 'auto_confirm': auto_confirm
})
return result
@@ -1314,6 +1316,70 @@ def remove_cookie(cid: str, current_user: Dict[str, Any] = Depends(get_current_u
raise HTTPException(status_code=400, detail=str(e))
+class AutoConfirmUpdate(BaseModel):
+ auto_confirm: bool
+
+
+@app.put("/cookies/{cid}/auto-confirm")
+def update_auto_confirm(cid: str, update_data: AutoConfirmUpdate, current_user: Dict[str, Any] = Depends(get_current_user)):
+ """更新账号的自动确认发货设置"""
+ if cookie_manager.manager is None:
+ raise HTTPException(status_code=500, detail="CookieManager 未就绪")
+ try:
+ # 检查cookie是否属于当前用户
+ user_id = current_user['user_id']
+ from db_manager import db_manager
+ user_cookies = db_manager.get_all_cookies(user_id)
+
+ if cid not in user_cookies:
+ raise HTTPException(status_code=403, detail="无权限操作该Cookie")
+
+ # 更新数据库中的auto_confirm设置
+ success = db_manager.update_auto_confirm(cid, update_data.auto_confirm)
+ if not success:
+ raise HTTPException(status_code=500, detail="更新自动确认发货设置失败")
+
+ # 通知CookieManager更新设置(如果账号正在运行)
+ if hasattr(cookie_manager.manager, 'update_auto_confirm_setting'):
+ cookie_manager.manager.update_auto_confirm_setting(cid, update_data.auto_confirm)
+
+ return {
+ "msg": "success",
+ "auto_confirm": update_data.auto_confirm,
+ "message": f"自动确认发货已{'开启' if update_data.auto_confirm else '关闭'}"
+ }
+ except HTTPException:
+ raise
+ except Exception as e:
+ raise HTTPException(status_code=500, detail=str(e))
+
+
+@app.get("/cookies/{cid}/auto-confirm")
+def get_auto_confirm(cid: str, current_user: Dict[str, Any] = Depends(get_current_user)):
+ """获取账号的自动确认发货设置"""
+ if cookie_manager.manager is None:
+ raise HTTPException(status_code=500, detail="CookieManager 未就绪")
+ try:
+ # 检查cookie是否属于当前用户
+ user_id = current_user['user_id']
+ from db_manager import db_manager
+ user_cookies = db_manager.get_all_cookies(user_id)
+
+ if cid not in user_cookies:
+ raise HTTPException(status_code=403, detail="无权限操作该Cookie")
+
+ # 获取auto_confirm设置
+ auto_confirm = db_manager.get_auto_confirm(cid)
+ return {
+ "auto_confirm": auto_confirm,
+ "message": f"自动确认发货当前{'开启' if auto_confirm else '关闭'}"
+ }
+ except HTTPException:
+ raise
+ except Exception as e:
+ raise HTTPException(status_code=500, detail=str(e))
+
+
diff --git a/static/index.html b/static/index.html
index aa5a720..be9e777 100644
--- a/static/index.html
+++ b/static/index.html
@@ -1341,12 +1341,13 @@
账号ID
- Cookie值
+ Cookie值
关键词
状态
- 默认回复
- AI回复
- 操作
+ 默认回复
+ AI回复
+ 自动确认发货
+ 操作